1 diff -urN linux-2.4.18/arch/alpha/config.in linux-2.4.18-mh15/arch/alpha/config.in
2 --- linux-2.4.18/arch/alpha/config.in 2001-11-21 00:49:31.000000000 +0100
3 +++ linux-2.4.18-mh15/arch/alpha/config.in 2004-08-01 16:26:22.000000000 +0200
5 source drivers/usb/Config.in
6 source drivers/input/Config.in
8 -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
9 - source net/bluetooth/Config.in
11 +source net/bluetooth/Config.in
13 mainmenu_option next_comment
14 comment 'Kernel hacking'
15 diff -urN linux-2.4.18/arch/arm/config.in linux-2.4.18-mh15/arch/arm/config.in
16 --- linux-2.4.18/arch/arm/config.in 2001-11-09 22:58:02.000000000 +0100
17 +++ linux-2.4.18-mh15/arch/arm/config.in 2004-08-01 16:26:22.000000000 +0200
20 source drivers/usb/Config.in
22 -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
23 - source net/bluetooth/Config.in
25 +source net/bluetooth/Config.in
27 mainmenu_option next_comment
28 comment 'Kernel hacking'
29 diff -urN linux-2.4.18/arch/i386/config.in linux-2.4.18-mh15/arch/i386/config.in
30 --- linux-2.4.18/arch/i386/config.in 2002-02-25 20:37:52.000000000 +0100
31 +++ linux-2.4.18-mh15/arch/i386/config.in 2004-08-01 16:26:22.000000000 +0200
34 source drivers/usb/Config.in
36 -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
37 - source net/bluetooth/Config.in
39 +source net/bluetooth/Config.in
41 mainmenu_option next_comment
42 comment 'Kernel hacking'
43 diff -urN linux-2.4.18/arch/ppc/config.in linux-2.4.18-mh15/arch/ppc/config.in
44 --- linux-2.4.18/arch/ppc/config.in 2002-02-25 20:37:55.000000000 +0100
45 +++ linux-2.4.18-mh15/arch/ppc/config.in 2004-08-01 16:26:22.000000000 +0200
48 source drivers/usb/Config.in
50 -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
51 - source net/bluetooth/Config.in
53 +source net/bluetooth/Config.in
55 mainmenu_option next_comment
56 comment 'Kernel hacking'
57 diff -urN linux-2.4.18/arch/sparc/config.in linux-2.4.18-mh15/arch/sparc/config.in
58 --- linux-2.4.18/arch/sparc/config.in 2001-06-12 04:15:27.000000000 +0200
59 +++ linux-2.4.18-mh15/arch/sparc/config.in 2004-08-01 16:26:22.000000000 +0200
64 -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
65 - source net/bluetooth/Config.in
67 +source net/bluetooth/Config.in
69 mainmenu_option next_comment
71 diff -urN linux-2.4.18/arch/sparc64/config.in linux-2.4.18-mh15/arch/sparc64/config.in
72 --- linux-2.4.18/arch/sparc64/config.in 2001-12-21 18:41:53.000000000 +0100
73 +++ linux-2.4.18-mh15/arch/sparc64/config.in 2004-08-01 16:26:22.000000000 +0200
76 source drivers/usb/Config.in
78 -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
79 - source net/bluetooth/Config.in
81 +source net/bluetooth/Config.in
83 mainmenu_option next_comment
85 diff -urN linux-2.4.18/arch/sparc64/kernel/ioctl32.c linux-2.4.18-mh15/arch/sparc64/kernel/ioctl32.c
86 --- linux-2.4.18/arch/sparc64/kernel/ioctl32.c 2002-02-25 20:37:56.000000000 +0100
87 +++ linux-2.4.18-mh15/arch/sparc64/kernel/ioctl32.c 2004-08-01 16:26:23.000000000 +0200
90 #include <net/bluetooth/bluetooth.h>
91 #include <net/bluetooth/hci.h>
92 +#include <net/bluetooth/rfcomm.h>
94 #include <linux/usb.h>
95 #include <linux/usbdevice_fs.h>
96 @@ -3822,6 +3823,15 @@
100 +/* Bluetooth ioctls */
101 +#define HCIUARTSETPROTO _IOW('U', 200, int)
102 +#define HCIUARTGETPROTO _IOR('U', 201, int)
104 +#define BNEPCONNADD _IOW('B', 200, int)
105 +#define BNEPCONNDEL _IOW('B', 201, int)
106 +#define BNEPGETCONNLIST _IOR('B', 210, int)
107 +#define BNEPGETCONNINFO _IOR('B', 211, int)
109 struct mtd_oob_buf32 {
112 @@ -3878,6 +3888,16 @@
113 return ((0 == ret) ? 0 : -EFAULT);
116 +#define CMTPCONNADD _IOW('C', 200, int)
117 +#define CMTPCONNDEL _IOW('C', 201, int)
118 +#define CMTPGETCONNLIST _IOR('C', 210, int)
119 +#define CMTPGETCONNINFO _IOR('C', 211, int)
121 +#define HIDPCONNADD _IOW('H', 200, int)
122 +#define HIDPCONNDEL _IOW('H', 201, int)
123 +#define HIDPGETCONNLIST _IOR('H', 210, int)
124 +#define HIDPGETCONNINFO _IOR('H', 211, int)
128 unsigned int handler;
129 @@ -4540,6 +4560,25 @@
130 COMPATIBLE_IOCTL(HCISETSCAN)
131 COMPATIBLE_IOCTL(HCISETAUTH)
132 COMPATIBLE_IOCTL(HCIINQUIRY)
133 +COMPATIBLE_IOCTL(HCIUARTSETPROTO)
134 +COMPATIBLE_IOCTL(HCIUARTGETPROTO)
135 +COMPATIBLE_IOCTL(RFCOMMCREATEDEV)
136 +COMPATIBLE_IOCTL(RFCOMMRELEASEDEV)
137 +COMPATIBLE_IOCTL(RFCOMMGETDEVLIST)
138 +COMPATIBLE_IOCTL(RFCOMMGETDEVINFO)
139 +COMPATIBLE_IOCTL(RFCOMMSTEALDLC)
140 +COMPATIBLE_IOCTL(BNEPCONNADD)
141 +COMPATIBLE_IOCTL(BNEPCONNDEL)
142 +COMPATIBLE_IOCTL(BNEPGETCONNLIST)
143 +COMPATIBLE_IOCTL(BNEPGETCONNINFO)
144 +COMPATIBLE_IOCTL(CMTPCONNADD)
145 +COMPATIBLE_IOCTL(CMTPCONNDEL)
146 +COMPATIBLE_IOCTL(CMTPGETCONNLIST)
147 +COMPATIBLE_IOCTL(CMTPGETCONNINFO)
148 +COMPATIBLE_IOCTL(HIDPCONNADD)
149 +COMPATIBLE_IOCTL(HIDPCONNDEL)
150 +COMPATIBLE_IOCTL(HIDPGETCONNLIST)
151 +COMPATIBLE_IOCTL(HIDPGETCONNINFO)
153 COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */
154 COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */
155 diff -urN linux-2.4.18/CREDITS linux-2.4.18-mh15/CREDITS
156 --- linux-2.4.18/CREDITS 2002-02-25 20:37:50.000000000 +0100
157 +++ linux-2.4.18-mh15/CREDITS 2004-08-01 16:26:23.000000000 +0200
158 @@ -1317,6 +1317,16 @@
159 S: Provo, Utah 84606-5607
163 +E: marcel@holtmann.org
164 +W: http://www.holtmann.org
165 +D: Maintainer of the Linux Bluetooth Subsystem
166 +D: Author and maintainer of the various Bluetooth HCI drivers
167 +D: Author and maintainer of the CAPI message transport protocol driver
168 +D: Author and maintainer of the Bluetooth HID protocol driver
169 +D: Various other Bluetooth related patches, cleanups and fixes
173 E: hooft@EMBL-Heidelberg.DE
174 D: Shared libs for graphics-tools and for the f2c compiler
175 @@ -2546,6 +2556,7 @@
176 N: Aristeu Sergio Rozanski Filho
177 E: aris@conectiva.com.br
178 D: Support for EtherExpress 10 ISA (i82595) in eepro driver
179 +D: User level driver support for input
181 S: R. Tocantins, 89 - Cristo Rei
182 S: 80050-430 - Curitiba - Paraná
183 diff -urN linux-2.4.18/Documentation/Configure.help linux-2.4.18-mh15/Documentation/Configure.help
184 --- linux-2.4.18/Documentation/Configure.help 2002-02-25 20:37:51.000000000 +0100
185 +++ linux-2.4.18-mh15/Documentation/Configure.help 2004-08-01 16:26:23.000000000 +0200
186 @@ -2824,14 +2824,6 @@
190 -HCI EMU (virtual device) driver
192 - Bluetooth Virtual HCI device driver.
193 - This driver is required if you want to use HCI Emulation software.
195 - Say Y here to compile support for Virtual HCI devices into the
196 - kernel or say M to compile it as module (hci_usb.o).
201 @@ -11037,6 +11029,12 @@
205 +Hotplug firmware loading support (EXPERIMENTAL)
207 + This option is provided for the case where no in-kernel-tree modules require
208 + hotplug firmware loading support, but a module built outside the kernel tree
211 Use PCI shared memory for NIC registers
213 Use PCI shared memory for the NIC registers, rather than going through
214 @@ -12896,6 +12894,15 @@
215 accessible under char device 13:64+ - /dev/input/eventX in a generic
216 way. This is the future ...
219 + Say Y here if you want to support user level drivers for input
220 + subsystem accessible under char device 10:223 - /dev/input/uinput.
222 + This driver is also available as a module ( = code which can be
223 + inserted in and removed from the running kernel whenever you want).
224 + The module will be called uinput.o. If you want to compile it as a
225 + module, say M here and read <file:Documentation/modules.txt>.
229 Say Y here if you want to connect a USB scanner to your computer's
230 @@ -19870,19 +19877,22 @@
231 Bluetooth can be found at <http://www.bluetooth.com/>.
233 Linux Bluetooth subsystem consist of several layers:
234 - HCI Core (device and connection manager, scheduler)
235 - HCI Device drivers (interface to the hardware)
236 - L2CAP Module (L2CAP protocol)
237 + BlueZ Core (HCI device and connection manager, scheduler)
238 + HCI Device drivers (Interface to the hardware)
239 + SCO Module (SCO audio links)
240 + L2CAP Module (Logical Link Control and Adaptation Protocol)
241 + RFCOMM Module (RFCOMM Protocol)
242 + BNEP Module (Bluetooth Network Encapsulation Protocol)
243 + CMTP Module (CAPI Message Transport Protocol)
244 + HIDP Module (Human Interface Device Protocol)
246 - Say Y here to enable Linux Bluetooth support and to build HCI Core
248 + Say Y here to compile Bluetooth support into the kernel or say M to
249 + compile it as module (bluez.o).
251 To use Linux Bluetooth subsystem, you will need several user-space
252 utilities like hciconfig and hcid. These utilities and updates to
253 Bluetooth kernel modules are provided in the BlueZ package.
254 - For more information, see <http://bluez.sourceforge.net/>.
256 - If you want to compile HCI Core as module (hci.o) say M here.
257 + For more information, see <http://www.bluez.org/>.
259 L2CAP protocol support
261 @@ -19893,15 +19903,96 @@
262 Say Y here to compile L2CAP support into the kernel or say M to
263 compile it as module (l2cap.o).
267 + SCO link provides voice transport over Bluetooth. SCO support is
268 + required for voice applications like Headset and Audio.
270 + Say Y here to compile SCO support into the kernel or say M to
271 + compile it as module (sco.o).
273 +RFCOMM protocol support
275 + RFCOMM provides connection oriented stream transport. RFCOMM
276 + support is required for Dialup Networking, OBEX and other Bluetooth
279 + Say Y here to compile RFCOMM support into the kernel or say M to
280 + compile it as module (rfcomm.o).
282 +RFCOMM TTY emulation support
283 +CONFIG_BLUEZ_RFCOMM_TTY
284 + This option enables TTY emulation support for RFCOMM channels.
286 +BNEP protocol support
288 + BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet
289 + emulation layer on top of Bluetooth. BNEP is required for
290 + Bluetooth PAN (Personal Area Network).
292 + Say Y here to compile BNEP support into the kernel or say M to
293 + compile it as module (bnep.o).
295 +BNEP multicast filter support
296 +CONFIG_BLUEZ_BNEP_MC_FILTER
297 + This option enables the multicast filter support for BNEP.
299 +BNEP protocol filter support
300 +CONFIG_BLUEZ_BNEP_PROTO_FILTER
301 + This option enables the protocol filter support for BNEP.
303 +CMTP protocol support
305 + CMTP (CAPI Message Transport Protocol) is a transport layer
306 + for CAPI messages. CMTP is required for the Bluetooth Common
307 + ISDN Access Profile.
309 + Say Y here to compile CMTP support into the kernel or say M to
310 + compile it as module (cmtp.o).
312 +HIDP protocol support
314 + HIDP (Human Interface Device Protocol) is a transport layer
315 + for HID reports. HIDP is required for the Bluetooth Human
316 + Interface Device Profile.
318 + Say Y here to compile HIDP support into the kernel or say M to
319 + compile it as module (hidp.o).
323 Bluetooth HCI UART driver.
324 This driver is required if you want to use Bluetooth devices with
325 - serial port interface.
326 + serial port interface. You will also need this driver if you have
327 + UART based Bluetooth PCMCIA and CF devices like Xircom Credit Card
328 + adapter and BrainBoxes Bluetooth PC Card.
330 Say Y here to compile support for Bluetooth UART devices into the
331 kernel or say M to compile it as module (hci_uart.o).
333 +HCI UART (H4) protocol support
334 +CONFIG_BLUEZ_HCIUART_H4
335 + UART (H4) is serial protocol for communication between Bluetooth
336 + device and host. This protocol is required for most Bluetooth devices
337 + with UART interface, including PCMCIA and CF cards.
339 + Say Y here to compile support for HCI UART (H4) protocol.
341 +HCI BCSP protocol support
342 +CONFIG_BLUEZ_HCIUART_BCSP
343 + BCSP (BlueCore Serial Protocol) is serial protocol for communication
344 + between Bluetooth device and host. This protocol is required for non
345 + USB Bluetooth devices based on CSR BlueCore chip, including PCMCIA and
348 + Say Y here to compile support for HCI BCSP protocol.
350 +HCI BCSP transmit CRC with every BCSP packet
351 +CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
352 + If you say Y here, a 16-bit CRC checksum will be transmitted along with
353 + every BCSP (BlueCore Serial Protocol) packet sent to the Bluetooth chip.
354 + This increases reliability, but slightly reduces efficiency.
358 Bluetooth HCI USB driver.
359 @@ -19911,7 +20002,16 @@
360 Say Y here to compile support for Bluetooth USB devices into the
361 kernel or say M to compile it as module (hci_usb.o).
363 -HCI VHCI virtual HCI device driver
364 +HCI USB SCO (voice) support
365 +CONFIG_BLUEZ_HCIUSB_SCO
366 + This option enables the SCO support in the HCI USB driver. You need this
367 + to transmit voice data with your Bluetooth USB device. And your device
368 + must also support sending SCO data over the HCI layer, because some of
369 + them sends the SCO data to an internal PCM adapter.
371 + Say Y here to compile support for HCI SCO data.
373 +HCI VHCI Virtual HCI device driver
375 Bluetooth Virtual HCI device driver.
376 This driver is required if you want to use HCI Emulation software.
377 @@ -19919,6 +20019,63 @@
378 Say Y here to compile support for virtual HCI devices into the
379 kernel or say M to compile it as module (hci_vhci.o).
381 +HCI BFUSB device driver
382 +CONFIG_BLUEZ_HCIBFUSB
383 + Bluetooth HCI BlueFRITZ! USB driver.
384 + This driver provides support for Bluetooth USB devices with AVM
388 + Say Y here to compile support for HCI BFUSB devices into the
389 + kernel or say M to compile it as module (bfusb.o).
391 +HCI DTL1 (PC Card) device driver
392 +CONFIG_BLUEZ_HCIDTL1
393 + Bluetooth HCI DTL1 (PC Card) driver.
394 + This driver provides support for Bluetooth PCMCIA devices with
395 + Nokia DTL1 interface:
396 + Nokia Bluetooth Card
397 + Socket Bluetooth CF Card
399 + Say Y here to compile support for HCI DTL1 devices into the
400 + kernel or say M to compile it as module (dtl1_cs.o).
402 +HCI BT3C (PC Card) device driver
403 +CONFIG_BLUEZ_HCIBT3C
404 + Bluetooth HCI BT3C (PC Card) driver.
405 + This driver provides support for Bluetooth PCMCIA devices with
406 + 3Com BT3C interface:
407 + 3Com Bluetooth Card (3CRWB6096)
410 + Say Y here to compile support for HCI BT3C devices into the
411 + kernel or say M to compile it as module (bt3c_cs.o).
413 +HCI BlueCard (PC Card) device driver
414 +CONFIG_BLUEZ_HCIBLUECARD
415 + Bluetooth HCI BlueCard (PC Card) driver.
416 + This driver provides support for Bluetooth PCMCIA devices with
417 + Anycom BlueCard interface:
418 + Anycom Bluetooth PC Card
419 + Anycom Bluetooth CF Card
421 + Say Y here to compile support for HCI BlueCard devices into the
422 + kernel or say M to compile it as module (bluecard_cs.o).
424 +HCI UART (PC Card) device driver
425 +CONFIG_BLUEZ_HCIBTUART
426 + Bluetooth HCI UART (PC Card) driver.
427 + This driver provides support for Bluetooth PCMCIA devices with
429 + Xircom CreditCard Bluetooth Adapter
430 + Xircom RealPort2 Bluetooth Adapter
433 + Cyber-blue Compact Flash Card
435 + Say Y here to compile support for HCI UART devices into the
436 + kernel or say M to compile it as module (btuart_cs.o).
438 # The following options are for Linux when running on the Hitachi
439 # SuperH family of RISC microprocessors.
441 diff -urN linux-2.4.18/Documentation/devices.txt linux-2.4.18-mh15/Documentation/devices.txt
442 --- linux-2.4.18/Documentation/devices.txt 2001-11-07 23:46:01.000000000 +0100
443 +++ linux-2.4.18-mh15/Documentation/devices.txt 2004-08-01 16:26:23.000000000 +0200
445 220 = /dev/mptctl Message passing technology (MPT) control
446 221 = /dev/mvista/hssdsi Montavista PICMG hot swap system driver
447 222 = /dev/mvista/hasi Montavista PICMG high availability
448 + 223 = /dev/input/uinput User level driver support for input
449 240-255 Reserved for local use
451 11 char Raw keyboard device
452 diff -urN linux-2.4.18/Documentation/firmware_class/firmware_sample_driver.c linux-2.4.18-mh15/Documentation/firmware_class/firmware_sample_driver.c
453 --- linux-2.4.18/Documentation/firmware_class/firmware_sample_driver.c 1970-01-01 01:00:00.000000000 +0100
454 +++ linux-2.4.18-mh15/Documentation/firmware_class/firmware_sample_driver.c 2004-08-01 16:26:23.000000000 +0200
457 + * firmware_sample_driver.c -
459 + * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
461 + * Sample code on how to use request_firmware() from drivers.
463 + * Note that register_firmware() is currently useless.
467 +#include <linux/module.h>
468 +#include <linux/kernel.h>
469 +#include <linux/init.h>
470 +#include <linux/string.h>
472 +#include "linux/firmware.h"
474 +#define WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
475 +#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
476 +char __init inkernel_firmware[] = "let's say that this is firmware\n";
479 +static char ghost_device[] = "ghost0";
481 +static void sample_firmware_load(char *firmware, int size)
484 + memcpy(buf, firmware, size);
486 + printk("firmware_sample_driver: firmware: %s\n", buf);
489 +static void sample_probe_default(void)
491 + /* uses the default method to get the firmware */
492 + const struct firmware *fw_entry;
493 + printk("firmware_sample_driver: a ghost device got inserted :)\n");
495 + if(request_firmware(&fw_entry, "sample_driver_fw", ghost_device)!=0)
498 + "firmware_sample_driver: Firmware not available\n");
502 + sample_firmware_load(fw_entry->data, fw_entry->size);
504 + release_firmware(fw_entry);
506 + /* finish setting up the device */
508 +static void sample_probe_specific(void)
510 + /* Uses some specific hotplug support to get the firmware from
511 + * userspace directly into the hardware, or via some sysfs file */
513 + /* NOTE: This currently doesn't work */
515 + printk("firmware_sample_driver: a ghost device got inserted :)\n");
517 + if(request_firmware(NULL, "sample_driver_fw", ghost_device)!=0)
520 + "firmware_sample_driver: Firmware load failed\n");
524 + /* request_firmware blocks until userspace finished, so at
525 + * this point the firmware should be already in the device */
527 + /* finish setting up the device */
529 +static void sample_probe_async_cont(const struct firmware *fw, void *context)
533 + "firmware_sample_driver: firmware load failed\n");
537 + printk("firmware_sample_driver: device pointer \"%s\"\n",
539 + sample_firmware_load(fw->data, fw->size);
541 +static void sample_probe_async(void)
543 + /* Let's say that I can't sleep */
545 + error = request_firmware_nowait (THIS_MODULE,
546 + "sample_driver_fw", ghost_device,
547 + "my device pointer",
548 + sample_probe_async_cont);
551 + "firmware_sample_driver:"
552 + " request_firmware_nowait failed\n");
556 +static int sample_init(void)
558 +#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
559 + register_firmware("sample_driver_fw", inkernel_firmware,
560 + sizeof(inkernel_firmware));
562 + /* since there is no real hardware insertion I just call the
563 + * sample probe functions here */
564 + sample_probe_specific();
565 + sample_probe_default();
566 + sample_probe_async();
569 +static void __exit sample_exit(void)
573 +module_init (sample_init);
574 +module_exit (sample_exit);
576 +MODULE_LICENSE("GPL");
577 diff -urN linux-2.4.18/Documentation/firmware_class/hotplug-script linux-2.4.18-mh15/Documentation/firmware_class/hotplug-script
578 --- linux-2.4.18/Documentation/firmware_class/hotplug-script 1970-01-01 01:00:00.000000000 +0100
579 +++ linux-2.4.18-mh15/Documentation/firmware_class/hotplug-script 2004-08-01 16:26:23.000000000 +0200
583 +# Simple hotplug script sample:
585 +# Both $DEVPATH and $FIRMWARE are already provided in the environment.
587 +HOTPLUG_FW_DIR=/usr/lib/hotplug/firmware/
589 +echo 1 > /sysfs/$DEVPATH/loading
590 +cat $HOTPLUG_FW_DIR/$FIRMWARE > /sysfs/$DEVPATH/data
591 +echo 0 > /sysfs/$DEVPATH/loading
593 +# To cancel the load in case of error:
595 +# echo -1 > /sysfs/$DEVPATH/loading
597 diff -urN linux-2.4.18/Documentation/firmware_class/README linux-2.4.18-mh15/Documentation/firmware_class/README
598 --- linux-2.4.18/Documentation/firmware_class/README 1970-01-01 01:00:00.000000000 +0100
599 +++ linux-2.4.18-mh15/Documentation/firmware_class/README 2004-08-01 16:26:23.000000000 +0200
602 + request_firmware() hotplug interface:
603 + ------------------------------------
604 + Copyright (C) 2003 Manuel Estrada Sainz <ranty@debian.org>
609 + Today, the most extended way to use firmware in the Linux kernel is linking
610 + it statically in a header file. Which has political and technical issues:
612 + 1) Some firmware is not legal to redistribute.
613 + 2) The firmware occupies memory permanently, even though it often is just
615 + 3) Some people, like the Debian crowd, don't consider some firmware free
616 + enough and remove entire drivers (e.g.: keyspan).
618 + about in-kernel persistence:
619 + ---------------------------
620 + Under some circumstances, as explained below, it would be interesting to keep
621 + firmware images in non-swappable kernel memory or even in the kernel image
622 + (probably within initramfs).
624 + Note that this functionality has not been implemented.
626 + - Why OPTIONAL in-kernel persistence may be a good idea sometimes:
628 + - If the device that needs the firmware is needed to access the
629 + filesystem. When upon some error the device has to be reset and the
630 + firmware reloaded, it won't be possible to get it from userspace.
632 + - A diskless client with a network card that needs firmware.
633 + - The filesystem is stored in a disk behind an scsi device
634 + that needs firmware.
635 + - Replacing buggy DSDT/SSDT ACPI tables on boot.
636 + Note: this would require the persistent objects to be included
637 + within the kernel image, probably within initramfs.
639 + And the same device can be needed to access the filesystem or not depending
640 + on the setup, so I think that the choice on what firmware to make
641 + persistent should be left to userspace.
643 + - Why register_firmware()+__init can be useful:
644 + - For boot devices needing firmware.
645 + - To make the transition easier:
646 + The firmware can be declared __init and register_firmware()
647 + called on module_init. Then the firmware is warranted to be
648 + there even if "firmware hotplug userspace" is not there yet or
649 + it doesn't yet provide the needed firmware.
650 + Once the firmware is widely available in userspace, it can be
651 + removed from the kernel. Or made optional (CONFIG_.*_FIRMWARE).
653 + In either case, if firmware hotplug support is there, it can move the
654 + firmware out of kernel memory into the real filesystem for later
657 + Note: If persistence is implemented on top of initramfs,
658 + register_firmware() may not be appropriate.
659 diff -urN linux-2.4.18/drivers/bluetooth/bfusb.c linux-2.4.18-mh15/drivers/bluetooth/bfusb.c
660 --- linux-2.4.18/drivers/bluetooth/bfusb.c 1970-01-01 01:00:00.000000000 +0100
661 +++ linux-2.4.18-mh15/drivers/bluetooth/bfusb.c 2004-08-01 16:26:23.000000000 +0200
665 + * AVM BlueFRITZ! USB driver
667 + * Copyright (C) 2003 Marcel Holtmann <marcel@holtmann.org>
670 + * This program is free software; you can redistribute it and/or modify
671 + * it under the terms of the GNU General Public License as published by
672 + * the Free Software Foundation; either version 2 of the License, or
673 + * (at your option) any later version.
675 + * This program is distributed in the hope that it will be useful,
676 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
677 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
678 + * GNU General Public License for more details.
680 + * You should have received a copy of the GNU General Public License
681 + * along with this program; if not, write to the Free Software
682 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
686 +#include <linux/config.h>
687 +#include <linux/module.h>
689 +#include <linux/kernel.h>
690 +#include <linux/init.h>
691 +#include <linux/slab.h>
692 +#include <linux/types.h>
693 +#include <linux/sched.h>
694 +#include <linux/errno.h>
695 +#include <linux/skbuff.h>
697 +#include <linux/firmware.h>
698 +#include <linux/usb.h>
700 +#include <net/bluetooth/bluetooth.h>
701 +#include <net/bluetooth/hci_core.h>
703 +#ifndef CONFIG_BLUEZ_HCIBFUSB_DEBUG
705 +#define BT_DBG(D...)
708 +#define VERSION "1.1"
710 +static struct usb_device_id bfusb_table[] = {
711 + /* AVM BlueFRITZ! USB */
712 + { USB_DEVICE(0x057c, 0x2200) },
714 + { } /* Terminating entry */
717 +MODULE_DEVICE_TABLE(usb, bfusb_table);
720 +#define BFUSB_MAX_BLOCK_SIZE 256
722 +#define BFUSB_BLOCK_TIMEOUT (HZ * 3)
724 +#define BFUSB_TX_PROCESS 1
725 +#define BFUSB_TX_WAKEUP 2
727 +#define BFUSB_MAX_BULK_TX 1
728 +#define BFUSB_MAX_BULK_RX 1
731 + struct hci_dev hdev;
733 + unsigned long state;
735 + struct usb_device *udev;
737 + unsigned int bulk_in_ep;
738 + unsigned int bulk_out_ep;
739 + unsigned int bulk_pkt_size;
743 + struct sk_buff_head transmit_q;
745 + struct sk_buff *reassembly;
747 + atomic_t pending_tx;
748 + struct sk_buff_head pending_q;
749 + struct sk_buff_head completed_q;
756 +static void bfusb_tx_complete(struct urb *urb);
757 +static void bfusb_rx_complete(struct urb *urb);
759 +static struct urb *bfusb_get_completed(struct bfusb *bfusb)
761 + struct sk_buff *skb;
762 + struct urb *urb = NULL;
764 + BT_DBG("bfusb %p", bfusb);
766 + skb = skb_dequeue(&bfusb->completed_q);
768 + urb = ((struct bfusb_scb *) skb->cb)->urb;
775 +static inline void bfusb_unlink_urbs(struct bfusb *bfusb)
777 + struct sk_buff *skb;
780 + BT_DBG("bfusb %p", bfusb);
782 + while ((skb = skb_dequeue(&bfusb->pending_q))) {
783 + urb = ((struct bfusb_scb *) skb->cb)->urb;
784 + usb_unlink_urb(urb);
785 + skb_queue_tail(&bfusb->completed_q, skb);
788 + while ((urb = bfusb_get_completed(bfusb)))
793 +static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb)
795 + struct bfusb_scb *scb = (void *) skb->cb;
796 + struct urb *urb = bfusb_get_completed(bfusb);
799 + BT_DBG("bfusb %p skb %p len %d", bfusb, skb, skb->len);
801 + if (!urb && !(urb = usb_alloc_urb(0)))
804 + pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
806 + FILL_BULK_URB(urb, bfusb->udev, pipe, skb->data, skb->len,
807 + bfusb_tx_complete, skb);
809 + urb->transfer_flags = USB_QUEUE_BULK;
813 + skb_queue_tail(&bfusb->pending_q, skb);
815 + err = usb_submit_urb(urb);
817 + BT_ERR("%s bulk tx submit failed urb %p err %d",
818 + bfusb->hdev.name, urb, err);
822 + atomic_inc(&bfusb->pending_tx);
827 +static void bfusb_tx_wakeup(struct bfusb *bfusb)
829 + struct sk_buff *skb;
831 + BT_DBG("bfusb %p", bfusb);
833 + if (test_and_set_bit(BFUSB_TX_PROCESS, &bfusb->state)) {
834 + set_bit(BFUSB_TX_WAKEUP, &bfusb->state);
839 + clear_bit(BFUSB_TX_WAKEUP, &bfusb->state);
841 + while ((atomic_read(&bfusb->pending_tx) < BFUSB_MAX_BULK_TX) &&
842 + (skb = skb_dequeue(&bfusb->transmit_q))) {
843 + if (bfusb_send_bulk(bfusb, skb) < 0) {
844 + skb_queue_head(&bfusb->transmit_q, skb);
849 + } while (test_bit(BFUSB_TX_WAKEUP, &bfusb->state));
851 + clear_bit(BFUSB_TX_PROCESS, &bfusb->state);
854 +static void bfusb_tx_complete(struct urb *urb)
856 + struct sk_buff *skb = (struct sk_buff *) urb->context;
857 + struct bfusb *bfusb = (struct bfusb *) skb->dev;
859 + BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
861 + atomic_dec(&bfusb->pending_tx);
863 + if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags))
867 + bfusb->hdev.stat.byte_tx += skb->len;
869 + bfusb->hdev.stat.err_tx++;
871 + read_lock(&bfusb->lock);
874 + skb_queue_tail(&bfusb->completed_q, skb);
876 + bfusb_tx_wakeup(bfusb);
878 + read_unlock(&bfusb->lock);
882 +static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb)
884 + struct bfusb_scb *scb;
885 + struct sk_buff *skb;
886 + int err, pipe, size = HCI_MAX_FRAME_SIZE + 32;
888 + BT_DBG("bfusb %p urb %p", bfusb, urb);
890 + if (!urb && !(urb = usb_alloc_urb(0)))
893 + if (!(skb = bluez_skb_alloc(size, GFP_ATOMIC))) {
898 + skb->dev = (void *) bfusb;
900 + scb = (struct bfusb_scb *) skb->cb;
903 + pipe = usb_rcvbulkpipe(bfusb->udev, bfusb->bulk_in_ep);
905 + FILL_BULK_URB(urb, bfusb->udev, pipe, skb->data, size,
906 + bfusb_rx_complete, skb);
908 + urb->transfer_flags = USB_QUEUE_BULK;
910 + skb_queue_tail(&bfusb->pending_q, skb);
912 + err = usb_submit_urb(urb);
914 + BT_ERR("%s bulk rx submit failed urb %p err %d",
915 + bfusb->hdev.name, urb, err);
924 +static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *data, int len)
926 + BT_DBG("bfusb %p hdr 0x%02x data %p len %d", bfusb, hdr, data, len);
929 + BT_ERR("%s error in block", bfusb->hdev.name);
930 + if (bfusb->reassembly)
931 + kfree_skb(bfusb->reassembly);
932 + bfusb->reassembly = NULL;
937 + struct sk_buff *skb;
938 + unsigned char pkt_type;
941 + if (bfusb->reassembly) {
942 + BT_ERR("%s unexpected start block", bfusb->hdev.name);
943 + kfree_skb(bfusb->reassembly);
944 + bfusb->reassembly = NULL;
948 + BT_ERR("%s no packet type found", bfusb->hdev.name);
952 + pkt_type = *data++; len--;
954 + switch (pkt_type) {
955 + case HCI_EVENT_PKT:
956 + if (len >= HCI_EVENT_HDR_SIZE) {
957 + hci_event_hdr *hdr = (hci_event_hdr *) data;
958 + pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;
960 + BT_ERR("%s event block is too short", bfusb->hdev.name);
965 + case HCI_ACLDATA_PKT:
966 + if (len >= HCI_ACL_HDR_SIZE) {
967 + hci_acl_hdr *hdr = (hci_acl_hdr *) data;
968 + pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen);
970 + BT_ERR("%s data block is too short", bfusb->hdev.name);
975 + case HCI_SCODATA_PKT:
976 + if (len >= HCI_SCO_HDR_SIZE) {
977 + hci_sco_hdr *hdr = (hci_sco_hdr *) data;
978 + pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen;
980 + BT_ERR("%s audio block is too short", bfusb->hdev.name);
986 + skb = bluez_skb_alloc(pkt_len, GFP_ATOMIC);
988 + BT_ERR("%s no memory for the packet", bfusb->hdev.name);
992 + skb->dev = (void *) &bfusb->hdev;
993 + skb->pkt_type = pkt_type;
995 + bfusb->reassembly = skb;
997 + if (!bfusb->reassembly) {
998 + BT_ERR("%s unexpected continuation block", bfusb->hdev.name);
1004 + memcpy(skb_put(bfusb->reassembly, len), data, len);
1007 + hci_recv_frame(bfusb->reassembly);
1008 + bfusb->reassembly = NULL;
1014 +static void bfusb_rx_complete(struct urb *urb)
1016 + struct sk_buff *skb = (struct sk_buff *) urb->context;
1017 + struct bfusb *bfusb = (struct bfusb *) skb->dev;
1018 + unsigned char *buf = urb->transfer_buffer;
1019 + int count = urb->actual_length;
1020 + int err, hdr, len;
1022 + BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
1024 + read_lock(&bfusb->lock);
1026 + if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags))
1029 + if (urb->status || !count)
1032 + bfusb->hdev.stat.byte_rx += count;
1034 + skb_put(skb, count);
1037 + hdr = buf[0] | (buf[1] << 8);
1039 + if (hdr & 0x4000) {
1044 + len = (buf[2] == 0) ? 256 : buf[2];
1049 + if (count < len) {
1050 + BT_ERR("%s block extends over URB buffer ranges",
1051 + bfusb->hdev.name);
1054 + if ((hdr & 0xe1) == 0xc1)
1055 + bfusb_recv_block(bfusb, hdr, buf, len);
1064 + bfusb_rx_submit(bfusb, urb);
1066 + read_unlock(&bfusb->lock);
1071 + urb->dev = bfusb->udev;
1073 + err = usb_submit_urb(urb);
1075 + BT_ERR("%s bulk resubmit failed urb %p err %d",
1076 + bfusb->hdev.name, urb, err);
1080 + read_unlock(&bfusb->lock);
1084 +static int bfusb_open(struct hci_dev *hdev)
1086 + struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
1087 + unsigned long flags;
1090 + BT_DBG("hdev %p bfusb %p", hdev, bfusb);
1092 + if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
1095 + MOD_INC_USE_COUNT;
1097 + write_lock_irqsave(&bfusb->lock, flags);
1099 + err = bfusb_rx_submit(bfusb, NULL);
1101 + for (i = 1; i < BFUSB_MAX_BULK_RX; i++)
1102 + bfusb_rx_submit(bfusb, NULL);
1104 + clear_bit(HCI_RUNNING, &hdev->flags);
1105 + MOD_DEC_USE_COUNT;
1108 + write_unlock_irqrestore(&bfusb->lock, flags);
1113 +static int bfusb_flush(struct hci_dev *hdev)
1115 + struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
1117 + BT_DBG("hdev %p bfusb %p", hdev, bfusb);
1119 + skb_queue_purge(&bfusb->transmit_q);
1124 +static int bfusb_close(struct hci_dev *hdev)
1126 + struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
1127 + unsigned long flags;
1129 + BT_DBG("hdev %p bfusb %p", hdev, bfusb);
1131 + if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
1134 + write_lock_irqsave(&bfusb->lock, flags);
1136 + bfusb_unlink_urbs(bfusb);
1137 + bfusb_flush(hdev);
1139 + write_unlock_irqrestore(&bfusb->lock, flags);
1141 + MOD_DEC_USE_COUNT;
1146 +static int bfusb_send_frame(struct sk_buff *skb)
1148 + struct hci_dev *hdev = (struct hci_dev *) skb->dev;
1149 + struct bfusb *bfusb;
1150 + struct sk_buff *nskb;
1151 + unsigned char buf[3];
1152 + int sent = 0, size, count;
1154 + BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, skb->pkt_type, skb->len);
1157 + BT_ERR("Frame for unknown HCI device (hdev=NULL)");
1161 + if (!test_bit(HCI_RUNNING, &hdev->flags))
1164 + bfusb = (struct bfusb *) hdev->driver_data;
1166 + switch (skb->pkt_type) {
1167 + case HCI_COMMAND_PKT:
1168 + hdev->stat.cmd_tx++;
1170 + case HCI_ACLDATA_PKT:
1171 + hdev->stat.acl_tx++;
1173 + case HCI_SCODATA_PKT:
1174 + hdev->stat.sco_tx++;
1178 + /* Prepend skb with frame type */
1179 + memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
1183 + /* Max HCI frame size seems to be 1511 + 1 */
1184 + if (!(nskb = bluez_skb_alloc(count + 32, GFP_ATOMIC))) {
1185 + BT_ERR("Can't allocate memory for new packet");
1189 + nskb->dev = (void *) bfusb;
1192 + size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE);
1194 + buf[0] = 0xc1 | ((sent == 0) ? 0x04 : 0) | ((count == size) ? 0x08 : 0);
1196 + buf[2] = (size == BFUSB_MAX_BLOCK_SIZE) ? 0 : size;
1198 + memcpy(skb_put(nskb, 3), buf, 3);
1199 + memcpy(skb_put(nskb, size), skb->data + sent, size);
1205 + /* Don't send frame with multiple size of bulk max packet */
1206 + if ((nskb->len % bfusb->bulk_pkt_size) == 0) {
1209 + memcpy(skb_put(nskb, 2), buf, 2);
1212 + read_lock(&bfusb->lock);
1214 + skb_queue_tail(&bfusb->transmit_q, nskb);
1215 + bfusb_tx_wakeup(bfusb);
1217 + read_unlock(&bfusb->lock);
1224 +static void bfusb_destruct(struct hci_dev *hdev)
1226 + struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
1228 + BT_DBG("hdev %p bfusb %p", hdev, bfusb);
1233 +static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
1235 + return -ENOIOCTLCMD;
1239 +static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int count)
1241 + unsigned char *buf;
1242 + int err, pipe, len, size, sent = 0;
1244 + BT_DBG("bfusb %p udev %p firmware %p count %d", bfusb, bfusb->udev, firmware, count);
1246 + BT_INFO("BlueFRITZ! USB loading firmware");
1248 + if (usb_set_configuration(bfusb->udev, 1) < 0) {
1249 + BT_ERR("Can't change to loading configuration");
1253 + buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
1255 + BT_ERR("Can't allocate memory chunk for firmware");
1259 + pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
1262 + size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3);
1264 + memcpy(buf, firmware + sent, size);
1266 + err = usb_bulk_msg(bfusb->udev, pipe, buf, size,
1267 + &len, BFUSB_BLOCK_TIMEOUT);
1269 + if (err || (len != size)) {
1270 + BT_ERR("Error in firmware loading");
1278 + if ((err = usb_bulk_msg(bfusb->udev, pipe, NULL, 0,
1279 + &len, BFUSB_BLOCK_TIMEOUT)) < 0) {
1280 + BT_ERR("Error in null packet request");
1284 + if ((err = usb_set_configuration(bfusb->udev, 2)) < 0) {
1285 + BT_ERR("Can't change to running configuration");
1289 + BT_INFO("BlueFRITZ! USB device ready");
1297 + pipe = usb_sndctrlpipe(bfusb->udev, 0);
1299 + usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
1300 + 0, 0, 0, NULL, 0, BFUSB_BLOCK_TIMEOUT);
1305 +static void *bfusb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
1307 + const struct firmware *firmware;
1309 + struct usb_interface *iface;
1310 + struct usb_interface_descriptor *iface_desc;
1311 + struct usb_endpoint_descriptor *bulk_out_ep;
1312 + struct usb_endpoint_descriptor *bulk_in_ep;
1313 + struct hci_dev *hdev;
1314 + struct bfusb *bfusb;
1316 + BT_DBG("udev %p ifnum %d id %p", udev, ifnum, id);
1318 + /* Check number of endpoints */
1319 + iface = &udev->actconfig->interface[0];
1320 + iface_desc = &iface->altsetting[0];
1322 + if (iface_desc->bNumEndpoints < 2)
1325 + bulk_out_ep = &iface_desc->endpoint[0];
1326 + bulk_in_ep = &iface_desc->endpoint[1];
1328 + if (!bulk_out_ep || !bulk_in_ep) {
1329 + BT_ERR("Bulk endpoints not found");
1333 + /* Initialize control structure and load firmware */
1334 + if (!(bfusb = kmalloc(sizeof(struct bfusb), GFP_KERNEL))) {
1335 + BT_ERR("Can't allocate memory for control structure");
1339 + memset(bfusb, 0, sizeof(struct bfusb));
1341 + bfusb->udev = udev;
1342 + bfusb->bulk_in_ep = bulk_in_ep->bEndpointAddress;
1343 + bfusb->bulk_out_ep = bulk_out_ep->bEndpointAddress;
1344 + bfusb->bulk_pkt_size = bulk_out_ep->wMaxPacketSize;
1346 + bfusb->lock = RW_LOCK_UNLOCKED;
1348 + bfusb->reassembly = NULL;
1350 + skb_queue_head_init(&bfusb->transmit_q);
1351 + skb_queue_head_init(&bfusb->pending_q);
1352 + skb_queue_head_init(&bfusb->completed_q);
1354 + snprintf(device, sizeof(device), "bfusb%3.3d%3.3d", udev->bus->busnum, udev->devnum);
1356 + if (request_firmware(&firmware, "bfubase.frm", device) < 0) {
1357 + BT_ERR("Firmware request failed");
1361 + if (bfusb_load_firmware(bfusb, firmware->data, firmware->size) < 0) {
1362 + BT_ERR("Firmware loading failed");
1366 + release_firmware(firmware);
1368 + /* Initialize and register HCI device */
1369 + hdev = &bfusb->hdev;
1371 + hdev->type = HCI_USB;
1372 + hdev->driver_data = bfusb;
1374 + hdev->open = bfusb_open;
1375 + hdev->close = bfusb_close;
1376 + hdev->flush = bfusb_flush;
1377 + hdev->send = bfusb_send_frame;
1378 + hdev->destruct = bfusb_destruct;
1379 + hdev->ioctl = bfusb_ioctl;
1381 + if (hci_register_dev(hdev) < 0) {
1382 + BT_ERR("Can't register HCI device");
1389 + release_firmware(firmware);
1398 +static void bfusb_disconnect(struct usb_device *udev, void *ptr)
1400 + struct bfusb *bfusb = (struct bfusb *) ptr;
1401 + struct hci_dev *hdev = &bfusb->hdev;
1403 + BT_DBG("udev %p ptr %p", udev, ptr);
1408 + bfusb_close(hdev);
1410 + if (hci_unregister_dev(hdev) < 0)
1411 + BT_ERR("Can't unregister HCI device %s", hdev->name);
1414 +static struct usb_driver bfusb_driver = {
1416 + probe: bfusb_probe,
1417 + disconnect: bfusb_disconnect,
1418 + id_table: bfusb_table,
1421 +static int __init bfusb_init(void)
1425 + BT_INFO("BlueFRITZ! USB driver ver %s", VERSION);
1426 + BT_INFO("Copyright (C) 2003 Marcel Holtmann <marcel@holtmann.org>");
1428 + if ((err = usb_register(&bfusb_driver)) < 0)
1429 + BT_ERR("Failed to register BlueFRITZ! USB driver");
1434 +static void __exit bfusb_cleanup(void)
1436 + usb_deregister(&bfusb_driver);
1439 +module_init(bfusb_init);
1440 +module_exit(bfusb_cleanup);
1442 +MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
1443 +MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION);
1444 +MODULE_LICENSE("GPL");
1445 diff -urN linux-2.4.18/drivers/bluetooth/bluecard_cs.c linux-2.4.18-mh15/drivers/bluetooth/bluecard_cs.c
1446 --- linux-2.4.18/drivers/bluetooth/bluecard_cs.c 1970-01-01 01:00:00.000000000 +0100
1447 +++ linux-2.4.18-mh15/drivers/bluetooth/bluecard_cs.c 2004-08-01 16:26:23.000000000 +0200
1451 + * Bluetooth driver for the Anycom BlueCard (LSE039/LSE041)
1453 + * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
1456 + * This program is free software; you can redistribute it and/or modify
1457 + * it under the terms of the GNU General Public License version 2 as
1458 + * published by the Free Software Foundation;
1460 + * Software distributed under the License is distributed on an "AS
1461 + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
1462 + * implied. See the License for the specific language governing
1463 + * rights and limitations under the License.
1465 + * The initial developer of the original code is David A. Hinds
1466 + * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
1467 + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
1471 +#include <linux/config.h>
1472 +#include <linux/module.h>
1474 +#include <linux/kernel.h>
1475 +#include <linux/init.h>
1476 +#include <linux/slab.h>
1477 +#include <linux/types.h>
1478 +#include <linux/sched.h>
1479 +#include <linux/timer.h>
1480 +#include <linux/errno.h>
1481 +#include <linux/ptrace.h>
1482 +#include <linux/ioport.h>
1483 +#include <linux/spinlock.h>
1484 +#include <linux/skbuff.h>
1485 +#include <asm/io.h>
1487 +#include <pcmcia/version.h>
1488 +#include <pcmcia/cs_types.h>
1489 +#include <pcmcia/cs.h>
1490 +#include <pcmcia/cistpl.h>
1491 +#include <pcmcia/ciscode.h>
1492 +#include <pcmcia/ds.h>
1493 +#include <pcmcia/cisreg.h>
1495 +#include <net/bluetooth/bluetooth.h>
1496 +#include <net/bluetooth/hci_core.h>
1500 +/* ======================== Module parameters ======================== */
1503 +/* Bit map of interrupts to choose from */
1504 +static u_int irq_mask = 0x86bc;
1505 +static int irq_list[4] = { -1 };
1507 +MODULE_PARM(irq_mask, "i");
1508 +MODULE_PARM(irq_list, "1-4i");
1510 +MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
1511 +MODULE_DESCRIPTION("BlueZ driver for the Anycom BlueCard (LSE039/LSE041)");
1512 +MODULE_LICENSE("GPL");
1516 +/* ======================== Local structures ======================== */
1519 +typedef struct bluecard_info_t {
1523 + struct hci_dev hdev;
1525 + spinlock_t lock; /* For serializing operations */
1526 + struct timer_list timer; /* For LED control */
1528 + struct sk_buff_head txq;
1529 + unsigned long tx_state;
1531 + unsigned long rx_state;
1532 + unsigned long rx_count;
1533 + struct sk_buff *rx_skb;
1535 + unsigned char ctrl_reg;
1536 + unsigned long hw_state; /* Status of the hardware and LED control */
1540 +void bluecard_config(dev_link_t *link);
1541 +void bluecard_release(u_long arg);
1542 +int bluecard_event(event_t event, int priority, event_callback_args_t *args);
1544 +static dev_info_t dev_info = "bluecard_cs";
1546 +dev_link_t *bluecard_attach(void);
1547 +void bluecard_detach(dev_link_t *);
1549 +static dev_link_t *dev_list = NULL;
1552 +/* Default baud rate: 57600, 115200, 230400 or 460800 */
1553 +#define DEFAULT_BAUD_RATE 230400
1556 +/* Hardware states */
1557 +#define CARD_READY 1
1558 +#define CARD_HAS_PCCARD_ID 4
1559 +#define CARD_HAS_POWER_LED 5
1560 +#define CARD_HAS_ACTIVITY_LED 6
1562 +/* Transmit states */
1563 +#define XMIT_SENDING 1
1564 +#define XMIT_WAKEUP 2
1565 +#define XMIT_BUFFER_NUMBER 5 /* unset = buffer one, set = buffer two */
1566 +#define XMIT_BUF_ONE_READY 6
1567 +#define XMIT_BUF_TWO_READY 7
1568 +#define XMIT_SENDING_READY 8
1570 +/* Receiver states */
1571 +#define RECV_WAIT_PACKET_TYPE 0
1572 +#define RECV_WAIT_EVENT_HEADER 1
1573 +#define RECV_WAIT_ACL_HEADER 2
1574 +#define RECV_WAIT_SCO_HEADER 3
1575 +#define RECV_WAIT_DATA 4
1577 +/* Special packet types */
1578 +#define PKT_BAUD_RATE_57600 0x80
1579 +#define PKT_BAUD_RATE_115200 0x81
1580 +#define PKT_BAUD_RATE_230400 0x82
1581 +#define PKT_BAUD_RATE_460800 0x83
1584 +/* These are the register offsets */
1585 +#define REG_COMMAND 0x20
1586 +#define REG_INTERRUPT 0x21
1587 +#define REG_CONTROL 0x22
1588 +#define REG_RX_CONTROL 0x24
1589 +#define REG_CARD_RESET 0x30
1590 +#define REG_LED_CTRL 0x30
1593 +#define REG_COMMAND_TX_BUF_ONE 0x01
1594 +#define REG_COMMAND_TX_BUF_TWO 0x02
1595 +#define REG_COMMAND_RX_BUF_ONE 0x04
1596 +#define REG_COMMAND_RX_BUF_TWO 0x08
1597 +#define REG_COMMAND_RX_WIN_ONE 0x00
1598 +#define REG_COMMAND_RX_WIN_TWO 0x10
1601 +#define REG_CONTROL_BAUD_RATE_57600 0x00
1602 +#define REG_CONTROL_BAUD_RATE_115200 0x01
1603 +#define REG_CONTROL_BAUD_RATE_230400 0x02
1604 +#define REG_CONTROL_BAUD_RATE_460800 0x03
1605 +#define REG_CONTROL_RTS 0x04
1606 +#define REG_CONTROL_BT_ON 0x08
1607 +#define REG_CONTROL_BT_RESET 0x10
1608 +#define REG_CONTROL_BT_RES_PU 0x20
1609 +#define REG_CONTROL_INTERRUPT 0x40
1610 +#define REG_CONTROL_CARD_RESET 0x80
1612 +/* REG_RX_CONTROL */
1613 +#define RTS_LEVEL_SHIFT_BITS 0x02
1617 +/* ======================== LED handling routines ======================== */
1620 +void bluecard_activity_led_timeout(u_long arg)
1622 + bluecard_info_t *info = (bluecard_info_t *)arg;
1623 + unsigned int iobase = info->link.io.BasePort1;
1625 + if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) {
1626 + /* Disable activity LED */
1627 + outb(0x08 | 0x20, iobase + 0x30);
1629 + /* Disable power LED */
1630 + outb(0x00, iobase + 0x30);
1635 +static void bluecard_enable_activity_led(bluecard_info_t *info)
1637 + unsigned int iobase = info->link.io.BasePort1;
1639 + if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) {
1640 + /* Enable activity LED */
1641 + outb(0x10 | 0x40, iobase + 0x30);
1643 + /* Stop the LED after HZ/4 */
1644 + mod_timer(&(info->timer), jiffies + HZ / 4);
1646 + /* Enable power LED */
1647 + outb(0x08 | 0x20, iobase + 0x30);
1649 + /* Stop the LED after HZ/2 */
1650 + mod_timer(&(info->timer), jiffies + HZ / 2);
1656 +/* ======================== Interrupt handling ======================== */
1659 +static int bluecard_write(unsigned int iobase, unsigned int offset, __u8 *buf, int len)
1663 + actual = (len > 15) ? 15 : len;
1665 + outb_p(actual, iobase + offset);
1667 + for (i = 0; i < actual; i++)
1668 + outb_p(buf[i], iobase + offset + i + 1);
1674 +static void bluecard_write_wakeup(bluecard_info_t *info)
1677 + printk(KERN_WARNING "bluecard_cs: Call of write_wakeup for unknown device.\n");
1681 + if (!test_bit(XMIT_SENDING_READY, &(info->tx_state)))
1684 + if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
1685 + set_bit(XMIT_WAKEUP, &(info->tx_state));
1690 + register unsigned int iobase = info->link.io.BasePort1;
1691 + register unsigned int offset;
1692 + register unsigned char command;
1693 + register unsigned long ready_bit;
1694 + register struct sk_buff *skb;
1697 + clear_bit(XMIT_WAKEUP, &(info->tx_state));
1699 + if (!(info->link.state & DEV_PRESENT))
1702 + if (test_bit(XMIT_BUFFER_NUMBER, &(info->tx_state))) {
1703 + if (!test_bit(XMIT_BUF_TWO_READY, &(info->tx_state)))
1706 + command = REG_COMMAND_TX_BUF_TWO;
1707 + ready_bit = XMIT_BUF_TWO_READY;
1709 + if (!test_bit(XMIT_BUF_ONE_READY, &(info->tx_state)))
1712 + command = REG_COMMAND_TX_BUF_ONE;
1713 + ready_bit = XMIT_BUF_ONE_READY;
1716 + if (!(skb = skb_dequeue(&(info->txq))))
1719 + if (skb->pkt_type & 0x80) {
1721 + info->ctrl_reg |= REG_CONTROL_RTS;
1722 + outb(info->ctrl_reg, iobase + REG_CONTROL);
1725 + /* Activate LED */
1726 + bluecard_enable_activity_led(info);
1729 + len = bluecard_write(iobase, offset, skb->data, skb->len);
1731 + /* Tell the FPGA to send the data */
1732 + outb_p(command, iobase + REG_COMMAND);
1734 + /* Mark the buffer as dirty */
1735 + clear_bit(ready_bit, &(info->tx_state));
1737 + if (skb->pkt_type & 0x80) {
1739 + wait_queue_head_t wait;
1740 + unsigned char baud_reg;
1742 + switch (skb->pkt_type) {
1743 + case PKT_BAUD_RATE_460800:
1744 + baud_reg = REG_CONTROL_BAUD_RATE_460800;
1746 + case PKT_BAUD_RATE_230400:
1747 + baud_reg = REG_CONTROL_BAUD_RATE_230400;
1749 + case PKT_BAUD_RATE_115200:
1750 + baud_reg = REG_CONTROL_BAUD_RATE_115200;
1752 + case PKT_BAUD_RATE_57600:
1753 + /* Fall through... */
1755 + baud_reg = REG_CONTROL_BAUD_RATE_57600;
1759 + /* Wait until the command reaches the baseband */
1760 + init_waitqueue_head(&wait);
1761 + interruptible_sleep_on_timeout(&wait, HZ / 10);
1763 + /* Set baud on baseband */
1764 + info->ctrl_reg &= ~0x03;
1765 + info->ctrl_reg |= baud_reg;
1766 + outb(info->ctrl_reg, iobase + REG_CONTROL);
1769 + info->ctrl_reg &= ~REG_CONTROL_RTS;
1770 + outb(info->ctrl_reg, iobase + REG_CONTROL);
1772 + /* Wait before the next HCI packet can be send */
1773 + interruptible_sleep_on_timeout(&wait, HZ);
1777 + if (len == skb->len) {
1780 + skb_pull(skb, len);
1781 + skb_queue_head(&(info->txq), skb);
1784 + info->hdev.stat.byte_tx += len;
1786 + /* Change buffer */
1787 + change_bit(XMIT_BUFFER_NUMBER, &(info->tx_state));
1789 + } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
1791 + clear_bit(XMIT_SENDING, &(info->tx_state));
1795 +static int bluecard_read(unsigned int iobase, unsigned int offset, __u8 *buf, int size)
1799 + outb(REG_COMMAND_RX_WIN_ONE, iobase + REG_COMMAND);
1801 + len = inb(iobase + offset);
1808 + outb(REG_COMMAND_RX_WIN_TWO, iobase + REG_COMMAND);
1812 + buf[n] = inb(iobase + offset + i);
1823 +static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
1825 + unsigned int iobase;
1826 + unsigned char buf[31];
1830 + printk(KERN_WARNING "bluecard_cs: Call of receive for unknown device.\n");
1834 + iobase = info->link.io.BasePort1;
1836 + if (test_bit(XMIT_SENDING_READY, &(info->tx_state)))
1837 + bluecard_enable_activity_led(info);
1839 + len = bluecard_read(iobase, offset, buf, sizeof(buf));
1841 + for (i = 0; i < len; i++) {
1843 + /* Allocate packet */
1844 + if (info->rx_skb == NULL) {
1845 + info->rx_state = RECV_WAIT_PACKET_TYPE;
1846 + info->rx_count = 0;
1847 + if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
1848 + printk(KERN_WARNING "bluecard_cs: Can't allocate mem for new packet.\n");
1853 + if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
1855 + info->rx_skb->dev = (void *)&(info->hdev);
1856 + info->rx_skb->pkt_type = buf[i];
1858 + switch (info->rx_skb->pkt_type) {
1862 + if (offset != 0x00) {
1863 + set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
1864 + set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
1865 + set_bit(XMIT_SENDING_READY, &(info->tx_state));
1866 + bluecard_write_wakeup(info);
1869 + kfree_skb(info->rx_skb);
1870 + info->rx_skb = NULL;
1873 + case HCI_EVENT_PKT:
1874 + info->rx_state = RECV_WAIT_EVENT_HEADER;
1875 + info->rx_count = HCI_EVENT_HDR_SIZE;
1878 + case HCI_ACLDATA_PKT:
1879 + info->rx_state = RECV_WAIT_ACL_HEADER;
1880 + info->rx_count = HCI_ACL_HDR_SIZE;
1883 + case HCI_SCODATA_PKT:
1884 + info->rx_state = RECV_WAIT_SCO_HEADER;
1885 + info->rx_count = HCI_SCO_HDR_SIZE;
1889 + /* unknown packet */
1890 + printk(KERN_WARNING "bluecard_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
1891 + info->hdev.stat.err_rx++;
1893 + kfree_skb(info->rx_skb);
1894 + info->rx_skb = NULL;
1901 + *skb_put(info->rx_skb, 1) = buf[i];
1904 + if (info->rx_count == 0) {
1907 + hci_event_hdr *eh;
1911 + switch (info->rx_state) {
1913 + case RECV_WAIT_EVENT_HEADER:
1914 + eh = (hci_event_hdr *)(info->rx_skb->data);
1915 + info->rx_state = RECV_WAIT_DATA;
1916 + info->rx_count = eh->plen;
1919 + case RECV_WAIT_ACL_HEADER:
1920 + ah = (hci_acl_hdr *)(info->rx_skb->data);
1921 + dlen = __le16_to_cpu(ah->dlen);
1922 + info->rx_state = RECV_WAIT_DATA;
1923 + info->rx_count = dlen;
1926 + case RECV_WAIT_SCO_HEADER:
1927 + sh = (hci_sco_hdr *)(info->rx_skb->data);
1928 + info->rx_state = RECV_WAIT_DATA;
1929 + info->rx_count = sh->dlen;
1932 + case RECV_WAIT_DATA:
1933 + hci_recv_frame(info->rx_skb);
1934 + info->rx_skb = NULL;
1946 + info->hdev.stat.byte_rx += len;
1950 +void bluecard_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
1952 + bluecard_info_t *info = dev_inst;
1953 + unsigned int iobase;
1954 + unsigned char reg;
1957 + printk(KERN_WARNING "bluecard_cs: Call of irq %d for unknown device.\n", irq);
1961 + if (!test_bit(CARD_READY, &(info->hw_state)))
1964 + iobase = info->link.io.BasePort1;
1966 + spin_lock(&(info->lock));
1968 + /* Disable interrupt */
1969 + info->ctrl_reg &= ~REG_CONTROL_INTERRUPT;
1970 + outb(info->ctrl_reg, iobase + REG_CONTROL);
1972 + reg = inb(iobase + REG_INTERRUPT);
1974 + if ((reg != 0x00) && (reg != 0xff)) {
1977 + bluecard_receive(info, 0x00);
1978 + outb(0x04, iobase + REG_INTERRUPT);
1979 + outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
1983 + bluecard_receive(info, 0x10);
1984 + outb(0x08, iobase + REG_INTERRUPT);
1985 + outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);
1989 + set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
1990 + outb(0x01, iobase + REG_INTERRUPT);
1991 + bluecard_write_wakeup(info);
1995 + set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
1996 + outb(0x02, iobase + REG_INTERRUPT);
1997 + bluecard_write_wakeup(info);
2002 + /* Enable interrupt */
2003 + info->ctrl_reg |= REG_CONTROL_INTERRUPT;
2004 + outb(info->ctrl_reg, iobase + REG_CONTROL);
2006 + spin_unlock(&(info->lock));
2011 +/* ======================== Device specific HCI commands ======================== */
2014 +static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
2016 + bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
2017 + struct sk_buff *skb;
2019 + /* Ericsson baud rate command */
2020 + unsigned char cmd[] = { HCI_COMMAND_PKT, 0x09, 0xfc, 0x01, 0x03 };
2022 + if (!(skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
2023 + printk(KERN_WARNING "bluecard_cs: Can't allocate mem for new packet.\n");
2030 + skb->pkt_type = PKT_BAUD_RATE_460800;
2034 + skb->pkt_type = PKT_BAUD_RATE_230400;
2038 + skb->pkt_type = PKT_BAUD_RATE_115200;
2041 + /* Fall through... */
2044 + skb->pkt_type = PKT_BAUD_RATE_57600;
2048 + memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
2050 + skb_queue_tail(&(info->txq), skb);
2052 + bluecard_write_wakeup(info);
2059 +/* ======================== HCI interface ======================== */
2062 +static int bluecard_hci_flush(struct hci_dev *hdev)
2064 + bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
2066 + /* Drop TX queue */
2067 + skb_queue_purge(&(info->txq));
2073 +static int bluecard_hci_open(struct hci_dev *hdev)
2075 + bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
2076 + unsigned int iobase = info->link.io.BasePort1;
2078 + bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
2080 + if (test_and_set_bit(HCI_RUNNING, &(hdev->flags)))
2084 + outb(0x08 | 0x20, iobase + 0x30);
2090 +static int bluecard_hci_close(struct hci_dev *hdev)
2092 + bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
2093 + unsigned int iobase = info->link.io.BasePort1;
2095 + if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
2098 + bluecard_hci_flush(hdev);
2101 + outb(0x00, iobase + 0x30);
2107 +static int bluecard_hci_send_frame(struct sk_buff *skb)
2109 + bluecard_info_t *info;
2110 + struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
2113 + printk(KERN_WARNING "bluecard_cs: Frame for unknown HCI device (hdev=NULL).");
2117 + info = (bluecard_info_t *)(hdev->driver_data);
2119 + switch (skb->pkt_type) {
2120 + case HCI_COMMAND_PKT:
2121 + hdev->stat.cmd_tx++;
2123 + case HCI_ACLDATA_PKT:
2124 + hdev->stat.acl_tx++;
2126 + case HCI_SCODATA_PKT:
2127 + hdev->stat.sco_tx++;
2131 + /* Prepend skb with frame type */
2132 + memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
2133 + skb_queue_tail(&(info->txq), skb);
2135 + bluecard_write_wakeup(info);
2141 +static void bluecard_hci_destruct(struct hci_dev *hdev)
2146 +static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
2148 + return -ENOIOCTLCMD;
2153 +/* ======================== Card services HCI interaction ======================== */
2156 +int bluecard_open(bluecard_info_t *info)
2158 + unsigned int iobase = info->link.io.BasePort1;
2159 + struct hci_dev *hdev;
2162 + spin_lock_init(&(info->lock));
2164 + init_timer(&(info->timer));
2165 + info->timer.function = &bluecard_activity_led_timeout;
2166 + info->timer.data = (u_long)info;
2168 + skb_queue_head_init(&(info->txq));
2170 + info->rx_state = RECV_WAIT_PACKET_TYPE;
2171 + info->rx_count = 0;
2172 + info->rx_skb = NULL;
2174 + id = inb(iobase + 0x30);
2176 + if ((id & 0x0f) == 0x02)
2177 + set_bit(CARD_HAS_PCCARD_ID, &(info->hw_state));
2180 + set_bit(CARD_HAS_POWER_LED, &(info->hw_state));
2183 + set_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state));
2186 + info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
2187 + outb(info->ctrl_reg, iobase + REG_CONTROL);
2189 + /* Turn FPGA off */
2190 + outb(0x80, iobase + 0x30);
2192 + /* Wait some time */
2193 + set_current_state(TASK_INTERRUPTIBLE);
2194 + schedule_timeout(HZ / 100);
2196 + /* Turn FPGA on */
2197 + outb(0x00, iobase + 0x30);
2199 + /* Activate card */
2200 + info->ctrl_reg = REG_CONTROL_BT_ON | REG_CONTROL_BT_RES_PU;
2201 + outb(info->ctrl_reg, iobase + REG_CONTROL);
2203 + /* Enable interrupt */
2204 + outb(0xff, iobase + REG_INTERRUPT);
2205 + info->ctrl_reg |= REG_CONTROL_INTERRUPT;
2206 + outb(info->ctrl_reg, iobase + REG_CONTROL);
2208 + /* Start the RX buffers */
2209 + outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
2210 + outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);
2212 + /* Signal that the hardware is ready */
2213 + set_bit(CARD_READY, &(info->hw_state));
2215 + /* Drop TX queue */
2216 + skb_queue_purge(&(info->txq));
2218 + /* Control the point at which RTS is enabled */
2219 + outb((0x0f << RTS_LEVEL_SHIFT_BITS) | 1, iobase + REG_RX_CONTROL);
2221 + /* Timeout before it is safe to send the first HCI packet */
2222 + set_current_state(TASK_INTERRUPTIBLE);
2223 + schedule_timeout((HZ * 5) / 4); // or set it to 3/2
2226 + /* Initialize and register HCI device */
2228 + hdev = &(info->hdev);
2230 + hdev->type = HCI_PCCARD;
2231 + hdev->driver_data = info;
2233 + hdev->open = bluecard_hci_open;
2234 + hdev->close = bluecard_hci_close;
2235 + hdev->flush = bluecard_hci_flush;
2236 + hdev->send = bluecard_hci_send_frame;
2237 + hdev->destruct = bluecard_hci_destruct;
2238 + hdev->ioctl = bluecard_hci_ioctl;
2240 + if (hci_register_dev(hdev) < 0) {
2241 + printk(KERN_WARNING "bluecard_cs: Can't register HCI device %s.\n", hdev->name);
2249 +int bluecard_close(bluecard_info_t *info)
2251 + unsigned int iobase = info->link.io.BasePort1;
2252 + struct hci_dev *hdev = &(info->hdev);
2254 + if (info->link.state & DEV_CONFIG_PENDING)
2257 + bluecard_hci_close(hdev);
2259 + clear_bit(CARD_READY, &(info->hw_state));
2262 + info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
2263 + outb(info->ctrl_reg, iobase + REG_CONTROL);
2265 + /* Turn FPGA off */
2266 + outb(0x80, iobase + 0x30);
2268 + if (hci_unregister_dev(hdev) < 0)
2269 + printk(KERN_WARNING "bluecard_cs: Can't unregister HCI device %s.\n", hdev->name);
2276 +/* ======================== Card services ======================== */
2279 +static void cs_error(client_handle_t handle, int func, int ret)
2281 + error_info_t err = { func, ret };
2283 + CardServices(ReportError, handle, &err);
2287 +dev_link_t *bluecard_attach(void)
2289 + bluecard_info_t *info;
2290 + client_reg_t client_reg;
2294 + /* Create new info device */
2295 + info = kmalloc(sizeof(*info), GFP_KERNEL);
2298 + memset(info, 0, sizeof(*info));
2300 + link = &info->link;
2301 + link->priv = info;
2303 + link->release.function = &bluecard_release;
2304 + link->release.data = (u_long)link;
2305 + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
2306 + link->io.NumPorts1 = 8;
2307 + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
2308 + link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
2310 + if (irq_list[0] == -1)
2311 + link->irq.IRQInfo2 = irq_mask;
2313 + for (i = 0; i < 4; i++)
2314 + link->irq.IRQInfo2 |= 1 << irq_list[i];
2316 + link->irq.Handler = bluecard_interrupt;
2317 + link->irq.Instance = info;
2319 + link->conf.Attributes = CONF_ENABLE_IRQ;
2320 + link->conf.Vcc = 50;
2321 + link->conf.IntType = INT_MEMORY_AND_IO;
2323 + /* Register with Card Services */
2324 + link->next = dev_list;
2326 + client_reg.dev_info = &dev_info;
2327 + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
2328 + client_reg.EventMask =
2329 + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
2330 + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
2331 + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
2332 + client_reg.event_handler = &bluecard_event;
2333 + client_reg.Version = 0x0210;
2334 + client_reg.event_callback_args.client_data = link;
2336 + ret = CardServices(RegisterClient, &link->handle, &client_reg);
2337 + if (ret != CS_SUCCESS) {
2338 + cs_error(link->handle, RegisterClient, ret);
2339 + bluecard_detach(link);
2347 +void bluecard_detach(dev_link_t *link)
2349 + bluecard_info_t *info = link->priv;
2350 + dev_link_t **linkp;
2353 + /* Locate device structure */
2354 + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
2355 + if (*linkp == link)
2358 + if (*linkp == NULL)
2361 + del_timer(&link->release);
2362 + if (link->state & DEV_CONFIG)
2363 + bluecard_release((u_long)link);
2365 + if (link->handle) {
2366 + ret = CardServices(DeregisterClient, link->handle);
2367 + if (ret != CS_SUCCESS)
2368 + cs_error(link->handle, DeregisterClient, ret);
2371 + /* Unlink device structure, free bits */
2372 + *linkp = link->next;
2378 +static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
2382 + i = CardServices(fn, handle, tuple);
2383 + if (i != CS_SUCCESS)
2384 + return CS_NO_MORE_ITEMS;
2386 + i = CardServices(GetTupleData, handle, tuple);
2387 + if (i != CS_SUCCESS)
2390 + return CardServices(ParseTuple, handle, tuple, parse);
2394 +#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
2395 +#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
2397 +void bluecard_config(dev_link_t *link)
2399 + client_handle_t handle = link->handle;
2400 + bluecard_info_t *info = link->priv;
2404 + config_info_t config;
2405 + int i, n, last_ret, last_fn;
2407 + tuple.TupleData = (cisdata_t *)buf;
2408 + tuple.TupleOffset = 0;
2409 + tuple.TupleDataMax = 255;
2410 + tuple.Attributes = 0;
2412 + /* Get configuration register information */
2413 + tuple.DesiredTuple = CISTPL_CONFIG;
2414 + last_ret = first_tuple(handle, &tuple, &parse);
2415 + if (last_ret != CS_SUCCESS) {
2416 + last_fn = ParseTuple;
2419 + link->conf.ConfigBase = parse.config.base;
2420 + link->conf.Present = parse.config.rmask[0];
2422 + /* Configure card */
2423 + link->state |= DEV_CONFIG;
2424 + i = CardServices(GetConfigurationInfo, handle, &config);
2425 + link->conf.Vcc = config.Vcc;
2427 + link->conf.ConfigIndex = 0x20;
2428 + link->io.NumPorts1 = 64;
2429 + link->io.IOAddrLines = 6;
2431 + for (n = 0; n < 0x400; n += 0x40) {
2432 + link->io.BasePort1 = n ^ 0x300;
2433 + i = CardServices(RequestIO, link->handle, &link->io);
2434 + if (i == CS_SUCCESS)
2438 + if (i != CS_SUCCESS) {
2439 + cs_error(link->handle, RequestIO, i);
2443 + i = CardServices(RequestIRQ, link->handle, &link->irq);
2444 + if (i != CS_SUCCESS) {
2445 + cs_error(link->handle, RequestIRQ, i);
2446 + link->irq.AssignedIRQ = 0;
2449 + i = CardServices(RequestConfiguration, link->handle, &link->conf);
2450 + if (i != CS_SUCCESS) {
2451 + cs_error(link->handle, RequestConfiguration, i);
2455 + MOD_INC_USE_COUNT;
2457 + if (bluecard_open(info) != 0)
2460 + strcpy(info->node.dev_name, info->hdev.name);
2461 + link->dev = &info->node;
2462 + link->state &= ~DEV_CONFIG_PENDING;
2467 + cs_error(link->handle, last_fn, last_ret);
2470 + bluecard_release((u_long)link);
2474 +void bluecard_release(u_long arg)
2476 + dev_link_t *link = (dev_link_t *)arg;
2477 + bluecard_info_t *info = link->priv;
2479 + if (link->state & DEV_PRESENT)
2480 + bluecard_close(info);
2482 + MOD_DEC_USE_COUNT;
2486 + CardServices(ReleaseConfiguration, link->handle);
2487 + CardServices(ReleaseIO, link->handle, &link->io);
2488 + CardServices(ReleaseIRQ, link->handle, &link->irq);
2490 + link->state &= ~DEV_CONFIG;
2494 +int bluecard_event(event_t event, int priority, event_callback_args_t *args)
2496 + dev_link_t *link = args->client_data;
2497 + bluecard_info_t *info = link->priv;
2500 + case CS_EVENT_CARD_REMOVAL:
2501 + link->state &= ~DEV_PRESENT;
2502 + if (link->state & DEV_CONFIG) {
2503 + bluecard_close(info);
2504 + mod_timer(&link->release, jiffies + HZ / 20);
2507 + case CS_EVENT_CARD_INSERTION:
2508 + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2509 + bluecard_config(link);
2511 + case CS_EVENT_PM_SUSPEND:
2512 + link->state |= DEV_SUSPEND;
2513 + /* Fall through... */
2514 + case CS_EVENT_RESET_PHYSICAL:
2515 + if (link->state & DEV_CONFIG)
2516 + CardServices(ReleaseConfiguration, link->handle);
2518 + case CS_EVENT_PM_RESUME:
2519 + link->state &= ~DEV_SUSPEND;
2520 + /* Fall through... */
2521 + case CS_EVENT_CARD_RESET:
2523 + CardServices(RequestConfiguration, link->handle, &link->conf);
2532 +/* ======================== Module initialization ======================== */
2535 +int __init init_bluecard_cs(void)
2540 + CardServices(GetCardServicesInfo, &serv);
2541 + if (serv.Revision != CS_RELEASE_CODE) {
2542 + printk(KERN_NOTICE "bluecard_cs: Card Services release does not match!\n");
2546 + err = register_pccard_driver(&dev_info, &bluecard_attach, &bluecard_detach);
2552 +void __exit exit_bluecard_cs(void)
2554 + unregister_pccard_driver(&dev_info);
2556 + while (dev_list != NULL)
2557 + bluecard_detach(dev_list);
2561 +module_init(init_bluecard_cs);
2562 +module_exit(exit_bluecard_cs);
2565 diff -urN linux-2.4.18/drivers/bluetooth/bt3c_cs.c linux-2.4.18-mh15/drivers/bluetooth/bt3c_cs.c
2566 --- linux-2.4.18/drivers/bluetooth/bt3c_cs.c 1970-01-01 01:00:00.000000000 +0100
2567 +++ linux-2.4.18-mh15/drivers/bluetooth/bt3c_cs.c 2004-08-01 16:26:23.000000000 +0200
2571 + * Driver for the 3Com Bluetooth PCMCIA card
2573 + * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
2574 + * Jose Orlando Pereira <jop@di.uminho.pt>
2577 + * This program is free software; you can redistribute it and/or modify
2578 + * it under the terms of the GNU General Public License version 2 as
2579 + * published by the Free Software Foundation;
2581 + * Software distributed under the License is distributed on an "AS
2582 + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
2583 + * implied. See the License for the specific language governing
2584 + * rights and limitations under the License.
2586 + * The initial developer of the original code is David A. Hinds
2587 + * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
2588 + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
2592 +#include <linux/config.h>
2593 +#include <linux/module.h>
2595 +#include <linux/kernel.h>
2596 +#include <linux/kmod.h>
2597 +#include <linux/init.h>
2598 +#include <linux/slab.h>
2599 +#include <linux/types.h>
2600 +#include <linux/sched.h>
2601 +#include <linux/delay.h>
2602 +#include <linux/timer.h>
2603 +#include <linux/errno.h>
2604 +#include <linux/unistd.h>
2605 +#include <linux/ptrace.h>
2606 +#include <linux/ioport.h>
2607 +#include <linux/spinlock.h>
2609 +#include <linux/skbuff.h>
2610 +#include <linux/string.h>
2611 +#include <linux/serial.h>
2612 +#include <linux/serial_reg.h>
2613 +#include <asm/system.h>
2614 +#include <asm/bitops.h>
2615 +#include <asm/io.h>
2617 +#include <linux/firmware.h>
2619 +#include <pcmcia/version.h>
2620 +#include <pcmcia/cs_types.h>
2621 +#include <pcmcia/cs.h>
2622 +#include <pcmcia/cistpl.h>
2623 +#include <pcmcia/ciscode.h>
2624 +#include <pcmcia/ds.h>
2625 +#include <pcmcia/cisreg.h>
2627 +#include <net/bluetooth/bluetooth.h>
2628 +#include <net/bluetooth/hci_core.h>
2632 +/* ======================== Module parameters ======================== */
2635 +/* Bit map of interrupts to choose from */
2636 +static u_int irq_mask = 0xffff;
2637 +static int irq_list[4] = { -1 };
2639 +MODULE_PARM(irq_mask, "i");
2640 +MODULE_PARM(irq_list, "1-4i");
2642 +MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>, Jose Orlando Pereira <jop@di.uminho.pt>");
2643 +MODULE_DESCRIPTION("BlueZ driver for the 3Com Bluetooth PCMCIA card");
2644 +MODULE_LICENSE("GPL");
2648 +/* ======================== Local structures ======================== */
2651 +typedef struct bt3c_info_t {
2655 + struct hci_dev hdev;
2657 + spinlock_t lock; /* For serializing operations */
2659 + struct sk_buff_head txq;
2660 + unsigned long tx_state;
2662 + unsigned long rx_state;
2663 + unsigned long rx_count;
2664 + struct sk_buff *rx_skb;
2668 +void bt3c_config(dev_link_t *link);
2669 +void bt3c_release(u_long arg);
2670 +int bt3c_event(event_t event, int priority, event_callback_args_t *args);
2672 +static dev_info_t dev_info = "bt3c_cs";
2674 +dev_link_t *bt3c_attach(void);
2675 +void bt3c_detach(dev_link_t *);
2677 +static dev_link_t *dev_list = NULL;
2680 +/* Transmit states */
2681 +#define XMIT_SENDING 1
2682 +#define XMIT_WAKEUP 2
2683 +#define XMIT_WAITING 8
2685 +/* Receiver states */
2686 +#define RECV_WAIT_PACKET_TYPE 0
2687 +#define RECV_WAIT_EVENT_HEADER 1
2688 +#define RECV_WAIT_ACL_HEADER 2
2689 +#define RECV_WAIT_SCO_HEADER 3
2690 +#define RECV_WAIT_DATA 4
2694 +/* ======================== Special I/O functions ======================== */
2704 +inline void bt3c_address(unsigned int iobase, unsigned short addr)
2706 + outb(addr & 0xff, iobase + ADDR_L);
2707 + outb((addr >> 8) & 0xff, iobase + ADDR_H);
2711 +inline void bt3c_put(unsigned int iobase, unsigned short value)
2713 + outb(value & 0xff, iobase + DATA_L);
2714 + outb((value >> 8) & 0xff, iobase + DATA_H);
2718 +inline void bt3c_io_write(unsigned int iobase, unsigned short addr, unsigned short value)
2720 + bt3c_address(iobase, addr);
2721 + bt3c_put(iobase, value);
2725 +inline unsigned short bt3c_get(unsigned int iobase)
2727 + unsigned short value = inb(iobase + DATA_L);
2729 + value |= inb(iobase + DATA_H) << 8;
2735 +inline unsigned short bt3c_read(unsigned int iobase, unsigned short addr)
2737 + bt3c_address(iobase, addr);
2739 + return bt3c_get(iobase);
2744 +/* ======================== Interrupt handling ======================== */
2747 +static int bt3c_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
2751 + bt3c_address(iobase, 0x7080);
2753 + /* Fill FIFO with current frame */
2754 + while (actual < len) {
2755 + /* Transmit next byte */
2756 + bt3c_put(iobase, buf[actual]);
2760 + bt3c_io_write(iobase, 0x7005, actual);
2766 +static void bt3c_write_wakeup(bt3c_info_t *info, int from)
2768 + unsigned long flags;
2771 + printk(KERN_WARNING "bt3c_cs: Call of write_wakeup for unknown device.\n");
2775 + if (test_and_set_bit(XMIT_SENDING, &(info->tx_state)))
2778 + spin_lock_irqsave(&(info->lock), flags);
2781 + register unsigned int iobase = info->link.io.BasePort1;
2782 + register struct sk_buff *skb;
2785 + if (!(info->link.state & DEV_PRESENT))
2789 + if (!(skb = skb_dequeue(&(info->txq)))) {
2790 + clear_bit(XMIT_SENDING, &(info->tx_state));
2795 + len = bt3c_write(iobase, 256, skb->data, skb->len);
2797 + if (len != skb->len) {
2798 + printk(KERN_WARNING "bt3c_cs: very strange\n");
2803 + info->hdev.stat.byte_tx += len;
2807 + spin_unlock_irqrestore(&(info->lock), flags);
2811 +static void bt3c_receive(bt3c_info_t *info)
2813 + unsigned int iobase;
2814 + int size = 0, avail;
2817 + printk(KERN_WARNING "bt3c_cs: Call of receive for unknown device.\n");
2821 + iobase = info->link.io.BasePort1;
2823 + avail = bt3c_read(iobase, 0x7006);
2824 + //printk("bt3c_cs: receiving %d bytes\n", avail);
2826 + bt3c_address(iobase, 0x7480);
2827 + while (size < avail) {
2829 + info->hdev.stat.byte_rx++;
2831 + /* Allocate packet */
2832 + if (info->rx_skb == NULL) {
2833 + info->rx_state = RECV_WAIT_PACKET_TYPE;
2834 + info->rx_count = 0;
2835 + if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
2836 + printk(KERN_WARNING "bt3c_cs: Can't allocate mem for new packet.\n");
2842 + if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
2844 + info->rx_skb->dev = (void *)&(info->hdev);
2845 + info->rx_skb->pkt_type = inb(iobase + DATA_L);
2846 + inb(iobase + DATA_H);
2847 + //printk("bt3c: PACKET_TYPE=%02x\n", info->rx_skb->pkt_type);
2849 + switch (info->rx_skb->pkt_type) {
2851 + case HCI_EVENT_PKT:
2852 + info->rx_state = RECV_WAIT_EVENT_HEADER;
2853 + info->rx_count = HCI_EVENT_HDR_SIZE;
2856 + case HCI_ACLDATA_PKT:
2857 + info->rx_state = RECV_WAIT_ACL_HEADER;
2858 + info->rx_count = HCI_ACL_HDR_SIZE;
2861 + case HCI_SCODATA_PKT:
2862 + info->rx_state = RECV_WAIT_SCO_HEADER;
2863 + info->rx_count = HCI_SCO_HDR_SIZE;
2867 + /* Unknown packet */
2868 + printk(KERN_WARNING "bt3c_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
2869 + info->hdev.stat.err_rx++;
2870 + clear_bit(HCI_RUNNING, &(info->hdev.flags));
2872 + kfree_skb(info->rx_skb);
2873 + info->rx_skb = NULL;
2880 + __u8 x = inb(iobase + DATA_L);
2882 + *skb_put(info->rx_skb, 1) = x;
2883 + inb(iobase + DATA_H);
2886 + if (info->rx_count == 0) {
2889 + hci_event_hdr *eh;
2893 + switch (info->rx_state) {
2895 + case RECV_WAIT_EVENT_HEADER:
2896 + eh = (hci_event_hdr *)(info->rx_skb->data);
2897 + info->rx_state = RECV_WAIT_DATA;
2898 + info->rx_count = eh->plen;
2901 + case RECV_WAIT_ACL_HEADER:
2902 + ah = (hci_acl_hdr *)(info->rx_skb->data);
2903 + dlen = __le16_to_cpu(ah->dlen);
2904 + info->rx_state = RECV_WAIT_DATA;
2905 + info->rx_count = dlen;
2908 + case RECV_WAIT_SCO_HEADER:
2909 + sh = (hci_sco_hdr *)(info->rx_skb->data);
2910 + info->rx_state = RECV_WAIT_DATA;
2911 + info->rx_count = sh->dlen;
2914 + case RECV_WAIT_DATA:
2915 + hci_recv_frame(info->rx_skb);
2916 + info->rx_skb = NULL;
2927 + bt3c_io_write(iobase, 0x7006, 0x0000);
2931 +void bt3c_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
2933 + bt3c_info_t *info = dev_inst;
2934 + unsigned int iobase;
2938 + printk(KERN_WARNING "bt3c_cs: Call of irq %d for unknown device.\n", irq);
2942 + iobase = info->link.io.BasePort1;
2944 + spin_lock(&(info->lock));
2946 + iir = inb(iobase + CONTROL);
2948 + int stat = bt3c_read(iobase, 0x7001);
2950 + if ((stat & 0xff) == 0x7f) {
2951 + printk(KERN_WARNING "bt3c_cs: STRANGE stat=%04x\n", stat);
2952 + } else if ((stat & 0xff) != 0xff) {
2953 + if (stat & 0x0020) {
2954 + int stat = bt3c_read(iobase, 0x7002) & 0x10;
2955 + printk(KERN_WARNING "bt3c_cs: antena %s\n", stat ? "OUT" : "IN");
2957 + if (stat & 0x0001)
2958 + bt3c_receive(info);
2959 + if (stat & 0x0002) {
2960 + //printk("bt3c_cs: ACK %04x\n", stat);
2961 + clear_bit(XMIT_SENDING, &(info->tx_state));
2962 + bt3c_write_wakeup(info, 1);
2965 + bt3c_io_write(iobase, 0x7001, 0x0000);
2967 + outb(iir, iobase + CONTROL);
2971 + spin_unlock(&(info->lock));
2977 +/* ======================== HCI interface ======================== */
2980 +static int bt3c_hci_flush(struct hci_dev *hdev)
2982 + bt3c_info_t *info = (bt3c_info_t *)(hdev->driver_data);
2984 + /* Drop TX queue */
2985 + skb_queue_purge(&(info->txq));
2991 +static int bt3c_hci_open(struct hci_dev *hdev)
2993 + set_bit(HCI_RUNNING, &(hdev->flags));
2999 +static int bt3c_hci_close(struct hci_dev *hdev)
3001 + if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
3004 + bt3c_hci_flush(hdev);
3010 +static int bt3c_hci_send_frame(struct sk_buff *skb)
3012 + bt3c_info_t *info;
3013 + struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
3016 + printk(KERN_WARNING "bt3c_cs: Frame for unknown HCI device (hdev=NULL).");
3020 + info = (bt3c_info_t *) (hdev->driver_data);
3022 + switch (skb->pkt_type) {
3023 + case HCI_COMMAND_PKT:
3024 + hdev->stat.cmd_tx++;
3026 + case HCI_ACLDATA_PKT:
3027 + hdev->stat.acl_tx++;
3029 + case HCI_SCODATA_PKT:
3030 + hdev->stat.sco_tx++;
3034 + /* Prepend skb with frame type */
3035 + memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
3036 + skb_queue_tail(&(info->txq), skb);
3038 + bt3c_write_wakeup(info, 0);
3044 +static void bt3c_hci_destruct(struct hci_dev *hdev)
3049 +static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
3051 + return -ENOIOCTLCMD;
3056 +/* ======================== Card services HCI interaction ======================== */
3059 +static int bt3c_load_firmware(bt3c_info_t *info, unsigned char *firmware, int count)
3061 + char *ptr = (char *) firmware;
3063 + unsigned int iobase, size, addr, fcs, tmp;
3066 + iobase = info->link.io.BasePort1;
3070 + bt3c_io_write(iobase, 0x8040, 0x0404);
3071 + bt3c_io_write(iobase, 0x8040, 0x0400);
3075 + bt3c_io_write(iobase, 0x8040, 0x0404);
3082 + if (ptr[0] != 'S') {
3083 + printk(KERN_WARNING "bt3c_cs: Bad address in firmware.\n");
3088 + memset(b, 0, sizeof(b));
3089 + memcpy(b, ptr + 2, 2);
3090 + size = simple_strtol(b, NULL, 16);
3092 + memset(b, 0, sizeof(b));
3093 + memcpy(b, ptr + 4, 8);
3094 + addr = simple_strtol(b, NULL, 16);
3096 + memset(b, 0, sizeof(b));
3097 + memcpy(b, ptr + (size * 2) + 2, 2);
3098 + fcs = simple_strtol(b, NULL, 16);
3100 + memset(b, 0, sizeof(b));
3101 + for (tmp = 0, i = 0; i < size; i++) {
3102 + memcpy(b, ptr + (i * 2) + 2, 2);
3103 + tmp += simple_strtol(b, NULL, 16);
3106 + if (((tmp + fcs) & 0xff) != 0xff) {
3107 + printk(KERN_WARNING "bt3c_cs: Checksum error in firmware.\n");
3112 + if (ptr[1] == '3') {
3113 + bt3c_address(iobase, addr);
3115 + memset(b, 0, sizeof(b));
3116 + for (i = 0; i < (size - 4) / 2; i++) {
3117 + memcpy(b, ptr + (i * 4) + 12, 4);
3118 + tmp = simple_strtol(b, NULL, 16);
3119 + bt3c_put(iobase, tmp);
3123 + ptr += (size * 2) + 6;
3124 + count -= (size * 2) + 6;
3131 + bt3c_address(iobase, 0x3000);
3132 + outb(inb(iobase + CONTROL) | 0x40, iobase + CONTROL);
3139 + bt3c_io_write(iobase, 0x7006, 0x0000);
3140 + bt3c_io_write(iobase, 0x7005, 0x0000);
3141 + bt3c_io_write(iobase, 0x7001, 0x0000);
3147 +int bt3c_open(bt3c_info_t *info)
3149 + const struct firmware *firmware;
3151 + struct hci_dev *hdev;
3154 + spin_lock_init(&(info->lock));
3156 + skb_queue_head_init(&(info->txq));
3158 + info->rx_state = RECV_WAIT_PACKET_TYPE;
3159 + info->rx_count = 0;
3160 + info->rx_skb = NULL;
3162 + /* Load firmware */
3164 + snprintf(device, sizeof(device), "bt3c%4.4x", info->link.io.BasePort1);
3166 + err = request_firmware(&firmware, "BT3CPCC.bin", device);
3168 + printk(KERN_WARNING "bt3c_cs: Firmware request failed.\n");
3172 + err = bt3c_load_firmware(info, firmware->data, firmware->size);
3174 + release_firmware(firmware);
3177 + printk(KERN_WARNING "bt3c_cs: Firmware loading failed.\n");
3181 + /* Timeout before it is safe to send the first HCI packet */
3183 + set_current_state(TASK_INTERRUPTIBLE);
3184 + schedule_timeout(HZ);
3187 + /* Initialize and register HCI device */
3189 + hdev = &(info->hdev);
3191 + hdev->type = HCI_PCCARD;
3192 + hdev->driver_data = info;
3194 + hdev->open = bt3c_hci_open;
3195 + hdev->close = bt3c_hci_close;
3196 + hdev->flush = bt3c_hci_flush;
3197 + hdev->send = bt3c_hci_send_frame;
3198 + hdev->destruct = bt3c_hci_destruct;
3199 + hdev->ioctl = bt3c_hci_ioctl;
3201 + if (hci_register_dev(hdev) < 0) {
3202 + printk(KERN_WARNING "bt3c_cs: Can't register HCI device %s.\n", hdev->name);
3210 +int bt3c_close(bt3c_info_t *info)
3212 + struct hci_dev *hdev = &(info->hdev);
3214 + if (info->link.state & DEV_CONFIG_PENDING)
3217 + bt3c_hci_close(hdev);
3219 + if (hci_unregister_dev(hdev) < 0)
3220 + printk(KERN_WARNING "bt3c_cs: Can't unregister HCI device %s.\n", hdev->name);
3227 +/* ======================== Card services ======================== */
3230 +static void cs_error(client_handle_t handle, int func, int ret)
3232 + error_info_t err = { func, ret };
3234 + CardServices(ReportError, handle, &err);
3238 +dev_link_t *bt3c_attach(void)
3240 + bt3c_info_t *info;
3241 + client_reg_t client_reg;
3245 + /* Create new info device */
3246 + info = kmalloc(sizeof(*info), GFP_KERNEL);
3249 + memset(info, 0, sizeof(*info));
3251 + link = &info->link;
3252 + link->priv = info;
3254 + link->release.function = &bt3c_release;
3255 + link->release.data = (u_long)link;
3256 + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
3257 + link->io.NumPorts1 = 8;
3258 + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
3259 + link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
3261 + if (irq_list[0] == -1)
3262 + link->irq.IRQInfo2 = irq_mask;
3264 + for (i = 0; i < 4; i++)
3265 + link->irq.IRQInfo2 |= 1 << irq_list[i];
3267 + link->irq.Handler = bt3c_interrupt;
3268 + link->irq.Instance = info;
3270 + link->conf.Attributes = CONF_ENABLE_IRQ;
3271 + link->conf.Vcc = 50;
3272 + link->conf.IntType = INT_MEMORY_AND_IO;
3274 + /* Register with Card Services */
3275 + link->next = dev_list;
3277 + client_reg.dev_info = &dev_info;
3278 + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
3279 + client_reg.EventMask =
3280 + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
3281 + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
3282 + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
3283 + client_reg.event_handler = &bt3c_event;
3284 + client_reg.Version = 0x0210;
3285 + client_reg.event_callback_args.client_data = link;
3287 + ret = CardServices(RegisterClient, &link->handle, &client_reg);
3288 + if (ret != CS_SUCCESS) {
3289 + cs_error(link->handle, RegisterClient, ret);
3290 + bt3c_detach(link);
3298 +void bt3c_detach(dev_link_t *link)
3300 + bt3c_info_t *info = link->priv;
3301 + dev_link_t **linkp;
3304 + /* Locate device structure */
3305 + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
3306 + if (*linkp == link)
3309 + if (*linkp == NULL)
3312 + del_timer(&link->release);
3314 + if (link->state & DEV_CONFIG)
3315 + bt3c_release((u_long)link);
3317 + if (link->handle) {
3318 + ret = CardServices(DeregisterClient, link->handle);
3319 + if (ret != CS_SUCCESS)
3320 + cs_error(link->handle, DeregisterClient, ret);
3323 + /* Unlink device structure, free bits */
3324 + *linkp = link->next;
3330 +static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
3334 + i = CardServices(fn, handle, tuple);
3335 + if (i != CS_SUCCESS)
3336 + return CS_NO_MORE_ITEMS;
3338 + i = CardServices(GetTupleData, handle, tuple);
3339 + if (i != CS_SUCCESS)
3342 + return CardServices(ParseTuple, handle, tuple, parse);
3346 +#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
3347 +#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
3349 +void bt3c_config(dev_link_t *link)
3351 + static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
3352 + client_handle_t handle = link->handle;
3353 + bt3c_info_t *info = link->priv;
3357 + cistpl_cftable_entry_t *cf = &parse.cftable_entry;
3358 + config_info_t config;
3359 + int i, j, try, last_ret, last_fn;
3361 + tuple.TupleData = (cisdata_t *)buf;
3362 + tuple.TupleOffset = 0;
3363 + tuple.TupleDataMax = 255;
3364 + tuple.Attributes = 0;
3366 + /* Get configuration register information */
3367 + tuple.DesiredTuple = CISTPL_CONFIG;
3368 + last_ret = first_tuple(handle, &tuple, &parse);
3369 + if (last_ret != CS_SUCCESS) {
3370 + last_fn = ParseTuple;
3373 + link->conf.ConfigBase = parse.config.base;
3374 + link->conf.Present = parse.config.rmask[0];
3376 + /* Configure card */
3377 + link->state |= DEV_CONFIG;
3378 + i = CardServices(GetConfigurationInfo, handle, &config);
3379 + link->conf.Vcc = config.Vcc;
3381 + /* First pass: look for a config entry that looks normal. */
3382 + tuple.TupleData = (cisdata_t *)buf;
3383 + tuple.TupleOffset = 0;
3384 + tuple.TupleDataMax = 255;
3385 + tuple.Attributes = 0;
3386 + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
3387 + /* Two tries: without IO aliases, then with aliases */
3388 + for (try = 0; try < 2; try++) {
3389 + i = first_tuple(handle, &tuple, &parse);
3390 + while (i != CS_NO_MORE_ITEMS) {
3391 + if (i != CS_SUCCESS)
3393 + if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
3394 + link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
3395 + if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
3396 + link->conf.ConfigIndex = cf->index;
3397 + link->io.BasePort1 = cf->io.win[0].base;
3398 + link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
3399 + i = CardServices(RequestIO, link->handle, &link->io);
3400 + if (i == CS_SUCCESS)
3404 + i = next_tuple(handle, &tuple, &parse);
3408 + /* Second pass: try to find an entry that isn't picky about
3409 + its base address, then try to grab any standard serial port
3410 + address, and finally try to get any free port. */
3411 + i = first_tuple(handle, &tuple, &parse);
3412 + while (i != CS_NO_MORE_ITEMS) {
3413 + if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
3414 + link->conf.ConfigIndex = cf->index;
3415 + for (j = 0; j < 5; j++) {
3416 + link->io.BasePort1 = base[j];
3417 + link->io.IOAddrLines = base[j] ? 16 : 3;
3418 + i = CardServices(RequestIO, link->handle, &link->io);
3419 + if (i == CS_SUCCESS)
3423 + i = next_tuple(handle, &tuple, &parse);
3427 + if (i != CS_SUCCESS) {
3428 + printk(KERN_NOTICE "bt3c_cs: No usable port range found. Giving up.\n");
3429 + cs_error(link->handle, RequestIO, i);
3433 + i = CardServices(RequestIRQ, link->handle, &link->irq);
3434 + if (i != CS_SUCCESS) {
3435 + cs_error(link->handle, RequestIRQ, i);
3436 + link->irq.AssignedIRQ = 0;
3439 + i = CardServices(RequestConfiguration, link->handle, &link->conf);
3440 + if (i != CS_SUCCESS) {
3441 + cs_error(link->handle, RequestConfiguration, i);
3445 + MOD_INC_USE_COUNT;
3447 + if (bt3c_open(info) != 0)
3450 + strcpy(info->node.dev_name, info->hdev.name);
3451 + link->dev = &info->node;
3452 + link->state &= ~DEV_CONFIG_PENDING;
3457 + cs_error(link->handle, last_fn, last_ret);
3460 + bt3c_release((u_long)link);
3464 +void bt3c_release(u_long arg)
3466 + dev_link_t *link = (dev_link_t *)arg;
3467 + bt3c_info_t *info = link->priv;
3469 + if (link->state & DEV_PRESENT)
3472 + MOD_DEC_USE_COUNT;
3476 + CardServices(ReleaseConfiguration, link->handle);
3477 + CardServices(ReleaseIO, link->handle, &link->io);
3478 + CardServices(ReleaseIRQ, link->handle, &link->irq);
3480 + link->state &= ~DEV_CONFIG;
3484 +int bt3c_event(event_t event, int priority, event_callback_args_t *args)
3486 + dev_link_t *link = args->client_data;
3487 + bt3c_info_t *info = link->priv;
3490 + case CS_EVENT_CARD_REMOVAL:
3491 + link->state &= ~DEV_PRESENT;
3492 + if (link->state & DEV_CONFIG) {
3494 + mod_timer(&link->release, jiffies + HZ / 20);
3497 + case CS_EVENT_CARD_INSERTION:
3498 + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
3499 + bt3c_config(link);
3501 + case CS_EVENT_PM_SUSPEND:
3502 + link->state |= DEV_SUSPEND;
3503 + /* Fall through... */
3504 + case CS_EVENT_RESET_PHYSICAL:
3505 + if (link->state & DEV_CONFIG)
3506 + CardServices(ReleaseConfiguration, link->handle);
3508 + case CS_EVENT_PM_RESUME:
3509 + link->state &= ~DEV_SUSPEND;
3510 + /* Fall through... */
3511 + case CS_EVENT_CARD_RESET:
3513 + CardServices(RequestConfiguration, link->handle, &link->conf);
3522 +/* ======================== Module initialization ======================== */
3525 +int __init init_bt3c_cs(void)
3530 + CardServices(GetCardServicesInfo, &serv);
3531 + if (serv.Revision != CS_RELEASE_CODE) {
3532 + printk(KERN_NOTICE "bt3c_cs: Card Services release does not match!\n");
3536 + err = register_pccard_driver(&dev_info, &bt3c_attach, &bt3c_detach);
3542 +void __exit exit_bt3c_cs(void)
3544 + unregister_pccard_driver(&dev_info);
3546 + while (dev_list != NULL)
3547 + bt3c_detach(dev_list);
3551 +module_init(init_bt3c_cs);
3552 +module_exit(exit_bt3c_cs);
3555 diff -urN linux-2.4.18/drivers/bluetooth/btuart_cs.c linux-2.4.18-mh15/drivers/bluetooth/btuart_cs.c
3556 --- linux-2.4.18/drivers/bluetooth/btuart_cs.c 1970-01-01 01:00:00.000000000 +0100
3557 +++ linux-2.4.18-mh15/drivers/bluetooth/btuart_cs.c 2004-08-01 16:26:23.000000000 +0200
3561 + * Driver for Bluetooth PCMCIA cards with HCI UART interface
3563 + * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
3566 + * This program is free software; you can redistribute it and/or modify
3567 + * it under the terms of the GNU General Public License version 2 as
3568 + * published by the Free Software Foundation;
3570 + * Software distributed under the License is distributed on an "AS
3571 + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
3572 + * implied. See the License for the specific language governing
3573 + * rights and limitations under the License.
3575 + * The initial developer of the original code is David A. Hinds
3576 + * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
3577 + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
3581 +#include <linux/config.h>
3582 +#include <linux/module.h>
3584 +#include <linux/kernel.h>
3585 +#include <linux/init.h>
3586 +#include <linux/slab.h>
3587 +#include <linux/types.h>
3588 +#include <linux/sched.h>
3589 +#include <linux/timer.h>
3590 +#include <linux/errno.h>
3591 +#include <linux/ptrace.h>
3592 +#include <linux/ioport.h>
3593 +#include <linux/spinlock.h>
3595 +#include <linux/skbuff.h>
3596 +#include <linux/string.h>
3597 +#include <linux/serial.h>
3598 +#include <linux/serial_reg.h>
3599 +#include <asm/system.h>
3600 +#include <asm/bitops.h>
3601 +#include <asm/io.h>
3603 +#include <pcmcia/version.h>
3604 +#include <pcmcia/cs_types.h>
3605 +#include <pcmcia/cs.h>
3606 +#include <pcmcia/cistpl.h>
3607 +#include <pcmcia/ciscode.h>
3608 +#include <pcmcia/ds.h>
3609 +#include <pcmcia/cisreg.h>
3611 +#include <net/bluetooth/bluetooth.h>
3612 +#include <net/bluetooth/hci_core.h>
3616 +/* ======================== Module parameters ======================== */
3619 +/* Bit map of interrupts to choose from */
3620 +static u_int irq_mask = 0xffff;
3621 +static int irq_list[4] = { -1 };
3623 +MODULE_PARM(irq_mask, "i");
3624 +MODULE_PARM(irq_list, "1-4i");
3626 +MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
3627 +MODULE_DESCRIPTION("BlueZ driver for Bluetooth PCMCIA cards with HCI UART interface");
3628 +MODULE_LICENSE("GPL");
3632 +/* ======================== Local structures ======================== */
3635 +typedef struct btuart_info_t {
3639 + struct hci_dev hdev;
3641 + spinlock_t lock; /* For serializing operations */
3643 + struct sk_buff_head txq;
3644 + unsigned long tx_state;
3646 + unsigned long rx_state;
3647 + unsigned long rx_count;
3648 + struct sk_buff *rx_skb;
3652 +void btuart_config(dev_link_t *link);
3653 +void btuart_release(u_long arg);
3654 +int btuart_event(event_t event, int priority, event_callback_args_t *args);
3656 +static dev_info_t dev_info = "btuart_cs";
3658 +dev_link_t *btuart_attach(void);
3659 +void btuart_detach(dev_link_t *);
3661 +static dev_link_t *dev_list = NULL;
3664 +/* Maximum baud rate */
3665 +#define SPEED_MAX 115200
3667 +/* Default baud rate: 57600, 115200, 230400 or 460800 */
3668 +#define DEFAULT_BAUD_RATE 115200
3671 +/* Transmit states */
3672 +#define XMIT_SENDING 1
3673 +#define XMIT_WAKEUP 2
3674 +#define XMIT_WAITING 8
3676 +/* Receiver states */
3677 +#define RECV_WAIT_PACKET_TYPE 0
3678 +#define RECV_WAIT_EVENT_HEADER 1
3679 +#define RECV_WAIT_ACL_HEADER 2
3680 +#define RECV_WAIT_SCO_HEADER 3
3681 +#define RECV_WAIT_DATA 4
3685 +/* ======================== Interrupt handling ======================== */
3688 +static int btuart_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
3692 + /* Tx FIFO should be empty */
3693 + if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
3696 + /* Fill FIFO with current frame */
3697 + while ((fifo_size-- > 0) && (actual < len)) {
3698 + /* Transmit next byte */
3699 + outb(buf[actual], iobase + UART_TX);
3707 +static void btuart_write_wakeup(btuart_info_t *info)
3710 + printk(KERN_WARNING "btuart_cs: Call of write_wakeup for unknown device.\n");
3714 + if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
3715 + set_bit(XMIT_WAKEUP, &(info->tx_state));
3720 + register unsigned int iobase = info->link.io.BasePort1;
3721 + register struct sk_buff *skb;
3724 + clear_bit(XMIT_WAKEUP, &(info->tx_state));
3726 + if (!(info->link.state & DEV_PRESENT))
3729 + if (!(skb = skb_dequeue(&(info->txq))))
3733 + len = btuart_write(iobase, 16, skb->data, skb->len);
3734 + set_bit(XMIT_WAKEUP, &(info->tx_state));
3736 + if (len == skb->len) {
3739 + skb_pull(skb, len);
3740 + skb_queue_head(&(info->txq), skb);
3743 + info->hdev.stat.byte_tx += len;
3745 + } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
3747 + clear_bit(XMIT_SENDING, &(info->tx_state));
3751 +static void btuart_receive(btuart_info_t *info)
3753 + unsigned int iobase;
3754 + int boguscount = 0;
3757 + printk(KERN_WARNING "btuart_cs: Call of receive for unknown device.\n");
3761 + iobase = info->link.io.BasePort1;
3764 + info->hdev.stat.byte_rx++;
3766 + /* Allocate packet */
3767 + if (info->rx_skb == NULL) {
3768 + info->rx_state = RECV_WAIT_PACKET_TYPE;
3769 + info->rx_count = 0;
3770 + if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
3771 + printk(KERN_WARNING "btuart_cs: Can't allocate mem for new packet.\n");
3776 + if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
3778 + info->rx_skb->dev = (void *)&(info->hdev);
3779 + info->rx_skb->pkt_type = inb(iobase + UART_RX);
3781 + switch (info->rx_skb->pkt_type) {
3783 + case HCI_EVENT_PKT:
3784 + info->rx_state = RECV_WAIT_EVENT_HEADER;
3785 + info->rx_count = HCI_EVENT_HDR_SIZE;
3788 + case HCI_ACLDATA_PKT:
3789 + info->rx_state = RECV_WAIT_ACL_HEADER;
3790 + info->rx_count = HCI_ACL_HDR_SIZE;
3793 + case HCI_SCODATA_PKT:
3794 + info->rx_state = RECV_WAIT_SCO_HEADER;
3795 + info->rx_count = HCI_SCO_HDR_SIZE;
3799 + /* Unknown packet */
3800 + printk(KERN_WARNING "btuart_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
3801 + info->hdev.stat.err_rx++;
3802 + clear_bit(HCI_RUNNING, &(info->hdev.flags));
3804 + kfree_skb(info->rx_skb);
3805 + info->rx_skb = NULL;
3812 + *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
3815 + if (info->rx_count == 0) {
3818 + hci_event_hdr *eh;
3823 + switch (info->rx_state) {
3825 + case RECV_WAIT_EVENT_HEADER:
3826 + eh = (hci_event_hdr *)(info->rx_skb->data);
3827 + info->rx_state = RECV_WAIT_DATA;
3828 + info->rx_count = eh->plen;
3831 + case RECV_WAIT_ACL_HEADER:
3832 + ah = (hci_acl_hdr *)(info->rx_skb->data);
3833 + dlen = __le16_to_cpu(ah->dlen);
3834 + info->rx_state = RECV_WAIT_DATA;
3835 + info->rx_count = dlen;
3838 + case RECV_WAIT_SCO_HEADER:
3839 + sh = (hci_sco_hdr *)(info->rx_skb->data);
3840 + info->rx_state = RECV_WAIT_DATA;
3841 + info->rx_count = sh->dlen;
3844 + case RECV_WAIT_DATA:
3845 + hci_recv_frame(info->rx_skb);
3846 + info->rx_skb = NULL;
3855 + /* Make sure we don't stay here to long */
3856 + if (boguscount++ > 16)
3859 + } while (inb(iobase + UART_LSR) & UART_LSR_DR);
3863 +void btuart_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
3865 + btuart_info_t *info = dev_inst;
3866 + unsigned int iobase;
3867 + int boguscount = 0;
3871 + printk(KERN_WARNING "btuart_cs: Call of irq %d for unknown device.\n", irq);
3875 + iobase = info->link.io.BasePort1;
3877 + spin_lock(&(info->lock));
3879 + iir = inb(iobase + UART_IIR) & UART_IIR_ID;
3882 + /* Clear interrupt */
3883 + lsr = inb(iobase + UART_LSR);
3886 + case UART_IIR_RLSI:
3887 + printk(KERN_NOTICE "btuart_cs: RLSI\n");
3889 + case UART_IIR_RDI:
3890 + /* Receive interrupt */
3891 + btuart_receive(info);
3893 + case UART_IIR_THRI:
3894 + if (lsr & UART_LSR_THRE) {
3895 + /* Transmitter ready for data */
3896 + btuart_write_wakeup(info);
3900 + printk(KERN_NOTICE "btuart_cs: Unhandled IIR=%#x\n", iir);
3904 + /* Make sure we don't stay here to long */
3905 + if (boguscount++ > 100)
3908 + iir = inb(iobase + UART_IIR) & UART_IIR_ID;
3912 + spin_unlock(&(info->lock));
3916 +static void btuart_change_speed(btuart_info_t *info, unsigned int speed)
3918 + unsigned long flags;
3919 + unsigned int iobase;
3920 + int fcr; /* FIFO control reg */
3921 + int lcr; /* Line control reg */
3925 + printk(KERN_WARNING "btuart_cs: Call of change speed for unknown device.\n");
3929 + iobase = info->link.io.BasePort1;
3931 + spin_lock_irqsave(&(info->lock), flags);
3933 + /* Turn off interrupts */
3934 + outb(0, iobase + UART_IER);
3936 + divisor = SPEED_MAX / speed;
3938 + fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT;
3941 + * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and
3942 + * almost 1,7 ms at 19200 bps. At speeds above that we can just forget
3943 + * about this timeout since it will always be fast enough.
3946 + if (speed < 38400)
3947 + fcr |= UART_FCR_TRIGGER_1;
3949 + fcr |= UART_FCR_TRIGGER_14;
3951 + /* Bluetooth cards use 8N1 */
3952 + lcr = UART_LCR_WLEN8;
3954 + outb(UART_LCR_DLAB | lcr, iobase + UART_LCR); /* Set DLAB */
3955 + outb(divisor & 0xff, iobase + UART_DLL); /* Set speed */
3956 + outb(divisor >> 8, iobase + UART_DLM);
3957 + outb(lcr, iobase + UART_LCR); /* Set 8N1 */
3958 + outb(fcr, iobase + UART_FCR); /* Enable FIFO's */
3960 + /* Turn on interrups */
3961 + outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
3963 + spin_unlock_irqrestore(&(info->lock), flags);
3968 +/* ======================== HCI interface ======================== */
3971 +static int btuart_hci_flush(struct hci_dev *hdev)
3973 + btuart_info_t *info = (btuart_info_t *)(hdev->driver_data);
3975 + /* Drop TX queue */
3976 + skb_queue_purge(&(info->txq));
3982 +static int btuart_hci_open(struct hci_dev *hdev)
3984 + set_bit(HCI_RUNNING, &(hdev->flags));
3990 +static int btuart_hci_close(struct hci_dev *hdev)
3992 + if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
3995 + btuart_hci_flush(hdev);
4001 +static int btuart_hci_send_frame(struct sk_buff *skb)
4003 + btuart_info_t *info;
4004 + struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
4007 + printk(KERN_WARNING "btuart_cs: Frame for unknown HCI device (hdev=NULL).");
4011 + info = (btuart_info_t *)(hdev->driver_data);
4013 + switch (skb->pkt_type) {
4014 + case HCI_COMMAND_PKT:
4015 + hdev->stat.cmd_tx++;
4017 + case HCI_ACLDATA_PKT:
4018 + hdev->stat.acl_tx++;
4020 + case HCI_SCODATA_PKT:
4021 + hdev->stat.sco_tx++;
4025 + /* Prepend skb with frame type */
4026 + memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
4027 + skb_queue_tail(&(info->txq), skb);
4029 + btuart_write_wakeup(info);
4035 +static void btuart_hci_destruct(struct hci_dev *hdev)
4040 +static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
4042 + return -ENOIOCTLCMD;
4047 +/* ======================== Card services HCI interaction ======================== */
4050 +int btuart_open(btuart_info_t *info)
4052 + unsigned long flags;
4053 + unsigned int iobase = info->link.io.BasePort1;
4054 + struct hci_dev *hdev;
4056 + spin_lock_init(&(info->lock));
4058 + skb_queue_head_init(&(info->txq));
4060 + info->rx_state = RECV_WAIT_PACKET_TYPE;
4061 + info->rx_count = 0;
4062 + info->rx_skb = NULL;
4064 + spin_lock_irqsave(&(info->lock), flags);
4067 + outb(0, iobase + UART_MCR);
4069 + /* Turn off interrupts */
4070 + outb(0, iobase + UART_IER);
4072 + /* Initialize UART */
4073 + outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
4074 + outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
4076 + /* Turn on interrupts */
4077 + // outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
4079 + spin_unlock_irqrestore(&(info->lock), flags);
4081 + btuart_change_speed(info, DEFAULT_BAUD_RATE);
4083 + /* Timeout before it is safe to send the first HCI packet */
4084 + set_current_state(TASK_INTERRUPTIBLE);
4085 + schedule_timeout(HZ);
4088 + /* Initialize and register HCI device */
4090 + hdev = &(info->hdev);
4092 + hdev->type = HCI_PCCARD;
4093 + hdev->driver_data = info;
4095 + hdev->open = btuart_hci_open;
4096 + hdev->close = btuart_hci_close;
4097 + hdev->flush = btuart_hci_flush;
4098 + hdev->send = btuart_hci_send_frame;
4099 + hdev->destruct = btuart_hci_destruct;
4100 + hdev->ioctl = btuart_hci_ioctl;
4102 + if (hci_register_dev(hdev) < 0) {
4103 + printk(KERN_WARNING "btuart_cs: Can't register HCI device %s.\n", hdev->name);
4111 +int btuart_close(btuart_info_t *info)
4113 + unsigned long flags;
4114 + unsigned int iobase = info->link.io.BasePort1;
4115 + struct hci_dev *hdev = &(info->hdev);
4117 + if (info->link.state & DEV_CONFIG_PENDING)
4120 + btuart_hci_close(hdev);
4122 + spin_lock_irqsave(&(info->lock), flags);
4125 + outb(0, iobase + UART_MCR);
4127 + /* Turn off interrupts */
4128 + outb(0, iobase + UART_IER);
4130 + spin_unlock_irqrestore(&(info->lock), flags);
4132 + if (hci_unregister_dev(hdev) < 0)
4133 + printk(KERN_WARNING "btuart_cs: Can't unregister HCI device %s.\n", hdev->name);
4140 +/* ======================== Card services ======================== */
4143 +static void cs_error(client_handle_t handle, int func, int ret)
4145 + error_info_t err = { func, ret };
4147 + CardServices(ReportError, handle, &err);
4151 +dev_link_t *btuart_attach(void)
4153 + btuart_info_t *info;
4154 + client_reg_t client_reg;
4158 + /* Create new info device */
4159 + info = kmalloc(sizeof(*info), GFP_KERNEL);
4162 + memset(info, 0, sizeof(*info));
4164 + link = &info->link;
4165 + link->priv = info;
4167 + link->release.function = &btuart_release;
4168 + link->release.data = (u_long)link;
4169 + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
4170 + link->io.NumPorts1 = 8;
4171 + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
4172 + link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
4174 + if (irq_list[0] == -1)
4175 + link->irq.IRQInfo2 = irq_mask;
4177 + for (i = 0; i < 4; i++)
4178 + link->irq.IRQInfo2 |= 1 << irq_list[i];
4180 + link->irq.Handler = btuart_interrupt;
4181 + link->irq.Instance = info;
4183 + link->conf.Attributes = CONF_ENABLE_IRQ;
4184 + link->conf.Vcc = 50;
4185 + link->conf.IntType = INT_MEMORY_AND_IO;
4187 + /* Register with Card Services */
4188 + link->next = dev_list;
4190 + client_reg.dev_info = &dev_info;
4191 + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
4192 + client_reg.EventMask =
4193 + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
4194 + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
4195 + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
4196 + client_reg.event_handler = &btuart_event;
4197 + client_reg.Version = 0x0210;
4198 + client_reg.event_callback_args.client_data = link;
4200 + ret = CardServices(RegisterClient, &link->handle, &client_reg);
4201 + if (ret != CS_SUCCESS) {
4202 + cs_error(link->handle, RegisterClient, ret);
4203 + btuart_detach(link);
4211 +void btuart_detach(dev_link_t *link)
4213 + btuart_info_t *info = link->priv;
4214 + dev_link_t **linkp;
4217 + /* Locate device structure */
4218 + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
4219 + if (*linkp == link)
4222 + if (*linkp == NULL)
4225 + del_timer(&link->release);
4226 + if (link->state & DEV_CONFIG)
4227 + btuart_release((u_long)link);
4229 + if (link->handle) {
4230 + ret = CardServices(DeregisterClient, link->handle);
4231 + if (ret != CS_SUCCESS)
4232 + cs_error(link->handle, DeregisterClient, ret);
4235 + /* Unlink device structure, free bits */
4236 + *linkp = link->next;
4242 +static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
4246 + i = CardServices(fn, handle, tuple);
4247 + if (i != CS_SUCCESS)
4248 + return CS_NO_MORE_ITEMS;
4250 + i = CardServices(GetTupleData, handle, tuple);
4251 + if (i != CS_SUCCESS)
4254 + return CardServices(ParseTuple, handle, tuple, parse);
4258 +#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
4259 +#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
4261 +void btuart_config(dev_link_t *link)
4263 + static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
4264 + client_handle_t handle = link->handle;
4265 + btuart_info_t *info = link->priv;
4269 + cistpl_cftable_entry_t *cf = &parse.cftable_entry;
4270 + config_info_t config;
4271 + int i, j, try, last_ret, last_fn;
4273 + tuple.TupleData = (cisdata_t *)buf;
4274 + tuple.TupleOffset = 0;
4275 + tuple.TupleDataMax = 255;
4276 + tuple.Attributes = 0;
4278 + /* Get configuration register information */
4279 + tuple.DesiredTuple = CISTPL_CONFIG;
4280 + last_ret = first_tuple(handle, &tuple, &parse);
4281 + if (last_ret != CS_SUCCESS) {
4282 + last_fn = ParseTuple;
4285 + link->conf.ConfigBase = parse.config.base;
4286 + link->conf.Present = parse.config.rmask[0];
4288 + /* Configure card */
4289 + link->state |= DEV_CONFIG;
4290 + i = CardServices(GetConfigurationInfo, handle, &config);
4291 + link->conf.Vcc = config.Vcc;
4293 + /* First pass: look for a config entry that looks normal. */
4294 + tuple.TupleData = (cisdata_t *) buf;
4295 + tuple.TupleOffset = 0;
4296 + tuple.TupleDataMax = 255;
4297 + tuple.Attributes = 0;
4298 + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
4299 + /* Two tries: without IO aliases, then with aliases */
4300 + for (try = 0; try < 2; try++) {
4301 + i = first_tuple(handle, &tuple, &parse);
4302 + while (i != CS_NO_MORE_ITEMS) {
4303 + if (i != CS_SUCCESS)
4305 + if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
4306 + link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
4307 + if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
4308 + link->conf.ConfigIndex = cf->index;
4309 + link->io.BasePort1 = cf->io.win[0].base;
4310 + link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
4311 + i = CardServices(RequestIO, link->handle, &link->io);
4312 + if (i == CS_SUCCESS)
4316 + i = next_tuple(handle, &tuple, &parse);
4320 + /* Second pass: try to find an entry that isn't picky about
4321 + its base address, then try to grab any standard serial port
4322 + address, and finally try to get any free port. */
4323 + i = first_tuple(handle, &tuple, &parse);
4324 + while (i != CS_NO_MORE_ITEMS) {
4325 + if ((i == CS_SUCCESS) && (cf->io.nwin > 0)
4326 + && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
4327 + link->conf.ConfigIndex = cf->index;
4328 + for (j = 0; j < 5; j++) {
4329 + link->io.BasePort1 = base[j];
4330 + link->io.IOAddrLines = base[j] ? 16 : 3;
4331 + i = CardServices(RequestIO, link->handle, &link->io);
4332 + if (i == CS_SUCCESS)
4336 + i = next_tuple(handle, &tuple, &parse);
4340 + if (i != CS_SUCCESS) {
4341 + printk(KERN_NOTICE "btuart_cs: No usable port range found. Giving up.\n");
4342 + cs_error(link->handle, RequestIO, i);
4346 + i = CardServices(RequestIRQ, link->handle, &link->irq);
4347 + if (i != CS_SUCCESS) {
4348 + cs_error(link->handle, RequestIRQ, i);
4349 + link->irq.AssignedIRQ = 0;
4352 + i = CardServices(RequestConfiguration, link->handle, &link->conf);
4353 + if (i != CS_SUCCESS) {
4354 + cs_error(link->handle, RequestConfiguration, i);
4358 + MOD_INC_USE_COUNT;
4360 + if (btuart_open(info) != 0)
4363 + strcpy(info->node.dev_name, info->hdev.name);
4364 + link->dev = &info->node;
4365 + link->state &= ~DEV_CONFIG_PENDING;
4370 + cs_error(link->handle, last_fn, last_ret);
4373 + btuart_release((u_long) link);
4377 +void btuart_release(u_long arg)
4379 + dev_link_t *link = (dev_link_t *)arg;
4380 + btuart_info_t *info = link->priv;
4382 + if (link->state & DEV_PRESENT)
4383 + btuart_close(info);
4385 + MOD_DEC_USE_COUNT;
4389 + CardServices(ReleaseConfiguration, link->handle);
4390 + CardServices(ReleaseIO, link->handle, &link->io);
4391 + CardServices(ReleaseIRQ, link->handle, &link->irq);
4393 + link->state &= ~DEV_CONFIG;
4397 +int btuart_event(event_t event, int priority, event_callback_args_t *args)
4399 + dev_link_t *link = args->client_data;
4400 + btuart_info_t *info = link->priv;
4403 + case CS_EVENT_CARD_REMOVAL:
4404 + link->state &= ~DEV_PRESENT;
4405 + if (link->state & DEV_CONFIG) {
4406 + btuart_close(info);
4407 + mod_timer(&link->release, jiffies + HZ / 20);
4410 + case CS_EVENT_CARD_INSERTION:
4411 + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
4412 + btuart_config(link);
4414 + case CS_EVENT_PM_SUSPEND:
4415 + link->state |= DEV_SUSPEND;
4416 + /* Fall through... */
4417 + case CS_EVENT_RESET_PHYSICAL:
4418 + if (link->state & DEV_CONFIG)
4419 + CardServices(ReleaseConfiguration, link->handle);
4421 + case CS_EVENT_PM_RESUME:
4422 + link->state &= ~DEV_SUSPEND;
4423 + /* Fall through... */
4424 + case CS_EVENT_CARD_RESET:
4426 + CardServices(RequestConfiguration, link->handle, &link->conf);
4435 +/* ======================== Module initialization ======================== */
4438 +int __init init_btuart_cs(void)
4443 + CardServices(GetCardServicesInfo, &serv);
4444 + if (serv.Revision != CS_RELEASE_CODE) {
4445 + printk(KERN_NOTICE "btuart_cs: Card Services release does not match!\n");
4449 + err = register_pccard_driver(&dev_info, &btuart_attach, &btuart_detach);
4455 +void __exit exit_btuart_cs(void)
4457 + unregister_pccard_driver(&dev_info);
4459 + while (dev_list != NULL)
4460 + btuart_detach(dev_list);
4464 +module_init(init_btuart_cs);
4465 +module_exit(exit_btuart_cs);
4468 diff -urN linux-2.4.18/drivers/bluetooth/Config.in linux-2.4.18-mh15/drivers/bluetooth/Config.in
4469 --- linux-2.4.18/drivers/bluetooth/Config.in 2001-09-07 18:28:38.000000000 +0200
4470 +++ linux-2.4.18-mh15/drivers/bluetooth/Config.in 2004-08-01 16:26:23.000000000 +0200
4473 +# Bluetooth HCI device drivers configuration
4476 mainmenu_option next_comment
4477 comment 'Bluetooth device drivers'
4479 dep_tristate 'HCI USB driver' CONFIG_BLUEZ_HCIUSB $CONFIG_BLUEZ $CONFIG_USB
4480 +if [ "$CONFIG_BLUEZ_HCIUSB" != "n" ]; then
4481 + bool ' SCO (voice) support' CONFIG_BLUEZ_HCIUSB_SCO
4484 dep_tristate 'HCI UART driver' CONFIG_BLUEZ_HCIUART $CONFIG_BLUEZ
4485 -dep_tristate 'HCI VHCI virtual HCI device driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
4486 +if [ "$CONFIG_BLUEZ_HCIUART" != "n" ]; then
4487 + bool ' UART (H4) protocol support' CONFIG_BLUEZ_HCIUART_H4
4488 + bool ' BCSP protocol support' CONFIG_BLUEZ_HCIUART_BCSP
4489 + dep_bool ' Transmit CRC with every BCSP packet' CONFIG_BLUEZ_HCIUART_BCSP_TXCRC $CONFIG_BLUEZ_HCIUART_BCSP
4492 +dep_tristate 'HCI BlueFRITZ! USB driver' CONFIG_BLUEZ_HCIBFUSB $CONFIG_BLUEZ $CONFIG_USB
4494 +dep_tristate 'HCI DTL1 (PC Card) driver' CONFIG_BLUEZ_HCIDTL1 $CONFIG_PCMCIA $CONFIG_BLUEZ
4496 +dep_tristate 'HCI BT3C (PC Card) driver' CONFIG_BLUEZ_HCIBT3C $CONFIG_PCMCIA $CONFIG_BLUEZ
4498 +dep_tristate 'HCI BlueCard (PC Card) driver' CONFIG_BLUEZ_HCIBLUECARD $CONFIG_PCMCIA $CONFIG_BLUEZ
4500 +dep_tristate 'HCI UART (PC Card) driver' CONFIG_BLUEZ_HCIBTUART $CONFIG_PCMCIA $CONFIG_BLUEZ
4502 +dep_tristate 'HCI VHCI (Virtual HCI device) driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
4506 diff -urN linux-2.4.18/drivers/bluetooth/dtl1_cs.c linux-2.4.18-mh15/drivers/bluetooth/dtl1_cs.c
4507 --- linux-2.4.18/drivers/bluetooth/dtl1_cs.c 1970-01-01 01:00:00.000000000 +0100
4508 +++ linux-2.4.18-mh15/drivers/bluetooth/dtl1_cs.c 2004-08-01 16:26:23.000000000 +0200
4512 + * A driver for Nokia Connectivity Card DTL-1 devices
4514 + * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
4517 + * This program is free software; you can redistribute it and/or modify
4518 + * it under the terms of the GNU General Public License version 2 as
4519 + * published by the Free Software Foundation;
4521 + * Software distributed under the License is distributed on an "AS
4522 + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
4523 + * implied. See the License for the specific language governing
4524 + * rights and limitations under the License.
4526 + * The initial developer of the original code is David A. Hinds
4527 + * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
4528 + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
4532 +#include <linux/config.h>
4533 +#include <linux/module.h>
4535 +#include <linux/kernel.h>
4536 +#include <linux/init.h>
4537 +#include <linux/slab.h>
4538 +#include <linux/types.h>
4539 +#include <linux/sched.h>
4540 +#include <linux/timer.h>
4541 +#include <linux/errno.h>
4542 +#include <linux/ptrace.h>
4543 +#include <linux/ioport.h>
4544 +#include <linux/spinlock.h>
4546 +#include <linux/skbuff.h>
4547 +#include <linux/string.h>
4548 +#include <linux/serial.h>
4549 +#include <linux/serial_reg.h>
4550 +#include <asm/system.h>
4551 +#include <asm/bitops.h>
4552 +#include <asm/io.h>
4554 +#include <pcmcia/version.h>
4555 +#include <pcmcia/cs_types.h>
4556 +#include <pcmcia/cs.h>
4557 +#include <pcmcia/cistpl.h>
4558 +#include <pcmcia/ciscode.h>
4559 +#include <pcmcia/ds.h>
4560 +#include <pcmcia/cisreg.h>
4562 +#include <net/bluetooth/bluetooth.h>
4563 +#include <net/bluetooth/hci_core.h>
4567 +/* ======================== Module parameters ======================== */
4570 +/* Bit map of interrupts to choose from */
4571 +static u_int irq_mask = 0xffff;
4572 +static int irq_list[4] = { -1 };
4574 +MODULE_PARM(irq_mask, "i");
4575 +MODULE_PARM(irq_list, "1-4i");
4577 +MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
4578 +MODULE_DESCRIPTION("BlueZ driver for Nokia Connectivity Card DTL-1");
4579 +MODULE_LICENSE("GPL");
4583 +/* ======================== Local structures ======================== */
4586 +typedef struct dtl1_info_t {
4590 + struct hci_dev hdev;
4592 + spinlock_t lock; /* For serializing operations */
4594 + unsigned long flowmask; /* HCI flow mask */
4597 + struct sk_buff_head txq;
4598 + unsigned long tx_state;
4600 + unsigned long rx_state;
4601 + unsigned long rx_count;
4602 + struct sk_buff *rx_skb;
4606 +void dtl1_config(dev_link_t *link);
4607 +void dtl1_release(u_long arg);
4608 +int dtl1_event(event_t event, int priority, event_callback_args_t *args);
4610 +static dev_info_t dev_info = "dtl1_cs";
4612 +dev_link_t *dtl1_attach(void);
4613 +void dtl1_detach(dev_link_t *);
4615 +static dev_link_t *dev_list = NULL;
4618 +/* Transmit states */
4619 +#define XMIT_SENDING 1
4620 +#define XMIT_WAKEUP 2
4621 +#define XMIT_WAITING 8
4623 +/* Receiver States */
4624 +#define RECV_WAIT_NSH 0
4625 +#define RECV_WAIT_DATA 1
4632 +} __attribute__ ((packed)) nsh_t; /* Nokia Specific Header */
4634 +#define NSHL 4 /* Nokia Specific Header Length */
4638 +/* ======================== Interrupt handling ======================== */
4641 +static int dtl1_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
4645 + /* Tx FIFO should be empty */
4646 + if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
4649 + /* Fill FIFO with current frame */
4650 + while ((fifo_size-- > 0) && (actual < len)) {
4651 + /* Transmit next byte */
4652 + outb(buf[actual], iobase + UART_TX);
4660 +static void dtl1_write_wakeup(dtl1_info_t *info)
4663 + printk(KERN_WARNING "dtl1_cs: Call of write_wakeup for unknown device.\n");
4667 + if (test_bit(XMIT_WAITING, &(info->tx_state))) {
4668 + set_bit(XMIT_WAKEUP, &(info->tx_state));
4672 + if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
4673 + set_bit(XMIT_WAKEUP, &(info->tx_state));
4678 + register unsigned int iobase = info->link.io.BasePort1;
4679 + register struct sk_buff *skb;
4682 + clear_bit(XMIT_WAKEUP, &(info->tx_state));
4684 + if (!(info->link.state & DEV_PRESENT))
4687 + if (!(skb = skb_dequeue(&(info->txq))))
4691 + len = dtl1_write(iobase, 32, skb->data, skb->len);
4693 + if (len == skb->len) {
4694 + set_bit(XMIT_WAITING, &(info->tx_state));
4697 + skb_pull(skb, len);
4698 + skb_queue_head(&(info->txq), skb);
4701 + info->hdev.stat.byte_tx += len;
4703 + } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
4705 + clear_bit(XMIT_SENDING, &(info->tx_state));
4709 +static void dtl1_control(dtl1_info_t *info, struct sk_buff *skb)
4711 + u8 flowmask = *(u8 *)skb->data;
4714 + printk(KERN_INFO "dtl1_cs: Nokia control data = ");
4715 + for (i = 0; i < skb->len; i++) {
4716 + printk("%02x ", skb->data[i]);
4720 + /* transition to active state */
4721 + if (((info->flowmask & 0x07) == 0) && ((flowmask & 0x07) != 0)) {
4722 + clear_bit(XMIT_WAITING, &(info->tx_state));
4723 + dtl1_write_wakeup(info);
4726 + info->flowmask = flowmask;
4732 +static void dtl1_receive(dtl1_info_t *info)
4734 + unsigned int iobase;
4736 + int boguscount = 0;
4739 + printk(KERN_WARNING "dtl1_cs: Call of receive for unknown device.\n");
4743 + iobase = info->link.io.BasePort1;
4746 + info->hdev.stat.byte_rx++;
4748 + /* Allocate packet */
4749 + if (info->rx_skb == NULL)
4750 + if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
4751 + printk(KERN_WARNING "dtl1_cs: Can't allocate mem for new packet.\n");
4752 + info->rx_state = RECV_WAIT_NSH;
4753 + info->rx_count = NSHL;
4757 + *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
4758 + nsh = (nsh_t *)info->rx_skb->data;
4762 + if (info->rx_count == 0) {
4764 + switch (info->rx_state) {
4765 + case RECV_WAIT_NSH:
4766 + info->rx_state = RECV_WAIT_DATA;
4767 + info->rx_count = nsh->len + (nsh->len & 0x0001);
4769 + case RECV_WAIT_DATA:
4770 + info->rx_skb->pkt_type = nsh->type;
4772 + /* remove PAD byte if it exists */
4773 + if (nsh->len & 0x0001) {
4774 + info->rx_skb->tail--;
4775 + info->rx_skb->len--;
4779 + skb_pull(info->rx_skb, NSHL);
4781 + switch (info->rx_skb->pkt_type) {
4783 + /* control data for the Nokia Card */
4784 + dtl1_control(info, info->rx_skb);
4789 + /* send frame to the HCI layer */
4790 + info->rx_skb->dev = (void *)&(info->hdev);
4791 + info->rx_skb->pkt_type &= 0x0f;
4792 + hci_recv_frame(info->rx_skb);
4795 + /* unknown packet */
4796 + printk(KERN_WARNING "dtl1_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
4797 + kfree_skb(info->rx_skb);
4801 + info->rx_state = RECV_WAIT_NSH;
4802 + info->rx_count = NSHL;
4803 + info->rx_skb = NULL;
4809 + /* Make sure we don't stay here to long */
4810 + if (boguscount++ > 32)
4813 + } while (inb(iobase + UART_LSR) & UART_LSR_DR);
4817 +void dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
4819 + dtl1_info_t *info = dev_inst;
4820 + unsigned int iobase;
4821 + unsigned char msr;
4822 + int boguscount = 0;
4826 + printk(KERN_WARNING "dtl1_cs: Call of irq %d for unknown device.\n", irq);
4830 + iobase = info->link.io.BasePort1;
4832 + spin_lock(&(info->lock));
4834 + iir = inb(iobase + UART_IIR) & UART_IIR_ID;
4837 + /* Clear interrupt */
4838 + lsr = inb(iobase + UART_LSR);
4841 + case UART_IIR_RLSI:
4842 + printk(KERN_NOTICE "dtl1_cs: RLSI\n");
4844 + case UART_IIR_RDI:
4845 + /* Receive interrupt */
4846 + dtl1_receive(info);
4848 + case UART_IIR_THRI:
4849 + if (lsr & UART_LSR_THRE) {
4850 + /* Transmitter ready for data */
4851 + dtl1_write_wakeup(info);
4855 + printk(KERN_NOTICE "dtl1_cs: Unhandled IIR=%#x\n", iir);
4859 + /* Make sure we don't stay here to long */
4860 + if (boguscount++ > 100)
4863 + iir = inb(iobase + UART_IIR) & UART_IIR_ID;
4867 + msr = inb(iobase + UART_MSR);
4869 + if (info->ri_latch ^ (msr & UART_MSR_RI)) {
4870 + info->ri_latch = msr & UART_MSR_RI;
4871 + clear_bit(XMIT_WAITING, &(info->tx_state));
4872 + dtl1_write_wakeup(info);
4875 + spin_unlock(&(info->lock));
4880 +/* ======================== HCI interface ======================== */
4883 +static int dtl1_hci_open(struct hci_dev *hdev)
4885 + set_bit(HCI_RUNNING, &(hdev->flags));
4891 +static int dtl1_hci_flush(struct hci_dev *hdev)
4893 + dtl1_info_t *info = (dtl1_info_t *)(hdev->driver_data);
4895 + /* Drop TX queue */
4896 + skb_queue_purge(&(info->txq));
4902 +static int dtl1_hci_close(struct hci_dev *hdev)
4904 + if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
4907 + dtl1_hci_flush(hdev);
4913 +static int dtl1_hci_send_frame(struct sk_buff *skb)
4915 + dtl1_info_t *info;
4916 + struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
4917 + struct sk_buff *s;
4921 + printk(KERN_WARNING "dtl1_cs: Frame for unknown HCI device (hdev=NULL).");
4925 + info = (dtl1_info_t *)(hdev->driver_data);
4927 + switch (skb->pkt_type) {
4928 + case HCI_COMMAND_PKT:
4929 + hdev->stat.cmd_tx++;
4932 + case HCI_ACLDATA_PKT:
4933 + hdev->stat.acl_tx++;
4936 + case HCI_SCODATA_PKT:
4937 + hdev->stat.sco_tx++;
4943 + nsh.len = skb->len;
4945 + s = bluez_skb_alloc(NSHL + skb->len + 1, GFP_ATOMIC);
4946 + skb_reserve(s, NSHL);
4947 + memcpy(skb_put(s, skb->len), skb->data, skb->len);
4948 + if (skb->len & 0x0001)
4949 + *skb_put(s, 1) = 0; /* PAD */
4951 + /* Prepend skb with Nokia frame header and queue */
4952 + memcpy(skb_push(s, NSHL), &nsh, NSHL);
4953 + skb_queue_tail(&(info->txq), s);
4955 + dtl1_write_wakeup(info);
4963 +static void dtl1_hci_destruct(struct hci_dev *hdev)
4968 +static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
4970 + return -ENOIOCTLCMD;
4975 +/* ======================== Card services HCI interaction ======================== */
4978 +int dtl1_open(dtl1_info_t *info)
4980 + unsigned long flags;
4981 + unsigned int iobase = info->link.io.BasePort1;
4982 + struct hci_dev *hdev;
4984 + spin_lock_init(&(info->lock));
4986 + skb_queue_head_init(&(info->txq));
4988 + info->rx_state = RECV_WAIT_NSH;
4989 + info->rx_count = NSHL;
4990 + info->rx_skb = NULL;
4992 + set_bit(XMIT_WAITING, &(info->tx_state));
4994 + spin_lock_irqsave(&(info->lock), flags);
4997 + outb(0, iobase + UART_MCR);
4999 + /* Turn off interrupts */
5000 + outb(0, iobase + UART_IER);
5002 + /* Initialize UART */
5003 + outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
5004 + outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
5006 + info->ri_latch = inb(info->link.io.BasePort1 + UART_MSR) & UART_MSR_RI;
5008 + /* Turn on interrupts */
5009 + outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
5011 + spin_unlock_irqrestore(&(info->lock), flags);
5013 + /* Timeout before it is safe to send the first HCI packet */
5014 + set_current_state(TASK_INTERRUPTIBLE);
5015 + schedule_timeout(HZ * 2);
5018 + /* Initialize and register HCI device */
5020 + hdev = &(info->hdev);
5022 + hdev->type = HCI_PCCARD;
5023 + hdev->driver_data = info;
5025 + hdev->open = dtl1_hci_open;
5026 + hdev->close = dtl1_hci_close;
5027 + hdev->flush = dtl1_hci_flush;
5028 + hdev->send = dtl1_hci_send_frame;
5029 + hdev->destruct = dtl1_hci_destruct;
5030 + hdev->ioctl = dtl1_hci_ioctl;
5032 + if (hci_register_dev(hdev) < 0) {
5033 + printk(KERN_WARNING "dtl1_cs: Can't register HCI device %s.\n", hdev->name);
5041 +int dtl1_close(dtl1_info_t *info)
5043 + unsigned long flags;
5044 + unsigned int iobase = info->link.io.BasePort1;
5045 + struct hci_dev *hdev = &(info->hdev);
5047 + if (info->link.state & DEV_CONFIG_PENDING)
5050 + dtl1_hci_close(hdev);
5052 + spin_lock_irqsave(&(info->lock), flags);
5055 + outb(0, iobase + UART_MCR);
5057 + /* Turn off interrupts */
5058 + outb(0, iobase + UART_IER);
5060 + spin_unlock_irqrestore(&(info->lock), flags);
5062 + if (hci_unregister_dev(hdev) < 0)
5063 + printk(KERN_WARNING "dtl1_cs: Can't unregister HCI device %s.\n", hdev->name);
5070 +/* ======================== Card services ======================== */
5073 +static void cs_error(client_handle_t handle, int func, int ret)
5075 + error_info_t err = { func, ret };
5077 + CardServices(ReportError, handle, &err);
5081 +dev_link_t *dtl1_attach(void)
5083 + dtl1_info_t *info;
5084 + client_reg_t client_reg;
5088 + /* Create new info device */
5089 + info = kmalloc(sizeof(*info), GFP_KERNEL);
5092 + memset(info, 0, sizeof(*info));
5094 + link = &info->link;
5095 + link->priv = info;
5097 + link->release.function = &dtl1_release;
5098 + link->release.data = (u_long)link;
5099 + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
5100 + link->io.NumPorts1 = 8;
5101 + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
5102 + link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
5104 + if (irq_list[0] == -1)
5105 + link->irq.IRQInfo2 = irq_mask;
5107 + for (i = 0; i < 4; i++)
5108 + link->irq.IRQInfo2 |= 1 << irq_list[i];
5110 + link->irq.Handler = dtl1_interrupt;
5111 + link->irq.Instance = info;
5113 + link->conf.Attributes = CONF_ENABLE_IRQ;
5114 + link->conf.Vcc = 50;
5115 + link->conf.IntType = INT_MEMORY_AND_IO;
5117 + /* Register with Card Services */
5118 + link->next = dev_list;
5120 + client_reg.dev_info = &dev_info;
5121 + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
5122 + client_reg.EventMask =
5123 + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
5124 + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
5125 + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
5126 + client_reg.event_handler = &dtl1_event;
5127 + client_reg.Version = 0x0210;
5128 + client_reg.event_callback_args.client_data = link;
5130 + ret = CardServices(RegisterClient, &link->handle, &client_reg);
5131 + if (ret != CS_SUCCESS) {
5132 + cs_error(link->handle, RegisterClient, ret);
5133 + dtl1_detach(link);
5141 +void dtl1_detach(dev_link_t *link)
5143 + dtl1_info_t *info = link->priv;
5144 + dev_link_t **linkp;
5147 + /* Locate device structure */
5148 + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
5149 + if (*linkp == link)
5152 + if (*linkp == NULL)
5155 + del_timer(&link->release);
5156 + if (link->state & DEV_CONFIG)
5157 + dtl1_release((u_long)link);
5159 + if (link->handle) {
5160 + ret = CardServices(DeregisterClient, link->handle);
5161 + if (ret != CS_SUCCESS)
5162 + cs_error(link->handle, DeregisterClient, ret);
5165 + /* Unlink device structure, free bits */
5166 + *linkp = link->next;
5172 +static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
5176 + i = CardServices(fn, handle, tuple);
5177 + if (i != CS_SUCCESS)
5178 + return CS_NO_MORE_ITEMS;
5180 + i = CardServices(GetTupleData, handle, tuple);
5181 + if (i != CS_SUCCESS)
5184 + return CardServices(ParseTuple, handle, tuple, parse);
5188 +#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
5189 +#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
5191 +void dtl1_config(dev_link_t *link)
5193 + client_handle_t handle = link->handle;
5194 + dtl1_info_t *info = link->priv;
5198 + cistpl_cftable_entry_t *cf = &parse.cftable_entry;
5199 + config_info_t config;
5200 + int i, last_ret, last_fn;
5202 + tuple.TupleData = (cisdata_t *)buf;
5203 + tuple.TupleOffset = 0;
5204 + tuple.TupleDataMax = 255;
5205 + tuple.Attributes = 0;
5207 + /* Get configuration register information */
5208 + tuple.DesiredTuple = CISTPL_CONFIG;
5209 + last_ret = first_tuple(handle, &tuple, &parse);
5210 + if (last_ret != CS_SUCCESS) {
5211 + last_fn = ParseTuple;
5214 + link->conf.ConfigBase = parse.config.base;
5215 + link->conf.Present = parse.config.rmask[0];
5217 + /* Configure card */
5218 + link->state |= DEV_CONFIG;
5219 + i = CardServices(GetConfigurationInfo, handle, &config);
5220 + link->conf.Vcc = config.Vcc;
5222 + tuple.TupleData = (cisdata_t *)buf;
5223 + tuple.TupleOffset = 0;
5224 + tuple.TupleDataMax = 255;
5225 + tuple.Attributes = 0;
5226 + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
5228 + /* Look for a generic full-sized window */
5229 + link->io.NumPorts1 = 8;
5230 + i = first_tuple(handle, &tuple, &parse);
5231 + while (i != CS_NO_MORE_ITEMS) {
5232 + if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
5233 + link->conf.ConfigIndex = cf->index;
5234 + link->io.BasePort1 = cf->io.win[0].base;
5235 + link->io.NumPorts1 = cf->io.win[0].len; /*yo */
5236 + link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
5237 + i = CardServices(RequestIO, link->handle, &link->io);
5238 + if (i == CS_SUCCESS)
5241 + i = next_tuple(handle, &tuple, &parse);
5244 + if (i != CS_SUCCESS) {
5245 + cs_error(link->handle, RequestIO, i);
5249 + i = CardServices(RequestIRQ, link->handle, &link->irq);
5250 + if (i != CS_SUCCESS) {
5251 + cs_error(link->handle, RequestIRQ, i);
5252 + link->irq.AssignedIRQ = 0;
5255 + i = CardServices(RequestConfiguration, link->handle, &link->conf);
5256 + if (i != CS_SUCCESS) {
5257 + cs_error(link->handle, RequestConfiguration, i);
5261 + MOD_INC_USE_COUNT;
5263 + if (dtl1_open(info) != 0)
5266 + strcpy(info->node.dev_name, info->hdev.name);
5267 + link->dev = &info->node;
5268 + link->state &= ~DEV_CONFIG_PENDING;
5273 + cs_error(link->handle, last_fn, last_ret);
5276 + dtl1_release((u_long)link);
5280 +void dtl1_release(u_long arg)
5282 + dev_link_t *link = (dev_link_t *)arg;
5283 + dtl1_info_t *info = link->priv;
5285 + if (link->state & DEV_PRESENT)
5288 + MOD_DEC_USE_COUNT;
5292 + CardServices(ReleaseConfiguration, link->handle);
5293 + CardServices(ReleaseIO, link->handle, &link->io);
5294 + CardServices(ReleaseIRQ, link->handle, &link->irq);
5296 + link->state &= ~DEV_CONFIG;
5300 +int dtl1_event(event_t event, int priority, event_callback_args_t *args)
5302 + dev_link_t *link = args->client_data;
5303 + dtl1_info_t *info = link->priv;
5306 + case CS_EVENT_CARD_REMOVAL:
5307 + link->state &= ~DEV_PRESENT;
5308 + if (link->state & DEV_CONFIG) {
5310 + mod_timer(&link->release, jiffies + HZ / 20);
5313 + case CS_EVENT_CARD_INSERTION:
5314 + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
5315 + dtl1_config(link);
5317 + case CS_EVENT_PM_SUSPEND:
5318 + link->state |= DEV_SUSPEND;
5319 + /* Fall through... */
5320 + case CS_EVENT_RESET_PHYSICAL:
5321 + if (link->state & DEV_CONFIG)
5322 + CardServices(ReleaseConfiguration, link->handle);
5324 + case CS_EVENT_PM_RESUME:
5325 + link->state &= ~DEV_SUSPEND;
5326 + /* Fall through... */
5327 + case CS_EVENT_CARD_RESET:
5329 + CardServices(RequestConfiguration, link->handle, &link->conf);
5338 +/* ======================== Module initialization ======================== */
5341 +int __init init_dtl1_cs(void)
5346 + CardServices(GetCardServicesInfo, &serv);
5347 + if (serv.Revision != CS_RELEASE_CODE) {
5348 + printk(KERN_NOTICE "dtl1_cs: Card Services release does not match!\n");
5352 + err = register_pccard_driver(&dev_info, &dtl1_attach, &dtl1_detach);
5358 +void __exit exit_dtl1_cs(void)
5360 + unregister_pccard_driver(&dev_info);
5362 + while (dev_list != NULL)
5363 + dtl1_detach(dev_list);
5367 +module_init(init_dtl1_cs);
5368 +module_exit(exit_dtl1_cs);
5371 diff -urN linux-2.4.18/drivers/bluetooth/hci_bcsp.c linux-2.4.18-mh15/drivers/bluetooth/hci_bcsp.c
5372 --- linux-2.4.18/drivers/bluetooth/hci_bcsp.c 1970-01-01 01:00:00.000000000 +0100
5373 +++ linux-2.4.18-mh15/drivers/bluetooth/hci_bcsp.c 2004-08-01 16:26:23.000000000 +0200
5376 + BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
5377 + Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com>
5380 + hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com>
5381 + ABCSP by Carl Orsborn <cjo@csr.com>
5383 + This program is free software; you can redistribute it and/or modify
5384 + it under the terms of the GNU General Public License version 2 as
5385 + published by the Free Software Foundation;
5387 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
5388 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5389 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
5390 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
5391 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
5392 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
5393 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
5394 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
5396 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
5397 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
5398 + SOFTWARE IS DISCLAIMED.
5402 + * $Id: hci_bcsp.c,v 1.2 2002/09/26 05:05:14 maxk Exp $
5405 +#define VERSION "0.1"
5407 +#include <linux/config.h>
5408 +#include <linux/module.h>
5410 +#include <linux/version.h>
5411 +#include <linux/kernel.h>
5412 +#include <linux/init.h>
5413 +#include <linux/sched.h>
5414 +#include <linux/types.h>
5415 +#include <linux/fcntl.h>
5416 +#include <linux/interrupt.h>
5417 +#include <linux/ptrace.h>
5418 +#include <linux/poll.h>
5420 +#include <linux/slab.h>
5421 +#include <linux/tty.h>
5422 +#include <linux/errno.h>
5423 +#include <linux/string.h>
5424 +#include <linux/signal.h>
5425 +#include <linux/ioctl.h>
5426 +#include <linux/skbuff.h>
5428 +#include <net/bluetooth/bluetooth.h>
5429 +#include <net/bluetooth/hci_core.h>
5430 +#include "hci_uart.h"
5431 +#include "hci_bcsp.h"
5433 +#ifndef HCI_UART_DEBUG
5435 +#define BT_DBG( A... )
5437 +#define BT_DMP( A... )
5440 +/* ---- BCSP CRC calculation ---- */
5442 +/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
5443 +initial value 0xffff, bits shifted in reverse order. */
5445 +static const u16 crc_table[] = {
5446 + 0x0000, 0x1081, 0x2102, 0x3183,
5447 + 0x4204, 0x5285, 0x6306, 0x7387,
5448 + 0x8408, 0x9489, 0xa50a, 0xb58b,
5449 + 0xc60c, 0xd68d, 0xe70e, 0xf78f
5452 +/* Initialise the crc calculator */
5453 +#define BCSP_CRC_INIT(x) x = 0xffff
5456 + Update crc with next data byte
5458 + Implementation note
5459 + The data byte is treated as two nibbles. The crc is generated
5460 + in reverse, i.e., bits are fed into the register from the top.
5462 +static void bcsp_crc_update(u16 *crc, u8 d)
5466 + reg = (reg >> 4) ^ crc_table[(reg ^ d) & 0x000f];
5467 + reg = (reg >> 4) ^ crc_table[(reg ^ (d >> 4)) & 0x000f];
5473 + Get reverse of generated crc
5475 + Implementation note
5476 + The crc generator (bcsp_crc_init() and bcsp_crc_update())
5477 + creates a reversed crc, so it needs to be swapped back before
5480 +static u16 bcsp_crc_reverse(u16 crc)
5484 + for (b = 0, rev = 0; b < 16; b++) {
5492 +/* ---- BCSP core ---- */
5494 +static void bcsp_slip_msgdelim(struct sk_buff *skb)
5496 + const char pkt_delim = 0xc0;
5497 + memcpy(skb_put(skb, 1), &pkt_delim, 1);
5500 +static void bcsp_slip_one_byte(struct sk_buff *skb, u8 c)
5502 + const char esc_c0[2] = { 0xdb, 0xdc };
5503 + const char esc_db[2] = { 0xdb, 0xdd };
5507 + memcpy(skb_put(skb, 2), &esc_c0, 2);
5510 + memcpy(skb_put(skb, 2), &esc_db, 2);
5513 + memcpy(skb_put(skb, 1), &c, 1);
5517 +static int bcsp_enqueue(struct hci_uart *hu, struct sk_buff *skb)
5519 + struct bcsp_struct *bcsp = hu->priv;
5521 + if (skb->len > 0xFFF) {
5522 + BT_ERR("Packet too long");
5527 + switch (skb->pkt_type) {
5528 + case HCI_ACLDATA_PKT:
5529 + case HCI_COMMAND_PKT:
5530 + skb_queue_tail(&bcsp->rel, skb);
5533 + case HCI_SCODATA_PKT:
5534 + skb_queue_tail(&bcsp->unrel, skb);
5538 + BT_ERR("Unknown packet type");
5545 +static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
5546 + int len, int pkt_type)
5548 + struct sk_buff *nskb;
5552 +#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
5553 + u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
5556 + switch (pkt_type) {
5557 + case HCI_ACLDATA_PKT:
5558 + chan = 6; /* BCSP ACL channel */
5559 + rel = 1; /* reliable channel */
5561 + case HCI_COMMAND_PKT:
5562 + chan = 5; /* BCSP cmd/evt channel */
5563 + rel = 1; /* reliable channel */
5565 + case HCI_SCODATA_PKT:
5566 + chan = 7; /* BCSP SCO channel */
5567 + rel = 0; /* unreliable channel */
5570 + chan = 1; /* BCSP LE channel */
5571 + rel = 0; /* unreliable channel */
5573 + case BCSP_ACK_PKT:
5574 + chan = 0; /* BCSP internal channel */
5575 + rel = 0; /* unreliable channel */
5578 + BT_ERR("Unknown packet type");
5582 + /* Max len of packet: (original len +4(bcsp hdr) +2(crc))*2
5583 + (because bytes 0xc0 and 0xdb are escaped, worst case is
5584 + when the packet is all made of 0xc0 and 0xdb :) )
5585 + + 2 (0xc0 delimiters at start and end). */
5587 + nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC);
5591 + nskb->pkt_type = pkt_type;
5593 + bcsp_slip_msgdelim(nskb);
5595 + hdr[0] = bcsp->rxseq_txack << 3;
5596 + bcsp->txack_req = 0;
5597 + BT_DBG("We request packet no %u to card", bcsp->rxseq_txack);
5600 + hdr[0] |= 0x80 + bcsp->msgq_txseq;
5601 + BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
5602 + bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07;
5604 +#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
5608 + hdr[1] = (len << 4) & 0xFF;
5610 + hdr[2] = len >> 4;
5611 + hdr[3] = ~(hdr[0] + hdr[1] + hdr[2]);
5613 + /* Put BCSP header */
5614 + for (i = 0; i < 4; i++) {
5615 + bcsp_slip_one_byte(nskb, hdr[i]);
5616 +#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
5617 + bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
5622 + for (i = 0; i < len; i++) {
5623 + bcsp_slip_one_byte(nskb, data[i]);
5624 +#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
5625 + bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
5629 +#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
5631 + bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
5632 + bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
5633 + bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
5636 + bcsp_slip_msgdelim(nskb);
5640 +/* This is a rewrite of pkt_avail in ABCSP */
5641 +static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
5643 + struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
5644 + unsigned long flags;
5645 + struct sk_buff *skb;
5647 + /* First of all, check for unreliable messages in the queue,
5648 + since they have priority */
5650 + if ((skb = skb_dequeue(&bcsp->unrel)) != NULL) {
5651 + struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
5656 + skb_queue_head(&bcsp->unrel, skb);
5657 + BT_ERR("Could not dequeue pkt because alloc_skb failed");
5661 + /* Now, try to send a reliable pkt. We can only send a
5662 + reliable packet if the number of packets sent but not yet ack'ed
5663 + is < than the winsize */
5665 + spin_lock_irqsave(&bcsp->unack.lock, flags);
5667 + if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) {
5668 + struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
5670 + __skb_queue_tail(&bcsp->unack, skb);
5671 + mod_timer(&bcsp->tbcsp, jiffies + HZ / 4);
5672 + spin_unlock_irqrestore(&bcsp->unack.lock, flags);
5675 + skb_queue_head(&bcsp->rel, skb);
5676 + BT_ERR("Could not dequeue pkt because alloc_skb failed");
5680 + spin_unlock_irqrestore(&bcsp->unack.lock, flags);
5683 + /* We could not send a reliable packet, either because there are
5684 + none or because there are too many unack'ed pkts. Did we receive
5685 + any packets we have not acknowledged yet ? */
5687 + if (bcsp->txack_req) {
5688 + /* if so, craft an empty ACK pkt and send it on BCSP unreliable
5690 + struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, NULL, 0, BCSP_ACK_PKT);
5694 + /* We have nothing to send */
5698 +static int bcsp_flush(struct hci_uart *hu)
5700 + BT_DBG("hu %p", hu);
5704 +/* Remove ack'ed packets */
5705 +static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
5707 + unsigned long flags;
5708 + struct sk_buff *skb;
5709 + int i, pkts_to_be_removed;
5712 + spin_lock_irqsave(&bcsp->unack.lock, flags);
5714 + pkts_to_be_removed = bcsp->unack.qlen;
5715 + seqno = bcsp->msgq_txseq;
5717 + while (pkts_to_be_removed) {
5718 + if (bcsp->rxack == seqno)
5720 + pkts_to_be_removed--;
5721 + seqno = (seqno - 1) & 0x07;
5724 + if (bcsp->rxack != seqno)
5725 + BT_ERR("Peer acked invalid packet");
5727 + BT_DBG("Removing %u pkts out of %u, up to seqno %u",
5728 + pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07);
5730 + for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed
5731 + && skb != (struct sk_buff *) &bcsp->unack; i++) {
5732 + struct sk_buff *nskb;
5735 + __skb_unlink(skb, &bcsp->unack);
5739 + if (bcsp->unack.qlen == 0)
5740 + del_timer(&bcsp->tbcsp);
5741 + spin_unlock_irqrestore(&bcsp->unack.lock, flags);
5743 + if (i != pkts_to_be_removed)
5744 + BT_ERR("Removed only %u out of %u pkts", i, pkts_to_be_removed);
5747 +/* Handle BCSP link-establishment packets. When we
5748 + detect a "sync" packet, symptom that the BT module has reset,
5749 + we do nothing :) (yet) */
5750 +static void bcsp_handle_le_pkt(struct hci_uart *hu)
5752 + struct bcsp_struct *bcsp = hu->priv;
5753 + u8 conf_pkt[4] = { 0xad, 0xef, 0xac, 0xed };
5754 + u8 conf_rsp_pkt[4] = { 0xde, 0xad, 0xd0, 0xd0 };
5755 + u8 sync_pkt[4] = { 0xda, 0xdc, 0xed, 0xed };
5757 + /* spot "conf" pkts and reply with a "conf rsp" pkt */
5758 + if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
5759 + !memcmp(&bcsp->rx_skb->data[4], conf_pkt, 4)) {
5760 + struct sk_buff *nskb = alloc_skb(4, GFP_ATOMIC);
5762 + BT_DBG("Found a LE conf pkt");
5765 + memcpy(skb_put(nskb, 4), conf_rsp_pkt, 4);
5766 + nskb->pkt_type = BCSP_LE_PKT;
5768 + skb_queue_head(&bcsp->unrel, nskb);
5769 + hci_uart_tx_wakeup(hu);
5771 + /* Spot "sync" pkts. If we find one...disaster! */
5772 + else if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
5773 + !memcmp(&bcsp->rx_skb->data[4], sync_pkt, 4)) {
5774 + BT_ERR("Found a LE sync pkt, card has reset");
5778 +static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char byte)
5780 + const u8 c0 = 0xc0, db = 0xdb;
5782 + switch (bcsp->rx_esc_state) {
5783 + case BCSP_ESCSTATE_NOESC:
5786 + bcsp->rx_esc_state = BCSP_ESCSTATE_ESC;
5789 + memcpy(skb_put(bcsp->rx_skb, 1), &byte, 1);
5790 + if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
5791 + bcsp->rx_state != BCSP_W4_CRC)
5792 + bcsp_crc_update(&bcsp->message_crc, byte);
5797 + case BCSP_ESCSTATE_ESC:
5800 + memcpy(skb_put(bcsp->rx_skb, 1), &c0, 1);
5801 + if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
5802 + bcsp->rx_state != BCSP_W4_CRC)
5803 + bcsp_crc_update(&bcsp-> message_crc, 0xc0);
5804 + bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
5809 + memcpy(skb_put(bcsp->rx_skb, 1), &db, 1);
5810 + if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
5811 + bcsp->rx_state != BCSP_W4_CRC)
5812 + bcsp_crc_update(&bcsp-> message_crc, 0xdb);
5813 + bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
5818 + BT_ERR ("Invalid byte %02x after esc byte", byte);
5819 + kfree_skb(bcsp->rx_skb);
5820 + bcsp->rx_skb = NULL;
5821 + bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
5822 + bcsp->rx_count = 0;
5827 +static inline void bcsp_complete_rx_pkt(struct hci_uart *hu)
5829 + struct bcsp_struct *bcsp = hu->priv;
5832 + if (bcsp->rx_skb->data[0] & 0x80) { /* reliable pkt */
5833 + BT_DBG("Received seqno %u from card", bcsp->rxseq_txack);
5834 + bcsp->rxseq_txack++;
5835 + bcsp->rxseq_txack %= 0x8;
5836 + bcsp->txack_req = 1;
5838 + /* If needed, transmit an ack pkt */
5839 + hci_uart_tx_wakeup(hu);
5842 + bcsp->rxack = (bcsp->rx_skb->data[0] >> 3) & 0x07;
5843 + BT_DBG("Request for pkt %u from card", bcsp->rxack);
5845 + bcsp_pkt_cull(bcsp);
5846 + if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
5847 + bcsp->rx_skb->data[0] & 0x80) {
5848 + bcsp->rx_skb->pkt_type = HCI_ACLDATA_PKT;
5850 + } else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
5851 + bcsp->rx_skb->data[0] & 0x80) {
5852 + bcsp->rx_skb->pkt_type = HCI_EVENT_PKT;
5854 + } else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
5855 + bcsp->rx_skb->pkt_type = HCI_SCODATA_PKT;
5857 + } else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 &&
5858 + !(bcsp->rx_skb->data[0] & 0x80)) {
5859 + bcsp_handle_le_pkt(hu);
5865 + if ((bcsp->rx_skb->data[1] & 0x0f) != 0 &&
5866 + (bcsp->rx_skb->data[1] & 0x0f) != 1) {
5867 + BT_ERR ("Packet for unknown channel (%u %s)",
5868 + bcsp->rx_skb->data[1] & 0x0f,
5869 + bcsp->rx_skb->data[0] & 0x80 ?
5870 + "reliable" : "unreliable");
5872 + kfree_skb(bcsp->rx_skb);
5874 + /* Pull out BCSP hdr */
5875 + skb_pull(bcsp->rx_skb, 4);
5877 + hci_recv_frame(bcsp->rx_skb);
5879 + bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
5880 + bcsp->rx_skb = NULL;
5884 +static int bcsp_recv(struct hci_uart *hu, void *data, int count)
5886 + struct bcsp_struct *bcsp = hu->priv;
5887 + register unsigned char *ptr;
5889 + BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
5890 + hu, count, bcsp->rx_state, bcsp->rx_count);
5894 + if (bcsp->rx_count) {
5895 + if (*ptr == 0xc0) {
5896 + BT_ERR("Short BCSP packet");
5897 + kfree_skb(bcsp->rx_skb);
5898 + bcsp->rx_state = BCSP_W4_PKT_START;
5899 + bcsp->rx_count = 0;
5901 + bcsp_unslip_one_byte(bcsp, *ptr);
5907 + switch (bcsp->rx_state) {
5908 + case BCSP_W4_BCSP_HDR:
5909 + if ((0xff & (u8) ~ (bcsp->rx_skb->data[0] + bcsp->rx_skb->data[1] +
5910 + bcsp->rx_skb->data[2])) != bcsp->rx_skb->data[3]) {
5911 + BT_ERR("Error in BCSP hdr checksum");
5912 + kfree_skb(bcsp->rx_skb);
5913 + bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
5914 + bcsp->rx_count = 0;
5917 + if (bcsp->rx_skb->data[0] & 0x80 /* reliable pkt */
5918 + && (bcsp->rx_skb->data[0] & 0x07) != bcsp->rxseq_txack) {
5919 + BT_ERR ("Out-of-order packet arrived, got %u expected %u",
5920 + bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);
5922 + kfree_skb(bcsp->rx_skb);
5923 + bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
5924 + bcsp->rx_count = 0;
5927 + bcsp->rx_state = BCSP_W4_DATA;
5928 + bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) +
5929 + (bcsp->rx_skb->data[2] << 4); /* May be 0 */
5932 + case BCSP_W4_DATA:
5933 + if (bcsp->rx_skb->data[0] & 0x40) { /* pkt with crc */
5934 + bcsp->rx_state = BCSP_W4_CRC;
5935 + bcsp->rx_count = 2;
5937 + bcsp_complete_rx_pkt(hu);
5941 + if (bcsp_crc_reverse(bcsp->message_crc) !=
5942 + (bcsp->rx_skb->data[bcsp->rx_skb->len - 2] << 8) +
5943 + bcsp->rx_skb->data[bcsp->rx_skb->len - 1]) {
5945 + BT_ERR ("Checksum failed: computed %04x received %04x",
5946 + bcsp_crc_reverse(bcsp->message_crc),
5947 + (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) +
5948 + bcsp->rx_skb->data[bcsp->rx_skb->len - 1]);
5950 + kfree_skb(bcsp->rx_skb);
5951 + bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
5952 + bcsp->rx_count = 0;
5955 + skb_trim(bcsp->rx_skb, bcsp->rx_skb->len - 2);
5956 + bcsp_complete_rx_pkt(hu);
5959 + case BCSP_W4_PKT_DELIMITER:
5962 + bcsp->rx_state = BCSP_W4_PKT_START;
5965 + /*BT_ERR("Ignoring byte %02x", *ptr);*/
5971 + case BCSP_W4_PKT_START:
5978 + bcsp->rx_state = BCSP_W4_BCSP_HDR;
5979 + bcsp->rx_count = 4;
5980 + bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
5981 + BCSP_CRC_INIT(bcsp->message_crc);
5983 + /* Do not increment ptr or decrement count
5984 + * Allocate packet. Max len of a BCSP pkt=
5985 + * 0xFFF (payload) +4 (header) +2 (crc) */
5987 + bcsp->rx_skb = bluez_skb_alloc(0x1005, GFP_ATOMIC);
5988 + if (!bcsp->rx_skb) {
5989 + BT_ERR("Can't allocate mem for new packet");
5990 + bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
5991 + bcsp->rx_count = 0;
5994 + bcsp->rx_skb->dev = (void *) &hu->hdev;
6003 + /* Arrange to retransmit all messages in the relq. */
6004 +static void bcsp_timed_event(unsigned long arg)
6006 + struct hci_uart *hu = (struct hci_uart *) arg;
6007 + struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
6008 + struct sk_buff *skb;
6009 + unsigned long flags;
6011 + BT_DBG("hu %p retransmitting %u pkts", hu, bcsp->unack.qlen);
6013 + spin_lock_irqsave(&bcsp->unack.lock, flags);
6015 + while ((skb = __skb_dequeue_tail(&bcsp->unack)) != NULL) {
6016 + bcsp->msgq_txseq = (bcsp->msgq_txseq - 1) & 0x07;
6017 + skb_queue_head(&bcsp->rel, skb);
6020 + spin_unlock_irqrestore(&bcsp->unack.lock, flags);
6022 + hci_uart_tx_wakeup(hu);
6025 +static int bcsp_open(struct hci_uart *hu)
6027 + struct bcsp_struct *bcsp;
6029 + BT_DBG("hu %p", hu);
6031 + bcsp = kmalloc(sizeof(*bcsp), GFP_ATOMIC);
6034 + memset(bcsp, 0, sizeof(*bcsp));
6037 + skb_queue_head_init(&bcsp->unack);
6038 + skb_queue_head_init(&bcsp->rel);
6039 + skb_queue_head_init(&bcsp->unrel);
6041 + init_timer(&bcsp->tbcsp);
6042 + bcsp->tbcsp.function = bcsp_timed_event;
6043 + bcsp->tbcsp.data = (u_long) hu;
6045 + bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
6050 +static int bcsp_close(struct hci_uart *hu)
6052 + struct bcsp_struct *bcsp = hu->priv;
6055 + BT_DBG("hu %p", hu);
6057 + skb_queue_purge(&bcsp->unack);
6058 + skb_queue_purge(&bcsp->rel);
6059 + skb_queue_purge(&bcsp->unrel);
6060 + del_timer(&bcsp->tbcsp);
6066 +static struct hci_uart_proto bcsp = {
6067 + id: HCI_UART_BCSP,
6069 + close: bcsp_close,
6070 + enqueue: bcsp_enqueue,
6071 + dequeue: bcsp_dequeue,
6076 +int bcsp_init(void)
6078 + return hci_uart_register_proto(&bcsp);
6081 +int bcsp_deinit(void)
6083 + return hci_uart_unregister_proto(&bcsp);
6085 diff -urN linux-2.4.18/drivers/bluetooth/hci_bcsp.h linux-2.4.18-mh15/drivers/bluetooth/hci_bcsp.h
6086 --- linux-2.4.18/drivers/bluetooth/hci_bcsp.h 1970-01-01 01:00:00.000000000 +0100
6087 +++ linux-2.4.18-mh15/drivers/bluetooth/hci_bcsp.h 2004-08-01 16:26:23.000000000 +0200
6090 + BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
6091 + Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com>
6094 + hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com>
6095 + ABCSP by Carl Orsborn <cjo@csr.com>
6097 + This program is free software; you can redistribute it and/or modify
6098 + it under the terms of the GNU General Public License version 2 as
6099 + published by the Free Software Foundation;
6101 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
6102 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6103 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
6104 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
6105 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
6106 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
6107 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
6108 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
6110 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
6111 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
6112 + SOFTWARE IS DISCLAIMED.
6116 + * $Id: hci_bcsp.h,v 1.2 2002/09/26 05:05:14 maxk Exp $
6119 +#ifndef __HCI_BCSP_H__
6120 +#define __HCI_BCSP_H__
6122 +#define BCSP_TXWINSIZE 4
6124 +#define BCSP_ACK_PKT 0x05
6125 +#define BCSP_LE_PKT 0x06
6127 +struct bcsp_struct {
6128 + struct sk_buff_head unack; /* Unack'ed packets queue */
6129 + struct sk_buff_head rel; /* Reliable packets queue */
6130 + struct sk_buff_head unrel; /* Unreliable packets queue */
6132 + unsigned long rx_count;
6133 + struct sk_buff *rx_skb;
6134 + u8 rxseq_txack; /* rxseq == txack. */
6135 + u8 rxack; /* Last packet sent by us that the peer ack'ed */
6136 + struct timer_list tbcsp;
6139 + BCSP_W4_PKT_DELIMITER,
6140 + BCSP_W4_PKT_START,
6147 + BCSP_ESCSTATE_NOESC,
6152 + u8 txack_req; /* Do we need to send ack's to the peer? */
6154 + /* Reliable packet sequence number - used to assign seq to each rel pkt. */
6158 +#endif /* __HCI_BCSP_H__ */
6159 diff -urN linux-2.4.18/drivers/bluetooth/hci_h4.c linux-2.4.18-mh15/drivers/bluetooth/hci_h4.c
6160 --- linux-2.4.18/drivers/bluetooth/hci_h4.c 1970-01-01 01:00:00.000000000 +0100
6161 +++ linux-2.4.18-mh15/drivers/bluetooth/hci_h4.c 2004-08-01 16:26:23.000000000 +0200
6164 + BlueZ - Bluetooth protocol stack for Linux
6165 + Copyright (C) 2000-2001 Qualcomm Incorporated
6167 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6169 + This program is free software; you can redistribute it and/or modify
6170 + it under the terms of the GNU General Public License version 2 as
6171 + published by the Free Software Foundation;
6173 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
6174 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6175 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
6176 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
6177 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
6178 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
6179 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
6180 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
6182 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
6183 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
6184 + SOFTWARE IS DISCLAIMED.
6188 + * BlueZ HCI UART(H4) protocol.
6190 + * $Id: hci_h4.c,v 1.3 2002/09/09 01:17:32 maxk Exp $
6192 +#define VERSION "1.2"
6194 +#include <linux/config.h>
6195 +#include <linux/module.h>
6197 +#include <linux/version.h>
6198 +#include <linux/kernel.h>
6199 +#include <linux/init.h>
6200 +#include <linux/sched.h>
6201 +#include <linux/types.h>
6202 +#include <linux/fcntl.h>
6203 +#include <linux/interrupt.h>
6204 +#include <linux/ptrace.h>
6205 +#include <linux/poll.h>
6207 +#include <linux/slab.h>
6208 +#include <linux/tty.h>
6209 +#include <linux/errno.h>
6210 +#include <linux/string.h>
6211 +#include <linux/signal.h>
6212 +#include <linux/ioctl.h>
6213 +#include <linux/skbuff.h>
6215 +#include <net/bluetooth/bluetooth.h>
6216 +#include <net/bluetooth/hci_core.h>
6217 +#include "hci_uart.h"
6218 +#include "hci_h4.h"
6220 +#ifndef HCI_UART_DEBUG
6222 +#define BT_DBG( A... )
6224 +#define BT_DMP( A... )
6227 +/* Initialize protocol */
6228 +static int h4_open(struct hci_uart *hu)
6230 + struct h4_struct *h4;
6232 + BT_DBG("hu %p", hu);
6234 + h4 = kmalloc(sizeof(*h4), GFP_ATOMIC);
6237 + memset(h4, 0, sizeof(*h4));
6239 + skb_queue_head_init(&h4->txq);
6245 +/* Flush protocol data */
6246 +static int h4_flush(struct hci_uart *hu)
6248 + struct h4_struct *h4 = hu->priv;
6250 + BT_DBG("hu %p", hu);
6251 + skb_queue_purge(&h4->txq);
6255 +/* Close protocol */
6256 +static int h4_close(struct hci_uart *hu)
6258 + struct h4_struct *h4 = hu->priv;
6261 + BT_DBG("hu %p", hu);
6263 + skb_queue_purge(&h4->txq);
6265 + kfree_skb(h4->rx_skb);
6272 +/* Enqueue frame for transmittion (padding, crc, etc) */
6273 +static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
6275 + struct h4_struct *h4 = hu->priv;
6277 + BT_DBG("hu %p skb %p", hu, skb);
6279 + /* Prepend skb with frame type */
6280 + memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
6281 + skb_queue_tail(&h4->txq, skb);
6285 +static inline int h4_check_data_len(struct h4_struct *h4, int len)
6287 + register int room = skb_tailroom(h4->rx_skb);
6289 + BT_DBG("len %d room %d", len, room);
6291 + BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
6292 + hci_recv_frame(h4->rx_skb);
6293 + } else if (len > room) {
6294 + BT_ERR("Data length is too large");
6295 + kfree_skb(h4->rx_skb);
6297 + h4->rx_state = H4_W4_DATA;
6298 + h4->rx_count = len;
6302 + h4->rx_state = H4_W4_PACKET_TYPE;
6303 + h4->rx_skb = NULL;
6309 +static int h4_recv(struct hci_uart *hu, void *data, int count)
6311 + struct h4_struct *h4 = hu->priv;
6312 + register char *ptr;
6313 + hci_event_hdr *eh;
6316 + register int len, type, dlen;
6318 + BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
6319 + hu, count, h4->rx_state, h4->rx_count);
6323 + if (h4->rx_count) {
6324 + len = MIN(h4->rx_count, count);
6325 + memcpy(skb_put(h4->rx_skb, len), ptr, len);
6326 + h4->rx_count -= len; count -= len; ptr += len;
6331 + switch (h4->rx_state) {
6333 + BT_DBG("Complete data");
6335 + BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
6337 + hci_recv_frame(h4->rx_skb);
6339 + h4->rx_state = H4_W4_PACKET_TYPE;
6340 + h4->rx_skb = NULL;
6343 + case H4_W4_EVENT_HDR:
6344 + eh = (hci_event_hdr *) h4->rx_skb->data;
6346 + BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
6348 + h4_check_data_len(h4, eh->plen);
6351 + case H4_W4_ACL_HDR:
6352 + ah = (hci_acl_hdr *) h4->rx_skb->data;
6353 + dlen = __le16_to_cpu(ah->dlen);
6355 + BT_DBG("ACL header: dlen %d", dlen);
6357 + h4_check_data_len(h4, dlen);
6360 + case H4_W4_SCO_HDR:
6361 + sh = (hci_sco_hdr *) h4->rx_skb->data;
6363 + BT_DBG("SCO header: dlen %d", sh->dlen);
6365 + h4_check_data_len(h4, sh->dlen);
6370 + /* H4_W4_PACKET_TYPE */
6372 + case HCI_EVENT_PKT:
6373 + BT_DBG("Event packet");
6374 + h4->rx_state = H4_W4_EVENT_HDR;
6375 + h4->rx_count = HCI_EVENT_HDR_SIZE;
6376 + type = HCI_EVENT_PKT;
6379 + case HCI_ACLDATA_PKT:
6380 + BT_DBG("ACL packet");
6381 + h4->rx_state = H4_W4_ACL_HDR;
6382 + h4->rx_count = HCI_ACL_HDR_SIZE;
6383 + type = HCI_ACLDATA_PKT;
6386 + case HCI_SCODATA_PKT:
6387 + BT_DBG("SCO packet");
6388 + h4->rx_state = H4_W4_SCO_HDR;
6389 + h4->rx_count = HCI_SCO_HDR_SIZE;
6390 + type = HCI_SCODATA_PKT;
6394 + BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
6395 + hu->hdev.stat.err_rx++;
6401 + /* Allocate packet */
6402 + h4->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
6403 + if (!h4->rx_skb) {
6404 + BT_ERR("Can't allocate mem for new packet");
6405 + h4->rx_state = H4_W4_PACKET_TYPE;
6409 + h4->rx_skb->dev = (void *) &hu->hdev;
6410 + h4->rx_skb->pkt_type = type;
6415 +static struct sk_buff *h4_dequeue(struct hci_uart *hu)
6417 + struct h4_struct *h4 = hu->priv;
6418 + return skb_dequeue(&h4->txq);
6421 +static struct hci_uart_proto h4p = {
6426 + enqueue: h4_enqueue,
6427 + dequeue: h4_dequeue,
6433 + return hci_uart_register_proto(&h4p);
6436 +int h4_deinit(void)
6438 + return hci_uart_unregister_proto(&h4p);
6440 diff -urN linux-2.4.18/drivers/bluetooth/hci_h4.h linux-2.4.18-mh15/drivers/bluetooth/hci_h4.h
6441 --- linux-2.4.18/drivers/bluetooth/hci_h4.h 1970-01-01 01:00:00.000000000 +0100
6442 +++ linux-2.4.18-mh15/drivers/bluetooth/hci_h4.h 2004-08-01 16:26:23.000000000 +0200
6445 + BlueZ - Bluetooth protocol stack for Linux
6446 + Copyright (C) 2000-2001 Qualcomm Incorporated
6448 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6450 + This program is free software; you can redistribute it and/or modify
6451 + it under the terms of the GNU General Public License version 2 as
6452 + published by the Free Software Foundation;
6454 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
6455 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6456 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
6457 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
6458 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
6459 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
6460 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
6461 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
6463 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
6464 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
6465 + SOFTWARE IS DISCLAIMED.
6469 + * $Id: hci_h4.h,v 1.2 2002/09/09 01:17:32 maxk Exp $
6474 + unsigned long rx_state;
6475 + unsigned long rx_count;
6476 + struct sk_buff *rx_skb;
6477 + struct sk_buff_head txq;
6480 +/* H4 receiver States */
6481 +#define H4_W4_PACKET_TYPE 0
6482 +#define H4_W4_EVENT_HDR 1
6483 +#define H4_W4_ACL_HDR 2
6484 +#define H4_W4_SCO_HDR 3
6485 +#define H4_W4_DATA 4
6487 +#endif /* __KERNEL__ */
6488 diff -urN linux-2.4.18/drivers/bluetooth/hci_ldisc.c linux-2.4.18-mh15/drivers/bluetooth/hci_ldisc.c
6489 --- linux-2.4.18/drivers/bluetooth/hci_ldisc.c 1970-01-01 01:00:00.000000000 +0100
6490 +++ linux-2.4.18-mh15/drivers/bluetooth/hci_ldisc.c 2004-08-01 16:26:23.000000000 +0200
6493 + BlueZ - Bluetooth protocol stack for Linux
6494 + Copyright (C) 2000-2001 Qualcomm Incorporated
6496 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6498 + This program is free software; you can redistribute it and/or modify
6499 + it under the terms of the GNU General Public License version 2 as
6500 + published by the Free Software Foundation;
6502 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
6503 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6504 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
6505 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
6506 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
6507 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
6508 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
6509 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
6511 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
6512 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
6513 + SOFTWARE IS DISCLAIMED.
6517 + * BlueZ HCI UART driver.
6519 + * $Id: hci_ldisc.c,v 1.5 2002/10/02 18:37:20 maxk Exp $
6521 +#define VERSION "2.1"
6523 +#include <linux/config.h>
6524 +#include <linux/module.h>
6526 +#include <linux/version.h>
6527 +#include <linux/kernel.h>
6528 +#include <linux/init.h>
6529 +#include <linux/sched.h>
6530 +#include <linux/types.h>
6531 +#include <linux/fcntl.h>
6532 +#include <linux/interrupt.h>
6533 +#include <linux/ptrace.h>
6534 +#include <linux/poll.h>
6536 +#include <linux/slab.h>
6537 +#include <linux/tty.h>
6538 +#include <linux/errno.h>
6539 +#include <linux/string.h>
6540 +#include <linux/signal.h>
6541 +#include <linux/ioctl.h>
6542 +#include <linux/skbuff.h>
6544 +#include <net/bluetooth/bluetooth.h>
6545 +#include <net/bluetooth/hci_core.h>
6546 +#include "hci_uart.h"
6548 +#ifndef HCI_UART_DEBUG
6550 +#define BT_DBG( A... )
6552 +#define BT_DMP( A... )
6555 +static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
6557 +int hci_uart_register_proto(struct hci_uart_proto *p)
6559 + if (p->id >= HCI_UART_MAX_PROTO)
6569 +int hci_uart_unregister_proto(struct hci_uart_proto *p)
6571 + if (p->id >= HCI_UART_MAX_PROTO)
6577 + hup[p->id] = NULL;
6581 +static struct hci_uart_proto *hci_uart_get_proto(unsigned int id)
6583 + if (id >= HCI_UART_MAX_PROTO)
6588 +static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type)
6590 + struct hci_dev *hdev = &hu->hdev;
6592 + /* Update HCI stat counters */
6593 + switch (pkt_type) {
6594 + case HCI_COMMAND_PKT:
6595 + hdev->stat.cmd_tx++;
6598 + case HCI_ACLDATA_PKT:
6599 + hdev->stat.acl_tx++;
6602 + case HCI_SCODATA_PKT:
6603 + hdev->stat.cmd_tx++;
6608 +static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu)
6610 + struct sk_buff *skb = hu->tx_skb;
6612 + skb = hu->proto->dequeue(hu);
6614 + hu->tx_skb = NULL;
6618 +int hci_uart_tx_wakeup(struct hci_uart *hu)
6620 + struct tty_struct *tty = hu->tty;
6621 + struct hci_dev *hdev = &hu->hdev;
6622 + struct sk_buff *skb;
6624 + if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
6625 + set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
6632 + clear_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
6634 + while ((skb = hci_uart_dequeue(hu))) {
6637 + set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
6638 + len = tty->driver.write(tty, 0, skb->data, skb->len);
6639 + hdev->stat.byte_tx += len;
6641 + skb_pull(skb, len);
6647 + hci_uart_tx_complete(hu, skb->pkt_type);
6651 + if (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state))
6654 + clear_bit(HCI_UART_SENDING, &hu->tx_state);
6658 +/* ------- Interface to HCI layer ------ */
6659 +/* Initialize device */
6660 +static int hci_uart_open(struct hci_dev *hdev)
6662 + BT_DBG("%s %p", hdev->name, hdev);
6664 + /* Nothing to do for UART driver */
6666 + set_bit(HCI_RUNNING, &hdev->flags);
6671 +static int hci_uart_flush(struct hci_dev *hdev)
6673 + struct hci_uart *hu = (struct hci_uart *) hdev->driver_data;
6674 + struct tty_struct *tty = hu->tty;
6676 + BT_DBG("hdev %p tty %p", hdev, tty);
6679 + kfree_skb(hu->tx_skb); hu->tx_skb = NULL;
6682 + /* Flush any pending characters in the driver and discipline. */
6683 + if (tty->ldisc.flush_buffer)
6684 + tty->ldisc.flush_buffer(tty);
6686 + if (tty->driver.flush_buffer)
6687 + tty->driver.flush_buffer(tty);
6689 + if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
6690 + hu->proto->flush(hu);
6696 +static int hci_uart_close(struct hci_dev *hdev)
6698 + BT_DBG("hdev %p", hdev);
6700 + if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
6703 + hci_uart_flush(hdev);
6707 +/* Send frames from HCI layer */
6708 +static int hci_uart_send_frame(struct sk_buff *skb)
6710 + struct hci_dev* hdev = (struct hci_dev *) skb->dev;
6711 + struct tty_struct *tty;
6712 + struct hci_uart *hu;
6715 + BT_ERR("Frame for uknown device (hdev=NULL)");
6719 + if (!test_bit(HCI_RUNNING, &hdev->flags))
6722 + hu = (struct hci_uart *) hdev->driver_data;
6725 + BT_DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
6727 + hu->proto->enqueue(hu, skb);
6729 + hci_uart_tx_wakeup(hu);
6733 +static void hci_uart_destruct(struct hci_dev *hdev)
6735 + struct hci_uart *hu;
6737 + if (!hdev) return;
6739 + BT_DBG("%s", hdev->name);
6741 + hu = (struct hci_uart *) hdev->driver_data;
6744 + MOD_DEC_USE_COUNT;
6747 +/* ------ LDISC part ------ */
6748 +/* hci_uart_tty_open
6750 + * Called when line discipline changed to HCI_UART.
6753 + * tty pointer to tty info structure
6755 + * 0 if success, otherwise error code
6757 +static int hci_uart_tty_open(struct tty_struct *tty)
6759 + struct hci_uart *hu = (void *) tty->disc_data;
6761 + BT_DBG("tty %p", tty);
6766 + if (!(hu = kmalloc(sizeof(struct hci_uart), GFP_KERNEL))) {
6767 + BT_ERR("Can't allocate controll structure");
6770 + memset(hu, 0, sizeof(struct hci_uart));
6772 + tty->disc_data = hu;
6775 + spin_lock_init(&hu->rx_lock);
6777 + /* Flush any pending characters in the driver and line discipline */
6778 + if (tty->ldisc.flush_buffer)
6779 + tty->ldisc.flush_buffer(tty);
6781 + if (tty->driver.flush_buffer)
6782 + tty->driver.flush_buffer(tty);
6784 + MOD_INC_USE_COUNT;
6788 +/* hci_uart_tty_close()
6790 + * Called when the line discipline is changed to something
6791 + * else, the tty is closed, or the tty detects a hangup.
6793 +static void hci_uart_tty_close(struct tty_struct *tty)
6795 + struct hci_uart *hu = (void *)tty->disc_data;
6797 + BT_DBG("tty %p", tty);
6799 + /* Detach from the tty */
6800 + tty->disc_data = NULL;
6803 + struct hci_dev *hdev = &hu->hdev;
6804 + hci_uart_close(hdev);
6806 + if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
6807 + hu->proto->close(hu);
6808 + hci_unregister_dev(hdev);
6811 + MOD_DEC_USE_COUNT;
6815 +/* hci_uart_tty_wakeup()
6817 + * Callback for transmit wakeup. Called when low level
6818 + * device driver can accept more send data.
6820 + * Arguments: tty pointer to associated tty instance data
6821 + * Return Value: None
6823 +static void hci_uart_tty_wakeup(struct tty_struct *tty)
6825 + struct hci_uart *hu = (void *)tty->disc_data;
6832 + clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
6834 + if (tty != hu->tty)
6837 + if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
6838 + hci_uart_tx_wakeup(hu);
6841 +/* hci_uart_tty_room()
6843 + * Callback function from tty driver. Return the amount of
6844 + * space left in the receiver's buffer to decide if remote
6845 + * transmitter is to be throttled.
6847 + * Arguments: tty pointer to associated tty instance data
6848 + * Return Value: number of bytes left in receive buffer
6850 +static int hci_uart_tty_room (struct tty_struct *tty)
6855 +/* hci_uart_tty_receive()
6857 + * Called by tty low level driver when receive data is
6860 + * Arguments: tty pointer to tty isntance data
6861 + * data pointer to received data
6862 + * flags pointer to flags for data
6863 + * count count of received data in bytes
6865 + * Return Value: None
6867 +static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char *flags, int count)
6869 + struct hci_uart *hu = (void *)tty->disc_data;
6871 + if (!hu || tty != hu->tty)
6874 + if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
6877 + spin_lock(&hu->rx_lock);
6878 + hu->proto->recv(hu, (void *) data, count);
6879 + hu->hdev.stat.byte_rx += count;
6880 + spin_unlock(&hu->rx_lock);
6882 + if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver.unthrottle)
6883 + tty->driver.unthrottle(tty);
6886 +static int hci_uart_register_dev(struct hci_uart *hu)
6888 + struct hci_dev *hdev;
6892 + /* Initialize and register HCI device */
6895 + hdev->type = HCI_UART;
6896 + hdev->driver_data = hu;
6898 + hdev->open = hci_uart_open;
6899 + hdev->close = hci_uart_close;
6900 + hdev->flush = hci_uart_flush;
6901 + hdev->send = hci_uart_send_frame;
6902 + hdev->destruct = hci_uart_destruct;
6904 + if (hci_register_dev(hdev) < 0) {
6905 + BT_ERR("Can't register HCI device %s", hdev->name);
6908 + MOD_INC_USE_COUNT;
6912 +static int hci_uart_set_proto(struct hci_uart *hu, int id)
6914 + struct hci_uart_proto *p;
6917 + p = hci_uart_get_proto(id);
6919 + return -EPROTONOSUPPORT;
6921 + err = p->open(hu);
6927 + err = hci_uart_register_dev(hu);
6935 +/* hci_uart_tty_ioctl()
6937 + * Process IOCTL system call for the tty device.
6941 + * tty pointer to tty instance data
6942 + * file pointer to open file object for device
6943 + * cmd IOCTL command code
6944 + * arg argument for IOCTL call (cmd dependent)
6946 + * Return Value: Command dependent
6948 +static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
6949 + unsigned int cmd, unsigned long arg)
6951 + struct hci_uart *hu = (void *)tty->disc_data;
6956 + /* Verify the status of the device */
6961 + case HCIUARTSETPROTO:
6962 + if (!test_and_set_bit(HCI_UART_PROTO_SET, &hu->flags)) {
6963 + err = hci_uart_set_proto(hu, arg);
6965 + clear_bit(HCI_UART_PROTO_SET, &hu->flags);
6968 + tty->low_latency = 1;
6972 + case HCIUARTGETPROTO:
6973 + if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
6974 + return hu->proto->id;
6978 + err = n_tty_ioctl(tty, file, cmd, arg);
6986 + * We don't provide read/write/poll interface for user space.
6988 +static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr)
6992 +static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
6996 +static unsigned int hci_uart_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
7001 +#ifdef CONFIG_BLUEZ_HCIUART_H4
7003 +int h4_deinit(void);
7005 +#ifdef CONFIG_BLUEZ_HCIUART_BCSP
7006 +int bcsp_init(void);
7007 +int bcsp_deinit(void);
7010 +int __init hci_uart_init(void)
7012 + static struct tty_ldisc hci_uart_ldisc;
7015 + BT_INFO("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
7017 + BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
7019 + /* Register the tty discipline */
7021 + memset(&hci_uart_ldisc, 0, sizeof (hci_uart_ldisc));
7022 + hci_uart_ldisc.magic = TTY_LDISC_MAGIC;
7023 + hci_uart_ldisc.name = "n_hci";
7024 + hci_uart_ldisc.open = hci_uart_tty_open;
7025 + hci_uart_ldisc.close = hci_uart_tty_close;
7026 + hci_uart_ldisc.read = hci_uart_tty_read;
7027 + hci_uart_ldisc.write = hci_uart_tty_write;
7028 + hci_uart_ldisc.ioctl = hci_uart_tty_ioctl;
7029 + hci_uart_ldisc.poll = hci_uart_tty_poll;
7030 + hci_uart_ldisc.receive_room= hci_uart_tty_room;
7031 + hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
7032 + hci_uart_ldisc.write_wakeup= hci_uart_tty_wakeup;
7034 + if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) {
7035 + BT_ERR("Can't register HCI line discipline (%d)", err);
7039 +#ifdef CONFIG_BLUEZ_HCIUART_H4
7042 +#ifdef CONFIG_BLUEZ_HCIUART_BCSP
7049 +void hci_uart_cleanup(void)
7053 +#ifdef CONFIG_BLUEZ_HCIUART_H4
7056 +#ifdef CONFIG_BLUEZ_HCIUART_BCSP
7060 + /* Release tty registration of line discipline */
7061 + if ((err = tty_register_ldisc(N_HCI, NULL)))
7062 + BT_ERR("Can't unregister HCI line discipline (%d)", err);
7065 +module_init(hci_uart_init);
7066 +module_exit(hci_uart_cleanup);
7068 +MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
7069 +MODULE_DESCRIPTION("BlueZ HCI UART driver ver " VERSION);
7070 +MODULE_LICENSE("GPL");
7071 diff -urN linux-2.4.18/drivers/bluetooth/hci_uart.c linux-2.4.18-mh15/drivers/bluetooth/hci_uart.c
7072 --- linux-2.4.18/drivers/bluetooth/hci_uart.c 2001-09-07 18:28:38.000000000 +0200
7073 +++ linux-2.4.18-mh15/drivers/bluetooth/hci_uart.c 1970-01-01 01:00:00.000000000 +0100
7076 - BlueZ - Bluetooth protocol stack for Linux
7077 - Copyright (C) 2000-2001 Qualcomm Incorporated
7079 - Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
7081 - This program is free software; you can redistribute it and/or modify
7082 - it under the terms of the GNU General Public License version 2 as
7083 - published by the Free Software Foundation;
7085 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7086 - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7087 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
7088 - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
7089 - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
7090 - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
7091 - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
7092 - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
7094 - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
7095 - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
7096 - SOFTWARE IS DISCLAIMED.
7100 - * BlueZ HCI UART driver.
7102 - * $Id: hci_uart.c,v 1.5 2001/07/05 18:42:44 maxk Exp $
7104 -#define VERSION "1.0"
7106 -#include <linux/config.h>
7107 -#include <linux/module.h>
7109 -#include <linux/version.h>
7110 -#include <linux/config.h>
7111 -#include <linux/kernel.h>
7112 -#include <linux/init.h>
7113 -#include <linux/sched.h>
7114 -#include <linux/types.h>
7115 -#include <linux/fcntl.h>
7116 -#include <linux/interrupt.h>
7117 -#include <linux/ptrace.h>
7118 -#include <linux/poll.h>
7120 -#include <linux/slab.h>
7121 -#include <linux/tty.h>
7122 -#include <linux/errno.h>
7123 -#include <linux/string.h>
7124 -#include <linux/signal.h>
7125 -#include <linux/ioctl.h>
7126 -#include <linux/skbuff.h>
7128 -#include <net/bluetooth/bluetooth.h>
7129 -#include <net/bluetooth/bluez.h>
7130 -#include <net/bluetooth/hci_core.h>
7131 -#include <net/bluetooth/hci_uart.h>
7133 -#ifndef HCI_UART_DEBUG
7135 -#define DBG( A... )
7137 -#define DMP( A... )
7140 -/* ------- Interface to HCI layer ------ */
7141 -/* Initialize device */
7142 -int n_hci_open(struct hci_dev *hdev)
7144 - DBG("%s %p", hdev->name, hdev);
7146 - /* Nothing to do for UART driver */
7148 - hdev->flags |= HCI_RUNNING;
7154 -int n_hci_flush(struct hci_dev *hdev)
7156 - struct n_hci *n_hci = (struct n_hci *) hdev->driver_data;
7157 - struct tty_struct *tty = n_hci->tty;
7159 - DBG("hdev %p tty %p", hdev, tty);
7161 - /* Drop TX queue */
7162 - skb_queue_purge(&n_hci->txq);
7164 - /* Flush any pending characters in the driver and discipline. */
7165 - if (tty->ldisc.flush_buffer)
7166 - tty->ldisc.flush_buffer(tty);
7168 - if (tty->driver.flush_buffer)
7169 - tty->driver.flush_buffer(tty);
7175 -int n_hci_close(struct hci_dev *hdev)
7177 - DBG("hdev %p", hdev);
7179 - hdev->flags &= ~HCI_RUNNING;
7181 - n_hci_flush(hdev);
7186 -int n_hci_tx_wakeup(struct n_hci *n_hci)
7188 - register struct tty_struct *tty = n_hci->tty;
7190 - if (test_and_set_bit(TRANS_SENDING, &n_hci->tx_state)) {
7191 - set_bit(TRANS_WAKEUP, &n_hci->tx_state);
7197 - register struct sk_buff *skb;
7200 - clear_bit(TRANS_WAKEUP, &n_hci->tx_state);
7202 - if (!(skb = skb_dequeue(&n_hci->txq)))
7205 - DMP(skb->data, skb->len);
7207 - /* Send frame to TTY driver */
7208 - tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
7209 - len = tty->driver.write(tty, 0, skb->data, skb->len);
7211 - n_hci->hdev.stat.byte_tx += len;
7213 - DBG("sent %d", len);
7215 - if (len == skb->len) {
7216 - /* Full frame was sent */
7219 - /* Subtract sent part and requeue */
7220 - skb_pull(skb, len);
7221 - skb_queue_head(&n_hci->txq, skb);
7223 - } while (test_bit(TRANS_WAKEUP, &n_hci->tx_state));
7224 - clear_bit(TRANS_SENDING, &n_hci->tx_state);
7229 -/* Send frames from HCI layer */
7230 -int n_hci_send_frame(struct sk_buff *skb)
7232 - struct hci_dev* hdev = (struct hci_dev *) skb->dev;
7233 - struct tty_struct *tty;
7234 - struct n_hci *n_hci;
7237 - ERR("Frame for uknown device (hdev=NULL)");
7241 - if (!(hdev->flags & HCI_RUNNING))
7244 - n_hci = (struct n_hci *) hdev->driver_data;
7245 - tty = n_hci2tty(n_hci);
7247 - DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
7249 - switch (skb->pkt_type) {
7250 - case HCI_COMMAND_PKT:
7251 - hdev->stat.cmd_tx++;
7254 - case HCI_ACLDATA_PKT:
7255 - hdev->stat.acl_tx++;
7258 - case HCI_SCODATA_PKT:
7259 - hdev->stat.cmd_tx++;
7263 - /* Prepend skb with frame type and queue */
7264 - memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
7265 - skb_queue_tail(&n_hci->txq, skb);
7267 - n_hci_tx_wakeup(n_hci);
7272 -/* ------ LDISC part ------ */
7276 - * Called when line discipline changed to N_HCI.
7279 - * tty pointer to tty info structure
7281 - * 0 if success, otherwise error code
7283 -static int n_hci_tty_open(struct tty_struct *tty)
7285 - struct n_hci *n_hci = tty2n_hci(tty);
7286 - struct hci_dev *hdev;
7288 - DBG("tty %p", tty);
7293 - if (!(n_hci = kmalloc(sizeof(struct n_hci), GFP_KERNEL))) {
7294 - ERR("Can't allocate controll structure");
7297 - memset(n_hci, 0, sizeof(struct n_hci));
7299 - /* Initialize and register HCI device */
7300 - hdev = &n_hci->hdev;
7302 - hdev->type = HCI_UART;
7303 - hdev->driver_data = n_hci;
7305 - hdev->open = n_hci_open;
7306 - hdev->close = n_hci_close;
7307 - hdev->flush = n_hci_flush;
7308 - hdev->send = n_hci_send_frame;
7310 - if (hci_register_dev(hdev) < 0) {
7311 - ERR("Can't register HCI device %s", hdev->name);
7316 - tty->disc_data = n_hci;
7319 - spin_lock_init(&n_hci->rx_lock);
7320 - n_hci->rx_state = WAIT_PACKET_TYPE;
7322 - skb_queue_head_init(&n_hci->txq);
7324 - MOD_INC_USE_COUNT;
7326 - /* Flush any pending characters in the driver and discipline. */
7327 - if (tty->ldisc.flush_buffer)
7328 - tty->ldisc.flush_buffer(tty);
7330 - if (tty->driver.flush_buffer)
7331 - tty->driver.flush_buffer(tty);
7336 -/* n_hci_tty_close()
7338 - * Called when the line discipline is changed to something
7339 - * else, the tty is closed, or the tty detects a hangup.
7341 -static void n_hci_tty_close(struct tty_struct *tty)
7343 - struct n_hci *n_hci = tty2n_hci(tty);
7344 - struct hci_dev *hdev = &n_hci->hdev;
7346 - DBG("tty %p hdev %p", tty, hdev);
7348 - if (n_hci != NULL) {
7349 - n_hci_close(hdev);
7351 - if (hci_unregister_dev(hdev) < 0) {
7352 - ERR("Can't unregister HCI device %s",hdev->name);
7355 - hdev->driver_data = NULL;
7356 - tty->disc_data = NULL;
7359 - MOD_DEC_USE_COUNT;
7363 -/* n_hci_tty_wakeup()
7365 - * Callback for transmit wakeup. Called when low level
7366 - * device driver can accept more send data.
7368 - * Arguments: tty pointer to associated tty instance data
7369 - * Return Value: None
7371 -static void n_hci_tty_wakeup( struct tty_struct *tty )
7373 - struct n_hci *n_hci = tty2n_hci(tty);
7380 - tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
7382 - if (tty != n_hci->tty)
7385 - n_hci_tx_wakeup(n_hci);
7388 -/* n_hci_tty_room()
7390 - * Callback function from tty driver. Return the amount of
7391 - * space left in the receiver's buffer to decide if remote
7392 - * transmitter is to be throttled.
7394 - * Arguments: tty pointer to associated tty instance data
7395 - * Return Value: number of bytes left in receive buffer
7397 -static int n_hci_tty_room (struct tty_struct *tty)
7402 -static inline int n_hci_check_data_len(struct n_hci *n_hci, int len)
7404 - register int room = skb_tailroom(n_hci->rx_skb);
7406 - DBG("len %d room %d", len, room);
7408 - DMP(n_hci->rx_skb->data, n_hci->rx_skb->len);
7409 - hci_recv_frame(n_hci->rx_skb);
7410 - } else if (len > room) {
7411 - ERR("Data length is to large");
7412 - kfree_skb(n_hci->rx_skb);
7413 - n_hci->hdev.stat.err_rx++;
7415 - n_hci->rx_state = WAIT_DATA;
7416 - n_hci->rx_count = len;
7420 - n_hci->rx_state = WAIT_PACKET_TYPE;
7421 - n_hci->rx_skb = NULL;
7422 - n_hci->rx_count = 0;
7426 -static inline void n_hci_rx(struct n_hci *n_hci, const __u8 * data, char *flags, int count)
7428 - register const char *ptr;
7429 - hci_event_hdr *eh;
7432 - register int len, type, dlen;
7434 - DBG("count %d state %ld rx_count %ld", count, n_hci->rx_state, n_hci->rx_count);
7436 - n_hci->hdev.stat.byte_rx += count;
7440 - if (n_hci->rx_count) {
7441 - len = MIN(n_hci->rx_count, count);
7442 - memcpy(skb_put(n_hci->rx_skb, len), ptr, len);
7443 - n_hci->rx_count -= len; count -= len; ptr += len;
7445 - if (n_hci->rx_count)
7448 - switch (n_hci->rx_state) {
7450 - DBG("Complete data");
7452 - DMP(n_hci->rx_skb->data, n_hci->rx_skb->len);
7454 - hci_recv_frame(n_hci->rx_skb);
7456 - n_hci->rx_state = WAIT_PACKET_TYPE;
7457 - n_hci->rx_skb = NULL;
7460 - case WAIT_EVENT_HDR:
7461 - eh = (hci_event_hdr *) n_hci->rx_skb->data;
7463 - DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
7465 - n_hci_check_data_len(n_hci, eh->plen);
7468 - case WAIT_ACL_HDR:
7469 - ah = (hci_acl_hdr *) n_hci->rx_skb->data;
7470 - dlen = __le16_to_cpu(ah->dlen);
7472 - DBG("ACL header: dlen %d", dlen);
7474 - n_hci_check_data_len(n_hci, dlen);
7477 - case WAIT_SCO_HDR:
7478 - sh = (hci_sco_hdr *) n_hci->rx_skb->data;
7480 - DBG("SCO header: dlen %d", sh->dlen);
7482 - n_hci_check_data_len(n_hci, sh->dlen);
7487 - /* WAIT_PACKET_TYPE */
7489 - case HCI_EVENT_PKT:
7490 - DBG("Event packet");
7491 - n_hci->rx_state = WAIT_EVENT_HDR;
7492 - n_hci->rx_count = HCI_EVENT_HDR_SIZE;
7493 - type = HCI_EVENT_PKT;
7496 - case HCI_ACLDATA_PKT:
7497 - DBG("ACL packet");
7498 - n_hci->rx_state = WAIT_ACL_HDR;
7499 - n_hci->rx_count = HCI_ACL_HDR_SIZE;
7500 - type = HCI_ACLDATA_PKT;
7503 - case HCI_SCODATA_PKT:
7504 - DBG("SCO packet");
7505 - n_hci->rx_state = WAIT_SCO_HDR;
7506 - n_hci->rx_count = HCI_SCO_HDR_SIZE;
7507 - type = HCI_SCODATA_PKT;
7511 - ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
7512 - n_hci->hdev.stat.err_rx++;
7518 - /* Allocate packet */
7519 - if (!(n_hci->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
7520 - ERR("Can't allocate mem for new packet");
7522 - n_hci->rx_state = WAIT_PACKET_TYPE;
7523 - n_hci->rx_count = 0;
7526 - n_hci->rx_skb->dev = (void *) &n_hci->hdev;
7527 - n_hci->rx_skb->pkt_type = type;
7531 -/* n_hci_tty_receive()
7533 - * Called by tty low level driver when receive data is
7536 - * Arguments: tty pointer to tty isntance data
7537 - * data pointer to received data
7538 - * flags pointer to flags for data
7539 - * count count of received data in bytes
7541 - * Return Value: None
7543 -static void n_hci_tty_receive(struct tty_struct *tty, const __u8 * data, char *flags, int count)
7545 - struct n_hci *n_hci = tty2n_hci(tty);
7547 - if (!n_hci || tty != n_hci->tty)
7550 - spin_lock(&n_hci->rx_lock);
7551 - n_hci_rx(n_hci, data, flags, count);
7552 - spin_unlock(&n_hci->rx_lock);
7554 - if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver.unthrottle)
7555 - tty->driver.unthrottle(tty);
7558 -/* n_hci_tty_ioctl()
7560 - * Process IOCTL system call for the tty device.
7564 - * tty pointer to tty instance data
7565 - * file pointer to open file object for device
7566 - * cmd IOCTL command code
7567 - * arg argument for IOCTL call (cmd dependent)
7569 - * Return Value: Command dependent
7571 -static int n_hci_tty_ioctl (struct tty_struct *tty, struct file * file,
7572 - unsigned int cmd, unsigned long arg)
7574 - struct n_hci *n_hci = tty2n_hci(tty);
7579 - /* Verify the status of the device */
7585 - error = n_tty_ioctl(tty, file, cmd, arg);
7593 - * We don't provide read/write/poll interface for user space.
7595 -static ssize_t n_hci_tty_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr)
7599 -static ssize_t n_hci_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
7603 -static unsigned int n_hci_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
7608 -int __init n_hci_init(void)
7610 - static struct tty_ldisc n_hci_ldisc;
7613 - INF("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
7615 - INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
7617 - /* Register the tty discipline */
7619 - memset(&n_hci_ldisc, 0, sizeof (n_hci_ldisc));
7620 - n_hci_ldisc.magic = TTY_LDISC_MAGIC;
7621 - n_hci_ldisc.name = "n_hci";
7622 - n_hci_ldisc.open = n_hci_tty_open;
7623 - n_hci_ldisc.close = n_hci_tty_close;
7624 - n_hci_ldisc.read = n_hci_tty_read;
7625 - n_hci_ldisc.write = n_hci_tty_write;
7626 - n_hci_ldisc.ioctl = n_hci_tty_ioctl;
7627 - n_hci_ldisc.poll = n_hci_tty_poll;
7628 - n_hci_ldisc.receive_room= n_hci_tty_room;
7629 - n_hci_ldisc.receive_buf = n_hci_tty_receive;
7630 - n_hci_ldisc.write_wakeup= n_hci_tty_wakeup;
7632 - if ((err = tty_register_ldisc(N_HCI, &n_hci_ldisc))) {
7633 - ERR("Can't register HCI line discipline (%d)", err);
7640 -void n_hci_cleanup(void)
7644 - /* Release tty registration of line discipline */
7645 - if ((err = tty_register_ldisc(N_HCI, NULL)))
7646 - ERR("Can't unregister HCI line discipline (%d)", err);
7649 -module_init(n_hci_init);
7650 -module_exit(n_hci_cleanup);
7652 -MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
7653 -MODULE_DESCRIPTION("BlueZ HCI UART driver ver " VERSION);
7654 -MODULE_LICENSE("GPL");
7655 diff -urN linux-2.4.18/drivers/bluetooth/hci_uart.h linux-2.4.18-mh15/drivers/bluetooth/hci_uart.h
7656 --- linux-2.4.18/drivers/bluetooth/hci_uart.h 1970-01-01 01:00:00.000000000 +0100
7657 +++ linux-2.4.18-mh15/drivers/bluetooth/hci_uart.h 2004-08-01 16:26:23.000000000 +0200
7660 + BlueZ - Bluetooth protocol stack for Linux
7661 + Copyright (C) 2000-2001 Qualcomm Incorporated
7663 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
7665 + This program is free software; you can redistribute it and/or modify
7666 + it under the terms of the GNU General Public License version 2 as
7667 + published by the Free Software Foundation;
7669 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7670 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7671 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
7672 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
7673 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
7674 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
7675 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
7676 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
7678 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
7679 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
7680 + SOFTWARE IS DISCLAIMED.
7684 + * $Id: hci_uart.h,v 1.2 2002/09/09 01:17:32 maxk Exp $
7692 +#define HCIUARTSETPROTO _IOW('U', 200, int)
7693 +#define HCIUARTGETPROTO _IOR('U', 201, int)
7695 +/* UART protocols */
7696 +#define HCI_UART_MAX_PROTO 4
7698 +#define HCI_UART_H4 0
7699 +#define HCI_UART_BCSP 1
7700 +#define HCI_UART_3WIRE 2
7701 +#define HCI_UART_H4DS 3
7706 +struct hci_uart_proto {
7708 + int (*open)(struct hci_uart *hu);
7709 + int (*close)(struct hci_uart *hu);
7710 + int (*flush)(struct hci_uart *hu);
7711 + int (*recv)(struct hci_uart *hu, void *data, int len);
7712 + int (*enqueue)(struct hci_uart *hu, struct sk_buff *skb);
7713 + struct sk_buff *(*dequeue)(struct hci_uart *hu);
7717 + struct tty_struct *tty;
7718 + struct hci_dev hdev;
7719 + unsigned long flags;
7721 + struct hci_uart_proto *proto;
7724 + struct sk_buff *tx_skb;
7725 + unsigned long tx_state;
7726 + spinlock_t rx_lock;
7729 +/* HCI_UART flag bits */
7730 +#define HCI_UART_PROTO_SET 0
7733 +#define HCI_UART_SENDING 1
7734 +#define HCI_UART_TX_WAKEUP 2
7736 +int hci_uart_register_proto(struct hci_uart_proto *p);
7737 +int hci_uart_unregister_proto(struct hci_uart_proto *p);
7738 +int hci_uart_tx_wakeup(struct hci_uart *hu);
7740 +#endif /* __KERNEL__ */
7741 diff -urN linux-2.4.18/drivers/bluetooth/hci_usb.c linux-2.4.18-mh15/drivers/bluetooth/hci_usb.c
7742 --- linux-2.4.18/drivers/bluetooth/hci_usb.c 2001-09-07 18:28:38.000000000 +0200
7743 +++ linux-2.4.18-mh15/drivers/bluetooth/hci_usb.c 2004-08-01 16:26:23.000000000 +0200
7746 - BlueZ - Bluetooth protocol stack for Linux
7747 + HCI USB driver for Linux Bluetooth protocol stack (BlueZ)
7748 Copyright (C) 2000-2001 Qualcomm Incorporated
7750 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
7752 + Copyright (C) 2003 Maxim Krasnyansky <maxk@qualcomm.com>
7754 This program is free software; you can redistribute it and/or modify
7755 it under the terms of the GNU General Public License version 2 as
7756 published by the Free Software Foundation;
7757 @@ -23,598 +24,938 @@
7761 - * BlueZ HCI USB driver.
7762 * Based on original USB Bluetooth driver for Linux kernel
7763 * Copyright (c) 2000 Greg Kroah-Hartman <greg@kroah.com>
7764 * Copyright (c) 2000 Mark Douglas Corner <mcorner@umich.edu>
7766 - * $Id: hci_usb.c,v 1.5 2001/07/05 18:42:44 maxk Exp $
7767 + * $Id: hci_usb.c,v 1.8 2002/07/18 17:23:09 maxk Exp $
7769 -#define VERSION "1.0"
7770 +#define VERSION "2.7"
7772 #include <linux/config.h>
7773 #include <linux/module.h>
7775 #include <linux/version.h>
7776 -#include <linux/config.h>
7777 #include <linux/kernel.h>
7778 #include <linux/init.h>
7779 #include <linux/sched.h>
7780 +#include <linux/unistd.h>
7781 #include <linux/types.h>
7782 -#include <linux/fcntl.h>
7783 #include <linux/interrupt.h>
7784 -#include <linux/ptrace.h>
7785 -#include <linux/poll.h>
7787 #include <linux/slab.h>
7788 -#include <linux/tty.h>
7789 #include <linux/errno.h>
7790 #include <linux/string.h>
7791 -#include <linux/signal.h>
7792 -#include <linux/ioctl.h>
7793 #include <linux/skbuff.h>
7795 #include <linux/usb.h>
7797 #include <net/bluetooth/bluetooth.h>
7798 -#include <net/bluetooth/bluez.h>
7799 #include <net/bluetooth/hci_core.h>
7800 -#include <net/bluetooth/hci_usb.h>
7802 +#include "hci_usb.h"
7804 #ifndef HCI_USB_DEBUG
7806 -#define DBG( A... )
7808 -#define DMP( A... )
7810 +#define BT_DBG( A... )
7812 +#define BT_DMP( A... )
7815 -static struct usb_device_id usb_bluetooth_ids [] = {
7816 +#ifndef CONFIG_BLUEZ_HCIUSB_ZERO_PACKET
7817 +#undef USB_ZERO_PACKET
7818 +#define USB_ZERO_PACKET 0
7821 +static struct usb_driver hci_usb_driver;
7823 +static struct usb_device_id bluetooth_ids[] = {
7824 + /* Generic Bluetooth USB device */
7825 { USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) },
7827 + /* AVM BlueFRITZ! USB v2.0 */
7828 + { USB_DEVICE(0x057c, 0x3800) },
7830 + /* Bluetooth Ultraport Module from IBM */
7831 + { USB_DEVICE(0x04bf, 0x030a) },
7833 + /* ALPS Modules with non-standard id */
7834 + { USB_DEVICE(0x044e, 0x3001) },
7835 + { USB_DEVICE(0x044e, 0x3002) },
7837 + /* Ericsson with non-standard id */
7838 + { USB_DEVICE(0x0bdb, 0x1002) },
7840 { } /* Terminating entry */
7843 -MODULE_DEVICE_TABLE (usb, usb_bluetooth_ids);
7844 +MODULE_DEVICE_TABLE (usb, bluetooth_ids);
7846 -static int hci_usb_ctrl_msg(struct hci_usb *husb, struct sk_buff *skb);
7847 -static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb);
7848 +static struct usb_device_id blacklist_ids[] = {
7849 + /* Broadcom BCM2033 without firmware */
7850 + { USB_DEVICE(0x0a5c, 0x2033), driver_info: HCI_IGNORE },
7852 -static void hci_usb_unlink_urbs(struct hci_usb *husb)
7853 + /* Broadcom BCM2035 */
7854 + { USB_DEVICE(0x0a5c, 0x200a), driver_info: HCI_RESET },
7856 + /* ISSC Bluetooth Adapter v3.1 */
7857 + { USB_DEVICE(0x1131, 0x1001), driver_info: HCI_RESET },
7859 + /* Digianswer device */
7860 + { USB_DEVICE(0x08fd, 0x0001), driver_info: HCI_DIGIANSWER },
7862 + /* RTX Telecom based adapter with buggy SCO support */
7863 + { USB_DEVICE(0x0400, 0x0807), driver_info: HCI_BROKEN_ISOC },
7865 + { } /* Terminating entry */
7868 +struct _urb *_urb_alloc(int isoc, int gfp)
7870 - usb_unlink_urb(husb->read_urb);
7871 - usb_unlink_urb(husb->intr_urb);
7872 - usb_unlink_urb(husb->ctrl_urb);
7873 - usb_unlink_urb(husb->write_urb);
7874 + struct _urb *_urb = kmalloc(sizeof(struct _urb) +
7875 + sizeof(iso_packet_descriptor_t) * isoc, gfp);
7877 + memset(_urb, 0, sizeof(*_urb));
7878 + spin_lock_init(&_urb->urb.lock);
7883 +struct _urb *_urb_dequeue(struct _urb_queue *q)
7885 + struct _urb *_urb = NULL;
7886 + unsigned long flags;
7887 + spin_lock_irqsave(&q->lock, flags);
7889 + struct list_head *head = &q->head;
7890 + struct list_head *next = head->next;
7891 + if (next != head) {
7892 + _urb = list_entry(next, struct _urb, list);
7893 + list_del(next); _urb->queue = NULL;
7896 + spin_unlock_irqrestore(&q->lock, flags);
7900 -static void hci_usb_free_bufs(struct hci_usb *husb)
7901 +static void hci_usb_rx_complete(struct urb *urb);
7902 +static void hci_usb_tx_complete(struct urb *urb);
7904 +#define __pending_tx(husb, type) (&husb->pending_tx[type-1])
7905 +#define __pending_q(husb, type) (&husb->pending_q[type-1])
7906 +#define __completed_q(husb, type) (&husb->completed_q[type-1])
7907 +#define __transmit_q(husb, type) (&husb->transmit_q[type-1])
7908 +#define __reassembly(husb, type) (husb->reassembly[type-1])
7910 +static inline struct _urb *__get_completed(struct hci_usb *husb, int type)
7912 - if (husb->read_urb) {
7913 - if (husb->read_urb->transfer_buffer)
7914 - kfree(husb->read_urb->transfer_buffer);
7915 - usb_free_urb(husb->read_urb);
7917 + return _urb_dequeue(__completed_q(husb, type));
7920 - if (husb->intr_urb) {
7921 - if (husb->intr_urb->transfer_buffer)
7922 - kfree(husb->intr_urb->transfer_buffer);
7923 - usb_free_urb(husb->intr_urb);
7924 +#ifdef CONFIG_BLUEZ_HCIUSB_SCO
7925 +static void __fill_isoc_desc(struct urb *urb, int len, int mtu)
7927 + int offset = 0, i;
7929 + BT_DBG("len %d mtu %d", len, mtu);
7931 + for (i=0; i < HCI_MAX_ISOC_FRAMES && len >= mtu; i++, offset += mtu, len -= mtu) {
7932 + urb->iso_frame_desc[i].offset = offset;
7933 + urb->iso_frame_desc[i].length = mtu;
7934 + BT_DBG("desc %d offset %d len %d", i, offset, mtu);
7936 + if (len && i < HCI_MAX_ISOC_FRAMES) {
7937 + urb->iso_frame_desc[i].offset = offset;
7938 + urb->iso_frame_desc[i].length = len;
7939 + BT_DBG("desc %d offset %d len %d", i, offset, len);
7942 + urb->number_of_packets = i;
7946 - if (husb->ctrl_urb)
7947 - usb_free_urb(husb->ctrl_urb);
7948 +static int hci_usb_intr_rx_submit(struct hci_usb *husb)
7950 + struct _urb *_urb;
7952 + int err, pipe, interval, size;
7955 + BT_DBG("%s", husb->hdev.name);
7957 + size = husb->intr_in_ep->wMaxPacketSize;
7959 + buf = kmalloc(size, GFP_ATOMIC);
7963 + _urb = _urb_alloc(0, GFP_ATOMIC);
7968 + _urb->type = HCI_EVENT_PKT;
7969 + _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
7972 + pipe = usb_rcvintpipe(husb->udev, husb->intr_in_ep->bEndpointAddress);
7973 + interval = husb->intr_in_ep->bInterval;
7974 + FILL_INT_URB(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb, interval);
7976 + err = usb_submit_urb(urb);
7978 + BT_ERR("%s intr rx submit failed urb %p err %d",
7979 + husb->hdev.name, urb, err);
7980 + _urb_unlink(_urb);
7987 - if (husb->write_urb)
7988 - usb_free_urb(husb->write_urb);
7989 +static int hci_usb_bulk_rx_submit(struct hci_usb *husb)
7991 + struct _urb *_urb;
7993 + int err, pipe, size = HCI_MAX_FRAME_SIZE;
7996 + buf = kmalloc(size, GFP_ATOMIC);
8000 + _urb = _urb_alloc(0, GFP_ATOMIC);
8005 + _urb->type = HCI_ACLDATA_PKT;
8006 + _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
8009 + pipe = usb_rcvbulkpipe(husb->udev, husb->bulk_in_ep->bEndpointAddress);
8010 + FILL_BULK_URB(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb);
8011 + urb->transfer_flags = USB_QUEUE_BULK;
8013 + BT_DBG("%s urb %p", husb->hdev.name, urb);
8015 + err = usb_submit_urb(urb);
8017 + BT_ERR("%s bulk rx submit failed urb %p err %d",
8018 + husb->hdev.name, urb, err);
8019 + _urb_unlink(_urb);
8026 - if (husb->intr_skb)
8027 - kfree_skb(husb->intr_skb);
8028 +#ifdef CONFIG_BLUEZ_HCIUSB_SCO
8029 +static int hci_usb_isoc_rx_submit(struct hci_usb *husb)
8031 + struct _urb *_urb;
8033 + int err, mtu, size;
8036 + mtu = husb->isoc_in_ep->wMaxPacketSize;
8037 + size = mtu * HCI_MAX_ISOC_FRAMES;
8039 + buf = kmalloc(size, GFP_ATOMIC);
8043 + _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
8048 + _urb->type = HCI_SCODATA_PKT;
8049 + _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
8053 + urb->context = husb;
8054 + urb->dev = husb->udev;
8055 + urb->pipe = usb_rcvisocpipe(husb->udev, husb->isoc_in_ep->bEndpointAddress);
8056 + urb->complete = hci_usb_rx_complete;
8058 + urb->transfer_buffer_length = size;
8059 + urb->transfer_buffer = buf;
8060 + urb->transfer_flags = USB_ISO_ASAP;
8062 + __fill_isoc_desc(urb, size, mtu);
8064 + BT_DBG("%s urb %p", husb->hdev.name, urb);
8066 + err = usb_submit_urb(urb);
8068 + BT_ERR("%s isoc rx submit failed urb %p err %d",
8069 + husb->hdev.name, urb, err);
8070 + _urb_unlink(_urb);
8078 -/* ------- Interface to HCI layer ------ */
8079 /* Initialize device */
8080 -int hci_usb_open(struct hci_dev *hdev)
8081 +static int hci_usb_open(struct hci_dev *hdev)
8083 struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
8086 + unsigned long flags;
8088 + BT_DBG("%s", hdev->name);
8090 - DBG("%s", hdev->name);
8091 + if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
8094 - husb->read_urb->dev = husb->udev;
8095 - if ((status = usb_submit_urb(husb->read_urb)))
8096 - DBG("read submit failed. %d", status);
8097 + MOD_INC_USE_COUNT;
8099 - husb->intr_urb->dev = husb->udev;
8100 - if ((status = usb_submit_urb(husb->intr_urb)))
8101 - DBG("interrupt submit failed. %d", status);
8102 + write_lock_irqsave(&husb->completion_lock, flags);
8104 - hdev->flags |= HCI_RUNNING;
8105 + err = hci_usb_intr_rx_submit(husb);
8107 + for (i = 0; i < HCI_MAX_BULK_RX; i++)
8108 + hci_usb_bulk_rx_submit(husb);
8110 +#ifdef CONFIG_BLUEZ_HCIUSB_SCO
8111 + if (husb->isoc_iface)
8112 + for (i = 0; i < HCI_MAX_ISOC_RX; i++)
8113 + hci_usb_isoc_rx_submit(husb);
8116 + clear_bit(HCI_RUNNING, &hdev->flags);
8117 + MOD_DEC_USE_COUNT;
8121 + write_unlock_irqrestore(&husb->completion_lock, flags);
8126 -int hci_usb_flush(struct hci_dev *hdev)
8127 +static int hci_usb_flush(struct hci_dev *hdev)
8129 struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
8132 - DBG("%s", hdev->name);
8134 - /* Drop TX queues */
8135 - skb_queue_purge(&husb->tx_ctrl_q);
8136 - skb_queue_purge(&husb->tx_write_q);
8137 + BT_DBG("%s", hdev->name);
8139 + for (i=0; i < 4; i++)
8140 + skb_queue_purge(&husb->transmit_q[i]);
8145 -int hci_usb_close(struct hci_dev *hdev)
8146 +static void hci_usb_unlink_urbs(struct hci_usb *husb)
8148 - struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
8151 - DBG("%s", hdev->name);
8152 + BT_DBG("%s", husb->hdev.name);
8154 - hdev->flags &= ~HCI_RUNNING;
8155 - hci_usb_unlink_urbs(husb);
8156 + for (i=0; i < 4; i++) {
8157 + struct _urb *_urb;
8160 + /* Kill pending requests */
8161 + while ((_urb = _urb_dequeue(&husb->pending_q[i]))) {
8163 + BT_DBG("%s unlinking _urb %p type %d urb %p",
8164 + husb->hdev.name, _urb, _urb->type, urb);
8165 + usb_unlink_urb(urb);
8166 + _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
8169 - hci_usb_flush(hdev);
8170 + /* Release completed requests */
8171 + while ((_urb = _urb_dequeue(&husb->completed_q[i]))) {
8173 + BT_DBG("%s freeing _urb %p type %d urb %p",
8174 + husb->hdev.name, _urb, _urb->type, urb);
8175 + if (urb->setup_packet)
8176 + kfree(urb->setup_packet);
8177 + if (urb->transfer_buffer)
8178 + kfree(urb->transfer_buffer);
8183 + /* Release reassembly buffers */
8184 + if (husb->reassembly[i]) {
8185 + kfree_skb(husb->reassembly[i]);
8186 + husb->reassembly[i] = NULL;
8191 -void hci_usb_ctrl_wakeup(struct hci_usb *husb)
8193 +static int hci_usb_close(struct hci_dev *hdev)
8195 - struct sk_buff *skb;
8196 + struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
8197 + unsigned long flags;
8199 + if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
8202 - if (test_and_set_bit(HCI_TX_CTRL, &husb->tx_state))
8204 + BT_DBG("%s", hdev->name);
8206 - DBG("%s", husb->hdev.name);
8207 + write_lock_irqsave(&husb->completion_lock, flags);
8209 + hci_usb_unlink_urbs(husb);
8210 + hci_usb_flush(hdev);
8212 - if (!(skb = skb_dequeue(&husb->tx_ctrl_q)))
8214 + write_unlock_irqrestore(&husb->completion_lock, flags);
8216 - if (hci_usb_ctrl_msg(husb, skb)){
8220 + MOD_DEC_USE_COUNT;
8224 - DMP(skb->data, skb->len);
8225 +static int __tx_submit(struct hci_usb *husb, struct _urb *_urb)
8227 + struct urb *urb = &_urb->urb;
8230 - husb->hdev.stat.byte_tx += skb->len;
8232 + BT_DBG("%s urb %p type %d", husb->hdev.name, urb, _urb->type);
8234 + _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
8235 + err = usb_submit_urb(urb);
8237 + BT_ERR("%s tx submit failed urb %p type %d err %d",
8238 + husb->hdev.name, urb, _urb->type, err);
8239 + _urb_unlink(_urb);
8240 + _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
8242 + atomic_inc(__pending_tx(husb, _urb->type));
8245 - clear_bit(HCI_TX_CTRL, &husb->tx_state);
8250 -void hci_usb_write_wakeup(struct hci_usb *husb)
8251 +static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
8253 - struct sk_buff *skb;
8254 + struct _urb *_urb = __get_completed(husb, skb->pkt_type);
8259 + _urb = _urb_alloc(0, GFP_ATOMIC);
8262 + _urb->type = skb->pkt_type;
8264 + dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
8270 + dr = (void *) _urb->urb.setup_packet;
8272 - if (test_and_set_bit(HCI_TX_WRITE, &husb->tx_state))
8274 + dr->requesttype = husb->ctrl_req;
8278 + dr->length = __cpu_to_le16(skb->len);
8280 - DBG("%s", husb->hdev.name);
8282 + FILL_CONTROL_URB(urb, husb->udev, usb_sndctrlpipe(husb->udev, 0),
8283 + (void *) dr, skb->data, skb->len, hci_usb_tx_complete, husb);
8285 - if (!(skb = skb_dequeue(&husb->tx_write_q)))
8287 + BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
8290 + return __tx_submit(husb, _urb);
8293 - if (hci_usb_write_msg(husb, skb)) {
8294 - skb_queue_head(&husb->tx_write_q, skb);
8296 +static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
8298 + struct _urb *_urb = __get_completed(husb, skb->pkt_type);
8303 + _urb = _urb_alloc(0, GFP_ATOMIC);
8306 + _urb->type = skb->pkt_type;
8309 - DMP(skb->data, skb->len);
8311 + pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep->bEndpointAddress);
8312 + FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,
8313 + hci_usb_tx_complete, husb);
8314 + urb->transfer_flags = USB_QUEUE_BULK | USB_ZERO_PACKET;
8316 - husb->hdev.stat.byte_tx += skb->len;
8318 + BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
8321 - clear_bit(HCI_TX_WRITE, &husb->tx_state);
8324 + return __tx_submit(husb, _urb);
8327 -/* Send frames from HCI layer */
8328 -int hci_usb_send_frame(struct sk_buff *skb)
8329 +#ifdef CONFIG_BLUEZ_HCIUSB_SCO
8330 +static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb)
8332 - struct hci_dev *hdev = (struct hci_dev *) skb->dev;
8333 - struct hci_usb *husb;
8336 - ERR("frame for uknown device (hdev=NULL)");
8338 + struct _urb *_urb = __get_completed(husb, skb->pkt_type);
8342 + _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
8345 + _urb->type = skb->pkt_type;
8348 - if (!(hdev->flags & HCI_RUNNING))
8350 + BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
8352 - husb = (struct hci_usb *) hdev->driver_data;
8355 + urb->context = husb;
8356 + urb->dev = husb->udev;
8357 + urb->pipe = usb_sndisocpipe(husb->udev, husb->isoc_out_ep->bEndpointAddress);
8358 + urb->complete = hci_usb_tx_complete;
8359 + urb->transfer_flags = USB_ISO_ASAP;
8361 - DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
8362 + urb->transfer_buffer = skb->data;
8363 + urb->transfer_buffer_length = skb->len;
8365 + __fill_isoc_desc(urb, skb->len, husb->isoc_out_ep->wMaxPacketSize);
8367 - switch (skb->pkt_type) {
8368 - case HCI_COMMAND_PKT:
8369 - skb_queue_tail(&husb->tx_ctrl_q, skb);
8370 - hci_usb_ctrl_wakeup(husb);
8371 - hdev->stat.cmd_tx++;
8374 - case HCI_ACLDATA_PKT:
8375 - skb_queue_tail(&husb->tx_write_q, skb);
8376 - hci_usb_write_wakeup(husb);
8377 - hdev->stat.acl_tx++;
8380 - case HCI_SCODATA_PKT:
8381 - return -EOPNOTSUPP;
8386 + return __tx_submit(husb, _urb);
8390 -/* ---------- USB ------------- */
8392 -static void hci_usb_ctrl(struct urb *urb)
8393 +static void hci_usb_tx_process(struct hci_usb *husb)
8395 - struct sk_buff *skb = (struct sk_buff *) urb->context;
8396 - struct hci_dev *hdev;
8397 - struct hci_usb *husb;
8398 + struct sk_buff_head *q;
8399 + struct sk_buff *skb;
8403 - hdev = (struct hci_dev *) skb->dev;
8404 - husb = (struct hci_usb *) hdev->driver_data;
8405 + BT_DBG("%s", husb->hdev.name);
8407 - DBG("%s", hdev->name);
8409 + clear_bit(HCI_USB_TX_WAKEUP, &husb->state);
8412 - DBG("%s ctrl status: %d", hdev->name, urb->status);
8413 + /* Process command queue */
8414 + q = __transmit_q(husb, HCI_COMMAND_PKT);
8415 + if (!atomic_read(__pending_tx(husb, HCI_COMMAND_PKT)) &&
8416 + (skb = skb_dequeue(q))) {
8417 + if (hci_usb_send_ctrl(husb, skb) < 0)
8418 + skb_queue_head(q, skb);
8421 - clear_bit(HCI_TX_CTRL, &husb->tx_state);
8423 +#ifdef CONFIG_BLUEZ_HCIUSB_SCO
8424 + /* Process SCO queue */
8425 + q = __transmit_q(husb, HCI_SCODATA_PKT);
8426 + if (atomic_read(__pending_tx(husb, HCI_SCODATA_PKT)) < HCI_MAX_ISOC_TX &&
8427 + (skb = skb_dequeue(q))) {
8428 + if (hci_usb_send_isoc(husb, skb) < 0)
8429 + skb_queue_head(q, skb);
8433 + /* Process ACL queue */
8434 + q = __transmit_q(husb, HCI_ACLDATA_PKT);
8435 + while (atomic_read(__pending_tx(husb, HCI_ACLDATA_PKT)) < HCI_MAX_BULK_TX &&
8436 + (skb = skb_dequeue(q))) {
8437 + if (hci_usb_send_bulk(husb, skb) < 0) {
8438 + skb_queue_head(q, skb);
8442 + } while(test_bit(HCI_USB_TX_WAKEUP, &husb->state));
8445 - /* Wake up device */
8446 - hci_usb_ctrl_wakeup(husb);
8447 +static inline void hci_usb_tx_wakeup(struct hci_usb *husb)
8449 + /* Serialize TX queue processing to avoid data reordering */
8450 + if (!test_and_set_bit(HCI_USB_TX_PROCESS, &husb->state)) {
8451 + hci_usb_tx_process(husb);
8452 + clear_bit(HCI_USB_TX_PROCESS, &husb->state);
8454 + set_bit(HCI_USB_TX_WAKEUP, &husb->state);
8457 -static void hci_usb_bulk_write(struct urb *urb)
8458 +/* Send frames from HCI layer */
8459 +static int hci_usb_send_frame(struct sk_buff *skb)
8461 - struct sk_buff *skb = (struct sk_buff *) urb->context;
8462 - struct hci_dev *hdev;
8463 + struct hci_dev *hdev = (struct hci_dev *) skb->dev;
8464 struct hci_usb *husb;
8468 - hdev = (struct hci_dev *) skb->dev;
8469 - husb = (struct hci_usb *) hdev->driver_data;
8471 + BT_ERR("frame for uknown device (hdev=NULL)");
8475 - DBG("%s", hdev->name);
8476 + if (!test_bit(HCI_RUNNING, &hdev->flags))
8480 - DBG("%s bulk write status: %d", hdev->name, urb->status);
8481 + BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
8483 - clear_bit(HCI_TX_WRITE, &husb->tx_state);
8485 + husb = (struct hci_usb *) hdev->driver_data;
8487 - /* Wake up device */
8488 - hci_usb_write_wakeup(husb);
8489 + switch (skb->pkt_type) {
8490 + case HCI_COMMAND_PKT:
8491 + hdev->stat.cmd_tx++;
8494 + case HCI_ACLDATA_PKT:
8495 + hdev->stat.acl_tx++;
8498 +#ifdef CONFIG_BLUEZ_HCIUSB_SCO
8499 + case HCI_SCODATA_PKT:
8500 + hdev->stat.sco_tx++;
8511 -static void hci_usb_intr(struct urb *urb)
8513 - struct hci_usb *husb = (struct hci_usb *) urb->context;
8514 - unsigned char *data = urb->transfer_buffer;
8515 - register int count = urb->actual_length;
8516 - register struct sk_buff *skb = husb->intr_skb;
8517 - hci_event_hdr *eh;
8519 + read_lock(&husb->completion_lock);
8523 + skb_queue_tail(__transmit_q(husb, skb->pkt_type), skb);
8524 + hci_usb_tx_wakeup(husb);
8526 - DBG("%s count %d", husb->hdev.name, count);
8527 + read_unlock(&husb->completion_lock);
8531 - if (urb->status || !count) {
8532 - DBG("%s intr status %d, count %d", husb->hdev.name, urb->status, count);
8535 +static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int count)
8537 + BT_DBG("%s type %d data %p count %d", husb->hdev.name, type, data, count);
8539 - /* Do we really have to handle continuations here ? */
8542 - if (count < HCI_EVENT_HDR_SIZE) {
8543 - DBG("%s bad frame len %d", husb->hdev.name, count);
8546 + husb->hdev.stat.byte_rx += count;
8548 - eh = (hci_event_hdr *) data;
8549 - len = eh->plen + HCI_EVENT_HDR_SIZE;
8551 + struct sk_buff *skb = __reassembly(husb, type);
8552 + struct { int expect; } *scb;
8556 + /* Start of the frame */
8559 + case HCI_EVENT_PKT:
8560 + if (count >= HCI_EVENT_HDR_SIZE) {
8561 + hci_event_hdr *h = data;
8562 + len = HCI_EVENT_HDR_SIZE + h->plen;
8567 - if (count > len) {
8568 - DBG("%s corrupted frame, len %d", husb->hdev.name, count);
8571 + case HCI_ACLDATA_PKT:
8572 + if (count >= HCI_ACL_HDR_SIZE) {
8573 + hci_acl_hdr *h = data;
8574 + len = HCI_ACL_HDR_SIZE + __le16_to_cpu(h->dlen);
8578 +#ifdef CONFIG_BLUEZ_HCIUSB_SCO
8579 + case HCI_SCODATA_PKT:
8580 + if (count >= HCI_SCO_HDR_SIZE) {
8581 + hci_sco_hdr *h = data;
8582 + len = HCI_SCO_HDR_SIZE + h->dlen;
8588 + BT_DBG("new packet len %d", len);
8590 - /* Allocate skb */
8591 - if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {
8592 - ERR("Can't allocate mem for new packet");
8594 + skb = bluez_skb_alloc(len, GFP_ATOMIC);
8596 + BT_ERR("%s no memory for the packet", husb->hdev.name);
8599 + skb->dev = (void *) &husb->hdev;
8600 + skb->pkt_type = type;
8602 + __reassembly(husb, type) = skb;
8604 + scb = (void *) skb->cb;
8605 + scb->expect = len;
8607 + /* Continuation */
8608 + scb = (void *) skb->cb;
8609 + len = scb->expect;
8611 - skb->dev = (void *) &husb->hdev;
8612 - skb->pkt_type = HCI_EVENT_PKT;
8614 - husb->intr_skb = skb;
8615 - husb->intr_count = len;
8617 - /* Continuation */
8618 - if (count > husb->intr_count) {
8619 - ERR("%s bad frame len %d (expected %d)", husb->hdev.name, count, husb->intr_count);
8622 - husb->intr_skb = NULL;
8623 - husb->intr_count = 0;
8625 + len = min(len, count);
8627 + memcpy(skb_put(skb, len), data, len);
8629 + scb->expect -= len;
8630 + if (!scb->expect) {
8631 + /* Complete frame */
8632 + __reassembly(husb, type) = NULL;
8633 + hci_recv_frame(skb);
8637 - memcpy(skb_put(skb, count), data, count);
8638 - husb->intr_count -= count;
8642 - if (!husb->intr_count) {
8643 - /* Got complete frame */
8645 - husb->hdev.stat.byte_rx += skb->len;
8646 - hci_recv_frame(skb);
8648 - husb->intr_skb = NULL;
8649 + count -= len; data += len;
8654 -static void hci_usb_bulk_read(struct urb *urb)
8655 +static void hci_usb_rx_complete(struct urb *urb)
8657 - struct hci_usb *husb = (struct hci_usb *) urb->context;
8658 - unsigned char *data = urb->transfer_buffer;
8659 - int count = urb->actual_length, status;
8660 - struct sk_buff *skb;
8662 - register __u16 dlen;
8666 + struct _urb *_urb = container_of(urb, struct _urb, urb);
8667 + struct hci_usb *husb = (void *) urb->context;
8668 + struct hci_dev *hdev = &husb->hdev;
8669 + int err, count = urb->actual_length;
8671 - DBG("%s status %d, count %d, flags %x", husb->hdev.name, urb->status, count, urb->transfer_flags);
8672 + BT_DBG("%s urb %p type %d status %d count %d flags %x", hdev->name, urb,
8673 + _urb->type, urb->status, count, urb->transfer_flags);
8675 - if (urb->status) {
8676 - /* Do not re-submit URB on critical errors */
8677 - switch (urb->status) {
8688 + read_lock(&husb->completion_lock);
8690 - ah = (hci_acl_hdr *) data;
8691 - dlen = le16_to_cpu(ah->dlen);
8692 + if (!test_bit(HCI_RUNNING, &hdev->flags))
8695 - /* Verify frame len and completeness */
8696 - if ((count - HCI_ACL_HDR_SIZE) != dlen) {
8697 - ERR("%s corrupted ACL packet: count %d, plen %d", husb->hdev.name, count, dlen);
8698 + if (urb->status || !count)
8702 - /* Allocate packet */
8703 - if (!(skb = bluez_skb_alloc(count, GFP_ATOMIC))) {
8704 - ERR("Can't allocate mem for new packet");
8706 + if (_urb->type == HCI_SCODATA_PKT) {
8707 +#ifdef CONFIG_BLUEZ_HCIUSB_SCO
8709 + for (i=0; i < urb->number_of_packets; i++) {
8710 + BT_DBG("desc %d status %d offset %d len %d", i,
8711 + urb->iso_frame_desc[i].status,
8712 + urb->iso_frame_desc[i].offset,
8713 + urb->iso_frame_desc[i].actual_length);
8715 + if (!urb->iso_frame_desc[i].status)
8716 + __recv_frame(husb, _urb->type,
8717 + urb->transfer_buffer + urb->iso_frame_desc[i].offset,
8718 + urb->iso_frame_desc[i].actual_length);
8724 + err = __recv_frame(husb, _urb->type, urb->transfer_buffer, count);
8726 + BT_ERR("%s corrupted packet: type %d count %d",
8727 + husb->hdev.name, _urb->type, count);
8728 + hdev->stat.err_rx++;
8732 - memcpy(skb_put(skb, count), data, count);
8733 - skb->dev = (void *) &husb->hdev;
8734 - skb->pkt_type = HCI_ACLDATA_PKT;
8736 - husb->hdev.stat.byte_rx += skb->len;
8738 - hci_recv_frame(skb);
8741 - husb->read_urb->dev = husb->udev;
8742 - if ((status = usb_submit_urb(husb->read_urb)))
8743 - DBG("%s read URB submit failed %d", husb->hdev.name, status);
8744 + if (_urb->type != HCI_EVENT_PKT) {
8745 + urb->dev = husb->udev;
8746 + err = usb_submit_urb(urb);
8747 + BT_DBG("%s urb %p type %d resubmit status %d", hdev->name, urb,
8751 - DBG("%s read URB re-submited", husb->hdev.name);
8753 + read_unlock(&husb->completion_lock);
8756 -static int hci_usb_ctrl_msg(struct hci_usb *husb, struct sk_buff *skb)
8757 +static void hci_usb_tx_complete(struct urb *urb)
8759 - struct urb *urb = husb->ctrl_urb;
8760 - devrequest *dr = &husb->dev_req;
8762 + struct _urb *_urb = container_of(urb, struct _urb, urb);
8763 + struct hci_usb *husb = (void *) urb->context;
8764 + struct hci_dev *hdev = &husb->hdev;
8766 - DBG("%s len %d", husb->hdev.name, skb->len);
8767 + BT_DBG("%s urb %p status %d flags %x", hdev->name, urb,
8768 + urb->status, urb->transfer_flags);
8770 - pipe = usb_sndctrlpipe(husb->udev, 0);
8771 + atomic_dec(__pending_tx(husb, _urb->type));
8773 - dr->requesttype = HCI_CTRL_REQ;
8777 - dr->length = cpu_to_le16(skb->len);
8779 - FILL_CONTROL_URB(urb, husb->udev, pipe, (void*)dr, skb->data, skb->len,
8780 - hci_usb_ctrl, skb);
8781 + urb->transfer_buffer = NULL;
8782 + kfree_skb((struct sk_buff *) _urb->priv);
8784 - if ((status = usb_submit_urb(urb))) {
8785 - DBG("%s control URB submit failed %d", husb->hdev.name, status);
8788 + if (!test_bit(HCI_RUNNING, &hdev->flags))
8794 + hdev->stat.byte_tx += urb->transfer_buffer_length;
8796 + hdev->stat.err_tx++;
8798 -static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb)
8800 - struct urb *urb = husb->write_urb;
8802 + read_lock(&husb->completion_lock);
8804 - DBG("%s len %d", husb->hdev.name, skb->len);
8805 + _urb_unlink(_urb);
8806 + _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
8808 - pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep_addr);
8809 + hci_usb_tx_wakeup(husb);
8811 + read_unlock(&husb->completion_lock);
8814 - FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,
8815 - hci_usb_bulk_write, skb);
8816 - urb->transfer_flags |= USB_QUEUE_BULK;
8817 +static void hci_usb_destruct(struct hci_dev *hdev)
8819 + struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
8821 - if ((status = usb_submit_urb(urb))) {
8822 - DBG("%s write URB submit failed %d", husb->hdev.name, status);
8825 + BT_DBG("%s", hdev->name);
8831 -static void * hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
8832 +static void *hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
8834 - struct usb_endpoint_descriptor *bulk_out_ep, *intr_in_ep, *bulk_in_ep;
8835 + struct usb_endpoint_descriptor *bulk_out_ep[HCI_MAX_IFACE_NUM];
8836 + struct usb_endpoint_descriptor *isoc_out_ep[HCI_MAX_IFACE_NUM];
8837 + struct usb_endpoint_descriptor *bulk_in_ep[HCI_MAX_IFACE_NUM];
8838 + struct usb_endpoint_descriptor *isoc_in_ep[HCI_MAX_IFACE_NUM];
8839 + struct usb_endpoint_descriptor *intr_in_ep[HCI_MAX_IFACE_NUM];
8840 struct usb_interface_descriptor *uif;
8841 struct usb_endpoint_descriptor *ep;
8842 + struct usb_interface *iface, *isoc_iface;
8843 struct hci_usb *husb;
8844 struct hci_dev *hdev;
8845 - int i, size, pipe;
8847 + int i, a, e, size, ifn, isoc_ifnum, isoc_alts;
8849 - DBG("udev %p ifnum %d", udev, ifnum);
8850 + BT_DBG("udev %p ifnum %d", udev, ifnum);
8852 - /* Check device signature */
8853 - if ((udev->descriptor.bDeviceClass != HCI_DEV_CLASS) ||
8854 - (udev->descriptor.bDeviceSubClass != HCI_DEV_SUBCLASS)||
8855 - (udev->descriptor.bDeviceProtocol != HCI_DEV_PROTOCOL) )
8857 + iface = &udev->actconfig->interface[0];
8859 - MOD_INC_USE_COUNT;
8861 - uif = &udev->actconfig->interface[ifnum].altsetting[0];
8862 + if (!id->driver_info) {
8863 + const struct usb_device_id *match;
8864 + match = usb_match_id(udev, iface, blacklist_ids);
8869 - if (uif->bNumEndpoints != 3) {
8870 - DBG("Wrong number of endpoints %d", uif->bNumEndpoints);
8871 - MOD_DEC_USE_COUNT;
8872 + if (id->driver_info & HCI_IGNORE)
8876 - bulk_out_ep = intr_in_ep = bulk_in_ep = NULL;
8877 + /* Check number of endpoints */
8878 + if (udev->actconfig->interface[ifnum].altsetting[0].bNumEndpoints < 3)
8881 + memset(bulk_out_ep, 0, sizeof(bulk_out_ep));
8882 + memset(isoc_out_ep, 0, sizeof(isoc_out_ep));
8883 + memset(bulk_in_ep, 0, sizeof(bulk_in_ep));
8884 + memset(isoc_in_ep, 0, sizeof(isoc_in_ep));
8885 + memset(intr_in_ep, 0, sizeof(intr_in_ep));
8888 + isoc_iface = NULL;
8889 + isoc_alts = isoc_ifnum = 0;
8891 /* Find endpoints that we need */
8892 - for ( i = 0; i < uif->bNumEndpoints; ++i) {
8893 - ep = &uif->endpoint[i];
8895 - switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
8896 - case USB_ENDPOINT_XFER_BULK:
8897 - if (ep->bEndpointAddress & USB_DIR_IN)
8902 + ifn = MIN(udev->actconfig->bNumInterfaces, HCI_MAX_IFACE_NUM);
8903 + for (i = 0; i < ifn; i++) {
8904 + iface = &udev->actconfig->interface[i];
8905 + for (a = 0; a < iface->num_altsetting; a++) {
8906 + uif = &iface->altsetting[a];
8907 + for (e = 0; e < uif->bNumEndpoints; e++) {
8908 + ep = &uif->endpoint[e];
8910 + switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
8911 + case USB_ENDPOINT_XFER_INT:
8912 + if (ep->bEndpointAddress & USB_DIR_IN)
8913 + intr_in_ep[i] = ep;
8916 + case USB_ENDPOINT_XFER_BULK:
8917 + if (ep->bEndpointAddress & USB_DIR_IN)
8918 + bulk_in_ep[i] = ep;
8920 + bulk_out_ep[i] = ep;
8923 +#ifdef CONFIG_BLUEZ_HCIUSB_SCO
8924 + case USB_ENDPOINT_XFER_ISOC:
8925 + if (ep->wMaxPacketSize < size || a > 2)
8927 + size = ep->wMaxPacketSize;
8929 + isoc_iface = iface;
8933 + if (ep->bEndpointAddress & USB_DIR_IN)
8934 + isoc_in_ep[i] = ep;
8936 + isoc_out_ep[i] = ep;
8944 - case USB_ENDPOINT_XFER_INT:
8948 + if (!bulk_in_ep[0] || !bulk_out_ep[0] || !intr_in_ep[0]) {
8949 + BT_DBG("Bulk endpoints not found");
8953 - if (!bulk_in_ep || !bulk_out_ep || !intr_in_ep) {
8954 - DBG("Endpoints not found: %p %p %p", bulk_in_ep, bulk_out_ep, intr_in_ep);
8955 - MOD_DEC_USE_COUNT;
8957 +#ifdef CONFIG_BLUEZ_HCIUSB_SCO
8958 + if (id->driver_info & HCI_BROKEN_ISOC || !isoc_in_ep[1] || !isoc_out_ep[1]) {
8959 + BT_DBG("Isoc endpoints not found");
8960 + isoc_iface = NULL;
8964 if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
8965 - ERR("Can't allocate: control structure");
8966 - MOD_DEC_USE_COUNT;
8968 + BT_ERR("Can't allocate: control structure");
8972 memset(husb, 0, sizeof(struct hci_usb));
8975 - husb->bulk_out_ep_addr = bulk_out_ep->bEndpointAddress;
8977 - if (!(husb->ctrl_urb = usb_alloc_urb(0))) {
8978 - ERR("Can't allocate: control URB");
8982 - if (!(husb->write_urb = usb_alloc_urb(0))) {
8983 - ERR("Can't allocate: write URB");
8987 - if (!(husb->read_urb = usb_alloc_urb(0))) {
8988 - ERR("Can't allocate: read URB");
8993 - pipe = usb_rcvbulkpipe(udev, ep->bEndpointAddress);
8994 - size = HCI_MAX_FRAME_SIZE;
8996 - if (!(buf = kmalloc(size, GFP_KERNEL))) {
8997 - ERR("Can't allocate: read buffer");
9001 - FILL_BULK_URB(husb->read_urb, udev, pipe, buf, size, hci_usb_bulk_read, husb);
9002 - husb->read_urb->transfer_flags |= USB_QUEUE_BULK;
9005 - pipe = usb_rcvintpipe(udev, ep->bEndpointAddress);
9006 - size = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
9008 - if (!(husb->intr_urb = usb_alloc_urb(0))) {
9009 - ERR("Can't allocate: interrupt URB");
9011 + husb->bulk_out_ep = bulk_out_ep[0];
9012 + husb->bulk_in_ep = bulk_in_ep[0];
9013 + husb->intr_in_ep = intr_in_ep[0];
9015 + if (id->driver_info & HCI_DIGIANSWER)
9016 + husb->ctrl_req = HCI_DIGI_REQ;
9018 + husb->ctrl_req = HCI_CTRL_REQ;
9020 +#ifdef CONFIG_BLUEZ_HCIUSB_SCO
9022 + BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, isoc_alts);
9023 + if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) {
9024 + BT_ERR("Can't set isoc interface settings");
9025 + isoc_iface = NULL;
9027 + usb_driver_claim_interface(&hci_usb_driver, isoc_iface, husb);
9028 + husb->isoc_iface = isoc_iface;
9029 + husb->isoc_in_ep = isoc_in_ep[isoc_ifnum];
9030 + husb->isoc_out_ep = isoc_out_ep[isoc_ifnum];
9034 + husb->completion_lock = RW_LOCK_UNLOCKED;
9036 - if (!(buf = kmalloc(size, GFP_KERNEL))) {
9037 - ERR("Can't allocate: interrupt buffer");
9039 + for (i = 0; i < 4; i++) {
9040 + skb_queue_head_init(&husb->transmit_q[i]);
9041 + _urb_queue_init(&husb->pending_q[i]);
9042 + _urb_queue_init(&husb->completed_q[i]);
9045 - FILL_INT_URB(husb->intr_urb, udev, pipe, buf, size, hci_usb_intr, husb, ep->bInterval);
9047 - skb_queue_head_init(&husb->tx_ctrl_q);
9048 - skb_queue_head_init(&husb->tx_write_q);
9050 /* Initialize and register HCI device */
9053 - hdev->type = HCI_USB;
9054 + hdev->type = HCI_USB;
9055 hdev->driver_data = husb;
9057 hdev->open = hci_usb_open;
9058 hdev->close = hci_usb_close;
9059 hdev->flush = hci_usb_flush;
9060 - hdev->send = hci_usb_send_frame;
9061 + hdev->send = hci_usb_send_frame;
9062 + hdev->destruct = hci_usb_destruct;
9064 + if (id->driver_info & HCI_RESET)
9065 + set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
9067 if (hci_register_dev(hdev) < 0) {
9068 - ERR("Can't register HCI device %s", hdev->name);
9069 + BT_ERR("Can't register HCI device");
9076 - hci_usb_free_bufs(husb);
9078 - MOD_DEC_USE_COUNT;
9084 @@ -626,38 +967,34 @@
9088 - DBG("%s", hdev->name);
9089 + BT_DBG("%s", hdev->name);
9091 hci_usb_close(hdev);
9093 - if (hci_unregister_dev(hdev) < 0) {
9094 - ERR("Can't unregister HCI device %s", hdev->name);
9096 + if (husb->isoc_iface)
9097 + usb_driver_release_interface(&hci_usb_driver, husb->isoc_iface);
9099 - hci_usb_free_bufs(husb);
9102 - MOD_DEC_USE_COUNT;
9103 + if (hci_unregister_dev(hdev) < 0)
9104 + BT_ERR("Can't unregister HCI device %s", hdev->name);
9107 -static struct usb_driver hci_usb_driver =
9109 +static struct usb_driver hci_usb_driver = {
9111 probe: hci_usb_probe,
9112 disconnect: hci_usb_disconnect,
9113 - id_table: usb_bluetooth_ids,
9114 + id_table: bluetooth_ids,
9117 int hci_usb_init(void)
9121 - INF("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
9122 + BT_INFO("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
9124 - INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
9125 + BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
9127 if ((err = usb_register(&hci_usb_driver)) < 0)
9128 - ERR("Failed to register HCI USB driver");
9129 + BT_ERR("Failed to register HCI USB driver");
9133 @@ -670,6 +1007,6 @@
9134 module_init(hci_usb_init);
9135 module_exit(hci_usb_cleanup);
9137 -MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
9138 +MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
9139 MODULE_DESCRIPTION("BlueZ HCI USB driver ver " VERSION);
9140 MODULE_LICENSE("GPL");
9141 diff -urN linux-2.4.18/drivers/bluetooth/hci_usb.h linux-2.4.18-mh15/drivers/bluetooth/hci_usb.h
9142 --- linux-2.4.18/drivers/bluetooth/hci_usb.h 1970-01-01 01:00:00.000000000 +0100
9143 +++ linux-2.4.18-mh15/drivers/bluetooth/hci_usb.h 2004-08-01 16:26:23.000000000 +0200
9146 + HCI USB driver for Linux Bluetooth protocol stack (BlueZ)
9147 + Copyright (C) 2000-2001 Qualcomm Incorporated
9148 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
9150 + Copyright (C) 2003 Maxim Krasnyansky <maxk@qualcomm.com>
9152 + This program is free software; you can redistribute it and/or modify
9153 + it under the terms of the GNU General Public License version 2 as
9154 + published by the Free Software Foundation;
9156 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
9157 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9158 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
9159 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
9160 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
9161 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
9162 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
9163 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
9165 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
9166 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
9167 + SOFTWARE IS DISCLAIMED.
9171 + * $Id: hci_usb.h,v 1.2 2002/03/18 19:10:04 maxk Exp $
9176 +/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
9177 +#define HCI_DEV_CLASS 0xe0 /* Wireless class */
9178 +#define HCI_DEV_SUBCLASS 0x01 /* RF subclass */
9179 +#define HCI_DEV_PROTOCOL 0x01 /* Bluetooth programming protocol */
9181 +#define HCI_CTRL_REQ 0x20
9182 +#define HCI_DIGI_REQ 0x40
9184 +#define HCI_IGNORE 0x01
9185 +#define HCI_RESET 0x02
9186 +#define HCI_DIGIANSWER 0x04
9187 +#define HCI_BROKEN_ISOC 0x08
9189 +#define HCI_MAX_IFACE_NUM 3
9191 +#define HCI_MAX_BULK_TX 4
9192 +#define HCI_MAX_BULK_RX 1
9194 +#define HCI_MAX_ISOC_RX 2
9195 +#define HCI_MAX_ISOC_TX 2
9197 +#define HCI_MAX_ISOC_FRAMES 10
9199 +struct _urb_queue {
9200 + struct list_head head;
9205 + struct list_head list;
9206 + struct _urb_queue *queue;
9212 +struct _urb *_urb_alloc(int isoc, int gfp);
9214 +static inline void _urb_free(struct _urb *_urb)
9219 +static inline void _urb_queue_init(struct _urb_queue *q)
9221 + INIT_LIST_HEAD(&q->head);
9222 + spin_lock_init(&q->lock);
9225 +static inline void _urb_queue_head(struct _urb_queue *q, struct _urb *_urb)
9227 + unsigned long flags;
9228 + spin_lock_irqsave(&q->lock, flags);
9229 + list_add(&_urb->list, &q->head); _urb->queue = q;
9230 + spin_unlock_irqrestore(&q->lock, flags);
9233 +static inline void _urb_queue_tail(struct _urb_queue *q, struct _urb *_urb)
9235 + unsigned long flags;
9236 + spin_lock_irqsave(&q->lock, flags);
9237 + list_add_tail(&_urb->list, &q->head); _urb->queue = q;
9238 + spin_unlock_irqrestore(&q->lock, flags);
9241 +static inline void _urb_unlink(struct _urb *_urb)
9243 + struct _urb_queue *q = _urb->queue;
9244 + unsigned long flags;
9246 + spin_lock_irqsave(&q->lock, flags);
9247 + list_del(&_urb->list); _urb->queue = NULL;
9248 + spin_unlock_irqrestore(&q->lock, flags);
9252 +struct _urb *_urb_dequeue(struct _urb_queue *q);
9254 +#ifndef container_of
9255 +#define container_of(ptr, type, member) ({ \
9256 + const typeof( ((type *)0)->member ) *__mptr = (ptr); \
9257 + (type *)( (char *)__mptr - offsetof(type,member) );})
9261 + struct hci_dev hdev;
9263 + unsigned long state;
9265 + struct usb_device *udev;
9267 + struct usb_endpoint_descriptor *bulk_in_ep;
9268 + struct usb_endpoint_descriptor *bulk_out_ep;
9269 + struct usb_endpoint_descriptor *intr_in_ep;
9271 + struct usb_interface *isoc_iface;
9272 + struct usb_endpoint_descriptor *isoc_out_ep;
9273 + struct usb_endpoint_descriptor *isoc_in_ep;
9277 + struct sk_buff_head transmit_q[4];
9278 + struct sk_buff *reassembly[4]; // Reassembly buffers
9280 + rwlock_t completion_lock;
9282 + atomic_t pending_tx[4]; // Number of pending requests
9283 + struct _urb_queue pending_q[4]; // Pending requests
9284 + struct _urb_queue completed_q[4]; // Completed requests
9288 +#define HCI_USB_TX_PROCESS 1
9289 +#define HCI_USB_TX_WAKEUP 2
9291 +#endif /* __KERNEL__ */
9292 diff -urN linux-2.4.18/drivers/bluetooth/hci_vhci.c linux-2.4.18-mh15/drivers/bluetooth/hci_vhci.c
9293 --- linux-2.4.18/drivers/bluetooth/hci_vhci.c 2001-09-07 18:28:38.000000000 +0200
9294 +++ linux-2.4.18-mh15/drivers/bluetooth/hci_vhci.c 2004-08-01 16:26:23.000000000 +0200
9297 * BlueZ HCI virtual device driver.
9299 - * $Id: hci_vhci.c,v 1.3 2001/08/03 04:19:50 maxk Exp $
9300 + * $Id: hci_vhci.c,v 1.3 2002/04/17 17:37:20 maxk Exp $
9302 -#define VERSION "1.0"
9303 +#define VERSION "1.1"
9305 #include <linux/config.h>
9306 #include <linux/module.h>
9308 #include <asm/uaccess.h>
9310 #include <net/bluetooth/bluetooth.h>
9311 -#include <net/bluetooth/bluez.h>
9312 #include <net/bluetooth/hci_core.h>
9313 -#include <net/bluetooth/hci_vhci.h>
9314 +#include "hci_vhci.h"
9316 /* HCI device part */
9318 -int hci_vhci_open(struct hci_dev *hdev)
9319 +static int hci_vhci_open(struct hci_dev *hdev)
9321 - hdev->flags |= HCI_RUNNING;
9322 + set_bit(HCI_RUNNING, &hdev->flags);
9326 -int hci_vhci_flush(struct hci_dev *hdev)
9327 +static int hci_vhci_flush(struct hci_dev *hdev)
9329 struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
9330 skb_queue_purge(&hci_vhci->readq);
9334 -int hci_vhci_close(struct hci_dev *hdev)
9335 +static int hci_vhci_close(struct hci_dev *hdev)
9337 - hdev->flags &= ~HCI_RUNNING;
9338 + if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
9341 hci_vhci_flush(hdev);
9345 -int hci_vhci_send_frame(struct sk_buff *skb)
9346 +static void hci_vhci_destruct(struct hci_dev *hdev)
9348 + struct hci_vhci_struct *vhci;
9350 + if (!hdev) return;
9352 + vhci = (struct hci_vhci_struct *) hdev->driver_data;
9355 + MOD_DEC_USE_COUNT;
9358 +static int hci_vhci_send_frame(struct sk_buff *skb)
9360 struct hci_dev* hdev = (struct hci_dev *) skb->dev;
9361 struct hci_vhci_struct *hci_vhci;
9364 - ERR("Frame for uknown device (hdev=NULL)");
9365 + BT_ERR("Frame for uknown device (hdev=NULL)");
9369 - if (!(hdev->flags & HCI_RUNNING))
9370 + if (!test_bit(HCI_RUNNING, &hdev->flags))
9373 hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
9376 add_wait_queue(&hci_vhci->read_wait, &wait);
9378 - current->state = TASK_INTERRUPTIBLE;
9379 + set_current_state(TASK_INTERRUPTIBLE);
9381 /* Read frames from device queue */
9382 if (!(skb = skb_dequeue(&hci_vhci->readq))) {
9388 - current->state = TASK_RUNNING;
9389 + set_current_state(TASK_RUNNING);
9390 remove_wait_queue(&hci_vhci->read_wait, &wait);
9393 @@ -270,11 +282,13 @@
9394 hdev->close = hci_vhci_close;
9395 hdev->flush = hci_vhci_flush;
9396 hdev->send = hci_vhci_send_frame;
9397 + hdev->destruct = hci_vhci_destruct;
9399 if (hci_register_dev(hdev) < 0) {
9403 + MOD_INC_USE_COUNT;
9405 file->private_data = hci_vhci;
9407 @@ -285,12 +299,10 @@
9408 struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
9410 if (hci_unregister_dev(&hci_vhci->hdev) < 0) {
9411 - ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
9412 + BT_ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
9416 file->private_data = NULL;
9421 @@ -315,12 +327,12 @@
9423 int __init hci_vhci_init(void)
9425 - INF("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
9426 + BT_INFO("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
9428 - INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
9429 + BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
9431 if (misc_register(&hci_vhci_miscdev)) {
9432 - ERR("Can't register misc device %d\n", VHCI_MINOR);
9433 + BT_ERR("Can't register misc device %d\n", VHCI_MINOR);
9439 MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
9440 MODULE_DESCRIPTION("BlueZ VHCI driver ver " VERSION);
9441 -MODULE_LICENSE("GPL");
9442 +MODULE_LICENSE("GPL");
9443 diff -urN linux-2.4.18/drivers/bluetooth/hci_vhci.h linux-2.4.18-mh15/drivers/bluetooth/hci_vhci.h
9444 --- linux-2.4.18/drivers/bluetooth/hci_vhci.h 1970-01-01 01:00:00.000000000 +0100
9445 +++ linux-2.4.18-mh15/drivers/bluetooth/hci_vhci.h 2004-08-01 16:26:23.000000000 +0200
9448 + BlueZ - Bluetooth protocol stack for Linux
9449 + Copyright (C) 2000-2001 Qualcomm Incorporated
9451 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
9453 + This program is free software; you can redistribute it and/or modify
9454 + it under the terms of the GNU General Public License version 2 as
9455 + published by the Free Software Foundation;
9457 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
9458 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9459 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
9460 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
9461 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
9462 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
9463 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
9464 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
9466 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
9467 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
9468 + SOFTWARE IS DISCLAIMED.
9472 + * $Id: hci_vhci.h,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $
9475 +#ifndef __HCI_VHCI_H
9476 +#define __HCI_VHCI_H
9480 +struct hci_vhci_struct {
9481 + struct hci_dev hdev;
9483 + wait_queue_head_t read_wait;
9484 + struct sk_buff_head readq;
9485 + struct fasync_struct *fasync;
9488 +/* VHCI device flags */
9489 +#define VHCI_FASYNC 0x0010
9491 +#endif /* __KERNEL__ */
9493 +#define VHCI_DEV "/dev/vhci"
9494 +#define VHCI_MINOR 250
9496 +#endif /* __HCI_VHCI_H */
9497 diff -urN linux-2.4.18/drivers/bluetooth/Makefile linux-2.4.18-mh15/drivers/bluetooth/Makefile
9498 --- linux-2.4.18/drivers/bluetooth/Makefile 2001-09-07 18:28:38.000000000 +0200
9499 +++ linux-2.4.18-mh15/drivers/bluetooth/Makefile 2004-08-01 16:26:23.000000000 +0200
9502 -# Makefile for Bluetooth HCI device drivers.
9503 +# Makefile for the Linux Bluetooth HCI device drivers
9506 O_TARGET := bluetooth.o
9508 +list-multi := hci_uart.o
9510 obj-$(CONFIG_BLUEZ_HCIUSB) += hci_usb.o
9511 -obj-$(CONFIG_BLUEZ_HCIUART) += hci_uart.o
9512 obj-$(CONFIG_BLUEZ_HCIVHCI) += hci_vhci.o
9514 +obj-$(CONFIG_BLUEZ_HCIUART) += hci_uart.o
9515 +uart-y := hci_ldisc.o
9516 +uart-$(CONFIG_BLUEZ_HCIUART_H4) += hci_h4.o
9517 +uart-$(CONFIG_BLUEZ_HCIUART_BCSP) += hci_bcsp.o
9519 +obj-$(CONFIG_BLUEZ_HCIBFUSB) += bfusb.o
9521 +obj-$(CONFIG_BLUEZ_HCIDTL1) += dtl1_cs.o
9522 +obj-$(CONFIG_BLUEZ_HCIBT3C) += bt3c_cs.o
9523 +obj-$(CONFIG_BLUEZ_HCIBLUECARD) += bluecard_cs.o
9524 +obj-$(CONFIG_BLUEZ_HCIBTUART) += btuart_cs.o
9526 include $(TOPDIR)/Rules.make
9528 +hci_uart.o: $(uart-y)
9529 + $(LD) -r -o $@ $(uart-y)
9530 diff -urN linux-2.4.18/drivers/bluetooth/Makefile.lib linux-2.4.18-mh15/drivers/bluetooth/Makefile.lib
9531 --- linux-2.4.18/drivers/bluetooth/Makefile.lib 1970-01-01 01:00:00.000000000 +0100
9532 +++ linux-2.4.18-mh15/drivers/bluetooth/Makefile.lib 2004-08-01 16:26:23.000000000 +0200
9534 +obj-$(CONFIG_BLUEZ_HCIBFUSB) += firmware_class.o
9535 +obj-$(CONFIG_BLUEZ_HCIBT3C) += firmware_class.o
9536 diff -urN linux-2.4.18/drivers/char/pcmcia/serial_cs.c linux-2.4.18-mh15/drivers/char/pcmcia/serial_cs.c
9537 --- linux-2.4.18/drivers/char/pcmcia/serial_cs.c 2001-12-21 18:41:54.000000000 +0100
9538 +++ linux-2.4.18-mh15/drivers/char/pcmcia/serial_cs.c 2004-08-01 16:26:23.000000000 +0200
9541 A driver for PCMCIA serial devices
9543 - serial_cs.c 1.128 2001/10/18 12:18:35
9544 + serial_cs.c 1.138 2002/10/25 06:24:52
9546 The contents of this file are subject to the Mozilla Public
9547 License Version 1.1 (the "License"); you may not use this file
9549 static int irq_list[4] = { -1 };
9550 MODULE_PARM(irq_list, "1-4i");
9552 -/* Enable the speaker? */
9553 -INT_MODULE_PARM(do_sound, 1);
9554 +INT_MODULE_PARM(do_sound, 1); /* Enable the speaker? */
9555 +INT_MODULE_PARM(buggy_uart, 0); /* Skip strict UART tests? */
9558 INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
9559 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
9560 static char *version =
9561 -"serial_cs.c 1.128 2001/10/18 12:18:35 (David Hinds)";
9562 +"serial_cs.c 1.138 2002/10/25 06:24:52 (David Hinds)";
9564 #define DEBUG(n, args...)
9567 { MANFID_OMEGA, PRODID_OMEGA_QSP_100, 4 },
9568 { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232, 2 },
9569 { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 },
9570 + { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D2, 2 },
9571 { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS232, 4 },
9572 { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS422, 2 },
9573 { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS422, 4 },
9575 client_reg_t client_reg;
9580 DEBUG(0, "serial_attach()\n");
9582 /* Create new serial device */
9584 link->release.function = &serial_release;
9585 link->release.data = (u_long)link;
9586 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
9587 - link->io.NumPorts1 = 8;
9588 + link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
9589 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
9590 link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
9591 if (irq_list[0] == -1)
9592 @@ -169,13 +170,12 @@
9593 for (i = 0; i < 4; i++)
9594 link->irq.IRQInfo2 |= 1 << irq_list[i];
9595 link->conf.Attributes = CONF_ENABLE_IRQ;
9596 - link->conf.Vcc = 50;
9598 link->conf.Attributes |= CONF_ENABLE_SPKR;
9599 link->conf.Status = CCSR_AUDIO_ENA;
9601 link->conf.IntType = INT_MEMORY_AND_IO;
9604 /* Register with Card Services */
9605 link->next = dev_list;
9608 serial_detach(link);
9614 } /* serial_attach */
9619 DEBUG(0, "serial_detach(0x%p)\n", link);
9622 /* Locate device structure */
9623 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
9624 if (*linkp == link) break;
9625 @@ -224,17 +224,17 @@
9626 del_timer(&link->release);
9627 if (link->state & DEV_CONFIG)
9628 serial_release((u_long)link);
9632 ret = CardServices(DeregisterClient, link->handle);
9633 if (ret != CS_SUCCESS)
9634 cs_error(link->handle, DeregisterClient, ret);
9638 /* Unlink device structure, free bits */
9639 *linkp = link->next;
9643 } /* serial_detach */
9645 /*====================================================================*/
9646 @@ -243,18 +243,20 @@
9648 struct serial_struct serial;
9652 memset(&serial, 0, sizeof(serial));
9655 serial.flags = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ;
9657 + serial.flags |= ASYNC_BUGGY_UART;
9658 line = register_serial(&serial);
9660 printk(KERN_NOTICE "serial_cs: register_serial() at 0x%04lx,"
9661 " irq %d failed\n", (u_long)serial.port, serial.irq);
9666 info->line[info->ndev] = line;
9667 sprintf(info->node[info->ndev].dev_name, "ttyS%d", line);
9668 info->node[info->ndev].major = TTY_MAJOR;
9671 info->node[info->ndev-1].next = &info->node[info->ndev];
9678 @@ -313,7 +315,10 @@
9679 return setup_serial(info, port, config.AssignedIRQ);
9681 link->conf.Vcc = config.Vcc;
9684 + link->io.NumPorts1 = 8;
9685 + link->io.NumPorts2 = 0;
9687 /* First pass: look for a config entry that looks normal. */
9688 tuple.TupleData = (cisdata_t *)buf;
9689 tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
9691 i = next_tuple(handle, &tuple, &parse);
9696 /* Second pass: try to find an entry that isn't picky about
9697 its base address, then try to grab any standard serial port
9698 address, and finally try to get any free port. */
9700 for (j = 0; j < 5; j++) {
9701 link->io.BasePort1 = base[j];
9702 link->io.IOAddrLines = base[j] ? 16 : 3;
9703 - i = CardServices(RequestIO, link->handle,
9705 + i = CardServices(RequestIO, link->handle, &link->io);
9706 if (i == CS_SUCCESS) goto found_port;
9710 cs_error(link->handle, RequestIO, i);
9715 i = CardServices(RequestIRQ, link->handle, &link->irq);
9716 if (i != CS_SUCCESS) {
9717 cs_error(link->handle, RequestIRQ, i);
9718 @@ -390,8 +394,12 @@
9721 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
9722 + config_info_t config;
9725 + CardServices(GetConfigurationInfo, handle, &config);
9726 + link->conf.Vcc = config.Vcc;
9728 tuple.TupleData = (cisdata_t *)buf;
9729 tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
9730 tuple.Attributes = 0;
9731 @@ -433,12 +441,12 @@
9732 i = next_tuple(handle, &tuple, &parse);
9737 if (i != CS_SUCCESS) {
9738 - cs_error(link->handle, RequestIO, i);
9740 + /* At worst, try to configure as a single port */
9741 + return simple_config(link);
9745 i = CardServices(RequestIRQ, link->handle, &link->irq);
9746 if (i != CS_SUCCESS) {
9747 cs_error(link->handle, RequestIRQ, i);
9748 @@ -454,14 +462,27 @@
9749 cs_error(link->handle, RequestConfiguration, i);
9754 + /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
9755 + 8 registers are for the UART, the others are extra registers */
9756 + if (info->manfid == MANFID_OXSEMI) {
9757 + if (cf->index == 1 || cf->index == 3) {
9758 + setup_serial(info, base2, link->irq.AssignedIRQ);
9759 + outb(12,link->io.BasePort1+1);
9761 + setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
9767 setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
9768 /* The Nokia cards are not really multiport cards */
9769 if (info->manfid == MANFID_NOKIA)
9771 for (i = 0; i < info->multi-1; i++)
9772 setup_serial(info, base2+(8*i), link->irq.AssignedIRQ);
9780 link->conf.ConfigBase = parse.config.base;
9781 link->conf.Present = parse.config.rmask[0];
9784 /* Configure card */
9785 link->state |= DEV_CONFIG;
9788 tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
9789 tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
9790 info->multi = (first_tuple(handle, &tuple, &parse) == CS_SUCCESS);
9792 - /* Is this a multiport card? */
9794 + /* Scan list of known multiport card ID's */
9795 tuple.DesiredTuple = CISTPL_MANFID;
9796 if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
9797 info->manfid = le16_to_cpu(buf[0]);
9798 @@ -537,15 +558,15 @@
9804 if (info->multi > 1)
9807 simple_config(link);
9810 if (info->ndev == 0)
9814 if (info->manfid == MANFID_IBM) {
9815 conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
9816 CS_CHECK(AccessConfigurationRegister, link->handle, ®);
9818 cs_error(link->handle, last_fn, last_ret);
9820 serial_release((u_long)link);
9821 + link->state &= ~DEV_CONFIG_PENDING;
9823 } /* serial_config */
9827 After a card is removed, serial_release() will unregister the net
9828 device, and release the PCMCIA configuration.
9831 ======================================================================*/
9833 void serial_release(u_long arg)
9835 dev_link_t *link = (dev_link_t *)arg;
9836 serial_info_t *info = link->priv;
9840 DEBUG(0, "serial_release(0x%p)\n", link);
9842 for (i = 0; i < info->ndev; i++) {
9844 CardServices(ReleaseIO, link->handle, &link->io);
9845 CardServices(ReleaseIRQ, link->handle, &link->irq);
9849 link->state &= ~DEV_CONFIG;
9851 } /* serial_release */
9853 stuff to run after an event is received. A CARD_REMOVAL event
9854 also sets some flags to discourage the serial drivers from
9855 talking to the ports.
9858 ======================================================================*/
9860 static int serial_event(event_t event, int priority,
9863 dev_link_t *link = args->client_data;
9864 serial_info_t *info = link->priv;
9867 DEBUG(1, "serial_event(0x%06x)\n", event);
9871 case CS_EVENT_CARD_REMOVAL:
9872 link->state &= ~DEV_PRESENT;
9874 if (serv.Revision != CS_RELEASE_CODE) {
9875 printk(KERN_NOTICE "serial_cs: Card Services release "
9876 "does not match!\n");
9880 register_pccard_driver(&dev_info, &serial_attach, &serial_detach);
9882 diff -urN linux-2.4.18/drivers/input/Config.in linux-2.4.18-mh15/drivers/input/Config.in
9883 --- linux-2.4.18/drivers/input/Config.in 2001-09-13 00:34:06.000000000 +0200
9884 +++ linux-2.4.18-mh15/drivers/input/Config.in 2004-08-01 16:26:23.000000000 +0200
9887 dep_tristate ' Joystick support' CONFIG_INPUT_JOYDEV $CONFIG_INPUT
9888 dep_tristate ' Event interface support' CONFIG_INPUT_EVDEV $CONFIG_INPUT
9889 +dep_tristate ' User level driver support' CONFIG_INPUT_UINPUT $CONFIG_INPUT
9892 diff -urN linux-2.4.18/drivers/input/keybdev.c linux-2.4.18-mh15/drivers/input/keybdev.c
9893 --- linux-2.4.18/drivers/input/keybdev.c 2001-10-11 18:14:32.000000000 +0200
9894 +++ linux-2.4.18-mh15/drivers/input/keybdev.c 2004-08-01 16:26:23.000000000 +0200
9895 @@ -154,16 +154,18 @@
9897 static struct input_handler keybdev_handler;
9899 +static unsigned int ledstate = 0xff;
9901 void keybdev_ledfunc(unsigned int led)
9903 struct input_handle *handle;
9905 - for (handle = keybdev_handler.handle; handle; handle = handle->hnext) {
9908 + for (handle = keybdev_handler.handle; handle; handle = handle->hnext) {
9909 input_event(handle->dev, EV_LED, LED_SCROLLL, !!(led & 0x01));
9910 input_event(handle->dev, EV_LED, LED_NUML, !!(led & 0x02));
9911 input_event(handle->dev, EV_LED, LED_CAPSL, !!(led & 0x04));
9916 @@ -202,6 +204,12 @@
9918 // printk(KERN_INFO "keybdev.c: Adding keyboard: input%d\n", dev->number);
9920 + if (ledstate != 0xff) {
9921 + input_event(dev, EV_LED, LED_SCROLLL, !!(ledstate & 0x01));
9922 + input_event(dev, EV_LED, LED_NUML, !!(ledstate & 0x02));
9923 + input_event(dev, EV_LED, LED_CAPSL, !!(ledstate & 0x04));
9929 diff -urN linux-2.4.18/drivers/input/Makefile linux-2.4.18-mh15/drivers/input/Makefile
9930 --- linux-2.4.18/drivers/input/Makefile 2000-12-29 23:07:22.000000000 +0100
9931 +++ linux-2.4.18-mh15/drivers/input/Makefile 2004-08-01 16:26:23.000000000 +0200
9933 obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
9934 obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
9935 obj-$(CONFIG_INPUT_EVDEV) += evdev.o
9936 +obj-$(CONFIG_INPUT_UINPUT) += uinput.o
9938 # The global Rules.make.
9940 diff -urN linux-2.4.18/drivers/input/uinput.c linux-2.4.18-mh15/drivers/input/uinput.c
9941 --- linux-2.4.18/drivers/input/uinput.c 1970-01-01 01:00:00.000000000 +0100
9942 +++ linux-2.4.18-mh15/drivers/input/uinput.c 2004-08-01 16:26:23.000000000 +0200
9945 + * User level driver support for input subsystem
9947 + * Heavily based on evdev.c by Vojtech Pavlik
9949 + * This program is free software; you can redistribute it and/or modify
9950 + * it under the terms of the GNU General Public License as published by
9951 + * the Free Software Foundation; either version 2 of the License, or
9952 + * (at your option) any later version.
9954 + * This program is distributed in the hope that it will be useful,
9955 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9956 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9957 + * GNU General Public License for more details.
9959 + * You should have received a copy of the GNU General Public License
9960 + * along with this program; if not, write to the Free Software
9961 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
9963 + * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
9965 + * Changes/Revisions:
9967 + * - first public version
9970 +#include <linux/poll.h>
9971 +#include <linux/slab.h>
9972 +#include <linux/module.h>
9973 +#include <linux/init.h>
9974 +#include <linux/input.h>
9975 +#include <linux/smp_lock.h>
9976 +#include <linux/fs.h>
9977 +#include <linux/miscdevice.h>
9978 +#include <linux/uinput.h>
9980 +static int uinput_dev_open(struct input_dev *dev)
9985 +static void uinput_dev_close(struct input_dev *dev)
9989 +static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
9991 + struct uinput_device *udev;
9993 + udev = (struct uinput_device *)dev->private;
9995 + udev->buff[udev->head].type = type;
9996 + udev->buff[udev->head].code = code;
9997 + udev->buff[udev->head].value = value;
9998 + do_gettimeofday(&udev->buff[udev->head].time);
9999 + udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE;
10001 + wake_up_interruptible(&udev->waitq);
10006 +static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect)
10011 +static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
10016 +static int uinput_create_device(struct uinput_device *udev)
10018 + if (!udev->dev->name) {
10019 + printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME);
10023 + udev->dev->open = uinput_dev_open;
10024 + udev->dev->close = uinput_dev_close;
10025 + udev->dev->event = uinput_dev_event;
10026 + udev->dev->upload_effect = uinput_dev_upload_effect;
10027 + udev->dev->erase_effect = uinput_dev_erase_effect;
10028 + udev->dev->private = udev;
10030 + init_waitqueue_head(&(udev->waitq));
10032 + input_register_device(udev->dev);
10034 + set_bit(UIST_CREATED, &(udev->state));
10039 +static int uinput_destroy_device(struct uinput_device *udev)
10041 + if (!test_bit(UIST_CREATED, &(udev->state))) {
10042 + printk(KERN_WARNING "%s: create the device first\n", UINPUT_NAME);
10046 + input_unregister_device(udev->dev);
10048 + clear_bit(UIST_CREATED, &(udev->state));
10053 +static int uinput_open(struct inode *inode, struct file *file)
10055 + struct uinput_device *newdev;
10056 + struct input_dev *newinput;
10058 + newdev = kmalloc(sizeof(struct uinput_device), GFP_KERNEL);
10061 + memset(newdev, 0, sizeof(struct uinput_device));
10063 + newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
10066 + memset(newinput, 0, sizeof(struct input_dev));
10068 + newdev->dev = newinput;
10070 + file->private_data = newdev;
10079 +static int uinput_validate_absbits(struct input_dev *dev)
10081 + unsigned int cnt;
10084 + for (cnt = 0; cnt < ABS_MAX; cnt++) {
10085 + if (!test_bit(cnt, dev->absbit))
10088 + if (/*!dev->absmin[cnt] || !dev->absmax[cnt] || */
10089 + (dev->absmax[cnt] <= dev->absmin[cnt])) {
10090 + printk(KERN_DEBUG
10091 + "%s: invalid abs[%02x] min:%d max:%d\n",
10092 + UINPUT_NAME, cnt,
10093 + dev->absmin[cnt], dev->absmax[cnt]);
10094 + retval = -EINVAL;
10098 + if ((dev->absflat[cnt] < dev->absmin[cnt]) ||
10099 + (dev->absflat[cnt] > dev->absmax[cnt])) {
10100 + printk(KERN_DEBUG
10101 + "%s: absflat[%02x] out of range: %d "
10102 + "(min:%d/max:%d)\n",
10103 + UINPUT_NAME, cnt, dev->absflat[cnt],
10104 + dev->absmin[cnt], dev->absmax[cnt]);
10105 + retval = -EINVAL;
10112 +static int uinput_alloc_device(struct file *file, const char *buffer, size_t count)
10114 + struct uinput_user_dev *user_dev;
10115 + struct input_dev *dev;
10116 + struct uinput_device *udev;
10122 + udev = (struct uinput_device *)file->private_data;
10125 + user_dev = kmalloc(sizeof(*user_dev), GFP_KERNEL);
10127 + retval = -ENOMEM;
10131 + if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) {
10132 + retval = -EFAULT;
10136 + if (NULL != dev->name)
10137 + kfree(dev->name);
10139 + size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
10140 + dev->name = kmalloc(size, GFP_KERNEL);
10141 + if (!dev->name) {
10142 + retval = -ENOMEM;
10146 + strncpy(dev->name, user_dev->name, size);
10147 + dev->idbus = user_dev->idbus;
10148 + dev->idvendor = user_dev->idvendor;
10149 + dev->idproduct = user_dev->idproduct;
10150 + dev->idversion = user_dev->idversion;
10151 + dev->ff_effects_max = user_dev->ff_effects_max;
10153 + size = sizeof(int) * (ABS_MAX + 1);
10154 + memcpy(dev->absmax, user_dev->absmax, size);
10155 + memcpy(dev->absmin, user_dev->absmin, size);
10156 + memcpy(dev->absfuzz, user_dev->absfuzz, size);
10157 + memcpy(dev->absflat, user_dev->absflat, size);
10159 + /* check if absmin/absmax/absfuzz/absflat are filled as
10160 + * told in Documentation/input/input-programming.txt */
10161 + if (test_bit(EV_ABS, dev->evbit)) {
10162 + retval = uinput_validate_absbits(dev);
10164 + kfree(dev->name);
10172 +static ssize_t uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
10174 + struct uinput_device *udev = file->private_data;
10176 + if (test_bit(UIST_CREATED, &(udev->state))) {
10177 + struct input_event ev;
10179 + if (copy_from_user(&ev, buffer, sizeof(struct input_event)))
10181 + input_event(udev->dev, ev.type, ev.code, ev.value);
10184 + count = uinput_alloc_device(file, buffer, count);
10189 +static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
10191 + struct uinput_device *udev = file->private_data;
10194 + if (!test_bit(UIST_CREATED, &(udev->state)))
10197 + if ((udev->head == udev->tail) && (file->f_flags & O_NONBLOCK))
10200 + retval = wait_event_interruptible(udev->waitq,
10201 + (udev->head != udev->tail) ||
10202 + !test_bit(UIST_CREATED, &(udev->state)));
10207 + if (!test_bit(UIST_CREATED, &(udev->state)))
10210 + while ((udev->head != udev->tail) &&
10211 + (retval + sizeof(struct input_event) <= count)) {
10212 + if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]),
10213 + sizeof(struct input_event))) return -EFAULT;
10214 + udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE;
10215 + retval += sizeof(struct input_event);
10221 +static unsigned int uinput_poll(struct file *file, poll_table *wait)
10223 + struct uinput_device *udev = file->private_data;
10225 + poll_wait(file, &udev->waitq, wait);
10227 + if (udev->head != udev->tail)
10228 + return POLLIN | POLLRDNORM;
10233 +static int uinput_burn_device(struct uinput_device *udev)
10235 + if (test_bit(UIST_CREATED, &(udev->state)))
10236 + uinput_destroy_device(udev);
10238 + kfree(udev->dev);
10244 +static int uinput_close(struct inode *inode, struct file *file)
10246 + return uinput_burn_device((struct uinput_device *)file->private_data);
10249 +static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
10252 + struct uinput_device *udev;
10254 + udev = (struct uinput_device *)file->private_data;
10256 + /* device attributes can not be changed after the device is created */
10257 + if (cmd >= UI_SET_EVBIT && test_bit(UIST_CREATED, &(udev->state)))
10261 + case UI_DEV_CREATE:
10262 + retval = uinput_create_device(udev);
10265 + case UI_DEV_DESTROY:
10266 + retval = uinput_destroy_device(udev);
10269 + case UI_SET_EVBIT:
10270 + if (arg > EV_MAX) {
10271 + retval = -EINVAL;
10274 + set_bit(arg, udev->dev->evbit);
10277 + case UI_SET_KEYBIT:
10278 + if (arg > KEY_MAX) {
10279 + retval = -EINVAL;
10282 + set_bit(arg, udev->dev->keybit);
10285 + case UI_SET_RELBIT:
10286 + if (arg > REL_MAX) {
10287 + retval = -EINVAL;
10290 + set_bit(arg, udev->dev->relbit);
10293 + case UI_SET_ABSBIT:
10294 + if (arg > ABS_MAX) {
10295 + retval = -EINVAL;
10298 + set_bit(arg, udev->dev->absbit);
10301 + case UI_SET_MSCBIT:
10302 + if (arg > MSC_MAX) {
10303 + retval = -EINVAL;
10306 + set_bit(arg, udev->dev->mscbit);
10309 + case UI_SET_LEDBIT:
10310 + if (arg > LED_MAX) {
10311 + retval = -EINVAL;
10314 + set_bit(arg, udev->dev->ledbit);
10317 + case UI_SET_SNDBIT:
10318 + if (arg > SND_MAX) {
10319 + retval = -EINVAL;
10322 + set_bit(arg, udev->dev->sndbit);
10325 + case UI_SET_FFBIT:
10326 + if (arg > FF_MAX) {
10327 + retval = -EINVAL;
10330 + set_bit(arg, udev->dev->ffbit);
10334 + retval = -EFAULT;
10339 +struct file_operations uinput_fops = {
10340 + owner: THIS_MODULE,
10341 + open: uinput_open,
10342 + release: uinput_close,
10343 + read: uinput_read,
10344 + write: uinput_write,
10345 + poll: uinput_poll,
10346 + ioctl: uinput_ioctl,
10349 +static struct miscdevice uinput_misc = {
10350 + fops: &uinput_fops,
10351 + minor: UINPUT_MINOR,
10352 + name: UINPUT_NAME,
10355 +static int __init uinput_init(void)
10357 + return misc_register(&uinput_misc);
10360 +static void __exit uinput_exit(void)
10362 + misc_deregister(&uinput_misc);
10365 +MODULE_AUTHOR("Aristeu Sergio Rozanski Filho");
10366 +MODULE_DESCRIPTION("User level driver support for input subsystem");
10367 +MODULE_LICENSE("GPL");
10369 +module_init(uinput_init);
10370 +module_exit(uinput_exit);
10372 diff -urN linux-2.4.18/drivers/isdn/avmb1/capidrv.c linux-2.4.18-mh15/drivers/isdn/avmb1/capidrv.c
10373 --- linux-2.4.18/drivers/isdn/avmb1/capidrv.c 2001-12-21 18:41:54.000000000 +0100
10374 +++ linux-2.4.18-mh15/drivers/isdn/avmb1/capidrv.c 2004-08-01 16:26:23.000000000 +0200
10375 @@ -514,13 +514,25 @@
10377 static void send_message(capidrv_contr * card, _cmsg * cmsg)
10379 - struct sk_buff *skb;
10381 + struct sk_buff *skb;
10385 capi_cmsg2message(cmsg, cmsg->buf);
10386 len = CAPIMSG_LEN(cmsg->buf);
10387 skb = alloc_skb(len, GFP_ATOMIC);
10389 + printk(KERN_ERR "no skb len(%d) memory\n", len);
10392 memcpy(skb_put(skb, len), cmsg->buf, len);
10393 - (*capifuncs->capi_put_message) (global.appid, skb);
10394 + err = (*capifuncs->capi_put_message) (global.appid, skb);
10396 + printk(KERN_WARNING "%s: capi_put_message error: %04x\n",
10397 + __FUNCTION__, err);
10401 global.nsentctlpkt++;
10404 @@ -2179,10 +2191,10 @@
10405 free_ncci(card, card->bchans[card->nbchan-1].nccip);
10406 if (card->bchans[card->nbchan-1].plcip)
10407 free_plci(card, card->bchans[card->nbchan-1].plcip);
10408 - if (card->plci_list)
10409 - printk(KERN_ERR "capidrv: bug in free_plci()\n");
10412 + if (card->plci_list)
10413 + printk(KERN_ERR "capidrv: bug in free_plci()\n");
10414 kfree(card->bchans);
10417 diff -urN linux-2.4.18/drivers/isdn/avmb1/kcapi.c linux-2.4.18-mh15/drivers/isdn/avmb1/kcapi.c
10418 --- linux-2.4.18/drivers/isdn/avmb1/kcapi.c 2001-12-21 18:41:54.000000000 +0100
10419 +++ linux-2.4.18-mh15/drivers/isdn/avmb1/kcapi.c 2004-08-01 16:26:23.000000000 +0200
10420 @@ -545,7 +545,13 @@
10421 static void notify_up(__u32 contr)
10423 struct capi_interface_user *p;
10426 + for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
10427 + if (!VALID_APPLID(appl)) continue;
10428 + if (APPL(appl)->releasing) continue;
10429 + CARD(contr)->driver->register_appl(CARD(contr), appl, &APPL(appl)->rparam);
10431 printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr);
10432 spin_lock(&capi_users_lock);
10433 for (p = capi_users; p; p = p->next) {
10434 @@ -705,12 +711,16 @@
10435 nextpp = &(*pp)->next;
10438 - APPL(appl)->releasing--;
10439 - if (APPL(appl)->releasing <= 0) {
10440 - APPL(appl)->signal = 0;
10441 - APPL_MARK_FREE(appl);
10442 - printk(KERN_INFO "kcapi: appl %d down\n", appl);
10444 + if (APPL(appl)->releasing) { /* only release if the application was marked for release */
10445 + printk(KERN_DEBUG "kcapi: appl %d releasing(%d)\n", appl, APPL(appl)->releasing);
10446 + APPL(appl)->releasing--;
10447 + if (APPL(appl)->releasing <= 0) {
10448 + APPL(appl)->signal = 0;
10449 + APPL_MARK_FREE(appl);
10450 + printk(KERN_INFO "kcapi: appl %d down\n", appl);
10453 + printk(KERN_WARNING "kcapi: appl %d card%d released without request\n", appl, card->cnr);
10457 @@ -863,16 +873,7 @@
10459 static void controllercb_ready(struct capi_ctr * card)
10463 card->cardstate = CARD_RUNNING;
10465 - for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
10466 - if (!VALID_APPLID(appl)) continue;
10467 - if (APPL(appl)->releasing) continue;
10468 - card->driver->register_appl(card, appl, &APPL(appl)->rparam);
10471 printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n",
10472 CARDNR(card), card->name);
10474 diff -urN linux-2.4.18/drivers/usb/Config.in linux-2.4.18-mh15/drivers/usb/Config.in
10475 --- linux-2.4.18/drivers/usb/Config.in 2002-02-25 20:38:07.000000000 +0100
10476 +++ linux-2.4.18-mh15/drivers/usb/Config.in 2004-08-01 16:26:23.000000000 +0200
10479 comment 'USB Device Class drivers'
10480 dep_tristate ' USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND
10481 -dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB $CONFIG_EXPERIMENTAL
10482 +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
10483 + if [ "$CONFIG_BLUEZ" = "n" ]; then
10484 + dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB
10486 + comment ' USB Bluetooth can only be used with disabled Bluetooth subsystem'
10489 if [ "$CONFIG_SCSI" = "n" ]; then
10490 comment ' SCSI support is needed for USB Storage'
10492 diff -urN linux-2.4.18/drivers/usb/hid-core.c linux-2.4.18-mh15/drivers/usb/hid-core.c
10493 --- linux-2.4.18/drivers/usb/hid-core.c 2001-12-21 18:41:55.000000000 +0100
10494 +++ linux-2.4.18-mh15/drivers/usb/hid-core.c 2004-08-01 16:26:23.000000000 +0200
10495 @@ -217,6 +217,8 @@
10497 offset = report->size;
10498 report->size += parser->global.report_size * parser->global.report_count;
10499 + if (usages < parser->global.report_count)
10500 + usages = parser->global.report_count;
10503 return 0; /* ignore padding fields */
10504 diff -urN linux-2.4.18/include/linux/firmware.h linux-2.4.18-mh15/include/linux/firmware.h
10505 --- linux-2.4.18/include/linux/firmware.h 1970-01-01 01:00:00.000000000 +0100
10506 +++ linux-2.4.18-mh15/include/linux/firmware.h 2004-08-01 16:26:23.000000000 +0200
10508 +#ifndef _LINUX_FIRMWARE_H
10509 +#define _LINUX_FIRMWARE_H
10510 +#include <linux/module.h>
10511 +#include <linux/types.h>
10512 +#define FIRMWARE_NAME_MAX 30
10517 +int request_firmware (const struct firmware **fw, const char *name,
10518 + const char *device);
10519 +int request_firmware_nowait (
10520 + struct module *module,
10521 + const char *name, const char *device, void *context,
10522 + void (*cont)(const struct firmware *fw, void *context));
10523 +/* On 2.5 'device' is 'struct device *' */
10525 +void release_firmware (const struct firmware *fw);
10526 +void register_firmware (const char *name, const u8 *data, size_t size);
10528 diff -urN linux-2.4.18/include/linux/input.h linux-2.4.18-mh15/include/linux/input.h
10529 --- linux-2.4.18/include/linux/input.h 2001-09-13 00:34:06.000000000 +0200
10530 +++ linux-2.4.18-mh15/include/linux/input.h 2004-08-01 16:26:23.000000000 +0200
10531 @@ -468,6 +468,8 @@
10532 #define BUS_PCI 0x01
10533 #define BUS_ISAPNP 0x02
10534 #define BUS_USB 0x03
10535 +#define BUS_HIL 0x04
10536 +#define BUS_BLUETOOTH 0x05
10538 #define BUS_ISA 0x10
10539 #define BUS_I8042 0x11
10540 diff -urN linux-2.4.18/include/linux/kernel.h linux-2.4.18-mh15/include/linux/kernel.h
10541 --- linux-2.4.18/include/linux/kernel.h 2002-02-25 20:38:13.000000000 +0100
10542 +++ linux-2.4.18-mh15/include/linux/kernel.h 2004-08-01 16:26:23.000000000 +0200
10544 #include <linux/linkage.h>
10545 #include <linux/stddef.h>
10546 #include <linux/types.h>
10547 +#include <linux/compiler.h>
10549 /* Optimization barrier */
10550 /* The "volatile" is due to gcc bugs */
10551 @@ -181,4 +182,6 @@
10552 char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
10556 +#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
10558 +#endif /* _LINUX_KERNEL_H */
10559 diff -urN linux-2.4.18/include/linux/net.h linux-2.4.18-mh15/include/linux/net.h
10560 --- linux-2.4.18/include/linux/net.h 2001-11-22 20:46:19.000000000 +0100
10561 +++ linux-2.4.18-mh15/include/linux/net.h 2004-08-01 16:26:23.000000000 +0200
10562 @@ -139,6 +139,7 @@
10563 extern int sock_recvmsg(struct socket *, struct msghdr *m, int len, int flags);
10564 extern int sock_readv_writev(int type, struct inode * inode, struct file * file,
10565 const struct iovec * iov, long count, long size);
10566 +extern struct socket *sockfd_lookup(int fd, int *err);
10568 extern int net_ratelimit(void);
10569 extern unsigned long net_random(void);
10570 diff -urN linux-2.4.18/include/linux/uinput.h linux-2.4.18-mh15/include/linux/uinput.h
10571 --- linux-2.4.18/include/linux/uinput.h 1970-01-01 01:00:00.000000000 +0100
10572 +++ linux-2.4.18-mh15/include/linux/uinput.h 2004-08-01 16:26:23.000000000 +0200
10575 + * User level driver support for input subsystem
10577 + * Heavily based on evdev.c by Vojtech Pavlik
10579 + * This program is free software; you can redistribute it and/or modify
10580 + * it under the terms of the GNU General Public License as published by
10581 + * the Free Software Foundation; either version 2 of the License, or
10582 + * (at your option) any later version.
10584 + * This program is distributed in the hope that it will be useful,
10585 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10586 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10587 + * GNU General Public License for more details.
10589 + * You should have received a copy of the GNU General Public License
10590 + * along with this program; if not, write to the Free Software
10591 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
10593 + * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
10595 + * Changes/Revisions:
10597 + * - first public version
10600 +#ifndef __UINPUT_H_
10601 +#define __UINPUT_H_
10604 +#define UINPUT_MINOR 223
10605 +#define UINPUT_NAME "uinput"
10606 +#define UINPUT_BUFFER_SIZE 16
10608 +/* state flags => bit index for {set|clear|test}_bit ops */
10609 +#define UIST_CREATED 0
10611 +struct uinput_device {
10612 + struct input_dev *dev;
10613 + unsigned long state;
10614 + wait_queue_head_t waitq;
10615 + unsigned char ready,
10618 + struct input_event buff[UINPUT_BUFFER_SIZE];
10620 +#endif /* __KERNEL__ */
10623 +#define UINPUT_IOCTL_BASE 'U'
10624 +#define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1)
10625 +#define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2)
10626 +#define UI_SET_EVBIT _IOW(UINPUT_IOCTL_BASE, 100, int)
10627 +#define UI_SET_KEYBIT _IOW(UINPUT_IOCTL_BASE, 101, int)
10628 +#define UI_SET_RELBIT _IOW(UINPUT_IOCTL_BASE, 102, int)
10629 +#define UI_SET_ABSBIT _IOW(UINPUT_IOCTL_BASE, 103, int)
10630 +#define UI_SET_MSCBIT _IOW(UINPUT_IOCTL_BASE, 104, int)
10631 +#define UI_SET_LEDBIT _IOW(UINPUT_IOCTL_BASE, 105, int)
10632 +#define UI_SET_SNDBIT _IOW(UINPUT_IOCTL_BASE, 106, int)
10633 +#define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int)
10636 +#define NBITS(x) ((((x)-1)/(sizeof(long)*8))+1)
10637 +#endif /* NBITS */
10639 +#define UINPUT_MAX_NAME_SIZE 80
10640 +struct uinput_user_dev {
10641 + char name[UINPUT_MAX_NAME_SIZE];
10642 + unsigned short idbus;
10643 + unsigned short idvendor;
10644 + unsigned short idproduct;
10645 + unsigned short idversion;
10646 + int ff_effects_max;
10647 + int absmax[ABS_MAX + 1];
10648 + int absmin[ABS_MAX + 1];
10649 + int absfuzz[ABS_MAX + 1];
10650 + int absflat[ABS_MAX + 1];
10652 +#endif /* __UINPUT_H_ */
10653 diff -urN linux-2.4.18/include/net/bluetooth/bluetooth.h linux-2.4.18-mh15/include/net/bluetooth/bluetooth.h
10654 --- linux-2.4.18/include/net/bluetooth/bluetooth.h 2001-09-07 18:28:38.000000000 +0200
10655 +++ linux-2.4.18-mh15/include/net/bluetooth/bluetooth.h 2004-08-01 16:26:23.000000000 +0200
10660 - * $Id: bluetooth.h,v 1.6 2001/08/03 04:19:49 maxk Exp $
10661 + * $Id: bluetooth.h,v 1.9 2002/05/06 21:11:55 maxk Exp $
10664 #ifndef __BLUETOOTH_H
10665 @@ -31,17 +31,64 @@
10667 #include <asm/types.h>
10668 #include <asm/byteorder.h>
10669 +#include <linux/poll.h>
10670 +#include <net/sock.h>
10672 #ifndef AF_BLUETOOTH
10673 #define AF_BLUETOOTH 31
10674 #define PF_BLUETOOTH AF_BLUETOOTH
10677 +/* Reserv for core and drivers use */
10678 +#define BLUEZ_SKB_RESERVE 8
10681 +#define MIN(a,b) ((a) < (b) ? (a) : (b))
10684 #define BTPROTO_L2CAP 0
10685 #define BTPROTO_HCI 1
10686 +#define BTPROTO_SCO 2
10687 +#define BTPROTO_RFCOMM 3
10688 +#define BTPROTO_BNEP 4
10689 +#define BTPROTO_CMTP 5
10690 +#define BTPROTO_HIDP 6
10693 #define SOL_L2CAP 6
10694 +#define SOL_SCO 17
10695 +#define SOL_RFCOMM 18
10698 +#ifdef CONFIG_BLUEZ_DEBUG
10700 +#define HCI_CORE_DEBUG 1
10701 +#define HCI_SOCK_DEBUG 1
10702 +#define HCI_UART_DEBUG 1
10703 +#define HCI_USB_DEBUG 1
10704 +//#define HCI_DATA_DUMP 1
10706 +#define L2CAP_DEBUG 1
10707 +#define SCO_DEBUG 1
10708 +#define AF_BLUETOOTH_DEBUG 1
10710 +#endif /* CONFIG_BLUEZ_DEBUG */
10712 +extern void bluez_dump(char *pref, __u8 *buf, int count);
10714 +#if __GNUC__ <= 2 && __GNUC_MINOR__ < 95
10715 +#define __func__ __FUNCTION__
10718 +#define BT_INFO(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
10719 +#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __func__ , ## arg)
10720 +#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
10722 +#ifdef HCI_DATA_DUMP
10723 +#define BT_DMP(buf, len) bluez_dump(__func__, buf, len)
10725 +#define BT_DMP(D...)
10728 /* Connection and socket states */
10740 } __attribute__((packed)) bdaddr_t;
10742 -#define BDADDR_ANY ((bdaddr_t *)"\000\000\000\000\000")
10743 +#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
10744 +#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
10746 /* Copy, swap, convert BD Address */
10747 static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2)
10748 @@ -82,6 +131,91 @@
10749 char *batostr(bdaddr_t *ba);
10750 bdaddr_t *strtoba(char *str);
10752 +/* Common socket structures and functions */
10754 +#define bluez_pi(sk) ((struct bluez_pinfo *) &sk->protinfo)
10755 +#define bluez_sk(pi) ((struct sock *) \
10756 + ((void *)pi - (unsigned long)(&((struct sock *)0)->protinfo)))
10758 +struct bluez_pinfo {
10762 + struct list_head accept_q;
10763 + struct sock *parent;
10766 +struct bluez_sock_list {
10767 + struct sock *head;
10771 +int bluez_sock_register(int proto, struct net_proto_family *ops);
10772 +int bluez_sock_unregister(int proto);
10773 +void bluez_sock_init(struct socket *sock, struct sock *sk);
10774 +void bluez_sock_link(struct bluez_sock_list *l, struct sock *s);
10775 +void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *s);
10776 +int bluez_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm);
10777 +uint bluez_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
10778 +int bluez_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
10780 +void bluez_accept_enqueue(struct sock *parent, struct sock *sk);
10781 +struct sock * bluez_accept_dequeue(struct sock *parent, struct socket *newsock);
10784 +struct bluez_skb_cb {
10787 +#define bluez_cb(skb) ((struct bluez_skb_cb *)(skb->cb))
10789 +static inline struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
10791 + struct sk_buff *skb;
10793 + if ((skb = alloc_skb(len + BLUEZ_SKB_RESERVE, how))) {
10794 + skb_reserve(skb, BLUEZ_SKB_RESERVE);
10795 + bluez_cb(skb)->incomming = 0;
10800 +static inline struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len,
10801 + int nb, int *err)
10803 + struct sk_buff *skb;
10805 + if ((skb = sock_alloc_send_skb(sk, len + BLUEZ_SKB_RESERVE, nb, err))) {
10806 + skb_reserve(skb, BLUEZ_SKB_RESERVE);
10807 + bluez_cb(skb)->incomming = 0;
10813 +static inline int skb_frags_no(struct sk_buff *skb)
10815 + register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
10816 + register int n = 1;
10818 + for (; frag; frag=frag->next, n++);
10822 +int hci_core_init(void);
10823 +int hci_core_cleanup(void);
10824 +int hci_sock_init(void);
10825 +int hci_sock_cleanup(void);
10827 int bterr(__u16 code);
10829 +#ifndef MODULE_LICENSE
10830 +#define MODULE_LICENSE(x)
10833 +#ifndef list_for_each_safe
10834 +#define list_for_each_safe(pos, n, head) \
10835 + for (pos = (head)->next, n = pos->next; pos != (head); \
10836 + pos = n, n = pos->next)
10839 #endif /* __BLUETOOTH_H */
10840 diff -urN linux-2.4.18/include/net/bluetooth/bluez.h linux-2.4.18-mh15/include/net/bluetooth/bluez.h
10841 --- linux-2.4.18/include/net/bluetooth/bluez.h 2001-09-07 18:28:38.000000000 +0200
10842 +++ linux-2.4.18-mh15/include/net/bluetooth/bluez.h 1970-01-01 01:00:00.000000000 +0100
10845 - BlueZ - Bluetooth protocol stack for Linux
10846 - Copyright (C) 2000-2001 Qualcomm Incorporated
10848 - Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
10850 - This program is free software; you can redistribute it and/or modify
10851 - it under the terms of the GNU General Public License version 2 as
10852 - published by the Free Software Foundation;
10854 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10855 - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
10856 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
10857 - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
10858 - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
10859 - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
10860 - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
10861 - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
10863 - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
10864 - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
10865 - SOFTWARE IS DISCLAIMED.
10869 - * $Id: bluez.h,v 1.4 2001/08/03 04:19:49 maxk Exp $
10872 -#ifndef __IF_BLUEZ_H
10873 -#define __IF_BLUEZ_H
10875 -#include <net/sock.h>
10877 -#define BLUEZ_MAX_PROTO 2
10879 -/* Reserv for core and drivers use */
10880 -#define BLUEZ_SKB_RESERVE 8
10883 -#define MIN(a,b) ((a) < (b) ? (a) : (b))
10887 -#ifdef BLUEZ_DEBUG
10889 -#define HCI_CORE_DEBUG 1
10890 -#define HCI_SOCK_DEBUG 1
10891 -#define HCI_UART_DEBUG 1
10892 -#define HCI_USB_DEBUG 1
10893 -//#define HCI_DATA_DUMP 1
10895 -#define L2CAP_DEBUG 1
10897 -#endif /* BLUEZ_DEBUG */
10899 -extern void bluez_dump(char *pref, __u8 *buf, int count);
10901 -#define INF(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
10902 -#define DBG(fmt, arg...) printk(KERN_INFO __FUNCTION__ ": " fmt "\n" , ## arg)
10903 -#define ERR(fmt, arg...) printk(KERN_ERR __FUNCTION__ ": " fmt "\n" , ## arg)
10905 -#ifdef HCI_DATA_DUMP
10906 -#define DMP(buf, len) bluez_dump(__FUNCTION__, buf, len)
10911 -/* ----- Sockets ------ */
10912 -struct bluez_sock_list {
10913 - struct sock *head;
10917 -extern int bluez_sock_register(int proto, struct net_proto_family *ops);
10918 -extern int bluez_sock_unregister(int proto);
10920 -extern void bluez_sock_link(struct bluez_sock_list *l, struct sock *s);
10921 -extern void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *s);
10923 -/* ----- SKB helpers ----- */
10924 -struct bluez_skb_cb {
10927 -#define bluez_cb(skb) ((struct bluez_skb_cb *)(skb->cb))
10929 -static inline struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
10931 - struct sk_buff *skb;
10933 - if ((skb = alloc_skb(len + BLUEZ_SKB_RESERVE, how))) {
10934 - skb_reserve(skb, BLUEZ_SKB_RESERVE);
10935 - bluez_cb(skb)->incomming = 0;
10940 -static inline struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len,
10941 - int nb, int *err)
10943 - struct sk_buff *skb;
10945 - if ((skb = sock_alloc_send_skb(sk, len + BLUEZ_SKB_RESERVE, nb, err))) {
10946 - skb_reserve(skb, BLUEZ_SKB_RESERVE);
10947 - bluez_cb(skb)->incomming = 0;
10953 -static inline int skb_frags_no(struct sk_buff *skb)
10955 - register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
10956 - register int n = 1;
10958 - for (; frag; frag=frag->next, n++);
10962 -extern int hci_core_init(void);
10963 -extern int hci_core_cleanup(void);
10964 -extern int hci_sock_init(void);
10965 -extern int hci_sock_cleanup(void);
10967 -#endif /* __IF_BLUEZ_H */
10968 diff -urN linux-2.4.18/include/net/bluetooth/hci_core.h linux-2.4.18-mh15/include/net/bluetooth/hci_core.h
10969 --- linux-2.4.18/include/net/bluetooth/hci_core.h 2001-09-07 18:28:38.000000000 +0200
10970 +++ linux-2.4.18-mh15/include/net/bluetooth/hci_core.h 2004-08-01 16:26:23.000000000 +0200
10975 - * $Id: hci_core.h,v 1.11 2001/08/05 06:02:15 maxk Exp $
10976 + * $Id: hci_core.h,v 1.5 2002/06/27 04:56:30 maxk Exp $
10979 #ifndef __HCI_CORE_H
10980 @@ -32,14 +32,12 @@
10981 #include <net/bluetooth/hci.h>
10983 /* HCI upper protocols */
10984 -#define HCI_MAX_PROTO 1
10985 #define HCI_PROTO_L2CAP 0
10986 +#define HCI_PROTO_SCO 1
10988 #define HCI_INIT_TIMEOUT (HZ * 10)
10990 -/* ----- Inquiry cache ----- */
10991 -#define INQUIRY_CACHE_AGE_MAX (HZ*5) // 5 seconds
10992 -#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds
10993 +/* HCI Core structures */
10995 struct inquiry_entry {
10996 struct inquiry_entry *next;
10997 @@ -53,111 +51,188 @@
10998 struct inquiry_entry *list;
11001 -static inline void inquiry_cache_init(struct inquiry_cache *cache)
11003 - spin_lock_init(&cache->lock);
11004 - cache->list = NULL;
11006 +struct conn_hash {
11007 + struct list_head list;
11009 + unsigned int num;
11012 -static inline void inquiry_cache_lock(struct inquiry_cache *cache)
11014 - spin_lock(&cache->lock);
11017 + struct list_head list;
11021 -static inline void inquiry_cache_unlock(struct inquiry_cache *cache)
11023 - spin_unlock(&cache->lock);
11026 + unsigned long flags;
11030 + __u8 features[8];
11032 -static inline void inquiry_cache_lock_bh(struct inquiry_cache *cache)
11034 - spin_lock_bh(&cache->lock);
11037 + __u16 link_policy;
11040 -static inline void inquiry_cache_unlock_bh(struct inquiry_cache *cache)
11042 - spin_unlock_bh(&cache->lock);
11044 + unsigned long quirks;
11046 -static inline long inquiry_cache_age(struct inquiry_cache *cache)
11048 - return jiffies - cache->timestamp;
11050 + atomic_t cmd_cnt;
11051 + unsigned int acl_cnt;
11052 + unsigned int sco_cnt;
11054 -static inline long inquiry_entry_age(struct inquiry_entry *e)
11056 - return jiffies - e->timestamp;
11058 -extern void inquiry_cache_flush(struct inquiry_cache *cache);
11059 + unsigned int acl_mtu;
11060 + unsigned int sco_mtu;
11061 + unsigned int acl_pkts;
11062 + unsigned int sco_pkts;
11065 + unsigned long cmd_last_tx;
11066 + unsigned long acl_last_tx;
11067 + unsigned long sco_last_tx;
11069 + struct tasklet_struct cmd_task;
11070 + struct tasklet_struct rx_task;
11071 + struct tasklet_struct tx_task;
11073 + struct sk_buff_head rx_q;
11074 + struct sk_buff_head raw_q;
11075 + struct sk_buff_head cmd_q;
11077 + struct sk_buff *sent_cmd;
11079 + struct semaphore req_lock;
11080 + wait_queue_head_t req_wait_q;
11081 + __u32 req_status;
11082 + __u32 req_result;
11084 + struct inquiry_cache inq_cache;
11085 + struct conn_hash conn_hash;
11087 + struct hci_dev_stats stat;
11089 + void *driver_data;
11092 + atomic_t promisc;
11094 + int (*open)(struct hci_dev *hdev);
11095 + int (*close)(struct hci_dev *hdev);
11096 + int (*flush)(struct hci_dev *hdev);
11097 + int (*send)(struct sk_buff *skb);
11098 + void (*destruct)(struct hci_dev *hdev);
11099 + int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
11102 -/* ----- HCI Connections ----- */
11104 struct list_head list;
11113 - unsigned int sent;
11116 + unsigned long pend;
11118 + unsigned int sent;
11120 + struct sk_buff_head data_q;
11122 + struct timer_list timer;
11124 struct hci_dev *hdev;
11129 - struct sk_buff_head data_q;
11130 + struct hci_conn *link;
11133 -struct conn_hash {
11134 - struct list_head list;
11136 - unsigned int num;
11138 +extern struct hci_proto *hci_proto[];
11139 +extern struct list_head hdev_list;
11140 +extern rwlock_t hdev_list_lock;
11142 +/* ----- Inquiry cache ----- */
11143 +#define INQUIRY_CACHE_AGE_MAX (HZ*30) // 30 seconds
11144 +#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds
11146 +#define inquiry_cache_lock(c) spin_lock(&c->lock)
11147 +#define inquiry_cache_unlock(c) spin_unlock(&c->lock)
11148 +#define inquiry_cache_lock_bh(c) spin_lock_bh(&c->lock)
11149 +#define inquiry_cache_unlock_bh(c) spin_unlock_bh(&c->lock)
11151 -static inline void conn_hash_init(struct conn_hash *h)
11152 +static inline void inquiry_cache_init(struct hci_dev *hdev)
11154 - INIT_LIST_HEAD(&h->list);
11155 - spin_lock_init(&h->lock);
11157 + struct inquiry_cache *c = &hdev->inq_cache;
11158 + spin_lock_init(&c->lock);
11162 -static inline void conn_hash_lock(struct conn_hash *h)
11163 +static inline int inquiry_cache_empty(struct hci_dev *hdev)
11165 - spin_lock(&h->lock);
11166 + struct inquiry_cache *c = &hdev->inq_cache;
11167 + return (c->list == NULL);
11170 -static inline void conn_hash_unlock(struct conn_hash *h)
11171 +static inline long inquiry_cache_age(struct hci_dev *hdev)
11173 - spin_unlock(&h->lock);
11174 + struct inquiry_cache *c = &hdev->inq_cache;
11175 + return jiffies - c->timestamp;
11178 -static inline void __conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
11179 +static inline long inquiry_entry_age(struct inquiry_entry *e)
11181 - list_add(&c->list, &h->list);
11183 + return jiffies - e->timestamp;
11186 -static inline void conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
11187 +struct inquiry_entry *inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
11188 +void inquiry_cache_update(struct hci_dev *hdev, inquiry_info *info);
11189 +void inquiry_cache_flush(struct hci_dev *hdev);
11190 +int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf);
11192 +/* ----- HCI Connections ----- */
11194 + HCI_CONN_AUTH_PEND,
11195 + HCI_CONN_ENCRYPT_PEND
11198 +#define hci_conn_lock(c) spin_lock(&c->lock)
11199 +#define hci_conn_unlock(c) spin_unlock(&c->lock)
11200 +#define hci_conn_lock_bh(c) spin_lock_bh(&c->lock)
11201 +#define hci_conn_unlock_bh(c) spin_unlock_bh(&c->lock)
11203 +#define conn_hash_lock(d) spin_lock(&d->conn_hash->lock)
11204 +#define conn_hash_unlock(d) spin_unlock(&d->conn_hash->lock)
11205 +#define conn_hash_lock_bh(d) spin_lock_bh(&d->conn_hash->lock)
11206 +#define conn_hash_unlock_bh(d) spin_unlock_bh(&d->conn_hash->lock)
11208 +static inline void conn_hash_init(struct hci_dev *hdev)
11210 - conn_hash_lock(h);
11211 - __conn_hash_add(h, handle, c);
11212 - conn_hash_unlock(h);
11213 + struct conn_hash *h = &hdev->conn_hash;
11214 + INIT_LIST_HEAD(&h->list);
11215 + spin_lock_init(&h->lock);
11219 -static inline void __conn_hash_del(struct conn_hash *h, struct hci_conn *c)
11220 +static inline void conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
11222 - list_del(&c->list);
11224 + struct conn_hash *h = &hdev->conn_hash;
11225 + list_add(&c->list, &h->list);
11229 -static inline void conn_hash_del(struct conn_hash *h, struct hci_conn *c)
11230 +static inline void conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
11232 - conn_hash_lock(h);
11233 - __conn_hash_del(h, c);
11234 - conn_hash_unlock(h);
11235 + struct conn_hash *h = &hdev->conn_hash;
11236 + list_del(&c->list);
11240 -static inline struct hci_conn *__conn_hash_lookup(struct conn_hash *h, __u16 handle)
11241 +static inline struct hci_conn *conn_hash_lookup_handle(struct hci_dev *hdev,
11244 + register struct conn_hash *h = &hdev->conn_hash;
11245 register struct list_head *p;
11246 register struct hci_conn *c;
11248 @@ -169,101 +244,97 @@
11252 -static inline struct hci_conn *conn_hash_lookup(struct conn_hash *h, __u16 handle)
11253 +static inline struct hci_conn *conn_hash_lookup_ba(struct hci_dev *hdev,
11254 + __u8 type, bdaddr_t *ba)
11256 - struct hci_conn *conn;
11257 + register struct conn_hash *h = &hdev->conn_hash;
11258 + register struct list_head *p;
11259 + register struct hci_conn *c;
11261 - conn_hash_lock(h);
11262 - conn = __conn_hash_lookup(h, handle);
11263 - conn_hash_unlock(h);
11265 + list_for_each(p, &h->list) {
11266 + c = list_entry(p, struct hci_conn, list);
11267 + if (c->type == type && !bacmp(&c->dst, ba))
11273 -/* ----- HCI Devices ----- */
11282 - __u8 features[8];
11286 - atomic_t cmd_cnt;
11287 - unsigned int acl_cnt;
11288 - unsigned int sco_cnt;
11290 - unsigned int acl_mtu;
11291 - unsigned int sco_mtu;
11292 - unsigned int acl_max;
11293 - unsigned int sco_max;
11295 - void *driver_data;
11296 - void *l2cap_data;
11299 - struct tasklet_struct cmd_task;
11300 - struct tasklet_struct rx_task;
11301 - struct tasklet_struct tx_task;
11303 - struct sk_buff_head rx_q;
11304 - struct sk_buff_head raw_q;
11305 - struct sk_buff_head cmd_q;
11307 - struct sk_buff *sent_cmd;
11308 +void hci_acl_connect(struct hci_conn *conn);
11309 +void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
11310 +void hci_add_sco(struct hci_conn *conn, __u16 handle);
11312 - struct semaphore req_lock;
11313 - wait_queue_head_t req_wait_q;
11314 - __u32 req_status;
11315 - __u32 req_result;
11316 +struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
11317 +int hci_conn_del(struct hci_conn *conn);
11318 +void hci_conn_hash_flush(struct hci_dev *hdev);
11320 - struct inquiry_cache inq_cache;
11321 +struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src);
11322 +int hci_conn_auth(struct hci_conn *conn);
11323 +int hci_conn_encrypt(struct hci_conn *conn);
11325 - struct conn_hash conn_hash;
11327 - struct hci_dev_stats stat;
11329 - int (*open)(struct hci_dev *hdev);
11330 - int (*close)(struct hci_dev *hdev);
11331 - int (*flush)(struct hci_dev *hdev);
11332 - int (*send)(struct sk_buff *skb);
11334 +static inline void hci_conn_set_timer(struct hci_conn *conn, long timeout)
11336 + mod_timer(&conn->timer, jiffies + timeout);
11339 -static inline void hci_dev_hold(struct hci_dev *hdev)
11340 +static inline void hci_conn_del_timer(struct hci_conn *conn)
11342 - atomic_inc(&hdev->refcnt);
11343 + del_timer(&conn->timer);
11346 -static inline void hci_dev_put(struct hci_dev *hdev)
11347 +static inline void hci_conn_hold(struct hci_conn *conn)
11349 - atomic_dec(&hdev->refcnt);
11350 + atomic_inc(&conn->refcnt);
11351 + hci_conn_del_timer(conn);
11354 -extern struct hci_dev *hci_dev_get(int index);
11355 -extern int hci_register_dev(struct hci_dev *hdev);
11356 -extern int hci_unregister_dev(struct hci_dev *hdev);
11357 -extern int hci_dev_open(__u16 dev);
11358 -extern int hci_dev_close(__u16 dev);
11359 -extern int hci_dev_reset(__u16 dev);
11360 -extern int hci_dev_reset_stat(__u16 dev);
11361 -extern int hci_dev_info(unsigned long arg);
11362 -extern int hci_dev_list(unsigned long arg);
11363 -extern int hci_dev_setscan(unsigned long arg);
11364 -extern int hci_dev_setauth(unsigned long arg);
11365 -extern int hci_dev_setptype(unsigned long arg);
11366 -extern int hci_conn_list(unsigned long arg);
11367 -extern int hci_inquiry(unsigned long arg);
11368 +static inline void hci_conn_put(struct hci_conn *conn)
11370 + if (atomic_dec_and_test(&conn->refcnt)) {
11371 + if (conn->type == ACL_LINK) {
11372 + unsigned long timeo = (conn->out) ?
11373 + HCI_DISCONN_TIMEOUT : HCI_DISCONN_TIMEOUT * 2;
11374 + hci_conn_set_timer(conn, timeo);
11376 + hci_conn_set_timer(conn, HZ / 100);
11380 -extern __u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode);
11381 -extern __u32 hci_dev_getmode(struct hci_dev *hdev);
11382 +/* ----- HCI Devices ----- */
11383 +static inline void hci_dev_put(struct hci_dev *d)
11385 + if (atomic_dec_and_test(&d->refcnt))
11388 +#define hci_dev_hold(d) atomic_inc(&d->refcnt)
11390 +#define hci_dev_lock(d) spin_lock(&d->lock)
11391 +#define hci_dev_unlock(d) spin_unlock(&d->lock)
11392 +#define hci_dev_lock_bh(d) spin_lock_bh(&d->lock)
11393 +#define hci_dev_unlock_bh(d) spin_unlock_bh(&d->lock)
11395 +struct hci_dev *hci_dev_get(int index);
11396 +struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst);
11397 +int hci_register_dev(struct hci_dev *hdev);
11398 +int hci_unregister_dev(struct hci_dev *hdev);
11399 +int hci_suspend_dev(struct hci_dev *hdev);
11400 +int hci_resume_dev(struct hci_dev *hdev);
11401 +int hci_dev_open(__u16 dev);
11402 +int hci_dev_close(__u16 dev);
11403 +int hci_dev_reset(__u16 dev);
11404 +int hci_dev_reset_stat(__u16 dev);
11405 +int hci_dev_cmd(unsigned int cmd, unsigned long arg);
11406 +int hci_get_dev_list(unsigned long arg);
11407 +int hci_get_dev_info(unsigned long arg);
11408 +int hci_get_conn_list(unsigned long arg);
11409 +int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg);
11410 +int hci_inquiry(unsigned long arg);
11412 -extern int hci_recv_frame(struct sk_buff *skb);
11413 +int hci_recv_frame(struct sk_buff *skb);
11414 +void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
11416 /* ----- LMP capabilities ----- */
11417 #define lmp_rswitch_capable(dev) (dev->features[0] & LMP_RSWITCH)
11418 +#define lmp_encrypt_capable(dev) (dev->features[0] & LMP_ENCRYPT)
11420 /* ----- HCI tasks ----- */
11421 static inline void hci_sched_cmd(struct hci_dev *hdev)
11422 @@ -284,43 +355,130 @@
11423 /* ----- HCI protocols ----- */
11429 + unsigned long flags;
11433 - int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr);
11434 - int (*connect_cfm) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 status, struct hci_conn *conn);
11435 + int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type);
11436 + int (*connect_cfm) (struct hci_conn *conn, __u8 status);
11437 int (*disconn_ind) (struct hci_conn *conn, __u8 reason);
11438 - int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb , __u16 flags);
11439 + int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
11440 int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb);
11441 + int (*auth_cfm) (struct hci_conn *conn, __u8 status);
11442 + int (*encrypt_cfm) (struct hci_conn *conn, __u8 status);
11445 -extern int hci_register_proto(struct hci_proto *hproto);
11446 -extern int hci_unregister_proto(struct hci_proto *hproto);
11447 -extern int hci_register_notifier(struct notifier_block *nb);
11448 -extern int hci_unregister_notifier(struct notifier_block *nb);
11449 -extern int hci_connect(struct hci_dev * hdev, bdaddr_t * bdaddr);
11450 -extern int hci_disconnect(struct hci_conn *conn, __u8 reason);
11451 -extern int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void * param);
11452 -extern int hci_send_raw(struct sk_buff *skb);
11453 -extern int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
11454 -extern int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
11455 +static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
11457 + register struct hci_proto *hp;
11460 + hp = hci_proto[HCI_PROTO_L2CAP];
11461 + if (hp && hp->connect_ind)
11462 + mask |= hp->connect_ind(hdev, bdaddr, type);
11464 + hp = hci_proto[HCI_PROTO_SCO];
11465 + if (hp && hp->connect_ind)
11466 + mask |= hp->connect_ind(hdev, bdaddr, type);
11471 +static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
11473 + register struct hci_proto *hp;
11475 + hp = hci_proto[HCI_PROTO_L2CAP];
11476 + if (hp && hp->connect_cfm)
11477 + hp->connect_cfm(conn, status);
11479 + hp = hci_proto[HCI_PROTO_SCO];
11480 + if (hp && hp->connect_cfm)
11481 + hp->connect_cfm(conn, status);
11484 +static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason)
11486 + register struct hci_proto *hp;
11488 + hp = hci_proto[HCI_PROTO_L2CAP];
11489 + if (hp && hp->disconn_ind)
11490 + hp->disconn_ind(conn, reason);
11492 + hp = hci_proto[HCI_PROTO_SCO];
11493 + if (hp && hp->disconn_ind)
11494 + hp->disconn_ind(conn, reason);
11497 +static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
11499 + register struct hci_proto *hp;
11501 + hp = hci_proto[HCI_PROTO_L2CAP];
11502 + if (hp && hp->auth_cfm)
11503 + hp->auth_cfm(conn, status);
11505 + hp = hci_proto[HCI_PROTO_SCO];
11506 + if (hp && hp->auth_cfm)
11507 + hp->auth_cfm(conn, status);
11510 +static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status)
11512 + register struct hci_proto *hp;
11514 + hp = hci_proto[HCI_PROTO_L2CAP];
11515 + if (hp && hp->encrypt_cfm)
11516 + hp->encrypt_cfm(conn, status);
11518 + hp = hci_proto[HCI_PROTO_SCO];
11519 + if (hp && hp->encrypt_cfm)
11520 + hp->encrypt_cfm(conn, status);
11523 +int hci_register_proto(struct hci_proto *hproto);
11524 +int hci_unregister_proto(struct hci_proto *hproto);
11525 +int hci_register_notifier(struct notifier_block *nb);
11526 +int hci_unregister_notifier(struct notifier_block *nb);
11528 +int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param);
11529 +int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
11530 +int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
11532 +void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf);
11534 +void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
11536 /* ----- HCI Sockets ----- */
11537 -extern void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
11538 +void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
11540 /* HCI info for socket */
11541 -#define hci_pi(sk) ((struct hci_pinfo *) &sk->protinfo)
11542 +#define hci_pi(sk) ((struct hci_pinfo *) &sk->tp_pinfo)
11544 struct hci_dev *hdev;
11545 struct hci_filter filter;
11549 +/* HCI security filter */
11550 +#define HCI_SFLT_MAX_OGF 5
11552 +struct hci_sec_filter {
11554 + __u32 event_mask[2];
11555 + __u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4];
11558 /* ----- HCI requests ----- */
11559 #define HCI_REQ_DONE 0
11560 #define HCI_REQ_PEND 1
11561 #define HCI_REQ_CANCELED 2
11563 +#define hci_req_lock(d) down(&d->req_lock)
11564 +#define hci_req_unlock(d) up(&d->req_lock)
11566 +void hci_req_complete(struct hci_dev *hdev, int result);
11567 +void hci_req_cancel(struct hci_dev *hdev, int err);
11569 #endif /* __HCI_CORE_H */
11570 diff -urN linux-2.4.18/include/net/bluetooth/hci.h linux-2.4.18-mh15/include/net/bluetooth/hci.h
11571 --- linux-2.4.18/include/net/bluetooth/hci.h 2001-09-07 18:28:38.000000000 +0200
11572 +++ linux-2.4.18-mh15/include/net/bluetooth/hci.h 2004-08-01 16:26:23.000000000 +0200
11573 @@ -23,59 +23,80 @@
11577 - * $Id: hci.h,v 1.15 2001/08/05 06:02:15 maxk Exp $
11578 + * $Id: hci.h,v 1.5 2002/06/27 17:29:30 maxk Exp $
11584 -#include <asm/byteorder.h>
11586 -#define HCI_MAX_DEV 8
11587 -#define HCI_MAX_FRAME_SIZE 2048
11588 +#define HCI_MAX_ACL_SIZE 1024
11589 +#define HCI_MAX_SCO_SIZE 255
11590 +#define HCI_MAX_EVENT_SIZE 260
11591 +#define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4)
11593 /* HCI dev events */
11594 #define HCI_DEV_REG 1
11595 #define HCI_DEV_UNREG 2
11596 #define HCI_DEV_UP 3
11597 #define HCI_DEV_DOWN 4
11598 +#define HCI_DEV_SUSPEND 5
11599 +#define HCI_DEV_RESUME 6
11601 /* HCI device types */
11602 -#define HCI_UART 0
11603 +#define HCI_VHCI 0
11605 -#define HCI_VHCI 2
11607 -/* HCI device modes */
11608 -#define HCI_NORMAL 0x0001
11609 -#define HCI_RAW 0x0002
11610 -#define HCI_MODE_MASK (HCI_NORMAL | HCI_RAW)
11611 -#define HCI_SOCK 0x1000
11613 -/* HCI device states */
11614 -#define HCI_INIT 0x0010
11615 -#define HCI_UP 0x0020
11616 -#define HCI_RUNNING 0x0040
11617 +#define HCI_PCCARD 2
11618 +#define HCI_UART 3
11619 +#define HCI_RS232 4
11622 +/* HCI device quirks */
11624 + HCI_QUIRK_RESET_ON_INIT
11627 /* HCI device flags */
11628 -#define HCI_PSCAN 0x0100
11629 -#define HCI_ISCAN 0x0200
11630 -#define HCI_AUTH 0x0400
11645 -/* HCI Ioctl defines */
11646 +/* HCI ioctl defines */
11647 #define HCIDEVUP _IOW('H', 201, int)
11648 #define HCIDEVDOWN _IOW('H', 202, int)
11649 #define HCIDEVRESET _IOW('H', 203, int)
11650 -#define HCIRESETSTAT _IOW('H', 204, int)
11651 -#define HCIGETINFO _IOR('H', 205, int)
11652 -#define HCIGETDEVLIST _IOR('H', 206, int)
11653 -#define HCISETRAW _IOW('H', 207, int)
11654 -#define HCISETSCAN _IOW('H', 208, int)
11655 -#define HCISETAUTH _IOW('H', 209, int)
11656 -#define HCIINQUIRY _IOR('H', 210, int)
11657 -#define HCISETPTYPE _IOW('H', 211, int)
11658 +#define HCIDEVRESTAT _IOW('H', 204, int)
11660 +#define HCIGETDEVLIST _IOR('H', 210, int)
11661 +#define HCIGETDEVINFO _IOR('H', 211, int)
11662 #define HCIGETCONNLIST _IOR('H', 212, int)
11663 +#define HCIGETCONNINFO _IOR('H', 213, int)
11665 -#ifndef __NO_HCI_DEFS
11666 +#define HCISETRAW _IOW('H', 220, int)
11667 +#define HCISETSCAN _IOW('H', 221, int)
11668 +#define HCISETAUTH _IOW('H', 222, int)
11669 +#define HCISETENCRYPT _IOW('H', 223, int)
11670 +#define HCISETPTYPE _IOW('H', 224, int)
11671 +#define HCISETLINKPOL _IOW('H', 225, int)
11672 +#define HCISETLINKMODE _IOW('H', 226, int)
11673 +#define HCISETACLMTU _IOW('H', 227, int)
11674 +#define HCISETSCOMTU _IOW('H', 228, int)
11676 +#define HCIINQUIRY _IOR('H', 240, int)
11678 +/* HCI timeouts */
11679 +#define HCI_CONN_TIMEOUT (HZ * 40)
11680 +#define HCI_DISCONN_TIMEOUT (HZ * 2)
11681 +#define HCI_CONN_IDLE_TIMEOUT (HZ * 60)
11683 /* HCI Packet types */
11684 #define HCI_COMMAND_PKT 0x01
11685 @@ -92,11 +113,18 @@
11686 #define HCI_DH3 0x0800
11687 #define HCI_DH5 0x8000
11689 +#define HCI_HV1 0x0020
11690 +#define HCI_HV2 0x0040
11691 +#define HCI_HV3 0x0080
11693 +#define SCO_PTYPE_MASK (HCI_HV1 | HCI_HV2 | HCI_HV3)
11694 +#define ACL_PTYPE_MASK (~SCO_PTYPE_MASK)
11697 -#define ACL_CONT 0x0001
11698 -#define ACL_START 0x0002
11699 -#define ACL_ACTIVE_BCAST 0x0010
11700 -#define ACL_PICO_BCAST 0x0020
11701 +#define ACL_CONT 0x01
11702 +#define ACL_START 0x02
11703 +#define ACL_ACTIVE_BCAST 0x04
11704 +#define ACL_PICO_BCAST 0x08
11706 /* Baseband links */
11707 #define SCO_LINK 0x00
11708 @@ -125,6 +153,20 @@
11709 #define LMP_PSCHEME 0x02
11710 #define LMP_PCONTROL 0x04
11712 +/* Link policies */
11713 +#define HCI_LP_RSWITCH 0x0001
11714 +#define HCI_LP_HOLD 0x0002
11715 +#define HCI_LP_SNIFF 0x0004
11716 +#define HCI_LP_PARK 0x0008
11719 +#define HCI_LM_ACCEPT 0x8000
11720 +#define HCI_LM_MASTER 0x0001
11721 +#define HCI_LM_AUTH 0x0002
11722 +#define HCI_LM_ENCRYPT 0x0004
11723 +#define HCI_LM_TRUSTED 0x0008
11724 +#define HCI_LM_RELIABLE 0x0010
11726 /* ----- HCI Commands ----- */
11727 /* OGF & OCF values */
11729 @@ -137,9 +179,10 @@
11735 + __u16 manufacturer;
11736 + __u16 lmp_subver;
11737 } __attribute__ ((packed)) read_local_version_rp;
11738 +#define READ_LOCAL_VERSION_RP_SIZE 9
11740 #define OCF_READ_LOCAL_FEATURES 0x0003
11742 @@ -165,18 +208,24 @@
11743 /* Host Controller and Baseband */
11744 #define OGF_HOST_CTL 0x03
11745 #define OCF_RESET 0x0003
11746 +#define OCF_READ_AUTH_ENABLE 0x001F
11747 #define OCF_WRITE_AUTH_ENABLE 0x0020
11748 - #define AUTH_DISABLED 0x00
11749 - #define AUTH_ENABLED 0x01
11750 + #define AUTH_DISABLED 0x00
11751 + #define AUTH_ENABLED 0x01
11753 +#define OCF_READ_ENCRYPT_MODE 0x0021
11754 +#define OCF_WRITE_ENCRYPT_MODE 0x0022
11755 + #define ENCRYPT_DISABLED 0x00
11756 + #define ENCRYPT_P2P 0x01
11757 + #define ENCRYPT_BOTH 0x02
11759 #define OCF_WRITE_CA_TIMEOUT 0x0016
11760 #define OCF_WRITE_PG_TIMEOUT 0x0018
11762 #define OCF_WRITE_SCAN_ENABLE 0x001A
11763 - #define SCANS_DISABLED 0x00
11764 - #define IS_ENA_PS_DIS 0x01
11765 - #define IS_DIS_PS_ENA 0x02
11766 - #define IS_ENA_PS_ENA 0x03
11767 + #define SCAN_DISABLED 0x00
11768 + #define SCAN_INQUIRY 0x01
11769 + #define SCAN_PAGE 0x02
11771 #define OCF_SET_EVENT_FLT 0x0005
11773 @@ -226,9 +275,18 @@
11774 } __attribute__ ((packed)) write_class_of_dev_cp;
11775 #define WRITE_CLASS_OF_DEV_CP_SIZE 3
11777 +#define OCF_HOST_BUFFER_SIZE 0x0033
11781 + __u16 acl_max_pkt;
11782 + __u16 sco_max_pkt;
11783 +} __attribute__ ((packed)) host_buffer_size_cp;
11784 +#define HOST_BUFFER_SIZE_CP_SIZE 7
11787 #define OGF_LINK_CTL 0x01
11788 -#define OCF_CREATE_CONN 0x0005
11789 +#define OCF_CREATE_CONN 0x0005
11793 @@ -246,6 +304,13 @@
11794 } __attribute__ ((packed)) accept_conn_req_cp;
11795 #define ACCEPT_CONN_REQ_CP_SIZE 7
11797 +#define OCF_REJECT_CONN_REQ 0x000a
11801 +} __attribute__ ((packed)) reject_conn_req_cp;
11802 +#define REJECT_CONN_REQ_CP_SIZE 7
11804 #define OCF_DISCONNECT 0x0006
11807 @@ -253,17 +318,142 @@
11808 } __attribute__ ((packed)) disconnect_cp;
11809 #define DISCONNECT_CP_SIZE 3
11811 +#define OCF_ADD_SCO 0x0007
11815 +} __attribute__ ((packed)) add_sco_cp;
11816 +#define ADD_SCO_CP_SIZE 4
11818 #define OCF_INQUIRY 0x0001
11824 } __attribute__ ((packed)) inquiry_cp;
11825 #define INQUIRY_CP_SIZE 5
11827 -#define OGF_LINK_POLICY 0x02 /* Link Policy */
11831 +} __attribute__ ((packed)) status_bdaddr_rp;
11832 +#define STATUS_BDADDR_RP_SIZE 7
11834 +#define OCF_INQUIRY_CANCEL 0x0002
11836 +#define OCF_LINK_KEY_REPLY 0x000B
11837 +#define OCF_LINK_KEY_NEG_REPLY 0x000C
11840 + __u8 link_key[16];
11841 +} __attribute__ ((packed)) link_key_reply_cp;
11842 +#define LINK_KEY_REPLY_CP_SIZE 22
11844 +#define OCF_PIN_CODE_REPLY 0x000D
11845 +#define OCF_PIN_CODE_NEG_REPLY 0x000E
11849 + __u8 pin_code[16];
11850 +} __attribute__ ((packed)) pin_code_reply_cp;
11851 +#define PIN_CODE_REPLY_CP_SIZE 23
11853 +#define OCF_CHANGE_CONN_PTYPE 0x000F
11857 +} __attribute__ ((packed)) change_conn_ptype_cp;
11858 +#define CHANGE_CONN_PTYPE_CP_SIZE 4
11860 +#define OCF_AUTH_REQUESTED 0x0011
11863 +} __attribute__ ((packed)) auth_requested_cp;
11864 +#define AUTH_REQUESTED_CP_SIZE 2
11866 +#define OCF_SET_CONN_ENCRYPT 0x0013
11870 +} __attribute__ ((packed)) set_conn_encrypt_cp;
11871 +#define SET_CONN_ENCRYPT_CP_SIZE 3
11873 +#define OCF_REMOTE_NAME_REQ 0x0019
11876 + __u8 pscan_rep_mode;
11878 + __u16 clock_offset;
11879 +} __attribute__ ((packed)) remote_name_req_cp;
11880 +#define REMOTE_NAME_REQ_CP_SIZE 10
11882 +#define OCF_READ_REMOTE_FEATURES 0x001B
11885 +} __attribute__ ((packed)) read_remote_features_cp;
11886 +#define READ_REMOTE_FEATURES_CP_SIZE 2
11888 +#define OCF_READ_REMOTE_VERSION 0x001D
11891 +} __attribute__ ((packed)) read_remote_version_cp;
11892 +#define READ_REMOTE_VERSION_CP_SIZE 2
11895 +#define OGF_LINK_POLICY 0x02
11896 +#define OCF_ROLE_DISCOVERY 0x0009
11899 +} __attribute__ ((packed)) role_discovery_cp;
11900 +#define ROLE_DISCOVERY_CP_SIZE 2
11905 +} __attribute__ ((packed)) role_discovery_rp;
11906 +#define ROLE_DISCOVERY_RP_SIZE 4
11908 +#define OCF_READ_LINK_POLICY 0x000C
11911 +} __attribute__ ((packed)) read_link_policy_cp;
11912 +#define READ_LINK_POLICY_CP_SIZE 2
11917 +} __attribute__ ((packed)) read_link_policy_rp;
11918 +#define READ_LINK_POLICY_RP_SIZE 5
11920 -/* --------- HCI Events --------- */
11921 +#define OCF_SWITCH_ROLE 0x000B
11925 +} __attribute__ ((packed)) switch_role_cp;
11926 +#define SWITCH_ROLE_CP_SIZE 7
11928 +#define OCF_WRITE_LINK_POLICY 0x000D
11932 +} __attribute__ ((packed)) write_link_policy_cp;
11933 +#define WRITE_LINK_POLICY_CP_SIZE 4
11937 +} __attribute__ ((packed)) write_link_policy_rp;
11938 +#define WRITE_LINK_POLICY_RP_SIZE 3
11940 +/* Status params */
11941 +#define OGF_STATUS_PARAM 0x05
11943 +/* Testing commands */
11944 +#define OGF_TESTING_CMD 0x3e
11946 +/* Vendor specific commands */
11947 +#define OGF_VENDOR_CMD 0x3f
11949 +/* ---- HCI Events ---- */
11950 #define EVT_INQUIRY_COMPLETE 0x01
11952 #define EVT_INQUIRY_RESULT 0x02
11953 @@ -272,11 +462,22 @@
11954 __u8 pscan_rep_mode;
11955 __u8 pscan_period_mode;
11958 + __u8 dev_class[3];
11959 __u16 clock_offset;
11960 } __attribute__ ((packed)) inquiry_info;
11961 #define INQUIRY_INFO_SIZE 14
11963 +#define EVT_INQUIRY_RESULT_WITH_RSSI 0x22
11966 + __u8 pscan_rep_mode;
11967 + __u8 pscan_period_mode;
11968 + __u8 dev_class[3];
11969 + __u16 clock_offset;
11971 +} __attribute__ ((packed)) inquiry_info_with_rssi;
11972 +#define INQUIRY_INFO_WITH_RSSI_SIZE 14
11974 #define EVT_CONN_COMPLETE 0x03
11977 @@ -303,6 +504,44 @@
11978 } __attribute__ ((packed)) evt_disconn_complete;
11979 #define EVT_DISCONN_COMPLETE_SIZE 4
11981 +#define EVT_AUTH_COMPLETE 0x06
11985 +} __attribute__ ((packed)) evt_auth_complete;
11986 +#define EVT_AUTH_COMPLETE_SIZE 3
11988 +#define EVT_REMOTE_NAME_REQ_COMPLETE 0x07
11993 +} __attribute__ ((packed)) evt_remote_name_req_complete;
11994 +#define EVT_REMOTE_NAME_REQ_COMPLETE_SIZE 255
11996 +#define EVT_ENCRYPT_CHANGE 0x08
12001 +} __attribute__ ((packed)) evt_encrypt_change;
12002 +#define EVT_ENCRYPT_CHANGE_SIZE 5
12004 +#define EVT_QOS_SETUP_COMPLETE 0x0D
12006 + __u8 service_type;
12007 + __u32 token_rate;
12008 + __u32 peak_bandwidth;
12010 + __u32 delay_variation;
12011 +} __attribute__ ((packed)) hci_qos;
12016 +} __attribute__ ((packed)) evt_qos_setup_complete;
12017 +#define EVT_QOS_SETUP_COMPLETE_SIZE 20
12019 #define EVT_CMD_COMPLETE 0x0e
12022 @@ -321,16 +560,78 @@
12023 #define EVT_NUM_COMP_PKTS 0x13
12026 - /* variable lenght part */
12027 + /* variable length part */
12028 } __attribute__ ((packed)) evt_num_comp_pkts;
12029 #define EVT_NUM_COMP_PKTS_SIZE 1
12031 -#define EVT_HCI_DEV_EVENT 0xfd
12032 +#define EVT_ROLE_CHANGE 0x12
12037 +} __attribute__ ((packed)) evt_role_change;
12038 +#define EVT_ROLE_CHANGE_SIZE 8
12040 +#define EVT_PIN_CODE_REQ 0x16
12043 +} __attribute__ ((packed)) evt_pin_code_req;
12044 +#define EVT_PIN_CODE_REQ_SIZE 6
12046 +#define EVT_LINK_KEY_REQ 0x17
12049 +} __attribute__ ((packed)) evt_link_key_req;
12050 +#define EVT_LINK_KEY_REQ_SIZE 6
12052 +#define EVT_LINK_KEY_NOTIFY 0x18
12055 + __u8 link_key[16];
12057 +} __attribute__ ((packed)) evt_link_key_notify;
12058 +#define EVT_LINK_KEY_NOTIFY_SIZE 23
12060 +#define EVT_READ_REMOTE_FEATURES_COMPLETE 0x0B
12064 + __u8 features[8];
12065 +} __attribute__ ((packed)) evt_read_remote_features_complete;
12066 +#define EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE 11
12068 +#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C
12073 + __u16 manufacturer;
12074 + __u16 lmp_subver;
12075 +} __attribute__ ((packed)) evt_read_remote_version_complete;
12076 +#define EVT_READ_REMOTE_VERSION_COMPLETE_SIZE 8
12078 +/* Internal events generated by BlueZ stack */
12079 +#define EVT_STACK_INTERNAL 0xfd
12083 +} __attribute__ ((packed)) evt_stack_internal;
12084 +#define EVT_STACK_INTERNAL_SIZE 2
12086 +#define EVT_SI_DEVICE 0x01
12090 +} __attribute__ ((packed)) evt_si_device;
12091 +#define EVT_SI_DEVICE_SIZE 4
12093 +#define EVT_SI_SECURITY 0x02
12097 -} __attribute__ ((packed)) evt_hci_dev_event;
12098 -#define EVT_HCI_DEV_EVENT_SIZE 4
12102 +} __attribute__ ((packed)) evt_si_security;
12104 /* -------- HCI Packet structures -------- */
12105 #define HCI_TYPE_LEN 1
12106 @@ -369,14 +670,14 @@
12107 #define acl_handle(h) (h & 0x0fff)
12108 #define acl_flags(h) (h >> 12)
12110 -#endif /* _NO_HCI_DEFS */
12112 /* HCI Socket options */
12113 -#define HCI_DATA_DIR 0x0001
12114 -#define HCI_FILTER 0x0002
12115 +#define HCI_DATA_DIR 1
12116 +#define HCI_FILTER 2
12117 +#define HCI_TIME_STAMP 3
12119 /* HCI CMSG flags */
12120 #define HCI_CMSG_DIR 0x0001
12121 +#define HCI_CMSG_TSTAMP 0x0002
12123 struct sockaddr_hci {
12124 sa_family_t hci_family;
12125 @@ -387,27 +688,29 @@
12126 struct hci_filter {
12128 __u32 event_mask[2];
12132 -struct hci_dev_req {
12137 -struct hci_dev_list_req {
12139 - struct hci_dev_req dev_req[0]; /* hci_dev_req structures */
12142 -struct hci_inquiry_req {
12149 -#define IREQ_CACHE_FLUSH 0x0001
12150 +#define HCI_FLT_TYPE_BITS 31
12151 +#define HCI_FLT_EVENT_BITS 63
12152 +#define HCI_FLT_OGF_BITS 63
12153 +#define HCI_FLT_OCF_BITS 127
12155 +#if BITS_PER_LONG == 64
12156 +static inline void hci_set_bit(int nr, void *addr)
12158 + *((__u32 *) addr + (nr >> 5)) |= ((__u32) 1 << (nr & 31));
12160 +static inline int hci_test_bit(int nr, void *addr)
12162 + return *((__u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
12165 +#define hci_set_bit set_bit
12166 +#define hci_test_bit test_bit
12169 +/* Ioctl requests structures */
12170 struct hci_dev_stats {
12173 @@ -433,11 +736,13 @@
12177 + __u32 link_policy;
12187 struct hci_dev_stats stat;
12189 @@ -445,6 +750,20 @@
12190 struct hci_conn_info {
12199 +struct hci_dev_req {
12204 +struct hci_dev_list_req {
12206 + struct hci_dev_req dev_req[0]; /* hci_dev_req structures */
12209 struct hci_conn_list_req {
12210 @@ -453,4 +772,26 @@
12211 struct hci_conn_info conn_info[0];
12214 +struct hci_conn_info_req {
12217 + struct hci_conn_info conn_info[0];
12220 +struct hci_inquiry_req {
12227 +#define IREQ_CACHE_FLUSH 0x0001
12229 +struct hci_remotename_req {
12236 #endif /* __HCI_H */
12237 diff -urN linux-2.4.18/include/net/bluetooth/hci_uart.h linux-2.4.18-mh15/include/net/bluetooth/hci_uart.h
12238 --- linux-2.4.18/include/net/bluetooth/hci_uart.h 2001-09-07 18:28:38.000000000 +0200
12239 +++ linux-2.4.18-mh15/include/net/bluetooth/hci_uart.h 1970-01-01 01:00:00.000000000 +0100
12242 - BlueZ - Bluetooth protocol stack for Linux
12243 - Copyright (C) 2000-2001 Qualcomm Incorporated
12245 - Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
12247 - This program is free software; you can redistribute it and/or modify
12248 - it under the terms of the GNU General Public License version 2 as
12249 - published by the Free Software Foundation;
12251 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12252 - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12253 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12254 - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
12255 - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
12256 - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12257 - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
12258 - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
12260 - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
12261 - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
12262 - SOFTWARE IS DISCLAIMED.
12266 - * $Id: hci_uart.h,v 1.2 2001/06/02 01:40:08 maxk Exp $
12275 -#define tty2n_hci(tty) ((struct n_hci *)((tty)->disc_data))
12276 -#define n_hci2tty(n_hci) ((n_hci)->tty)
12279 - struct tty_struct *tty;
12280 - struct hci_dev hdev;
12282 - struct sk_buff_head txq;
12283 - unsigned long tx_state;
12285 - spinlock_t rx_lock;
12286 - unsigned long rx_state;
12287 - unsigned long rx_count;
12288 - struct sk_buff *rx_skb;
12291 -/* Transmit states */
12292 -#define TRANS_SENDING 1
12293 -#define TRANS_WAKEUP 2
12295 -/* Receiver States */
12296 -#define WAIT_PACKET_TYPE 0
12297 -#define WAIT_EVENT_HDR 1
12298 -#define WAIT_ACL_HDR 2
12299 -#define WAIT_SCO_HDR 3
12300 -#define WAIT_DATA 4
12302 -#endif /* __KERNEL__ */
12303 diff -urN linux-2.4.18/include/net/bluetooth/hci_usb.h linux-2.4.18-mh15/include/net/bluetooth/hci_usb.h
12304 --- linux-2.4.18/include/net/bluetooth/hci_usb.h 2001-09-07 18:28:38.000000000 +0200
12305 +++ linux-2.4.18-mh15/include/net/bluetooth/hci_usb.h 1970-01-01 01:00:00.000000000 +0100
12308 - BlueZ - Bluetooth protocol stack for Linux
12309 - Copyright (C) 2000-2001 Qualcomm Incorporated
12311 - Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
12313 - This program is free software; you can redistribute it and/or modify
12314 - it under the terms of the GNU General Public License version 2 as
12315 - published by the Free Software Foundation;
12317 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12318 - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12319 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12320 - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
12321 - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
12322 - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12323 - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
12324 - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
12326 - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
12327 - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
12328 - SOFTWARE IS DISCLAIMED.
12332 - * $Id: hci_usb.h,v 1.3 2001/06/02 01:40:08 maxk Exp $
12337 -/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
12338 -#define HCI_DEV_CLASS 0xe0 /* Wireless class */
12339 -#define HCI_DEV_SUBCLASS 0x01 /* RF subclass */
12340 -#define HCI_DEV_PROTOCOL 0x01 /* Bluetooth programming protocol */
12342 -#define HCI_CTRL_REQ 0x20
12345 - struct usb_device *udev;
12347 - devrequest dev_req;
12348 - struct urb *ctrl_urb;
12349 - struct urb *intr_urb;
12350 - struct urb *read_urb;
12351 - struct urb *write_urb;
12355 - struct sk_buff *intr_skb;
12358 - __u8 bulk_out_ep_addr;
12359 - __u8 bulk_in_ep_addr;
12360 - __u8 intr_in_ep_addr;
12361 - __u8 intr_in_interval;
12363 - struct hci_dev hdev;
12365 - unsigned long tx_state;
12366 - struct sk_buff_head tx_ctrl_q;
12367 - struct sk_buff_head tx_write_q;
12370 -/* Transmit states */
12371 -#define HCI_TX_CTRL 1
12372 -#define HCI_TX_WRITE 2
12374 -#endif /* __KERNEL__ */
12375 diff -urN linux-2.4.18/include/net/bluetooth/hci_vhci.h linux-2.4.18-mh15/include/net/bluetooth/hci_vhci.h
12376 --- linux-2.4.18/include/net/bluetooth/hci_vhci.h 2001-09-07 18:28:38.000000000 +0200
12377 +++ linux-2.4.18-mh15/include/net/bluetooth/hci_vhci.h 1970-01-01 01:00:00.000000000 +0100
12380 - BlueZ - Bluetooth protocol stack for Linux
12381 - Copyright (C) 2000-2001 Qualcomm Incorporated
12383 - Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
12385 - This program is free software; you can redistribute it and/or modify
12386 - it under the terms of the GNU General Public License version 2 as
12387 - published by the Free Software Foundation;
12389 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12390 - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12391 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12392 - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
12393 - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
12394 - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12395 - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
12396 - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
12398 - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
12399 - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
12400 - SOFTWARE IS DISCLAIMED.
12404 - * $Id: hci_vhci.h,v 1.2 2001/08/01 01:02:20 maxk Exp $
12407 -#ifndef __HCI_VHCI_H
12408 -#define __HCI_VHCI_H
12412 -struct hci_vhci_struct {
12413 - struct hci_dev hdev;
12415 - wait_queue_head_t read_wait;
12416 - struct sk_buff_head readq;
12417 - struct fasync_struct *fasync;
12420 -/* VHCI device flags */
12421 -#define VHCI_FASYNC 0x0010
12423 -#endif /* __KERNEL__ */
12425 -#define VHCI_DEV "/dev/vhci"
12426 -#define VHCI_MINOR 250
12428 -#endif /* __HCI_VHCI_H */
12429 diff -urN linux-2.4.18/include/net/bluetooth/l2cap_core.h linux-2.4.18-mh15/include/net/bluetooth/l2cap_core.h
12430 --- linux-2.4.18/include/net/bluetooth/l2cap_core.h 2001-09-07 18:28:38.000000000 +0200
12431 +++ linux-2.4.18-mh15/include/net/bluetooth/l2cap_core.h 1970-01-01 01:00:00.000000000 +0100
12434 - BlueZ - Bluetooth protocol stack for Linux
12435 - Copyright (C) 2000-2001 Qualcomm Incorporated
12437 - Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
12439 - This program is free software; you can redistribute it and/or modify
12440 - it under the terms of the GNU General Public License version 2 as
12441 - published by the Free Software Foundation;
12443 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12444 - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12445 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12446 - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
12447 - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
12448 - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12449 - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
12450 - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
12452 - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
12453 - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
12454 - SOFTWARE IS DISCLAIMED.
12458 - * $Id: l2cap_core.h,v 1.6 2001/08/03 04:19:49 maxk Exp $
12461 -#ifndef __L2CAP_CORE_H
12462 -#define __L2CAP_CORE_H
12466 -/* ----- L2CAP interface ----- */
12467 -struct l2cap_iff {
12468 - struct list_head list;
12469 - struct hci_dev *hdev;
12470 - bdaddr_t *bdaddr;
12473 - struct list_head conn_list;
12476 -static inline void l2cap_iff_lock(struct l2cap_iff *iff)
12478 - spin_lock(&iff->lock);
12481 -static inline void l2cap_iff_unlock(struct l2cap_iff *iff)
12483 - spin_unlock(&iff->lock);
12486 -/* ----- L2CAP connections ----- */
12487 -struct l2cap_chan_list {
12488 - struct sock *head;
12493 -struct l2cap_conn {
12494 - struct l2cap_iff *iff;
12495 - struct list_head list;
12497 - struct hci_conn *hconn;
12507 - struct sk_buff *rx_skb;
12512 - struct l2cap_chan_list chan_list;
12514 - struct timer_list timer;
12517 -static inline void __l2cap_conn_link(struct l2cap_iff *iff, struct l2cap_conn *c)
12519 - list_add(&c->list, &iff->conn_list);
12522 -static inline void __l2cap_conn_unlink(struct l2cap_iff *iff, struct l2cap_conn *c)
12524 - list_del(&c->list);
12527 -/* ----- L2CAP channel and socket info ----- */
12528 -#define l2cap_pi(sk) ((struct l2cap_pinfo *) &sk->protinfo)
12530 -struct l2cap_accept_q {
12531 - struct sock *head;
12532 - struct sock *tail;
12535 -struct l2cap_pinfo {
12552 - struct l2cap_conn *conn;
12553 - struct sock *next_c;
12554 - struct sock *prev_c;
12556 - struct sock *parent;
12557 - struct sock *next_q;
12558 - struct sock *prev_q;
12560 - struct l2cap_accept_q accept_q;
12563 -#define CONF_REQ_SENT 0x01
12564 -#define CONF_INPUT_DONE 0x02
12565 -#define CONF_OUTPUT_DONE 0x04
12567 -extern struct bluez_sock_list l2cap_sk_list;
12568 -extern struct list_head l2cap_iff_list;
12569 -extern rwlock_t l2cap_rt_lock;
12571 -extern void l2cap_register_proc(void);
12572 -extern void l2cap_unregister_proc(void);
12574 -#endif /* __KERNEL__ */
12576 -#endif /* __L2CAP_CORE_H */
12577 diff -urN linux-2.4.18/include/net/bluetooth/l2cap.h linux-2.4.18-mh15/include/net/bluetooth/l2cap.h
12578 --- linux-2.4.18/include/net/bluetooth/l2cap.h 2001-09-07 18:28:38.000000000 +0200
12579 +++ linux-2.4.18-mh15/include/net/bluetooth/l2cap.h 2004-08-01 16:26:23.000000000 +0200
12580 @@ -23,22 +23,17 @@
12584 - * $Id: l2cap.h,v 1.5 2001/06/14 21:28:26 maxk Exp $
12585 + * $Id: l2cap.h,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $
12591 -#include <asm/types.h>
12592 -#include <asm/byteorder.h>
12594 /* L2CAP defaults */
12595 #define L2CAP_DEFAULT_MTU 672
12596 #define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
12598 #define L2CAP_CONN_TIMEOUT (HZ * 40)
12599 -#define L2CAP_DISCONN_TIMEOUT (HZ * 2)
12600 -#define L2CAP_CONN_IDLE_TIMEOUT (HZ * 60)
12602 /* L2CAP socket address */
12603 struct sockaddr_l2 {
12604 @@ -47,17 +42,12 @@
12605 bdaddr_t l2_bdaddr;
12608 -/* set/get sockopt defines */
12609 -#define L2CAP_OPTIONS 0x01
12610 +/* Socket options */
12611 +#define L2CAP_OPTIONS 0x01
12612 struct l2cap_options {
12616 - __u32 token_rate;
12617 - __u32 bucket_size;
12623 #define L2CAP_CONNINFO 0x02
12628 +#define L2CAP_LM 0x03
12629 +#define L2CAP_LM_MASTER 0x0001
12630 +#define L2CAP_LM_AUTH 0x0002
12631 +#define L2CAP_LM_ENCRYPT 0x0004
12632 +#define L2CAP_LM_TRUSTED 0x0008
12633 +#define L2CAP_LM_RELIABLE 0x0010
12635 +#define L2CAP_QOS 0x04
12636 +struct l2cap_qos {
12637 + __u16 service_type;
12638 + __u32 token_rate;
12639 + __u32 token_bucket_size;
12640 + __u32 peak_bandwidth;
12642 + __u32 delay_variation;
12645 +#define L2CAP_SERV_NO_TRAFFIC 0x00
12646 +#define L2CAP_SERV_BEST_EFFORT 0x01
12647 +#define L2CAP_SERV_GUARANTEED 0x02
12649 /* L2CAP command codes */
12650 #define L2CAP_COMMAND_REJ 0x01
12651 #define L2CAP_CONN_REQ 0x02
12653 #define L2CAP_INFO_RSP 0x0b
12655 /* L2CAP structures */
12660 @@ -112,11 +122,17 @@
12661 } __attribute__ ((packed)) l2cap_conn_rsp;
12662 #define L2CAP_CONN_RSP_SIZE 8
12664 -#define L2CAP_CONN_SUCCESS 0x0000
12665 -#define L2CAP_CONN_PEND 0x0001
12666 -#define L2CAP_CONN_BAD_PSM 0x0002
12667 -#define L2CAP_CONN_SEC_BLOCK 0x0003
12668 -#define L2CAP_CONN_NO_MEM 0x0004
12669 +/* connect result */
12670 +#define L2CAP_CR_SUCCESS 0x0000
12671 +#define L2CAP_CR_PEND 0x0001
12672 +#define L2CAP_CR_BAD_PSM 0x0002
12673 +#define L2CAP_CR_SEC_BLOCK 0x0003
12674 +#define L2CAP_CR_NO_MEM 0x0004
12676 +/* connect status */
12677 +#define L2CAP_CS_NO_INFO 0x0000
12678 +#define L2CAP_CS_AUTHEN_PEND 0x0001
12679 +#define L2CAP_CS_AUTHOR_PEND 0x0002
12683 @@ -147,6 +163,8 @@
12684 #define L2CAP_CONF_FLUSH_TO 0x02
12685 #define L2CAP_CONF_QOS 0x03
12687 +#define L2CAP_CONF_MAX_SIZE 22
12692 @@ -159,4 +177,82 @@
12693 } __attribute__ ((packed)) l2cap_disconn_rsp;
12694 #define L2CAP_DISCONN_RSP_SIZE 4
12699 +} __attribute__ ((packed)) l2cap_info_req;
12700 +#define L2CAP_INFO_REQ_SIZE 2
12706 +} __attribute__ ((packed)) l2cap_info_rsp;
12707 +#define L2CAP_INFO_RSP_SIZE 4
12710 +#define L2CAP_IT_CL_MTU 0x0001
12711 +#define L2CAP_IT_FEAT_MASK 0x0002
12714 +#define L2CAP_IR_SUCCESS 0x0000
12715 +#define L2CAP_IR_NOTSUPP 0x0001
12717 +/* ----- L2CAP connections ----- */
12718 +struct l2cap_chan_list {
12719 + struct sock *head;
12724 +struct l2cap_conn {
12725 + struct hci_conn *hcon;
12730 + unsigned int mtu;
12734 + struct sk_buff *rx_skb;
12739 + struct l2cap_chan_list chan_list;
12742 +/* ----- L2CAP channel and socket info ----- */
12743 +#define l2cap_pi(sk) ((struct l2cap_pinfo *) &sk->tp_pinfo)
12745 +struct l2cap_pinfo {
12762 + struct l2cap_conn *conn;
12763 + struct sock *next_c;
12764 + struct sock *prev_c;
12767 +#define L2CAP_CONF_REQ_SENT 0x01
12768 +#define L2CAP_CONF_INPUT_DONE 0x02
12769 +#define L2CAP_CONF_OUTPUT_DONE 0x04
12770 +#define L2CAP_CONF_MAX_RETRIES 2
12772 +void l2cap_load(void);
12774 #endif /* __L2CAP_H */
12775 diff -urN linux-2.4.18/include/net/bluetooth/rfcomm.h linux-2.4.18-mh15/include/net/bluetooth/rfcomm.h
12776 --- linux-2.4.18/include/net/bluetooth/rfcomm.h 1970-01-01 01:00:00.000000000 +0100
12777 +++ linux-2.4.18-mh15/include/net/bluetooth/rfcomm.h 2004-08-01 16:26:23.000000000 +0200
12780 + RFCOMM implementation for Linux Bluetooth stack (BlueZ).
12781 + Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
12782 + Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
12784 + This program is free software; you can redistribute it and/or modify
12785 + it under the terms of the GNU General Public License version 2 as
12786 + published by the Free Software Foundation;
12788 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12789 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12790 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12791 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
12792 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
12793 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12794 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
12795 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
12797 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
12798 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
12799 + SOFTWARE IS DISCLAIMED.
12803 + RPN support - Dirk Husemann <hud@zurich.ibm.com>
12807 + * $Id: rfcomm.h,v 1.31 2002/10/18 20:12:11 maxk Exp $
12810 +#ifndef __RFCOMM_H
12811 +#define __RFCOMM_H
12813 +#define RFCOMM_PSM 3
12815 +#define RFCOMM_CONN_TIMEOUT (HZ * 30)
12816 +#define RFCOMM_DISC_TIMEOUT (HZ * 20)
12818 +#define RFCOMM_DEFAULT_MTU 127
12819 +#define RFCOMM_DEFAULT_CREDITS 7
12821 +#define RFCOMM_MAX_L2CAP_MTU 1024
12822 +#define RFCOMM_MAX_CREDITS 40
12824 +#define RFCOMM_SKB_HEAD_RESERVE 8
12825 +#define RFCOMM_SKB_TAIL_RESERVE 2
12826 +#define RFCOMM_SKB_RESERVE (RFCOMM_SKB_HEAD_RESERVE + RFCOMM_SKB_TAIL_RESERVE)
12828 +#define RFCOMM_SABM 0x2f
12829 +#define RFCOMM_DISC 0x43
12830 +#define RFCOMM_UA 0x63
12831 +#define RFCOMM_DM 0x0f
12832 +#define RFCOMM_UIH 0xef
12834 +#define RFCOMM_TEST 0x08
12835 +#define RFCOMM_FCON 0x28
12836 +#define RFCOMM_FCOFF 0x18
12837 +#define RFCOMM_MSC 0x38
12838 +#define RFCOMM_RPN 0x24
12839 +#define RFCOMM_RLS 0x14
12840 +#define RFCOMM_PN 0x20
12841 +#define RFCOMM_NSC 0x04
12843 +#define RFCOMM_V24_FC 0x02
12844 +#define RFCOMM_V24_RTC 0x04
12845 +#define RFCOMM_V24_RTR 0x08
12846 +#define RFCOMM_V24_IC 0x40
12847 +#define RFCOMM_V24_DV 0x80
12849 +#define RFCOMM_RPN_BR_2400 0x0
12850 +#define RFCOMM_RPN_BR_4800 0x1
12851 +#define RFCOMM_RPN_BR_7200 0x2
12852 +#define RFCOMM_RPN_BR_9600 0x3
12853 +#define RFCOMM_RPN_BR_19200 0x4
12854 +#define RFCOMM_RPN_BR_38400 0x5
12855 +#define RFCOMM_RPN_BR_57600 0x6
12856 +#define RFCOMM_RPN_BR_115200 0x7
12857 +#define RFCOMM_RPN_BR_230400 0x8
12859 +#define RFCOMM_RPN_DATA_5 0x0
12860 +#define RFCOMM_RPN_DATA_6 0x1
12861 +#define RFCOMM_RPN_DATA_7 0x2
12862 +#define RFCOMM_RPN_DATA_8 0x3
12864 +#define RFCOMM_RPN_STOP_1 0
12865 +#define RFCOMM_RPN_STOP_15 1
12867 +#define RFCOMM_RPN_PARITY_NONE 0x0
12868 +#define RFCOMM_RPN_PARITY_ODD 0x4
12869 +#define RFCOMM_RPN_PARITY_EVEN 0x5
12870 +#define RFCOMM_RPN_PARITY_MARK 0x6
12871 +#define RFCOMM_RPN_PARITY_SPACE 0x7
12873 +#define RFCOMM_RPN_FLOW_NONE 0x00
12875 +#define RFCOMM_RPN_XON_CHAR 0x11
12876 +#define RFCOMM_RPN_XOFF_CHAR 0x13
12878 +#define RFCOMM_RPN_PM_BITRATE 0x0001
12879 +#define RFCOMM_RPN_PM_DATA 0x0002
12880 +#define RFCOMM_RPN_PM_STOP 0x0004
12881 +#define RFCOMM_RPN_PM_PARITY 0x0008
12882 +#define RFCOMM_RPN_PM_PARITY_TYPE 0x0010
12883 +#define RFCOMM_RPN_PM_XON 0x0020
12884 +#define RFCOMM_RPN_PM_XOFF 0x0040
12885 +#define RFCOMM_RPN_PM_FLOW 0x3F00
12887 +#define RFCOMM_RPN_PM_ALL 0x3F7F
12889 +struct rfcomm_hdr {
12892 + u8 len; // Actual size can be 2 bytes
12893 +} __attribute__ ((packed));
12895 +struct rfcomm_cmd {
12900 +} __attribute__ ((packed));
12902 +struct rfcomm_mcc {
12905 +} __attribute__ ((packed));
12907 +struct rfcomm_pn {
12915 +} __attribute__ ((packed));
12917 +struct rfcomm_rpn {
12920 + u8 line_settings;
12925 +} __attribute__ ((packed));
12927 +struct rfcomm_rls {
12930 +} __attribute__ ((packed));
12932 +struct rfcomm_msc {
12935 +} __attribute__ ((packed));
12937 +/* ---- Core structures, flags etc ---- */
12939 +struct rfcomm_session {
12940 + struct list_head list;
12941 + struct socket *sock;
12942 + unsigned long state;
12943 + unsigned long flags;
12947 + /* Default DLC parameters */
12951 + struct list_head dlcs;
12954 +struct rfcomm_dlc {
12955 + struct list_head list;
12956 + struct rfcomm_session *session;
12957 + struct sk_buff_head tx_queue;
12958 + struct timer_list timer;
12961 + unsigned long state;
12962 + unsigned long flags;
12977 + void (*data_ready)(struct rfcomm_dlc *d, struct sk_buff *skb);
12978 + void (*state_change)(struct rfcomm_dlc *d, int err);
12979 + void (*modem_status)(struct rfcomm_dlc *d, u8 v24_sig);
12982 +/* DLC and session flags */
12983 +#define RFCOMM_RX_THROTTLED 0
12984 +#define RFCOMM_TX_THROTTLED 1
12985 +#define RFCOMM_MSC_PENDING 2
12986 +#define RFCOMM_TIMED_OUT 3
12988 +/* Scheduling flags and events */
12989 +#define RFCOMM_SCHED_STATE 0
12990 +#define RFCOMM_SCHED_RX 1
12991 +#define RFCOMM_SCHED_TX 2
12992 +#define RFCOMM_SCHED_TIMEO 3
12993 +#define RFCOMM_SCHED_WAKEUP 31
12995 +/* MSC exchange flags */
12996 +#define RFCOMM_MSCEX_TX 1
12997 +#define RFCOMM_MSCEX_RX 2
12998 +#define RFCOMM_MSCEX_OK (RFCOMM_MSCEX_TX + RFCOMM_MSCEX_RX)
13001 +#define RFCOMM_CFC_UNKNOWN -1
13002 +#define RFCOMM_CFC_DISABLED 0
13003 +#define RFCOMM_CFC_ENABLED RFCOMM_MAX_CREDITS
13005 +extern struct task_struct *rfcomm_thread;
13006 +extern unsigned long rfcomm_event;
13008 +static inline void rfcomm_schedule(uint event)
13010 + if (!rfcomm_thread)
13012 + set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
13013 + wake_up_process(rfcomm_thread);
13016 +extern struct semaphore rfcomm_sem;
13017 +#define rfcomm_lock() down(&rfcomm_sem);
13018 +#define rfcomm_unlock() up(&rfcomm_sem);
13020 +/* ---- RFCOMM DLCs (channels) ---- */
13021 +struct rfcomm_dlc *rfcomm_dlc_alloc(int prio);
13022 +void rfcomm_dlc_free(struct rfcomm_dlc *d);
13023 +int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel);
13024 +int rfcomm_dlc_close(struct rfcomm_dlc *d, int reason);
13025 +int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb);
13026 +int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig);
13027 +int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig);
13029 +#define rfcomm_dlc_lock(d) spin_lock(&d->lock)
13030 +#define rfcomm_dlc_unlock(d) spin_unlock(&d->lock)
13032 +static inline void rfcomm_dlc_hold(struct rfcomm_dlc *d)
13034 + atomic_inc(&d->refcnt);
13037 +static inline void rfcomm_dlc_put(struct rfcomm_dlc *d)
13039 + if (atomic_dec_and_test(&d->refcnt))
13040 + rfcomm_dlc_free(d);
13043 +extern void FASTCALL(__rfcomm_dlc_throttle(struct rfcomm_dlc *d));
13044 +extern void FASTCALL(__rfcomm_dlc_unthrottle(struct rfcomm_dlc *d));
13046 +static inline void rfcomm_dlc_throttle(struct rfcomm_dlc *d)
13048 + if (!test_and_set_bit(RFCOMM_RX_THROTTLED, &d->flags))
13049 + __rfcomm_dlc_throttle(d);
13052 +static inline void rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
13054 + if (test_and_clear_bit(RFCOMM_RX_THROTTLED, &d->flags))
13055 + __rfcomm_dlc_unthrottle(d);
13058 +/* ---- RFCOMM sessions ---- */
13059 +struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state);
13060 +struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
13061 +struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err);
13062 +void rfcomm_session_del(struct rfcomm_session *s);
13063 +void rfcomm_session_close(struct rfcomm_session *s, int err);
13064 +void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst);
13066 +static inline void rfcomm_session_hold(struct rfcomm_session *s)
13068 + atomic_inc(&s->refcnt);
13071 +static inline void rfcomm_session_put(struct rfcomm_session *s)
13073 + if (atomic_dec_and_test(&s->refcnt))
13074 + rfcomm_session_del(s);
13077 +/* ---- RFCOMM chechsum ---- */
13078 +extern u8 rfcomm_crc_table[];
13080 +/* ---- RFCOMM sockets ---- */
13081 +struct sockaddr_rc {
13082 + sa_family_t rc_family;
13083 + bdaddr_t rc_bdaddr;
13087 +#define rfcomm_pi(sk) ((struct rfcomm_pinfo *) &sk->tp_pinfo)
13089 +struct rfcomm_pinfo {
13090 + struct rfcomm_dlc *dlc;
13094 +int rfcomm_init_sockets(void);
13095 +void rfcomm_cleanup_sockets(void);
13097 +int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d);
13099 +/* ---- RFCOMM TTY ---- */
13100 +#define RFCOMM_MAX_DEV 256
13102 +#define RFCOMMCREATEDEV _IOW('R', 200, int)
13103 +#define RFCOMMRELEASEDEV _IOW('R', 201, int)
13104 +#define RFCOMMGETDEVLIST _IOR('R', 210, int)
13105 +#define RFCOMMGETDEVINFO _IOR('R', 211, int)
13106 +#define RFCOMMSTEALDLC _IOW('R', 220, int)
13108 +#define RFCOMM_REUSE_DLC 0
13109 +#define RFCOMM_RELEASE_ONHUP 1
13110 +#define RFCOMM_HANGUP_NOW 2
13111 +#define RFCOMM_TTY_ATTACHED 3
13113 +struct rfcomm_dev_req {
13121 +struct rfcomm_dev_info {
13130 +struct rfcomm_dev_list_req {
13132 + struct rfcomm_dev_info dev_info[0];
13135 +int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg);
13136 +int rfcomm_init_ttys(void);
13137 +void rfcomm_cleanup_ttys(void);
13139 +#endif /* __RFCOMM_H */
13140 diff -urN linux-2.4.18/include/net/bluetooth/sco.h linux-2.4.18-mh15/include/net/bluetooth/sco.h
13141 --- linux-2.4.18/include/net/bluetooth/sco.h 1970-01-01 01:00:00.000000000 +0100
13142 +++ linux-2.4.18-mh15/include/net/bluetooth/sco.h 2004-08-01 16:26:23.000000000 +0200
13145 + BlueZ - Bluetooth protocol stack for Linux
13146 + Copyright (C) 2000-2001 Qualcomm Incorporated
13148 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
13150 + This program is free software; you can redistribute it and/or modify
13151 + it under the terms of the GNU General Public License version 2 as
13152 + published by the Free Software Foundation;
13154 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
13155 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13156 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
13157 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13158 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
13159 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13160 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13161 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
13163 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
13164 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
13165 + SOFTWARE IS DISCLAIMED.
13169 + * $Id: sco.h,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $
13175 +/* SCO defaults */
13176 +#define SCO_DEFAULT_MTU 500
13177 +#define SCO_DEFAULT_FLUSH_TO 0xFFFF
13179 +#define SCO_CONN_TIMEOUT (HZ * 40)
13180 +#define SCO_DISCONN_TIMEOUT (HZ * 2)
13181 +#define SCO_CONN_IDLE_TIMEOUT (HZ * 60)
13183 +/* SCO socket address */
13184 +struct sockaddr_sco {
13185 + sa_family_t sco_family;
13186 + bdaddr_t sco_bdaddr;
13189 +/* set/get sockopt defines */
13190 +#define SCO_OPTIONS 0x01
13191 +struct sco_options {
13195 +#define SCO_CONNINFO 0x02
13196 +struct sco_conninfo {
13197 + __u16 hci_handle;
13200 +/* ---- SCO connections ---- */
13202 + struct hci_conn *hcon;
13210 + unsigned int mtu;
13213 +#define sco_conn_lock(c) spin_lock(&c->lock);
13214 +#define sco_conn_unlock(c) spin_unlock(&c->lock);
13216 +/* ----- SCO socket info ----- */
13217 +#define sco_pi(sk) ((struct sco_pinfo *) &sk->tp_pinfo)
13219 +struct sco_pinfo {
13221 + struct sco_conn *conn;
13224 +#endif /* __SCO_H */
13225 diff -urN linux-2.4.18/include/pcmcia/ciscode.h linux-2.4.18-mh15/include/pcmcia/ciscode.h
13226 --- linux-2.4.18/include/pcmcia/ciscode.h 2001-12-21 18:42:04.000000000 +0100
13227 +++ linux-2.4.18-mh15/include/pcmcia/ciscode.h 2004-08-01 16:26:23.000000000 +0200
13230 - * ciscode.h 1.48 2001/08/24 12:16:12
13231 + * ciscode.h 1.57 2002/11/03 20:38:14
13233 * The contents of this file are subject to the Mozilla Public License
13234 * Version 1.1 (the "License"); you may not use this file except in
13236 #define PRODID_INTEL_DUAL_RS232 0x0301
13237 #define PRODID_INTEL_2PLUS 0x8422
13239 +#define MANFID_KME 0x0032
13240 +#define PRODID_KME_KXLC005_A 0x0704
13241 +#define PRODID_KME_KXLC005_B 0x2904
13243 #define MANFID_LINKSYS 0x0143
13244 #define PRODID_LINKSYS_PCMLM28 0xc0ab
13245 #define PRODID_LINKSYS_3400 0x3341
13247 #define PRODID_OSITECH_JACK_336 0x0007
13248 #define PRODID_OSITECH_SEVEN 0x0008
13250 +#define MANFID_OXSEMI 0x0279
13252 #define MANFID_PIONEER 0x000b
13254 #define MANFID_PSION 0x016c
13255 @@ -103,6 +109,7 @@
13256 #define PRODID_QUATECH_SPP100 0x0003
13257 #define PRODID_QUATECH_DUAL_RS232 0x0012
13258 #define PRODID_QUATECH_DUAL_RS232_D1 0x0007
13259 +#define PRODID_QUATECH_DUAL_RS232_D2 0x0052
13260 #define PRODID_QUATECH_QUAD_RS232 0x001b
13261 #define PRODID_QUATECH_DUAL_RS422 0x000e
13262 #define PRODID_QUATECH_QUAD_RS422 0x0045
13263 @@ -120,9 +127,12 @@
13265 #define MANFID_TDK 0x0105
13266 #define PRODID_TDK_CF010 0x0900
13267 +#define PRODID_TDK_GN3410 0x4815
13269 #define MANFID_TOSHIBA 0x0098
13271 +#define MANFID_UNGERMANN 0x02c0
13273 #define MANFID_XIRCOM 0x0105
13275 #endif /* _LINUX_CISCODE_H */
13276 diff -urN linux-2.4.18/kernel/ksyms.c linux-2.4.18-mh15/kernel/ksyms.c
13277 --- linux-2.4.18/kernel/ksyms.c 2002-02-25 20:38:13.000000000 +0100
13278 +++ linux-2.4.18-mh15/kernel/ksyms.c 2004-08-01 16:26:23.000000000 +0200
13280 #include <linux/in6.h>
13281 #include <linux/completion.h>
13282 #include <linux/seq_file.h>
13283 +#include <linux/firmware.h>
13284 #include <asm/checksum.h>
13286 #if defined(CONFIG_PROC_FS)
13287 @@ -538,6 +539,13 @@
13288 EXPORT_SYMBOL(strspn);
13289 EXPORT_SYMBOL(strsep);
13291 +#ifdef CONFIG_FW_LOADER
13292 +EXPORT_SYMBOL(release_firmware);
13293 +EXPORT_SYMBOL(request_firmware);
13294 +EXPORT_SYMBOL(request_firmware_nowait);
13295 +EXPORT_SYMBOL(register_firmware);
13298 /* software interrupts */
13299 EXPORT_SYMBOL(tasklet_hi_vec);
13300 EXPORT_SYMBOL(tasklet_vec);
13301 diff -urN linux-2.4.18/lib/Config.in linux-2.4.18-mh15/lib/Config.in
13302 --- linux-2.4.18/lib/Config.in 1970-01-01 01:00:00.000000000 +0100
13303 +++ linux-2.4.18-mh15/lib/Config.in 2004-08-01 16:26:23.000000000 +0200
13306 +# Library configuration
13308 +mainmenu_option next_comment
13309 +comment 'Library routines'
13311 +if [ "$CONFIG_EXPERIMENTAL" = "y" -a \
13312 + "$CONFIG_HOTPLUG" = "y" ]; then
13313 + tristate 'Hotplug firmware loading support (EXPERIMENTAL)' CONFIG_FW_LOADER
13317 diff -urN linux-2.4.18/lib/firmware_class.c linux-2.4.18-mh15/lib/firmware_class.c
13318 --- linux-2.4.18/lib/firmware_class.c 1970-01-01 01:00:00.000000000 +0100
13319 +++ linux-2.4.18-mh15/lib/firmware_class.c 2004-08-01 16:26:23.000000000 +0200
13322 + * firmware_class.c - Multi purpose firmware loading support
13324 + * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
13326 + * Please see Documentation/firmware_class/ for more information.
13330 + * Based on kernel/kmod.c and drivers/usb/usb.c
13336 + Reorganized not to be a daemon by Adam Richter, with guidance
13337 + from Greg Zornetzer.
13339 + Modified to avoid chroot and file sharing problems.
13340 + Mikael Pettersson
13342 + Limit the concurrent number of kmod modprobes to catch loops from
13343 + "modprobe needs a service that is in a module".
13344 + Keith Owens <kaos@ocs.com.au> December 1999
13346 + Unblock all signals when we exec a usermode process.
13347 + Shuu Yamaguchi <shuu@wondernetworkresources.com> December 2000
13350 + * drivers/usb/usb.c
13352 + * (C) Copyright Linus Torvalds 1999
13353 + * (C) Copyright Johannes Erdfelt 1999-2001
13354 + * (C) Copyright Andreas Gal 1999
13355 + * (C) Copyright Gregory P. Smith 1999
13356 + * (C) Copyright Deti Fliegl 1999 (new USB architecture)
13357 + * (C) Copyright Randy Dunlap 2000
13358 + * (C) Copyright David Brownell 2000 (kernel hotplug, usb_device_id)
13359 + * (C) Copyright Yggdrasil Computing, Inc. 2000
13360 + * (usb_device_id matching changes by Adam J. Richter)
13363 +#include <linux/config.h>
13364 +#include <linux/module.h>
13365 +#include <linux/string.h>
13366 +#include <linux/types.h>
13367 +#include <linux/init.h>
13368 +#include <linux/slab.h>
13369 +#include <linux/kmod.h>
13370 +#include <linux/proc_fs.h>
13371 +#include <linux/vmalloc.h>
13372 +#include <asm/hardirq.h>
13374 +#include "linux/firmware.h"
13376 +MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>");
13377 +MODULE_DESCRIPTION("Multi purpose firmware loading support");
13378 +MODULE_LICENSE("GPL");
13380 +#define err(format, arg...) \
13381 + printk(KERN_ERR "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
13382 +#define warn(format, arg...) \
13383 + printk(KERN_WARNING "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
13384 +#define dbg(format, arg...) \
13385 + printk(KERN_DEBUG "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
13387 +static int loading_timeout = 10; /* In seconds */
13388 +static struct proc_dir_entry *proc_dir_timeout;
13389 +static struct proc_dir_entry *proc_dir;
13391 +#ifdef CONFIG_HOTPLUG
13394 +call_helper(char *verb, const char *name, const char *device)
13396 + char *argv[3], **envp, *buf, *scratch;
13401 + if (!hotplug_path[0])
13403 + if (in_interrupt()) {
13404 + err("in_interrupt");
13407 + if (!current->fs->root) {
13408 + warn("call_policy %s -- no FS yet", verb);
13412 + if (!(envp = (char **) kmalloc(20 * sizeof (char *), GFP_KERNEL))) {
13413 + err("unable to allocate envp");
13416 + if (!(buf = kmalloc(256, GFP_KERNEL))) {
13418 + err("unable to allocate buf");
13422 + /* only one standardized param to hotplug command: type */
13423 + argv[0] = hotplug_path;
13424 + argv[1] = "firmware";
13427 + /* minimal command environment */
13428 + envp[i++] = "HOME=/";
13429 + envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
13432 + /* hint that policy agent should enter no-stdout debug mode */
13433 + envp[i++] = "DEBUG=kernel";
13438 + envp[i++] = scratch;
13439 + scratch += snprintf(scratch, FIRMWARE_NAME_MAX+25,
13440 + "DEVPATH=/driver/firmware/%s", device) + 1;
13443 + envp[i++] = scratch;
13444 + scratch += sprintf(scratch, "ACTION=%s", verb) + 1;
13446 + envp[i++] = scratch;
13447 + scratch += snprintf(scratch, FIRMWARE_NAME_MAX,
13448 + "FIRMWARE=%s", name) + 1;
13453 + dbg("firmware: %s %s %s", argv[0], argv[1], verb);
13456 + retval = call_usermodehelper(argv[0], argv, envp);
13458 + printk("call_usermodehelper return %d\n", retval);
13468 +call_helper(char *verb, const char *name, const char *device)
13473 +#endif /* CONFIG_HOTPLUG */
13475 +struct firmware_priv {
13476 + struct completion completion;
13477 + struct proc_dir_entry *proc_dir;
13478 + struct proc_dir_entry *attr_data;
13479 + struct proc_dir_entry *attr_loading;
13480 + struct firmware *fw;
13484 + struct timer_list timeout;
13488 +firmware_timeout_show(char *buf, char **start, off_t off,
13489 + int count, int *eof, void *data)
13491 + return sprintf(buf, "%d\n", loading_timeout);
13495 + * firmware_timeout_store:
13497 + * Sets the number of seconds to wait for the firmware. Once
13498 + * this expires an error will be return to the driver and no
13499 + * firmware will be provided.
13501 + * Note: zero means 'wait for ever'
13505 +firmware_timeout_store(struct file *file, const char *buf,
13506 + unsigned long count, void *data)
13508 + loading_timeout = simple_strtol(buf, NULL, 10);
13513 +firmware_loading_show(char *buf, char **start, off_t off,
13514 + int count, int *eof, void *data)
13516 + struct firmware_priv *fw_priv = data;
13517 + return sprintf(buf, "%d\n", fw_priv->loading);
13521 + * firmware_loading_store: - loading control file
13523 + * The relevant values are:
13525 + * 1: Start a load, discarding any previous partial load.
13526 + * 0: Conclude the load and handle the data to the driver code.
13527 + * -1: Conclude the load with an error and discard any written data.
13530 +firmware_loading_store(struct file *file, const char *buf,
13531 + unsigned long count, void *data)
13533 + struct firmware_priv *fw_priv = data;
13534 + int prev_loading = fw_priv->loading;
13536 + fw_priv->loading = simple_strtol(buf, NULL, 10);
13538 + switch (fw_priv->loading) {
13540 + fw_priv->abort = 1;
13542 + complete(&fw_priv->completion);
13545 + kfree(fw_priv->fw->data);
13546 + fw_priv->fw->data = NULL;
13547 + fw_priv->fw->size = 0;
13548 + fw_priv->alloc_size = 0;
13551 + if (prev_loading == 1)
13552 + complete(&fw_priv->completion);
13560 +firmware_data_read(char *buffer, char **start, off_t offset,
13561 + int count, int *eof, void *data)
13563 + struct firmware_priv *fw_priv = data;
13564 + struct firmware *fw = fw_priv->fw;
13566 + if (offset > fw->size)
13568 + if (offset + count > fw->size)
13569 + count = fw->size - offset;
13571 + memcpy(buffer, fw->data + offset, count);
13572 + *start = (void *) ((long) count);
13576 +fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
13581 + if (min_size <= fw_priv->alloc_size)
13583 + if((min_size % PAGE_SIZE) == 0)
13584 + new_size = min_size;
13586 + new_size = (min_size + PAGE_SIZE) & PAGE_MASK;
13587 + new_data = vmalloc(new_size);
13589 + printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__);
13590 + /* Make sure that we don't keep incomplete data */
13591 + fw_priv->abort = 1;
13594 + fw_priv->alloc_size = new_size;
13595 + if (fw_priv->fw->data) {
13596 + memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size);
13597 + vfree(fw_priv->fw->data);
13599 + fw_priv->fw->data = new_data;
13600 + BUG_ON(min_size > fw_priv->alloc_size);
13605 + * firmware_data_write:
13609 + * Data written to the 'data' attribute will be later handled to
13610 + * the driver as a firmware image.
13613 +firmware_data_write(struct file *file, const char *buffer,
13614 + unsigned long count, void *data)
13616 + struct firmware_priv *fw_priv = data;
13617 + struct firmware *fw = fw_priv->fw;
13618 + int offset = file->f_pos;
13621 + retval = fw_realloc_buffer(fw_priv, offset + count);
13623 + printk("%s: retval:%d\n", __FUNCTION__, retval);
13627 + memcpy(fw->data + offset, buffer, count);
13629 + fw->size = max_t(size_t, offset + count, fw->size);
13630 + file->f_pos += count;
13635 +firmware_class_timeout(u_long data)
13637 + struct firmware_priv *fw_priv = (struct firmware_priv *) data;
13638 + fw_priv->abort = 1;
13640 + complete(&fw_priv->completion);
13643 +fw_setup_class_device(struct firmware_priv **fw_priv_p,
13644 + const char *fw_name, const char *device)
13647 + struct firmware_priv *fw_priv = kmalloc(sizeof (struct firmware_priv),
13649 + *fw_priv_p = fw_priv;
13651 + retval = -ENOMEM;
13654 + memset(fw_priv, 0, sizeof (*fw_priv));
13656 + init_completion(&fw_priv->completion);
13658 + fw_priv->timeout.function = firmware_class_timeout;
13659 + fw_priv->timeout.data = (u_long) fw_priv;
13660 + init_timer(&fw_priv->timeout);
13662 + retval = -EAGAIN;
13663 + fw_priv->proc_dir = create_proc_entry(device, 0644 | S_IFDIR, proc_dir);
13664 + if (!fw_priv->proc_dir)
13665 + goto err_free_fw_priv;
13667 + fw_priv->attr_data = create_proc_entry("data", 0644 | S_IFREG,
13668 + fw_priv->proc_dir);
13669 + if (!fw_priv->attr_data)
13670 + goto err_remove_dir;
13672 + fw_priv->attr_data->read_proc = firmware_data_read;
13673 + fw_priv->attr_data->write_proc = firmware_data_write;
13674 + fw_priv->attr_data->data = fw_priv;
13676 + fw_priv->attr_loading = create_proc_entry("loading", 0644 | S_IFREG,
13677 + fw_priv->proc_dir);
13678 + if (!fw_priv->attr_loading)
13679 + goto err_remove_data;
13681 + fw_priv->attr_loading->read_proc = firmware_loading_show;
13682 + fw_priv->attr_loading->write_proc = firmware_loading_store;
13683 + fw_priv->attr_loading->data = fw_priv;
13686 + fw_priv->fw = kmalloc(sizeof (struct firmware), GFP_KERNEL);
13687 + if (!fw_priv->fw) {
13688 + printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n",
13690 + retval = -ENOMEM;
13691 + goto err_remove_loading;
13693 + memset(fw_priv->fw, 0, sizeof (*fw_priv->fw));
13697 +err_remove_loading:
13698 + remove_proc_entry("loading", fw_priv->proc_dir);
13700 + remove_proc_entry("data", fw_priv->proc_dir);
13702 + remove_proc_entry(device, proc_dir);
13709 +fw_remove_class_device(struct firmware_priv *fw_priv)
13711 + remove_proc_entry("loading", fw_priv->proc_dir);
13712 + remove_proc_entry("data", fw_priv->proc_dir);
13713 + remove_proc_entry(fw_priv->proc_dir->name, proc_dir);
13717 + * request_firmware: - request firmware to hotplug and wait for it
13719 + * @firmware will be used to return a firmware image by the name
13720 + * of @name for device @device.
13722 + * Should be called from user context where sleeping is allowed.
13724 + * @name will be use as $FIRMWARE in the hotplug environment and
13725 + * should be distinctive enough not to be confused with any other
13726 + * firmware image for this or any other device.
13729 +request_firmware(const struct firmware **firmware, const char *name,
13730 + const char *device)
13732 + struct firmware_priv *fw_priv;
13736 + retval = -EINVAL;
13739 + *firmware = NULL;
13741 + retval = fw_setup_class_device(&fw_priv, name, device);
13745 + retval = call_helper("add", name, device);
13748 + if (loading_timeout) {
13749 + fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
13750 + add_timer(&fw_priv->timeout);
13753 + wait_for_completion(&fw_priv->completion);
13755 + del_timer(&fw_priv->timeout);
13756 + fw_remove_class_device(fw_priv);
13758 + if (fw_priv->fw->size && !fw_priv->abort) {
13759 + *firmware = fw_priv->fw;
13761 + retval = -ENOENT;
13762 + vfree(fw_priv->fw->data);
13763 + kfree(fw_priv->fw);
13771 +release_firmware(const struct firmware *fw)
13780 + * register_firmware: - provide a firmware image for later usage
13783 + * Make sure that @data will be available by requesting firmware @name.
13785 + * Note: This will not be possible until some kind of persistence
13789 +register_firmware(const char *name, const u8 *data, size_t size)
13791 + /* This is meaningless without firmware caching, so until we
13792 + * decide if firmware caching is reasonable just leave it as a
13796 +/* Async support */
13797 +struct firmware_work {
13798 + struct tq_struct work;
13799 + struct module *module;
13800 + const char *name;
13801 + const char *device;
13803 + void (*cont)(const struct firmware *fw, void *context);
13807 +request_firmware_work_func(void *arg)
13809 + struct firmware_work *fw_work = arg;
13810 + const struct firmware *fw;
13813 + request_firmware(&fw, fw_work->name, fw_work->device);
13814 + fw_work->cont(fw, fw_work->context);
13815 + release_firmware(fw);
13816 + __MOD_DEC_USE_COUNT(fw_work->module);
13821 + * request_firmware_nowait:
13824 + * Asynchronous variant of request_firmware() for contexts where
13825 + * it is not possible to sleep.
13827 + * @cont will be called asynchronously when the firmware request is over.
13829 + * @context will be passed over to @cont.
13831 + * @fw may be %NULL if firmware request fails.
13835 +request_firmware_nowait(
13836 + struct module *module,
13837 + const char *name, const char *device, void *context,
13838 + void (*cont)(const struct firmware *fw, void *context))
13840 + struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
13844 + if (!try_inc_mod_count(module)) {
13849 + *fw_work = (struct firmware_work) {
13850 + .module = module,
13852 + .device = device,
13853 + .context = context,
13856 + INIT_TQUEUE(&fw_work->work, request_firmware_work_func, fw_work);
13858 + schedule_task(&fw_work->work);
13863 +firmware_class_init(void)
13865 + proc_dir = create_proc_entry("driver/firmware", 0755 | S_IFDIR, NULL);
13868 + proc_dir_timeout = create_proc_entry("timeout",
13869 + 0644 | S_IFREG, proc_dir);
13870 + if (!proc_dir_timeout) {
13871 + remove_proc_entry("driver/firmware", NULL);
13874 + proc_dir_timeout->read_proc = firmware_timeout_show;
13875 + proc_dir_timeout->write_proc = firmware_timeout_store;
13878 +static void __exit
13879 +firmware_class_exit(void)
13881 + remove_proc_entry("timeout", proc_dir);
13882 + remove_proc_entry("driver/firmware", NULL);
13885 +module_init(firmware_class_init);
13886 +module_exit(firmware_class_exit);
13888 +#ifndef CONFIG_FW_LOADER
13889 +EXPORT_SYMBOL(release_firmware);
13890 +EXPORT_SYMBOL(request_firmware);
13891 +EXPORT_SYMBOL(request_firmware_nowait);
13892 +EXPORT_SYMBOL(register_firmware);
13894 diff -urN linux-2.4.18/lib/Makefile linux-2.4.18-mh15/lib/Makefile
13895 --- linux-2.4.18/lib/Makefile 2001-09-18 00:31:15.000000000 +0200
13896 +++ linux-2.4.18-mh15/lib/Makefile 2004-08-01 16:26:23.000000000 +0200
13901 -export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o
13902 +export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o \
13905 obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o bust_spinlocks.o rbtree.o
13907 +obj-$(CONFIG_FW_LOADER) += firmware_class.o
13908 obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
13909 obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
13911 +include $(TOPDIR)/drivers/bluetooth/Makefile.lib
13913 ifneq ($(CONFIG_HAVE_DEC_LOCK),y)
13914 obj-y += dec_and_lock.o
13916 diff -urN linux-2.4.18/MAINTAINERS linux-2.4.18-mh15/MAINTAINERS
13917 --- linux-2.4.18/MAINTAINERS 2002-02-25 20:37:52.000000000 +0100
13918 +++ linux-2.4.18-mh15/MAINTAINERS 2004-08-01 16:26:23.000000000 +0200
13919 @@ -252,10 +252,88 @@
13920 L: linux-kernel@vger.kernel.org
13923 -BLUETOOTH SUBSYSTEM (BlueZ)
13924 +BLUETOOTH SUBSYSTEM
13925 +P: Marcel Holtmann
13926 +M: marcel@holtmann.org
13927 P: Maxim Krasnyansky
13928 M: maxk@qualcomm.com
13929 +L: bluez-devel@lists.sf.net
13930 W: http://bluez.sf.net
13931 +W: http://www.bluez.org
13932 +W: http://www.holtmann.org/linux/bluetooth/
13935 +BLUETOOTH RFCOMM LAYER
13936 +P: Marcel Holtmann
13937 +M: marcel@holtmann.org
13938 +P: Maxim Krasnyansky
13939 +M: maxk@qualcomm.com
13942 +BLUETOOTH BNEP LAYER
13943 +P: Marcel Holtmann
13944 +M: marcel@holtmann.org
13945 +P: Maxim Krasnyansky
13946 +M: maxk@qualcomm.com
13949 +BLUETOOTH CMTP LAYER
13950 +P: Marcel Holtmann
13951 +M: marcel@holtmann.org
13954 +BLUETOOTH HIDP LAYER
13955 +P: Marcel Holtmann
13956 +M: marcel@holtmann.org
13959 +BLUETOOTH HCI UART DRIVER
13960 +P: Marcel Holtmann
13961 +M: marcel@holtmann.org
13962 +P: Maxim Krasnyansky
13963 +M: maxk@qualcomm.com
13966 +BLUETOOTH HCI USB DRIVER
13967 +P: Marcel Holtmann
13968 +M: marcel@holtmann.org
13969 +P: Maxim Krasnyansky
13970 +M: maxk@qualcomm.com
13973 +BLUETOOTH HCI BCM203X DRIVER
13974 +P: Marcel Holtmann
13975 +M: marcel@holtmann.org
13978 +BLUETOOTH HCI BFUSB DRIVER
13979 +P: Marcel Holtmann
13980 +M: marcel@holtmann.org
13983 +BLUETOOTH HCI DTL1 DRIVER
13984 +P: Marcel Holtmann
13985 +M: marcel@holtmann.org
13988 +BLUETOOTH HCI BLUECARD DRIVER
13989 +P: Marcel Holtmann
13990 +M: marcel@holtmann.org
13993 +BLUETOOTH HCI BT3C DRIVER
13994 +P: Marcel Holtmann
13995 +M: marcel@holtmann.org
13998 +BLUETOOTH HCI BTUART DRIVER
13999 +P: Marcel Holtmann
14000 +M: marcel@holtmann.org
14003 +BLUETOOTH HCI VHCI DRIVER
14004 +P: Maxim Krasnyansky
14005 +M: maxk@qualcomm.com
14008 BTTV VIDEO4LINUX DRIVER
14009 diff -urN linux-2.4.18/net/bluetooth/af_bluetooth.c linux-2.4.18-mh15/net/bluetooth/af_bluetooth.c
14010 --- linux-2.4.18/net/bluetooth/af_bluetooth.c 2001-09-07 18:28:38.000000000 +0200
14011 +++ linux-2.4.18-mh15/net/bluetooth/af_bluetooth.c 2004-08-01 16:26:23.000000000 +0200
14012 @@ -25,14 +25,15 @@
14014 * BlueZ Bluetooth address family and sockets.
14016 - * $Id: af_bluetooth.c,v 1.4 2001/07/05 18:42:44 maxk Exp $
14017 + * $Id: af_bluetooth.c,v 1.8 2002/07/22 20:32:54 maxk Exp $
14019 -#define VERSION "1.1"
14020 +#define VERSION "2.4"
14022 #include <linux/config.h>
14023 #include <linux/module.h>
14025 #include <linux/types.h>
14026 +#include <linux/list.h>
14027 #include <linux/errno.h>
14028 #include <linux/kernel.h>
14029 #include <linux/major.h>
14031 #include <linux/slab.h>
14032 #include <linux/skbuff.h>
14033 #include <linux/init.h>
14034 +#include <linux/poll.h>
14035 #include <linux/proc_fs.h>
14036 #include <net/sock.h>
14038 @@ -48,70 +50,79 @@
14041 #include <net/bluetooth/bluetooth.h>
14042 -#include <net/bluetooth/bluez.h>
14044 +#ifndef AF_BLUETOOTH_DEBUG
14046 +#define BT_DBG( A... )
14049 /* Bluetooth sockets */
14050 -static struct net_proto_family *bluez_sock[BLUEZ_MAX_PROTO];
14051 +#define BLUEZ_MAX_PROTO 7
14052 +static struct net_proto_family *bluez_proto[BLUEZ_MAX_PROTO];
14054 int bluez_sock_register(int proto, struct net_proto_family *ops)
14056 - if (proto > BLUEZ_MAX_PROTO)
14057 + if (proto >= BLUEZ_MAX_PROTO)
14060 - if (bluez_sock[proto])
14061 + if (bluez_proto[proto])
14064 - bluez_sock[proto] = ops;
14065 + bluez_proto[proto] = ops;
14069 int bluez_sock_unregister(int proto)
14071 - if (proto > BLUEZ_MAX_PROTO)
14072 + if (proto >= BLUEZ_MAX_PROTO)
14075 - if (!bluez_sock[proto])
14076 + if (!bluez_proto[proto])
14079 - bluez_sock[proto] = NULL;
14080 + bluez_proto[proto] = NULL;
14084 static int bluez_sock_create(struct socket *sock, int proto)
14086 - if (proto > BLUEZ_MAX_PROTO)
14087 + if (proto >= BLUEZ_MAX_PROTO)
14090 #if defined(CONFIG_KMOD)
14091 - if (!bluez_sock[proto]) {
14092 + if (!bluez_proto[proto]) {
14093 char module_name[30];
14094 sprintf(module_name, "bt-proto-%d", proto);
14095 request_module(module_name);
14099 - if (!bluez_sock[proto])
14100 + if (!bluez_proto[proto])
14103 - return bluez_sock[proto]->create(sock, proto);
14104 + return bluez_proto[proto]->create(sock, proto);
14107 +void bluez_sock_init(struct socket *sock, struct sock *sk)
14109 + sock_init_data(sock, sk);
14110 + INIT_LIST_HEAD(&bluez_pi(sk)->accept_q);
14113 void bluez_sock_link(struct bluez_sock_list *l, struct sock *sk)
14115 - write_lock(&l->lock);
14117 + write_lock_bh(&l->lock);
14118 sk->next = l->head;
14122 - write_unlock(&l->lock);
14123 + write_unlock_bh(&l->lock);
14126 void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *sk)
14130 - write_lock(&l->lock);
14131 + write_lock_bh(&l->lock);
14132 for (skp = &l->head; *skp; skp = &((*skp)->next)) {
14135 @@ -119,7 +130,163 @@
14139 - write_unlock(&l->lock);
14140 + write_unlock_bh(&l->lock);
14143 +void bluez_accept_enqueue(struct sock *parent, struct sock *sk)
14145 + BT_DBG("parent %p, sk %p", parent, sk);
14148 + list_add_tail(&bluez_pi(sk)->accept_q, &bluez_pi(parent)->accept_q);
14149 + bluez_pi(sk)->parent = parent;
14150 + parent->ack_backlog++;
14153 +static void bluez_accept_unlink(struct sock *sk)
14155 + BT_DBG("sk %p state %d", sk, sk->state);
14157 + list_del_init(&bluez_pi(sk)->accept_q);
14158 + bluez_pi(sk)->parent->ack_backlog--;
14159 + bluez_pi(sk)->parent = NULL;
14163 +struct sock *bluez_accept_dequeue(struct sock *parent, struct socket *newsock)
14165 + struct list_head *p, *n;
14166 + struct bluez_pinfo *pi;
14169 + BT_DBG("parent %p", parent);
14171 + list_for_each_safe(p, n, &bluez_pi(parent)->accept_q) {
14172 + pi = list_entry(p, struct bluez_pinfo, accept_q);
14173 + sk = bluez_sk(pi);
14176 + if (sk->state == BT_CLOSED) {
14177 + release_sock(sk);
14178 + bluez_accept_unlink(sk);
14182 + if (sk->state == BT_CONNECTED || !newsock) {
14183 + bluez_accept_unlink(sk);
14185 + sock_graft(sk, newsock);
14186 + release_sock(sk);
14189 + release_sock(sk);
14194 +int bluez_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
14196 + int noblock = flags & MSG_DONTWAIT;
14197 + struct sock *sk = sock->sk;
14198 + struct sk_buff *skb;
14201 + BT_DBG("sock %p sk %p len %d", sock, sk, len);
14203 + if (flags & (MSG_OOB))
14204 + return -EOPNOTSUPP;
14206 + if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) {
14207 + if (sk->shutdown & RCV_SHUTDOWN)
14212 + msg->msg_namelen = 0;
14214 + copied = skb->len;
14215 + if (len < copied) {
14216 + msg->msg_flags |= MSG_TRUNC;
14220 + skb->h.raw = skb->data;
14221 + err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
14223 + skb_free_datagram(sk, skb);
14225 + return err ? : copied;
14228 +unsigned int bluez_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
14230 + struct sock *sk = sock->sk;
14231 + unsigned int mask = 0;
14233 + BT_DBG("sock %p, sk %p", sock, sk);
14235 + poll_wait(file, sk->sleep, wait);
14237 + if (sk->err || !skb_queue_empty(&sk->error_queue))
14240 + if (sk->shutdown == SHUTDOWN_MASK)
14243 + if (!skb_queue_empty(&sk->receive_queue) ||
14244 + !list_empty(&bluez_pi(sk)->accept_q) ||
14245 + (sk->shutdown & RCV_SHUTDOWN))
14246 + mask |= POLLIN | POLLRDNORM;
14248 + if (sk->state == BT_CLOSED)
14251 + if (sk->state == BT_CONNECT ||
14252 + sk->state == BT_CONNECT2 ||
14253 + sk->state == BT_CONFIG)
14256 + if (sock_writeable(sk))
14257 + mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
14259 + set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
14264 +int bluez_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
14266 + DECLARE_WAITQUEUE(wait, current);
14269 + BT_DBG("sk %p", sk);
14271 + add_wait_queue(sk->sleep, &wait);
14272 + while (sk->state != state) {
14273 + set_current_state(TASK_INTERRUPTIBLE);
14280 + if (signal_pending(current)) {
14281 + err = sock_intr_errno(timeo);
14285 + release_sock(sk);
14286 + timeo = schedule_timeout(timeo);
14290 + err = sock_error(sk);
14294 + set_current_state(TASK_RUNNING);
14295 + remove_wait_queue(sk->sleep, &wait);
14299 struct net_proto_family bluez_sock_family_ops =
14300 @@ -129,9 +296,9 @@
14302 int bluez_init(void)
14304 - INF("BlueZ HCI Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
14305 + BT_INFO("BlueZ Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
14307 - INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
14308 + BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
14310 proc_mkdir("bluetooth", NULL);
14312 @@ -164,5 +331,6 @@
14313 module_exit(bluez_cleanup);
14315 MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
14316 -MODULE_DESCRIPTION("BlueZ HCI Core ver " VERSION);
14317 +MODULE_DESCRIPTION("BlueZ Core ver " VERSION);
14318 +MODULE_LICENSE("GPL");
14320 diff -urN linux-2.4.18/net/bluetooth/bnep/bnep.h linux-2.4.18-mh15/net/bluetooth/bnep/bnep.h
14321 --- linux-2.4.18/net/bluetooth/bnep/bnep.h 1970-01-01 01:00:00.000000000 +0100
14322 +++ linux-2.4.18-mh15/net/bluetooth/bnep/bnep.h 2004-08-01 16:26:23.000000000 +0200
14325 + BNEP protocol definition for Linux Bluetooth stack (BlueZ).
14326 + Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
14328 + This program is free software; you can redistribute it and/or modify
14329 + it under the terms of the GNU General Public License, version 2, as
14330 + published by the Free Software Foundation.
14332 + This program is distributed in the hope that it will be useful,
14333 + but WITHOUT ANY WARRANTY; without even the implied warranty of
14334 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14335 + GNU General Public License for more details.
14337 + You should have received a copy of the GNU General Public License
14338 + along with this program; if not, write to the Free Software
14339 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14343 + * $Id: bnep2.h,v 1.9 2002/07/14 07:09:19 maxk Exp $
14349 +#include <linux/types.h>
14350 +#include <net/bluetooth/bluetooth.h>
14352 +#include "crc32.h"
14355 +#define BNEP_MAX_PROTO_FILTERS 5
14356 +#define BNEP_MAX_MULTICAST_FILTERS 20
14359 +#define BNEP_BASE_UUID 0x0000000000001000800000805F9B34FB
14360 +#define BNEP_UUID16 0x02
14361 +#define BNEP_UUID32 0x04
14362 +#define BNEP_UUID128 0x16
14364 +#define BNEP_SVC_PANU 0x1115
14365 +#define BNEP_SVC_NAP 0x1116
14366 +#define BNEP_SVC_GN 0x1117
14369 +#define BNEP_GENERAL 0x00
14370 +#define BNEP_CONTROL 0x01
14371 +#define BNEP_COMPRESSED 0x02
14372 +#define BNEP_COMPRESSED_SRC_ONLY 0x03
14373 +#define BNEP_COMPRESSED_DST_ONLY 0x04
14376 +#define BNEP_CMD_NOT_UNDERSTOOD 0x00
14377 +#define BNEP_SETUP_CONN_REQ 0x01
14378 +#define BNEP_SETUP_CONN_RSP 0x02
14379 +#define BNEP_FILTER_NET_TYPE_SET 0x03
14380 +#define BNEP_FILTER_NET_TYPE_RSP 0x04
14381 +#define BNEP_FILTER_MULTI_ADDR_SET 0x05
14382 +#define BNEP_FILTER_MULTI_ADDR_RSP 0x06
14384 +// Extension types
14385 +#define BNEP_EXT_CONTROL 0x00
14387 +// Response messages
14388 +#define BNEP_SUCCESS 0x00
14390 +#define BNEP_CONN_INVALID_DST 0x01
14391 +#define BNEP_CONN_INVALID_SRC 0x02
14392 +#define BNEP_CONN_INVALID_SVC 0x03
14393 +#define BNEP_CONN_NOT_ALLOWED 0x04
14395 +#define BNEP_FILTER_UNSUPPORTED_REQ 0x01
14396 +#define BNEP_FILTER_INVALID_RANGE 0x02
14397 +#define BNEP_FILTER_INVALID_MCADDR 0x02
14398 +#define BNEP_FILTER_LIMIT_REACHED 0x03
14399 +#define BNEP_FILTER_DENIED_SECURITY 0x04
14402 +#define BNEP_MTU 1691
14403 +#define BNEP_PSM 0x0f
14404 +#define BNEP_FLUSH_TO 0xffff
14405 +#define BNEP_CONNECT_TO 15
14406 +#define BNEP_FILTER_TO 15
14409 +#define BNEP_TYPE_MASK 0x7f
14410 +#define BNEP_EXT_HEADER 0x80
14412 +struct bnep_setup_conn_req {
14417 +} __attribute__((packed));
14419 +struct bnep_set_filter_req {
14424 +} __attribute__((packed));
14426 +struct bnep_control_rsp {
14430 +} __attribute__((packed));
14432 +struct bnep_ext_hdr {
14436 +} __attribute__((packed));
14438 +/* BNEP ioctl defines */
14439 +#define BNEPCONNADD _IOW('B', 200, int)
14440 +#define BNEPCONNDEL _IOW('B', 201, int)
14441 +#define BNEPGETCONNLIST _IOR('B', 210, int)
14442 +#define BNEPGETCONNINFO _IOR('B', 211, int)
14444 +struct bnep_connadd_req {
14445 + int sock; // Connected socket
14448 + char device[16]; // Name of the Ethernet device
14451 +struct bnep_conndel_req {
14453 + __u8 dst[ETH_ALEN];
14456 +struct bnep_conninfo {
14460 + __u8 dst[ETH_ALEN];
14464 +struct bnep_connlist_req {
14466 + struct bnep_conninfo *ci;
14469 +struct bnep_proto_filter {
14474 +int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock);
14475 +int bnep_del_connection(struct bnep_conndel_req *req);
14476 +int bnep_get_connlist(struct bnep_connlist_req *req);
14477 +int bnep_get_conninfo(struct bnep_conninfo *ci);
14480 +struct bnep_session {
14481 + struct list_head list;
14483 + unsigned int role;
14484 + unsigned long state;
14485 + unsigned long flags;
14488 + struct ethhdr eh;
14489 + struct msghdr msg;
14491 + struct bnep_proto_filter proto_filter[BNEP_MAX_PROTO_FILTERS];
14494 + struct socket *sock;
14495 + struct net_device dev;
14496 + struct net_device_stats stats;
14499 +int bnep_net_init(struct net_device *dev);
14500 +int bnep_sock_init(void);
14501 +int bnep_sock_cleanup(void);
14503 +static inline int bnep_mc_hash(__u8 *addr)
14505 + return (bnep_crc32(~0, addr, ETH_ALEN) >> 26);
14509 diff -urN linux-2.4.18/net/bluetooth/bnep/Config.in linux-2.4.18-mh15/net/bluetooth/bnep/Config.in
14510 --- linux-2.4.18/net/bluetooth/bnep/Config.in 1970-01-01 01:00:00.000000000 +0100
14511 +++ linux-2.4.18-mh15/net/bluetooth/bnep/Config.in 2004-08-01 16:26:23.000000000 +0200
14514 +# Bluetooth BNEP layer configuration
14517 +dep_tristate 'BNEP protocol support' CONFIG_BLUEZ_BNEP $CONFIG_BLUEZ_L2CAP
14519 +if [ "$CONFIG_BLUEZ_BNEP" != "n" ]; then
14520 + bool ' Multicast filter support' CONFIG_BLUEZ_BNEP_MC_FILTER
14521 + bool ' Protocol filter support' CONFIG_BLUEZ_BNEP_PROTO_FILTER
14524 diff -urN linux-2.4.18/net/bluetooth/bnep/core.c linux-2.4.18-mh15/net/bluetooth/bnep/core.c
14525 --- linux-2.4.18/net/bluetooth/bnep/core.c 1970-01-01 01:00:00.000000000 +0100
14526 +++ linux-2.4.18-mh15/net/bluetooth/bnep/core.c 2004-08-01 16:26:23.000000000 +0200
14529 + BNEP implementation for Linux Bluetooth stack (BlueZ).
14530 + Copyright (C) 2001-2002 Inventel Systemes
14531 + Written 2001-2002 by
14532 + Clément Moreau <clement.moreau@inventel.fr>
14533 + David Libault <david.libault@inventel.fr>
14535 + Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
14537 + This program is free software; you can redistribute it and/or modify
14538 + it under the terms of the GNU General Public License version 2 as
14539 + published by the Free Software Foundation;
14541 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14542 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14543 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14544 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
14545 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14546 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14547 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14548 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14550 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
14551 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
14552 + SOFTWARE IS DISCLAIMED.
14556 + * $Id: core.c,v 1.18 2002/07/14 07:09:19 maxk Exp $
14559 +#define __KERNEL_SYSCALLS__
14561 +#include <linux/config.h>
14562 +#include <linux/module.h>
14564 +#include <linux/kernel.h>
14565 +#include <linux/sched.h>
14566 +#include <linux/signal.h>
14567 +#include <linux/init.h>
14568 +#include <linux/wait.h>
14569 +#include <linux/errno.h>
14570 +#include <linux/smp_lock.h>
14571 +#include <linux/net.h>
14572 +#include <net/sock.h>
14574 +#include <linux/socket.h>
14575 +#include <linux/file.h>
14577 +#include <linux/netdevice.h>
14578 +#include <linux/etherdevice.h>
14579 +#include <linux/skbuff.h>
14581 +#include <asm/unaligned.h>
14583 +#include <net/bluetooth/bluetooth.h>
14584 +#include <net/bluetooth/l2cap.h>
14588 +#ifndef CONFIG_BLUEZ_BNEP_DEBUG
14590 +#define BT_DBG(D...)
14593 +#define VERSION "1.2"
14595 +static LIST_HEAD(bnep_session_list);
14596 +static DECLARE_RWSEM(bnep_session_sem);
14598 +static struct bnep_session *__bnep_get_session(u8 *dst)
14600 + struct bnep_session *s;
14601 + struct list_head *p;
14605 + list_for_each(p, &bnep_session_list) {
14606 + s = list_entry(p, struct bnep_session, list);
14607 + if (!memcmp(dst, s->eh.h_source, ETH_ALEN))
14613 +static void __bnep_link_session(struct bnep_session *s)
14615 + MOD_INC_USE_COUNT;
14616 + list_add(&s->list, &bnep_session_list);
14619 +static void __bnep_unlink_session(struct bnep_session *s)
14621 + list_del(&s->list);
14622 + MOD_DEC_USE_COUNT;
14625 +static int bnep_send(struct bnep_session *s, void *data, size_t len)
14627 + struct socket *sock = s->sock;
14628 + struct iovec iv = { data, len };
14629 + s->msg.msg_iov = &iv;
14630 + s->msg.msg_iovlen = 1;
14631 + return sock->ops->sendmsg(sock, &s->msg, len, NULL);
14634 +static int bnep_send_rsp(struct bnep_session *s, u8 ctrl, u16 resp)
14636 + struct bnep_control_rsp rsp;
14637 + rsp.type = BNEP_CONTROL;
14639 + rsp.resp = htons(resp);
14640 + return bnep_send(s, &rsp, sizeof(rsp));
14643 +#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
14644 +static inline void bnep_set_default_proto_filter(struct bnep_session *s)
14646 + /* (IPv4, ARP) */
14647 + s->proto_filter[0].start = htons(0x0800);
14648 + s->proto_filter[0].end = htons(0x0806);
14649 + /* (RARP, AppleTalk) */
14650 + s->proto_filter[1].start = htons(0x8035);
14651 + s->proto_filter[1].end = htons(0x80F3);
14652 + /* (IPX, IPv6) */
14653 + s->proto_filter[2].start = htons(0x8137);
14654 + s->proto_filter[2].end = htons(0x86DD);
14658 +static int bnep_ctrl_set_netfilter(struct bnep_session *s, u16 *data, int len)
14665 + n = ntohs(get_unaligned(data));
14666 + data++; len -= 2;
14671 + BT_DBG("filter len %d", n);
14673 +#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
14675 + if (n <= BNEP_MAX_PROTO_FILTERS) {
14676 + struct bnep_proto_filter *f = s->proto_filter;
14679 + for (i = 0; i < n; i++) {
14680 + f[i].start = get_unaligned(data++);
14681 + f[i].end = get_unaligned(data++);
14683 + BT_DBG("proto filter start %d end %d",
14684 + f[i].start, f[i].end);
14687 + if (i < BNEP_MAX_PROTO_FILTERS)
14688 + memset(f + i, 0, sizeof(*f));
14691 + bnep_set_default_proto_filter(s);
14693 + bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_SUCCESS);
14695 + bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_LIMIT_REACHED);
14698 + bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
14703 +static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
14710 + n = ntohs(get_unaligned((u16 *) data));
14711 + data += 2; len -= 2;
14716 + BT_DBG("filter len %d", n);
14718 +#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
14719 + n /= (ETH_ALEN * 2);
14722 + s->mc_filter = 0;
14724 + /* Always send broadcast */
14725 + set_bit(bnep_mc_hash(s->dev.broadcast), &s->mc_filter);
14727 + /* Add address ranges to the multicast hash */
14728 + for (; n > 0; n--) {
14731 + memcpy(a1, data, ETH_ALEN); data += ETH_ALEN;
14732 + a2 = data; data += ETH_ALEN;
14734 + BT_DBG("mc filter %s -> %s",
14735 + batostr((void *) a1), batostr((void *) a2));
14737 + #define INCA(a) { int i = 5; while (i >=0 && ++a[i--] == 0); }
14739 + /* Iterate from a1 to a2 */
14740 + set_bit(bnep_mc_hash(a1), &s->mc_filter);
14741 + while (memcmp(a1, a2, 6) < 0 && s->mc_filter != ~0LL) {
14743 + set_bit(bnep_mc_hash(a1), &s->mc_filter);
14748 + BT_DBG("mc filter hash 0x%llx", s->mc_filter);
14750 + bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_SUCCESS);
14752 + bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
14757 +static int bnep_rx_control(struct bnep_session *s, void *data, int len)
14759 + u8 cmd = *(u8 *)data;
14765 + case BNEP_CMD_NOT_UNDERSTOOD:
14766 + case BNEP_SETUP_CONN_REQ:
14767 + case BNEP_SETUP_CONN_RSP:
14768 + case BNEP_FILTER_NET_TYPE_RSP:
14769 + case BNEP_FILTER_MULTI_ADDR_RSP:
14770 + /* Ignore these for now */
14773 + case BNEP_FILTER_NET_TYPE_SET:
14774 + err = bnep_ctrl_set_netfilter(s, data, len);
14777 + case BNEP_FILTER_MULTI_ADDR_SET:
14778 + err = bnep_ctrl_set_mcfilter(s, data, len);
14783 + pkt[0] = BNEP_CONTROL;
14784 + pkt[1] = BNEP_CMD_NOT_UNDERSTOOD;
14786 + bnep_send(s, pkt, sizeof(pkt));
14794 +static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb)
14796 + struct bnep_ext_hdr *h;
14800 + h = (void *) skb->data;
14801 + if (!skb_pull(skb, sizeof(*h))) {
14806 + BT_DBG("type 0x%x len %d", h->type, h->len);
14808 + switch (h->type & BNEP_TYPE_MASK) {
14809 + case BNEP_EXT_CONTROL:
14810 + bnep_rx_control(s, skb->data, skb->len);
14814 + /* Unknown extension, skip it. */
14818 + if (!skb_pull(skb, h->len)) {
14822 + } while (!err && (h->type & BNEP_EXT_HEADER));
14827 +static u8 __bnep_rx_hlen[] = {
14828 + ETH_HLEN, /* BNEP_GENERAL */
14829 + 0, /* BNEP_CONTROL */
14830 + 2, /* BNEP_COMPRESSED */
14831 + ETH_ALEN + 2, /* BNEP_COMPRESSED_SRC_ONLY */
14832 + ETH_ALEN + 2 /* BNEP_COMPRESSED_DST_ONLY */
14834 +#define BNEP_RX_TYPES (sizeof(__bnep_rx_hlen) - 1)
14836 +static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
14838 + struct net_device *dev = &s->dev;
14839 + struct sk_buff *nskb;
14842 + dev->last_rx = jiffies;
14843 + s->stats.rx_bytes += skb->len;
14845 + type = *(u8 *) skb->data; skb_pull(skb, 1);
14847 + if ((type & BNEP_TYPE_MASK) > BNEP_RX_TYPES)
14850 + if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) {
14851 + bnep_rx_control(s, skb->data, skb->len);
14856 + skb->mac.raw = skb->data;
14858 + /* Verify and pull out header */
14859 + if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK]))
14862 + s->eh.h_proto = get_unaligned((u16 *) (skb->data - 2));
14864 + if (type & BNEP_EXT_HEADER) {
14865 + if (bnep_rx_extension(s, skb) < 0)
14869 + /* Strip 802.1p header */
14870 + if (ntohs(s->eh.h_proto) == 0x8100) {
14871 + if (!skb_pull(skb, 4))
14873 + s->eh.h_proto = get_unaligned((u16 *) (skb->data - 2));
14876 + /* We have to alloc new skb and copy data here :(. Because original skb
14877 + * may not be modified and because of the alignment requirements. */
14878 + nskb = alloc_skb(2 + ETH_HLEN + skb->len, GFP_KERNEL);
14880 + s->stats.rx_dropped++;
14884 + skb_reserve(nskb, 2);
14886 + /* Decompress header and construct ether frame */
14887 + switch (type & BNEP_TYPE_MASK) {
14888 + case BNEP_COMPRESSED:
14889 + memcpy(__skb_put(nskb, ETH_HLEN), &s->eh, ETH_HLEN);
14892 + case BNEP_COMPRESSED_SRC_ONLY:
14893 + memcpy(__skb_put(nskb, ETH_ALEN), s->eh.h_dest, ETH_ALEN);
14894 + memcpy(__skb_put(nskb, ETH_ALEN), skb->mac.raw, ETH_ALEN);
14895 + put_unaligned(s->eh.h_proto, (u16 *) __skb_put(nskb, 2));
14898 + case BNEP_COMPRESSED_DST_ONLY:
14899 + memcpy(__skb_put(nskb, ETH_ALEN), skb->mac.raw, ETH_ALEN);
14900 + memcpy(__skb_put(nskb, ETH_ALEN + 2), s->eh.h_source, ETH_ALEN + 2);
14903 + case BNEP_GENERAL:
14904 + memcpy(__skb_put(nskb, ETH_ALEN * 2), skb->mac.raw, ETH_ALEN * 2);
14905 + put_unaligned(s->eh.h_proto, (u16 *) __skb_put(nskb, 2));
14909 + memcpy(__skb_put(nskb, skb->len), skb->data, skb->len);
14912 + s->stats.rx_packets++;
14914 + nskb->ip_summed = CHECKSUM_UNNECESSARY;
14915 + nskb->protocol = eth_type_trans(nskb, dev);
14916 + netif_rx_ni(nskb);
14920 + s->stats.rx_errors++;
14925 +static u8 __bnep_tx_types[] = {
14927 + BNEP_COMPRESSED_SRC_ONLY,
14928 + BNEP_COMPRESSED_DST_ONLY,
14932 +static inline int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb)
14934 + struct ethhdr *eh = (void *) skb->data;
14935 + struct socket *sock = s->sock;
14936 + struct iovec iv[3];
14937 + int len = 0, il = 0;
14940 + BT_DBG("skb %p dev %p type %d", skb, skb->dev, skb->pkt_type);
14943 + /* Control frame sent by us */
14947 + iv[il++] = (struct iovec) { &type, 1 };
14950 + if (!memcmp(eh->h_dest, s->eh.h_source, ETH_ALEN))
14953 + if (!memcmp(eh->h_source, s->eh.h_dest, ETH_ALEN))
14957 + skb_pull(skb, ETH_ALEN * 2);
14959 + type = __bnep_tx_types[type];
14961 + case BNEP_COMPRESSED_SRC_ONLY:
14962 + iv[il++] = (struct iovec) { eh->h_source, ETH_ALEN };
14966 + case BNEP_COMPRESSED_DST_ONLY:
14967 + iv[il++] = (struct iovec) { eh->h_dest, ETH_ALEN };
14973 + iv[il++] = (struct iovec) { skb->data, skb->len };
14976 + /* FIXME: linearize skb */
14978 + s->msg.msg_iov = iv;
14979 + s->msg.msg_iovlen = il;
14980 + len = sock->ops->sendmsg(sock, &s->msg, len, NULL);
14984 + s->stats.tx_bytes += len;
14985 + s->stats.tx_packets++;
14992 +static int bnep_session(void *arg)
14994 + struct bnep_session *s = arg;
14995 + struct net_device *dev = &s->dev;
14996 + struct sock *sk = s->sock->sk;
14997 + struct sk_buff *skb;
14998 + wait_queue_t wait;
15002 + daemonize(); reparent_to_init();
15004 + sprintf(current->comm, "kbnepd %s", dev->name);
15006 + sigfillset(¤t->blocked);
15007 + flush_signals(current);
15009 + current->nice = -15;
15011 + set_fs(KERNEL_DS);
15013 + init_waitqueue_entry(&wait, current);
15014 + add_wait_queue(sk->sleep, &wait);
15015 + while (!atomic_read(&s->killed)) {
15016 + set_current_state(TASK_INTERRUPTIBLE);
15019 + while ((skb = skb_dequeue(&sk->receive_queue))) {
15021 + bnep_rx_frame(s, skb);
15024 + if (sk->state != BT_CONNECTED)
15028 + while ((skb = skb_dequeue(&sk->write_queue)))
15029 + if (bnep_tx_frame(s, skb))
15031 + netif_wake_queue(dev);
15035 + set_current_state(TASK_RUNNING);
15036 + remove_wait_queue(sk->sleep, &wait);
15038 + /* Cleanup session */
15039 + down_write(&bnep_session_sem);
15041 + /* Delete network device */
15042 + unregister_netdev(dev);
15044 + /* Release the socket */
15045 + fput(s->sock->file);
15047 + __bnep_unlink_session(s);
15049 + up_write(&bnep_session_sem);
15054 +int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
15056 + struct net_device *dev;
15057 + struct bnep_session *s, *ss;
15058 + u8 dst[ETH_ALEN], src[ETH_ALEN];
15063 + baswap((void *) dst, &bluez_pi(sock->sk)->dst);
15064 + baswap((void *) src, &bluez_pi(sock->sk)->src);
15066 + s = kmalloc(sizeof(struct bnep_session), GFP_KERNEL);
15069 + memset(s, 0, sizeof(struct bnep_session));
15071 + down_write(&bnep_session_sem);
15073 + ss = __bnep_get_session(dst);
15074 + if (ss && ss->state == BT_CONNECTED) {
15081 + if (*req->device)
15082 + strcpy(dev->name, req->device);
15084 + strcpy(dev->name, "bnep%d");
15086 + memset(dev->broadcast, 0xff, ETH_ALEN);
15088 + /* This is rx header therefor addresses are swaped.
15089 + * ie eh.h_dest is our local address. */
15090 + memcpy(s->eh.h_dest, &src, ETH_ALEN);
15091 + memcpy(s->eh.h_source, &dst, ETH_ALEN);
15094 + s->role = req->role;
15095 + s->state = BT_CONNECTED;
15097 + s->msg.msg_flags = MSG_NOSIGNAL;
15099 +#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
15100 + /* Set default mc filter */
15101 + set_bit(bnep_mc_hash(dev->broadcast), &s->mc_filter);
15104 +#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
15105 + /* Set default protocol filter */
15106 + bnep_set_default_proto_filter(s);
15109 + dev->init = bnep_net_init;
15111 + err = register_netdev(dev);
15116 + __bnep_link_session(s);
15118 + err = kernel_thread(bnep_session, s, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
15120 + /* Session thread start failed, gotta cleanup. */
15121 + unregister_netdev(dev);
15122 + __bnep_unlink_session(s);
15126 + up_write(&bnep_session_sem);
15127 + strcpy(req->device, dev->name);
15131 + up_write(&bnep_session_sem);
15136 +int bnep_del_connection(struct bnep_conndel_req *req)
15138 + struct bnep_session *s;
15143 + down_read(&bnep_session_sem);
15145 + s = __bnep_get_session(req->dst);
15147 + /* Wakeup user-space which is polling for socket errors.
15148 + * This is temporary hack untill we have shutdown in L2CAP */
15149 + s->sock->sk->err = EUNATCH;
15151 + /* Kill session thread */
15152 + atomic_inc(&s->killed);
15153 + wake_up_interruptible(s->sock->sk->sleep);
15157 + up_read(&bnep_session_sem);
15161 +static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s)
15163 + memcpy(ci->dst, s->eh.h_source, ETH_ALEN);
15164 + strcpy(ci->device, s->dev.name);
15165 + ci->flags = s->flags;
15166 + ci->state = s->state;
15167 + ci->role = s->role;
15170 +int bnep_get_connlist(struct bnep_connlist_req *req)
15172 + struct list_head *p;
15173 + int err = 0, n = 0;
15175 + down_read(&bnep_session_sem);
15177 + list_for_each(p, &bnep_session_list) {
15178 + struct bnep_session *s;
15179 + struct bnep_conninfo ci;
15181 + s = list_entry(p, struct bnep_session, list);
15183 + __bnep_copy_ci(&ci, s);
15185 + if (copy_to_user(req->ci, &ci, sizeof(ci))) {
15190 + if (++n >= req->cnum)
15197 + up_read(&bnep_session_sem);
15201 +int bnep_get_conninfo(struct bnep_conninfo *ci)
15203 + struct bnep_session *s;
15206 + down_read(&bnep_session_sem);
15208 + s = __bnep_get_session(ci->dst);
15210 + __bnep_copy_ci(ci, s);
15214 + up_read(&bnep_session_sem);
15218 +static int __init bnep_init_module(void)
15222 + bnep_crc32_init();
15223 + bnep_sock_init();
15225 + BT_INFO("BlueZ BNEP ver %s", VERSION);
15226 + BT_INFO("Copyright (C) 2001,2002 Inventel Systemes");
15227 + BT_INFO("Written 2001,2002 by Clement Moreau <clement.moreau@inventel.fr>");
15228 + BT_INFO("Written 2001,2002 by David Libault <david.libault@inventel.fr>");
15229 + BT_INFO("Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>");
15234 +static void __exit bnep_cleanup_module(void)
15236 + bnep_sock_cleanup();
15237 + bnep_crc32_cleanup();
15240 +module_init(bnep_init_module);
15241 +module_exit(bnep_cleanup_module);
15243 +MODULE_DESCRIPTION("BlueZ BNEP ver " VERSION);
15244 +MODULE_AUTHOR("David Libault <david.libault@inventel.fr>, Maxim Krasnyanskiy <maxk@qualcomm.com>");
15245 +MODULE_LICENSE("GPL");
15246 diff -urN linux-2.4.18/net/bluetooth/bnep/crc32.c linux-2.4.18-mh15/net/bluetooth/bnep/crc32.c
15247 --- linux-2.4.18/net/bluetooth/bnep/crc32.c 1970-01-01 01:00:00.000000000 +0100
15248 +++ linux-2.4.18-mh15/net/bluetooth/bnep/crc32.c 2004-08-01 16:26:23.000000000 +0200
15251 + * Based on linux-2.5/lib/crc32 by Matt Domsch <Matt_Domsch@dell.com>
15253 + * FIXME: Remove in 2.5
15256 +#include <linux/kernel.h>
15257 +#include <linux/module.h>
15258 +#include <linux/types.h>
15259 +#include <linux/slab.h>
15260 +#include <linux/init.h>
15261 +#include <asm/atomic.h>
15263 +#include "crc32.h"
15265 +#define CRCPOLY_BE 0x04c11db7
15266 +#define CRC_BE_BITS 8
15268 +static u32 *bnep_crc32_table;
15271 + * This code is in the public domain; copyright abandoned.
15272 + * Liability for non-performance of this code is limited to the amount
15273 + * you paid for it. Since it is distributed for free, your refund will
15274 + * be very very small. If it breaks, you get to keep both pieces.
15276 +u32 bnep_crc32(u32 crc, unsigned char const *p, size_t len)
15279 + crc = (crc << 8) ^ bnep_crc32_table[(crc >> 24) ^ *p++];
15284 +int __init bnep_crc32_init(void)
15287 + u32 crc = 0x80000000;
15289 + bnep_crc32_table = kmalloc((1 << CRC_BE_BITS) * sizeof(u32), GFP_KERNEL);
15290 + if (!bnep_crc32_table)
15293 + bnep_crc32_table[0] = 0;
15295 + for (i = 1; i < 1 << CRC_BE_BITS; i <<= 1) {
15296 + crc = (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE : 0);
15297 + for (j = 0; j < i; j++)
15298 + bnep_crc32_table[i + j] = crc ^ bnep_crc32_table[j];
15303 +void __exit bnep_crc32_cleanup(void)
15305 + if (bnep_crc32_table)
15306 + kfree(bnep_crc32_table);
15307 + bnep_crc32_table = NULL;
15309 diff -urN linux-2.4.18/net/bluetooth/bnep/crc32.h linux-2.4.18-mh15/net/bluetooth/bnep/crc32.h
15310 --- linux-2.4.18/net/bluetooth/bnep/crc32.h 1970-01-01 01:00:00.000000000 +0100
15311 +++ linux-2.4.18-mh15/net/bluetooth/bnep/crc32.h 2004-08-01 16:26:23.000000000 +0200
15315 + * See crc32.c for license and changes
15317 + * FIXME: Remove in 2.5
15320 +int bnep_crc32_init(void);
15321 +void bnep_crc32_cleanup(void);
15322 +u32 bnep_crc32(u32 crc, unsigned char const *p, size_t len);
15323 diff -urN linux-2.4.18/net/bluetooth/bnep/Makefile linux-2.4.18-mh15/net/bluetooth/bnep/Makefile
15324 --- linux-2.4.18/net/bluetooth/bnep/Makefile 1970-01-01 01:00:00.000000000 +0100
15325 +++ linux-2.4.18-mh15/net/bluetooth/bnep/Makefile 2004-08-01 16:26:23.000000000 +0200
15328 +# Makefile for the Linux Bluetooth BNEP layer
15331 +O_TARGET := bnep.o
15333 +obj-y := core.o sock.o netdev.o crc32.o
15334 +obj-m += $(O_TARGET)
15336 +include $(TOPDIR)/Rules.make
15337 diff -urN linux-2.4.18/net/bluetooth/bnep/netdev.c linux-2.4.18-mh15/net/bluetooth/bnep/netdev.c
15338 --- linux-2.4.18/net/bluetooth/bnep/netdev.c 1970-01-01 01:00:00.000000000 +0100
15339 +++ linux-2.4.18-mh15/net/bluetooth/bnep/netdev.c 2004-08-01 16:26:23.000000000 +0200
15342 + BNEP implementation for Linux Bluetooth stack (BlueZ).
15343 + Copyright (C) 2001-2002 Inventel Systemes
15344 + Written 2001-2002 by
15345 + Clément Moreau <clement.moreau@inventel.fr>
15346 + David Libault <david.libault@inventel.fr>
15348 + Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
15350 + This program is free software; you can redistribute it and/or modify
15351 + it under the terms of the GNU General Public License version 2 as
15352 + published by the Free Software Foundation;
15354 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15355 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15356 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
15357 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
15358 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
15359 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15360 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15361 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15363 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
15364 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
15365 + SOFTWARE IS DISCLAIMED.
15369 + * $Id: netdev.c,v 1.7 2002/07/14 05:39:26 maxk Exp $
15372 +#include <linux/config.h>
15373 +#include <linux/module.h>
15375 +#include <linux/socket.h>
15376 +#include <linux/netdevice.h>
15377 +#include <linux/etherdevice.h>
15378 +#include <linux/skbuff.h>
15379 +#include <linux/wait.h>
15381 +#include <asm/unaligned.h>
15383 +#include <net/bluetooth/bluetooth.h>
15384 +#include <net/bluetooth/hci_core.h>
15385 +#include <net/bluetooth/l2cap.h>
15389 +#ifndef CONFIG_BLUEZ_BNEP_DEBUG
15391 +#define BT_DBG( A... )
15394 +#define BNEP_TX_QUEUE_LEN 20
15396 +static int bnep_net_open(struct net_device *dev)
15398 + netif_start_queue(dev);
15402 +static int bnep_net_close(struct net_device *dev)
15404 + netif_stop_queue(dev);
15408 +static struct net_device_stats *bnep_net_get_stats(struct net_device *dev)
15410 + struct bnep_session *s = dev->priv;
15411 + return &s->stats;
15414 +static void bnep_net_set_mc_list(struct net_device *dev)
15416 +#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
15417 + struct bnep_session *s = dev->priv;
15418 + struct sock *sk = s->sock->sk;
15419 + struct bnep_set_filter_req *r;
15420 + struct sk_buff *skb;
15423 + BT_DBG("%s mc_count %d", dev->name, dev->mc_count);
15425 + size = sizeof(*r) + (BNEP_MAX_MULTICAST_FILTERS + 1) * ETH_ALEN * 2;
15426 + skb = alloc_skb(size, GFP_ATOMIC);
15428 + BT_ERR("%s Multicast list allocation failed", dev->name);
15432 + r = (void *) skb->data;
15433 + __skb_put(skb, sizeof(*r));
15435 + r->type = BNEP_CONTROL;
15436 + r->ctrl = BNEP_FILTER_MULTI_ADDR_SET;
15438 + if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
15439 + u8 start[ETH_ALEN] = { 0x01 };
15441 + /* Request all addresses */
15442 + memcpy(__skb_put(skb, ETH_ALEN), start, ETH_ALEN);
15443 + memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
15444 + r->len = htons(ETH_ALEN * 2);
15446 + struct dev_mc_list *dmi = dev->mc_list;
15447 + int i, len = skb->len;
15449 + if (dev->flags & IFF_BROADCAST) {
15450 + memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
15451 + memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
15454 + /* FIXME: We should group addresses here. */
15456 + for (i = 0; i < dev->mc_count && i < BNEP_MAX_MULTICAST_FILTERS; i++) {
15457 + memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN);
15458 + memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN);
15461 + r->len = htons(skb->len - len);
15464 + skb_queue_tail(&sk->write_queue, skb);
15465 + wake_up_interruptible(sk->sleep);
15469 +static int bnep_net_set_mac_addr(struct net_device *dev, void *arg)
15471 + BT_DBG("%s", dev->name);
15475 +static void bnep_net_timeout(struct net_device *dev)
15477 + BT_DBG("net_timeout");
15478 + netif_wake_queue(dev);
15481 +static int bnep_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
15486 +#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
15487 +static inline int bnep_net_mc_filter(struct sk_buff *skb, struct bnep_session *s)
15489 + struct ethhdr *eh = (void *) skb->data;
15491 + if ((eh->h_dest[0] & 1) && !test_bit(bnep_mc_hash(eh->h_dest), &s->mc_filter)) {
15492 + BT_DBG("BNEP: filtered skb %p, dst %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", skb,
15493 + eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
15494 + eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]);
15501 +#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
15502 +/* Determine ether protocol. Based on eth_type_trans. */
15503 +static inline u16 bnep_net_eth_proto(struct sk_buff *skb)
15505 + struct ethhdr *eh = (void *) skb->data;
15507 + if (ntohs(eh->h_proto) >= 1536)
15508 + return eh->h_proto;
15510 + if (get_unaligned((u16 *) skb->data) == 0xFFFF)
15511 + return htons(ETH_P_802_3);
15513 + return htons(ETH_P_802_2);
15516 +static inline int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session *s)
15518 + u16 proto = bnep_net_eth_proto(skb);
15519 + struct bnep_proto_filter *f = s->proto_filter;
15522 + for (i = 0; i < BNEP_MAX_PROTO_FILTERS && f[i].end; i++) {
15523 + if (proto >= f[i].start && proto <= f[i].end)
15527 + BT_DBG("BNEP: filtered skb %p, proto 0x%.4x", skb, proto);
15532 +static int bnep_net_xmit(struct sk_buff *skb, struct net_device *dev)
15534 + struct bnep_session *s = dev->priv;
15535 + struct sock *sk = s->sock->sk;
15537 + BT_DBG("skb %p, dev %p", skb, dev);
15539 +#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
15540 + if (bnep_net_mc_filter(skb, s)) {
15546 +#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
15547 + if (bnep_net_proto_filter(skb, s)) {
15554 + * We cannot send L2CAP packets from here as we are potentially in a bh.
15555 + * So we have to queue them and wake up session thread which is sleeping
15556 + * on the sk->sleep.
15558 + dev->trans_start = jiffies;
15559 + skb_queue_tail(&sk->write_queue, skb);
15560 + wake_up_interruptible(sk->sleep);
15562 + if (skb_queue_len(&sk->write_queue) >= BNEP_TX_QUEUE_LEN) {
15563 + BT_DBG("tx queue is full");
15566 + * Session thread will do netif_wake_queue() */
15567 + netif_stop_queue(dev);
15573 +int bnep_net_init(struct net_device *dev)
15575 + struct bnep_session *s = dev->priv;
15577 + memcpy(dev->dev_addr, s->eh.h_dest, ETH_ALEN);
15578 + dev->addr_len = ETH_ALEN;
15580 + ether_setup(dev);
15582 + dev->open = bnep_net_open;
15583 + dev->stop = bnep_net_close;
15584 + dev->hard_start_xmit = bnep_net_xmit;
15585 + dev->get_stats = bnep_net_get_stats;
15586 + dev->do_ioctl = bnep_net_ioctl;
15587 + dev->set_mac_address = bnep_net_set_mac_addr;
15588 + dev->set_multicast_list = bnep_net_set_mc_list;
15590 + dev->watchdog_timeo = HZ * 2;
15591 + dev->tx_timeout = bnep_net_timeout;
15595 diff -urN linux-2.4.18/net/bluetooth/bnep/sock.c linux-2.4.18-mh15/net/bluetooth/bnep/sock.c
15596 --- linux-2.4.18/net/bluetooth/bnep/sock.c 1970-01-01 01:00:00.000000000 +0100
15597 +++ linux-2.4.18-mh15/net/bluetooth/bnep/sock.c 2004-08-01 16:26:23.000000000 +0200
15600 + BNEP implementation for Linux Bluetooth stack (BlueZ).
15601 + Copyright (C) 2001-2002 Inventel Systemes
15602 + Written 2001-2002 by
15603 + David Libault <david.libault@inventel.fr>
15605 + Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
15607 + This program is free software; you can redistribute it and/or modify
15608 + it under the terms of the GNU General Public License version 2 as
15609 + published by the Free Software Foundation;
15611 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15612 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15613 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
15614 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
15615 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
15616 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15617 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15618 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15620 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
15621 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
15622 + SOFTWARE IS DISCLAIMED.
15626 + * $Id: sock.c,v 1.3 2002/07/10 22:59:52 maxk Exp $
15629 +#include <linux/config.h>
15630 +#include <linux/module.h>
15632 +#include <linux/types.h>
15633 +#include <linux/errno.h>
15634 +#include <linux/kernel.h>
15635 +#include <linux/major.h>
15636 +#include <linux/sched.h>
15637 +#include <linux/slab.h>
15638 +#include <linux/poll.h>
15639 +#include <linux/fcntl.h>
15640 +#include <linux/skbuff.h>
15641 +#include <linux/socket.h>
15642 +#include <linux/ioctl.h>
15643 +#include <linux/file.h>
15644 +#include <net/sock.h>
15646 +#include <asm/system.h>
15647 +#include <asm/uaccess.h>
15651 +#ifndef CONFIG_BLUEZ_BNEP_DEBUG
15653 +#define BT_DBG( A... )
15656 +static int bnep_sock_release(struct socket *sock)
15658 + struct sock *sk = sock->sk;
15660 + BT_DBG("sock %p sk %p", sock, sk);
15668 + MOD_DEC_USE_COUNT;
15672 +static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
15674 + struct bnep_connlist_req cl;
15675 + struct bnep_connadd_req ca;
15676 + struct bnep_conndel_req cd;
15677 + struct bnep_conninfo ci;
15678 + struct socket *nsock;
15681 + BT_DBG("cmd %x arg %lx", cmd, arg);
15684 + case BNEPCONNADD:
15685 + if (!capable(CAP_NET_ADMIN))
15688 + if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
15691 + nsock = sockfd_lookup(ca.sock, &err);
15695 + if (nsock->sk->state != BT_CONNECTED) {
15696 + fput(nsock->file);
15700 + err = bnep_add_connection(&ca, nsock);
15702 + if (copy_to_user((void *) arg, &ca, sizeof(ca)))
15705 + fput(nsock->file);
15709 + case BNEPCONNDEL:
15710 + if (!capable(CAP_NET_ADMIN))
15713 + if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
15716 + return bnep_del_connection(&cd);
15718 + case BNEPGETCONNLIST:
15719 + if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
15722 + if (cl.cnum <= 0)
15725 + err = bnep_get_connlist(&cl);
15726 + if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
15731 + case BNEPGETCONNINFO:
15732 + if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
15735 + err = bnep_get_conninfo(&ci);
15736 + if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
15748 +static struct proto_ops bnep_sock_ops = {
15749 + family: PF_BLUETOOTH,
15750 + release: bnep_sock_release,
15751 + ioctl: bnep_sock_ioctl,
15752 + bind: sock_no_bind,
15753 + getname: sock_no_getname,
15754 + sendmsg: sock_no_sendmsg,
15755 + recvmsg: sock_no_recvmsg,
15756 + poll: sock_no_poll,
15757 + listen: sock_no_listen,
15758 + shutdown: sock_no_shutdown,
15759 + setsockopt: sock_no_setsockopt,
15760 + getsockopt: sock_no_getsockopt,
15761 + connect: sock_no_connect,
15762 + socketpair: sock_no_socketpair,
15763 + accept: sock_no_accept,
15764 + mmap: sock_no_mmap
15767 +static int bnep_sock_create(struct socket *sock, int protocol)
15771 + BT_DBG("sock %p", sock);
15773 + if (sock->type != SOCK_RAW)
15774 + return -ESOCKTNOSUPPORT;
15776 + sock->ops = &bnep_sock_ops;
15778 + if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, 1)))
15781 + MOD_INC_USE_COUNT;
15783 + sock->state = SS_UNCONNECTED;
15784 + sock_init_data(sock, sk);
15786 + sk->destruct = NULL;
15787 + sk->protocol = protocol;
15792 +static struct net_proto_family bnep_sock_family_ops = {
15793 + family: PF_BLUETOOTH,
15794 + create: bnep_sock_create
15797 +int bnep_sock_init(void)
15799 + bluez_sock_register(BTPROTO_BNEP, &bnep_sock_family_ops);
15803 +int bnep_sock_cleanup(void)
15805 + if (bluez_sock_unregister(BTPROTO_BNEP))
15806 + BT_ERR("Can't unregister BNEP socket");
15809 diff -urN linux-2.4.18/net/bluetooth/cmtp/capi.c linux-2.4.18-mh15/net/bluetooth/cmtp/capi.c
15810 --- linux-2.4.18/net/bluetooth/cmtp/capi.c 1970-01-01 01:00:00.000000000 +0100
15811 +++ linux-2.4.18-mh15/net/bluetooth/cmtp/capi.c 2004-08-01 16:26:23.000000000 +0200
15814 + CMTP implementation for Linux Bluetooth stack (BlueZ).
15815 + Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
15817 + This program is free software; you can redistribute it and/or modify
15818 + it under the terms of the GNU General Public License version 2 as
15819 + published by the Free Software Foundation;
15821 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15822 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15823 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
15824 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
15825 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
15826 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15827 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15828 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15830 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
15831 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
15832 + SOFTWARE IS DISCLAIMED.
15835 +#include <linux/config.h>
15836 +#include <linux/module.h>
15838 +#include <linux/types.h>
15839 +#include <linux/errno.h>
15840 +#include <linux/kernel.h>
15841 +#include <linux/major.h>
15842 +#include <linux/sched.h>
15843 +#include <linux/slab.h>
15844 +#include <linux/poll.h>
15845 +#include <linux/fcntl.h>
15846 +#include <linux/skbuff.h>
15847 +#include <linux/socket.h>
15848 +#include <linux/ioctl.h>
15849 +#include <linux/file.h>
15850 +#include <net/sock.h>
15852 +#include <linux/capi.h>
15854 +#include "../drivers/isdn/avmb1/capilli.h"
15855 +#include "../drivers/isdn/avmb1/capicmd.h"
15856 +#include "../drivers/isdn/avmb1/capiutil.h"
15860 +#ifndef CONFIG_BLUEZ_CMTP_DEBUG
15862 +#define BT_DBG(D...)
15865 +#define REVISION "1.0"
15867 +#define CAPI_INTEROPERABILITY 0x20
15869 +#define CAPI_INTEROPERABILITY_REQ CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
15870 +#define CAPI_INTEROPERABILITY_CONF CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
15871 +#define CAPI_INTEROPERABILITY_IND CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
15872 +#define CAPI_INTEROPERABILITY_RESP CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
15874 +#define CAPI_INTEROPERABILITY_REQ_LEN (CAPI_MSG_BASELEN + 2)
15875 +#define CAPI_INTEROPERABILITY_CONF_LEN (CAPI_MSG_BASELEN + 4)
15876 +#define CAPI_INTEROPERABILITY_IND_LEN (CAPI_MSG_BASELEN + 2)
15877 +#define CAPI_INTEROPERABILITY_RESP_LEN (CAPI_MSG_BASELEN + 2)
15879 +#define CAPI_FUNCTION_REGISTER 0
15880 +#define CAPI_FUNCTION_RELEASE 1
15881 +#define CAPI_FUNCTION_GET_PROFILE 2
15882 +#define CAPI_FUNCTION_GET_MANUFACTURER 3
15883 +#define CAPI_FUNCTION_GET_VERSION 4
15884 +#define CAPI_FUNCTION_GET_SERIAL_NUMBER 5
15885 +#define CAPI_FUNCTION_MANUFACTURER 6
15886 +#define CAPI_FUNCTION_LOOPBACK 7
15888 +static struct capi_driver_interface *di;
15891 +#define CMTP_MSGNUM 1
15892 +#define CMTP_APPLID 2
15893 +#define CMTP_MAPPING 3
15895 +static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
15897 + struct cmtp_application *app = kmalloc(sizeof(*app), GFP_KERNEL);
15899 + BT_DBG("session %p application %p appl %d", session, app, appl);
15904 + memset(app, 0, sizeof(*app));
15906 + app->state = BT_OPEN;
15907 + app->appl = appl;
15909 + list_add_tail(&app->list, &session->applications);
15914 +static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
15916 + BT_DBG("session %p application %p", session, app);
15919 + list_del(&app->list);
15924 +static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
15926 + struct cmtp_application *app;
15927 + struct list_head *p, *n;
15929 + list_for_each_safe(p, n, &session->applications) {
15930 + app = list_entry(p, struct cmtp_application, list);
15931 + switch (pattern) {
15932 + case CMTP_MSGNUM:
15933 + if (app->msgnum == value)
15936 + case CMTP_APPLID:
15937 + if (app->appl == value)
15940 + case CMTP_MAPPING:
15941 + if (app->mapping == value)
15950 +static int cmtp_msgnum_get(struct cmtp_session *session)
15952 + session->msgnum++;
15954 + if ((session->msgnum & 0xff) > 200)
15955 + session->msgnum = CMTP_INITIAL_MSGNUM + 1;
15957 + return session->msgnum;
15961 +static void cmtp_send_interopmsg(struct cmtp_session *session,
15962 + __u8 subcmd, __u16 appl, __u16 msgnum,
15963 + __u16 function, unsigned char *buf, int len)
15965 + struct sk_buff *skb;
15966 + unsigned char *s;
15968 + BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum);
15970 + if (!(skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC))) {
15971 + BT_ERR("Can't allocate memory for interoperability packet");
15975 + s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
15977 + capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
15978 + capimsg_setu16(s, 2, appl);
15979 + capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
15980 + capimsg_setu8 (s, 5, subcmd);
15981 + capimsg_setu16(s, 6, msgnum);
15983 + /* Interoperability selector (Bluetooth Device Management) */
15984 + capimsg_setu16(s, 8, 0x0001);
15986 + capimsg_setu8 (s, 10, 3 + len);
15987 + capimsg_setu16(s, 11, function);
15988 + capimsg_setu8 (s, 13, len);
15991 + memcpy(s + 14, buf, len);
15993 + cmtp_send_capimsg(session, skb);
15996 +static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
15998 + struct capi_ctr *ctrl = session->ctrl;
15999 + struct cmtp_application *application;
16000 + __u16 appl, msgnum, func, info;
16001 + __u32 controller;
16003 + BT_DBG("session %p skb %p len %d", session, skb, skb->len);
16005 + switch (CAPIMSG_SUBCOMMAND(skb->data)) {
16007 + func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
16008 + info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
16011 + case CAPI_FUNCTION_REGISTER:
16012 + msgnum = CAPIMSG_MSGID(skb->data);
16014 + application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
16015 + if (application) {
16016 + application->state = BT_CONNECTED;
16017 + application->msgnum = 0;
16018 + application->mapping = CAPIMSG_APPID(skb->data);
16019 + wake_up_interruptible(&session->wait);
16024 + case CAPI_FUNCTION_RELEASE:
16025 + appl = CAPIMSG_APPID(skb->data);
16027 + application = cmtp_application_get(session, CMTP_MAPPING, appl);
16028 + if (application) {
16029 + application->state = BT_CLOSED;
16030 + application->msgnum = 0;
16031 + wake_up_interruptible(&session->wait);
16036 + case CAPI_FUNCTION_GET_PROFILE:
16037 + controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
16038 + msgnum = CAPIMSG_MSGID(skb->data);
16040 + if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
16041 + session->ncontroller = controller;
16042 + wake_up_interruptible(&session->wait);
16046 + if (!info && ctrl) {
16047 + memcpy(&ctrl->profile,
16048 + skb->data + CAPI_MSG_BASELEN + 11,
16049 + sizeof(capi_profile));
16050 + session->state = BT_CONNECTED;
16051 + ctrl->ready(ctrl);
16056 + case CAPI_FUNCTION_GET_MANUFACTURER:
16057 + controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);
16059 + if (!info && ctrl) {
16060 + strncpy(ctrl->manu,
16061 + skb->data + CAPI_MSG_BASELEN + 15,
16062 + skb->data[CAPI_MSG_BASELEN + 14]);
16067 + case CAPI_FUNCTION_GET_VERSION:
16068 + controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
16070 + if (!info && ctrl) {
16071 + ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
16072 + ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
16073 + ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
16074 + ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
16079 + case CAPI_FUNCTION_GET_SERIAL_NUMBER:
16080 + controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
16082 + if (!info && ctrl) {
16083 + memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
16084 + strncpy(ctrl->serial,
16085 + skb->data + CAPI_MSG_BASELEN + 17,
16086 + skb->data[CAPI_MSG_BASELEN + 16]);
16095 + func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
16097 + if (func == CAPI_FUNCTION_LOOPBACK) {
16098 + appl = CAPIMSG_APPID(skb->data);
16099 + msgnum = CAPIMSG_MSGID(skb->data);
16100 + cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
16101 + skb->data + CAPI_MSG_BASELEN + 6,
16102 + skb->data[CAPI_MSG_BASELEN + 5]);
16111 +void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
16113 + struct capi_ctr *ctrl = session->ctrl;
16114 + struct cmtp_application *application;
16115 + __u16 cmd, appl, info;
16116 + __u32 ncci, contr;
16118 + BT_DBG("session %p skb %p len %d", session, skb, skb->len);
16120 + if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
16121 + cmtp_recv_interopmsg(session, skb);
16125 + if (session->flags & (1 << CMTP_LOOPBACK)) {
16130 + cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data));
16131 + appl = CAPIMSG_APPID(skb->data);
16132 + contr = CAPIMSG_CONTROL(skb->data);
16134 + application = cmtp_application_get(session, CMTP_MAPPING, appl);
16135 + if (application) {
16136 + appl = application->appl;
16137 + CAPIMSG_SETAPPID(skb->data, appl);
16139 + BT_ERR("Can't find application with id %d", appl);
16144 + if ((contr & 0x7f) == 0x01) {
16145 + contr = (contr & 0xffffff80) | session->num;
16146 + CAPIMSG_SETCONTROL(skb->data, contr);
16150 + BT_ERR("Can't find controller %d for message", session->num);
16156 + case CAPI_CONNECT_B3_CONF:
16157 + ncci = CAPIMSG_NCCI(skb->data);
16158 + info = CAPIMSG_U16(skb->data, 12);
16160 + BT_DBG("CONNECT_B3_CONF ncci 0x%02x info 0x%02x", ncci, info);
16163 + ctrl->new_ncci(ctrl, appl, ncci, 8);
16165 + ctrl->handle_capimsg(ctrl, appl, skb);
16168 + case CAPI_CONNECT_B3_IND:
16169 + ncci = CAPIMSG_NCCI(skb->data);
16171 + BT_DBG("CONNECT_B3_IND ncci 0x%02x", ncci);
16173 + ctrl->new_ncci(ctrl, appl, ncci, 8);
16174 + ctrl->handle_capimsg(ctrl, appl, skb);
16177 + case CAPI_DISCONNECT_B3_IND:
16178 + ncci = CAPIMSG_NCCI(skb->data);
16180 + BT_DBG("DISCONNECT_B3_IND ncci 0x%02x", ncci);
16182 + if (ncci == 0xffffffff)
16183 + BT_ERR("DISCONNECT_B3_IND with ncci 0xffffffff");
16185 + ctrl->handle_capimsg(ctrl, appl, skb);
16186 + ctrl->free_ncci(ctrl, appl, ncci);
16190 + ctrl->handle_capimsg(ctrl, appl, skb);
16195 +void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
16197 + struct cmtp_scb *scb = (void *) skb->cb;
16199 + BT_DBG("session %p skb %p len %d", session, skb, skb->len);
16202 + scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
16204 + skb_queue_tail(&session->transmit, skb);
16206 + cmtp_schedule(session);
16210 +static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
16212 + BT_DBG("ctrl %p data %p", ctrl, data);
16217 +static void cmtp_reset_ctr(struct capi_ctr *ctrl)
16219 + BT_DBG("ctrl %p", ctrl);
16221 + ctrl->reseted(ctrl);
16224 +static void cmtp_remove_ctr(struct capi_ctr *ctrl)
16226 + struct cmtp_session *session = ctrl->driverdata;
16228 + BT_DBG("ctrl %p", ctrl);
16230 + ctrl->suspend_output(ctrl);
16232 + atomic_inc(&session->terminate);
16233 + cmtp_schedule(session);
16236 +static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
16238 + DECLARE_WAITQUEUE(wait, current);
16239 + struct cmtp_session *session = ctrl->driverdata;
16240 + struct cmtp_application *application;
16241 + unsigned long timeo = CMTP_INTEROP_TIMEOUT;
16242 + unsigned char buf[8];
16243 + int err = 0, nconn, want = rp->level3cnt;
16245 + BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
16246 + ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
16248 + application = cmtp_application_add(session, appl);
16249 + if (!application) {
16250 + BT_ERR("Can't allocate memory for new application");
16251 + ctrl->appl_released(ctrl, appl);
16256 + nconn = ctrl->profile.nbchannel * -want;
16261 + nconn = ctrl->profile.nbchannel;
16263 + capimsg_setu16(buf, 0, nconn);
16264 + capimsg_setu16(buf, 2, rp->datablkcnt);
16265 + capimsg_setu16(buf, 4, rp->datablklen);
16267 + application->state = BT_CONFIG;
16268 + application->msgnum = cmtp_msgnum_get(session);
16270 + cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
16271 + CAPI_FUNCTION_REGISTER, buf, 6);
16273 + add_wait_queue(&session->wait, &wait);
16275 + set_current_state(TASK_INTERRUPTIBLE);
16282 + if (application->state == BT_CLOSED) {
16283 + err = -application->err;
16287 + if (application->state == BT_CONNECTED)
16290 + if (signal_pending(current)) {
16295 + timeo = schedule_timeout(timeo);
16297 + set_current_state(TASK_RUNNING);
16298 + remove_wait_queue(&session->wait, &wait);
16301 + ctrl->appl_released(ctrl, appl);
16302 + cmtp_application_del(session, application);
16306 + ctrl->appl_registered(ctrl, appl);
16309 +static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
16311 + DECLARE_WAITQUEUE(wait, current);
16312 + struct cmtp_session *session = ctrl->driverdata;
16313 + struct cmtp_application *application;
16314 + unsigned long timeo = CMTP_INTEROP_TIMEOUT;
16316 + BT_DBG("ctrl %p appl %d", ctrl, appl);
16318 + application = cmtp_application_get(session, CMTP_APPLID, appl);
16319 + if (!application) {
16320 + BT_ERR("Can't find application");
16324 + application->msgnum = cmtp_msgnum_get(session);
16326 + cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
16327 + CAPI_FUNCTION_RELEASE, NULL, 0);
16329 + add_wait_queue(&session->wait, &wait);
16331 + set_current_state(TASK_INTERRUPTIBLE);
16333 + if (application->state == BT_CLOSED)
16336 + if (signal_pending(current))
16339 + timeo = schedule_timeout(timeo);
16341 + set_current_state(TASK_RUNNING);
16342 + remove_wait_queue(&session->wait, &wait);
16344 + cmtp_application_del(session, application);
16345 + ctrl->appl_released(ctrl, appl);
16348 +static void cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
16350 + struct cmtp_session *session = ctrl->driverdata;
16351 + struct cmtp_application *application;
16355 + BT_DBG("ctrl %p skb %p", ctrl, skb);
16357 + appl = CAPIMSG_APPID(skb->data);
16358 + contr = CAPIMSG_CONTROL(skb->data);
16360 + application = cmtp_application_get(session, CMTP_APPLID, appl);
16361 + if ((!application) || (application->state != BT_CONNECTED)) {
16362 + BT_ERR("Can't find application with id %d", appl);
16367 + CAPIMSG_SETAPPID(skb->data, application->mapping);
16369 + if ((contr & 0x7f) == session->num) {
16370 + contr = (contr & 0xffffff80) | 0x01;
16371 + CAPIMSG_SETCONTROL(skb->data, contr);
16374 + cmtp_send_capimsg(session, skb);
16377 +static char *cmtp_procinfo(struct capi_ctr *ctrl)
16379 + return "CAPI Message Transport Protocol";
16382 +static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl)
16384 + struct cmtp_session *session = ctrl->driverdata;
16385 + struct cmtp_application *app;
16386 + struct list_head *p, *n;
16389 + len += sprintf(page + len, "%s (Revision %s)\n\n", cmtp_procinfo(ctrl), REVISION);
16390 + len += sprintf(page + len, "addr %s\n", session->name);
16391 + len += sprintf(page + len, "ctrl %d\n", session->num);
16393 + list_for_each_safe(p, n, &session->applications) {
16394 + app = list_entry(p, struct cmtp_application, list);
16395 + len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping);
16398 + if (off + count >= len)
16404 + *start = page + off;
16406 + return ((count < len - off) ? count : len - off);
16409 +static struct capi_driver cmtp_driver = {
16411 + revision: REVISION,
16412 + load_firmware: cmtp_load_firmware,
16413 + reset_ctr: cmtp_reset_ctr,
16414 + remove_ctr: cmtp_remove_ctr,
16415 + register_appl: cmtp_register_appl,
16416 + release_appl: cmtp_release_appl,
16417 + send_message: cmtp_send_message,
16418 + procinfo: cmtp_procinfo,
16419 + ctr_read_proc: cmtp_ctr_read_proc,
16421 + driver_read_proc: 0,
16426 +int cmtp_attach_device(struct cmtp_session *session)
16428 + DECLARE_WAITQUEUE(wait, current);
16429 + unsigned long timeo = CMTP_INTEROP_TIMEOUT;
16430 + unsigned char buf[4];
16432 + BT_DBG("session %p", session);
16434 + capimsg_setu32(buf, 0, 0);
16436 + cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
16437 + CAPI_FUNCTION_GET_PROFILE, buf, 4);
16439 + add_wait_queue(&session->wait, &wait);
16441 + set_current_state(TASK_INTERRUPTIBLE);
16443 + if (session->ncontroller)
16446 + if (signal_pending(current))
16449 + timeo = schedule_timeout(timeo);
16451 + set_current_state(TASK_RUNNING);
16452 + remove_wait_queue(&session->wait, &wait);
16454 + BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
16457 + return -ETIMEDOUT;
16459 + if (!session->ncontroller)
16463 + if (session->ncontroller > 1)
16464 + BT_INFO("Setting up only CAPI controller 1");
16466 + if (!(session->ctrl = di->attach_ctr(&cmtp_driver, session->name, session))) {
16467 + BT_ERR("Can't attach new controller");
16471 + session->num = session->ctrl->cnr;
16473 + BT_DBG("session %p ctrl %p num %d", session, session->ctrl, session->num);
16475 + capimsg_setu32(buf, 0, 1);
16477 + cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
16478 + CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
16480 + cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
16481 + CAPI_FUNCTION_GET_VERSION, buf, 4);
16483 + cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
16484 + CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
16486 + cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
16487 + CAPI_FUNCTION_GET_PROFILE, buf, 4);
16492 +void cmtp_detach_device(struct cmtp_session *session)
16494 + struct capi_ctr *ctrl = session->ctrl;
16496 + BT_DBG("session %p ctrl %p", session, ctrl);
16501 + ctrl->reseted(ctrl);
16503 + di->detach_ctr(ctrl);
16506 +int cmtp_init_capi(void)
16508 + if (!(di = attach_capi_driver(&cmtp_driver))) {
16509 + BT_ERR("Can't attach CAPI driver");
16516 +void cmtp_cleanup_capi(void)
16518 + detach_capi_driver(&cmtp_driver);
16520 diff -urN linux-2.4.18/net/bluetooth/cmtp/cmtp.h linux-2.4.18-mh15/net/bluetooth/cmtp/cmtp.h
16521 --- linux-2.4.18/net/bluetooth/cmtp/cmtp.h 1970-01-01 01:00:00.000000000 +0100
16522 +++ linux-2.4.18-mh15/net/bluetooth/cmtp/cmtp.h 2004-08-01 16:26:23.000000000 +0200
16525 + CMTP implementation for Linux Bluetooth stack (BlueZ).
16526 + Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
16528 + This program is free software; you can redistribute it and/or modify
16529 + it under the terms of the GNU General Public License version 2 as
16530 + published by the Free Software Foundation;
16532 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16533 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16534 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
16535 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
16536 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16537 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16538 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16539 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16541 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
16542 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
16543 + SOFTWARE IS DISCLAIMED.
16549 +#include <linux/types.h>
16550 +#include <net/bluetooth/bluetooth.h>
16552 +#define BTNAMSIZ 18
16554 +/* CMTP ioctl defines */
16555 +#define CMTPCONNADD _IOW('C', 200, int)
16556 +#define CMTPCONNDEL _IOW('C', 201, int)
16557 +#define CMTPGETCONNLIST _IOR('C', 210, int)
16558 +#define CMTPGETCONNINFO _IOR('C', 211, int)
16560 +#define CMTP_LOOPBACK 0
16562 +struct cmtp_connadd_req {
16563 + int sock; // Connected socket
16567 +struct cmtp_conndel_req {
16572 +struct cmtp_conninfo {
16579 +struct cmtp_connlist_req {
16581 + struct cmtp_conninfo *ci;
16584 +int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock);
16585 +int cmtp_del_connection(struct cmtp_conndel_req *req);
16586 +int cmtp_get_connlist(struct cmtp_connlist_req *req);
16587 +int cmtp_get_conninfo(struct cmtp_conninfo *ci);
16589 +/* CMTP session defines */
16590 +#define CMTP_INTEROP_TIMEOUT (HZ * 5)
16591 +#define CMTP_INITIAL_MSGNUM 0xff00
16593 +struct cmtp_session {
16594 + struct list_head list;
16596 + struct socket *sock;
16600 + unsigned long state;
16601 + unsigned long flags;
16605 + char name[BTNAMSIZ];
16607 + atomic_t terminate;
16609 + wait_queue_head_t wait;
16613 + struct capi_ctr *ctrl;
16615 + struct list_head applications;
16617 + unsigned long blockids;
16620 + struct sk_buff_head transmit;
16622 + struct sk_buff *reassembly[16];
16625 +struct cmtp_application {
16626 + struct list_head list;
16628 + unsigned long state;
16642 +int cmtp_attach_device(struct cmtp_session *session);
16643 +void cmtp_detach_device(struct cmtp_session *session);
16645 +void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb);
16646 +void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb);
16648 +static inline void cmtp_schedule(struct cmtp_session *session)
16650 + struct sock *sk = session->sock->sk;
16652 + wake_up_interruptible(sk->sleep);
16655 +/* CMTP init defines */
16656 +int cmtp_init_capi(void);
16657 +int cmtp_init_sockets(void);
16658 +void cmtp_cleanup_capi(void);
16659 +void cmtp_cleanup_sockets(void);
16661 +#endif /* __CMTP_H */
16662 diff -urN linux-2.4.18/net/bluetooth/cmtp/Config.in linux-2.4.18-mh15/net/bluetooth/cmtp/Config.in
16663 --- linux-2.4.18/net/bluetooth/cmtp/Config.in 1970-01-01 01:00:00.000000000 +0100
16664 +++ linux-2.4.18-mh15/net/bluetooth/cmtp/Config.in 2004-08-01 16:26:23.000000000 +0200
16667 +# Bluetooth CMTP layer configuration
16670 +if [ "$CONFIG_ISDN" = "y" -o "$CONFIG_ISDN" = "m" ]; then
16671 + dep_tristate 'CMTP protocol support' CONFIG_BLUEZ_CMTP $CONFIG_ISDN_CAPI $CONFIG_BLUEZ_L2CAP
16673 diff -urN linux-2.4.18/net/bluetooth/cmtp/core.c linux-2.4.18-mh15/net/bluetooth/cmtp/core.c
16674 --- linux-2.4.18/net/bluetooth/cmtp/core.c 1970-01-01 01:00:00.000000000 +0100
16675 +++ linux-2.4.18-mh15/net/bluetooth/cmtp/core.c 2004-08-01 16:26:23.000000000 +0200
16678 + CMTP implementation for Linux Bluetooth stack (BlueZ).
16679 + Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
16681 + This program is free software; you can redistribute it and/or modify
16682 + it under the terms of the GNU General Public License version 2 as
16683 + published by the Free Software Foundation;
16685 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16686 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16687 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
16688 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
16689 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16690 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16691 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16692 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16694 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
16695 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
16696 + SOFTWARE IS DISCLAIMED.
16699 +#include <linux/config.h>
16700 +#include <linux/module.h>
16702 +#include <linux/types.h>
16703 +#include <linux/errno.h>
16704 +#include <linux/kernel.h>
16705 +#include <linux/major.h>
16706 +#include <linux/sched.h>
16707 +#include <linux/slab.h>
16708 +#include <linux/poll.h>
16709 +#include <linux/fcntl.h>
16710 +#include <linux/skbuff.h>
16711 +#include <linux/socket.h>
16712 +#include <linux/ioctl.h>
16713 +#include <linux/file.h>
16714 +#include <linux/init.h>
16715 +#include <net/sock.h>
16717 +#include <net/bluetooth/bluetooth.h>
16718 +#include <net/bluetooth/l2cap.h>
16722 +#ifndef CONFIG_BLUEZ_CMTP_DEBUG
16724 +#define BT_DBG(D...)
16727 +#define VERSION "1.0"
16729 +static DECLARE_RWSEM(cmtp_session_sem);
16730 +static LIST_HEAD(cmtp_session_list);
16732 +static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr)
16734 + struct cmtp_session *session;
16735 + struct list_head *p;
16739 + list_for_each(p, &cmtp_session_list) {
16740 + session = list_entry(p, struct cmtp_session, list);
16741 + if (!bacmp(bdaddr, &session->bdaddr))
16747 +static void __cmtp_link_session(struct cmtp_session *session)
16749 + MOD_INC_USE_COUNT;
16750 + list_add(&session->list, &cmtp_session_list);
16753 +static void __cmtp_unlink_session(struct cmtp_session *session)
16755 + list_del(&session->list);
16756 + MOD_DEC_USE_COUNT;
16759 +static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci)
16761 + bacpy(&ci->bdaddr, &session->bdaddr);
16763 + ci->flags = session->flags;
16764 + ci->state = session->state;
16766 + ci->num = session->num;
16770 +static inline int cmtp_alloc_block_id(struct cmtp_session *session)
16774 + for (i = 0; i < 16; i++)
16775 + if (!test_and_set_bit(i, &session->blockids)) {
16783 +static inline void cmtp_free_block_id(struct cmtp_session *session, int id)
16785 + clear_bit(id, &session->blockids);
16788 +static inline void cmtp_add_msgpart(struct cmtp_session *session, int id, const unsigned char *buf, int count)
16790 + struct sk_buff *skb = session->reassembly[id], *nskb;
16793 + BT_DBG("session %p buf %p count %d", session, buf, count);
16795 + size = (skb) ? skb->len + count : count;
16797 + if (!(nskb = alloc_skb(size, GFP_ATOMIC))) {
16798 + BT_ERR("Can't allocate memory for CAPI message");
16802 + if (skb && (skb->len > 0))
16803 + memcpy(skb_put(nskb, skb->len), skb->data, skb->len);
16805 + memcpy(skb_put(nskb, count), buf, count);
16807 + session->reassembly[id] = nskb;
16813 +static inline int cmtp_recv_frame(struct cmtp_session *session, struct sk_buff *skb)
16815 + __u8 hdr, hdrlen, id;
16818 + BT_DBG("session %p skb %p len %d", session, skb, skb->len);
16820 + while (skb->len > 0) {
16821 + hdr = skb->data[0];
16823 + switch (hdr & 0xc0) {
16826 + len = skb->data[1];
16830 + len = skb->data[1] | (skb->data[2] << 8);
16838 + id = (hdr & 0x3c) >> 2;
16840 + BT_DBG("hdr 0x%02x hdrlen %d len %d id %d", hdr, hdrlen, len, id);
16842 + if (hdrlen + len > skb->len) {
16843 + BT_ERR("Wrong size or header information in CMTP frame");
16848 + skb_pull(skb, hdrlen);
16852 + switch (hdr & 0x03) {
16854 + cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
16855 + cmtp_recv_capimsg(session, session->reassembly[id]);
16856 + session->reassembly[id] = NULL;
16859 + cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
16862 + if (session->reassembly[id] != NULL)
16863 + kfree_skb(session->reassembly[id]);
16864 + session->reassembly[id] = NULL;
16868 + skb_pull(skb, hdrlen + len);
16875 +static int cmtp_send_frame(struct cmtp_session *session, unsigned char *data, int len)
16877 + struct socket *sock = session->sock;
16878 + struct iovec iv = { data, len };
16879 + struct msghdr msg;
16882 + BT_DBG("session %p data %p len %d", session, data, len);
16887 + memset(&msg, 0, sizeof(msg));
16888 + msg.msg_iovlen = 1;
16889 + msg.msg_iov = &iv;
16891 + err = sock->ops->sendmsg(sock, &msg, len, 0);
16895 +static int cmtp_process_transmit(struct cmtp_session *session)
16897 + struct sk_buff *skb, *nskb;
16898 + unsigned char *hdr;
16899 + unsigned int size, tail;
16901 + BT_DBG("session %p", session);
16903 + if (!(nskb = alloc_skb(session->mtu, GFP_ATOMIC))) {
16904 + BT_ERR("Can't allocate memory for new frame");
16908 + while ((skb = skb_dequeue(&session->transmit))) {
16909 + struct cmtp_scb *scb = (void *) skb->cb;
16911 + if ((tail = (session->mtu - nskb->len)) < 5) {
16912 + cmtp_send_frame(session, nskb->data, nskb->len);
16913 + skb_trim(nskb, 0);
16914 + tail = session->mtu;
16917 + size = min_t(uint, ((tail < 258) ? (tail - 2) : (tail - 3)), skb->len);
16919 + if ((scb->id < 0) && ((scb->id = cmtp_alloc_block_id(session)) < 0)) {
16920 + skb_queue_head(&session->transmit, skb);
16924 + if (size < 256) {
16925 + hdr = skb_put(nskb, 2);
16927 + | ((scb->id << 2) & 0x3c)
16928 + | ((skb->len == size) ? 0x00 : 0x01);
16931 + hdr = skb_put(nskb, 3);
16933 + | ((scb->id << 2) & 0x3c)
16934 + | ((skb->len == size) ? 0x00 : 0x01);
16935 + hdr[1] = size & 0xff;
16936 + hdr[2] = size >> 8;
16939 + memcpy(skb_put(nskb, size), skb->data, size);
16940 + skb_pull(skb, size);
16942 + if (skb->len > 0) {
16943 + skb_queue_head(&session->transmit, skb);
16945 + cmtp_free_block_id(session, scb->id);
16947 + cmtp_send_frame(session, nskb->data, nskb->len);
16948 + skb_trim(nskb, 0);
16954 + cmtp_send_frame(session, nskb->data, nskb->len);
16958 + return skb_queue_len(&session->transmit);
16961 +static int cmtp_session(void *arg)
16963 + struct cmtp_session *session = arg;
16964 + struct sock *sk = session->sock->sk;
16965 + struct sk_buff *skb;
16966 + wait_queue_t wait;
16968 + BT_DBG("session %p", session);
16970 + daemonize(); reparent_to_init();
16972 + sprintf(current->comm, "kcmtpd_ctr_%d", session->num);
16974 + sigfillset(¤t->blocked);
16975 + flush_signals(current);
16977 + current->nice = -15;
16979 + set_fs(KERNEL_DS);
16981 + init_waitqueue_entry(&wait, current);
16982 + add_wait_queue(sk->sleep, &wait);
16983 + while (!atomic_read(&session->terminate)) {
16984 + set_current_state(TASK_INTERRUPTIBLE);
16986 + if (sk->state != BT_CONNECTED)
16989 + while ((skb = skb_dequeue(&sk->receive_queue))) {
16991 + cmtp_recv_frame(session, skb);
16994 + cmtp_process_transmit(session);
16998 + set_current_state(TASK_RUNNING);
16999 + remove_wait_queue(sk->sleep, &wait);
17001 + down_write(&cmtp_session_sem);
17003 + if (!(session->flags & (1 << CMTP_LOOPBACK)))
17004 + cmtp_detach_device(session);
17006 + fput(session->sock->file);
17008 + __cmtp_unlink_session(session);
17010 + up_write(&cmtp_session_sem);
17016 +int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
17018 + struct cmtp_session *session, *s;
17019 + bdaddr_t src, dst;
17024 + baswap(&src, &bluez_pi(sock->sk)->src);
17025 + baswap(&dst, &bluez_pi(sock->sk)->dst);
17027 + session = kmalloc(sizeof(struct cmtp_session), GFP_KERNEL);
17030 + memset(session, 0, sizeof(struct cmtp_session));
17032 + down_write(&cmtp_session_sem);
17034 + s = __cmtp_get_session(&bluez_pi(sock->sk)->dst);
17035 + if (s && s->state == BT_CONNECTED) {
17040 + bacpy(&session->bdaddr, &bluez_pi(sock->sk)->dst);
17042 + session->mtu = min_t(uint, l2cap_pi(sock->sk)->omtu, l2cap_pi(sock->sk)->imtu);
17044 + BT_DBG("mtu %d", session->mtu);
17046 + sprintf(session->name, "%s", batostr(&dst));
17048 + session->sock = sock;
17049 + session->state = BT_CONFIG;
17051 + init_waitqueue_head(&session->wait);
17053 + session->ctrl = NULL;
17054 + session->msgnum = CMTP_INITIAL_MSGNUM;
17056 + INIT_LIST_HEAD(&session->applications);
17058 + skb_queue_head_init(&session->transmit);
17060 + for (i = 0; i < 16; i++)
17061 + session->reassembly[i] = NULL;
17063 + session->flags = req->flags;
17065 + __cmtp_link_session(session);
17067 + err = kernel_thread(cmtp_session, session, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
17071 + if (!(session->flags & (1 << CMTP_LOOPBACK))) {
17072 + err = cmtp_attach_device(session);
17077 + up_write(&cmtp_session_sem);
17081 + cmtp_detach_device(session);
17084 + __cmtp_unlink_session(session);
17087 + up_write(&cmtp_session_sem);
17092 +int cmtp_del_connection(struct cmtp_conndel_req *req)
17094 + struct cmtp_session *session;
17099 + down_read(&cmtp_session_sem);
17101 + session = __cmtp_get_session(&req->bdaddr);
17103 + /* Flush the transmit queue */
17104 + skb_queue_purge(&session->transmit);
17106 + /* Kill session thread */
17107 + atomic_inc(&session->terminate);
17108 + cmtp_schedule(session);
17112 + up_read(&cmtp_session_sem);
17116 +int cmtp_get_connlist(struct cmtp_connlist_req *req)
17118 + struct list_head *p;
17119 + int err = 0, n = 0;
17123 + down_read(&cmtp_session_sem);
17125 + list_for_each(p, &cmtp_session_list) {
17126 + struct cmtp_session *session;
17127 + struct cmtp_conninfo ci;
17129 + session = list_entry(p, struct cmtp_session, list);
17131 + __cmtp_copy_session(session, &ci);
17133 + if (copy_to_user(req->ci, &ci, sizeof(ci))) {
17138 + if (++n >= req->cnum)
17145 + up_read(&cmtp_session_sem);
17149 +int cmtp_get_conninfo(struct cmtp_conninfo *ci)
17151 + struct cmtp_session *session;
17154 + down_read(&cmtp_session_sem);
17156 + session = __cmtp_get_session(&ci->bdaddr);
17158 + __cmtp_copy_session(session, ci);
17162 + up_read(&cmtp_session_sem);
17167 +int __init init_cmtp(void)
17171 + cmtp_init_capi();
17172 + cmtp_init_sockets();
17174 + BT_INFO("BlueZ CMTP ver %s", VERSION);
17175 + BT_INFO("Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>");
17180 +void __exit exit_cmtp(void)
17182 + cmtp_cleanup_sockets();
17183 + cmtp_cleanup_capi();
17186 +module_init(init_cmtp);
17187 +module_exit(exit_cmtp);
17189 +MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
17190 +MODULE_DESCRIPTION("BlueZ CMTP ver " VERSION);
17191 +MODULE_LICENSE("GPL");
17192 diff -urN linux-2.4.18/net/bluetooth/cmtp/Makefile linux-2.4.18-mh15/net/bluetooth/cmtp/Makefile
17193 --- linux-2.4.18/net/bluetooth/cmtp/Makefile 1970-01-01 01:00:00.000000000 +0100
17194 +++ linux-2.4.18-mh15/net/bluetooth/cmtp/Makefile 2004-08-01 16:26:23.000000000 +0200
17197 +# Makefile for the Linux Bluetooth CMTP layer
17200 +O_TARGET := cmtp.o
17202 +obj-y := core.o sock.o capi.o
17203 +obj-m += $(O_TARGET)
17205 +include $(TOPDIR)/Rules.make
17206 diff -urN linux-2.4.18/net/bluetooth/cmtp/sock.c linux-2.4.18-mh15/net/bluetooth/cmtp/sock.c
17207 --- linux-2.4.18/net/bluetooth/cmtp/sock.c 1970-01-01 01:00:00.000000000 +0100
17208 +++ linux-2.4.18-mh15/net/bluetooth/cmtp/sock.c 2004-08-01 16:26:23.000000000 +0200
17211 + CMTP implementation for Linux Bluetooth stack (BlueZ).
17212 + Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
17214 + This program is free software; you can redistribute it and/or modify
17215 + it under the terms of the GNU General Public License version 2 as
17216 + published by the Free Software Foundation;
17218 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17219 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17220 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
17221 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
17222 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
17223 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17224 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17225 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17227 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
17228 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
17229 + SOFTWARE IS DISCLAIMED.
17232 +#include <linux/config.h>
17233 +#include <linux/module.h>
17235 +#include <linux/types.h>
17236 +#include <linux/errno.h>
17237 +#include <linux/kernel.h>
17238 +#include <linux/major.h>
17239 +#include <linux/sched.h>
17240 +#include <linux/slab.h>
17241 +#include <linux/poll.h>
17242 +#include <linux/fcntl.h>
17243 +#include <linux/skbuff.h>
17244 +#include <linux/socket.h>
17245 +#include <linux/ioctl.h>
17246 +#include <linux/file.h>
17247 +#include <net/sock.h>
17249 +#include <asm/system.h>
17250 +#include <asm/uaccess.h>
17254 +#ifndef CONFIG_BLUEZ_CMTP_DEBUG
17256 +#define BT_DBG(D...)
17259 +static int cmtp_sock_release(struct socket *sock)
17261 + struct sock *sk = sock->sk;
17263 + BT_DBG("sock %p sk %p", sock, sk);
17271 + MOD_DEC_USE_COUNT;
17275 +static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
17277 + struct cmtp_connadd_req ca;
17278 + struct cmtp_conndel_req cd;
17279 + struct cmtp_connlist_req cl;
17280 + struct cmtp_conninfo ci;
17281 + struct socket *nsock;
17284 + BT_DBG("cmd %x arg %lx", cmd, arg);
17287 + case CMTPCONNADD:
17288 + if (!capable(CAP_NET_ADMIN))
17291 + if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
17294 + nsock = sockfd_lookup(ca.sock, &err);
17298 + if (nsock->sk->state != BT_CONNECTED) {
17299 + fput(nsock->file);
17303 + err = cmtp_add_connection(&ca, nsock);
17305 + if (copy_to_user((void *) arg, &ca, sizeof(ca)))
17308 + fput(nsock->file);
17312 + case CMTPCONNDEL:
17313 + if (!capable(CAP_NET_ADMIN))
17316 + if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
17319 + return cmtp_del_connection(&cd);
17321 + case CMTPGETCONNLIST:
17322 + if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
17325 + if (cl.cnum <= 0)
17328 + err = cmtp_get_connlist(&cl);
17329 + if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
17334 + case CMTPGETCONNINFO:
17335 + if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
17338 + err = cmtp_get_conninfo(&ci);
17339 + if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
17348 +static struct proto_ops cmtp_sock_ops = {
17349 + family: PF_BLUETOOTH,
17350 + release: cmtp_sock_release,
17351 + ioctl: cmtp_sock_ioctl,
17352 + bind: sock_no_bind,
17353 + getname: sock_no_getname,
17354 + sendmsg: sock_no_sendmsg,
17355 + recvmsg: sock_no_recvmsg,
17356 + poll: sock_no_poll,
17357 + listen: sock_no_listen,
17358 + shutdown: sock_no_shutdown,
17359 + setsockopt: sock_no_setsockopt,
17360 + getsockopt: sock_no_getsockopt,
17361 + connect: sock_no_connect,
17362 + socketpair: sock_no_socketpair,
17363 + accept: sock_no_accept,
17364 + mmap: sock_no_mmap
17367 +static int cmtp_sock_create(struct socket *sock, int protocol)
17371 + BT_DBG("sock %p", sock);
17373 + if (sock->type != SOCK_RAW)
17374 + return -ESOCKTNOSUPPORT;
17376 + sock->ops = &cmtp_sock_ops;
17378 + if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, 1)))
17381 + MOD_INC_USE_COUNT;
17383 + sock->state = SS_UNCONNECTED;
17384 + sock_init_data(sock, sk);
17386 + sk->destruct = NULL;
17387 + sk->protocol = protocol;
17392 +static struct net_proto_family cmtp_sock_family_ops = {
17393 + family: PF_BLUETOOTH,
17394 + create: cmtp_sock_create
17397 +int cmtp_init_sockets(void)
17401 + if ((err = bluez_sock_register(BTPROTO_CMTP, &cmtp_sock_family_ops))) {
17402 + BT_ERR("Can't register CMTP socket layer (%d)", err);
17409 +void cmtp_cleanup_sockets(void)
17413 + if ((err = bluez_sock_unregister(BTPROTO_CMTP)))
17414 + BT_ERR("Can't unregister CMTP socket layer (%d)", err);
17418 diff -urN linux-2.4.18/net/bluetooth/Config.in linux-2.4.18-mh15/net/bluetooth/Config.in
17419 --- linux-2.4.18/net/bluetooth/Config.in 2001-06-12 04:15:27.000000000 +0200
17420 +++ linux-2.4.18-mh15/net/bluetooth/Config.in 2004-08-01 16:26:23.000000000 +0200
17423 -# Bluetooth configuration
17424 +# Bluetooth subsystem configuration
17427 if [ "$CONFIG_NET" != "n" ]; then
17429 mainmenu_option next_comment
17430 comment 'Bluetooth support'
17431 dep_tristate 'Bluetooth subsystem support' CONFIG_BLUEZ $CONFIG_NET
17433 if [ "$CONFIG_BLUEZ" != "n" ]; then
17434 dep_tristate 'L2CAP protocol support' CONFIG_BLUEZ_L2CAP $CONFIG_BLUEZ
17435 + dep_tristate 'SCO links support' CONFIG_BLUEZ_SCO $CONFIG_BLUEZ
17436 + source net/bluetooth/rfcomm/Config.in
17437 + source net/bluetooth/bnep/Config.in
17438 + source net/bluetooth/cmtp/Config.in
17439 + source net/bluetooth/hidp/Config.in
17440 source drivers/bluetooth/Config.in
17446 diff -urN linux-2.4.18/net/bluetooth/hci_conn.c linux-2.4.18-mh15/net/bluetooth/hci_conn.c
17447 --- linux-2.4.18/net/bluetooth/hci_conn.c 1970-01-01 01:00:00.000000000 +0100
17448 +++ linux-2.4.18-mh15/net/bluetooth/hci_conn.c 2004-08-01 16:26:23.000000000 +0200
17451 + BlueZ - Bluetooth protocol stack for Linux
17452 + Copyright (C) 2000-2001 Qualcomm Incorporated
17454 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
17456 + This program is free software; you can redistribute it and/or modify
17457 + it under the terms of the GNU General Public License version 2 as
17458 + published by the Free Software Foundation;
17460 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17461 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17462 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
17463 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
17464 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
17465 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17466 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17467 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17469 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
17470 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
17471 + SOFTWARE IS DISCLAIMED.
17475 + * HCI Connection handling.
17477 + * $Id: hci_conn.c,v 1.5 2002/07/17 18:46:25 maxk Exp $
17480 +#include <linux/config.h>
17481 +#include <linux/module.h>
17483 +#include <linux/types.h>
17484 +#include <linux/errno.h>
17485 +#include <linux/kernel.h>
17486 +#include <linux/major.h>
17487 +#include <linux/sched.h>
17488 +#include <linux/slab.h>
17489 +#include <linux/poll.h>
17490 +#include <linux/fcntl.h>
17491 +#include <linux/init.h>
17492 +#include <linux/skbuff.h>
17493 +#include <linux/interrupt.h>
17494 +#include <linux/notifier.h>
17495 +#include <net/sock.h>
17497 +#include <asm/system.h>
17498 +#include <asm/uaccess.h>
17499 +#include <asm/unaligned.h>
17501 +#include <net/bluetooth/bluetooth.h>
17502 +#include <net/bluetooth/hci_core.h>
17504 +#ifndef HCI_CORE_DEBUG
17506 +#define BT_DBG( A... )
17509 +void hci_acl_connect(struct hci_conn *conn)
17511 + struct hci_dev *hdev = conn->hdev;
17512 + struct inquiry_entry *ie;
17513 + create_conn_cp cp;
17515 + BT_DBG("%p", conn);
17517 + conn->state = BT_CONNECT;
17519 + conn->link_mode = HCI_LM_MASTER;
17521 + memset(&cp, 0, sizeof(cp));
17522 + bacpy(&cp.bdaddr, &conn->dst);
17523 + cp.pscan_rep_mode = 0x02;
17525 + if ((ie = inquiry_cache_lookup(hdev, &conn->dst)) &&
17526 + inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
17527 + cp.pscan_rep_mode = ie->info.pscan_rep_mode;
17528 + cp.pscan_mode = ie->info.pscan_mode;
17529 + cp.clock_offset = ie->info.clock_offset | __cpu_to_le16(0x8000);
17532 + cp.pkt_type = __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK);
17533 + if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
17534 + cp.role_switch = 0x01;
17536 + cp.role_switch = 0x00;
17538 + hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN,
17539 + CREATE_CONN_CP_SIZE, &cp);
17542 +void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
17544 + disconnect_cp cp;
17546 + BT_DBG("%p", conn);
17548 + conn->state = BT_DISCONN;
17550 + cp.handle = __cpu_to_le16(conn->handle);
17551 + cp.reason = reason;
17552 + hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT,
17553 + DISCONNECT_CP_SIZE, &cp);
17556 +void hci_add_sco(struct hci_conn *conn, __u16 handle)
17558 + struct hci_dev *hdev = conn->hdev;
17561 + BT_DBG("%p", conn);
17563 + conn->state = BT_CONNECT;
17566 + cp.pkt_type = __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
17567 + cp.handle = __cpu_to_le16(handle);
17569 + hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, ADD_SCO_CP_SIZE, &cp);
17572 +static void hci_conn_timeout(unsigned long arg)
17574 + struct hci_conn *conn = (void *)arg;
17575 + struct hci_dev *hdev = conn->hdev;
17577 + BT_DBG("conn %p state %d", conn, conn->state);
17579 + if (atomic_read(&conn->refcnt))
17582 + hci_dev_lock(hdev);
17583 + if (conn->state == BT_CONNECTED)
17584 + hci_acl_disconn(conn, 0x13);
17586 + conn->state = BT_CLOSED;
17587 + hci_dev_unlock(hdev);
17591 +static void hci_conn_init_timer(struct hci_conn *conn)
17593 + init_timer(&conn->timer);
17594 + conn->timer.function = hci_conn_timeout;
17595 + conn->timer.data = (unsigned long)conn;
17598 +struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
17600 + struct hci_conn *conn;
17602 + BT_DBG("%s dst %s", hdev->name, batostr(dst));
17604 + if (!(conn = kmalloc(sizeof(struct hci_conn), GFP_ATOMIC)))
17606 + memset(conn, 0, sizeof(struct hci_conn));
17608 + bacpy(&conn->dst, dst);
17609 + conn->type = type;
17610 + conn->hdev = hdev;
17611 + conn->state = BT_OPEN;
17613 + skb_queue_head_init(&conn->data_q);
17614 + hci_conn_init_timer(conn);
17616 + atomic_set(&conn->refcnt, 0);
17618 + hci_dev_hold(hdev);
17620 + tasklet_disable(&hdev->tx_task);
17621 + conn_hash_add(hdev, conn);
17622 + tasklet_enable(&hdev->tx_task);
17627 +int hci_conn_del(struct hci_conn *conn)
17629 + struct hci_dev *hdev = conn->hdev;
17631 + BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
17633 + hci_conn_del_timer(conn);
17635 + if (conn->type == SCO_LINK) {
17636 + struct hci_conn *acl = conn->link;
17638 + acl->link = NULL;
17639 + hci_conn_put(acl);
17642 + struct hci_conn *sco = conn->link;
17644 + sco->link = NULL;
17646 + /* Unacked frames */
17647 + hdev->acl_cnt += conn->sent;
17650 + tasklet_disable(&hdev->tx_task);
17651 + conn_hash_del(hdev, conn);
17652 + tasklet_enable(&hdev->tx_task);
17654 + skb_queue_purge(&conn->data_q);
17656 + hci_dev_put(hdev);
17662 +struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
17664 + int use_src = bacmp(src, BDADDR_ANY);
17665 + struct hci_dev *hdev = NULL;
17666 + struct list_head *p;
17668 + BT_DBG("%s -> %s", batostr(src), batostr(dst));
17670 + read_lock_bh(&hdev_list_lock);
17672 + list_for_each(p, &hdev_list) {
17673 + struct hci_dev *d;
17674 + d = list_entry(p, struct hci_dev, list);
17676 + if (!test_bit(HCI_UP, &d->flags))
17679 + /* Simple routing:
17680 + * No source address - find interface with bdaddr != dst
17681 + * Source address - find interface with bdaddr == src
17685 + if (!bacmp(&d->bdaddr, src)) {
17689 + if (bacmp(&d->bdaddr, dst)) {
17696 + hci_dev_hold(hdev);
17698 + read_unlock_bh(&hdev_list_lock);
17702 +/* Create SCO or ACL connection.
17703 + * Device _must_ be locked */
17704 +struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
17706 + struct hci_conn *acl;
17708 + BT_DBG("%s dst %s", hdev->name, batostr(dst));
17710 + if (!(acl = conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
17711 + if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
17715 + hci_conn_hold(acl);
17717 + if (acl->state == BT_OPEN || acl->state == BT_CLOSED)
17718 + hci_acl_connect(acl);
17720 + if (type == SCO_LINK) {
17721 + struct hci_conn *sco;
17723 + if (!(sco = conn_hash_lookup_ba(hdev, SCO_LINK, dst))) {
17724 + if (!(sco = hci_conn_add(hdev, SCO_LINK, dst))) {
17725 + hci_conn_put(acl);
17732 + hci_conn_hold(sco);
17734 + if (acl->state == BT_CONNECTED &&
17735 + (sco->state == BT_OPEN || sco->state == BT_CLOSED))
17736 + hci_add_sco(sco, acl->handle);
17744 +/* Authenticate remote device */
17745 +int hci_conn_auth(struct hci_conn *conn)
17747 + BT_DBG("conn %p", conn);
17749 + if (conn->link_mode & HCI_LM_AUTH)
17752 + if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
17753 + auth_requested_cp ar;
17754 + ar.handle = __cpu_to_le16(conn->handle);
17755 + hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_AUTH_REQUESTED,
17756 + AUTH_REQUESTED_CP_SIZE, &ar);
17761 +/* Enable encryption */
17762 +int hci_conn_encrypt(struct hci_conn *conn)
17764 + BT_DBG("conn %p", conn);
17766 + if (conn->link_mode & HCI_LM_ENCRYPT)
17769 + if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
17772 + if (hci_conn_auth(conn)) {
17773 + set_conn_encrypt_cp ce;
17774 + ce.handle = __cpu_to_le16(conn->handle);
17776 + hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT,
17777 + SET_CONN_ENCRYPT_CP_SIZE, &ce);
17782 +/* Drop all connection on the device */
17783 +void hci_conn_hash_flush(struct hci_dev *hdev)
17785 + struct conn_hash *h = &hdev->conn_hash;
17786 + struct list_head *p;
17788 + BT_DBG("hdev %s", hdev->name);
17790 + p = h->list.next;
17791 + while (p != &h->list) {
17792 + struct hci_conn *c;
17794 + c = list_entry(p, struct hci_conn, list);
17797 + c->state = BT_CLOSED;
17799 + hci_proto_disconn_ind(c, 0x16);
17804 +int hci_get_conn_list(unsigned long arg)
17806 + struct hci_conn_list_req req, *cl;
17807 + struct hci_conn_info *ci;
17808 + struct hci_dev *hdev;
17809 + struct list_head *p;
17810 + int n = 0, size, err;
17812 + if (copy_from_user(&req, (void *) arg, sizeof(req)))
17815 + if (!req.conn_num || req.conn_num > (PAGE_SIZE * 2) / sizeof(*ci))
17818 + size = sizeof(req) + req.conn_num * sizeof(*ci);
17820 + if (!(cl = (void *) kmalloc(size, GFP_KERNEL)))
17823 + if (!(hdev = hci_dev_get(req.dev_id))) {
17828 + ci = cl->conn_info;
17830 + hci_dev_lock_bh(hdev);
17831 + list_for_each(p, &hdev->conn_hash.list) {
17832 + register struct hci_conn *c;
17833 + c = list_entry(p, struct hci_conn, list);
17835 + bacpy(&(ci + n)->bdaddr, &c->dst);
17836 + (ci + n)->handle = c->handle;
17837 + (ci + n)->type = c->type;
17838 + (ci + n)->out = c->out;
17839 + (ci + n)->state = c->state;
17840 + (ci + n)->link_mode = c->link_mode;
17841 + if (++n >= req.conn_num)
17844 + hci_dev_unlock_bh(hdev);
17846 + cl->dev_id = hdev->id;
17847 + cl->conn_num = n;
17848 + size = sizeof(req) + n * sizeof(*ci);
17850 + hci_dev_put(hdev);
17852 + err = copy_to_user((void *) arg, cl, size);
17855 + return err ? -EFAULT : 0;
17858 +int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg)
17860 + struct hci_conn_info_req req;
17861 + struct hci_conn_info ci;
17862 + struct hci_conn *conn;
17863 + char *ptr = (void *) arg + sizeof(req);
17865 + if (copy_from_user(&req, (void *) arg, sizeof(req)))
17868 + hci_dev_lock_bh(hdev);
17869 + conn = conn_hash_lookup_ba(hdev, req.type, &req.bdaddr);
17871 + bacpy(&ci.bdaddr, &conn->dst);
17872 + ci.handle = conn->handle;
17873 + ci.type = conn->type;
17874 + ci.out = conn->out;
17875 + ci.state = conn->state;
17876 + ci.link_mode = conn->link_mode;
17878 + hci_dev_unlock_bh(hdev);
17883 + return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0;
17885 diff -urN linux-2.4.18/net/bluetooth/hci_core.c linux-2.4.18-mh15/net/bluetooth/hci_core.c
17886 --- linux-2.4.18/net/bluetooth/hci_core.c 2001-11-09 23:21:21.000000000 +0100
17887 +++ linux-2.4.18-mh15/net/bluetooth/hci_core.c 2004-08-01 16:26:23.000000000 +0200
17888 @@ -25,11 +25,12 @@
17892 - * $Id: hci_core.c,v 1.22 2001/08/03 04:19:50 maxk Exp $
17893 + * $Id: hci_core.c,v 1.14 2002/08/26 16:57:57 maxk Exp $
17896 #include <linux/config.h>
17897 #include <linux/module.h>
17898 +#include <linux/kmod.h>
17900 #include <linux/types.h>
17901 #include <linux/errno.h>
17902 @@ -50,12 +51,11 @@
17903 #include <asm/unaligned.h>
17905 #include <net/bluetooth/bluetooth.h>
17906 -#include <net/bluetooth/bluez.h>
17907 #include <net/bluetooth/hci_core.h>
17909 #ifndef HCI_CORE_DEBUG
17911 -#define DBG( A... )
17913 +#define BT_DBG( A... )
17916 static void hci_cmd_task(unsigned long arg);
17917 @@ -63,279 +63,69 @@
17918 static void hci_tx_task(unsigned long arg);
17919 static void hci_notify(struct hci_dev *hdev, int event);
17921 -static rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
17922 +rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
17924 /* HCI device list */
17925 -struct hci_dev *hdev_list[HCI_MAX_DEV];
17926 -spinlock_t hdev_list_lock;
17927 -#define GET_HDEV(a) (hdev_list[a])
17929 -/* HCI protocol list */
17930 -struct hci_proto *hproto_list[HCI_MAX_PROTO];
17931 -#define GET_HPROTO(a) (hproto_list[a])
17932 +LIST_HEAD(hdev_list);
17933 +rwlock_t hdev_list_lock = RW_LOCK_UNLOCKED;
17935 -/* HCI notifiers list */
17936 -struct notifier_block *hci_dev_notifier;
17938 -/* HCI device notifications */
17939 -int hci_register_notifier(struct notifier_block *nb)
17942 - struct hci_dev *hdev;
17944 - if ((err = notifier_chain_register(&hci_dev_notifier, nb)))
17947 - /* Notify about already registered devices */
17948 - spin_lock(&hdev_list_lock);
17949 - for (i = 0; i < HCI_MAX_DEV; i++) {
17950 - if (!(hdev = GET_HDEV(i)))
17952 - if (hdev->flags & HCI_UP)
17953 - (*nb->notifier_call)(nb, HCI_DEV_UP, hdev);
17955 - spin_unlock(&hdev_list_lock);
17960 -int hci_unregister_notifier(struct notifier_block *nb)
17962 - return notifier_chain_unregister(&hci_dev_notifier, nb);
17965 -static inline void hci_notify(struct hci_dev *hdev, int event)
17967 - notifier_call_chain(&hci_dev_notifier, event, hdev);
17970 -/* Get HCI device by index (device is locked on return)*/
17971 -struct hci_dev *hci_dev_get(int index)
17973 - struct hci_dev *hdev;
17974 - DBG("%d", index);
17976 - if (index < 0 || index >= HCI_MAX_DEV)
17979 - spin_lock(&hdev_list_lock);
17980 - if ((hdev = GET_HDEV(index)))
17981 - hci_dev_hold(hdev);
17982 - spin_unlock(&hdev_list_lock);
17987 -/* Flush inquiry cache */
17988 -void inquiry_cache_flush(struct inquiry_cache *cache)
17990 - struct inquiry_entry *next = cache->list, *e;
17992 - DBG("cache %p", cache);
17994 - cache->list = NULL;
17995 - while ((e = next)) {
18001 -/* Lookup by bdaddr.
18002 - * Cache must be locked. */
18003 -static struct inquiry_entry * __inquiry_cache_lookup(struct inquiry_cache *cache, bdaddr_t *bdaddr)
18005 - struct inquiry_entry *e;
18007 - DBG("cache %p, %s", cache, batostr(bdaddr));
18009 - for (e = cache->list; e; e = e->next)
18010 - if (!bacmp(&e->info.bdaddr, bdaddr))
18016 -static void inquiry_cache_update(struct inquiry_cache *cache, inquiry_info *info)
18018 - struct inquiry_entry *e;
18020 - DBG("cache %p, %s", cache, batostr(&info->bdaddr));
18022 - inquiry_cache_lock(cache);
18024 - if (!(e = __inquiry_cache_lookup(cache, &info->bdaddr))) {
18025 - /* Entry not in the cache. Add new one. */
18026 - if (!(e = kmalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
18028 - memset(e, 0, sizeof(struct inquiry_entry));
18029 - e->next = cache->list;
18033 - memcpy(&e->info, info, sizeof(inquiry_info));
18034 - e->timestamp = jiffies;
18035 - cache->timestamp = jiffies;
18037 - inquiry_cache_unlock(cache);
18040 -static int inquiry_cache_dump(struct inquiry_cache *cache, int num, __u8 *buf)
18042 - inquiry_info *info = (inquiry_info *) buf;
18043 - struct inquiry_entry *e;
18045 +/* HCI protocols */
18046 +#define HCI_MAX_PROTO 2
18047 +struct hci_proto *hci_proto[HCI_MAX_PROTO];
18049 - inquiry_cache_lock(cache);
18051 - for (e = cache->list; e && copied < num; e = e->next, copied++)
18052 - memcpy(info++, &e->info, sizeof(inquiry_info));
18053 +/* HCI notifiers list */
18054 +static struct notifier_block *hci_notifier;
18056 - inquiry_cache_unlock(cache);
18058 - DBG("cache %p, copied %d", cache, copied);
18061 +/* ---- HCI notifications ---- */
18063 -/* --------- BaseBand connections --------- */
18064 -static struct hci_conn *hci_conn_add(struct hci_dev *hdev, __u16 handle, __u8 type, bdaddr_t *dst)
18065 +int hci_register_notifier(struct notifier_block *nb)
18067 - struct hci_conn *conn;
18069 - DBG("%s handle %d dst %s", hdev->name, handle, batostr(dst));
18071 - if ( conn_hash_lookup(&hdev->conn_hash, handle)) {
18072 - ERR("%s handle 0x%x already exists", hdev->name, handle);
18076 - if (!(conn = kmalloc(sizeof(struct hci_conn), GFP_ATOMIC)))
18078 - memset(conn, 0, sizeof(struct hci_conn));
18080 - bacpy(&conn->dst, dst);
18081 - conn->handle = handle;
18082 - conn->type = type;
18083 - conn->hdev = hdev;
18085 - skb_queue_head_init(&conn->data_q);
18087 - hci_dev_hold(hdev);
18088 - conn_hash_add(&hdev->conn_hash, handle, conn);
18091 + return notifier_chain_register(&hci_notifier, nb);
18094 -static int hci_conn_del(struct hci_dev *hdev, struct hci_conn *conn)
18095 +int hci_unregister_notifier(struct notifier_block *nb)
18097 - DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
18099 - conn_hash_del(&hdev->conn_hash, conn);
18100 - hci_dev_put(hdev);
18102 - /* Unacked frames */
18103 - hdev->acl_cnt += conn->sent;
18105 - skb_queue_purge(&conn->data_q);
18109 + return notifier_chain_unregister(&hci_notifier, nb);
18112 -/* Drop all connection on the device */
18113 -static void hci_conn_hash_flush(struct hci_dev *hdev)
18114 +void hci_notify(struct hci_dev *hdev, int event)
18116 - struct conn_hash *h = &hdev->conn_hash;
18117 - struct hci_proto *hp;
18118 - struct list_head *p;
18120 - DBG("hdev %s", hdev->name);
18122 - p = h->list.next;
18123 - while (p != &h->list) {
18124 - struct hci_conn *c;
18126 - c = list_entry(p, struct hci_conn, list);
18129 - if (c->type == ACL_LINK) {
18130 - /* ACL link notify L2CAP layer */
18131 - if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
18132 - hp->disconn_ind(c, 0x16);
18134 - /* SCO link (no notification) */
18137 - hci_conn_del(hdev, c);
18139 + notifier_call_chain(&hci_notifier, event, hdev);
18142 -int hci_connect(struct hci_dev *hdev, bdaddr_t *bdaddr)
18144 - struct inquiry_cache *cache = &hdev->inq_cache;
18145 - struct inquiry_entry *e;
18146 - create_conn_cp cc;
18147 - __u16 clock_offset;
18149 - DBG("%s bdaddr %s", hdev->name, batostr(bdaddr));
18151 - if (!(hdev->flags & HCI_UP))
18154 - inquiry_cache_lock_bh(cache);
18156 - if (!(e = __inquiry_cache_lookup(cache, bdaddr)) || inquiry_entry_age(e) > INQUIRY_ENTRY_AGE_MAX) {
18157 - cc.pscan_rep_mode = 0;
18158 - cc.pscan_mode = 0;
18159 - clock_offset = 0;
18161 - cc.pscan_rep_mode = e->info.pscan_rep_mode;
18162 - cc.pscan_mode = e->info.pscan_mode;
18163 - clock_offset = __le16_to_cpu(e->info.clock_offset) & 0x8000;
18166 - inquiry_cache_unlock_bh(cache);
18168 - bacpy(&cc.bdaddr, bdaddr);
18169 - cc.pkt_type = __cpu_to_le16(hdev->pkt_type);
18170 - cc.clock_offset = __cpu_to_le16(clock_offset);
18172 - if (lmp_rswitch_capable(hdev))
18173 - cc.role_switch = 0x01;
18175 - cc.role_switch = 0x00;
18177 - hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, CREATE_CONN_CP_SIZE, &cc);
18178 +/* ---- HCI hotplug support ---- */
18182 +#ifdef CONFIG_HOTPLUG
18184 -int hci_disconnect(struct hci_conn *conn, __u8 reason)
18185 +static int hci_run_hotplug(char *dev, char *action)
18187 - disconnect_cp dc;
18189 - DBG("conn %p handle %d", conn, conn->handle);
18190 + char *argv[3], *envp[5], dstr[20], astr[32];
18192 - dc.handle = __cpu_to_le16(conn->handle);
18193 - dc.reason = reason;
18194 - hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT, DISCONNECT_CP_SIZE, &dc);
18195 + sprintf(dstr, "DEVICE=%s", dev);
18196 + sprintf(astr, "ACTION=%s", action);
18200 + argv[0] = hotplug_path;
18201 + argv[1] = "bluetooth";
18204 -/* --------- HCI request handling ------------ */
18205 -static inline void hci_req_lock(struct hci_dev *hdev)
18207 - down(&hdev->req_lock);
18208 + envp[0] = "HOME=/";
18209 + envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
18214 + return call_usermodehelper(argv[0], argv, envp);
18217 +#define hci_run_hotplug(A...)
18220 -static inline void hci_req_unlock(struct hci_dev *hdev)
18222 - up(&hdev->req_lock);
18224 +/* ---- HCI requests ---- */
18226 -static inline void hci_req_complete(struct hci_dev *hdev, int result)
18227 +void hci_req_complete(struct hci_dev *hdev, int result)
18229 - DBG("%s result 0x%2.2x", hdev->name, result);
18230 + BT_DBG("%s result 0x%2.2x", hdev->name, result);
18232 if (hdev->req_status == HCI_REQ_PEND) {
18233 hdev->req_result = result;
18234 @@ -344,9 +134,9 @@
18238 -static inline void hci_req_cancel(struct hci_dev *hdev, int err)
18239 +void hci_req_cancel(struct hci_dev *hdev, int err)
18241 - DBG("%s err 0x%2.2x", hdev->name, err);
18242 + BT_DBG("%s err 0x%2.2x", hdev->name, err);
18244 if (hdev->req_status == HCI_REQ_PEND) {
18245 hdev->req_result = err;
18246 @@ -356,23 +146,22 @@
18249 /* Execute request and wait for completion. */
18250 -static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
18251 - unsigned long opt, __u32 timeout)
18252 +static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), unsigned long opt, __u32 timeout)
18254 DECLARE_WAITQUEUE(wait, current);
18257 - DBG("%s start", hdev->name);
18258 + BT_DBG("%s start", hdev->name);
18260 hdev->req_status = HCI_REQ_PEND;
18262 add_wait_queue(&hdev->req_wait_q, &wait);
18263 - current->state = TASK_INTERRUPTIBLE;
18264 + set_current_state(TASK_INTERRUPTIBLE);
18267 schedule_timeout(timeout);
18269 - current->state = TASK_RUNNING;
18270 + set_current_state(TASK_RUNNING);
18271 remove_wait_queue(&hdev->req_wait_q, &wait);
18273 if (signal_pending(current))
18274 @@ -394,7 +183,7 @@
18276 hdev->req_status = hdev->req_result = 0;
18278 - DBG("%s end: err %d", hdev->name, err);
18279 + BT_DBG("%s end: err %d", hdev->name, err);
18283 @@ -412,10 +201,9 @@
18287 -/* --------- HCI requests ---------- */
18288 static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
18290 - DBG("%s %ld", hdev->name, opt);
18291 + BT_DBG("%s %ld", hdev->name, opt);
18294 hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
18295 @@ -423,27 +211,44 @@
18297 static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
18299 - set_event_flt_cp ec;
18300 + set_event_flt_cp ef;
18303 - DBG("%s %ld", hdev->name, opt);
18304 + BT_DBG("%s %ld", hdev->name, opt);
18306 /* Mandatory initialization */
18309 + if (test_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks))
18310 + hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
18312 /* Read Local Supported Features */
18313 hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES, 0, NULL);
18315 /* Read Buffer Size (ACL mtu, max pkt, etc.) */
18316 hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
18319 + /* Host buffer size */
18321 + host_buffer_size_cp bs;
18322 + bs.acl_mtu = __cpu_to_le16(HCI_MAX_ACL_SIZE);
18323 + bs.sco_mtu = HCI_MAX_SCO_SIZE;
18324 + bs.acl_max_pkt = __cpu_to_le16(0xffff);
18325 + bs.sco_max_pkt = __cpu_to_le16(0xffff);
18326 + hci_send_cmd(hdev, OGF_HOST_CTL, OCF_HOST_BUFFER_SIZE,
18327 + HOST_BUFFER_SIZE_CP_SIZE, &bs);
18331 /* Read BD Address */
18332 hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, NULL);
18334 /* Optional initialization */
18336 /* Clear Event Filters */
18337 - ec.flt_type = FLT_CLEAR_ALL;
18338 - hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &ec);
18339 + ef.flt_type = FLT_CLEAR_ALL;
18340 + hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &ef);
18342 /* Page timeout ~20 secs */
18343 param = __cpu_to_le16(0x8000);
18344 @@ -458,7 +263,7 @@
18348 - DBG("%s %x", hdev->name, scan);
18349 + BT_DBG("%s %x", hdev->name, scan);
18351 /* Inquiry and Page scans */
18352 hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, &scan);
18353 @@ -468,116 +273,273 @@
18357 - DBG("%s %x", hdev->name, auth);
18358 + BT_DBG("%s %x", hdev->name, auth);
18360 /* Authentication */
18361 hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE, 1, &auth);
18364 -static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
18365 +static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
18367 - struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
18369 + __u8 encrypt = opt;
18371 - DBG("%s", hdev->name);
18372 + BT_DBG("%s %x", hdev->name, encrypt);
18374 - /* Start Inquiry */
18375 - memcpy(&ic.lap, &ir->lap, 3);
18376 - ic.lenght = ir->length;
18377 - ic.num_rsp = ir->num_rsp;
18378 - hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, &ic);
18379 + /* Authentication */
18380 + hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE, 1, &encrypt);
18383 -/* HCI ioctl helpers */
18384 -int hci_dev_open(__u16 dev)
18385 +/* Get HCI device by index.
18386 + * Device is locked on return. */
18387 +struct hci_dev *hci_dev_get(int index)
18389 struct hci_dev *hdev;
18392 - if (!(hdev = hci_dev_get(dev)))
18394 + struct list_head *p;
18396 - DBG("%s %p", hdev->name, hdev);
18397 + BT_DBG("%d", index);
18399 - hci_req_lock(hdev);
18403 - if (hdev->flags & HCI_UP) {
18406 + read_lock(&hdev_list_lock);
18407 + list_for_each(p, &hdev_list) {
18408 + hdev = list_entry(p, struct hci_dev, list);
18409 + if (hdev->id == index) {
18410 + hci_dev_hold(hdev);
18416 + read_unlock(&hdev_list_lock);
18420 - if (hdev->open(hdev)) {
18424 +/* ---- Inquiry support ---- */
18425 +void inquiry_cache_flush(struct hci_dev *hdev)
18427 + struct inquiry_cache *cache = &hdev->inq_cache;
18428 + struct inquiry_entry *next = cache->list, *e;
18430 - if (hdev->flags & HCI_NORMAL) {
18431 - atomic_set(&hdev->cmd_cnt, 1);
18432 - hdev->flags |= HCI_INIT;
18433 + BT_DBG("cache %p", cache);
18435 - //__hci_request(hdev, hci_reset_req, 0, HZ);
18436 - ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
18438 - hdev->flags &= ~HCI_INIT;
18439 + cache->list = NULL;
18440 + while ((e = next)) {
18447 - hdev->flags |= HCI_UP;
18448 - hci_notify(hdev, HCI_DEV_UP);
18450 - /* Init failed, cleanup */
18451 - tasklet_kill(&hdev->rx_task);
18452 - tasklet_kill(&hdev->tx_task);
18453 - tasklet_kill(&hdev->cmd_task);
18454 +struct inquiry_entry *inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
18456 + struct inquiry_cache *cache = &hdev->inq_cache;
18457 + struct inquiry_entry *e;
18459 - skb_queue_purge(&hdev->cmd_q);
18460 - skb_queue_purge(&hdev->rx_q);
18461 + BT_DBG("cache %p, %s", cache, batostr(bdaddr));
18464 - hdev->flush(hdev);
18465 + for (e = cache->list; e; e = e->next)
18466 + if (!bacmp(&e->info.bdaddr, bdaddr))
18471 - if (hdev->sent_cmd) {
18472 - kfree_skb(hdev->sent_cmd);
18473 - hdev->sent_cmd = NULL;
18475 +void inquiry_cache_update(struct hci_dev *hdev, inquiry_info *info)
18477 + struct inquiry_cache *cache = &hdev->inq_cache;
18478 + struct inquiry_entry *e;
18480 - hdev->close(hdev);
18482 + BT_DBG("cache %p, %s", cache, batostr(&info->bdaddr));
18485 - hci_req_unlock(hdev);
18486 - hci_dev_put(hdev);
18487 + if (!(e = inquiry_cache_lookup(hdev, &info->bdaddr))) {
18488 + /* Entry not in the cache. Add new one. */
18489 + if (!(e = kmalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
18491 + memset(e, 0, sizeof(struct inquiry_entry));
18492 + e->next = cache->list;
18497 + memcpy(&e->info, info, sizeof(inquiry_info));
18498 + e->timestamp = jiffies;
18499 + cache->timestamp = jiffies;
18502 -int hci_dev_close(__u16 dev)
18503 +int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
18505 - struct hci_dev *hdev;
18507 - if (!(hdev = hci_dev_get(dev)))
18509 + struct inquiry_cache *cache = &hdev->inq_cache;
18510 + inquiry_info *info = (inquiry_info *) buf;
18511 + struct inquiry_entry *e;
18514 - DBG("%s %p", hdev->name, hdev);
18515 + for (e = cache->list; e && copied < num; e = e->next, copied++)
18516 + memcpy(info++, &e->info, sizeof(inquiry_info));
18518 - hci_req_cancel(hdev, ENODEV);
18519 - hci_req_lock(hdev);
18520 + BT_DBG("cache %p, copied %d", cache, copied);
18524 - if (!(hdev->flags & HCI_UP))
18526 +static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
18528 + struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
18531 - /* Kill RX and TX tasks */
18532 - tasklet_kill(&hdev->rx_task);
18533 - tasklet_kill(&hdev->tx_task);
18534 + BT_DBG("%s", hdev->name);
18536 - inquiry_cache_flush(&hdev->inq_cache);
18537 + if (test_bit(HCI_INQUIRY, &hdev->flags))
18540 - hci_conn_hash_flush(hdev);
18541 + /* Start Inquiry */
18542 + memcpy(&ic.lap, &ir->lap, 3);
18543 + ic.length = ir->length;
18544 + ic.num_rsp = ir->num_rsp;
18545 + hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, &ic);
18548 - /* Clear flags */
18549 - hdev->flags &= HCI_SOCK;
18550 - hdev->flags |= HCI_NORMAL;
18551 +int hci_inquiry(unsigned long arg)
18553 + struct hci_inquiry_req ir;
18554 + struct hci_dev *hdev;
18555 + int err = 0, do_inquiry = 0, max_rsp;
18559 + ptr = (void *) arg;
18560 + if (copy_from_user(&ir, ptr, sizeof(ir)))
18563 + if (!(hdev = hci_dev_get(ir.dev_id)))
18566 + hci_dev_lock_bh(hdev);
18567 + if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
18568 + inquiry_cache_empty(hdev) ||
18569 + ir.flags & IREQ_CACHE_FLUSH) {
18570 + inquiry_cache_flush(hdev);
18573 + hci_dev_unlock_bh(hdev);
18575 + timeo = ir.length * 2 * HZ;
18576 + if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
18579 + /* for unlimited number of responses we will use buffer with 255 entries */
18580 + max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
18582 + /* cache_dump can't sleep. Therefore we allocate temp buffer and then
18583 + * copy it to the user space.
18585 + if (!(buf = kmalloc(sizeof(inquiry_info) * max_rsp, GFP_KERNEL))) {
18590 + hci_dev_lock_bh(hdev);
18591 + ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
18592 + hci_dev_unlock_bh(hdev);
18594 + BT_DBG("num_rsp %d", ir.num_rsp);
18596 + if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) +
18597 + (sizeof(inquiry_info) * ir.num_rsp))) {
18598 + copy_to_user(ptr, &ir, sizeof(ir));
18599 + ptr += sizeof(ir);
18600 + copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
18607 + hci_dev_put(hdev);
18611 +/* ---- HCI ioctl helpers ---- */
18613 +int hci_dev_open(__u16 dev)
18615 + struct hci_dev *hdev;
18618 + if (!(hdev = hci_dev_get(dev)))
18621 + BT_DBG("%s %p", hdev->name, hdev);
18623 + hci_req_lock(hdev);
18625 + if (test_bit(HCI_UP, &hdev->flags)) {
18630 + if (hdev->open(hdev)) {
18635 + if (!test_bit(HCI_RAW, &hdev->flags)) {
18636 + atomic_set(&hdev->cmd_cnt, 1);
18637 + set_bit(HCI_INIT, &hdev->flags);
18639 + //__hci_request(hdev, hci_reset_req, 0, HZ);
18640 + ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
18642 + clear_bit(HCI_INIT, &hdev->flags);
18646 + set_bit(HCI_UP, &hdev->flags);
18647 + hci_notify(hdev, HCI_DEV_UP);
18649 + /* Init failed, cleanup */
18650 + tasklet_kill(&hdev->rx_task);
18651 + tasklet_kill(&hdev->tx_task);
18652 + tasklet_kill(&hdev->cmd_task);
18654 + skb_queue_purge(&hdev->cmd_q);
18655 + skb_queue_purge(&hdev->rx_q);
18658 + hdev->flush(hdev);
18660 + if (hdev->sent_cmd) {
18661 + kfree_skb(hdev->sent_cmd);
18662 + hdev->sent_cmd = NULL;
18665 + hdev->close(hdev);
18670 + hci_req_unlock(hdev);
18671 + hci_dev_put(hdev);
18675 +static int hci_dev_do_close(struct hci_dev *hdev)
18677 + BT_DBG("%s %p", hdev->name, hdev);
18679 + hci_req_cancel(hdev, ENODEV);
18680 + hci_req_lock(hdev);
18682 + if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
18683 + hci_req_unlock(hdev);
18687 + /* Kill RX and TX tasks */
18688 + tasklet_kill(&hdev->rx_task);
18689 + tasklet_kill(&hdev->tx_task);
18691 + hci_dev_lock_bh(hdev);
18692 + inquiry_cache_flush(hdev);
18693 + hci_conn_hash_flush(hdev);
18694 + hci_dev_unlock_bh(hdev);
18696 hci_notify(hdev, HCI_DEV_DOWN);
18699 @@ -586,9 +548,9 @@
18701 skb_queue_purge(&hdev->cmd_q);
18702 atomic_set(&hdev->cmd_cnt, 1);
18703 - hdev->flags |= HCI_INIT;
18704 - __hci_request(hdev, hci_reset_req, 0, HZ);
18705 - hdev->flags &= ~HCI_INIT;
18706 + set_bit(HCI_INIT, &hdev->flags);
18707 + __hci_request(hdev, hci_reset_req, 0, HZ/4);
18708 + clear_bit(HCI_INIT, &hdev->flags);
18710 /* Kill cmd task */
18711 tasklet_kill(&hdev->cmd_task);
18712 @@ -605,17 +567,28 @@
18715 /* After this point our queues are empty
18716 - * and no tasks are scheduled.
18718 + * and no tasks are scheduled. */
18722 - hci_req_unlock(hdev);
18723 - hci_dev_put(hdev);
18724 + /* Clear flags */
18727 + hci_req_unlock(hdev);
18731 +int hci_dev_close(__u16 dev)
18733 + struct hci_dev *hdev;
18736 + if (!(hdev = hci_dev_get(dev)))
18738 + err = hci_dev_do_close(hdev);
18739 + hci_dev_put(hdev);
18743 int hci_dev_reset(__u16 dev)
18745 struct hci_dev *hdev;
18746 @@ -627,16 +600,17 @@
18747 hci_req_lock(hdev);
18748 tasklet_disable(&hdev->tx_task);
18750 - if (!(hdev->flags & HCI_UP))
18751 + if (!test_bit(HCI_UP, &hdev->flags))
18755 skb_queue_purge(&hdev->rx_q);
18756 skb_queue_purge(&hdev->cmd_q);
18758 - inquiry_cache_flush(&hdev->inq_cache);
18760 + hci_dev_lock_bh(hdev);
18761 + inquiry_cache_flush(hdev);
18762 hci_conn_hash_flush(hdev);
18763 + hci_dev_unlock_bh(hdev);
18767 @@ -650,7 +624,6 @@
18768 tasklet_enable(&hdev->tx_task);
18769 hci_req_unlock(hdev);
18775 @@ -669,30 +642,11 @@
18779 -int hci_dev_setauth(unsigned long arg)
18781 - struct hci_dev *hdev;
18782 - struct hci_dev_req dr;
18785 - if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
18788 - if (!(hdev = hci_dev_get(dr.dev_id)))
18791 - ret = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
18793 - hci_dev_put(hdev);
18798 -int hci_dev_setscan(unsigned long arg)
18799 +int hci_dev_cmd(unsigned int cmd, unsigned long arg)
18801 struct hci_dev *hdev;
18802 struct hci_dev_req dr;
18806 if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
18808 @@ -700,75 +654,105 @@
18809 if (!(hdev = hci_dev_get(dr.dev_id)))
18812 - ret = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
18814 - hci_dev_put(hdev);
18817 + err = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
18822 + case HCISETENCRYPT:
18823 + if (!lmp_encrypt_capable(hdev)) {
18824 + err = -EOPNOTSUPP;
18828 -int hci_dev_setptype(unsigned long arg)
18830 - struct hci_dev *hdev;
18831 - struct hci_dev_req dr;
18833 + if (!test_bit(HCI_AUTH, &hdev->flags)) {
18834 + /* Auth must be enabled first */
18835 + err = hci_request(hdev, hci_auth_req,
18836 + dr.dev_opt, HCI_INIT_TIMEOUT);
18841 + err = hci_request(hdev, hci_encrypt_req,
18842 + dr.dev_opt, HCI_INIT_TIMEOUT);
18846 + err = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
18849 + case HCISETPTYPE:
18850 + hdev->pkt_type = (__u16) dr.dev_opt;
18853 + case HCISETLINKPOL:
18854 + hdev->link_policy = (__u16) dr.dev_opt;
18857 - if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
18859 + case HCISETLINKMODE:
18860 + hdev->link_mode = ((__u16) dr.dev_opt) & (HCI_LM_MASTER | HCI_LM_ACCEPT);
18863 - if (!(hdev = hci_dev_get(dr.dev_id)))
18865 + case HCISETACLMTU:
18866 + hdev->acl_mtu = *((__u16 *)&dr.dev_opt + 1);
18867 + hdev->acl_pkts = *((__u16 *)&dr.dev_opt + 0);
18870 - hdev->pkt_type = (__u16) dr.dev_opt;
18871 + case HCISETSCOMTU:
18872 + hdev->sco_mtu = *((__u16 *)&dr.dev_opt + 1);
18873 + hdev->sco_pkts = *((__u16 *)&dr.dev_opt + 0);
18886 -int hci_dev_list(unsigned long arg)
18887 +int hci_get_dev_list(unsigned long arg)
18889 struct hci_dev_list_req *dl;
18890 struct hci_dev_req *dr;
18891 - struct hci_dev *hdev;
18893 + struct list_head *p;
18894 + int n = 0, size, err;
18897 if (get_user(dev_num, (__u16 *) arg))
18900 - /* Avoid long loop, overflow */
18901 - if (dev_num > 2048)
18902 + if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
18905 - size = dev_num * sizeof(struct hci_dev_req) + sizeof(__u16);
18907 - if (verify_area(VERIFY_WRITE, (void *) arg, size))
18909 + size = sizeof(*dl) + dev_num * sizeof(*dr);
18911 if (!(dl = kmalloc(size, GFP_KERNEL)))
18916 - spin_lock_bh(&hdev_list_lock);
18917 - for (i = 0, n = 0; i < HCI_MAX_DEV && n < dev_num; i++) {
18918 - if ((hdev = hdev_list[i])) {
18919 - (dr + n)->dev_id = hdev->id;
18920 - (dr + n)->dev_opt = hdev->flags;
18923 + read_lock_bh(&hdev_list_lock);
18924 + list_for_each(p, &hdev_list) {
18925 + struct hci_dev *hdev;
18926 + hdev = list_entry(p, struct hci_dev, list);
18927 + (dr + n)->dev_id = hdev->id;
18928 + (dr + n)->dev_opt = hdev->flags;
18929 + if (++n >= dev_num)
18932 - spin_unlock_bh(&hdev_list_lock);
18933 + read_unlock_bh(&hdev_list_lock);
18936 - size = n * sizeof(struct hci_dev_req) + sizeof(__u16);
18937 + size = sizeof(*dl) + n * sizeof(*dr);
18939 - copy_to_user((void *) arg, dl, size);
18940 + err = copy_to_user((void *) arg, dl, size);
18944 + return err ? -EFAULT : 0;
18947 -int hci_dev_info(unsigned long arg)
18948 +int hci_get_dev_info(unsigned long arg)
18950 struct hci_dev *hdev;
18951 struct hci_dev_info di;
18952 @@ -786,9 +770,11 @@
18953 di.flags = hdev->flags;
18954 di.pkt_type = hdev->pkt_type;
18955 di.acl_mtu = hdev->acl_mtu;
18956 - di.acl_max = hdev->acl_max;
18957 + di.acl_pkts = hdev->acl_pkts;
18958 di.sco_mtu = hdev->sco_mtu;
18959 - di.sco_max = hdev->sco_max;
18960 + di.sco_pkts = hdev->sco_pkts;
18961 + di.link_policy = hdev->link_policy;
18962 + di.link_mode = hdev->link_mode;
18964 memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
18965 memcpy(&di.features, &hdev->features, sizeof(di.features));
18966 @@ -801,258 +787,168 @@
18970 -__u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode)
18972 - __u32 omode = hdev->flags & HCI_MODE_MASK;
18974 - hdev->flags &= ~HCI_MODE_MASK;
18975 - hdev->flags |= (mode & HCI_MODE_MASK);
18979 +/* ---- Interface to HCI drivers ---- */
18981 -__u32 hci_dev_getmode(struct hci_dev *hdev)
18982 +/* Register HCI device */
18983 +int hci_register_dev(struct hci_dev *hdev)
18985 - return hdev->flags & HCI_MODE_MASK;
18987 + struct list_head *head = &hdev_list, *p;
18990 -int hci_conn_list(unsigned long arg)
18992 - struct hci_conn_list_req req, *cl;
18993 - struct hci_conn_info *ci;
18994 - struct hci_dev *hdev;
18995 - struct list_head *p;
18997 + BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
18999 - if (copy_from_user(&req, (void *) arg, sizeof(req)))
19001 + if (!hdev->open || !hdev->close || !hdev->destruct)
19004 - if (!(hdev = hci_dev_get(req.dev_id)))
19006 + write_lock_bh(&hdev_list_lock);
19008 - /* Set a limit to avoid overlong loops, and also numeric overflow - AC */
19009 - if(req.conn_num < 2048)
19011 + /* Find first available device id */
19012 + list_for_each(p, &hdev_list) {
19013 + if (list_entry(p, struct hci_dev, list)->id != id)
19018 - size = req.conn_num * sizeof(struct hci_conn_info) + sizeof(req);
19019 + sprintf(hdev->name, "hci%d", id);
19021 + list_add(&hdev->list, head);
19023 - if (!(cl = kmalloc(size, GFP_KERNEL)))
19025 - ci = cl->conn_info;
19027 - local_bh_disable();
19028 - conn_hash_lock(&hdev->conn_hash);
19029 - list_for_each(p, &hdev->conn_hash.list) {
19030 - register struct hci_conn *c;
19031 - c = list_entry(p, struct hci_conn, list);
19032 + atomic_set(&hdev->refcnt, 1);
19033 + spin_lock_init(&hdev->lock);
19036 + hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1);
19037 + hdev->link_mode = (HCI_LM_ACCEPT);
19039 - (ci + n)->handle = c->handle;
19040 - bacpy(&(ci + n)->bdaddr, &c->dst);
19043 - conn_hash_unlock(&hdev->conn_hash);
19044 - local_bh_enable();
19046 - cl->dev_id = hdev->id;
19047 - cl->conn_num = n;
19048 - size = n * sizeof(struct hci_conn_info) + sizeof(req);
19049 + tasklet_init(&hdev->cmd_task, hci_cmd_task,(unsigned long) hdev);
19050 + tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
19051 + tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
19053 - hci_dev_put(hdev);
19054 + skb_queue_head_init(&hdev->rx_q);
19055 + skb_queue_head_init(&hdev->cmd_q);
19056 + skb_queue_head_init(&hdev->raw_q);
19058 - if(copy_to_user((void *) arg, cl, size))
19062 + init_waitqueue_head(&hdev->req_wait_q);
19063 + init_MUTEX(&hdev->req_lock);
19065 -int hci_inquiry(unsigned long arg)
19067 - struct inquiry_cache *cache;
19068 - struct hci_inquiry_req ir;
19069 - struct hci_dev *hdev;
19070 - int err = 0, do_inquiry = 0;
19073 + inquiry_cache_init(hdev);
19075 - ptr = (void *) arg;
19076 - if (copy_from_user(&ir, ptr, sizeof(ir)))
19078 + conn_hash_init(hdev);
19080 - if (!(hdev = hci_dev_get(ir.dev_id)))
19082 + memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
19084 - cache = &hdev->inq_cache;
19085 + atomic_set(&hdev->promisc, 0);
19087 - inquiry_cache_lock(cache);
19088 - if (inquiry_cache_age(cache) > INQUIRY_CACHE_AGE_MAX || ir.flags & IREQ_CACHE_FLUSH) {
19089 - inquiry_cache_flush(cache);
19092 - inquiry_cache_unlock(cache);
19093 + MOD_INC_USE_COUNT;
19095 - /* Limit inquiry time, also avoid overflows */
19096 + write_unlock_bh(&hdev_list_lock);
19098 - if(ir.length > 2048 || ir.num_rsp > 2048)
19103 + hci_notify(hdev, HCI_DEV_REG);
19104 + hci_run_hotplug(hdev->name, "register");
19106 - timeo = ir.length * 2 * HZ;
19107 - if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
19112 - /* cache_dump can't sleep. Therefore we allocate temp buffer and then
19113 - * copy it to the user space.
19115 - if (!(buf = kmalloc(sizeof(inquiry_info) * ir.num_rsp, GFP_KERNEL))) {
19119 - ir.num_rsp = inquiry_cache_dump(cache, ir.num_rsp, buf);
19120 +/* Unregister HCI device */
19121 +int hci_unregister_dev(struct hci_dev *hdev)
19123 + BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
19125 - DBG("num_rsp %d", ir.num_rsp);
19126 + write_lock_bh(&hdev_list_lock);
19127 + list_del(&hdev->list);
19128 + write_unlock_bh(&hdev_list_lock);
19130 - if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) + (sizeof(inquiry_info) * ir.num_rsp))) {
19131 - copy_to_user(ptr, &ir, sizeof(ir));
19132 - ptr += sizeof(ir);
19133 - copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
19136 + hci_dev_do_close(hdev);
19139 + hci_notify(hdev, HCI_DEV_UNREG);
19140 + hci_run_hotplug(hdev->name, "unregister");
19146 + MOD_DEC_USE_COUNT;
19150 -/* Interface to HCI drivers */
19152 -/* Register HCI device */
19153 -int hci_register_dev(struct hci_dev *hdev)
19154 +/* Suspend HCI device */
19155 +int hci_suspend_dev(struct hci_dev *hdev)
19158 + hci_notify(hdev, HCI_DEV_SUSPEND);
19159 + hci_run_hotplug(hdev->name, "suspend");
19163 - DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
19164 +/* Resume HCI device */
19165 +int hci_resume_dev(struct hci_dev *hdev)
19167 + hci_notify(hdev, HCI_DEV_RESUME);
19168 + hci_run_hotplug(hdev->name, "resume");
19172 - /* Find free slot */
19173 - spin_lock_bh(&hdev_list_lock);
19174 - for (i = 0; i < HCI_MAX_DEV; i++) {
19175 - if (!hdev_list[i]) {
19176 - hdev_list[i] = hdev;
19178 - sprintf(hdev->name, "hci%d", i);
19179 - atomic_set(&hdev->refcnt, 0);
19181 - hdev->flags = HCI_NORMAL;
19183 - hdev->pkt_type = (HCI_DM1 | HCI_DH1);
19185 - tasklet_init(&hdev->cmd_task, hci_cmd_task, (unsigned long) hdev);
19186 - tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
19187 - tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
19189 - skb_queue_head_init(&hdev->rx_q);
19190 - skb_queue_head_init(&hdev->cmd_q);
19191 - skb_queue_head_init(&hdev->raw_q);
19193 - init_waitqueue_head(&hdev->req_wait_q);
19194 - init_MUTEX(&hdev->req_lock);
19196 - inquiry_cache_init(&hdev->inq_cache);
19198 - conn_hash_init(&hdev->conn_hash);
19200 - memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
19202 - hci_notify(hdev, HCI_DEV_REG);
19204 - MOD_INC_USE_COUNT;
19208 - spin_unlock_bh(&hdev_list_lock);
19210 - return (i == HCI_MAX_DEV) ? -1 : i;
19213 -/* Unregister HCI device */
19214 -int hci_unregister_dev(struct hci_dev *hdev)
19215 +/* Receive frame from HCI drivers */
19216 +int hci_recv_frame(struct sk_buff *skb)
19220 - DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
19222 - if (hdev->flags & HCI_UP)
19223 - hci_dev_close(hdev->id);
19224 + struct hci_dev *hdev = (struct hci_dev *) skb->dev;
19226 - /* Find device slot */
19227 - spin_lock(&hdev_list_lock);
19228 - for (i = 0; i < HCI_MAX_DEV; i++) {
19229 - if (hdev_list[i] == hdev) {
19230 - hdev_list[i] = NULL;
19231 - MOD_DEC_USE_COUNT;
19234 + if (!hdev || (!test_bit(HCI_UP, &hdev->flags) &&
19235 + !test_bit(HCI_INIT, &hdev->flags)) ) {
19239 - spin_unlock(&hdev_list_lock);
19241 - hci_notify(hdev, HCI_DEV_UNREG);
19243 - /* Sleep while device is in use */
19244 - while (atomic_read(&hdev->refcnt)) {
19245 - int sleep_cnt = 100;
19246 + BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
19248 - DBG("%s sleeping on lock %d", hdev->name, atomic_read(&hdev->refcnt));
19249 + /* Incomming skb */
19250 + bluez_cb(skb)->incomming = 1;
19252 - sleep_on_timeout(&hdev->req_wait_q, HZ*10);
19253 - if (!(--sleep_cnt))
19257 + do_gettimeofday(&skb->stamp);
19259 + /* Queue frame for rx task */
19260 + skb_queue_tail(&hdev->rx_q, skb);
19261 + hci_sched_rx(hdev);
19265 -/* Interface to upper protocols */
19266 +/* ---- Interface to upper protocols ---- */
19268 /* Register/Unregister protocols.
19269 - * hci_task_lock is used to ensure that no tasks are running.
19271 -int hci_register_proto(struct hci_proto *hproto)
19272 + * hci_task_lock is used to ensure that no tasks are running. */
19273 +int hci_register_proto(struct hci_proto *hp)
19277 - DBG("%p name %s", hproto, hproto->name);
19278 + BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
19280 - if (hproto->id >= HCI_MAX_PROTO)
19281 + if (hp->id >= HCI_MAX_PROTO)
19284 write_lock_bh(&hci_task_lock);
19286 - if (!hproto_list[hproto->id])
19287 - hproto_list[hproto->id] = hproto;
19288 + if (!hci_proto[hp->id])
19289 + hci_proto[hp->id] = hp;
19294 write_unlock_bh(&hci_task_lock);
19299 -int hci_unregister_proto(struct hci_proto *hproto)
19300 +int hci_unregister_proto(struct hci_proto *hp)
19304 - DBG("%p name %s", hproto, hproto->name);
19305 + BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
19307 - if (hproto->id > HCI_MAX_PROTO)
19308 + if (hp->id >= HCI_MAX_PROTO)
19311 write_lock_bh(&hci_task_lock);
19313 - if (hproto_list[hproto->id])
19314 - hproto_list[hproto->id] = NULL;
19315 + if (hci_proto[hp->id])
19316 + hci_proto[hp->id] = NULL;
19320 @@ -1070,10 +966,14 @@
19324 - DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
19325 + BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
19327 + if (atomic_read(&hdev->promisc)) {
19329 + do_gettimeofday(&skb->stamp);
19331 - if (hdev->flags & HCI_SOCK)
19332 hci_send_to_sock(hdev, skb);
19335 /* Get rid of skb owner, prior to sending to the driver. */
19337 @@ -1081,128 +981,6 @@
19338 return hdev->send(skb);
19341 -/* Connection scheduler */
19342 -static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
19344 - struct conn_hash *h = &hdev->conn_hash;
19345 - struct hci_conn *conn = NULL;
19346 - int num = 0, min = 0xffff;
19347 - struct list_head *p;
19349 - conn_hash_lock(h);
19350 - list_for_each(p, &h->list) {
19351 - register struct hci_conn *c;
19353 - c = list_entry(p, struct hci_conn, list);
19355 - if (c->type != type || skb_queue_empty(&c->data_q))
19359 - if (c->sent < min) {
19364 - conn_hash_unlock(h);
19367 - int q = hdev->acl_cnt / num;
19368 - *quote = q ? q : 1;
19372 - DBG("conn %p quote %d", conn, *quote);
19377 -static inline void hci_sched_acl(struct hci_dev *hdev)
19379 - struct hci_conn *conn;
19380 - struct sk_buff *skb;
19383 - DBG("%s", hdev->name);
19385 - while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, "e))) {
19386 - while (quote && (skb = skb_dequeue(&conn->data_q))) {
19387 - DBG("skb %p len %d", skb, skb->len);
19389 - hci_send_frame(skb);
19398 -/* Schedule SCO */
19399 -static inline void hci_sched_sco(struct hci_dev *hdev)
19401 - /* FIXME: For now we queue SCO packets to the raw queue
19403 - while (hdev->sco_cnt && (skb = skb_dequeue(&conn->data_q))) {
19404 - hci_send_frame(skb);
19405 - conn->sco_sent++;
19411 -/* Get data from the previously sent command */
19412 -static void * hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
19414 - hci_command_hdr *hc;
19416 - if (!hdev->sent_cmd)
19419 - hc = (void *) hdev->sent_cmd->data;
19421 - if (hc->opcode != __cpu_to_le16(cmd_opcode_pack(ogf, ocf)))
19424 - DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
19426 - return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
19429 -/* Send raw HCI frame */
19430 -int hci_send_raw(struct sk_buff *skb)
19432 - struct hci_dev *hdev = (struct hci_dev *) skb->dev;
19439 - DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
19441 - if (hdev->flags & HCI_NORMAL) {
19442 - /* Queue frame according it's type */
19443 - switch (skb->pkt_type) {
19444 - case HCI_COMMAND_PKT:
19445 - skb_queue_tail(&hdev->cmd_q, skb);
19446 - hci_sched_cmd(hdev);
19449 - case HCI_ACLDATA_PKT:
19450 - case HCI_SCODATA_PKT:
19452 - * Check header here and queue to apropriate connection.
19458 - skb_queue_tail(&hdev->raw_q, skb);
19459 - hci_sched_tx(hdev);
19463 /* Send HCI command */
19464 int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param)
19466 @@ -1210,10 +988,10 @@
19467 hci_command_hdr *hc;
19468 struct sk_buff *skb;
19470 - DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
19471 + BT_DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
19473 if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {
19474 - ERR("%s Can't allocate memory for HCI command", hdev->name);
19475 + BT_ERR("%s Can't allocate memory for HCI command", hdev->name);
19479 @@ -1224,7 +1002,7 @@
19481 memcpy(skb_put(skb, plen), param, plen);
19483 - DBG("skb len %d", skb->len);
19484 + BT_DBG("skb len %d", skb->len);
19486 skb->pkt_type = HCI_COMMAND_PKT;
19487 skb->dev = (void *) hdev;
19488 @@ -1234,10 +1012,28 @@
19492 +/* Get data from the previously sent command */
19493 +void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
19495 + hci_command_hdr *hc;
19497 + if (!hdev->sent_cmd)
19500 + hc = (void *) hdev->sent_cmd->data;
19502 + if (hc->opcode != __cpu_to_le16(cmd_opcode_pack(ogf, ocf)))
19505 + BT_DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
19507 + return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
19510 /* Send ACL data */
19511 static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
19513 - int len = skb->len;
19514 + int len = skb->len;
19517 ah = (hci_acl_hdr *) skb_push(skb, HCI_ACL_HDR_SIZE);
19518 @@ -1252,7 +1048,7 @@
19519 struct hci_dev *hdev = conn->hdev;
19520 struct sk_buff *list;
19522 - DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
19523 + BT_DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
19525 skb->dev = (void *) hdev;
19526 skb->pkt_type = HCI_ACLDATA_PKT;
19527 @@ -1260,12 +1056,12 @@
19529 if (!(list = skb_shinfo(skb)->frag_list)) {
19530 /* Non fragmented */
19531 - DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
19532 + BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
19534 skb_queue_tail(&conn->data_q, skb);
19537 - DBG("%s frag %p len %d", hdev->name, skb, skb->len);
19538 + BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
19540 skb_shinfo(skb)->frag_list = NULL;
19542 @@ -1280,7 +1076,7 @@
19543 skb->pkt_type = HCI_ACLDATA_PKT;
19544 hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT);
19546 - DBG("%s frag %p len %d", hdev->name, skb, skb->len);
19547 + BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
19549 __skb_queue_tail(&conn->data_q, skb);
19551 @@ -1298,7 +1094,7 @@
19552 struct hci_dev *hdev = conn->hdev;
19555 - DBG("%s len %d", hdev->name, skb->len);
19556 + BT_DBG("%s len %d", hdev->name, skb->len);
19558 if (skb->len > hdev->sco_mtu) {
19560 @@ -1315,544 +1111,136 @@
19561 skb->pkt_type = HCI_SCODATA_PKT;
19562 skb_queue_tail(&conn->data_q, skb);
19563 hci_sched_tx(hdev);
19568 -/* Handle HCI Event packets */
19570 -/* Command Complete OGF LINK_CTL */
19571 -static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
19573 - DBG("%s ocf 0x%x", hdev->name, ocf);
19577 - DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
19582 -/* Command Complete OGF LINK_POLICY */
19583 -static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
19585 - DBG("%s ocf 0x%x", hdev->name, ocf);
19589 - DBG("%s: Command complete: ogf LINK_POLICY ocf %x", hdev->name, ocf);
19594 -/* Command Complete OGF HOST_CTL */
19595 -static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
19597 - __u8 status, param;
19601 - DBG("%s ocf 0x%x", hdev->name, ocf);
19605 - status = *((__u8 *) skb->data);
19607 - hci_req_complete(hdev, status);
19610 - case OCF_SET_EVENT_FLT:
19611 - status = *((__u8 *) skb->data);
19614 - DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
19616 - DBG("%s SET_EVENT_FLT succeseful", hdev->name);
19620 - case OCF_WRITE_AUTH_ENABLE:
19621 - if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE)))
19624 - status = *((__u8 *) skb->data);
19625 - param = *((__u8 *) sent);
19628 - if (param == AUTH_ENABLED)
19629 - hdev->flags |= HCI_AUTH;
19631 - hdev->flags &= ~HCI_AUTH;
19633 - hci_req_complete(hdev, status);
19636 - case OCF_WRITE_CA_TIMEOUT:
19637 - status = *((__u8 *) skb->data);
19640 - DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
19642 - DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
19646 - case OCF_WRITE_PG_TIMEOUT:
19647 - status = *((__u8 *) skb->data);
19650 - DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
19652 - DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
19656 - case OCF_WRITE_SCAN_ENABLE:
19657 - if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE)))
19659 - status = *((__u8 *) skb->data);
19660 - param = *((__u8 *) sent);
19662 - DBG("param 0x%x", param);
19666 - case IS_ENA_PS_ENA:
19667 - hdev->flags |= HCI_PSCAN | HCI_ISCAN;
19670 - case IS_ENA_PS_DIS:
19671 - hdev->flags &= ~HCI_PSCAN;
19672 - hdev->flags |= HCI_ISCAN;
19674 +/* ---- HCI TX task (outgoing data) ---- */
19676 - case IS_DIS_PS_ENA:
19677 - hdev->flags &= ~HCI_ISCAN;
19678 - hdev->flags |= HCI_PSCAN;
19682 - hdev->flags &= ~(HCI_ISCAN | HCI_PSCAN);
19686 - hci_req_complete(hdev, status);
19690 - DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
19695 -/* Command Complete OGF INFO_PARAM */
19696 -static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
19697 +/* HCI Connection scheduler */
19698 +static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
19700 - read_local_features_rp *lf;
19701 - read_buffer_size_rp *bs;
19702 - read_bd_addr_rp *ba;
19704 - DBG("%s ocf 0x%x", hdev->name, ocf);
19707 - case OCF_READ_LOCAL_FEATURES:
19708 - lf = (read_local_features_rp *) skb->data;
19710 - if (lf->status) {
19711 - DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
19715 - memcpy(hdev->features, lf->features, sizeof(hdev->features));
19717 - /* Adjust default settings according to features
19718 - * supported by device. */
19719 - if (hdev->features[0] & LMP_3SLOT)
19720 - hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
19722 - if (hdev->features[0] & LMP_5SLOT)
19723 - hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
19725 - DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
19729 - case OCF_READ_BUFFER_SIZE:
19730 - bs = (read_buffer_size_rp *) skb->data;
19732 - if (bs->status) {
19733 - DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
19737 - hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
19738 - hdev->sco_mtu = bs->sco_mtu;
19739 - hdev->acl_max = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
19740 - hdev->sco_max = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
19742 - DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
19743 - hdev->acl_mtu, hdev->sco_mtu, hdev->acl_max, hdev->sco_max);
19744 + struct conn_hash *h = &hdev->conn_hash;
19745 + struct hci_conn *conn = NULL;
19746 + int num = 0, min = ~0;
19747 + struct list_head *p;
19750 + /* We don't have to lock device here. Connections are always
19751 + * added and removed with TX task disabled. */
19752 + list_for_each(p, &h->list) {
19753 + struct hci_conn *c;
19754 + c = list_entry(p, struct hci_conn, list);
19756 - case OCF_READ_BD_ADDR:
19757 - ba = (read_bd_addr_rp *) skb->data;
19758 + if (c->type != type || c->state != BT_CONNECTED
19759 + || skb_queue_empty(&c->data_q))
19763 - if (!ba->status) {
19764 - bacpy(&hdev->bdaddr, &ba->bdaddr);
19766 - DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
19767 + if (c->sent < min) {
19773 - hci_req_complete(hdev, ba->status);
19776 + int cnt = (type == ACL_LINK ? hdev->acl_cnt : hdev->sco_cnt);
19777 + int q = cnt / num;
19778 + *quote = q ? q : 1;
19783 - DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
19786 + BT_DBG("conn %p quote %d", conn, *quote);
19790 -/* Command Status OGF LINK_CTL */
19791 -static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
19792 +static inline void hci_acl_tx_to(struct hci_dev *hdev)
19794 - struct hci_proto * hp;
19796 - DBG("%s ocf 0x%x", hdev->name, ocf);
19799 - case OCF_CREATE_CONN:
19801 - create_conn_cp *cc = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
19806 - DBG("%s Create connection error: status 0x%x %s", hdev->name,
19807 - status, batostr(&cc->bdaddr));
19808 + struct conn_hash *h = &hdev->conn_hash;
19809 + struct list_head *p;
19810 + struct hci_conn *c;
19812 - /* Notify upper protocols */
19813 - if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm) {
19814 - tasklet_disable(&hdev->tx_task);
19815 - hp->connect_cfm(hdev, &cc->bdaddr, status, NULL);
19816 - tasklet_enable(&hdev->tx_task);
19820 + BT_ERR("%s ACL tx timeout", hdev->name);
19822 - case OCF_INQUIRY:
19824 - DBG("%s Inquiry error: status 0x%x", hdev->name, status);
19825 - hci_req_complete(hdev, status);
19826 + /* Kill stalled connections */
19827 + list_for_each(p, &h->list) {
19828 + c = list_entry(p, struct hci_conn, list);
19829 + if (c->type == ACL_LINK && c->sent) {
19830 + BT_ERR("%s killing stalled ACL connection %s",
19831 + hdev->name, batostr(&c->dst));
19832 + hci_acl_disconn(c, 0x13);
19837 - DBG("%s Command status: ogf LINK_CTL ocf %x", hdev->name, ocf);
19842 -/* Command Status OGF LINK_POLICY */
19843 -static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
19845 - DBG("%s ocf 0x%x", hdev->name, ocf);
19849 - DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
19854 -/* Command Status OGF HOST_CTL */
19855 -static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
19857 - DBG("%s ocf 0x%x", hdev->name, ocf);
19861 - DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
19866 -/* Command Status OGF INFO_PARAM */
19867 -static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
19869 - DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
19873 - DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
19878 -/* Inquiry Complete */
19879 -static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
19881 - __u8 status = *((__u8 *) skb->data);
19883 - DBG("%s status %d", hdev->name, status);
19885 - hci_req_complete(hdev, status);
19889 -/* Inquiry Result */
19890 -static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
19891 +static inline void hci_sched_acl(struct hci_dev *hdev)
19893 - inquiry_info *info = (inquiry_info *) (skb->data + 1);
19894 - int num_rsp = *((__u8 *) skb->data);
19896 - DBG("%s num_rsp %d", hdev->name, num_rsp);
19897 + struct hci_conn *conn;
19898 + struct sk_buff *skb;
19901 - for (; num_rsp; num_rsp--)
19902 - inquiry_cache_update(&hdev->inq_cache, info++);
19904 + BT_DBG("%s", hdev->name);
19906 -/* Connect Request */
19907 -static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
19909 - evt_conn_request *cr = (evt_conn_request *) skb->data;
19910 - struct hci_proto *hp;
19911 - accept_conn_req_cp ac;
19913 + /* ACL tx timeout must be longer than maximum
19914 + * link supervision timeout (40.9 seconds) */
19915 + if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45))
19916 + hci_acl_tx_to(hdev);
19918 - DBG("%s Connection request: %s type 0x%x", hdev->name, batostr(&cr->bdaddr), cr->link_type);
19919 + while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, "e))) {
19920 + while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
19921 + BT_DBG("skb %p len %d", skb, skb->len);
19922 + hci_send_frame(skb);
19923 + hdev->acl_last_tx = jiffies;
19925 - /* Notify upper protocols */
19926 - if (cr->link_type == ACL_LINK) {
19927 - /* ACL link notify L2CAP */
19928 - if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_ind) {
19929 - tasklet_disable(&hdev->tx_task);
19930 - accept = hp->connect_ind(hdev, &cr->bdaddr);
19931 - tasklet_enable(&hdev->tx_task);
19936 - /* SCO link (no notification) */
19937 - /* FIXME: Should be accept it here or let the requester (app) accept it ? */
19942 - /* Connection accepted by upper layer */
19943 - bacpy(&ac.bdaddr, &cr->bdaddr);
19944 - ac.role = 0x01; /* Remain slave */
19945 - hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, ACCEPT_CONN_REQ_CP_SIZE, &ac);
19947 - /* Connection rejected by upper layer */
19949 - * Should we use HCI reject here ?
19955 -/* Connect Complete */
19956 -static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
19957 +/* Schedule SCO */
19958 +static inline void hci_sched_sco(struct hci_dev *hdev)
19960 - evt_conn_complete *cc = (evt_conn_complete *) skb->data;
19961 - struct hci_conn *conn = NULL;
19962 - struct hci_proto *hp;
19964 - DBG("%s", hdev->name);
19966 - tasklet_disable(&hdev->tx_task);
19969 - conn = hci_conn_add(hdev, __le16_to_cpu(cc->handle), cc->link_type, &cc->bdaddr);
19970 + struct hci_conn *conn;
19971 + struct sk_buff *skb;
19974 - /* Notify upper protocols */
19975 - if (cc->link_type == ACL_LINK) {
19976 - /* ACL link notify L2CAP layer */
19977 - if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm)
19978 - hp->connect_cfm(hdev, &cc->bdaddr, cc->status, conn);
19980 - /* SCO link (no notification) */
19982 + BT_DBG("%s", hdev->name);
19984 - tasklet_enable(&hdev->tx_task);
19986 + while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) {
19987 + while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
19988 + BT_DBG("skb %p len %d", skb, skb->len);
19989 + hci_send_frame(skb);
19991 -/* Disconnect Complete */
19992 -static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
19994 - evt_disconn_complete *dc = (evt_disconn_complete *) skb->data;
19995 - struct hci_conn *conn = NULL;
19996 - struct hci_proto *hp;
19997 - __u16 handle = __le16_to_cpu(dc->handle);
19999 - DBG("%s", hdev->name);
20001 - if (!dc->status && (conn = conn_hash_lookup(&hdev->conn_hash, handle))) {
20002 - tasklet_disable(&hdev->tx_task);
20004 - /* Notify upper protocols */
20005 - if (conn->type == ACL_LINK) {
20006 - /* ACL link notify L2CAP layer */
20007 - if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
20008 - hp->disconn_ind(conn, dc->reason);
20010 - /* SCO link (no notification) */
20012 + if (conn->sent == ~0)
20016 - hci_conn_del(hdev, conn);
20018 - tasklet_enable(&hdev->tx_task);
20022 -/* Number of completed packets */
20023 -static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
20024 +static void hci_tx_task(unsigned long arg)
20026 - evt_num_comp_pkts *nc = (evt_num_comp_pkts *) skb->data;
20030 - skb_pull(skb, EVT_NUM_COMP_PKTS_SIZE);
20032 - DBG("%s num_hndl %d", hdev->name, nc->num_hndl);
20033 + struct hci_dev *hdev = (struct hci_dev *) arg;
20034 + struct sk_buff *skb;
20036 - if (skb->len < nc->num_hndl * 4) {
20037 - DBG("%s bad parameters", hdev->name);
20040 + read_lock(&hci_task_lock);
20042 - tasklet_disable(&hdev->tx_task);
20043 + BT_DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
20045 - for (i = 0, ptr = (__u16 *) skb->data; i < nc->num_hndl; i++) {
20046 - struct hci_conn *conn;
20047 - __u16 handle, count;
20048 + /* Schedule queues and send stuff to HCI driver */
20050 - handle = __le16_to_cpu(get_unaligned(ptr++));
20051 - count = __le16_to_cpu(get_unaligned(ptr++));
20052 + hci_sched_acl(hdev);
20054 - hdev->acl_cnt += count;
20055 + hci_sched_sco(hdev);
20057 - if ((conn = conn_hash_lookup(&hdev->conn_hash, handle)))
20058 - conn->sent -= count;
20060 + /* Send next queued raw (unknown type) packet */
20061 + while ((skb = skb_dequeue(&hdev->raw_q)))
20062 + hci_send_frame(skb);
20064 - tasklet_enable(&hdev->tx_task);
20066 - hci_sched_tx(hdev);
20067 + read_unlock(&hci_task_lock);
20070 -static inline void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
20072 - hci_event_hdr *he = (hci_event_hdr *) skb->data;
20073 - evt_cmd_status *cs;
20074 - evt_cmd_complete *ec;
20075 - __u16 opcode, ocf, ogf;
20077 - skb_pull(skb, HCI_EVENT_HDR_SIZE);
20079 - DBG("%s evt 0x%x", hdev->name, he->evt);
20081 - switch (he->evt) {
20082 - case EVT_NUM_COMP_PKTS:
20083 - hci_num_comp_pkts_evt(hdev, skb);
20086 - case EVT_INQUIRY_COMPLETE:
20087 - hci_inquiry_complete_evt(hdev, skb);
20090 - case EVT_INQUIRY_RESULT:
20091 - hci_inquiry_result_evt(hdev, skb);
20094 - case EVT_CONN_REQUEST:
20095 - hci_conn_request_evt(hdev, skb);
20098 - case EVT_CONN_COMPLETE:
20099 - hci_conn_complete_evt(hdev, skb);
20102 - case EVT_DISCONN_COMPLETE:
20103 - hci_disconn_complete_evt(hdev, skb);
20106 - case EVT_CMD_STATUS:
20107 - cs = (evt_cmd_status *) skb->data;
20108 - skb_pull(skb, EVT_CMD_STATUS_SIZE);
20110 - opcode = __le16_to_cpu(cs->opcode);
20111 - ogf = cmd_opcode_ogf(opcode);
20112 - ocf = cmd_opcode_ocf(opcode);
20115 - case OGF_INFO_PARAM:
20116 - hci_cs_info_param(hdev, ocf, cs->status);
20119 - case OGF_HOST_CTL:
20120 - hci_cs_host_ctl(hdev, ocf, cs->status);
20123 - case OGF_LINK_CTL:
20124 - hci_cs_link_ctl(hdev, ocf, cs->status);
20127 - case OGF_LINK_POLICY:
20128 - hci_cs_link_policy(hdev, ocf, cs->status);
20132 - DBG("%s Command Status OGF %x", hdev->name, ogf);
20137 - atomic_set(&hdev->cmd_cnt, 1);
20138 - if (!skb_queue_empty(&hdev->cmd_q))
20139 - hci_sched_cmd(hdev);
20143 - case EVT_CMD_COMPLETE:
20144 - ec = (evt_cmd_complete *) skb->data;
20145 - skb_pull(skb, EVT_CMD_COMPLETE_SIZE);
20147 - opcode = __le16_to_cpu(ec->opcode);
20148 - ogf = cmd_opcode_ogf(opcode);
20149 - ocf = cmd_opcode_ocf(opcode);
20152 - case OGF_INFO_PARAM:
20153 - hci_cc_info_param(hdev, ocf, skb);
20156 - case OGF_HOST_CTL:
20157 - hci_cc_host_ctl(hdev, ocf, skb);
20160 - case OGF_LINK_CTL:
20161 - hci_cc_link_ctl(hdev, ocf, skb);
20164 - case OGF_LINK_POLICY:
20165 - hci_cc_link_policy(hdev, ocf, skb);
20169 - DBG("%s Command Completed OGF %x", hdev->name, ogf);
20174 - atomic_set(&hdev->cmd_cnt, 1);
20175 - if (!skb_queue_empty(&hdev->cmd_q))
20176 - hci_sched_cmd(hdev);
20182 - hdev->stat.evt_rx++;
20184 +/* ----- HCI RX task (incomming data proccessing) ----- */
20186 /* ACL data packet */
20187 static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
20188 @@ -1867,51 +1255,86 @@
20189 flags = acl_flags(handle);
20190 handle = acl_handle(handle);
20192 - DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
20193 + BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
20195 + hdev->stat.acl_rx++;
20197 - if ((conn = conn_hash_lookup(&hdev->conn_hash, handle))) {
20198 + hci_dev_lock(hdev);
20199 + conn = conn_hash_lookup_handle(hdev, handle);
20200 + hci_dev_unlock(hdev);
20203 register struct hci_proto *hp;
20205 /* Send to upper protocol */
20206 - if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->recv_acldata) {
20207 + if ((hp = hci_proto[HCI_PROTO_L2CAP]) && hp->recv_acldata) {
20208 hp->recv_acldata(conn, skb, flags);
20213 - ERR("%s ACL packet for unknown connection handle %d", hdev->name, handle);
20214 + BT_ERR("%s ACL packet for unknown connection handle %d",
20215 + hdev->name, handle);
20220 - hdev->stat.acl_rx++;
20223 /* SCO data packet */
20224 static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
20226 - DBG("%s len %d", hdev->name, skb->len);
20227 + hci_sco_hdr *sh = (void *) skb->data;
20228 + struct hci_conn *conn;
20231 + skb_pull(skb, HCI_SCO_HDR_SIZE);
20233 + handle = __le16_to_cpu(sh->handle);
20235 + BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
20238 hdev->stat.sco_rx++;
20240 + hci_dev_lock(hdev);
20241 + conn = conn_hash_lookup_handle(hdev, handle);
20242 + hci_dev_unlock(hdev);
20245 + register struct hci_proto *hp;
20247 + /* Send to upper protocol */
20248 + if ((hp = hci_proto[HCI_PROTO_SCO]) && hp->recv_scodata) {
20249 + hp->recv_scodata(conn, skb);
20253 + BT_ERR("%s SCO packet for unknown connection handle %d",
20254 + hdev->name, handle);
20260 -/* ----- HCI tasks ----- */
20261 void hci_rx_task(unsigned long arg)
20263 struct hci_dev *hdev = (struct hci_dev *) arg;
20264 struct sk_buff *skb;
20266 - DBG("%s", hdev->name);
20267 + BT_DBG("%s", hdev->name);
20269 read_lock(&hci_task_lock);
20271 while ((skb = skb_dequeue(&hdev->rx_q))) {
20272 - if (hdev->flags & HCI_SOCK) {
20273 + if (atomic_read(&hdev->promisc)) {
20274 /* Send copy to the sockets */
20275 hci_send_to_sock(hdev, skb);
20278 - if (hdev->flags & HCI_INIT) {
20279 + if (test_bit(HCI_RAW, &hdev->flags)) {
20284 + if (test_bit(HCI_INIT, &hdev->flags)) {
20285 /* Don't process data packets in this states. */
20286 switch (skb->pkt_type) {
20287 case HCI_ACLDATA_PKT:
20288 @@ -1921,64 +1344,43 @@
20292 - if (hdev->flags & HCI_NORMAL) {
20293 - /* Process frame */
20294 - switch (skb->pkt_type) {
20295 - case HCI_EVENT_PKT:
20296 - hci_event_packet(hdev, skb);
20298 + /* Process frame */
20299 + switch (skb->pkt_type) {
20300 + case HCI_EVENT_PKT:
20301 + hci_event_packet(hdev, skb);
20304 - case HCI_ACLDATA_PKT:
20305 - DBG("%s ACL data packet", hdev->name);
20306 - hci_acldata_packet(hdev, skb);
20308 + case HCI_ACLDATA_PKT:
20309 + BT_DBG("%s ACL data packet", hdev->name);
20310 + hci_acldata_packet(hdev, skb);
20313 - case HCI_SCODATA_PKT:
20314 - DBG("%s SCO data packet", hdev->name);
20315 - hci_scodata_packet(hdev, skb);
20317 + case HCI_SCODATA_PKT:
20318 + BT_DBG("%s SCO data packet", hdev->name);
20319 + hci_scodata_packet(hdev, skb);
20333 read_unlock(&hci_task_lock);
20336 -static void hci_tx_task(unsigned long arg)
20338 - struct hci_dev *hdev = (struct hci_dev *) arg;
20339 - struct sk_buff *skb;
20341 - read_lock(&hci_task_lock);
20343 - DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
20345 - /* Schedule queues and send stuff to HCI driver */
20347 - hci_sched_acl(hdev);
20349 - hci_sched_sco(hdev);
20351 - /* Send next queued raw (unknown type) packet */
20352 - while ((skb = skb_dequeue(&hdev->raw_q)))
20353 - hci_send_frame(skb);
20355 - read_unlock(&hci_task_lock);
20358 static void hci_cmd_task(unsigned long arg)
20360 struct hci_dev *hdev = (struct hci_dev *) arg;
20361 struct sk_buff *skb;
20363 - DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
20364 + BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
20366 + if (!atomic_read(&hdev->cmd_cnt) && (jiffies - hdev->cmd_last_tx) > HZ) {
20367 + BT_ERR("%s command tx timeout", hdev->name);
20368 + atomic_set(&hdev->cmd_cnt, 1);
20371 /* Send queued commands */
20372 if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) {
20373 if (hdev->sent_cmd)
20374 @@ -1987,6 +1389,7 @@
20375 if ((hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC))) {
20376 atomic_dec(&hdev->cmd_cnt);
20377 hci_send_frame(skb);
20378 + hdev->cmd_last_tx = jiffies;
20380 skb_queue_head(&hdev->cmd_q, skb);
20381 hci_sched_cmd(hdev);
20382 @@ -1994,33 +1397,10 @@
20386 -/* Receive frame from HCI drivers */
20387 -int hci_recv_frame(struct sk_buff *skb)
20389 - struct hci_dev *hdev = (struct hci_dev *) skb->dev;
20391 - if (!hdev || !(hdev->flags & (HCI_UP | HCI_INIT))) {
20396 - DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
20398 - /* Incomming skb */
20399 - bluez_cb(skb)->incomming = 1;
20401 - /* Queue frame for rx task */
20402 - skb_queue_tail(&hdev->rx_q, skb);
20403 - hci_sched_rx(hdev);
20407 +/* ---- Initialization ---- */
20409 int hci_core_init(void)
20412 - spin_lock_init(&hdev_list_lock);
20417 @@ -2028,5 +1408,3 @@
20422 -MODULE_LICENSE("GPL");
20423 diff -urN linux-2.4.18/net/bluetooth/hci_event.c linux-2.4.18-mh15/net/bluetooth/hci_event.c
20424 --- linux-2.4.18/net/bluetooth/hci_event.c 1970-01-01 01:00:00.000000000 +0100
20425 +++ linux-2.4.18-mh15/net/bluetooth/hci_event.c 2004-08-01 16:26:23.000000000 +0200
20428 + BlueZ - Bluetooth protocol stack for Linux
20429 + Copyright (C) 2000-2001 Qualcomm Incorporated
20431 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
20433 + This program is free software; you can redistribute it and/or modify
20434 + it under the terms of the GNU General Public License version 2 as
20435 + published by the Free Software Foundation;
20437 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20438 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20439 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
20440 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
20441 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
20442 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20443 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20444 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20446 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
20447 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
20448 + SOFTWARE IS DISCLAIMED.
20454 + * $Id: hci_event.c,v 1.4 2002/07/27 18:14:38 maxk Exp $
20457 +#include <linux/config.h>
20458 +#include <linux/module.h>
20460 +#include <linux/types.h>
20461 +#include <linux/errno.h>
20462 +#include <linux/kernel.h>
20463 +#include <linux/major.h>
20464 +#include <linux/sched.h>
20465 +#include <linux/slab.h>
20466 +#include <linux/poll.h>
20467 +#include <linux/fcntl.h>
20468 +#include <linux/init.h>
20469 +#include <linux/skbuff.h>
20470 +#include <linux/interrupt.h>
20471 +#include <linux/notifier.h>
20472 +#include <net/sock.h>
20474 +#include <asm/system.h>
20475 +#include <asm/uaccess.h>
20476 +#include <asm/unaligned.h>
20478 +#include <net/bluetooth/bluetooth.h>
20479 +#include <net/bluetooth/hci_core.h>
20481 +#ifndef HCI_CORE_DEBUG
20483 +#define BT_DBG( A... )
20486 +/* Handle HCI Event packets */
20488 +/* Command Complete OGF LINK_CTL */
20489 +static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
20493 + BT_DBG("%s ocf 0x%x", hdev->name, ocf);
20496 + case OCF_INQUIRY_CANCEL:
20497 + status = *((__u8 *) skb->data);
20500 + BT_DBG("%s Inquiry cancel error: status 0x%x", hdev->name, status);
20502 + clear_bit(HCI_INQUIRY, &hdev->flags);
20503 + hci_req_complete(hdev, status);
20508 + BT_DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
20513 +/* Command Complete OGF LINK_POLICY */
20514 +static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
20516 + struct hci_conn *conn;
20517 + role_discovery_rp *rd;
20519 + BT_DBG("%s ocf 0x%x", hdev->name, ocf);
20522 + case OCF_ROLE_DISCOVERY:
20523 + rd = (void *) skb->data;
20528 + hci_dev_lock(hdev);
20530 + conn = conn_hash_lookup_handle(hdev, __le16_to_cpu(rd->handle));
20533 + conn->link_mode &= ~HCI_LM_MASTER;
20535 + conn->link_mode |= HCI_LM_MASTER;
20538 + hci_dev_unlock(hdev);
20542 + BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x",
20543 + hdev->name, ocf);
20548 +/* Command Complete OGF HOST_CTL */
20549 +static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
20551 + __u8 status, param;
20554 + BT_DBG("%s ocf 0x%x", hdev->name, ocf);
20558 + status = *((__u8 *) skb->data);
20559 + hci_req_complete(hdev, status);
20562 + case OCF_SET_EVENT_FLT:
20563 + status = *((__u8 *) skb->data);
20565 + BT_DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
20567 + BT_DBG("%s SET_EVENT_FLT succeseful", hdev->name);
20571 + case OCF_WRITE_AUTH_ENABLE:
20572 + sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE);
20576 + status = *((__u8 *) skb->data);
20577 + param = *((__u8 *) sent);
20580 + if (param == AUTH_ENABLED)
20581 + set_bit(HCI_AUTH, &hdev->flags);
20583 + clear_bit(HCI_AUTH, &hdev->flags);
20585 + hci_req_complete(hdev, status);
20588 + case OCF_WRITE_ENCRYPT_MODE:
20589 + sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE);
20593 + status = *((__u8 *) skb->data);
20594 + param = *((__u8 *) sent);
20598 + set_bit(HCI_ENCRYPT, &hdev->flags);
20600 + clear_bit(HCI_ENCRYPT, &hdev->flags);
20602 + hci_req_complete(hdev, status);
20605 + case OCF_WRITE_CA_TIMEOUT:
20606 + status = *((__u8 *) skb->data);
20608 + BT_DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
20610 + BT_DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
20614 + case OCF_WRITE_PG_TIMEOUT:
20615 + status = *((__u8 *) skb->data);
20617 + BT_DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
20619 + BT_DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
20623 + case OCF_WRITE_SCAN_ENABLE:
20624 + sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE);
20627 + status = *((__u8 *) skb->data);
20628 + param = *((__u8 *) sent);
20630 + BT_DBG("param 0x%x", param);
20633 + clear_bit(HCI_PSCAN, &hdev->flags);
20634 + clear_bit(HCI_ISCAN, &hdev->flags);
20635 + if (param & SCAN_INQUIRY)
20636 + set_bit(HCI_ISCAN, &hdev->flags);
20638 + if (param & SCAN_PAGE)
20639 + set_bit(HCI_PSCAN, &hdev->flags);
20641 + hci_req_complete(hdev, status);
20644 + case OCF_HOST_BUFFER_SIZE:
20645 + status = *((__u8 *) skb->data);
20647 + BT_DBG("%s OCF_BUFFER_SIZE failed %d", hdev->name, status);
20648 + hci_req_complete(hdev, status);
20653 + BT_DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
20658 +/* Command Complete OGF INFO_PARAM */
20659 +static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
20661 + read_local_features_rp *lf;
20662 + read_buffer_size_rp *bs;
20663 + read_bd_addr_rp *ba;
20665 + BT_DBG("%s ocf 0x%x", hdev->name, ocf);
20668 + case OCF_READ_LOCAL_FEATURES:
20669 + lf = (read_local_features_rp *) skb->data;
20671 + if (lf->status) {
20672 + BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
20676 + memcpy(hdev->features, lf->features, sizeof(hdev->features));
20678 + /* Adjust default settings according to features
20679 + * supported by device. */
20680 + if (hdev->features[0] & LMP_3SLOT)
20681 + hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
20683 + if (hdev->features[0] & LMP_5SLOT)
20684 + hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
20686 + if (hdev->features[1] & LMP_HV2)
20687 + hdev->pkt_type |= (HCI_HV2);
20689 + if (hdev->features[1] & LMP_HV3)
20690 + hdev->pkt_type |= (HCI_HV3);
20692 + BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
20696 + case OCF_READ_BUFFER_SIZE:
20697 + bs = (read_buffer_size_rp *) skb->data;
20699 + if (bs->status) {
20700 + BT_DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
20701 + hci_req_complete(hdev, bs->status);
20705 + hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
20706 + hdev->sco_mtu = bs->sco_mtu ? bs->sco_mtu : 64;
20707 + hdev->acl_pkts = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
20708 + hdev->sco_pkts = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
20710 + BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
20711 + hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
20714 + case OCF_READ_BD_ADDR:
20715 + ba = (read_bd_addr_rp *) skb->data;
20717 + if (!ba->status) {
20718 + bacpy(&hdev->bdaddr, &ba->bdaddr);
20720 + BT_DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
20723 + hci_req_complete(hdev, ba->status);
20727 + BT_DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
20732 +/* Command Status OGF LINK_CTL */
20733 +static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
20735 + struct hci_conn *conn;
20736 + create_conn_cp *cc = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
20741 + hci_dev_lock(hdev);
20743 + conn = conn_hash_lookup_ba(hdev, ACL_LINK, &cc->bdaddr);
20745 + BT_DBG("%s status 0x%x bdaddr %s conn %p", hdev->name,
20746 + status, batostr(&cc->bdaddr), conn);
20749 + if (conn && conn->state == BT_CONNECT) {
20750 + conn->state = BT_CLOSED;
20751 + hci_proto_connect_cfm(conn, status);
20752 + hci_conn_del(conn);
20756 + conn = hci_conn_add(hdev, ACL_LINK, &cc->bdaddr);
20759 + conn->link_mode |= HCI_LM_MASTER;
20761 + BT_ERR("No memmory for new connection");
20765 + hci_dev_unlock(hdev);
20768 +static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
20770 + BT_DBG("%s ocf 0x%x", hdev->name, ocf);
20773 + case OCF_CREATE_CONN:
20774 + hci_cs_create_conn(hdev, status);
20777 + case OCF_ADD_SCO:
20779 + struct hci_conn *acl, *sco;
20780 + add_sco_cp *cp = hci_sent_cmd_data(hdev,
20781 + OGF_LINK_CTL, OCF_ADD_SCO);
20787 + handle = __le16_to_cpu(cp->handle);
20789 + BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
20791 + hci_dev_lock(hdev);
20793 + acl = conn_hash_lookup_handle(hdev, handle);
20794 + if (acl && (sco = acl->link)) {
20795 + sco->state = BT_CLOSED;
20796 + hci_proto_connect_cfm(sco, status);
20797 + hci_conn_del(sco);
20800 + hci_dev_unlock(hdev);
20804 + case OCF_INQUIRY:
20806 + BT_DBG("%s Inquiry error: status 0x%x", hdev->name, status);
20807 + hci_req_complete(hdev, status);
20809 + set_bit(HCI_INQUIRY, &hdev->flags);
20814 + BT_DBG("%s Command status: ogf LINK_CTL ocf %x status %d",
20815 + hdev->name, ocf, status);
20820 +/* Command Status OGF LINK_POLICY */
20821 +static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
20823 + BT_DBG("%s ocf 0x%x", hdev->name, ocf);
20827 + BT_DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
20832 +/* Command Status OGF HOST_CTL */
20833 +static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
20835 + BT_DBG("%s ocf 0x%x", hdev->name, ocf);
20839 + BT_DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
20844 +/* Command Status OGF INFO_PARAM */
20845 +static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
20847 + BT_DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
20851 + BT_DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
20856 +/* Inquiry Complete */
20857 +static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
20859 + __u8 status = *((__u8 *) skb->data);
20861 + BT_DBG("%s status %d", hdev->name, status);
20863 + clear_bit(HCI_INQUIRY, &hdev->flags);
20864 + hci_req_complete(hdev, status);
20867 +/* Inquiry Result */
20868 +static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
20870 + inquiry_info *info = (inquiry_info *) (skb->data + 1);
20871 + int num_rsp = *((__u8 *) skb->data);
20873 + BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
20875 + hci_dev_lock(hdev);
20876 + for (; num_rsp; num_rsp--)
20877 + inquiry_cache_update(hdev, info++);
20878 + hci_dev_unlock(hdev);
20881 +/* Inquiry Result With RSSI */
20882 +static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
20884 + inquiry_info_with_rssi *info = (inquiry_info_with_rssi *) (skb->data + 1);
20885 + int num_rsp = *((__u8 *) skb->data);
20887 + BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
20889 + hci_dev_lock(hdev);
20890 + for (; num_rsp; num_rsp--) {
20891 + inquiry_info tmp;
20892 + bacpy(&tmp.bdaddr, &info->bdaddr);
20893 + tmp.pscan_rep_mode = info->pscan_rep_mode;
20894 + tmp.pscan_period_mode = info->pscan_period_mode;
20895 + tmp.pscan_mode = 0x00;
20896 + memcpy(tmp.dev_class, &info->dev_class, 3);
20897 + tmp.clock_offset = info->clock_offset;
20899 + inquiry_cache_update(hdev, &tmp);
20901 + hci_dev_unlock(hdev);
20904 +/* Connect Request */
20905 +static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
20907 + evt_conn_request *cr = (evt_conn_request *) skb->data;
20908 + int mask = hdev->link_mode;
20910 + BT_DBG("%s Connection request: %s type 0x%x", hdev->name,
20911 + batostr(&cr->bdaddr), cr->link_type);
20913 + mask |= hci_proto_connect_ind(hdev, &cr->bdaddr, cr->link_type);
20915 + if (mask & HCI_LM_ACCEPT) {
20916 + /* Connection accepted */
20917 + struct hci_conn *conn;
20918 + accept_conn_req_cp ac;
20920 + hci_dev_lock(hdev);
20921 + conn = conn_hash_lookup_ba(hdev, cr->link_type, &cr->bdaddr);
20923 + if (!(conn = hci_conn_add(hdev, cr->link_type, &cr->bdaddr))) {
20924 + BT_ERR("No memmory for new connection");
20925 + hci_dev_unlock(hdev);
20929 + conn->state = BT_CONNECT;
20930 + hci_dev_unlock(hdev);
20932 + bacpy(&ac.bdaddr, &cr->bdaddr);
20934 + if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
20935 + ac.role = 0x00; /* Become master */
20937 + ac.role = 0x01; /* Remain slave */
20939 + hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ,
20940 + ACCEPT_CONN_REQ_CP_SIZE, &ac);
20942 + /* Connection rejected */
20943 + reject_conn_req_cp rc;
20945 + bacpy(&rc.bdaddr, &cr->bdaddr);
20946 + rc.reason = 0x0f;
20947 + hci_send_cmd(hdev, OGF_LINK_CTL, OCF_REJECT_CONN_REQ,
20948 + REJECT_CONN_REQ_CP_SIZE, &rc);
20952 +/* Connect Complete */
20953 +static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
20955 + evt_conn_complete *cc = (evt_conn_complete *) skb->data;
20956 + struct hci_conn *conn = NULL;
20958 + BT_DBG("%s", hdev->name);
20960 + hci_dev_lock(hdev);
20962 + conn = conn_hash_lookup_ba(hdev, cc->link_type, &cc->bdaddr);
20964 + hci_dev_unlock(hdev);
20968 + if (!cc->status) {
20969 + conn->handle = __le16_to_cpu(cc->handle);
20970 + conn->state = BT_CONNECTED;
20972 + if (test_bit(HCI_AUTH, &hdev->flags))
20973 + conn->link_mode |= HCI_LM_AUTH;
20975 + if (test_bit(HCI_ENCRYPT, &hdev->flags))
20976 + conn->link_mode |= HCI_LM_ENCRYPT;
20979 + /* Set link policy */
20980 + if (conn->type == ACL_LINK && hdev->link_policy) {
20981 + write_link_policy_cp lp;
20982 + lp.handle = cc->handle;
20983 + lp.policy = __cpu_to_le16(hdev->link_policy);
20984 + hci_send_cmd(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY,
20985 + WRITE_LINK_POLICY_CP_SIZE, &lp);
20988 + /* Set packet type for incomming connection */
20989 + if (!conn->out) {
20990 + change_conn_ptype_cp cp;
20991 + cp.handle = cc->handle;
20992 + cp.pkt_type = (conn->type == ACL_LINK) ?
20993 + __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK):
20994 + __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
20996 + hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CHANGE_CONN_PTYPE,
20997 + CHANGE_CONN_PTYPE_CP_SIZE, &cp);
21000 + conn->state = BT_CLOSED;
21002 + if (conn->type == ACL_LINK) {
21003 + struct hci_conn *sco = conn->link;
21006 + hci_add_sco(sco, conn->handle);
21008 + hci_proto_connect_cfm(sco, cc->status);
21009 + hci_conn_del(sco);
21014 + hci_proto_connect_cfm(conn, cc->status);
21016 + hci_conn_del(conn);
21018 + hci_dev_unlock(hdev);
21021 +/* Disconnect Complete */
21022 +static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
21024 + evt_disconn_complete *dc = (evt_disconn_complete *) skb->data;
21025 + struct hci_conn *conn = NULL;
21026 + __u16 handle = __le16_to_cpu(dc->handle);
21028 + BT_DBG("%s status %d", hdev->name, dc->status);
21033 + hci_dev_lock(hdev);
21035 + conn = conn_hash_lookup_handle(hdev, handle);
21037 + conn->state = BT_CLOSED;
21038 + hci_proto_disconn_ind(conn, dc->reason);
21039 + hci_conn_del(conn);
21042 + hci_dev_unlock(hdev);
21045 +/* Number of completed packets */
21046 +static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
21048 + evt_num_comp_pkts *nc = (evt_num_comp_pkts *) skb->data;
21052 + skb_pull(skb, EVT_NUM_COMP_PKTS_SIZE);
21054 + BT_DBG("%s num_hndl %d", hdev->name, nc->num_hndl);
21056 + if (skb->len < nc->num_hndl * 4) {
21057 + BT_DBG("%s bad parameters", hdev->name);
21061 + tasklet_disable(&hdev->tx_task);
21063 + for (i = 0, ptr = (__u16 *) skb->data; i < nc->num_hndl; i++) {
21064 + struct hci_conn *conn;
21065 + __u16 handle, count;
21067 + handle = __le16_to_cpu(get_unaligned(ptr++));
21068 + count = __le16_to_cpu(get_unaligned(ptr++));
21070 + conn = conn_hash_lookup_handle(hdev, handle);
21072 + conn->sent -= count;
21074 + if (conn->type == SCO_LINK) {
21075 + if ((hdev->sco_cnt += count) > hdev->sco_pkts)
21076 + hdev->sco_cnt = hdev->sco_pkts;
21078 + if ((hdev->acl_cnt += count) > hdev->acl_pkts)
21079 + hdev->acl_cnt = hdev->acl_pkts;
21083 + hci_sched_tx(hdev);
21085 + tasklet_enable(&hdev->tx_task);
21089 +static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
21091 + evt_role_change *rc = (evt_role_change *) skb->data;
21092 + struct hci_conn *conn = NULL;
21094 + BT_DBG("%s status %d", hdev->name, rc->status);
21099 + hci_dev_lock(hdev);
21101 + conn = conn_hash_lookup_ba(hdev, ACL_LINK, &rc->bdaddr);
21104 + conn->link_mode &= ~HCI_LM_MASTER;
21106 + conn->link_mode |= HCI_LM_MASTER;
21109 + hci_dev_unlock(hdev);
21112 +/* Authentication Complete */
21113 +static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
21115 + evt_auth_complete *ac = (evt_auth_complete *) skb->data;
21116 + struct hci_conn *conn = NULL;
21117 + __u16 handle = __le16_to_cpu(ac->handle);
21119 + BT_DBG("%s status %d", hdev->name, ac->status);
21121 + hci_dev_lock(hdev);
21123 + conn = conn_hash_lookup_handle(hdev, handle);
21126 + conn->link_mode |= HCI_LM_AUTH;
21127 + clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
21129 + hci_proto_auth_cfm(conn, ac->status);
21131 + if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
21132 + if (!ac->status) {
21133 + set_conn_encrypt_cp ce;
21134 + ce.handle = __cpu_to_le16(conn->handle);
21136 + hci_send_cmd(conn->hdev, OGF_LINK_CTL,
21137 + OCF_SET_CONN_ENCRYPT,
21138 + SET_CONN_ENCRYPT_CP_SIZE, &ce);
21140 + clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
21141 + hci_proto_encrypt_cfm(conn, ac->status);
21146 + hci_dev_unlock(hdev);
21149 +/* Encryption Change */
21150 +static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
21152 + evt_encrypt_change *ec = (evt_encrypt_change *) skb->data;
21153 + struct hci_conn *conn = NULL;
21154 + __u16 handle = __le16_to_cpu(ec->handle);
21156 + BT_DBG("%s status %d", hdev->name, ec->status);
21158 + hci_dev_lock(hdev);
21160 + conn = conn_hash_lookup_handle(hdev, handle);
21162 + if (!ec->status) {
21164 + conn->link_mode |= HCI_LM_ENCRYPT;
21166 + conn->link_mode &= ~HCI_LM_ENCRYPT;
21168 + clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
21170 + hci_proto_encrypt_cfm(conn, ec->status);
21173 + hci_dev_unlock(hdev);
21176 +void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
21178 + hci_event_hdr *he = (hci_event_hdr *) skb->data;
21179 + evt_cmd_status *cs;
21180 + evt_cmd_complete *ec;
21181 + __u16 opcode, ocf, ogf;
21183 + skb_pull(skb, HCI_EVENT_HDR_SIZE);
21185 + BT_DBG("%s evt 0x%x", hdev->name, he->evt);
21187 + switch (he->evt) {
21188 + case EVT_NUM_COMP_PKTS:
21189 + hci_num_comp_pkts_evt(hdev, skb);
21192 + case EVT_INQUIRY_COMPLETE:
21193 + hci_inquiry_complete_evt(hdev, skb);
21196 + case EVT_INQUIRY_RESULT:
21197 + hci_inquiry_result_evt(hdev, skb);
21200 + case EVT_INQUIRY_RESULT_WITH_RSSI:
21201 + hci_inquiry_result_with_rssi_evt(hdev, skb);
21204 + case EVT_CONN_REQUEST:
21205 + hci_conn_request_evt(hdev, skb);
21208 + case EVT_CONN_COMPLETE:
21209 + hci_conn_complete_evt(hdev, skb);
21212 + case EVT_DISCONN_COMPLETE:
21213 + hci_disconn_complete_evt(hdev, skb);
21216 + case EVT_ROLE_CHANGE:
21217 + hci_role_change_evt(hdev, skb);
21220 + case EVT_AUTH_COMPLETE:
21221 + hci_auth_complete_evt(hdev, skb);
21224 + case EVT_ENCRYPT_CHANGE:
21225 + hci_encrypt_change_evt(hdev, skb);
21228 + case EVT_CMD_STATUS:
21229 + cs = (evt_cmd_status *) skb->data;
21230 + skb_pull(skb, EVT_CMD_STATUS_SIZE);
21232 + opcode = __le16_to_cpu(cs->opcode);
21233 + ogf = cmd_opcode_ogf(opcode);
21234 + ocf = cmd_opcode_ocf(opcode);
21237 + case OGF_INFO_PARAM:
21238 + hci_cs_info_param(hdev, ocf, cs->status);
21241 + case OGF_HOST_CTL:
21242 + hci_cs_host_ctl(hdev, ocf, cs->status);
21245 + case OGF_LINK_CTL:
21246 + hci_cs_link_ctl(hdev, ocf, cs->status);
21249 + case OGF_LINK_POLICY:
21250 + hci_cs_link_policy(hdev, ocf, cs->status);
21254 + BT_DBG("%s Command Status OGF %x", hdev->name, ogf);
21259 + atomic_set(&hdev->cmd_cnt, 1);
21260 + if (!skb_queue_empty(&hdev->cmd_q))
21261 + hci_sched_cmd(hdev);
21265 + case EVT_CMD_COMPLETE:
21266 + ec = (evt_cmd_complete *) skb->data;
21267 + skb_pull(skb, EVT_CMD_COMPLETE_SIZE);
21269 + opcode = __le16_to_cpu(ec->opcode);
21270 + ogf = cmd_opcode_ogf(opcode);
21271 + ocf = cmd_opcode_ocf(opcode);
21274 + case OGF_INFO_PARAM:
21275 + hci_cc_info_param(hdev, ocf, skb);
21278 + case OGF_HOST_CTL:
21279 + hci_cc_host_ctl(hdev, ocf, skb);
21282 + case OGF_LINK_CTL:
21283 + hci_cc_link_ctl(hdev, ocf, skb);
21286 + case OGF_LINK_POLICY:
21287 + hci_cc_link_policy(hdev, ocf, skb);
21291 + BT_DBG("%s Command Completed OGF %x", hdev->name, ogf);
21296 + atomic_set(&hdev->cmd_cnt, 1);
21297 + if (!skb_queue_empty(&hdev->cmd_q))
21298 + hci_sched_cmd(hdev);
21304 + hdev->stat.evt_rx++;
21307 +/* General internal stack event */
21308 +void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
21310 + hci_event_hdr *eh;
21311 + evt_stack_internal *si;
21312 + struct sk_buff *skb;
21316 + size = HCI_EVENT_HDR_SIZE + EVT_STACK_INTERNAL_SIZE + dlen;
21317 + skb = bluez_skb_alloc(size, GFP_ATOMIC);
21321 + ptr = skb_put(skb, size);
21324 + eh->evt = EVT_STACK_INTERNAL;
21325 + eh->plen = EVT_STACK_INTERNAL_SIZE + dlen;
21326 + ptr += HCI_EVENT_HDR_SIZE;
21330 + memcpy(si->data, data, dlen);
21332 + skb->pkt_type = HCI_EVENT_PKT;
21333 + skb->dev = (void *) hdev;
21334 + hci_send_to_sock(hdev, skb);
21337 diff -urN linux-2.4.18/net/bluetooth/hci_sock.c linux-2.4.18-mh15/net/bluetooth/hci_sock.c
21338 --- linux-2.4.18/net/bluetooth/hci_sock.c 2001-09-07 18:28:38.000000000 +0200
21339 +++ linux-2.4.18-mh15/net/bluetooth/hci_sock.c 2004-08-01 16:26:23.000000000 +0200
21342 * BlueZ HCI socket layer.
21344 - * $Id: hci_sock.c,v 1.9 2001/08/05 06:02:16 maxk Exp $
21345 + * $Id: hci_sock.c,v 1.5 2002/07/22 20:32:54 maxk Exp $
21348 #include <linux/config.h>
21349 @@ -49,45 +49,54 @@
21351 #include <asm/system.h>
21352 #include <asm/uaccess.h>
21353 +#include <asm/unaligned.h>
21355 #include <net/bluetooth/bluetooth.h>
21356 -#include <net/bluetooth/bluez.h>
21357 #include <net/bluetooth/hci_core.h>
21359 #ifndef HCI_SOCK_DEBUG
21361 -#define DBG( A... )
21363 +#define BT_DBG( A... )
21366 -/* HCI socket interface */
21367 +/* ----- HCI socket interface ----- */
21369 +/* Security filter */
21370 +static struct hci_sec_filter hci_sec_filter = {
21371 + /* Packet types */
21374 + { 0x1000d9fe, 0x0000300c },
21378 + /* OGF_LINK_CTL */
21379 + { 0xbe000006, 0x00000001, 0x0000, 0x00 },
21380 + /* OGF_LINK_POLICY */
21381 + { 0x00005200, 0x00000000, 0x0000, 0x00 },
21382 + /* OGF_HOST_CTL */
21383 + { 0xaab00200, 0x2b402aaa, 0x0154, 0x00 },
21384 + /* OGF_INFO_PARAM */
21385 + { 0x000002be, 0x00000000, 0x0000, 0x00 },
21386 + /* OGF_STATUS_PARAM */
21387 + { 0x000000ea, 0x00000000, 0x0000, 0x00 }
21391 static struct bluez_sock_list hci_sk_list = {
21392 lock: RW_LOCK_UNLOCKED
21395 -static struct sock *hci_sock_lookup(struct hci_dev *hdev)
21399 - read_lock(&hci_sk_list.lock);
21400 - for (sk = hci_sk_list.head; sk; sk = sk->next) {
21401 - if (hci_pi(sk)->hdev == hdev)
21404 - read_unlock(&hci_sk_list.lock);
21408 /* Send frame to RAW socket */
21409 void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
21413 - DBG("hdev %p len %d", hdev, skb->len);
21414 + BT_DBG("hdev %p len %d", hdev, skb->len);
21416 read_lock(&hci_sk_list.lock);
21417 for (sk = hci_sk_list.head; sk; sk = sk->next) {
21418 - struct hci_filter *flt;
21419 + struct hci_filter *flt;
21420 struct sk_buff *nskb;
21422 if (sk->state != BT_BOUND || hci_pi(sk)->hdev != hdev)
21423 @@ -100,13 +109,19 @@
21425 flt = &hci_pi(sk)->filter;
21427 - if (!test_bit(skb->pkt_type, &flt->type_mask))
21428 + if (!hci_test_bit((skb->pkt_type & HCI_FLT_TYPE_BITS), &flt->type_mask))
21431 if (skb->pkt_type == HCI_EVENT_PKT) {
21432 - register int evt = (*(__u8 *)skb->data & 63);
21433 + register int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
21435 + if (!hci_test_bit(evt, &flt->event_mask))
21438 - if (!test_bit(evt, &flt->event_mask))
21439 + if (flt->opcode && ((evt == EVT_CMD_COMPLETE &&
21440 + flt->opcode != *(__u16 *)(skb->data + 3)) ||
21441 + (evt == EVT_CMD_STATUS &&
21442 + flt->opcode != *(__u16 *)(skb->data + 4))))
21446 @@ -116,8 +131,8 @@
21447 /* Put type byte before the data */
21448 memcpy(skb_push(nskb, 1), &nskb->pkt_type, 1);
21450 - skb_queue_tail(&sk->receive_queue, nskb);
21451 - sk->data_ready(sk, nskb->len);
21452 + if (sock_queue_rcv_skb(sk, nskb))
21455 read_unlock(&hci_sk_list.lock);
21457 @@ -127,7 +142,7 @@
21458 struct sock *sk = sock->sk;
21459 struct hci_dev *hdev = hci_pi(sk)->hdev;
21461 - DBG("sock %p sk %p", sock, sk);
21462 + BT_DBG("sock %p sk %p", sock, sk);
21466 @@ -135,9 +150,7 @@
21467 bluez_sock_unlink(&hci_sk_list, sk);
21470 - if (!hci_sock_lookup(hdev))
21471 - hdev->flags &= ~HCI_SOCK;
21473 + atomic_dec(&hdev->promisc);
21477 @@ -149,24 +162,55 @@
21485 -static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
21486 +/* Ioctls that require bound socket */
21487 +static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
21489 - struct sock *sk = sock->sk;
21490 struct hci_dev *hdev = hci_pi(sk)->hdev;
21493 - DBG("cmd %x arg %lx", cmd, arg);
21499 - return hci_dev_info(arg);
21501 + if (!capable(CAP_NET_ADMIN))
21505 + set_bit(HCI_RAW, &hdev->flags);
21507 + clear_bit(HCI_RAW, &hdev->flags);
21511 + case HCIGETCONNINFO:
21512 + return hci_get_conn_info(hdev, arg);
21516 + return hdev->ioctl(hdev, cmd, arg);
21521 +static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
21523 + struct sock *sk = sock->sk;
21526 + BT_DBG("cmd %x arg %lx", cmd, arg);
21529 case HCIGETDEVLIST:
21530 - return hci_dev_list(arg);
21531 + return hci_get_dev_list(arg);
21533 + case HCIGETDEVINFO:
21534 + return hci_get_dev_info(arg);
21536 + case HCIGETCONNLIST:
21537 + return hci_get_conn_list(arg);
21540 if (!capable(CAP_NET_ADMIN))
21541 @@ -183,48 +227,31 @@
21543 return hci_dev_reset(arg);
21545 - case HCIRESETSTAT:
21546 + case HCIDEVRESTAT:
21547 if (!capable(CAP_NET_ADMIN))
21549 return hci_dev_reset_stat(arg);
21552 - if (!capable(CAP_NET_ADMIN))
21554 - return hci_dev_setscan(arg);
21557 - if (!capable(CAP_NET_ADMIN))
21559 - return hci_dev_setauth(arg);
21562 - if (!capable(CAP_NET_ADMIN))
21571 - mode = HCI_NORMAL;
21573 - return hci_dev_setmode(hdev, mode);
21575 + case HCISETENCRYPT:
21577 + case HCISETLINKPOL:
21578 + case HCISETLINKMODE:
21579 + case HCISETACLMTU:
21580 + case HCISETSCOMTU:
21581 if (!capable(CAP_NET_ADMIN))
21583 - return hci_dev_setptype(arg);
21584 + return hci_dev_cmd(cmd, arg);
21587 return hci_inquiry(arg);
21589 - case HCIGETCONNLIST:
21590 - return hci_conn_list(arg);
21595 + err = hci_sock_bound_ioctl(sk, cmd, arg);
21596 + release_sock(sk);
21601 @@ -233,28 +260,35 @@
21602 struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
21603 struct sock *sk = sock->sk;
21604 struct hci_dev *hdev = NULL;
21607 - DBG("sock %p sk %p", sock, sk);
21608 + BT_DBG("sock %p sk %p", sock, sk);
21610 if (!haddr || haddr->hci_family != AF_BLUETOOTH)
21615 if (hci_pi(sk)->hdev) {
21616 - /* Already bound */
21622 if (haddr->hci_dev != HCI_DEV_NONE) {
21623 - if (!(hdev = hci_dev_get(haddr->hci_dev)))
21625 + if (!(hdev = hci_dev_get(haddr->hci_dev))) {
21630 - hdev->flags |= HCI_SOCK;
21631 + atomic_inc(&hdev->promisc);
21634 hci_pi(sk)->hdev = hdev;
21635 sk->state = BT_BOUND;
21639 + release_sock(sk);
21643 static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer)
21644 @@ -262,73 +296,44 @@
21645 struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
21646 struct sock *sk = sock->sk;
21648 - DBG("sock %p sk %p", sock, sk);
21649 + BT_DBG("sock %p sk %p", sock, sk);
21653 *addr_len = sizeof(*haddr);
21654 haddr->hci_family = AF_BLUETOOTH;
21655 haddr->hci_dev = hci_pi(sk)->hdev->id;
21657 + release_sock(sk);
21661 -static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
21662 - struct scm_cookie *scm)
21664 - struct sock *sk = sock->sk;
21665 - struct hci_dev *hdev = hci_pi(sk)->hdev;
21666 - struct sk_buff *skb;
21669 - DBG("sock %p sk %p", sock, sk);
21671 - if (msg->msg_flags & MSG_OOB)
21672 - return -EOPNOTSUPP;
21674 - if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
21680 - if (!(skb = bluez_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
21683 - if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
21688 - skb->dev = (void *) hdev;
21689 - skb->pkt_type = *((unsigned char *) skb->data);
21690 - skb_pull(skb, 1);
21692 - /* Send frame to HCI core */
21693 - hci_send_raw(skb);
21698 static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
21700 __u32 mask = hci_pi(sk)->cmsg_mask;
21702 if (mask & HCI_CMSG_DIR)
21703 put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(int), &bluez_cb(skb)->incomming);
21705 + if (mask & HCI_CMSG_TSTAMP)
21706 + put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, sizeof(skb->stamp), &skb->stamp);
21709 -static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len,
21710 - int flags, struct scm_cookie *scm)
21711 +static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
21713 int noblock = flags & MSG_DONTWAIT;
21714 struct sock *sk = sock->sk;
21715 struct sk_buff *skb;
21718 - DBG("sock %p sk %p", sock, sk);
21719 + BT_DBG("sock %p, sk %p", sock, sk);
21721 - if (flags & (MSG_OOB | MSG_PEEK))
21722 + if (flags & (MSG_OOB))
21723 return -EOPNOTSUPP;
21725 + if (sk->state == BT_CLOSED)
21728 if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
21731 @@ -343,28 +348,107 @@
21732 skb->h.raw = skb->data;
21733 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
21735 - if (hci_pi(sk)->cmsg_mask)
21736 - hci_sock_cmsg(sk, msg, skb);
21738 + hci_sock_cmsg(sk, msg, skb);
21740 skb_free_datagram(sk, skb);
21742 return err ? : copied;
21745 +static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
21746 + struct scm_cookie *scm)
21748 + struct sock *sk = sock->sk;
21749 + struct hci_dev *hdev;
21750 + struct sk_buff *skb;
21753 + BT_DBG("sock %p sk %p", sock, sk);
21755 + if (msg->msg_flags & MSG_OOB)
21756 + return -EOPNOTSUPP;
21758 + if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
21766 + if (!(hdev = hci_pi(sk)->hdev)) {
21771 + if (!(skb = bluez_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
21774 + if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
21779 + skb->pkt_type = *((unsigned char *) skb->data);
21780 + skb_pull(skb, 1);
21781 + skb->dev = (void *) hdev;
21783 + if (skb->pkt_type == HCI_COMMAND_PKT) {
21784 + u16 opcode = __le16_to_cpu(get_unaligned((u16 *)skb->data));
21785 + u16 ogf = cmd_opcode_ogf(opcode);
21786 + u16 ocf = cmd_opcode_ocf(opcode);
21788 + if (((ogf > HCI_SFLT_MAX_OGF) ||
21789 + !hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) &&
21790 + !capable(CAP_NET_RAW)) {
21795 + if (test_bit(HCI_RAW, &hdev->flags) || (ogf == OGF_VENDOR_CMD)) {
21796 + skb_queue_tail(&hdev->raw_q, skb);
21797 + hci_sched_tx(hdev);
21799 + skb_queue_tail(&hdev->cmd_q, skb);
21800 + hci_sched_cmd(hdev);
21803 + if (!capable(CAP_NET_RAW)) {
21808 + skb_queue_tail(&hdev->raw_q, skb);
21809 + hci_sched_tx(hdev);
21815 + release_sock(sk);
21823 int hci_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int len)
21825 struct sock *sk = sock->sk;
21826 - struct hci_filter flt;
21827 + struct hci_filter flt = { opcode: 0 };
21828 int err = 0, opt = 0;
21830 - DBG("sk %p, opt %d", sk, optname);
21831 + BT_DBG("sk %p, opt %d", sk, optname);
21837 - if (get_user(opt, (int *)optval))
21839 + if (get_user(opt, (int *)optval)) {
21845 hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
21846 @@ -372,12 +456,31 @@
21847 hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
21850 + case HCI_TIME_STAMP:
21851 + if (get_user(opt, (int *)optval)) {
21857 + hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
21859 + hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
21863 len = MIN(len, sizeof(struct hci_filter));
21864 if (copy_from_user(&flt, optval, len)) {
21869 + if (!capable(CAP_NET_RAW)) {
21870 + flt.type_mask &= hci_sec_filter.type_mask;
21871 + flt.event_mask[0] &= hci_sec_filter.event_mask[0];
21872 + flt.event_mask[1] &= hci_sec_filter.event_mask[1];
21875 memcpy(&hci_pi(sk)->filter, &flt, len);
21878 @@ -409,6 +512,16 @@
21882 + case HCI_TIME_STAMP:
21883 + if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
21888 + if (put_user(opt, optval))
21893 len = MIN(len, sizeof(struct hci_filter));
21894 if (copy_to_user(optval, &hci_pi(sk)->filter, len))
21895 @@ -446,7 +559,7 @@
21899 - DBG("sock %p", sock);
21900 + BT_DBG("sock %p", sock);
21902 if (sock->type != SOCK_RAW)
21903 return -ESOCKTNOSUPPORT;
21904 @@ -464,44 +577,31 @@
21905 sk->protocol = protocol;
21906 sk->state = BT_OPEN;
21908 - /* Initialize filter */
21909 - hci_pi(sk)->filter.type_mask = (1<<HCI_EVENT_PKT);
21910 - hci_pi(sk)->filter.event_mask[0] = ~0L;
21911 - hci_pi(sk)->filter.event_mask[1] = ~0L;
21913 bluez_sock_link(&hci_sk_list, sk);
21920 static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
21922 struct hci_dev *hdev = (struct hci_dev *) ptr;
21923 - struct sk_buff *skb;
21925 - DBG("hdev %s event %ld", hdev->name, event);
21926 + evt_si_device sd;
21928 + BT_DBG("hdev %s event %ld", hdev->name, event);
21930 /* Send event to sockets */
21931 - if ((skb = bluez_skb_alloc(HCI_EVENT_HDR_SIZE + EVT_HCI_DEV_EVENT_SIZE, GFP_ATOMIC))) {
21932 - hci_event_hdr eh = { EVT_HCI_DEV_EVENT, EVT_HCI_DEV_EVENT_SIZE };
21933 - evt_hci_dev_event he = { event, hdev->id };
21935 - skb->pkt_type = HCI_EVENT_PKT;
21936 - memcpy(skb_put(skb, HCI_EVENT_HDR_SIZE), &eh, HCI_EVENT_HDR_SIZE);
21937 - memcpy(skb_put(skb, EVT_HCI_DEV_EVENT_SIZE), &he, EVT_HCI_DEV_EVENT_SIZE);
21939 - hci_send_to_sock(NULL, skb);
21943 + sd.event = event;
21944 + sd.dev_id = hdev->id;
21945 + hci_si_event(NULL, EVT_SI_DEVICE, EVT_SI_DEVICE_SIZE, &sd);
21947 if (event == HCI_DEV_UNREG) {
21950 /* Detach sockets from device */
21951 read_lock(&hci_sk_list.lock);
21952 for (sk = hci_sk_list.head; sk; sk = sk->next) {
21953 + bh_lock_sock(sk);
21954 if (hci_pi(sk)->hdev == hdev) {
21955 hci_pi(sk)->hdev = NULL;
21957 @@ -510,6 +610,7 @@
21961 + bh_unlock_sock(sk);
21963 read_unlock(&hci_sk_list.lock);
21965 @@ -529,21 +630,19 @@
21966 int hci_sock_init(void)
21968 if (bluez_sock_register(BTPROTO_HCI, &hci_sock_family_ops)) {
21969 - ERR("Can't register HCI socket");
21970 + BT_ERR("Can't register HCI socket");
21974 hci_register_notifier(&hci_sock_nblock);
21979 int hci_sock_cleanup(void)
21981 if (bluez_sock_unregister(BTPROTO_HCI))
21982 - ERR("Can't unregister HCI socket");
21983 + BT_ERR("Can't unregister HCI socket");
21985 hci_unregister_notifier(&hci_sock_nblock);
21989 diff -urN linux-2.4.18/net/bluetooth/hidp/Config.in linux-2.4.18-mh15/net/bluetooth/hidp/Config.in
21990 --- linux-2.4.18/net/bluetooth/hidp/Config.in 1970-01-01 01:00:00.000000000 +0100
21991 +++ linux-2.4.18-mh15/net/bluetooth/hidp/Config.in 2004-08-01 16:26:23.000000000 +0200
21994 +# Bluetooth HIDP layer configuration
21997 +dep_tristate 'HIDP protocol support' CONFIG_BLUEZ_HIDP $CONFIG_INPUT $CONFIG_BLUEZ_L2CAP
21998 diff -urN linux-2.4.18/net/bluetooth/hidp/core.c linux-2.4.18-mh15/net/bluetooth/hidp/core.c
21999 --- linux-2.4.18/net/bluetooth/hidp/core.c 1970-01-01 01:00:00.000000000 +0100
22000 +++ linux-2.4.18-mh15/net/bluetooth/hidp/core.c 2004-08-01 16:26:23.000000000 +0200
22003 + HIDP implementation for Linux Bluetooth stack (BlueZ).
22004 + Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>
22006 + This program is free software; you can redistribute it and/or modify
22007 + it under the terms of the GNU General Public License version 2 as
22008 + published by the Free Software Foundation;
22010 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22011 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22012 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
22013 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
22014 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
22015 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
22016 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22017 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22019 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
22020 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
22021 + SOFTWARE IS DISCLAIMED.
22024 +#include <linux/config.h>
22025 +#include <linux/module.h>
22027 +#include <linux/types.h>
22028 +#include <linux/errno.h>
22029 +#include <linux/kernel.h>
22030 +#include <linux/major.h>
22031 +#include <linux/sched.h>
22032 +#include <linux/slab.h>
22033 +#include <linux/poll.h>
22034 +#include <linux/fcntl.h>
22035 +#include <linux/skbuff.h>
22036 +#include <linux/socket.h>
22037 +#include <linux/ioctl.h>
22038 +#include <linux/file.h>
22039 +#include <linux/init.h>
22040 +#include <net/sock.h>
22042 +#include <linux/input.h>
22044 +#include <net/bluetooth/bluetooth.h>
22045 +#include <net/bluetooth/l2cap.h>
22049 +#ifndef CONFIG_BT_HIDP_DEBUG
22051 +#define BT_DBG(D...)
22054 +#define VERSION "1.0"
22056 +static DECLARE_RWSEM(hidp_session_sem);
22057 +static LIST_HEAD(hidp_session_list);
22059 +static unsigned char hidp_keycode[256] = {
22060 + 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
22061 + 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
22062 + 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
22063 + 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
22064 + 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
22065 + 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
22066 + 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
22067 + 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
22068 + 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,
22069 + 122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22070 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22071 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22072 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22073 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22074 + 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
22075 + 150,158,159,128,136,177,178,176,142,152,173,140
22078 +static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr)
22080 + struct hidp_session *session;
22081 + struct list_head *p;
22085 + list_for_each(p, &hidp_session_list) {
22086 + session = list_entry(p, struct hidp_session, list);
22087 + if (!bacmp(bdaddr, &session->bdaddr))
22093 +static void __hidp_link_session(struct hidp_session *session)
22095 + MOD_INC_USE_COUNT;
22096 + list_add(&session->list, &hidp_session_list);
22099 +static void __hidp_unlink_session(struct hidp_session *session)
22101 + list_del(&session->list);
22102 + MOD_DEC_USE_COUNT;
22105 +static void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci)
22107 + bacpy(&ci->bdaddr, &session->bdaddr);
22109 + ci->flags = session->flags;
22110 + ci->state = session->state;
22112 + ci->vendor = 0x0000;
22113 + ci->product = 0x0000;
22114 + ci->version = 0x0000;
22115 + memset(ci->name, 0, 128);
22117 + if (session->input) {
22118 + ci->vendor = session->input->idvendor;
22119 + ci->product = session->input->idproduct;
22120 + ci->version = session->input->idversion;
22121 + if (session->input->name)
22122 + strncpy(ci->name, session->input->name, 128);
22124 + strncpy(ci->name, "HID Boot Device", 128);
22128 +static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
22130 + struct hidp_session *session = dev->private;
22131 + struct sk_buff *skb;
22132 + unsigned char newleds;
22134 + BT_DBG("session %p hid %p data %p size %d", session, device, data, size);
22136 + if (type != EV_LED)
22139 + newleds = (!!test_bit(LED_KANA, dev->led) << 3) |
22140 + (!!test_bit(LED_COMPOSE, dev->led) << 3) |
22141 + (!!test_bit(LED_SCROLLL, dev->led) << 2) |
22142 + (!!test_bit(LED_CAPSL, dev->led) << 1) |
22143 + (!!test_bit(LED_NUML, dev->led));
22145 + if (session->leds == newleds)
22148 + session->leds = newleds;
22150 + if (!(skb = alloc_skb(3, GFP_ATOMIC))) {
22151 + BT_ERR("Can't allocate memory for new frame");
22155 + *skb_put(skb, 1) = 0xa2;
22156 + *skb_put(skb, 1) = 0x01;
22157 + *skb_put(skb, 1) = newleds;
22159 + skb_queue_tail(&session->intr_transmit, skb);
22161 + hidp_schedule(session);
22166 +static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
22168 + struct input_dev *dev = session->input;
22169 + unsigned char *keys = session->keys;
22170 + unsigned char *udata = skb->data + 1;
22171 + signed char *sdata = skb->data + 1;
22172 + int i, size = skb->len - 1;
22174 + switch (skb->data[0]) {
22175 + case 0x01: /* Keyboard report */
22176 + for (i = 0; i < 8; i++)
22177 + input_report_key(dev, hidp_keycode[i + 224], (udata[0] >> i) & 1);
22179 + for (i = 2; i < 8; i++) {
22180 + if (keys[i] > 3 && memscan(udata + 2, keys[i], 6) == udata + 8) {
22181 + if (hidp_keycode[keys[i]])
22182 + input_report_key(dev, hidp_keycode[keys[i]], 0);
22184 + BT_ERR("Unknown key (scancode %#x) released.", keys[i]);
22187 + if (udata[i] > 3 && memscan(keys + 2, udata[i], 6) == keys + 8) {
22188 + if (hidp_keycode[udata[i]])
22189 + input_report_key(dev, hidp_keycode[udata[i]], 1);
22191 + BT_ERR("Unknown key (scancode %#x) pressed.", udata[i]);
22195 + memcpy(keys, udata, 8);
22198 + case 0x02: /* Mouse report */
22199 + input_report_key(dev, BTN_LEFT, sdata[0] & 0x01);
22200 + input_report_key(dev, BTN_RIGHT, sdata[0] & 0x02);
22201 + input_report_key(dev, BTN_MIDDLE, sdata[0] & 0x04);
22202 + input_report_key(dev, BTN_SIDE, sdata[0] & 0x08);
22203 + input_report_key(dev, BTN_EXTRA, sdata[0] & 0x10);
22205 + input_report_rel(dev, REL_X, sdata[1]);
22206 + input_report_rel(dev, REL_Y, sdata[2]);
22209 + input_report_rel(dev, REL_WHEEL, sdata[3]);
22213 + input_event(dev, EV_RST, 0, 0);
22216 +static void hidp_idle_timeout(unsigned long arg)
22218 + struct hidp_session *session = (struct hidp_session *) arg;
22220 + atomic_inc(&session->terminate);
22221 + hidp_schedule(session);
22224 +static inline void hidp_set_timer(struct hidp_session *session)
22226 + if (session->idle_to > 0)
22227 + mod_timer(&session->timer, jiffies + HZ * session->idle_to);
22230 +static inline void hidp_del_timer(struct hidp_session *session)
22232 + if (session->idle_to > 0)
22233 + del_timer(&session->timer);
22236 +static inline void hidp_send_message(struct hidp_session *session, unsigned char hdr)
22238 + struct sk_buff *skb;
22240 + BT_DBG("session %p", session);
22242 + if (!(skb = alloc_skb(1, GFP_ATOMIC))) {
22243 + BT_ERR("Can't allocate memory for message");
22247 + *skb_put(skb, 1) = hdr;
22249 + skb_queue_tail(&session->ctrl_transmit, skb);
22251 + hidp_schedule(session);
22254 +static inline int hidp_recv_frame(struct hidp_session *session, struct sk_buff *skb)
22258 + BT_DBG("session %p skb %p len %d", session, skb, skb->len);
22260 + hdr = skb->data[0];
22261 + skb_pull(skb, 1);
22263 + if (hdr == 0xa1) {
22264 + hidp_set_timer(session);
22266 + if (session->input)
22267 + hidp_input_report(session, skb);
22269 + BT_DBG("Unsupported protocol header 0x%02x", hdr);
22276 +static int hidp_send_frame(struct socket *sock, unsigned char *data, int len)
22278 + struct iovec iv = { data, len };
22279 + struct msghdr msg;
22281 + BT_DBG("sock %p data %p len %d", sock, data, len);
22286 + memset(&msg, 0, sizeof(msg));
22287 + msg.msg_iovlen = 1;
22288 + msg.msg_iov = &iv;
22290 + return sock_sendmsg(sock, &msg, len);
22293 +static int hidp_process_transmit(struct hidp_session *session)
22295 + struct sk_buff *skb;
22297 + BT_DBG("session %p", session);
22299 + while ((skb = skb_dequeue(&session->ctrl_transmit))) {
22300 + if (hidp_send_frame(session->ctrl_sock, skb->data, skb->len) < 0) {
22301 + skb_queue_head(&session->ctrl_transmit, skb);
22305 + hidp_set_timer(session);
22309 + while ((skb = skb_dequeue(&session->intr_transmit))) {
22310 + if (hidp_send_frame(session->intr_sock, skb->data, skb->len) < 0) {
22311 + skb_queue_head(&session->intr_transmit, skb);
22315 + hidp_set_timer(session);
22319 + return skb_queue_len(&session->ctrl_transmit) +
22320 + skb_queue_len(&session->intr_transmit);
22323 +static int hidp_session(void *arg)
22325 + struct hidp_session *session = arg;
22326 + struct sock *ctrl_sk = session->ctrl_sock->sk;
22327 + struct sock *intr_sk = session->intr_sock->sk;
22328 + struct sk_buff *skb;
22329 + int vendor = 0x0000, product = 0x0000;
22330 + wait_queue_t ctrl_wait, intr_wait;
22331 + unsigned long timeo = HZ;
22333 + BT_DBG("session %p", session);
22335 + if (session->input) {
22336 + vendor = session->input->idvendor;
22337 + product = session->input->idproduct;
22340 + daemonize(); reparent_to_init();
22342 + sprintf(current->comm, "khidpd_%04x%04x", vendor, product);
22344 + sigfillset(¤t->blocked);
22345 + flush_signals(current);
22347 + current->nice = -15;
22349 + set_fs(KERNEL_DS);
22351 + init_waitqueue_entry(&ctrl_wait, current);
22352 + init_waitqueue_entry(&intr_wait, current);
22353 + add_wait_queue(ctrl_sk->sleep, &ctrl_wait);
22354 + add_wait_queue(intr_sk->sleep, &intr_wait);
22355 + while (!atomic_read(&session->terminate)) {
22356 + set_current_state(TASK_INTERRUPTIBLE);
22358 + if (ctrl_sk->state != BT_CONNECTED || intr_sk->state != BT_CONNECTED)
22361 + while ((skb = skb_dequeue(&ctrl_sk->receive_queue))) {
22363 + hidp_recv_frame(session, skb);
22366 + while ((skb = skb_dequeue(&intr_sk->receive_queue))) {
22368 + hidp_recv_frame(session, skb);
22371 + hidp_process_transmit(session);
22375 + set_current_state(TASK_RUNNING);
22376 + remove_wait_queue(intr_sk->sleep, &intr_wait);
22377 + remove_wait_queue(ctrl_sk->sleep, &ctrl_wait);
22379 + down_write(&hidp_session_sem);
22381 + hidp_del_timer(session);
22383 + if (intr_sk->state != BT_CONNECTED) {
22384 + init_waitqueue_entry(&ctrl_wait, current);
22385 + add_wait_queue(ctrl_sk->sleep, &ctrl_wait);
22386 + while (timeo && ctrl_sk->state != BT_CLOSED) {
22387 + set_current_state(TASK_INTERRUPTIBLE);
22388 + timeo = schedule_timeout(timeo);
22390 + set_current_state(TASK_RUNNING);
22391 + remove_wait_queue(ctrl_sk->sleep, &ctrl_wait);
22395 + fput(session->ctrl_sock->file);
22397 + init_waitqueue_entry(&intr_wait, current);
22398 + add_wait_queue(intr_sk->sleep, &intr_wait);
22399 + while (timeo && intr_sk->state != BT_CLOSED) {
22400 + set_current_state(TASK_INTERRUPTIBLE);
22401 + timeo = schedule_timeout(timeo);
22403 + set_current_state(TASK_RUNNING);
22404 + remove_wait_queue(intr_sk->sleep, &intr_wait);
22406 + fput(session->intr_sock->file);
22408 + __hidp_unlink_session(session);
22410 + if (session->input) {
22411 + input_unregister_device(session->input);
22412 + kfree(session->input);
22415 + up_write(&hidp_session_sem);
22421 +static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req)
22423 + struct input_dev *input = session->input;
22426 + input->private = session;
22428 + input->idbus = BUS_BLUETOOTH;
22429 + input->idvendor = req->vendor;
22430 + input->idproduct = req->product;
22431 + input->idversion = req->version;
22433 + if (req->subclass & 0x40) {
22434 + set_bit(EV_KEY, input->evbit);
22435 + set_bit(EV_LED, input->evbit);
22436 + set_bit(EV_REP, input->evbit);
22438 + set_bit(LED_NUML, input->ledbit);
22439 + set_bit(LED_CAPSL, input->ledbit);
22440 + set_bit(LED_SCROLLL, input->ledbit);
22441 + set_bit(LED_COMPOSE, input->ledbit);
22442 + set_bit(LED_KANA, input->ledbit);
22444 + for (i = 0; i < sizeof(hidp_keycode); i++)
22445 + set_bit(hidp_keycode[i], input->keybit);
22446 + clear_bit(0, input->keybit);
22449 + if (req->subclass & 0x80) {
22450 + input->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
22451 + input->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
22452 + input->relbit[0] = BIT(REL_X) | BIT(REL_Y);
22453 + input->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
22454 + input->relbit[0] |= BIT(REL_WHEEL);
22457 + input->event = hidp_input_event;
22459 + input_register_device(input);
22462 +int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
22464 + struct hidp_session *session, *s;
22469 + if (bacmp(&bluez_pi(ctrl_sock->sk)->src, &bluez_pi(intr_sock->sk)->src) ||
22470 + bacmp(&bluez_pi(ctrl_sock->sk)->dst, &bluez_pi(intr_sock->sk)->dst))
22471 + return -ENOTUNIQ;
22473 + session = kmalloc(sizeof(struct hidp_session), GFP_KERNEL);
22476 + memset(session, 0, sizeof(struct hidp_session));
22478 + session->input = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
22479 + if (!session->input) {
22483 + memset(session->input, 0, sizeof(struct input_dev));
22485 + down_write(&hidp_session_sem);
22487 + s = __hidp_get_session(&bluez_pi(ctrl_sock->sk)->dst);
22488 + if (s && s->state == BT_CONNECTED) {
22493 + bacpy(&session->bdaddr, &bluez_pi(ctrl_sock->sk)->dst);
22495 + session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl_sock->sk)->omtu, l2cap_pi(ctrl_sock->sk)->imtu);
22496 + session->intr_mtu = min_t(uint, l2cap_pi(intr_sock->sk)->omtu, l2cap_pi(intr_sock->sk)->imtu);
22498 + BT_DBG("ctrl mtu %d intr mtu %d", session->ctrl_mtu, session->intr_mtu);
22500 + session->ctrl_sock = ctrl_sock;
22501 + session->intr_sock = intr_sock;
22502 + session->state = BT_CONNECTED;
22504 + init_timer(&session->timer);
22506 + session->timer.function = hidp_idle_timeout;
22507 + session->timer.data = (unsigned long) session;
22509 + skb_queue_head_init(&session->ctrl_transmit);
22510 + skb_queue_head_init(&session->intr_transmit);
22512 + session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID);
22513 + session->idle_to = req->idle_to;
22515 + if (session->input)
22516 + hidp_setup_input(session, req);
22518 + __hidp_link_session(session);
22520 + hidp_set_timer(session);
22522 + err = kernel_thread(hidp_session, session, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
22526 + if (session->input) {
22527 + hidp_send_message(session, 0x70);
22528 + session->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE);
22530 + session->leds = 0xff;
22531 + hidp_input_event(session->input, EV_LED, 0, 0);
22534 + up_write(&hidp_session_sem);
22538 + hidp_del_timer(session);
22540 + __hidp_unlink_session(session);
22542 + if (session->input)
22543 + input_unregister_device(session->input);
22546 + up_write(&hidp_session_sem);
22548 + if (session->input)
22549 + kfree(session->input);
22555 +int hidp_del_connection(struct hidp_conndel_req *req)
22557 + struct hidp_session *session;
22562 + down_read(&hidp_session_sem);
22564 + session = __hidp_get_session(&req->bdaddr);
22566 + if (req->flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG)) {
22567 + hidp_send_message(session, 0x15);
22569 + /* Flush the transmit queues */
22570 + skb_queue_purge(&session->ctrl_transmit);
22571 + skb_queue_purge(&session->intr_transmit);
22573 + /* Kill session thread */
22574 + atomic_inc(&session->terminate);
22575 + hidp_schedule(session);
22580 + up_read(&hidp_session_sem);
22584 +int hidp_get_connlist(struct hidp_connlist_req *req)
22586 + struct list_head *p;
22587 + int err = 0, n = 0;
22591 + down_read(&hidp_session_sem);
22593 + list_for_each(p, &hidp_session_list) {
22594 + struct hidp_session *session;
22595 + struct hidp_conninfo ci;
22597 + session = list_entry(p, struct hidp_session, list);
22599 + __hidp_copy_session(session, &ci);
22601 + if (copy_to_user(req->ci, &ci, sizeof(ci))) {
22606 + if (++n >= req->cnum)
22613 + up_read(&hidp_session_sem);
22617 +int hidp_get_conninfo(struct hidp_conninfo *ci)
22619 + struct hidp_session *session;
22622 + down_read(&hidp_session_sem);
22624 + session = __hidp_get_session(&ci->bdaddr);
22626 + __hidp_copy_session(session, ci);
22630 + up_read(&hidp_session_sem);
22634 +static int __init hidp_init(void)
22638 + hidp_init_sockets();
22640 + BT_INFO("BlueZ HIDP ver %s", VERSION);
22641 + BT_INFO("Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>");
22646 +static void __exit hidp_exit(void)
22648 + hidp_cleanup_sockets();
22651 +module_init(hidp_init);
22652 +module_exit(hidp_exit);
22654 +MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
22655 +MODULE_DESCRIPTION("Bluetooth HIDP ver " VERSION);
22656 +MODULE_LICENSE("GPL");
22657 diff -urN linux-2.4.18/net/bluetooth/hidp/hidp.h linux-2.4.18-mh15/net/bluetooth/hidp/hidp.h
22658 --- linux-2.4.18/net/bluetooth/hidp/hidp.h 1970-01-01 01:00:00.000000000 +0100
22659 +++ linux-2.4.18-mh15/net/bluetooth/hidp/hidp.h 2004-08-01 16:26:23.000000000 +0200
22662 + HIDP implementation for Linux Bluetooth stack (BlueZ).
22663 + Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>
22665 + This program is free software; you can redistribute it and/or modify
22666 + it under the terms of the GNU General Public License version 2 as
22667 + published by the Free Software Foundation;
22669 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22670 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22671 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
22672 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
22673 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
22674 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
22675 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22676 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22678 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
22679 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
22680 + SOFTWARE IS DISCLAIMED.
22686 +#include <linux/types.h>
22687 +#include <net/bluetooth/bluetooth.h>
22689 +/* HIDP ioctl defines */
22690 +#define HIDPCONNADD _IOW('H', 200, int)
22691 +#define HIDPCONNDEL _IOW('H', 201, int)
22692 +#define HIDPGETCONNLIST _IOR('H', 210, int)
22693 +#define HIDPGETCONNINFO _IOR('H', 211, int)
22695 +#define HIDP_VIRTUAL_CABLE_UNPLUG 0
22696 +#define HIDP_BOOT_PROTOCOL_MODE 1
22697 +#define HIDP_BLUETOOTH_VENDOR_ID 9
22699 +struct hidp_connadd_req {
22700 + int ctrl_sock; // Connected control socket
22701 + int intr_sock; // Connteted interrupt socket
22715 +struct hidp_conndel_req {
22720 +struct hidp_conninfo {
22730 +struct hidp_connlist_req {
22732 + struct hidp_conninfo *ci;
22735 +int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock);
22736 +int hidp_del_connection(struct hidp_conndel_req *req);
22737 +int hidp_get_connlist(struct hidp_connlist_req *req);
22738 +int hidp_get_conninfo(struct hidp_conninfo *ci);
22740 +/* HIDP session defines */
22741 +struct hidp_session {
22742 + struct list_head list;
22744 + struct socket *ctrl_sock;
22745 + struct socket *intr_sock;
22749 + unsigned long state;
22750 + unsigned long flags;
22751 + unsigned long idle_to;
22756 + atomic_t terminate;
22758 + unsigned char keys[8];
22759 + unsigned char leds;
22761 + struct input_dev *input;
22763 + struct timer_list timer;
22765 + struct sk_buff_head ctrl_transmit;
22766 + struct sk_buff_head intr_transmit;
22769 +static inline void hidp_schedule(struct hidp_session *session)
22771 + struct sock *ctrl_sk = session->ctrl_sock->sk;
22772 + struct sock *intr_sk = session->intr_sock->sk;
22774 + wake_up_interruptible(ctrl_sk->sleep);
22775 + wake_up_interruptible(intr_sk->sleep);
22778 +/* HIDP init defines */
22779 +extern int __init hidp_init_sockets(void);
22780 +extern void __exit hidp_cleanup_sockets(void);
22782 +#endif /* __HIDP_H */
22783 diff -urN linux-2.4.18/net/bluetooth/hidp/Makefile linux-2.4.18-mh15/net/bluetooth/hidp/Makefile
22784 --- linux-2.4.18/net/bluetooth/hidp/Makefile 1970-01-01 01:00:00.000000000 +0100
22785 +++ linux-2.4.18-mh15/net/bluetooth/hidp/Makefile 2004-08-01 16:26:23.000000000 +0200
22788 +# Makefile for the Linux Bluetooth HIDP layer
22791 +O_TARGET := hidp.o
22793 +obj-y := core.o sock.o
22794 +obj-m += $(O_TARGET)
22796 +include $(TOPDIR)/Rules.make
22797 diff -urN linux-2.4.18/net/bluetooth/hidp/sock.c linux-2.4.18-mh15/net/bluetooth/hidp/sock.c
22798 --- linux-2.4.18/net/bluetooth/hidp/sock.c 1970-01-01 01:00:00.000000000 +0100
22799 +++ linux-2.4.18-mh15/net/bluetooth/hidp/sock.c 2004-08-01 16:26:23.000000000 +0200
22802 + HIDP implementation for Linux Bluetooth stack (BlueZ).
22803 + Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>
22805 + This program is free software; you can redistribute it and/or modify
22806 + it under the terms of the GNU General Public License version 2 as
22807 + published by the Free Software Foundation;
22809 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22810 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22811 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
22812 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
22813 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
22814 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
22815 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22816 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22818 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
22819 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
22820 + SOFTWARE IS DISCLAIMED.
22823 +#include <linux/config.h>
22824 +#include <linux/module.h>
22826 +#include <linux/types.h>
22827 +#include <linux/errno.h>
22828 +#include <linux/kernel.h>
22829 +#include <linux/major.h>
22830 +#include <linux/sched.h>
22831 +#include <linux/slab.h>
22832 +#include <linux/poll.h>
22833 +#include <linux/fcntl.h>
22834 +#include <linux/skbuff.h>
22835 +#include <linux/socket.h>
22836 +#include <linux/ioctl.h>
22837 +#include <linux/file.h>
22838 +#include <linux/init.h>
22839 +#include <net/sock.h>
22843 +#ifndef CONFIG_BT_HIDP_DEBUG
22845 +#define BT_DBG(D...)
22848 +static int hidp_sock_release(struct socket *sock)
22850 + struct sock *sk = sock->sk;
22852 + BT_DBG("sock %p sk %p", sock, sk);
22860 + MOD_DEC_USE_COUNT;
22864 +static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
22866 + struct hidp_connadd_req ca;
22867 + struct hidp_conndel_req cd;
22868 + struct hidp_connlist_req cl;
22869 + struct hidp_conninfo ci;
22870 + struct socket *csock;
22871 + struct socket *isock;
22874 + BT_DBG("cmd %x arg %lx", cmd, arg);
22877 + case HIDPCONNADD:
22878 + if (!capable(CAP_NET_ADMIN))
22881 + if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
22884 + csock = sockfd_lookup(ca.ctrl_sock, &err);
22888 + isock = sockfd_lookup(ca.intr_sock, &err);
22890 + fput(csock->file);
22894 + if (csock->sk->state != BT_CONNECTED || isock->sk->state != BT_CONNECTED) {
22895 + fput(csock->file);
22896 + fput(isock->file);
22900 + err = hidp_add_connection(&ca, csock, isock);
22902 + if (copy_to_user((void *) arg, &ca, sizeof(ca)))
22905 + fput(csock->file);
22906 + fput(isock->file);
22911 + case HIDPCONNDEL:
22912 + if (!capable(CAP_NET_ADMIN))
22915 + if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
22918 + return hidp_del_connection(&cd);
22920 + case HIDPGETCONNLIST:
22921 + if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
22924 + if (cl.cnum <= 0)
22927 + err = hidp_get_connlist(&cl);
22928 + if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
22933 + case HIDPGETCONNINFO:
22934 + if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
22937 + err = hidp_get_conninfo(&ci);
22938 + if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
22947 +static struct proto_ops hidp_sock_ops = {
22948 + family: PF_BLUETOOTH,
22949 + release: hidp_sock_release,
22950 + ioctl: hidp_sock_ioctl,
22951 + bind: sock_no_bind,
22952 + getname: sock_no_getname,
22953 + sendmsg: sock_no_sendmsg,
22954 + recvmsg: sock_no_recvmsg,
22955 + poll: sock_no_poll,
22956 + listen: sock_no_listen,
22957 + shutdown: sock_no_shutdown,
22958 + setsockopt: sock_no_setsockopt,
22959 + getsockopt: sock_no_getsockopt,
22960 + connect: sock_no_connect,
22961 + socketpair: sock_no_socketpair,
22962 + accept: sock_no_accept,
22963 + mmap: sock_no_mmap
22966 +static int hidp_sock_create(struct socket *sock, int protocol)
22970 + BT_DBG("sock %p", sock);
22972 + if (sock->type != SOCK_RAW)
22973 + return -ESOCKTNOSUPPORT;
22975 + sock->ops = &hidp_sock_ops;
22977 + if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, 1)))
22980 + MOD_INC_USE_COUNT;
22982 + sock->state = SS_UNCONNECTED;
22983 + sock_init_data(sock, sk);
22985 + sk->destruct = NULL;
22986 + sk->protocol = protocol;
22991 +static struct net_proto_family hidp_sock_family_ops = {
22992 + family: PF_BLUETOOTH,
22993 + create: hidp_sock_create
22996 +int __init hidp_init_sockets(void)
23000 + if ((err = bluez_sock_register(BTPROTO_HIDP, &hidp_sock_family_ops)))
23001 + BT_ERR("Can't register HIDP socket layer (%d)", err);
23006 +void __exit hidp_cleanup_sockets(void)
23010 + if ((err = bluez_sock_unregister(BTPROTO_HIDP)))
23011 + BT_ERR("Can't unregister HIDP socket layer (%d)", err);
23013 diff -urN linux-2.4.18/net/bluetooth/l2cap.c linux-2.4.18-mh15/net/bluetooth/l2cap.c
23014 --- linux-2.4.18/net/bluetooth/l2cap.c 1970-01-01 01:00:00.000000000 +0100
23015 +++ linux-2.4.18-mh15/net/bluetooth/l2cap.c 2004-08-01 16:26:23.000000000 +0200
23018 + BlueZ - Bluetooth protocol stack for Linux
23019 + Copyright (C) 2000-2001 Qualcomm Incorporated
23021 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
23023 + This program is free software; you can redistribute it and/or modify
23024 + it under the terms of the GNU General Public License version 2 as
23025 + published by the Free Software Foundation;
23027 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23028 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23029 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
23030 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
23031 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
23032 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
23033 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
23034 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23036 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
23037 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
23038 + SOFTWARE IS DISCLAIMED.
23042 + * BlueZ L2CAP core and sockets.
23044 + * $Id: l2cap.c,v 1.15 2002/09/09 01:14:52 maxk Exp $
23046 +#define VERSION "2.3"
23048 +#include <linux/config.h>
23049 +#include <linux/module.h>
23051 +#include <linux/types.h>
23052 +#include <linux/errno.h>
23053 +#include <linux/kernel.h>
23054 +#include <linux/major.h>
23055 +#include <linux/sched.h>
23056 +#include <linux/slab.h>
23057 +#include <linux/poll.h>
23058 +#include <linux/fcntl.h>
23059 +#include <linux/init.h>
23060 +#include <linux/skbuff.h>
23061 +#include <linux/interrupt.h>
23062 +#include <linux/socket.h>
23063 +#include <linux/skbuff.h>
23064 +#include <linux/proc_fs.h>
23065 +#include <linux/list.h>
23066 +#include <net/sock.h>
23068 +#include <asm/system.h>
23069 +#include <asm/uaccess.h>
23070 +#include <asm/unaligned.h>
23072 +#include <net/bluetooth/bluetooth.h>
23073 +#include <net/bluetooth/hci_core.h>
23074 +#include <net/bluetooth/l2cap.h>
23076 +#ifndef L2CAP_DEBUG
23078 +#define BT_DBG( A... )
23081 +static struct proto_ops l2cap_sock_ops;
23083 +struct bluez_sock_list l2cap_sk_list = {
23084 + lock: RW_LOCK_UNLOCKED
23087 +static int l2cap_conn_del(struct hci_conn *conn, int err);
23089 +static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
23090 +static void l2cap_chan_del(struct sock *sk, int err);
23091 +static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len);
23093 +static void __l2cap_sock_close(struct sock *sk, int reason);
23094 +static void l2cap_sock_close(struct sock *sk);
23095 +static void l2cap_sock_kill(struct sock *sk);
23097 +static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data);
23098 +static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data);
23100 +/* ----- L2CAP timers ------ */
23101 +static void l2cap_sock_timeout(unsigned long arg)
23103 + struct sock *sk = (struct sock *) arg;
23105 + BT_DBG("sock %p state %d", sk, sk->state);
23107 + bh_lock_sock(sk);
23108 + __l2cap_sock_close(sk, ETIMEDOUT);
23109 + bh_unlock_sock(sk);
23111 + l2cap_sock_kill(sk);
23115 +static void l2cap_sock_set_timer(struct sock *sk, long timeout)
23117 + BT_DBG("sk %p state %d timeout %ld", sk, sk->state, timeout);
23119 + if (!mod_timer(&sk->timer, jiffies + timeout))
23123 +static void l2cap_sock_clear_timer(struct sock *sk)
23125 + BT_DBG("sock %p state %d", sk, sk->state);
23127 + if (timer_pending(&sk->timer) && del_timer(&sk->timer))
23131 +static void l2cap_sock_init_timer(struct sock *sk)
23133 + init_timer(&sk->timer);
23134 + sk->timer.function = l2cap_sock_timeout;
23135 + sk->timer.data = (unsigned long)sk;
23138 +/* -------- L2CAP connections --------- */
23139 +static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, __u8 status)
23141 + struct l2cap_conn *conn;
23143 + if ((conn = hcon->l2cap_data))
23149 + if (!(conn = kmalloc(sizeof(struct l2cap_conn), GFP_ATOMIC)))
23151 + memset(conn, 0, sizeof(struct l2cap_conn));
23153 + hcon->l2cap_data = conn;
23154 + conn->hcon = hcon;
23156 + conn->mtu = hcon->hdev->acl_mtu;
23157 + conn->src = &hcon->hdev->bdaddr;
23158 + conn->dst = &hcon->dst;
23160 + spin_lock_init(&conn->lock);
23161 + conn->chan_list.lock = RW_LOCK_UNLOCKED;
23163 + BT_DBG("hcon %p conn %p", hcon, conn);
23165 + MOD_INC_USE_COUNT;
23169 +static int l2cap_conn_del(struct hci_conn *hcon, int err)
23171 + struct l2cap_conn *conn;
23174 + if (!(conn = hcon->l2cap_data))
23177 + BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
23179 + if (conn->rx_skb)
23180 + kfree_skb(conn->rx_skb);
23182 + /* Kill channels */
23183 + while ((sk = conn->chan_list.head)) {
23184 + bh_lock_sock(sk);
23185 + l2cap_chan_del(sk, err);
23186 + bh_unlock_sock(sk);
23187 + l2cap_sock_kill(sk);
23190 + hcon->l2cap_data = NULL;
23193 + MOD_DEC_USE_COUNT;
23197 +/* -------- Socket interface ---------- */
23198 +static struct sock *__l2cap_get_sock_by_addr(__u16 psm, bdaddr_t *src)
23201 + for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
23202 + if (sk->sport == psm && !bacmp(&bluez_pi(sk)->src, src))
23208 +/* Find socket with psm and source bdaddr.
23209 + * Returns closest match.
23211 +static struct sock *__l2cap_get_sock_by_psm(int state, __u16 psm, bdaddr_t *src)
23213 + struct sock *sk, *sk1 = NULL;
23215 + for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
23216 + if (state && sk->state != state)
23219 + if (l2cap_pi(sk)->psm == psm) {
23220 + /* Exact match. */
23221 + if (!bacmp(&bluez_pi(sk)->src, src))
23224 + /* Closest match */
23225 + if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
23229 + return sk ? sk : sk1;
23232 +/* Find socket with given address (psm, src).
23233 + * Returns locked socket */
23234 +static inline struct sock *l2cap_get_sock_by_psm(int state, __u16 psm, bdaddr_t *src)
23237 + read_lock(&l2cap_sk_list.lock);
23238 + s = __l2cap_get_sock_by_psm(state, psm, src);
23239 + if (s) bh_lock_sock(s);
23240 + read_unlock(&l2cap_sk_list.lock);
23244 +static void l2cap_sock_destruct(struct sock *sk)
23246 + BT_DBG("sk %p", sk);
23248 + skb_queue_purge(&sk->receive_queue);
23249 + skb_queue_purge(&sk->write_queue);
23251 + MOD_DEC_USE_COUNT;
23254 +static void l2cap_sock_cleanup_listen(struct sock *parent)
23258 + BT_DBG("parent %p", parent);
23260 + /* Close not yet accepted channels */
23261 + while ((sk = bluez_accept_dequeue(parent, NULL)))
23262 + l2cap_sock_close(sk);
23264 + parent->state = BT_CLOSED;
23265 + parent->zapped = 1;
23268 +/* Kill socket (only if zapped and orphan)
23269 + * Must be called on unlocked socket.
23271 +static void l2cap_sock_kill(struct sock *sk)
23273 + if (!sk->zapped || sk->socket)
23276 + BT_DBG("sk %p state %d", sk, sk->state);
23278 + /* Kill poor orphan */
23279 + bluez_sock_unlink(&l2cap_sk_list, sk);
23286 +static void __l2cap_sock_close(struct sock *sk, int reason)
23288 + BT_DBG("sk %p state %d socket %p", sk, sk->state, sk->socket);
23290 + switch (sk->state) {
23292 + l2cap_sock_cleanup_listen(sk);
23295 + case BT_CONNECTED:
23297 + case BT_CONNECT2:
23298 + if (sk->type == SOCK_SEQPACKET) {
23299 + struct l2cap_conn *conn = l2cap_pi(sk)->conn;
23300 + l2cap_disconn_req req;
23302 + sk->state = BT_DISCONN;
23303 + l2cap_sock_set_timer(sk, sk->sndtimeo);
23305 + req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
23306 + req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
23307 + l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
23309 + l2cap_chan_del(sk, reason);
23315 + l2cap_chan_del(sk, reason);
23324 +/* Must be called on unlocked socket. */
23325 +static void l2cap_sock_close(struct sock *sk)
23327 + l2cap_sock_clear_timer(sk);
23329 + __l2cap_sock_close(sk, ECONNRESET);
23330 + release_sock(sk);
23331 + l2cap_sock_kill(sk);
23334 +static void l2cap_sock_init(struct sock *sk, struct sock *parent)
23336 + struct l2cap_pinfo *pi = l2cap_pi(sk);
23338 + BT_DBG("sk %p", sk);
23341 + sk->type = parent->type;
23342 + pi->imtu = l2cap_pi(parent)->imtu;
23343 + pi->omtu = l2cap_pi(parent)->omtu;
23344 + pi->link_mode = l2cap_pi(parent)->link_mode;
23346 + pi->imtu = L2CAP_DEFAULT_MTU;
23348 + pi->link_mode = 0;
23351 + /* Default config options */
23352 + pi->conf_mtu = L2CAP_DEFAULT_MTU;
23353 + pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
23356 +static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
23360 + if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
23363 + bluez_sock_init(sock, sk);
23367 + sk->destruct = l2cap_sock_destruct;
23368 + sk->sndtimeo = L2CAP_CONN_TIMEOUT;
23370 + sk->protocol = proto;
23371 + sk->state = BT_OPEN;
23373 + l2cap_sock_init_timer(sk);
23375 + bluez_sock_link(&l2cap_sk_list, sk);
23377 + MOD_INC_USE_COUNT;
23381 +static int l2cap_sock_create(struct socket *sock, int protocol)
23385 + BT_DBG("sock %p", sock);
23387 + sock->state = SS_UNCONNECTED;
23389 + if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
23390 + return -ESOCKTNOSUPPORT;
23392 + if (sock->type == SOCK_RAW && !capable(CAP_NET_RAW))
23395 + sock->ops = &l2cap_sock_ops;
23397 + if (!(sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL)))
23400 + l2cap_sock_init(sk, NULL);
23404 +static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
23406 + struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
23407 + struct sock *sk = sock->sk;
23410 + BT_DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
23412 + if (!addr || addr->sa_family != AF_BLUETOOTH)
23417 + if (sk->state != BT_OPEN) {
23422 + write_lock_bh(&l2cap_sk_list.lock);
23423 + if (la->l2_psm && __l2cap_get_sock_by_addr(la->l2_psm, &la->l2_bdaddr)) {
23424 + err = -EADDRINUSE;
23426 + /* Save source address */
23427 + bacpy(&bluez_pi(sk)->src, &la->l2_bdaddr);
23428 + l2cap_pi(sk)->psm = la->l2_psm;
23429 + sk->sport = la->l2_psm;
23430 + sk->state = BT_BOUND;
23432 + write_unlock_bh(&l2cap_sk_list.lock);
23435 + release_sock(sk);
23439 +static int l2cap_do_connect(struct sock *sk)
23441 + bdaddr_t *src = &bluez_pi(sk)->src;
23442 + bdaddr_t *dst = &bluez_pi(sk)->dst;
23443 + struct l2cap_conn *conn;
23444 + struct hci_conn *hcon;
23445 + struct hci_dev *hdev;
23448 + BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
23450 + if (!(hdev = hci_get_route(dst, src)))
23451 + return -EHOSTUNREACH;
23453 + hci_dev_lock_bh(hdev);
23457 + hcon = hci_connect(hdev, ACL_LINK, dst);
23461 + conn = l2cap_conn_add(hcon, 0);
23463 + hci_conn_put(hcon);
23469 + /* Update source addr of the socket */
23470 + bacpy(src, conn->src);
23472 + l2cap_chan_add(conn, sk, NULL);
23474 + sk->state = BT_CONNECT;
23475 + l2cap_sock_set_timer(sk, sk->sndtimeo);
23477 + if (hcon->state == BT_CONNECTED) {
23478 + if (sk->type == SOCK_SEQPACKET) {
23479 + l2cap_conn_req req;
23480 + req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
23481 + req.psm = l2cap_pi(sk)->psm;
23482 + l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
23484 + l2cap_sock_clear_timer(sk);
23485 + sk->state = BT_CONNECTED;
23490 + hci_dev_unlock_bh(hdev);
23491 + hci_dev_put(hdev);
23495 +static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
23497 + struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
23498 + struct sock *sk = sock->sk;
23503 + BT_DBG("sk %p", sk);
23505 + if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) {
23510 + if (sk->type == SOCK_SEQPACKET && !la->l2_psm) {
23515 + switch(sk->state) {
23517 + case BT_CONNECT2:
23519 + /* Already connecting */
23522 + case BT_CONNECTED:
23523 + /* Already connected */
23528 + /* Can connect */
23536 + /* Set destination address and psm */
23537 + bacpy(&bluez_pi(sk)->dst, &la->l2_bdaddr);
23538 + l2cap_pi(sk)->psm = la->l2_psm;
23540 + if ((err = l2cap_do_connect(sk)))
23544 + err = bluez_sock_wait_state(sk, BT_CONNECTED,
23545 + sock_sndtimeo(sk, flags & O_NONBLOCK));
23548 + release_sock(sk);
23552 +int l2cap_sock_listen(struct socket *sock, int backlog)
23554 + struct sock *sk = sock->sk;
23557 + BT_DBG("sk %p backlog %d", sk, backlog);
23561 + if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
23566 + if (!l2cap_pi(sk)->psm) {
23571 + sk->max_ack_backlog = backlog;
23572 + sk->ack_backlog = 0;
23573 + sk->state = BT_LISTEN;
23576 + release_sock(sk);
23580 +int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
23582 + DECLARE_WAITQUEUE(wait, current);
23583 + struct sock *sk = sock->sk, *nsk;
23589 + if (sk->state != BT_LISTEN) {
23594 + timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
23596 + BT_DBG("sk %p timeo %ld", sk, timeo);
23598 + /* Wait for an incoming connection. (wake-one). */
23599 + add_wait_queue_exclusive(sk->sleep, &wait);
23600 + while (!(nsk = bluez_accept_dequeue(sk, newsock))) {
23601 + set_current_state(TASK_INTERRUPTIBLE);
23607 + release_sock(sk);
23608 + timeo = schedule_timeout(timeo);
23611 + if (sk->state != BT_LISTEN) {
23616 + if (signal_pending(current)) {
23617 + err = sock_intr_errno(timeo);
23621 + set_current_state(TASK_RUNNING);
23622 + remove_wait_queue(sk->sleep, &wait);
23627 + newsock->state = SS_CONNECTED;
23629 + BT_DBG("new socket %p", nsk);
23632 + release_sock(sk);
23636 +static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
23638 + struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
23639 + struct sock *sk = sock->sk;
23641 + BT_DBG("sock %p, sk %p", sock, sk);
23643 + addr->sa_family = AF_BLUETOOTH;
23644 + *len = sizeof(struct sockaddr_l2);
23647 + bacpy(&la->l2_bdaddr, &bluez_pi(sk)->dst);
23649 + bacpy(&la->l2_bdaddr, &bluez_pi(sk)->src);
23651 + la->l2_psm = l2cap_pi(sk)->psm;
23655 +static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
23657 + struct sock *sk = sock->sk;
23660 + BT_DBG("sock %p, sk %p", sock, sk);
23663 + return sock_error(sk);
23665 + if (msg->msg_flags & MSG_OOB)
23666 + return -EOPNOTSUPP;
23668 + /* Check outgoing MTU */
23669 + if (len > l2cap_pi(sk)->omtu)
23674 + if (sk->state == BT_CONNECTED)
23675 + err = l2cap_chan_send(sk, msg, len);
23679 + release_sock(sk);
23683 +static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
23685 + struct sock *sk = sock->sk;
23686 + struct l2cap_options opts;
23687 + int err = 0, len;
23690 + BT_DBG("sk %p", sk);
23694 + switch (optname) {
23695 + case L2CAP_OPTIONS:
23696 + len = MIN(sizeof(opts), optlen);
23697 + if (copy_from_user((char *)&opts, optval, len)) {
23701 + l2cap_pi(sk)->imtu = opts.imtu;
23702 + l2cap_pi(sk)->omtu = opts.omtu;
23706 + if (get_user(opt, (__u32 *)optval)) {
23711 + l2cap_pi(sk)->link_mode = opt;
23715 + err = -ENOPROTOOPT;
23719 + release_sock(sk);
23723 +static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
23725 + struct sock *sk = sock->sk;
23726 + struct l2cap_options opts;
23727 + struct l2cap_conninfo cinfo;
23728 + int len, err = 0;
23730 + if (get_user(len, optlen))
23735 + switch (optname) {
23736 + case L2CAP_OPTIONS:
23737 + opts.imtu = l2cap_pi(sk)->imtu;
23738 + opts.omtu = l2cap_pi(sk)->omtu;
23739 + opts.flush_to = l2cap_pi(sk)->flush_to;
23741 + len = MIN(len, sizeof(opts));
23742 + if (copy_to_user(optval, (char *)&opts, len))
23748 + if (put_user(l2cap_pi(sk)->link_mode, (__u32 *)optval))
23752 + case L2CAP_CONNINFO:
23753 + if (sk->state != BT_CONNECTED) {
23758 + cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
23760 + len = MIN(len, sizeof(cinfo));
23761 + if (copy_to_user(optval, (char *)&cinfo, len))
23767 + err = -ENOPROTOOPT;
23771 + release_sock(sk);
23775 +static int l2cap_sock_shutdown(struct socket *sock, int how)
23777 + struct sock *sk = sock->sk;
23780 + BT_DBG("sock %p, sk %p", sock, sk);
23782 + if (!sk) return 0;
23785 + if (!sk->shutdown) {
23786 + sk->shutdown = SHUTDOWN_MASK;
23787 + l2cap_sock_clear_timer(sk);
23788 + __l2cap_sock_close(sk, 0);
23791 + err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
23793 + release_sock(sk);
23797 +static int l2cap_sock_release(struct socket *sock)
23799 + struct sock *sk = sock->sk;
23802 + BT_DBG("sock %p, sk %p", sock, sk);
23804 + if (!sk) return 0;
23806 + err = l2cap_sock_shutdown(sock, 2);
23809 + l2cap_sock_kill(sk);
23813 +/* --------- L2CAP channels --------- */
23814 +static struct sock * __l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
23817 + for (s = l->head; s; s = l2cap_pi(s)->next_c) {
23818 + if (l2cap_pi(s)->dcid == cid)
23824 +static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
23827 + for (s = l->head; s; s = l2cap_pi(s)->next_c) {
23828 + if (l2cap_pi(s)->scid == cid)
23834 +/* Find channel with given SCID.
23835 + * Returns locked socket */
23836 +static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
23839 + read_lock(&l->lock);
23840 + s = __l2cap_get_chan_by_scid(l, cid);
23841 + if (s) bh_lock_sock(s);
23842 + read_unlock(&l->lock);
23846 +static __u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
23848 + __u16 cid = 0x0040;
23850 + for (; cid < 0xffff; cid++) {
23851 + if(!__l2cap_get_chan_by_scid(l, cid))
23858 +static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
23863 + l2cap_pi(l->head)->prev_c = sk;
23865 + l2cap_pi(sk)->next_c = l->head;
23866 + l2cap_pi(sk)->prev_c = NULL;
23870 +static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
23872 + struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
23874 + write_lock(&l->lock);
23875 + if (sk == l->head)
23879 + l2cap_pi(next)->prev_c = prev;
23881 + l2cap_pi(prev)->next_c = next;
23882 + write_unlock(&l->lock);
23887 +static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
23889 + struct l2cap_chan_list *l = &conn->chan_list;
23891 + BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
23893 + l2cap_pi(sk)->conn = conn;
23895 + if (sk->type == SOCK_SEQPACKET) {
23896 + /* Alloc CID for connection-oriented socket */
23897 + l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
23898 + } else if (sk->type == SOCK_DGRAM) {
23899 + /* Connectionless socket */
23900 + l2cap_pi(sk)->scid = 0x0002;
23901 + l2cap_pi(sk)->dcid = 0x0002;
23902 + l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
23904 + /* Raw socket can send/recv signalling messages only */
23905 + l2cap_pi(sk)->scid = 0x0001;
23906 + l2cap_pi(sk)->dcid = 0x0001;
23907 + l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
23910 + __l2cap_chan_link(l, sk);
23913 + bluez_accept_enqueue(parent, sk);
23916 +static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
23918 + struct l2cap_chan_list *l = &conn->chan_list;
23919 + write_lock(&l->lock);
23920 + __l2cap_chan_add(conn, sk, parent);
23921 + write_unlock(&l->lock);
23924 +/* Delete channel.
23925 + * Must be called on the locked socket. */
23926 +static void l2cap_chan_del(struct sock *sk, int err)
23928 + struct l2cap_conn *conn = l2cap_pi(sk)->conn;
23929 + struct sock *parent = bluez_pi(sk)->parent;
23931 + l2cap_sock_clear_timer(sk);
23933 + BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
23936 + /* Unlink from channel list */
23937 + l2cap_chan_unlink(&conn->chan_list, sk);
23938 + l2cap_pi(sk)->conn = NULL;
23939 + hci_conn_put(conn->hcon);
23942 + sk->state = BT_CLOSED;
23949 + parent->data_ready(parent, 0);
23951 + sk->state_change(sk);
23954 +static void l2cap_conn_ready(struct l2cap_conn *conn)
23956 + struct l2cap_chan_list *l = &conn->chan_list;
23959 + BT_DBG("conn %p", conn);
23961 + read_lock(&l->lock);
23963 + for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
23964 + bh_lock_sock(sk);
23966 + if (sk->type != SOCK_SEQPACKET) {
23967 + l2cap_sock_clear_timer(sk);
23968 + sk->state = BT_CONNECTED;
23969 + sk->state_change(sk);
23970 + } else if (sk->state == BT_CONNECT) {
23971 + l2cap_conn_req req;
23972 + req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
23973 + req.psm = l2cap_pi(sk)->psm;
23974 + l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
23977 + bh_unlock_sock(sk);
23980 + read_unlock(&l->lock);
23983 +/* Notify sockets that we cannot guaranty reliability anymore */
23984 +static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
23986 + struct l2cap_chan_list *l = &conn->chan_list;
23989 + BT_DBG("conn %p", conn);
23991 + read_lock(&l->lock);
23992 + for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
23993 + if (l2cap_pi(sk)->link_mode & L2CAP_LM_RELIABLE)
23996 + read_unlock(&l->lock);
23999 +static void l2cap_chan_ready(struct sock *sk)
24001 + struct sock *parent = bluez_pi(sk)->parent;
24003 + BT_DBG("sk %p, parent %p", sk, parent);
24005 + l2cap_pi(sk)->conf_state = 0;
24006 + l2cap_sock_clear_timer(sk);
24009 + /* Outgoing channel.
24010 + * Wake up socket sleeping on connect.
24012 + sk->state = BT_CONNECTED;
24013 + sk->state_change(sk);
24015 + /* Incomming channel.
24016 + * Wake up socket sleeping on accept.
24018 + parent->data_ready(parent, 0);
24022 +/* Copy frame to all raw sockets on that connection */
24023 +void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
24025 + struct l2cap_chan_list *l = &conn->chan_list;
24026 + struct sk_buff *nskb;
24027 + struct sock * sk;
24029 + BT_DBG("conn %p", conn);
24031 + read_lock(&l->lock);
24032 + for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
24033 + if (sk->type != SOCK_RAW)
24036 + /* Don't send frame to the socket it came from */
24037 + if (skb->sk == sk)
24040 + if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
24043 + if (sock_queue_rcv_skb(sk, nskb))
24046 + read_unlock(&l->lock);
24049 +static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
24051 + struct l2cap_conn *conn = l2cap_pi(sk)->conn;
24052 + struct sk_buff *skb, **frag;
24053 + int err, hlen, count, sent=0;
24056 + BT_DBG("sk %p len %d", sk, len);
24058 + /* First fragment (with L2CAP header) */
24059 + if (sk->type == SOCK_DGRAM)
24060 + hlen = L2CAP_HDR_SIZE + 2;
24062 + hlen = L2CAP_HDR_SIZE;
24064 + count = MIN(conn->mtu - hlen, len);
24066 + skb = bluez_skb_send_alloc(sk, hlen + count,
24067 + msg->msg_flags & MSG_DONTWAIT, &err);
24071 + /* Create L2CAP header */
24072 + lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
24073 + lh->cid = __cpu_to_le16(l2cap_pi(sk)->dcid);
24074 + lh->len = __cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
24076 + if (sk->type == SOCK_DGRAM)
24077 + put_unaligned(l2cap_pi(sk)->psm, (__u16 *) skb_put(skb, 2));
24079 + if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
24087 + /* Continuation fragments (no L2CAP header) */
24088 + frag = &skb_shinfo(skb)->frag_list;
24090 + count = MIN(conn->mtu, len);
24092 + *frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
24096 + if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
24104 + frag = &(*frag)->next;
24107 + if ((err = hci_send_acl(conn->hcon, skb, 0)) < 0)
24117 +/* --------- L2CAP signalling commands --------- */
24118 +static inline __u8 l2cap_get_ident(struct l2cap_conn *conn)
24122 + /* Get next available identificator.
24123 + * 1 - 199 are used by kernel.
24124 + * 200 - 254 are used by utilities like l2ping, etc
24127 + spin_lock(&conn->lock);
24129 + if (++conn->tx_ident > 199)
24130 + conn->tx_ident = 1;
24132 + id = conn->tx_ident;
24134 + spin_unlock(&conn->lock);
24139 +static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
24140 + __u8 code, __u8 ident, __u16 dlen, void *data)
24142 + struct sk_buff *skb, **frag;
24143 + l2cap_cmd_hdr *cmd;
24147 + BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", conn, code, ident, dlen);
24149 + len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
24150 + count = MIN(conn->mtu, len);
24152 + skb = bluez_skb_alloc(count, GFP_ATOMIC);
24156 + lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
24157 + lh->len = __cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
24158 + lh->cid = __cpu_to_le16(0x0001);
24160 + cmd = (l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
24161 + cmd->code = code;
24162 + cmd->ident = ident;
24163 + cmd->len = __cpu_to_le16(dlen);
24166 + count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
24167 + memcpy(skb_put(skb, count), data, count);
24173 + /* Continuation fragments (no L2CAP header) */
24174 + frag = &skb_shinfo(skb)->frag_list;
24176 + count = MIN(conn->mtu, len);
24178 + *frag = bluez_skb_alloc(count, GFP_ATOMIC);
24182 + memcpy(skb_put(*frag, count), data, count);
24187 + frag = &(*frag)->next;
24197 +static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data)
24199 + __u8 ident = l2cap_get_ident(conn);
24200 + struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
24202 + BT_DBG("code 0x%2.2x", code);
24206 + return hci_send_acl(conn->hcon, skb, 0);
24209 +static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data)
24211 + struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
24213 + BT_DBG("code 0x%2.2x", code);
24217 + return hci_send_acl(conn->hcon, skb, 0);
24220 +static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
24222 + l2cap_conf_opt *opt = *ptr;
24225 + len = L2CAP_CONF_OPT_SIZE + opt->len;
24228 + *type = opt->type;
24229 + *olen = opt->len;
24231 + switch (opt->len) {
24233 + *val = *((__u8 *) opt->val);
24237 + *val = __le16_to_cpu(*((__u16 *)opt->val));
24241 + *val = __le32_to_cpu(*((__u32 *)opt->val));
24245 + *val = (unsigned long) opt->val;
24249 + BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
24253 +static inline void l2cap_parse_conf_req(struct sock *sk, void *data, int len)
24255 + int type, hint, olen;
24256 + unsigned long val;
24257 + void *ptr = data;
24259 + BT_DBG("sk %p len %d", sk, len);
24261 + while (len >= L2CAP_CONF_OPT_SIZE) {
24262 + len -= l2cap_get_conf_opt(&ptr, &type, &olen, &val);
24264 + hint = type & 0x80;
24268 + case L2CAP_CONF_MTU:
24269 + l2cap_pi(sk)->conf_mtu = val;
24272 + case L2CAP_CONF_FLUSH_TO:
24273 + l2cap_pi(sk)->flush_to = val;
24276 + case L2CAP_CONF_QOS:
24283 + /* FIXME: Reject unknown option */
24289 +static void l2cap_add_conf_opt(void **ptr, __u8 type, __u8 len, unsigned long val)
24291 + register l2cap_conf_opt *opt = *ptr;
24293 + BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
24295 + opt->type = type;
24300 + *((__u8 *) opt->val) = val;
24304 + *((__u16 *) opt->val) = __cpu_to_le16(val);
24308 + *((__u32 *) opt->val) = __cpu_to_le32(val);
24312 + memcpy(opt->val, (void *) val, len);
24316 + *ptr += L2CAP_CONF_OPT_SIZE + len;
24319 +static int l2cap_build_conf_req(struct sock *sk, void *data)
24321 + struct l2cap_pinfo *pi = l2cap_pi(sk);
24322 + l2cap_conf_req *req = (l2cap_conf_req *) data;
24323 + void *ptr = req->data;
24325 + BT_DBG("sk %p", sk);
24327 + if (pi->imtu != L2CAP_DEFAULT_MTU)
24328 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
24330 + /* FIXME. Need actual value of the flush timeout */
24331 + //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
24332 + // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
24334 + req->dcid = __cpu_to_le16(pi->dcid);
24335 + req->flags = __cpu_to_le16(0);
24337 + return ptr - data;
24340 +static inline int l2cap_conf_output(struct sock *sk, void **ptr)
24342 + struct l2cap_pinfo *pi = l2cap_pi(sk);
24345 + /* Configure output options and let the other side know
24346 + * which ones we don't like.
24348 + if (pi->conf_mtu < pi->omtu) {
24349 + l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu);
24350 + result = L2CAP_CONF_UNACCEPT;
24352 + pi->omtu = pi->conf_mtu;
24355 + BT_DBG("sk %p result %d", sk, result);
24359 +static int l2cap_build_conf_rsp(struct sock *sk, void *data, int *result)
24361 + l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data;
24362 + void *ptr = rsp->data;
24365 + BT_DBG("sk %p complete %d", sk, result ? 1 : 0);
24368 + *result = l2cap_conf_output(sk, &ptr);
24372 + rsp->scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
24373 + rsp->result = __cpu_to_le16(result ? *result : 0);
24374 + rsp->flags = __cpu_to_le16(flags);
24376 + return ptr - data;
24379 +static inline int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
24381 + struct l2cap_chan_list *list = &conn->chan_list;
24382 + l2cap_conn_req *req = (l2cap_conn_req *) data;
24383 + l2cap_conn_rsp rsp;
24384 + struct sock *sk, *parent;
24385 + int result = 0, status = 0;
24387 + __u16 dcid = 0, scid = __le16_to_cpu(req->scid);
24388 + __u16 psm = req->psm;
24390 + BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
24392 + /* Check if we have socket listening on psm */
24393 + parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
24395 + result = L2CAP_CR_BAD_PSM;
24399 + result = L2CAP_CR_NO_MEM;
24401 + /* Check for backlog size */
24402 + if (parent->ack_backlog > parent->max_ack_backlog) {
24403 + BT_DBG("backlog full %d", parent->ack_backlog);
24407 + sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC);
24411 + write_lock(&list->lock);
24413 + /* Check if we already have channel with that dcid */
24414 + if (__l2cap_get_chan_by_dcid(list, scid)) {
24415 + write_unlock(&list->lock);
24417 + l2cap_sock_kill(sk);
24421 + hci_conn_hold(conn->hcon);
24423 + l2cap_sock_init(sk, parent);
24424 + bacpy(&bluez_pi(sk)->src, conn->src);
24425 + bacpy(&bluez_pi(sk)->dst, conn->dst);
24426 + l2cap_pi(sk)->psm = psm;
24427 + l2cap_pi(sk)->dcid = scid;
24429 + __l2cap_chan_add(conn, sk, parent);
24430 + dcid = l2cap_pi(sk)->scid;
24432 + l2cap_sock_set_timer(sk, sk->sndtimeo);
24434 + /* Service level security */
24435 + result = L2CAP_CR_PEND;
24436 + status = L2CAP_CS_AUTHEN_PEND;
24437 + sk->state = BT_CONNECT2;
24438 + l2cap_pi(sk)->ident = cmd->ident;
24440 + if (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) {
24441 + if (!hci_conn_encrypt(conn->hcon))
24443 + } else if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH) {
24444 + if (!hci_conn_auth(conn->hcon))
24448 + sk->state = BT_CONFIG;
24449 + result = status = 0;
24452 + write_unlock(&list->lock);
24455 + bh_unlock_sock(parent);
24458 + rsp.scid = __cpu_to_le16(scid);
24459 + rsp.dcid = __cpu_to_le16(dcid);
24460 + rsp.result = __cpu_to_le16(result);
24461 + rsp.status = __cpu_to_le16(status);
24462 + l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
24466 +static inline int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
24468 + l2cap_conn_rsp *rsp = (l2cap_conn_rsp *) data;
24469 + __u16 scid, dcid, result, status;
24473 + scid = __le16_to_cpu(rsp->scid);
24474 + dcid = __le16_to_cpu(rsp->dcid);
24475 + result = __le16_to_cpu(rsp->result);
24476 + status = __le16_to_cpu(rsp->status);
24478 + BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
24480 + if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
24483 + switch (result) {
24484 + case L2CAP_CR_SUCCESS:
24485 + sk->state = BT_CONFIG;
24486 + l2cap_pi(sk)->dcid = dcid;
24487 + l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
24489 + l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
24492 + case L2CAP_CR_PEND:
24496 + l2cap_chan_del(sk, ECONNREFUSED);
24500 + bh_unlock_sock(sk);
24504 +static inline int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
24506 + l2cap_conf_req * req = (l2cap_conf_req *) data;
24507 + __u16 dcid, flags;
24512 + dcid = __le16_to_cpu(req->dcid);
24513 + flags = __le16_to_cpu(req->flags);
24515 + BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
24517 + if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
24520 + l2cap_parse_conf_req(sk, req->data, cmd->len - L2CAP_CONF_REQ_SIZE);
24522 + if (flags & 0x0001) {
24523 + /* Incomplete config. Send empty response. */
24524 + l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
24528 + /* Complete config. */
24529 + l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &result), rsp);
24534 + /* Output config done */
24535 + l2cap_pi(sk)->conf_state |= L2CAP_CONF_OUTPUT_DONE;
24537 + if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
24538 + sk->state = BT_CONNECTED;
24539 + l2cap_chan_ready(sk);
24540 + } else if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
24542 + l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
24546 + bh_unlock_sock(sk);
24550 +static inline int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
24552 + l2cap_conf_rsp *rsp = (l2cap_conf_rsp *)data;
24553 + __u16 scid, flags, result;
24557 + scid = __le16_to_cpu(rsp->scid);
24558 + flags = __le16_to_cpu(rsp->flags);
24559 + result = __le16_to_cpu(rsp->result);
24561 + BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
24563 + if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
24566 + switch (result) {
24567 + case L2CAP_CONF_SUCCESS:
24570 + case L2CAP_CONF_UNACCEPT:
24571 + if (++l2cap_pi(sk)->conf_retry < L2CAP_CONF_MAX_RETRIES) {
24574 + It does not make sense to adjust L2CAP parameters
24575 + that are currently defined in the spec. We simply
24576 + resend config request that we sent earlier. It is
24577 + stupid :) but it helps qualification testing
24578 + which expects at least some response from us.
24580 + l2cap_send_req(conn, L2CAP_CONF_REQ,
24581 + l2cap_build_conf_req(sk, req), req);
24585 + sk->state = BT_DISCONN;
24586 + sk->err = ECONNRESET;
24587 + l2cap_sock_set_timer(sk, HZ * 5);
24589 + l2cap_disconn_req req;
24590 + req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
24591 + req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
24592 + l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
24597 + if (flags & 0x01)
24600 + /* Input config done */
24601 + l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
24603 + if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
24604 + sk->state = BT_CONNECTED;
24605 + l2cap_chan_ready(sk);
24609 + bh_unlock_sock(sk);
24613 +static inline int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
24615 + l2cap_disconn_req *req = (l2cap_disconn_req *) data;
24616 + l2cap_disconn_rsp rsp;
24617 + __u16 dcid, scid;
24620 + scid = __le16_to_cpu(req->scid);
24621 + dcid = __le16_to_cpu(req->dcid);
24623 + BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
24625 + if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
24628 + rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
24629 + rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
24630 + l2cap_send_rsp(conn, cmd->ident, L2CAP_DISCONN_RSP, L2CAP_DISCONN_RSP_SIZE, &rsp);
24632 + sk->shutdown = SHUTDOWN_MASK;
24634 + l2cap_chan_del(sk, ECONNRESET);
24635 + bh_unlock_sock(sk);
24637 + l2cap_sock_kill(sk);
24641 +static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
24643 + l2cap_disconn_rsp *rsp = (l2cap_disconn_rsp *) data;
24644 + __u16 dcid, scid;
24647 + scid = __le16_to_cpu(rsp->scid);
24648 + dcid = __le16_to_cpu(rsp->dcid);
24650 + BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
24652 + if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
24654 + l2cap_chan_del(sk, 0);
24655 + bh_unlock_sock(sk);
24657 + l2cap_sock_kill(sk);
24661 +static inline int l2cap_information_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, u8 *data)
24663 + l2cap_info_req *req = (l2cap_info_req *) data;
24664 + l2cap_info_rsp rsp;
24667 + type = __le16_to_cpu(req->type);
24669 + BT_DBG("type 0x%4.4x", type);
24671 + rsp.type = __cpu_to_le16(type);
24672 + rsp.result = __cpu_to_le16(L2CAP_IR_NOTSUPP);
24673 + l2cap_send_rsp(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp), &rsp);
24677 +static inline int l2cap_information_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, u8 *data)
24679 + l2cap_info_rsp *rsp = (l2cap_info_rsp *) data;
24680 + u16 type, result;
24682 + type = __le16_to_cpu(rsp->type);
24683 + result = __le16_to_cpu(rsp->result);
24685 + BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
24690 +static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
24692 + __u8 *data = skb->data;
24693 + int len = skb->len;
24694 + l2cap_cmd_hdr cmd;
24697 + l2cap_raw_recv(conn, skb);
24699 + while (len >= L2CAP_CMD_HDR_SIZE) {
24700 + memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
24701 + data += L2CAP_CMD_HDR_SIZE;
24702 + len -= L2CAP_CMD_HDR_SIZE;
24704 + cmd.len = __le16_to_cpu(cmd.len);
24706 + BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
24708 + if (cmd.len > len || !cmd.ident) {
24709 + BT_DBG("corrupted command");
24713 + switch (cmd.code) {
24714 + case L2CAP_COMMAND_REJ:
24715 + /* FIXME: We should process this */
24718 + case L2CAP_CONN_REQ:
24719 + err = l2cap_connect_req(conn, &cmd, data);
24722 + case L2CAP_CONN_RSP:
24723 + err = l2cap_connect_rsp(conn, &cmd, data);
24726 + case L2CAP_CONF_REQ:
24727 + err = l2cap_config_req(conn, &cmd, data);
24730 + case L2CAP_CONF_RSP:
24731 + err = l2cap_config_rsp(conn, &cmd, data);
24734 + case L2CAP_DISCONN_REQ:
24735 + err = l2cap_disconnect_req(conn, &cmd, data);
24738 + case L2CAP_DISCONN_RSP:
24739 + err = l2cap_disconnect_rsp(conn, &cmd, data);
24742 + case L2CAP_ECHO_REQ:
24743 + l2cap_send_rsp(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data);
24746 + case L2CAP_ECHO_RSP:
24749 + case L2CAP_INFO_REQ:
24750 + err = l2cap_information_req(conn, &cmd, data);
24753 + case L2CAP_INFO_RSP:
24754 + err = l2cap_information_rsp(conn, &cmd, data);
24758 + BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
24764 + l2cap_cmd_rej rej;
24765 + BT_DBG("error %d", err);
24767 + /* FIXME: Map err to a valid reason */
24768 + rej.reason = __cpu_to_le16(0);
24769 + l2cap_send_rsp(conn, cmd.ident, L2CAP_COMMAND_REJ, L2CAP_CMD_REJ_SIZE, &rej);
24779 +static inline int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
24783 + sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
24785 + BT_DBG("unknown cid 0x%4.4x", cid);
24789 + BT_DBG("sk %p, len %d", sk, skb->len);
24791 + if (sk->state != BT_CONNECTED)
24794 + if (l2cap_pi(sk)->imtu < skb->len)
24797 + /* If socket recv buffers overflows we drop data here
24798 + * which is *bad* because L2CAP has to be reliable.
24799 + * But we don't have any other choice. L2CAP doesn't
24800 + * provide flow control mechanism */
24802 + if (!sock_queue_rcv_skb(sk, skb))
24809 + if (sk) bh_unlock_sock(sk);
24813 +static inline int l2cap_conless_channel(struct l2cap_conn *conn, __u16 psm, struct sk_buff *skb)
24817 + sk = l2cap_get_sock_by_psm(0, psm, conn->src);
24821 + BT_DBG("sk %p, len %d", sk, skb->len);
24823 + if (sk->state != BT_BOUND && sk->state != BT_CONNECTED)
24826 + if (l2cap_pi(sk)->imtu < skb->len)
24829 + if (!sock_queue_rcv_skb(sk, skb))
24836 + if (sk) bh_unlock_sock(sk);
24840 +static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
24842 + l2cap_hdr *lh = (l2cap_hdr *) skb->data;
24843 + __u16 cid, psm, len;
24845 + skb_pull(skb, L2CAP_HDR_SIZE);
24846 + cid = __le16_to_cpu(lh->cid);
24847 + len = __le16_to_cpu(lh->len);
24849 + BT_DBG("len %d, cid 0x%4.4x", len, cid);
24853 + l2cap_sig_channel(conn, skb);
24857 + psm = get_unaligned((__u16 *) skb->data);
24858 + skb_pull(skb, 2);
24859 + l2cap_conless_channel(conn, psm, skb);
24863 + l2cap_data_channel(conn, cid, skb);
24868 +/* ------------ L2CAP interface with lower layer (HCI) ------------- */
24870 +static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
24872 + int exact = 0, lm1 = 0, lm2 = 0;
24873 + register struct sock *sk;
24875 + if (type != ACL_LINK)
24878 + BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
24880 + /* Find listening sockets and check their link_mode */
24881 + read_lock(&l2cap_sk_list.lock);
24882 + for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
24883 + if (sk->state != BT_LISTEN)
24886 + if (!bacmp(&bluez_pi(sk)->src, &hdev->bdaddr)) {
24887 + lm1 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode);
24889 + } else if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
24890 + lm2 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode);
24892 + read_unlock(&l2cap_sk_list.lock);
24894 + return exact ? lm1 : lm2;
24897 +static int l2cap_connect_cfm(struct hci_conn *hcon, __u8 status)
24899 + BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
24901 + if (hcon->type != ACL_LINK)
24905 + struct l2cap_conn *conn;
24907 + conn = l2cap_conn_add(hcon, status);
24909 + l2cap_conn_ready(conn);
24911 + l2cap_conn_del(hcon, bterr(status));
24916 +static int l2cap_disconn_ind(struct hci_conn *hcon, __u8 reason)
24918 + BT_DBG("hcon %p reason %d", hcon, reason);
24920 + if (hcon->type != ACL_LINK)
24923 + l2cap_conn_del(hcon, bterr(reason));
24927 +static int l2cap_auth_cfm(struct hci_conn *hcon, __u8 status)
24929 + struct l2cap_chan_list *l;
24930 + struct l2cap_conn *conn;
24931 + l2cap_conn_rsp rsp;
24935 + if (!(conn = hcon->l2cap_data))
24937 + l = &conn->chan_list;
24939 + BT_DBG("conn %p", conn);
24941 + read_lock(&l->lock);
24943 + for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
24944 + bh_lock_sock(sk);
24946 + if (sk->state != BT_CONNECT2 ||
24947 + (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT)) {
24948 + bh_unlock_sock(sk);
24953 + sk->state = BT_CONFIG;
24956 + sk->state = BT_DISCONN;
24957 + l2cap_sock_set_timer(sk, HZ/10);
24958 + result = L2CAP_CR_SEC_BLOCK;
24961 + rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
24962 + rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
24963 + rsp.result = __cpu_to_le16(result);
24964 + rsp.status = __cpu_to_le16(0);
24965 + l2cap_send_rsp(conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP,
24966 + L2CAP_CONN_RSP_SIZE, &rsp);
24968 + bh_unlock_sock(sk);
24971 + read_unlock(&l->lock);
24975 +static int l2cap_encrypt_cfm(struct hci_conn *hcon, __u8 status)
24977 + struct l2cap_chan_list *l;
24978 + struct l2cap_conn *conn;
24979 + l2cap_conn_rsp rsp;
24983 + if (!(conn = hcon->l2cap_data))
24985 + l = &conn->chan_list;
24987 + BT_DBG("conn %p", conn);
24989 + read_lock(&l->lock);
24991 + for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
24992 + bh_lock_sock(sk);
24994 + if (sk->state != BT_CONNECT2) {
24995 + bh_unlock_sock(sk);
25000 + sk->state = BT_CONFIG;
25003 + sk->state = BT_DISCONN;
25004 + l2cap_sock_set_timer(sk, HZ/10);
25005 + result = L2CAP_CR_SEC_BLOCK;
25008 + rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
25009 + rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
25010 + rsp.result = __cpu_to_le16(result);
25011 + rsp.status = __cpu_to_le16(0);
25012 + l2cap_send_rsp(conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP,
25013 + L2CAP_CONN_RSP_SIZE, &rsp);
25015 + bh_unlock_sock(sk);
25018 + read_unlock(&l->lock);
25022 +static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, __u16 flags)
25024 + struct l2cap_conn *conn = hcon->l2cap_data;
25026 + if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
25029 + BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
25031 + if (flags & ACL_START) {
25035 + if (conn->rx_len) {
25036 + BT_ERR("Unexpected start frame (len %d)", skb->len);
25037 + kfree_skb(conn->rx_skb);
25038 + conn->rx_skb = NULL;
25039 + conn->rx_len = 0;
25040 + l2cap_conn_unreliable(conn, ECOMM);
25043 + if (skb->len < 2) {
25044 + BT_ERR("Frame is too short (len %d)", skb->len);
25045 + l2cap_conn_unreliable(conn, ECOMM);
25049 + hdr = (l2cap_hdr *) skb->data;
25050 + len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
25052 + if (len == skb->len) {
25053 + /* Complete frame received */
25054 + l2cap_recv_frame(conn, skb);
25058 + BT_DBG("Start: total len %d, frag len %d", len, skb->len);
25060 + if (skb->len > len) {
25061 + BT_ERR("Frame is too long (len %d, expected len %d)",
25063 + l2cap_conn_unreliable(conn, ECOMM);
25067 + /* Allocate skb for the complete frame including header */
25068 + conn->rx_skb = bluez_skb_alloc(len, GFP_ATOMIC);
25069 + if (!conn->rx_skb)
25072 + memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
25073 + conn->rx_len = len - skb->len;
25075 + BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
25077 + if (!conn->rx_len) {
25078 + BT_ERR("Unexpected continuation frame (len %d)", skb->len);
25079 + l2cap_conn_unreliable(conn, ECOMM);
25083 + if (skb->len > conn->rx_len) {
25084 + BT_ERR("Fragment is too long (len %d, expected %d)",
25085 + skb->len, conn->rx_len);
25086 + kfree_skb(conn->rx_skb);
25087 + conn->rx_skb = NULL;
25088 + conn->rx_len = 0;
25089 + l2cap_conn_unreliable(conn, ECOMM);
25093 + memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
25094 + conn->rx_len -= skb->len;
25096 + if (!conn->rx_len) {
25097 + /* Complete frame received */
25098 + l2cap_recv_frame(conn, conn->rx_skb);
25099 + conn->rx_skb = NULL;
25108 +/* ----- Proc fs support ------ */
25109 +static int l2cap_sock_dump(char *buf, struct bluez_sock_list *list)
25111 + struct l2cap_pinfo *pi;
25115 + read_lock_bh(&list->lock);
25117 + for (sk = list->head; sk; sk = sk->next) {
25118 + pi = l2cap_pi(sk);
25119 + ptr += sprintf(ptr, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n",
25120 + batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
25121 + sk->state, pi->psm, pi->scid, pi->dcid, pi->imtu, pi->omtu,
25125 + read_unlock_bh(&list->lock);
25127 + ptr += sprintf(ptr, "\n");
25128 + return ptr - buf;
25131 +static int l2cap_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
25136 + BT_DBG("count %d, offset %ld", count, offset);
25138 + ptr += l2cap_sock_dump(ptr, &l2cap_sk_list);
25141 + if (len <= count + offset)
25144 + *start = buf + offset;
25155 +static struct proto_ops l2cap_sock_ops = {
25156 + family: PF_BLUETOOTH,
25157 + release: l2cap_sock_release,
25158 + bind: l2cap_sock_bind,
25159 + connect: l2cap_sock_connect,
25160 + listen: l2cap_sock_listen,
25161 + accept: l2cap_sock_accept,
25162 + getname: l2cap_sock_getname,
25163 + sendmsg: l2cap_sock_sendmsg,
25164 + recvmsg: bluez_sock_recvmsg,
25165 + poll: bluez_sock_poll,
25166 + socketpair: sock_no_socketpair,
25167 + ioctl: sock_no_ioctl,
25168 + shutdown: l2cap_sock_shutdown,
25169 + setsockopt: l2cap_sock_setsockopt,
25170 + getsockopt: l2cap_sock_getsockopt,
25171 + mmap: sock_no_mmap
25174 +static struct net_proto_family l2cap_sock_family_ops = {
25175 + family: PF_BLUETOOTH,
25176 + create: l2cap_sock_create
25179 +static struct hci_proto l2cap_hci_proto = {
25181 + id: HCI_PROTO_L2CAP,
25182 + connect_ind: l2cap_connect_ind,
25183 + connect_cfm: l2cap_connect_cfm,
25184 + disconn_ind: l2cap_disconn_ind,
25185 + recv_acldata: l2cap_recv_acldata,
25186 + auth_cfm: l2cap_auth_cfm,
25187 + encrypt_cfm: l2cap_encrypt_cfm
25190 +int __init l2cap_init(void)
25194 + if ((err = bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops))) {
25195 + BT_ERR("Can't register L2CAP socket");
25199 + if ((err = hci_register_proto(&l2cap_hci_proto))) {
25200 + BT_ERR("Can't register L2CAP protocol");
25204 + create_proc_read_entry("bluetooth/l2cap", 0, 0, l2cap_read_proc, NULL);
25206 + BT_INFO("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
25207 + BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
25211 +void l2cap_cleanup(void)
25213 + remove_proc_entry("bluetooth/l2cap", NULL);
25215 + /* Unregister socket and protocol */
25216 + if (bluez_sock_unregister(BTPROTO_L2CAP))
25217 + BT_ERR("Can't unregister L2CAP socket");
25219 + if (hci_unregister_proto(&l2cap_hci_proto))
25220 + BT_ERR("Can't unregister L2CAP protocol");
25223 +void l2cap_load(void)
25225 + /* Dummy function to trigger automatic L2CAP module loading by
25226 + other modules that use L2CAP sockets but do not use any other
25227 + symbols from it. */
25231 +EXPORT_SYMBOL(l2cap_load);
25233 +module_init(l2cap_init);
25234 +module_exit(l2cap_cleanup);
25236 +MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
25237 +MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
25238 +MODULE_LICENSE("GPL");
25239 diff -urN linux-2.4.18/net/bluetooth/l2cap_core.c linux-2.4.18-mh15/net/bluetooth/l2cap_core.c
25240 --- linux-2.4.18/net/bluetooth/l2cap_core.c 2001-09-30 21:26:08.000000000 +0200
25241 +++ linux-2.4.18-mh15/net/bluetooth/l2cap_core.c 1970-01-01 01:00:00.000000000 +0100
25244 - BlueZ - Bluetooth protocol stack for Linux
25245 - Copyright (C) 2000-2001 Qualcomm Incorporated
25247 - Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
25249 - This program is free software; you can redistribute it and/or modify
25250 - it under the terms of the GNU General Public License version 2 as
25251 - published by the Free Software Foundation;
25253 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25254 - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25255 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
25256 - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
25257 - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
25258 - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
25259 - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
25260 - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25262 - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
25263 - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
25264 - SOFTWARE IS DISCLAIMED.
25268 - * BlueZ L2CAP core and sockets.
25270 - * $Id: l2cap_core.c,v 1.19 2001/08/03 04:19:50 maxk Exp $
25272 -#define VERSION "1.1"
25274 -#include <linux/config.h>
25275 -#include <linux/module.h>
25277 -#include <linux/types.h>
25278 -#include <linux/errno.h>
25279 -#include <linux/kernel.h>
25280 -#include <linux/major.h>
25281 -#include <linux/sched.h>
25282 -#include <linux/slab.h>
25283 -#include <linux/poll.h>
25284 -#include <linux/fcntl.h>
25285 -#include <linux/init.h>
25286 -#include <linux/skbuff.h>
25287 -#include <linux/interrupt.h>
25288 -#include <linux/socket.h>
25289 -#include <linux/skbuff.h>
25290 -#include <linux/proc_fs.h>
25291 -#include <linux/list.h>
25292 -#include <net/sock.h>
25294 -#include <asm/system.h>
25295 -#include <asm/uaccess.h>
25297 -#include <net/bluetooth/bluetooth.h>
25298 -#include <net/bluetooth/bluez.h>
25299 -#include <net/bluetooth/hci_core.h>
25300 -#include <net/bluetooth/l2cap.h>
25301 -#include <net/bluetooth/l2cap_core.h>
25303 -#ifndef L2CAP_DEBUG
25305 -#define DBG( A... )
25308 -struct proto_ops l2cap_sock_ops;
25310 -struct bluez_sock_list l2cap_sk_list = {
25311 - lock: RW_LOCK_UNLOCKED
25314 -struct list_head l2cap_iff_list = LIST_HEAD_INIT(l2cap_iff_list);
25315 -rwlock_t l2cap_rt_lock = RW_LOCK_UNLOCKED;
25317 -static int l2cap_conn_del(struct l2cap_conn *conn, int err);
25319 -static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
25320 -static void l2cap_chan_del(struct sock *sk, int err);
25321 -static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len);
25323 -static void l2cap_sock_close(struct sock *sk);
25324 -static void l2cap_sock_kill(struct sock *sk);
25326 -static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data);
25327 -static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data);
25329 -/* -------- L2CAP interfaces & routing --------- */
25330 -/* Add/delete L2CAP interface.
25331 - * Must be called with locked rt_lock
25334 -static void l2cap_iff_add(struct hci_dev *hdev)
25336 - struct l2cap_iff *iff;
25338 - DBG("%s", hdev->name);
25340 - DBG("iff_list %p next %p prev %p", &l2cap_iff_list, l2cap_iff_list.next, l2cap_iff_list.prev);
25342 - /* Allocate new interface and lock HCI device */
25343 - if (!(iff = kmalloc(sizeof(struct l2cap_iff), GFP_KERNEL))) {
25344 - ERR("Can't allocate new interface %s", hdev->name);
25347 - memset(iff, 0, sizeof(struct l2cap_iff));
25349 - hci_dev_hold(hdev);
25350 - hdev->l2cap_data = iff;
25351 - iff->hdev = hdev;
25352 - iff->mtu = hdev->acl_mtu - HCI_ACL_HDR_SIZE;
25353 - iff->bdaddr = &hdev->bdaddr;
25355 - spin_lock_init(&iff->lock);
25356 - INIT_LIST_HEAD(&iff->conn_list);
25358 - list_add(&iff->list, &l2cap_iff_list);
25361 -static void l2cap_iff_del(struct hci_dev *hdev)
25363 - struct l2cap_iff *iff;
25365 - if (!(iff = hdev->l2cap_data))
25368 - DBG("%s iff %p", hdev->name, iff);
25370 - list_del(&iff->list);
25372 - l2cap_iff_lock(iff);
25374 - /* Drop connections */
25375 - while (!list_empty(&iff->conn_list)) {
25376 - struct l2cap_conn *c;
25378 - c = list_entry(iff->conn_list.next, struct l2cap_conn, list);
25379 - l2cap_conn_del(c, ENODEV);
25382 - l2cap_iff_unlock(iff);
25384 - /* Unlock HCI device */
25385 - hdev->l2cap_data = NULL;
25386 - hci_dev_put(hdev);
25391 -/* Get route. Returns L2CAP interface.
25392 - * Must be called with locked rt_lock
25394 -static struct l2cap_iff *l2cap_get_route(bdaddr_t *src, bdaddr_t *dst)
25396 - struct list_head *p;
25399 - DBG("%s -> %s", batostr(src), batostr(dst));
25401 - use_src = bacmp(src, BDADDR_ANY) ? 0 : 1;
25403 - /* Simple routing:
25404 - * No source address - find interface with bdaddr != dst
25405 - * Source address - find interface with bdaddr == src
25408 - list_for_each(p, &l2cap_iff_list) {
25409 - struct l2cap_iff *iff;
25411 - iff = list_entry(p, struct l2cap_iff, list);
25413 - if (use_src && !bacmp(iff->bdaddr, src))
25415 - else if (bacmp(iff->bdaddr, dst))
25421 -/* ----- L2CAP timers ------ */
25422 -static void l2cap_sock_timeout(unsigned long arg)
25424 - struct sock *sk = (struct sock *) arg;
25426 - DBG("sock %p state %d", sk, sk->state);
25428 - bh_lock_sock(sk);
25429 - switch (sk->state) {
25431 - l2cap_chan_del(sk, ETIMEDOUT);
25435 - sk->err = ETIMEDOUT;
25436 - sk->state_change(sk);
25439 - bh_unlock_sock(sk);
25441 - l2cap_sock_kill(sk);
25445 -static void l2cap_sock_set_timer(struct sock *sk, long timeout)
25447 - DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
25449 - if (!mod_timer(&sk->timer, jiffies + timeout))
25453 -static void l2cap_sock_clear_timer(struct sock *sk)
25455 - DBG("sock %p state %d", sk, sk->state);
25457 - if (timer_pending(&sk->timer) && del_timer(&sk->timer))
25461 -static void l2cap_sock_init_timer(struct sock *sk)
25463 - init_timer(&sk->timer);
25464 - sk->timer.function = l2cap_sock_timeout;
25465 - sk->timer.data = (unsigned long)sk;
25468 -static void l2cap_conn_timeout(unsigned long arg)
25470 - struct l2cap_conn *conn = (void *)arg;
25472 - DBG("conn %p state %d", conn, conn->state);
25474 - if (conn->state == BT_CONNECTED) {
25475 - hci_disconnect(conn->hconn, 0x13);
25481 -static void l2cap_conn_set_timer(struct l2cap_conn *conn, long timeout)
25483 - DBG("conn %p state %d timeout %ld", conn, conn->state, timeout);
25485 - mod_timer(&conn->timer, jiffies + timeout);
25488 -static void l2cap_conn_clear_timer(struct l2cap_conn *conn)
25490 - DBG("conn %p state %d", conn, conn->state);
25492 - del_timer(&conn->timer);
25495 -static void l2cap_conn_init_timer(struct l2cap_conn *conn)
25497 - init_timer(&conn->timer);
25498 - conn->timer.function = l2cap_conn_timeout;
25499 - conn->timer.data = (unsigned long)conn;
25502 -/* -------- L2CAP connections --------- */
25503 -/* Add new connection to the interface.
25504 - * Interface must be locked
25506 -static struct l2cap_conn *l2cap_conn_add(struct l2cap_iff *iff, bdaddr_t *dst)
25508 - struct l2cap_conn *conn;
25509 - bdaddr_t *src = iff->bdaddr;
25511 - if (!(conn = kmalloc(sizeof(struct l2cap_conn), GFP_KERNEL)))
25514 - memset(conn, 0, sizeof(struct l2cap_conn));
25516 - conn->state = BT_OPEN;
25518 - bacpy(&conn->src, src);
25519 - bacpy(&conn->dst, dst);
25521 - spin_lock_init(&conn->lock);
25522 - conn->chan_list.lock = RW_LOCK_UNLOCKED;
25524 - l2cap_conn_init_timer(conn);
25526 - __l2cap_conn_link(iff, conn);
25528 - DBG("%s -> %s, %p", batostr(src), batostr(dst), conn);
25530 - MOD_INC_USE_COUNT;
25535 -/* Delete connection on the interface.
25536 - * Interface must be locked
25538 -static int l2cap_conn_del(struct l2cap_conn *conn, int err)
25542 - DBG("conn %p, state %d, err %d", conn, conn->state, err);
25544 - l2cap_conn_clear_timer(conn);
25545 - __l2cap_conn_unlink(conn->iff, conn);
25547 - conn->state = BT_CLOSED;
25549 - if (conn->rx_skb)
25550 - kfree_skb(conn->rx_skb);
25552 - /* Kill channels */
25553 - while ((sk = conn->chan_list.head)) {
25554 - bh_lock_sock(sk);
25555 - l2cap_sock_clear_timer(sk);
25556 - l2cap_chan_del(sk, err);
25557 - bh_unlock_sock(sk);
25559 - l2cap_sock_kill(sk);
25564 - MOD_DEC_USE_COUNT;
25568 -static inline struct l2cap_conn *l2cap_get_conn_by_addr(struct l2cap_iff *iff, bdaddr_t *dst)
25570 - struct list_head *p;
25572 - list_for_each(p, &iff->conn_list) {
25573 - struct l2cap_conn *c;
25575 - c = list_entry(p, struct l2cap_conn, list);
25576 - if (!bacmp(&c->dst, dst))
25582 -int l2cap_connect(struct sock *sk)
25584 - bdaddr_t *src = &l2cap_pi(sk)->src;
25585 - bdaddr_t *dst = &l2cap_pi(sk)->dst;
25586 - struct l2cap_conn *conn;
25587 - struct l2cap_iff *iff;
25590 - DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
25592 - read_lock_bh(&l2cap_rt_lock);
25594 - /* Get route to remote BD address */
25595 - if (!(iff = l2cap_get_route(src, dst))) {
25596 - err = -EHOSTUNREACH;
25600 - /* Update source addr of the socket */
25601 - bacpy(src, iff->bdaddr);
25603 - l2cap_iff_lock(iff);
25605 - if (!(conn = l2cap_get_conn_by_addr(iff, dst))) {
25606 - /* Connection doesn't exist */
25607 - if (!(conn = l2cap_conn_add(iff, dst))) {
25608 - l2cap_iff_unlock(iff);
25615 - l2cap_iff_unlock(iff);
25617 - l2cap_chan_add(conn, sk, NULL);
25619 - sk->state = BT_CONNECT;
25620 - l2cap_sock_set_timer(sk, sk->sndtimeo);
25622 - switch (conn->state) {
25623 - case BT_CONNECTED:
25624 - if (sk->type == SOCK_SEQPACKET) {
25625 - l2cap_conn_req req;
25626 - req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
25627 - req.psm = l2cap_pi(sk)->psm;
25628 - l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
25630 - l2cap_sock_clear_timer(sk);
25631 - sk->state = BT_CONNECTED;
25639 - /* Create ACL connection */
25640 - conn->state = BT_CONNECT;
25641 - hci_connect(iff->hdev, dst);
25646 - read_unlock_bh(&l2cap_rt_lock);
25650 -/* ------ Channel queues for listening sockets ------ */
25651 -void l2cap_accept_queue(struct sock *parent, struct sock *sk)
25653 - struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
25655 - DBG("parent %p, sk %p", parent, sk);
25658 - l2cap_pi(sk)->parent = parent;
25659 - l2cap_pi(sk)->next_q = NULL;
25662 - q->head = q->tail = sk;
25664 - struct sock *tail = q->tail;
25666 - l2cap_pi(sk)->prev_q = tail;
25667 - l2cap_pi(tail)->next_q = sk;
25671 - parent->ack_backlog++;
25674 -void l2cap_accept_unlink(struct sock *sk)
25676 - struct sock *parent = l2cap_pi(sk)->parent;
25677 - struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
25678 - struct sock *next, *prev;
25680 - DBG("sk %p", sk);
25682 - next = l2cap_pi(sk)->next_q;
25683 - prev = l2cap_pi(sk)->prev_q;
25685 - if (sk == q->head)
25687 - if (sk == q->tail)
25691 - l2cap_pi(next)->prev_q = prev;
25693 - l2cap_pi(prev)->next_q = next;
25695 - l2cap_pi(sk)->parent = NULL;
25697 - parent->ack_backlog--;
25701 -/* Get next connected channel in queue. */
25702 -struct sock *l2cap_accept_dequeue(struct sock *parent, int state)
25704 - struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
25707 - for (sk = q->head; sk; sk = l2cap_pi(sk)->next_q) {
25708 - if (!state || sk->state == state) {
25709 - l2cap_accept_unlink(sk);
25714 - DBG("parent %p, sk %p", parent, sk);
25719 -/* -------- Socket interface ---------- */
25720 -static struct sock *__l2cap_get_sock_by_addr(struct sockaddr_l2 *addr)
25722 - bdaddr_t *src = &addr->l2_bdaddr;
25723 - __u16 psm = addr->l2_psm;
25726 - for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
25727 - if (l2cap_pi(sk)->psm == psm &&
25728 - !bacmp(&l2cap_pi(sk)->src, src))
25735 -/* Find socket listening on psm and source bdaddr.
25736 - * Returns closest match.
25738 -static struct sock *l2cap_get_sock_listen(bdaddr_t *src, __u16 psm)
25740 - struct sock *sk, *sk1 = NULL;
25742 - read_lock(&l2cap_sk_list.lock);
25744 - for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
25745 - struct l2cap_pinfo *pi;
25747 - if (sk->state != BT_LISTEN)
25750 - pi = l2cap_pi(sk);
25752 - if (pi->psm == psm) {
25753 - /* Exact match. */
25754 - if (!bacmp(&pi->src, src))
25757 - /* Closest match */
25758 - if (!bacmp(&pi->src, BDADDR_ANY))
25763 - read_unlock(&l2cap_sk_list.lock);
25765 - return sk ? sk : sk1;
25768 -static void l2cap_sock_destruct(struct sock *sk)
25770 - DBG("sk %p", sk);
25772 - skb_queue_purge(&sk->receive_queue);
25773 - skb_queue_purge(&sk->write_queue);
25775 - MOD_DEC_USE_COUNT;
25778 -static void l2cap_sock_cleanup_listen(struct sock *parent)
25782 - DBG("parent %p", parent);
25784 - /* Close not yet accepted channels */
25785 - while ((sk = l2cap_accept_dequeue(parent, 0)))
25786 - l2cap_sock_close(sk);
25788 - parent->state = BT_CLOSED;
25789 - parent->zapped = 1;
25792 -/* Kill socket (only if zapped and orphan)
25793 - * Must be called on unlocked socket.
25795 -static void l2cap_sock_kill(struct sock *sk)
25797 - if (!sk->zapped || sk->socket)
25800 - DBG("sk %p state %d", sk, sk->state);
25802 - /* Kill poor orphan */
25803 - bluez_sock_unlink(&l2cap_sk_list, sk);
25809 - * Must be called on unlocked socket.
25811 -static void l2cap_sock_close(struct sock *sk)
25813 - struct l2cap_conn *conn;
25815 - l2cap_sock_clear_timer(sk);
25819 - conn = l2cap_pi(sk)->conn;
25821 - DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
25823 - switch (sk->state) {
25825 - l2cap_sock_cleanup_listen(sk);
25828 - case BT_CONNECTED:
25830 - if (sk->type == SOCK_SEQPACKET) {
25831 - l2cap_disconn_req req;
25833 - sk->state = BT_DISCONN;
25835 - req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
25836 - req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
25837 - l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
25839 - l2cap_sock_set_timer(sk, sk->sndtimeo);
25841 - l2cap_chan_del(sk, ECONNRESET);
25847 - l2cap_chan_del(sk, ECONNRESET);
25855 - release_sock(sk);
25857 - l2cap_sock_kill(sk);
25860 -static void l2cap_sock_init(struct sock *sk, struct sock *parent)
25862 - struct l2cap_pinfo *pi = l2cap_pi(sk);
25864 - DBG("sk %p", sk);
25867 - sk->type = parent->type;
25869 - pi->imtu = l2cap_pi(parent)->imtu;
25870 - pi->omtu = l2cap_pi(parent)->omtu;
25872 - pi->imtu = L2CAP_DEFAULT_MTU;
25876 - /* Default config options */
25877 - pi->conf_mtu = L2CAP_DEFAULT_MTU;
25878 - pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
25881 -static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
25885 - if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
25888 - sock_init_data(sock, sk);
25892 - sk->destruct = l2cap_sock_destruct;
25893 - sk->sndtimeo = L2CAP_CONN_TIMEOUT;
25895 - sk->protocol = proto;
25896 - sk->state = BT_OPEN;
25898 - l2cap_sock_init_timer(sk);
25900 - bluez_sock_link(&l2cap_sk_list, sk);
25902 - MOD_INC_USE_COUNT;
25907 -static int l2cap_sock_create(struct socket *sock, int protocol)
25911 - DBG("sock %p", sock);
25913 - sock->state = SS_UNCONNECTED;
25915 - if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_RAW)
25916 - return -ESOCKTNOSUPPORT;
25918 - sock->ops = &l2cap_sock_ops;
25920 - if (!(sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL)))
25923 - l2cap_sock_init(sk, NULL);
25928 -static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
25930 - struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
25931 - struct sock *sk = sock->sk;
25934 - DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
25936 - if (!addr || addr->sa_family != AF_BLUETOOTH)
25941 - if (sk->state != BT_OPEN) {
25946 - write_lock(&l2cap_sk_list.lock);
25948 - if (la->l2_psm && __l2cap_get_sock_by_addr(la)) {
25949 - err = -EADDRINUSE;
25953 - /* Save source address */
25954 - bacpy(&l2cap_pi(sk)->src, &la->l2_bdaddr);
25955 - l2cap_pi(sk)->psm = la->l2_psm;
25956 - sk->state = BT_BOUND;
25959 - write_unlock(&l2cap_sk_list.lock);
25962 - release_sock(sk);
25967 -static int l2cap_sock_w4_connect(struct sock *sk, int flags)
25969 - DECLARE_WAITQUEUE(wait, current);
25970 - long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
25973 - DBG("sk %p", sk);
25975 - add_wait_queue(sk->sleep, &wait);
25976 - current->state = TASK_INTERRUPTIBLE;
25978 - while (sk->state != BT_CONNECTED) {
25984 - release_sock(sk);
25985 - timeo = schedule_timeout(timeo);
25989 - if (sk->state == BT_CONNECTED)
25993 - err = sock_error(sk);
25997 - if (signal_pending(current)) {
25998 - err = sock_intr_errno(timeo);
26002 - current->state = TASK_RUNNING;
26003 - remove_wait_queue(sk->sleep, &wait);
26008 -static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
26010 - struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
26011 - struct sock *sk = sock->sk;
26016 - DBG("sk %p", sk);
26018 - if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) {
26023 - if (sk->state != BT_OPEN && sk->state != BT_BOUND) {
26028 - if (sk->type == SOCK_SEQPACKET && !la->l2_psm) {
26033 - /* Set destination address and psm */
26034 - bacpy(&l2cap_pi(sk)->dst, &la->l2_bdaddr);
26035 - l2cap_pi(sk)->psm = la->l2_psm;
26037 - if ((err = l2cap_connect(sk)))
26040 - err = l2cap_sock_w4_connect(sk, flags);
26043 - release_sock(sk);
26047 -int l2cap_sock_listen(struct socket *sock, int backlog)
26049 - struct sock *sk = sock->sk;
26052 - DBG("sk %p backlog %d", sk, backlog);
26056 - if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
26061 - if (!l2cap_pi(sk)->psm) {
26066 - sk->max_ack_backlog = backlog;
26067 - sk->ack_backlog = 0;
26068 - sk->state = BT_LISTEN;
26071 - release_sock(sk);
26075 -int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
26077 - DECLARE_WAITQUEUE(wait, current);
26078 - struct sock *sk = sock->sk, *ch;
26084 - if (sk->state != BT_LISTEN) {
26089 - timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
26091 - DBG("sk %p timeo %ld", sk, timeo);
26093 - /* Wait for an incoming connection. (wake-one). */
26094 - add_wait_queue_exclusive(sk->sleep, &wait);
26095 - current->state = TASK_INTERRUPTIBLE;
26096 - while (!(ch = l2cap_accept_dequeue(sk, BT_CONNECTED))) {
26102 - release_sock(sk);
26103 - timeo = schedule_timeout(timeo);
26106 - if (sk->state != BT_LISTEN) {
26111 - if (signal_pending(current)) {
26112 - err = sock_intr_errno(timeo);
26116 - current->state = TASK_RUNNING;
26117 - remove_wait_queue(sk->sleep, &wait);
26122 - sock_graft(ch, newsock);
26123 - newsock->state = SS_CONNECTED;
26125 - DBG("new socket %p", ch);
26128 - release_sock(sk);
26133 -static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
26135 - struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
26136 - struct sock *sk = sock->sk;
26138 - DBG("sock %p, sk %p", sock, sk);
26140 - addr->sa_family = AF_BLUETOOTH;
26141 - *len = sizeof(struct sockaddr_l2);
26144 - bacpy(&la->l2_bdaddr, &l2cap_pi(sk)->dst);
26146 - bacpy(&la->l2_bdaddr, &l2cap_pi(sk)->src);
26148 - la->l2_psm = l2cap_pi(sk)->psm;
26153 -static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
26155 - struct sock *sk = sock->sk;
26158 - DBG("sock %p, sk %p", sock, sk);
26161 - return sock_error(sk);
26163 - if (msg->msg_flags & MSG_OOB)
26164 - return -EOPNOTSUPP;
26168 - if (sk->state == BT_CONNECTED)
26169 - err = l2cap_chan_send(sk, msg, len);
26173 - release_sock(sk);
26177 -static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
26179 - struct sock *sk = sock->sk;
26180 - int noblock = flags & MSG_DONTWAIT;
26182 - struct sk_buff *skb;
26184 - DBG("sock %p, sk %p", sock, sk);
26186 - if (flags & (MSG_OOB))
26187 - return -EOPNOTSUPP;
26189 - if (sk->state == BT_CLOSED)
26192 - if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
26195 - msg->msg_namelen = 0;
26197 - copied = skb->len;
26198 - if (len < copied) {
26199 - msg->msg_flags |= MSG_TRUNC;
26203 - skb->h.raw = skb->data;
26204 - err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
26206 - skb_free_datagram(sk, skb);
26208 - return err ? : copied;
26211 -int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
26213 - struct sock *sk = sock->sk;
26214 - struct l2cap_options opts;
26217 - DBG("sk %p", sk);
26221 - switch (optname) {
26222 - case L2CAP_OPTIONS:
26223 - if (copy_from_user((char *)&opts, optval, optlen)) {
26227 - l2cap_pi(sk)->imtu = opts.imtu;
26228 - l2cap_pi(sk)->omtu = opts.omtu;
26232 - err = -ENOPROTOOPT;
26236 - release_sock(sk);
26240 -int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
26242 - struct sock *sk = sock->sk;
26243 - struct l2cap_options opts;
26244 - struct l2cap_conninfo cinfo;
26245 - int len, err = 0;
26247 - if (get_user(len, optlen))
26252 - switch (optname) {
26253 - case L2CAP_OPTIONS:
26254 - opts.imtu = l2cap_pi(sk)->imtu;
26255 - opts.omtu = l2cap_pi(sk)->omtu;
26256 - opts.flush_to = l2cap_pi(sk)->flush_to;
26258 - len = MIN(len, sizeof(opts));
26259 - if (copy_to_user(optval, (char *)&opts, len))
26264 - case L2CAP_CONNINFO:
26265 - if (sk->state != BT_CONNECTED) {
26270 - cinfo.hci_handle = l2cap_pi(sk)->conn->hconn->handle;
26272 - len = MIN(len, sizeof(cinfo));
26273 - if (copy_to_user(optval, (char *)&cinfo, len))
26279 - err = -ENOPROTOOPT;
26283 - release_sock(sk);
26287 -static unsigned int l2cap_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
26289 - struct sock *sk = sock->sk;
26290 - struct l2cap_accept_q *aq;
26291 - unsigned int mask;
26293 - DBG("sock %p, sk %p", sock, sk);
26295 - poll_wait(file, sk->sleep, wait);
26298 - if (sk->err || !skb_queue_empty(&sk->error_queue))
26301 - if (sk->shutdown == SHUTDOWN_MASK)
26304 - aq = &l2cap_pi(sk)->accept_q;
26305 - if (!skb_queue_empty(&sk->receive_queue) || aq->head || (sk->shutdown & RCV_SHUTDOWN))
26306 - mask |= POLLIN | POLLRDNORM;
26308 - if (sk->state == BT_CLOSED)
26311 - if (sock_writeable(sk))
26312 - mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
26314 - set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
26319 -static int l2cap_sock_release(struct socket *sock)
26321 - struct sock *sk = sock->sk;
26323 - DBG("sock %p, sk %p", sock, sk);
26330 - l2cap_sock_close(sk);
26335 -/* --------- L2CAP channels --------- */
26336 -static struct sock * __l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
26340 - for (s = l->head; s; s = l2cap_pi(s)->next_c) {
26341 - if (l2cap_pi(s)->dcid == cid)
26348 -static inline struct sock *l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
26352 - read_lock(&l->lock);
26353 - s = __l2cap_get_chan_by_dcid(l, cid);
26354 - read_unlock(&l->lock);
26359 -static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
26363 - for (s = l->head; s; s = l2cap_pi(s)->next_c) {
26364 - if (l2cap_pi(s)->scid == cid)
26370 -static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
26374 - read_lock(&l->lock);
26375 - s = __l2cap_get_chan_by_scid(l, cid);
26376 - read_unlock(&l->lock);
26381 -static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
26385 - for (s = l->head; s; s = l2cap_pi(s)->next_c) {
26386 - if (l2cap_pi(s)->ident == ident)
26393 -static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
26397 - read_lock(&l->lock);
26398 - s = __l2cap_get_chan_by_ident(l, ident);
26399 - read_unlock(&l->lock);
26404 -static __u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
26406 - __u16 cid = 0x0040;
26408 - for (; cid < 0xffff; cid++) {
26409 - if(!__l2cap_get_chan_by_scid(l, cid))
26416 -static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
26421 - l2cap_pi(l->head)->prev_c = sk;
26423 - l2cap_pi(sk)->next_c = l->head;
26424 - l2cap_pi(sk)->prev_c = NULL;
26428 -static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
26430 - struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
26432 - write_lock(&l->lock);
26433 - if (sk == l->head)
26437 - l2cap_pi(next)->prev_c = prev;
26439 - l2cap_pi(prev)->next_c = next;
26440 - write_unlock(&l->lock);
26445 -static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
26447 - struct l2cap_chan_list *l = &conn->chan_list;
26449 - DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
26451 - l2cap_conn_clear_timer(conn);
26453 - atomic_inc(&conn->refcnt);
26454 - l2cap_pi(sk)->conn = conn;
26456 - if (sk->type == SOCK_SEQPACKET) {
26457 - /* Alloc CID for normal socket */
26458 - l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
26460 - /* Raw socket can send only signalling messages */
26461 - l2cap_pi(sk)->scid = 0x0001;
26462 - l2cap_pi(sk)->dcid = 0x0001;
26463 - l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
26466 - __l2cap_chan_link(l, sk);
26469 - l2cap_accept_queue(parent, sk);
26472 -static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
26474 - struct l2cap_chan_list *l = &conn->chan_list;
26476 - write_lock(&l->lock);
26477 - __l2cap_chan_add(conn, sk, parent);
26478 - write_unlock(&l->lock);
26481 -/* Delete channel.
26482 - * Must be called on the locked socket. */
26483 -static void l2cap_chan_del(struct sock *sk, int err)
26485 - struct l2cap_conn *conn;
26486 - struct sock *parent;
26488 - conn = l2cap_pi(sk)->conn;
26489 - parent = l2cap_pi(sk)->parent;
26491 - DBG("sk %p, conn %p, err %d", sk, conn, err);
26494 - /* Unlink from parent accept queue */
26495 - bh_lock_sock(parent);
26496 - l2cap_accept_unlink(sk);
26497 - bh_unlock_sock(parent);
26503 - /* Unlink from channel list */
26504 - l2cap_chan_unlink(&conn->chan_list, sk);
26505 - l2cap_pi(sk)->conn = NULL;
26508 - timeout = L2CAP_DISCONN_TIMEOUT;
26510 - timeout = L2CAP_CONN_IDLE_TIMEOUT;
26512 - if (atomic_dec_and_test(&conn->refcnt) && conn->state == BT_CONNECTED) {
26513 - /* Schedule Baseband disconnect */
26514 - l2cap_conn_set_timer(conn, timeout);
26518 - sk->state = BT_CLOSED;
26520 - sk->state_change(sk);
26525 -static void l2cap_conn_ready(struct l2cap_conn *conn)
26527 - struct l2cap_chan_list *l = &conn->chan_list;
26530 - DBG("conn %p", conn);
26532 - read_lock(&l->lock);
26534 - for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
26535 - bh_lock_sock(sk);
26537 - if (sk->type != SOCK_SEQPACKET) {
26538 - sk->state = BT_CONNECTED;
26539 - sk->state_change(sk);
26540 - l2cap_sock_clear_timer(sk);
26541 - } else if (sk->state == BT_CONNECT) {
26542 - l2cap_conn_req req;
26543 - req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
26544 - req.psm = l2cap_pi(sk)->psm;
26545 - l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
26547 - l2cap_sock_set_timer(sk, sk->sndtimeo);
26550 - bh_unlock_sock(sk);
26553 - read_unlock(&l->lock);
26556 -static void l2cap_chan_ready(struct sock *sk)
26558 - struct sock *parent = l2cap_pi(sk)->parent;
26560 - DBG("sk %p, parent %p", sk, parent);
26562 - l2cap_pi(sk)->conf_state = 0;
26563 - l2cap_sock_clear_timer(sk);
26566 - /* Outgoing channel.
26567 - * Wake up socket sleeping on connect.
26569 - sk->state = BT_CONNECTED;
26570 - sk->state_change(sk);
26572 - /* Incomming channel.
26573 - * Wake up socket sleeping on accept.
26575 - parent->data_ready(parent, 1);
26579 -/* Copy frame to all raw sockets on that connection */
26580 -void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
26582 - struct l2cap_chan_list *l = &conn->chan_list;
26583 - struct sk_buff *nskb;
26584 - struct sock * sk;
26586 - DBG("conn %p", conn);
26588 - read_lock(&l->lock);
26589 - for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
26590 - if (sk->type != SOCK_RAW)
26593 - /* Don't send frame to the socket it came from */
26594 - if (skb->sk == sk)
26597 - if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
26600 - skb_queue_tail(&sk->receive_queue, nskb);
26601 - sk->data_ready(sk, nskb->len);
26603 - read_unlock(&l->lock);
26606 -static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
26608 - struct l2cap_conn *conn = l2cap_pi(sk)->conn;
26609 - struct sk_buff *skb, **frag;
26610 - int err, size, count, sent=0;
26613 - /* Check outgoing MTU */
26614 - if (len > l2cap_pi(sk)->omtu)
26617 - DBG("sk %p len %d", sk, len);
26619 - /* First fragment (with L2CAP header) */
26620 - count = MIN(conn->iff->mtu - L2CAP_HDR_SIZE, len);
26621 - size = L2CAP_HDR_SIZE + count;
26622 - if (!(skb = bluez_skb_send_alloc(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)))
26625 - /* Create L2CAP header */
26626 - lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
26627 - lh->len = __cpu_to_le16(len);
26628 - lh->cid = __cpu_to_le16(l2cap_pi(sk)->dcid);
26630 - if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
26638 - /* Continuation fragments (no L2CAP header) */
26639 - frag = &skb_shinfo(skb)->frag_list;
26641 - count = MIN(conn->iff->mtu, len);
26643 - *frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
26647 - if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
26655 - frag = &(*frag)->next;
26658 - if ((err = hci_send_acl(conn->hconn, skb, 0)) < 0)
26668 -/* --------- L2CAP signalling commands --------- */
26669 -static inline __u8 l2cap_get_ident(struct l2cap_conn *conn)
26673 - /* Get next available identificator.
26674 - * 1 - 199 are used by kernel.
26675 - * 200 - 254 are used by utilities like l2ping, etc
26678 - spin_lock(&conn->lock);
26680 - if (++conn->tx_ident > 199)
26681 - conn->tx_ident = 1;
26683 - id = conn->tx_ident;
26685 - spin_unlock(&conn->lock);
26690 -static inline struct sk_buff *l2cap_build_cmd(__u8 code, __u8 ident, __u16 len, void *data)
26692 - struct sk_buff *skb;
26693 - l2cap_cmd_hdr *cmd;
26697 - DBG("code 0x%2.2x, ident 0x%2.2x, len %d", code, ident, len);
26699 - size = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + len;
26700 - if (!(skb = bluez_skb_alloc(size, GFP_ATOMIC)))
26703 - lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
26704 - lh->len = __cpu_to_le16(L2CAP_CMD_HDR_SIZE + len);
26705 - lh->cid = __cpu_to_le16(0x0001);
26707 - cmd = (l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
26708 - cmd->code = code;
26709 - cmd->ident = ident;
26710 - cmd->len = __cpu_to_le16(len);
26713 - memcpy(skb_put(skb, len), data, len);
26718 -static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data)
26720 - struct sk_buff *skb;
26723 - DBG("code 0x%2.2x", code);
26725 - ident = l2cap_get_ident(conn);
26726 - if (!(skb = l2cap_build_cmd(code, ident, len, data)))
26728 - return hci_send_acl(conn->hconn, skb, 0);
26731 -static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data)
26733 - struct sk_buff *skb;
26735 - DBG("code 0x%2.2x", code);
26737 - if (!(skb = l2cap_build_cmd(code, ident, len, data)))
26739 - return hci_send_acl(conn->hconn, skb, 0);
26742 -static inline int l2cap_get_conf_opt(__u8 **ptr, __u8 *type, __u32 *val)
26744 - l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
26747 - *type = opt->type;
26748 - switch (opt->len) {
26750 - *val = *((__u8 *) opt->val);
26754 - *val = __le16_to_cpu(*((__u16 *)opt->val));
26758 - *val = __le32_to_cpu(*((__u32 *)opt->val));
26766 - DBG("type 0x%2.2x len %d val 0x%8.8x", *type, opt->len, *val);
26768 - len = L2CAP_CONF_OPT_SIZE + opt->len;
26775 -static inline void l2cap_parse_conf_req(struct sock *sk, char *data, int len)
26777 - __u8 type, hint; __u32 val;
26778 - __u8 *ptr = data;
26780 - DBG("sk %p len %d", sk, len);
26782 - while (len >= L2CAP_CONF_OPT_SIZE) {
26783 - len -= l2cap_get_conf_opt(&ptr, &type, &val);
26785 - hint = type & 0x80;
26789 - case L2CAP_CONF_MTU:
26790 - l2cap_pi(sk)->conf_mtu = val;
26793 - case L2CAP_CONF_FLUSH_TO:
26794 - l2cap_pi(sk)->flush_to = val;
26797 - case L2CAP_CONF_QOS:
26804 - /* FIXME: Reject unknon option */
26810 -static inline void l2cap_add_conf_opt(__u8 **ptr, __u8 type, __u8 len, __u32 val)
26812 - register l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
26814 - DBG("type 0x%2.2x len %d val 0x%8.8x", type, len, val);
26816 - opt->type = type;
26820 - *((__u8 *) opt->val) = val;
26824 - *((__u16 *) opt->val) = __cpu_to_le16(val);
26828 - *((__u32 *) opt->val) = __cpu_to_le32(val);
26832 - *ptr += L2CAP_CONF_OPT_SIZE + len;
26835 -static int l2cap_build_conf_req(struct sock *sk, __u8 *data)
26837 - struct l2cap_pinfo *pi = l2cap_pi(sk);
26838 - l2cap_conf_req *req = (l2cap_conf_req *) data;
26839 - __u8 *ptr = req->data;
26841 - DBG("sk %p", sk);
26843 - if (pi->imtu != L2CAP_DEFAULT_MTU)
26844 - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
26846 - /* FIXME. Need actual value of the flush timeout */
26847 - //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
26848 - // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
26850 - req->dcid = __cpu_to_le16(pi->dcid);
26851 - req->flags = __cpu_to_le16(0);
26853 - return ptr - data;
26856 -static int l2cap_conf_output(struct sock *sk, __u8 **ptr)
26858 - struct l2cap_pinfo *pi = l2cap_pi(sk);
26861 - /* Configure output options and let other side know
26862 - * which ones we don't like.
26864 - if (pi->conf_mtu < pi->omtu) {
26865 - l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, l2cap_pi(sk)->omtu);
26866 - result = L2CAP_CONF_UNACCEPT;
26868 - pi->omtu = pi->conf_mtu;
26871 - DBG("sk %p result %d", sk, result);
26875 -static int l2cap_build_conf_rsp(struct sock *sk, __u8 *data, int *result)
26877 - l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data;
26878 - __u8 *ptr = rsp->data;
26880 - DBG("sk %p complete %d", sk, result ? 1 : 0);
26883 - *result = l2cap_conf_output(sk, &ptr);
26885 - rsp->scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
26886 - rsp->result = __cpu_to_le16(result ? *result : 0);
26887 - rsp->flags = __cpu_to_le16(0);
26889 - return ptr - data;
26892 -static inline int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
26894 - struct l2cap_chan_list *list = &conn->chan_list;
26895 - l2cap_conn_req *req = (l2cap_conn_req *) data;
26896 - l2cap_conn_rsp rsp;
26897 - struct sock *sk, *parent;
26899 - __u16 scid = __le16_to_cpu(req->scid);
26900 - __u16 psm = req->psm;
26902 - DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
26904 - /* Check if we have socket listening on psm */
26905 - if (!(parent = l2cap_get_sock_listen(&conn->src, psm)))
26908 - bh_lock_sock(parent);
26909 - write_lock(&list->lock);
26911 - /* Check if we already have channel with that dcid */
26912 - if (__l2cap_get_chan_by_dcid(list, scid))
26915 - /* Check for backlog size */
26916 - if (parent->ack_backlog > parent->max_ack_backlog)
26919 - if (!(sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC)))
26922 - l2cap_sock_init(sk, parent);
26924 - bacpy(&l2cap_pi(sk)->src, &conn->src);
26925 - bacpy(&l2cap_pi(sk)->dst, &conn->dst);
26926 - l2cap_pi(sk)->psm = psm;
26927 - l2cap_pi(sk)->dcid = scid;
26929 - __l2cap_chan_add(conn, sk, parent);
26930 - sk->state = BT_CONFIG;
26932 - write_unlock(&list->lock);
26933 - bh_unlock_sock(parent);
26935 - rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
26936 - rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
26937 - rsp.result = __cpu_to_le16(0);
26938 - rsp.status = __cpu_to_le16(0);
26939 - l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
26944 - write_unlock(&list->lock);
26945 - bh_unlock_sock(parent);
26948 - rsp.scid = __cpu_to_le16(scid);
26949 - rsp.dcid = __cpu_to_le16(0);
26950 - rsp.status = __cpu_to_le16(0);
26951 - rsp.result = __cpu_to_le16(L2CAP_CONN_NO_MEM);
26952 - l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
26957 -static inline int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
26959 - l2cap_conn_rsp *rsp = (l2cap_conn_rsp *) data;
26960 - __u16 scid, dcid, result, status;
26963 - scid = __le16_to_cpu(rsp->scid);
26964 - dcid = __le16_to_cpu(rsp->dcid);
26965 - result = __le16_to_cpu(rsp->result);
26966 - status = __le16_to_cpu(rsp->status);
26968 - DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
26970 - if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
26973 - bh_lock_sock(sk);
26978 - sk->state = BT_CONFIG;
26979 - l2cap_pi(sk)->dcid = dcid;
26980 - l2cap_pi(sk)->conf_state |= CONF_REQ_SENT;
26982 - l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
26984 - l2cap_chan_del(sk, ECONNREFUSED);
26987 - bh_unlock_sock(sk);
26991 -static inline int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
26993 - l2cap_conf_req * req = (l2cap_conf_req *) data;
26994 - __u16 dcid, flags;
26999 - dcid = __le16_to_cpu(req->dcid);
27000 - flags = __le16_to_cpu(req->flags);
27002 - DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
27004 - if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
27007 - bh_lock_sock(sk);
27009 - l2cap_parse_conf_req(sk, req->data, cmd->len - L2CAP_CONF_REQ_SIZE);
27011 - if (flags & 0x01) {
27012 - /* Incomplete config. Send empty response. */
27013 - l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
27017 - /* Complete config. */
27018 - l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &result), rsp);
27023 - /* Output config done */
27024 - l2cap_pi(sk)->conf_state |= CONF_OUTPUT_DONE;
27026 - if (l2cap_pi(sk)->conf_state & CONF_INPUT_DONE) {
27027 - sk->state = BT_CONNECTED;
27028 - l2cap_chan_ready(sk);
27029 - } else if (!(l2cap_pi(sk)->conf_state & CONF_REQ_SENT)) {
27031 - l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
27035 - bh_unlock_sock(sk);
27040 -static inline int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
27042 - l2cap_conf_rsp *rsp = (l2cap_conf_rsp *)data;
27043 - __u16 scid, flags, result;
27047 - scid = __le16_to_cpu(rsp->scid);
27048 - flags = __le16_to_cpu(rsp->flags);
27049 - result = __le16_to_cpu(rsp->result);
27051 - DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
27053 - if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
27056 - bh_lock_sock(sk);
27059 - l2cap_disconn_req req;
27061 - /* They didn't like our options. Well... we do not negotiate.
27064 - sk->state = BT_DISCONN;
27066 - req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
27067 - req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
27068 - l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
27070 - l2cap_sock_set_timer(sk, sk->sndtimeo);
27074 - if (flags & 0x01)
27077 - /* Input config done */
27078 - l2cap_pi(sk)->conf_state |= CONF_INPUT_DONE;
27080 - if (l2cap_pi(sk)->conf_state & CONF_OUTPUT_DONE) {
27081 - sk->state = BT_CONNECTED;
27082 - l2cap_chan_ready(sk);
27086 - bh_unlock_sock(sk);
27091 -static inline int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
27093 - l2cap_disconn_req *req = (l2cap_disconn_req *) data;
27094 - l2cap_disconn_rsp rsp;
27095 - __u16 dcid, scid;
27098 - scid = __le16_to_cpu(req->scid);
27099 - dcid = __le16_to_cpu(req->dcid);
27101 - DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
27103 - if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
27106 - bh_lock_sock(sk);
27108 - rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
27109 - rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
27110 - l2cap_send_rsp(conn, cmd->ident, L2CAP_DISCONN_RSP, L2CAP_DISCONN_RSP_SIZE, &rsp);
27112 - l2cap_chan_del(sk, ECONNRESET);
27114 - bh_unlock_sock(sk);
27116 - l2cap_sock_kill(sk);
27121 -static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
27123 - l2cap_disconn_rsp *rsp = (l2cap_disconn_rsp *) data;
27124 - __u16 dcid, scid;
27127 - scid = __le16_to_cpu(rsp->scid);
27128 - dcid = __le16_to_cpu(rsp->dcid);
27130 - DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
27132 - if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
27135 - bh_lock_sock(sk);
27136 - l2cap_sock_clear_timer(sk);
27137 - l2cap_chan_del(sk, ECONNABORTED);
27138 - bh_unlock_sock(sk);
27140 - l2cap_sock_kill(sk);
27145 -static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
27147 - __u8 *data = skb->data;
27148 - int len = skb->len;
27149 - l2cap_cmd_hdr cmd;
27152 - while (len >= L2CAP_CMD_HDR_SIZE) {
27153 - memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
27154 - data += L2CAP_CMD_HDR_SIZE;
27155 - len -= L2CAP_CMD_HDR_SIZE;
27157 - cmd.len = __le16_to_cpu(cmd.len);
27159 - DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
27161 - if (cmd.len > len || !cmd.ident) {
27162 - DBG("corrupted command");
27166 - switch (cmd.code) {
27167 - case L2CAP_CONN_REQ:
27168 - err = l2cap_connect_req(conn, &cmd, data);
27171 - case L2CAP_CONN_RSP:
27172 - err = l2cap_connect_rsp(conn, &cmd, data);
27175 - case L2CAP_CONF_REQ:
27176 - err = l2cap_config_req(conn, &cmd, data);
27179 - case L2CAP_CONF_RSP:
27180 - err = l2cap_config_rsp(conn, &cmd, data);
27183 - case L2CAP_DISCONN_REQ:
27184 - err = l2cap_disconnect_req(conn, &cmd, data);
27187 - case L2CAP_DISCONN_RSP:
27188 - err = l2cap_disconnect_rsp(conn, &cmd, data);
27191 - case L2CAP_COMMAND_REJ:
27192 - /* FIXME: We should process this */
27193 - l2cap_raw_recv(conn, skb);
27196 - case L2CAP_ECHO_REQ:
27197 - l2cap_send_rsp(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data);
27200 - case L2CAP_ECHO_RSP:
27201 - case L2CAP_INFO_REQ:
27202 - case L2CAP_INFO_RSP:
27203 - l2cap_raw_recv(conn, skb);
27207 - ERR("Uknown signaling command 0x%2.2x", cmd.code);
27213 - l2cap_cmd_rej rej;
27214 - DBG("error %d", err);
27216 - /* FIXME: Map err to a valid reason. */
27217 - rej.reason = __cpu_to_le16(0);
27218 - l2cap_send_rsp(conn, cmd.ident, L2CAP_COMMAND_REJ, L2CAP_CMD_REJ_SIZE, &rej);
27228 -static inline int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
27232 - if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, cid))) {
27233 - DBG("unknown cid 0x%4.4x", cid);
27237 - DBG("sk %p, len %d", sk, skb->len);
27239 - if (sk->state != BT_CONNECTED)
27242 - if (l2cap_pi(sk)->imtu < skb->len)
27245 - skb_queue_tail(&sk->receive_queue, skb);
27246 - sk->data_ready(sk, skb->len);
27256 -static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
27258 - l2cap_hdr *lh = (l2cap_hdr *) skb->data;
27261 - skb_pull(skb, L2CAP_HDR_SIZE);
27262 - cid = __le16_to_cpu(lh->cid);
27263 - len = __le16_to_cpu(lh->len);
27265 - DBG("len %d, cid 0x%4.4x", len, cid);
27267 - if (cid == 0x0001)
27268 - l2cap_sig_channel(conn, skb);
27270 - l2cap_data_channel(conn, cid, skb);
27273 -/* ------------ L2CAP interface with lower layer (HCI) ------------- */
27274 -static int l2cap_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
27276 - struct hci_dev *hdev = (struct hci_dev *) ptr;
27278 - DBG("hdev %s, event %ld", hdev->name, event);
27280 - write_lock(&l2cap_rt_lock);
27284 - l2cap_iff_add(hdev);
27287 - case HCI_DEV_DOWN:
27288 - l2cap_iff_del(hdev);
27292 - write_unlock(&l2cap_rt_lock);
27294 - return NOTIFY_DONE;
27297 -int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
27299 - struct l2cap_iff *iff;
27301 - DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
27303 - if (!(iff = hdev->l2cap_data)) {
27304 - ERR("unknown interface");
27308 - /* Always accept connection */
27312 -int l2cap_connect_cfm(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 status, struct hci_conn *hconn)
27314 - struct l2cap_conn *conn;
27315 - struct l2cap_iff *iff;
27318 - DBG("hdev %s bdaddr %s hconn %p", hdev->name, batostr(bdaddr), hconn);
27320 - if (!(iff = hdev->l2cap_data)) {
27321 - ERR("unknown interface");
27325 - l2cap_iff_lock(iff);
27327 - conn = l2cap_get_conn_by_addr(iff, bdaddr);
27330 - /* Outgoing connection */
27331 - DBG("Outgoing connection: %s -> %s, %p, %2.2x", batostr(iff->bdaddr), batostr(bdaddr), conn, status);
27333 - if (!status && hconn) {
27334 - conn->state = BT_CONNECTED;
27335 - conn->hconn = hconn;
27337 - hconn->l2cap_data = (void *)conn;
27339 - /* Establish channels */
27340 - l2cap_conn_ready(conn);
27342 - l2cap_conn_del(conn, bterr(status));
27345 - /* Incomming connection */
27346 - DBG("Incomming connection: %s -> %s, %2.2x", batostr(iff->bdaddr), batostr(bdaddr), status);
27348 - if (status || !hconn)
27351 - if (!(conn = l2cap_conn_add(iff, bdaddr))) {
27356 - conn->hconn = hconn;
27357 - hconn->l2cap_data = (void *)conn;
27359 - conn->state = BT_CONNECTED;
27363 - l2cap_iff_unlock(iff);
27368 -int l2cap_disconn_ind(struct hci_conn *hconn, __u8 reason)
27370 - struct l2cap_conn *conn = hconn->l2cap_data;
27372 - DBG("hconn %p reason %d", hconn, reason);
27375 - ERR("unknown connection");
27378 - conn->hconn = NULL;
27380 - l2cap_iff_lock(conn->iff);
27381 - l2cap_conn_del(conn, bterr(reason));
27382 - l2cap_iff_unlock(conn->iff);
27387 -int l2cap_recv_acldata(struct hci_conn *hconn, struct sk_buff *skb, __u16 flags)
27389 - struct l2cap_conn *conn = hconn->l2cap_data;
27392 - ERR("unknown connection %p", hconn);
27396 - DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
27398 - if (flags & ACL_START) {
27399 - int flen, tlen, size;
27402 - if (conn->rx_len) {
27403 - ERR("Unexpected start frame (len %d)", skb->len);
27404 - kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
27405 - conn->rx_len = 0;
27408 - if (skb->len < L2CAP_HDR_SIZE) {
27409 - ERR("Frame is too small (len %d)", skb->len);
27413 - lh = (l2cap_hdr *)skb->data;
27414 - tlen = __le16_to_cpu(lh->len);
27415 - flen = skb->len - L2CAP_HDR_SIZE;
27417 - DBG("Start: total len %d, frag len %d", tlen, flen);
27419 - if (flen == tlen) {
27420 - /* Complete frame received */
27421 - l2cap_recv_frame(conn, skb);
27425 - /* Allocate skb for the complete frame (with header) */
27426 - size = L2CAP_HDR_SIZE + tlen;
27427 - if (!(conn->rx_skb = bluez_skb_alloc(size, GFP_ATOMIC)))
27430 - memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
27432 - conn->rx_len = tlen - flen;
27434 - DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
27436 - if (!conn->rx_len) {
27437 - ERR("Unexpected continuation frame (len %d)", skb->len);
27441 - if (skb->len > conn->rx_len) {
27442 - ERR("Fragment is too large (len %d)", skb->len);
27443 - kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
27447 - memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
27448 - conn->rx_len -= skb->len;
27450 - if (!conn->rx_len) {
27451 - /* Complete frame received */
27452 - l2cap_recv_frame(conn, conn->rx_skb);
27453 - conn->rx_skb = NULL;
27462 -struct proto_ops l2cap_sock_ops = {
27463 - family: PF_BLUETOOTH,
27464 - release: l2cap_sock_release,
27465 - bind: l2cap_sock_bind,
27466 - connect: l2cap_sock_connect,
27467 - listen: l2cap_sock_listen,
27468 - accept: l2cap_sock_accept,
27469 - getname: l2cap_sock_getname,
27470 - sendmsg: l2cap_sock_sendmsg,
27471 - recvmsg: l2cap_sock_recvmsg,
27472 - poll: l2cap_sock_poll,
27473 - socketpair: sock_no_socketpair,
27474 - ioctl: sock_no_ioctl,
27475 - shutdown: sock_no_shutdown,
27476 - setsockopt: l2cap_sock_setsockopt,
27477 - getsockopt: l2cap_sock_getsockopt,
27478 - mmap: sock_no_mmap
27481 -struct net_proto_family l2cap_sock_family_ops = {
27482 - family: PF_BLUETOOTH,
27483 - create: l2cap_sock_create
27486 -struct hci_proto l2cap_hci_proto = {
27488 - id: HCI_PROTO_L2CAP,
27489 - connect_ind: l2cap_connect_ind,
27490 - connect_cfm: l2cap_connect_cfm,
27491 - disconn_ind: l2cap_disconn_ind,
27492 - recv_acldata: l2cap_recv_acldata,
27495 -struct notifier_block l2cap_nblock = {
27496 - notifier_call: l2cap_dev_event
27499 -int __init l2cap_init(void)
27501 - INF("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc",
27503 - INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
27505 - if (bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops)) {
27506 - ERR("Can't register L2CAP socket");
27510 - if (hci_register_proto(&l2cap_hci_proto) < 0) {
27511 - ERR("Can't register L2CAP protocol");
27515 - hci_register_notifier(&l2cap_nblock);
27517 - l2cap_register_proc();
27522 -void l2cap_cleanup(void)
27524 - l2cap_unregister_proc();
27526 - /* Unregister socket, protocol and notifier */
27527 - if (bluez_sock_unregister(BTPROTO_L2CAP))
27528 - ERR("Can't unregister L2CAP socket");
27530 - if (hci_unregister_proto(&l2cap_hci_proto) < 0)
27531 - ERR("Can't unregister L2CAP protocol");
27533 - hci_unregister_notifier(&l2cap_nblock);
27535 - /* We _must_ not have any sockets and/or connections
27539 - /* Free interface list and unlock HCI devices */
27541 - struct list_head *list = &l2cap_iff_list;
27543 - while (!list_empty(list)) {
27544 - struct l2cap_iff *iff;
27546 - iff = list_entry(list->next, struct l2cap_iff, list);
27547 - l2cap_iff_del(iff->hdev);
27552 -module_init(l2cap_init);
27553 -module_exit(l2cap_cleanup);
27555 -MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
27556 -MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
27557 -MODULE_LICENSE("GPL");
27559 diff -urN linux-2.4.18/net/bluetooth/l2cap_proc.c linux-2.4.18-mh15/net/bluetooth/l2cap_proc.c
27560 --- linux-2.4.18/net/bluetooth/l2cap_proc.c 2001-09-07 18:28:38.000000000 +0200
27561 +++ linux-2.4.18-mh15/net/bluetooth/l2cap_proc.c 1970-01-01 01:00:00.000000000 +0100
27564 - BlueZ - Bluetooth protocol stack for Linux
27565 - Copyright (C) 2000-2001 Qualcomm Incorporated
27567 - Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
27569 - This program is free software; you can redistribute it and/or modify
27570 - it under the terms of the GNU General Public License version 2 as
27571 - published by the Free Software Foundation;
27573 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27574 - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27575 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
27576 - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
27577 - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
27578 - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
27579 - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
27580 - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27582 - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
27583 - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
27584 - SOFTWARE IS DISCLAIMED.
27588 - * BlueZ L2CAP proc fs support.
27590 - * $Id: l2cap_proc.c,v 1.2 2001/06/02 01:40:09 maxk Exp $
27593 -#include <linux/config.h>
27594 -#include <linux/module.h>
27596 -#include <linux/types.h>
27597 -#include <linux/errno.h>
27598 -#include <linux/kernel.h>
27599 -#include <linux/major.h>
27600 -#include <linux/sched.h>
27601 -#include <linux/slab.h>
27602 -#include <linux/poll.h>
27603 -#include <linux/fcntl.h>
27604 -#include <linux/init.h>
27605 -#include <linux/skbuff.h>
27606 -#include <linux/interrupt.h>
27607 -#include <linux/socket.h>
27608 -#include <linux/skbuff.h>
27609 -#include <linux/proc_fs.h>
27610 -#include <linux/list.h>
27611 -#include <net/sock.h>
27613 -#include <asm/system.h>
27614 -#include <asm/uaccess.h>
27616 -#include <net/bluetooth/bluez.h>
27617 -#include <net/bluetooth/bluetooth.h>
27618 -#include <net/bluetooth/hci_core.h>
27619 -#include <net/bluetooth/l2cap_core.h>
27621 -#ifndef L2CAP_DEBUG
27623 -#define DBG( A... )
27626 -/* ----- PROC fs support ----- */
27627 -static int l2cap_conn_dump(char *buf, struct l2cap_iff *iff)
27629 - struct list_head *p;
27632 - list_for_each(p, &iff->conn_list) {
27633 - struct l2cap_conn *c;
27635 - c = list_entry(p, struct l2cap_conn, list);
27636 - ptr += sprintf(ptr, " %p %d %p %p %s %s\n",
27637 - c, c->state, c->iff, c->hconn, batostr(&c->src), batostr(&c->dst));
27640 - return ptr - buf;
27643 -static int l2cap_iff_dump(char *buf)
27645 - struct list_head *p;
27648 - ptr += sprintf(ptr, "Interfaces:\n");
27650 - write_lock(&l2cap_rt_lock);
27652 - list_for_each(p, &l2cap_iff_list) {
27653 - struct l2cap_iff *iff;
27655 - iff = list_entry(p, struct l2cap_iff, list);
27657 - ptr += sprintf(ptr, " %s %p %p\n", iff->hdev->name, iff, iff->hdev);
27659 - l2cap_iff_lock(iff);
27660 - ptr += l2cap_conn_dump(ptr, iff);
27661 - l2cap_iff_unlock(iff);
27664 - write_unlock(&l2cap_rt_lock);
27666 - ptr += sprintf(ptr, "\n");
27668 - return ptr - buf;
27671 -static int l2cap_sock_dump(char *buf, struct bluez_sock_list *list)
27673 - struct l2cap_pinfo *pi;
27677 - ptr += sprintf(ptr, "Sockets:\n");
27679 - write_lock(&list->lock);
27681 - for (sk = list->head; sk; sk = sk->next) {
27682 - pi = l2cap_pi(sk);
27683 - 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,
27684 - batostr(&pi->src), batostr(&pi->dst), pi->scid, pi->dcid, pi->imtu, pi->omtu );
27687 - write_unlock(&list->lock);
27689 - ptr += sprintf(ptr, "\n");
27691 - return ptr - buf;
27694 -static int l2cap_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
27699 - DBG("count %d, offset %ld", count, offset);
27701 - ptr += l2cap_iff_dump(ptr);
27702 - ptr += l2cap_sock_dump(ptr, &l2cap_sk_list);
27705 - if (len <= count + offset)
27708 - *start = buf + offset;
27719 -void l2cap_register_proc(void)
27721 - create_proc_read_entry("bluetooth/l2cap", 0, 0, l2cap_read_proc, NULL);
27724 -void l2cap_unregister_proc(void)
27726 - remove_proc_entry("bluetooth/l2cap", NULL);
27728 diff -urN linux-2.4.18/net/bluetooth/lib.c linux-2.4.18-mh15/net/bluetooth/lib.c
27729 --- linux-2.4.18/net/bluetooth/lib.c 2001-09-07 18:28:38.000000000 +0200
27730 +++ linux-2.4.18-mh15/net/bluetooth/lib.c 2004-08-01 16:26:23.000000000 +0200
27733 * BlueZ kernel library.
27735 - * $Id: lib.c,v 1.3 2001/06/22 23:14:23 maxk Exp $
27736 + * $Id: lib.c,v 1.2 2002/06/20 19:55:08 maxk Exp $
27739 #include <linux/kernel.h>
27740 @@ -105,7 +105,7 @@
27749 diff -urN linux-2.4.18/net/bluetooth/Makefile linux-2.4.18-mh15/net/bluetooth/Makefile
27750 --- linux-2.4.18/net/bluetooth/Makefile 2001-06-12 04:15:27.000000000 +0200
27751 +++ linux-2.4.18-mh15/net/bluetooth/Makefile 2004-08-01 16:26:23.000000000 +0200
27754 -# Makefile for the Bluetooth subsystem
27755 +# Makefile for the Linux Bluetooth subsystem
27757 -O_TARGET := bluetooth.o
27759 -list-multi := hci.o l2cap.o
27760 -export-objs := syms.o
27761 -hci-objs := af_bluetooth.o hci_core.o hci_sock.o lib.o syms.o
27762 -l2cap-objs := l2cap_core.o l2cap_proc.o
27763 +O_TARGET := bluetooth.o
27765 -obj-$(CONFIG_BLUEZ) += hci.o
27766 +list-multi := bluez.o
27767 +export-objs := syms.o l2cap.o
27769 +bluez-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o lib.o syms.o
27771 +obj-$(CONFIG_BLUEZ) += bluez.o
27772 obj-$(CONFIG_BLUEZ_L2CAP) += l2cap.o
27773 +obj-$(CONFIG_BLUEZ_SCO) += sco.o
27775 -include $(TOPDIR)/Rules.make
27776 +subdir-$(CONFIG_BLUEZ_RFCOMM) += rfcomm
27777 +subdir-$(CONFIG_BLUEZ_BNEP) += bnep
27778 +subdir-$(CONFIG_BLUEZ_CMTP) += cmtp
27779 +subdir-$(CONFIG_BLUEZ_HIDP) += hidp
27781 +ifeq ($(CONFIG_BLUEZ_RFCOMM),y)
27782 +obj-y += rfcomm/rfcomm.o
27785 -hci.o: $(hci-objs)
27786 - $(LD) -r -o $@ $(hci-objs)
27787 +ifeq ($(CONFIG_BLUEZ_BNEP),y)
27788 +obj-y += bnep/bnep.o
27791 +ifeq ($(CONFIG_BLUEZ_CMTP),y)
27792 +obj-y += cmtp/cmtp.o
27795 +ifeq ($(CONFIG_BLUEZ_HIDP),y)
27796 +obj-y += hidp/hidp.o
27799 +include $(TOPDIR)/Rules.make
27801 -l2cap.o: $(l2cap-objs)
27802 - $(LD) -r -o $@ $(l2cap-objs)
27803 +bluez.o: $(bluez-objs)
27804 + $(LD) -r -o $@ $(bluez-objs)
27805 diff -urN linux-2.4.18/net/bluetooth/rfcomm/Config.in linux-2.4.18-mh15/net/bluetooth/rfcomm/Config.in
27806 --- linux-2.4.18/net/bluetooth/rfcomm/Config.in 1970-01-01 01:00:00.000000000 +0100
27807 +++ linux-2.4.18-mh15/net/bluetooth/rfcomm/Config.in 2004-08-01 16:26:23.000000000 +0200
27810 +# Bluetooth RFCOMM layer configuration
27813 +dep_tristate 'RFCOMM protocol support' CONFIG_BLUEZ_RFCOMM $CONFIG_BLUEZ_L2CAP
27815 +if [ "$CONFIG_BLUEZ_RFCOMM" != "n" ]; then
27816 + bool ' RFCOMM TTY support' CONFIG_BLUEZ_RFCOMM_TTY
27819 diff -urN linux-2.4.18/net/bluetooth/rfcomm/core.c linux-2.4.18-mh15/net/bluetooth/rfcomm/core.c
27820 --- linux-2.4.18/net/bluetooth/rfcomm/core.c 1970-01-01 01:00:00.000000000 +0100
27821 +++ linux-2.4.18-mh15/net/bluetooth/rfcomm/core.c 2004-08-01 16:26:23.000000000 +0200
27824 + RFCOMM implementation for Linux Bluetooth stack (BlueZ).
27825 + Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
27826 + Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
27828 + This program is free software; you can redistribute it and/or modify
27829 + it under the terms of the GNU General Public License version 2 as
27830 + published by the Free Software Foundation;
27832 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27833 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27834 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
27835 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
27836 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
27837 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
27838 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
27839 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27841 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
27842 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
27843 + SOFTWARE IS DISCLAIMED.
27847 + RPN support - Dirk Husemann <hud@zurich.ibm.com>
27853 + * $Id: core.c,v 1.46 2002/10/18 20:12:12 maxk Exp $
27856 +#define __KERNEL_SYSCALLS__
27858 +#include <linux/config.h>
27859 +#include <linux/module.h>
27860 +#include <linux/errno.h>
27861 +#include <linux/kernel.h>
27862 +#include <linux/sched.h>
27863 +#include <linux/signal.h>
27864 +#include <linux/init.h>
27865 +#include <linux/wait.h>
27866 +#include <linux/net.h>
27867 +#include <linux/proc_fs.h>
27868 +#include <net/sock.h>
27869 +#include <asm/uaccess.h>
27870 +#include <asm/unaligned.h>
27872 +#include <net/bluetooth/bluetooth.h>
27873 +#include <net/bluetooth/l2cap.h>
27874 +#include <net/bluetooth/rfcomm.h>
27876 +#define VERSION "1.1"
27878 +#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
27880 +#define BT_DBG(D...)
27883 +struct task_struct *rfcomm_thread;
27884 +DECLARE_MUTEX(rfcomm_sem);
27885 +unsigned long rfcomm_event;
27887 +static LIST_HEAD(session_list);
27888 +static atomic_t terminate, running;
27890 +static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len);
27891 +static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci);
27892 +static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci);
27893 +static int rfcomm_queue_disc(struct rfcomm_dlc *d);
27894 +static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type);
27895 +static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d);
27896 +static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig);
27897 +static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len);
27898 +static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits);
27899 +static void rfcomm_make_uih(struct sk_buff *skb, u8 addr);
27901 +static void rfcomm_process_connect(struct rfcomm_session *s);
27903 +/* ---- RFCOMM frame parsing macros ---- */
27904 +#define __get_dlci(b) ((b & 0xfc) >> 2)
27905 +#define __get_channel(b) ((b & 0xf8) >> 3)
27906 +#define __get_dir(b) ((b & 0x04) >> 2)
27907 +#define __get_type(b) ((b & 0xef))
27909 +#define __test_ea(b) ((b & 0x01))
27910 +#define __test_cr(b) ((b & 0x02))
27911 +#define __test_pf(b) ((b & 0x10))
27913 +#define __addr(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01)
27914 +#define __ctrl(type, pf) (((type & 0xef) | (pf << 4)))
27915 +#define __dlci(dir, chn) (((chn & 0x1f) << 1) | dir)
27916 +#define __srv_channel(dlci) (dlci >> 1)
27917 +#define __dir(dlci) (dlci & 0x01)
27919 +#define __len8(len) (((len) << 1) | 1)
27920 +#define __len16(len) ((len) << 1)
27923 +#define __mcc_type(cr, type) (((type << 2) | (cr << 1) | 0x01))
27924 +#define __get_mcc_type(b) ((b & 0xfc) >> 2)
27925 +#define __get_mcc_len(b) ((b & 0xfe) >> 1)
27928 +#define __rpn_line_settings(data, stop, parity) ((data & 0x3) | ((stop & 0x1) << 2) | ((parity & 0x3) << 3))
27929 +#define __get_rpn_data_bits(line) ((line) & 0x3)
27930 +#define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1)
27931 +#define __get_rpn_parity(line) (((line) >> 3) & 0x3)
27933 +/* ---- RFCOMM FCS computation ---- */
27935 +/* CRC on 2 bytes */
27936 +#define __crc(data) (rfcomm_crc_table[rfcomm_crc_table[0xff ^ data[0]] ^ data[1]])
27938 +/* FCS on 2 bytes */
27939 +static inline u8 __fcs(u8 *data)
27941 + return (0xff - __crc(data));
27944 +/* FCS on 3 bytes */
27945 +static inline u8 __fcs2(u8 *data)
27947 + return (0xff - rfcomm_crc_table[__crc(data) ^ data[2]]);
27951 +static inline int __check_fcs(u8 *data, int type, u8 fcs)
27953 + u8 f = __crc(data);
27955 + if (type != RFCOMM_UIH)
27956 + f = rfcomm_crc_table[f ^ data[2]];
27958 + return rfcomm_crc_table[f ^ fcs] != 0xcf;
27961 +/* ---- L2CAP callbacks ---- */
27962 +static void rfcomm_l2state_change(struct sock *sk)
27964 + BT_DBG("%p state %d", sk, sk->state);
27965 + rfcomm_schedule(RFCOMM_SCHED_STATE);
27968 +static void rfcomm_l2data_ready(struct sock *sk, int bytes)
27970 + BT_DBG("%p bytes %d", sk, bytes);
27971 + rfcomm_schedule(RFCOMM_SCHED_RX);
27974 +static int rfcomm_l2sock_create(struct socket **sock)
27980 + err = sock_create(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP, sock);
27982 + struct sock *sk = (*sock)->sk;
27983 + sk->data_ready = rfcomm_l2data_ready;
27984 + sk->state_change = rfcomm_l2state_change;
27989 +/* ---- RFCOMM DLCs ---- */
27990 +static void rfcomm_dlc_timeout(unsigned long arg)
27992 + struct rfcomm_dlc *d = (void *) arg;
27994 + BT_DBG("dlc %p state %ld", d, d->state);
27996 + set_bit(RFCOMM_TIMED_OUT, &d->flags);
27997 + rfcomm_dlc_put(d);
27998 + rfcomm_schedule(RFCOMM_SCHED_TIMEO);
28001 +static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout)
28003 + BT_DBG("dlc %p state %ld timeout %ld", d, d->state, timeout);
28005 + if (!mod_timer(&d->timer, jiffies + timeout))
28006 + rfcomm_dlc_hold(d);
28009 +static void rfcomm_dlc_clear_timer(struct rfcomm_dlc *d)
28011 + BT_DBG("dlc %p state %ld", d, d->state);
28013 + if (timer_pending(&d->timer) && del_timer(&d->timer))
28014 + rfcomm_dlc_put(d);
28017 +static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d)
28021 + d->state = BT_OPEN;
28024 + d->mtu = RFCOMM_DEFAULT_MTU;
28025 + d->v24_sig = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV;
28027 + d->cfc = RFCOMM_CFC_DISABLED;
28028 + d->rx_credits = RFCOMM_DEFAULT_CREDITS;
28031 +struct rfcomm_dlc *rfcomm_dlc_alloc(int prio)
28033 + struct rfcomm_dlc *d = kmalloc(sizeof(*d), prio);
28036 + memset(d, 0, sizeof(*d));
28038 + init_timer(&d->timer);
28039 + d->timer.function = rfcomm_dlc_timeout;
28040 + d->timer.data = (unsigned long) d;
28042 + skb_queue_head_init(&d->tx_queue);
28043 + spin_lock_init(&d->lock);
28044 + atomic_set(&d->refcnt, 1);
28046 + rfcomm_dlc_clear_state(d);
28052 +void rfcomm_dlc_free(struct rfcomm_dlc *d)
28056 + skb_queue_purge(&d->tx_queue);
28060 +static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d)
28062 + BT_DBG("dlc %p session %p", d, s);
28064 + rfcomm_session_hold(s);
28066 + rfcomm_dlc_hold(d);
28067 + list_add(&d->list, &s->dlcs);
28071 +static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
28073 + struct rfcomm_session *s = d->session;
28075 + BT_DBG("dlc %p refcnt %d session %p", d, atomic_read(&d->refcnt), s);
28077 + list_del(&d->list);
28078 + d->session = NULL;
28079 + rfcomm_dlc_put(d);
28081 + rfcomm_session_put(s);
28084 +static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci)
28086 + struct rfcomm_dlc *d;
28087 + struct list_head *p;
28089 + list_for_each(p, &s->dlcs) {
28090 + d = list_entry(p, struct rfcomm_dlc, list);
28091 + if (d->dlci == dlci)
28097 +static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
28099 + struct rfcomm_session *s;
28103 + BT_DBG("dlc %p state %ld %s %s channel %d",
28104 + d, d->state, batostr(src), batostr(dst), channel);
28106 + if (channel < 1 || channel > 30)
28109 + if (d->state != BT_OPEN && d->state != BT_CLOSED)
28112 + s = rfcomm_session_get(src, dst);
28114 + s = rfcomm_session_create(src, dst, &err);
28119 + dlci = __dlci(!s->initiator, channel);
28121 + /* Check if DLCI already exists */
28122 + if (rfcomm_dlc_get(s, dlci))
28125 + rfcomm_dlc_clear_state(d);
28128 + d->addr = __addr(s->initiator, dlci);
28131 + d->state = BT_CONFIG;
28132 + rfcomm_dlc_link(s, d);
28135 + d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc;
28137 + if (s->state == BT_CONNECTED)
28138 + rfcomm_send_pn(s, 1, d);
28139 + rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT);
28143 +int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
28150 + fs = get_fs(); set_fs(KERNEL_DS);
28151 + r = __rfcomm_dlc_open(d, src, dst, channel);
28158 +static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
28160 + struct rfcomm_session *s = d->session;
28164 + BT_DBG("dlc %p state %ld dlci %d err %d session %p",
28165 + d, d->state, d->dlci, err, s);
28167 + switch (d->state) {
28168 + case BT_CONNECTED:
28171 + d->state = BT_DISCONN;
28172 + if (skb_queue_empty(&d->tx_queue)) {
28173 + rfcomm_send_disc(s, d->dlci);
28174 + rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT);
28176 + rfcomm_queue_disc(d);
28177 + rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT * 2);
28182 + rfcomm_dlc_clear_timer(d);
28184 + rfcomm_dlc_lock(d);
28185 + d->state = BT_CLOSED;
28186 + d->state_change(d, err);
28187 + rfcomm_dlc_unlock(d);
28189 + skb_queue_purge(&d->tx_queue);
28190 + rfcomm_dlc_unlink(d);
28196 +int rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
28203 + fs = get_fs(); set_fs(KERNEL_DS);
28204 + r = __rfcomm_dlc_close(d, err);
28211 +int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
28213 + int len = skb->len;
28215 + if (d->state != BT_CONNECTED)
28216 + return -ENOTCONN;
28218 + BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len);
28220 + if (len > d->mtu)
28223 + rfcomm_make_uih(skb, d->addr);
28224 + skb_queue_tail(&d->tx_queue, skb);
28226 + if (!test_bit(RFCOMM_TX_THROTTLED, &d->flags))
28227 + rfcomm_schedule(RFCOMM_SCHED_TX);
28231 +void __rfcomm_dlc_throttle(struct rfcomm_dlc *d)
28233 + BT_DBG("dlc %p state %ld", d, d->state);
28236 + d->v24_sig |= RFCOMM_V24_FC;
28237 + set_bit(RFCOMM_MSC_PENDING, &d->flags);
28239 + rfcomm_schedule(RFCOMM_SCHED_TX);
28242 +void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
28244 + BT_DBG("dlc %p state %ld", d, d->state);
28247 + d->v24_sig &= ~RFCOMM_V24_FC;
28248 + set_bit(RFCOMM_MSC_PENDING, &d->flags);
28250 + rfcomm_schedule(RFCOMM_SCHED_TX);
28254 + Set/get modem status functions use _local_ status i.e. what we report
28255 + to the other side.
28256 + Remote status is provided by dlc->modem_status() callback.
28258 +int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig)
28260 + BT_DBG("dlc %p state %ld v24_sig 0x%x",
28261 + d, d->state, v24_sig);
28263 + if (test_bit(RFCOMM_RX_THROTTLED, &d->flags))
28264 + v24_sig |= RFCOMM_V24_FC;
28266 + v24_sig &= ~RFCOMM_V24_FC;
28268 + d->v24_sig = v24_sig;
28270 + if (!test_and_set_bit(RFCOMM_MSC_PENDING, &d->flags))
28271 + rfcomm_schedule(RFCOMM_SCHED_TX);
28276 +int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig)
28278 + BT_DBG("dlc %p state %ld v24_sig 0x%x",
28279 + d, d->state, d->v24_sig);
28281 + *v24_sig = d->v24_sig;
28285 +/* ---- RFCOMM sessions ---- */
28286 +struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
28288 + struct rfcomm_session *s = kmalloc(sizeof(*s), GFP_KERNEL);
28291 + memset(s, 0, sizeof(*s));
28293 + BT_DBG("session %p sock %p", s, sock);
28295 + INIT_LIST_HEAD(&s->dlcs);
28296 + s->state = state;
28299 + s->mtu = RFCOMM_DEFAULT_MTU;
28300 + s->cfc = RFCOMM_CFC_UNKNOWN;
28302 + list_add(&s->list, &session_list);
28304 + /* Do not increment module usage count for listeting sessions.
28305 + * Otherwise we won't be able to unload the module. */
28306 + if (state != BT_LISTEN)
28307 + MOD_INC_USE_COUNT;
28311 +void rfcomm_session_del(struct rfcomm_session *s)
28313 + int state = s->state;
28315 + BT_DBG("session %p state %ld", s, s->state);
28317 + list_del(&s->list);
28319 + if (state == BT_CONNECTED)
28320 + rfcomm_send_disc(s, 0);
28322 + sock_release(s->sock);
28325 + if (state != BT_LISTEN)
28326 + MOD_DEC_USE_COUNT;
28329 +struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
28331 + struct rfcomm_session *s;
28332 + struct list_head *p, *n;
28333 + struct bluez_pinfo *pi;
28334 + list_for_each_safe(p, n, &session_list) {
28335 + s = list_entry(p, struct rfcomm_session, list);
28336 + pi = bluez_pi(s->sock->sk);
28338 + if ((!bacmp(src, BDADDR_ANY) || !bacmp(&pi->src, src)) &&
28339 + !bacmp(&pi->dst, dst))
28345 +void rfcomm_session_close(struct rfcomm_session *s, int err)
28347 + struct rfcomm_dlc *d;
28348 + struct list_head *p, *n;
28350 + BT_DBG("session %p state %ld err %d", s, s->state, err);
28352 + rfcomm_session_hold(s);
28354 + s->state = BT_CLOSED;
28356 + /* Close all dlcs */
28357 + list_for_each_safe(p, n, &s->dlcs) {
28358 + d = list_entry(p, struct rfcomm_dlc, list);
28359 + d->state = BT_CLOSED;
28360 + __rfcomm_dlc_close(d, err);
28363 + rfcomm_session_put(s);
28366 +struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err)
28368 + struct rfcomm_session *s = NULL;
28369 + struct sockaddr_l2 addr;
28370 + struct l2cap_options opts;
28371 + struct socket *sock;
28374 + BT_DBG("%s %s", batostr(src), batostr(dst));
28376 + *err = rfcomm_l2sock_create(&sock);
28380 + bacpy(&addr.l2_bdaddr, src);
28381 + addr.l2_family = AF_BLUETOOTH;
28383 + *err = sock->ops->bind(sock, (struct sockaddr *) &addr, sizeof(addr));
28387 + /* Set L2CAP options */
28388 + size = sizeof(opts);
28389 + sock->ops->getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, &size);
28391 + opts.imtu = RFCOMM_MAX_L2CAP_MTU;
28392 + sock->ops->setsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, size);
28394 + s = rfcomm_session_add(sock, BT_BOUND);
28400 + s->initiator = 1;
28402 + bacpy(&addr.l2_bdaddr, dst);
28403 + addr.l2_family = AF_BLUETOOTH;
28404 + addr.l2_psm = htobs(RFCOMM_PSM);
28405 + *err = sock->ops->connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
28406 + if (*err == 0 || *err == -EAGAIN)
28409 + rfcomm_session_del(s);
28413 + sock_release(sock);
28417 +void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst)
28419 + struct sock *sk = s->sock->sk;
28421 + bacpy(src, &bluez_pi(sk)->src);
28423 + bacpy(dst, &bluez_pi(sk)->dst);
28426 +/* ---- RFCOMM frame sending ---- */
28427 +static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len)
28429 + struct socket *sock = s->sock;
28430 + struct iovec iv = { data, len };
28431 + struct msghdr msg;
28434 + BT_DBG("session %p len %d", s, len);
28436 + memset(&msg, 0, sizeof(msg));
28437 + msg.msg_iovlen = 1;
28438 + msg.msg_iov = &iv;
28440 + err = sock->ops->sendmsg(sock, &msg, len, 0);
28444 +static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci)
28446 + struct rfcomm_cmd cmd;
28448 + BT_DBG("%p dlci %d", s, dlci);
28450 + cmd.addr = __addr(s->initiator, dlci);
28451 + cmd.ctrl = __ctrl(RFCOMM_SABM, 1);
28452 + cmd.len = __len8(0);
28453 + cmd.fcs = __fcs2((u8 *) &cmd);
28455 + return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
28458 +static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci)
28460 + struct rfcomm_cmd cmd;
28462 + BT_DBG("%p dlci %d", s, dlci);
28464 + cmd.addr = __addr(!s->initiator, dlci);
28465 + cmd.ctrl = __ctrl(RFCOMM_UA, 1);
28466 + cmd.len = __len8(0);
28467 + cmd.fcs = __fcs2((u8 *) &cmd);
28469 + return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
28472 +static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci)
28474 + struct rfcomm_cmd cmd;
28476 + BT_DBG("%p dlci %d", s, dlci);
28478 + cmd.addr = __addr(s->initiator, dlci);
28479 + cmd.ctrl = __ctrl(RFCOMM_DISC, 1);
28480 + cmd.len = __len8(0);
28481 + cmd.fcs = __fcs2((u8 *) &cmd);
28483 + return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
28486 +static int rfcomm_queue_disc(struct rfcomm_dlc *d)
28488 + struct rfcomm_cmd *cmd;
28489 + struct sk_buff *skb;
28491 + BT_DBG("dlc %p dlci %d", d, d->dlci);
28493 + skb = alloc_skb(sizeof(*cmd), GFP_KERNEL);
28497 + cmd = (void *) __skb_put(skb, sizeof(*cmd));
28498 + cmd->addr = d->addr;
28499 + cmd->ctrl = __ctrl(RFCOMM_DISC, 1);
28500 + cmd->len = __len8(0);
28501 + cmd->fcs = __fcs2((u8 *) cmd);
28503 + skb_queue_tail(&d->tx_queue, skb);
28504 + rfcomm_schedule(RFCOMM_SCHED_TX);
28508 +static int rfcomm_send_dm(struct rfcomm_session *s, u8 dlci)
28510 + struct rfcomm_cmd cmd;
28512 + BT_DBG("%p dlci %d", s, dlci);
28514 + cmd.addr = __addr(!s->initiator, dlci);
28515 + cmd.ctrl = __ctrl(RFCOMM_DM, 1);
28516 + cmd.len = __len8(0);
28517 + cmd.fcs = __fcs2((u8 *) &cmd);
28519 + return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
28522 +static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type)
28524 + struct rfcomm_hdr *hdr;
28525 + struct rfcomm_mcc *mcc;
28526 + u8 buf[16], *ptr = buf;
28528 + BT_DBG("%p cr %d type %d", s, cr, type);
28530 + hdr = (void *) ptr; ptr += sizeof(*hdr);
28531 + hdr->addr = __addr(s->initiator, 0);
28532 + hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
28533 + hdr->len = __len8(sizeof(*mcc) + 1);
28535 + mcc = (void *) ptr; ptr += sizeof(*mcc);
28536 + mcc->type = __mcc_type(cr, RFCOMM_NSC);
28537 + mcc->len = __len8(1);
28539 + /* Type that we didn't like */
28540 + *ptr = __mcc_type(cr, type); ptr++;
28542 + *ptr = __fcs(buf); ptr++;
28544 + return rfcomm_send_frame(s, buf, ptr - buf);
28547 +static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d)
28549 + struct rfcomm_hdr *hdr;
28550 + struct rfcomm_mcc *mcc;
28551 + struct rfcomm_pn *pn;
28552 + u8 buf[16], *ptr = buf;
28554 + BT_DBG("%p cr %d dlci %d mtu %d", s, cr, d->dlci, d->mtu);
28556 + hdr = (void *) ptr; ptr += sizeof(*hdr);
28557 + hdr->addr = __addr(s->initiator, 0);
28558 + hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
28559 + hdr->len = __len8(sizeof(*mcc) + sizeof(*pn));
28561 + mcc = (void *) ptr; ptr += sizeof(*mcc);
28562 + mcc->type = __mcc_type(cr, RFCOMM_PN);
28563 + mcc->len = __len8(sizeof(*pn));
28565 + pn = (void *) ptr; ptr += sizeof(*pn);
28566 + pn->dlci = d->dlci;
28567 + pn->priority = d->priority;
28568 + pn->ack_timer = 0;
28569 + pn->max_retrans = 0;
28572 + pn->flow_ctrl = cr ? 0xf0 : 0xe0;
28573 + pn->credits = RFCOMM_DEFAULT_CREDITS;
28575 + pn->flow_ctrl = 0;
28579 + pn->mtu = htobs(d->mtu);
28581 + *ptr = __fcs(buf); ptr++;
28583 + return rfcomm_send_frame(s, buf, ptr - buf);
28586 +static int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,
28587 + u8 bit_rate, u8 data_bits, u8 stop_bits,
28588 + u8 parity, u8 flow_ctrl_settings,
28589 + u8 xon_char, u8 xoff_char, u16 param_mask)
28591 + struct rfcomm_hdr *hdr;
28592 + struct rfcomm_mcc *mcc;
28593 + struct rfcomm_rpn *rpn;
28594 + u8 buf[16], *ptr = buf;
28596 + BT_DBG("%p cr %d dlci %d bit_r 0x%x data_b 0x%x stop_b 0x%x parity 0x%x"
28597 + "flwc_s 0x%x xon_c 0x%x xoff_c 0x%x p_mask 0x%x",
28598 + s, cr, dlci, bit_rate, data_bits, stop_bits, parity,
28599 + flow_ctrl_settings, xon_char, xoff_char, param_mask);
28601 + hdr = (void *) ptr; ptr += sizeof(*hdr);
28602 + hdr->addr = __addr(s->initiator, 0);
28603 + hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
28604 + hdr->len = __len8(sizeof(*mcc) + sizeof(*rpn));
28606 + mcc = (void *) ptr; ptr += sizeof(*mcc);
28607 + mcc->type = __mcc_type(cr, RFCOMM_RPN);
28608 + mcc->len = __len8(sizeof(*rpn));
28610 + rpn = (void *) ptr; ptr += sizeof(*rpn);
28611 + rpn->dlci = __addr(1, dlci);
28612 + rpn->bit_rate = bit_rate;
28613 + rpn->line_settings = __rpn_line_settings(data_bits, stop_bits, parity);
28614 + rpn->flow_ctrl = flow_ctrl_settings;
28615 + rpn->xon_char = xon_char;
28616 + rpn->xoff_char = xoff_char;
28617 + rpn->param_mask = param_mask;
28619 + *ptr = __fcs(buf); ptr++;
28621 + return rfcomm_send_frame(s, buf, ptr - buf);
28624 +static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status)
28626 + struct rfcomm_hdr *hdr;
28627 + struct rfcomm_mcc *mcc;
28628 + struct rfcomm_rls *rls;
28629 + u8 buf[16], *ptr = buf;
28631 + BT_DBG("%p cr %d status 0x%x", s, cr, status);
28633 + hdr = (void *) ptr; ptr += sizeof(*hdr);
28634 + hdr->addr = __addr(s->initiator, 0);
28635 + hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
28636 + hdr->len = __len8(sizeof(*mcc) + sizeof(*rls));
28638 + mcc = (void *) ptr; ptr += sizeof(*mcc);
28639 + mcc->type = __mcc_type(cr, RFCOMM_RLS);
28640 + mcc->len = __len8(sizeof(*rls));
28642 + rls = (void *) ptr; ptr += sizeof(*rls);
28643 + rls->dlci = __addr(1, dlci);
28644 + rls->status = status;
28646 + *ptr = __fcs(buf); ptr++;
28648 + return rfcomm_send_frame(s, buf, ptr - buf);
28651 +static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig)
28653 + struct rfcomm_hdr *hdr;
28654 + struct rfcomm_mcc *mcc;
28655 + struct rfcomm_msc *msc;
28656 + u8 buf[16], *ptr = buf;
28658 + BT_DBG("%p cr %d v24 0x%x", s, cr, v24_sig);
28660 + hdr = (void *) ptr; ptr += sizeof(*hdr);
28661 + hdr->addr = __addr(s->initiator, 0);
28662 + hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
28663 + hdr->len = __len8(sizeof(*mcc) + sizeof(*msc));
28665 + mcc = (void *) ptr; ptr += sizeof(*mcc);
28666 + mcc->type = __mcc_type(cr, RFCOMM_MSC);
28667 + mcc->len = __len8(sizeof(*msc));
28669 + msc = (void *) ptr; ptr += sizeof(*msc);
28670 + msc->dlci = __addr(1, dlci);
28671 + msc->v24_sig = v24_sig | 0x01;
28673 + *ptr = __fcs(buf); ptr++;
28675 + return rfcomm_send_frame(s, buf, ptr - buf);
28678 +static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr)
28680 + struct rfcomm_hdr *hdr;
28681 + struct rfcomm_mcc *mcc;
28682 + u8 buf[16], *ptr = buf;
28684 + BT_DBG("%p cr %d", s, cr);
28686 + hdr = (void *) ptr; ptr += sizeof(*hdr);
28687 + hdr->addr = __addr(s->initiator, 0);
28688 + hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
28689 + hdr->len = __len8(sizeof(*mcc));
28691 + mcc = (void *) ptr; ptr += sizeof(*mcc);
28692 + mcc->type = __mcc_type(cr, RFCOMM_FCOFF);
28693 + mcc->len = __len8(0);
28695 + *ptr = __fcs(buf); ptr++;
28697 + return rfcomm_send_frame(s, buf, ptr - buf);
28700 +static int rfcomm_send_fcon(struct rfcomm_session *s, int cr)
28702 + struct rfcomm_hdr *hdr;
28703 + struct rfcomm_mcc *mcc;
28704 + u8 buf[16], *ptr = buf;
28706 + BT_DBG("%p cr %d", s, cr);
28708 + hdr = (void *) ptr; ptr += sizeof(*hdr);
28709 + hdr->addr = __addr(s->initiator, 0);
28710 + hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
28711 + hdr->len = __len8(sizeof(*mcc));
28713 + mcc = (void *) ptr; ptr += sizeof(*mcc);
28714 + mcc->type = __mcc_type(cr, RFCOMM_FCON);
28715 + mcc->len = __len8(0);
28717 + *ptr = __fcs(buf); ptr++;
28719 + return rfcomm_send_frame(s, buf, ptr - buf);
28722 +static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len)
28724 + struct socket *sock = s->sock;
28725 + struct iovec iv[3];
28726 + struct msghdr msg;
28727 + unsigned char hdr[5], crc[1];
28732 + BT_DBG("%p cr %d", s, cr);
28734 + hdr[0] = __addr(s->initiator, 0);
28735 + hdr[1] = __ctrl(RFCOMM_UIH, 0);
28736 + hdr[2] = 0x01 | ((len + 2) << 1);
28737 + hdr[3] = 0x01 | ((cr & 0x01) << 1) | (RFCOMM_TEST << 2);
28738 + hdr[4] = 0x01 | (len << 1);
28740 + crc[0] = __fcs(hdr);
28742 + iv[0].iov_base = hdr;
28743 + iv[0].iov_len = 5;
28744 + iv[1].iov_base = pattern;
28745 + iv[1].iov_len = len;
28746 + iv[2].iov_base = crc;
28747 + iv[2].iov_len = 1;
28749 + memset(&msg, 0, sizeof(msg));
28750 + msg.msg_iovlen = 3;
28751 + msg.msg_iov = iv;
28752 + return sock->ops->sendmsg(sock, &msg, 6 + len, 0);
28755 +static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits)
28757 + struct rfcomm_hdr *hdr;
28758 + u8 buf[16], *ptr = buf;
28760 + BT_DBG("%p addr %d credits %d", s, addr, credits);
28762 + hdr = (void *) ptr; ptr += sizeof(*hdr);
28763 + hdr->addr = addr;
28764 + hdr->ctrl = __ctrl(RFCOMM_UIH, 1);
28765 + hdr->len = __len8(0);
28767 + *ptr = credits; ptr++;
28769 + *ptr = __fcs(buf); ptr++;
28771 + return rfcomm_send_frame(s, buf, ptr - buf);
28774 +static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
28776 + struct rfcomm_hdr *hdr;
28777 + int len = skb->len;
28781 + hdr = (void *) skb_push(skb, 4);
28782 + put_unaligned(htobs(__len16(len)), (u16 *) &hdr->len);
28784 + hdr = (void *) skb_push(skb, 3);
28785 + hdr->len = __len8(len);
28787 + hdr->addr = addr;
28788 + hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
28790 + crc = skb_put(skb, 1);
28791 + *crc = __fcs((void *) hdr);
28794 +/* ---- RFCOMM frame reception ---- */
28795 +static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
28797 + BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
28800 + /* Data channel */
28801 + struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
28803 + rfcomm_send_dm(s, dlci);
28807 + switch (d->state) {
28809 + rfcomm_dlc_clear_timer(d);
28811 + rfcomm_dlc_lock(d);
28812 + d->state = BT_CONNECTED;
28813 + d->state_change(d, 0);
28814 + rfcomm_dlc_unlock(d);
28816 + rfcomm_send_msc(s, 1, dlci, d->v24_sig);
28820 + d->state = BT_CLOSED;
28821 + __rfcomm_dlc_close(d, 0);
28825 + /* Control channel */
28826 + switch (s->state) {
28828 + s->state = BT_CONNECTED;
28829 + rfcomm_process_connect(s);
28836 +static int rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci)
28840 + BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
28844 + struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
28846 + if (d->state == BT_CONNECT || d->state == BT_CONFIG)
28847 + err = ECONNREFUSED;
28849 + err = ECONNRESET;
28851 + d->state = BT_CLOSED;
28852 + __rfcomm_dlc_close(d, err);
28855 + if (s->state == BT_CONNECT)
28856 + err = ECONNREFUSED;
28858 + err = ECONNRESET;
28860 + s->state = BT_CLOSED;
28861 + rfcomm_session_close(s, err);
28866 +static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
28870 + BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
28873 + struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
28875 + rfcomm_send_ua(s, dlci);
28877 + if (d->state == BT_CONNECT || d->state == BT_CONFIG)
28878 + err = ECONNREFUSED;
28880 + err = ECONNRESET;
28882 + d->state = BT_CLOSED;
28883 + __rfcomm_dlc_close(d, err);
28885 + rfcomm_send_dm(s, dlci);
28888 + rfcomm_send_ua(s, 0);
28890 + if (s->state == BT_CONNECT)
28891 + err = ECONNREFUSED;
28893 + err = ECONNRESET;
28895 + s->state = BT_CLOSED;
28896 + rfcomm_session_close(s, err);
28902 +static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
28904 + struct rfcomm_dlc *d;
28907 + BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
28910 + rfcomm_send_ua(s, 0);
28912 + if (s->state == BT_OPEN) {
28913 + s->state = BT_CONNECTED;
28914 + rfcomm_process_connect(s);
28919 + /* Check if DLC exists */
28920 + d = rfcomm_dlc_get(s, dlci);
28922 + if (d->state == BT_OPEN) {
28923 + /* DLC was previously opened by PN request */
28924 + rfcomm_send_ua(s, dlci);
28926 + rfcomm_dlc_lock(d);
28927 + d->state = BT_CONNECTED;
28928 + d->state_change(d, 0);
28929 + rfcomm_dlc_unlock(d);
28931 + rfcomm_send_msc(s, 1, dlci, d->v24_sig);
28936 + /* Notify socket layer about incomming connection */
28937 + channel = __srv_channel(dlci);
28938 + if (rfcomm_connect_ind(s, channel, &d)) {
28940 + d->addr = __addr(s->initiator, dlci);
28941 + rfcomm_dlc_link(s, d);
28943 + rfcomm_send_ua(s, dlci);
28945 + rfcomm_dlc_lock(d);
28946 + d->state = BT_CONNECTED;
28947 + d->state_change(d, 0);
28948 + rfcomm_dlc_unlock(d);
28950 + rfcomm_send_msc(s, 1, dlci, d->v24_sig);
28952 + rfcomm_send_dm(s, dlci);
28958 +static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
28960 + struct rfcomm_session *s = d->session;
28962 + BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d",
28963 + d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits);
28965 + if (pn->flow_ctrl == 0xf0 || pn->flow_ctrl == 0xe0) {
28966 + d->cfc = s->cfc = RFCOMM_CFC_ENABLED;
28967 + d->tx_credits = pn->credits;
28969 + d->cfc = s->cfc = RFCOMM_CFC_DISABLED;
28970 + set_bit(RFCOMM_TX_THROTTLED, &d->flags);
28973 + d->priority = pn->priority;
28975 + d->mtu = s->mtu = btohs(pn->mtu);
28980 +static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb)
28982 + struct rfcomm_pn *pn = (void *) skb->data;
28983 + struct rfcomm_dlc *d;
28984 + u8 dlci = pn->dlci;
28986 + BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
28991 + d = rfcomm_dlc_get(s, dlci);
28995 + rfcomm_apply_pn(d, cr, pn);
28996 + rfcomm_send_pn(s, 0, d);
28998 + /* PN response */
28999 + switch (d->state) {
29001 + rfcomm_apply_pn(d, cr, pn);
29003 + d->state = BT_CONNECT;
29004 + rfcomm_send_sabm(s, d->dlci);
29009 + u8 channel = __srv_channel(dlci);
29014 + /* PN request for non existing DLC.
29015 + * Assume incomming connection. */
29016 + if (rfcomm_connect_ind(s, channel, &d)) {
29018 + d->addr = __addr(s->initiator, dlci);
29019 + rfcomm_dlc_link(s, d);
29021 + rfcomm_apply_pn(d, cr, pn);
29023 + d->state = BT_OPEN;
29024 + rfcomm_send_pn(s, 0, d);
29026 + rfcomm_send_dm(s, dlci);
29032 +static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_buff *skb)
29034 + struct rfcomm_rpn *rpn = (void *) skb->data;
29035 + u8 dlci = __get_dlci(rpn->dlci);
29038 + u8 data_bits = 0;
29039 + u8 stop_bits = 0;
29041 + u8 flow_ctrl = 0;
29043 + u8 xoff_char = 0;
29044 + u16 rpn_mask = RFCOMM_RPN_PM_ALL;
29046 + 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",
29047 + dlci, cr, len, rpn->bit_rate, rpn->line_settings, rpn->flow_ctrl,
29048 + rpn->xon_char, rpn->xoff_char, rpn->param_mask);
29054 + /* request: return default setting */
29055 + bit_rate = RFCOMM_RPN_BR_115200;
29056 + data_bits = RFCOMM_RPN_DATA_8;
29057 + stop_bits = RFCOMM_RPN_STOP_1;
29058 + parity = RFCOMM_RPN_PARITY_NONE;
29059 + flow_ctrl = RFCOMM_RPN_FLOW_NONE;
29060 + xon_char = RFCOMM_RPN_XON_CHAR;
29061 + xoff_char = RFCOMM_RPN_XOFF_CHAR;
29065 + /* check for sane values: ignore/accept bit_rate, 8 bits, 1 stop bit, no parity,
29066 + no flow control lines, normal XON/XOFF chars */
29067 + if (rpn->param_mask & RFCOMM_RPN_PM_BITRATE) {
29068 + bit_rate = rpn->bit_rate;
29069 + if (bit_rate != RFCOMM_RPN_BR_115200) {
29070 + BT_DBG("RPN bit rate mismatch 0x%x", bit_rate);
29071 + bit_rate = RFCOMM_RPN_BR_115200;
29072 + rpn_mask ^= RFCOMM_RPN_PM_BITRATE;
29075 + if (rpn->param_mask & RFCOMM_RPN_PM_DATA) {
29076 + data_bits = __get_rpn_data_bits(rpn->line_settings);
29077 + if (data_bits != RFCOMM_RPN_DATA_8) {
29078 + BT_DBG("RPN data bits mismatch 0x%x", data_bits);
29079 + data_bits = RFCOMM_RPN_DATA_8;
29080 + rpn_mask ^= RFCOMM_RPN_PM_DATA;
29083 + if (rpn->param_mask & RFCOMM_RPN_PM_STOP) {
29084 + stop_bits = __get_rpn_stop_bits(rpn->line_settings);
29085 + if (stop_bits != RFCOMM_RPN_STOP_1) {
29086 + BT_DBG("RPN stop bits mismatch 0x%x", stop_bits);
29087 + stop_bits = RFCOMM_RPN_STOP_1;
29088 + rpn_mask ^= RFCOMM_RPN_PM_STOP;
29091 + if (rpn->param_mask & RFCOMM_RPN_PM_PARITY) {
29092 + parity = __get_rpn_parity(rpn->line_settings);
29093 + if (parity != RFCOMM_RPN_PARITY_NONE) {
29094 + BT_DBG("RPN parity mismatch 0x%x", parity);
29095 + parity = RFCOMM_RPN_PARITY_NONE;
29096 + rpn_mask ^= RFCOMM_RPN_PM_PARITY;
29099 + if (rpn->param_mask & RFCOMM_RPN_PM_FLOW) {
29100 + flow_ctrl = rpn->flow_ctrl;
29101 + if (flow_ctrl != RFCOMM_RPN_FLOW_NONE) {
29102 + BT_DBG("RPN flow ctrl mismatch 0x%x", flow_ctrl);
29103 + flow_ctrl = RFCOMM_RPN_FLOW_NONE;
29104 + rpn_mask ^= RFCOMM_RPN_PM_FLOW;
29107 + if (rpn->param_mask & RFCOMM_RPN_PM_XON) {
29108 + xon_char = rpn->xon_char;
29109 + if (xon_char != RFCOMM_RPN_XON_CHAR) {
29110 + BT_DBG("RPN XON char mismatch 0x%x", xon_char);
29111 + xon_char = RFCOMM_RPN_XON_CHAR;
29112 + rpn_mask ^= RFCOMM_RPN_PM_XON;
29115 + if (rpn->param_mask & RFCOMM_RPN_PM_XOFF) {
29116 + xoff_char = rpn->xoff_char;
29117 + if (xoff_char != RFCOMM_RPN_XOFF_CHAR) {
29118 + BT_DBG("RPN XOFF char mismatch 0x%x", xoff_char);
29119 + xoff_char = RFCOMM_RPN_XOFF_CHAR;
29120 + rpn_mask ^= RFCOMM_RPN_PM_XOFF;
29125 + rfcomm_send_rpn(s, 0, dlci,
29126 + bit_rate, data_bits, stop_bits, parity, flow_ctrl,
29127 + xon_char, xoff_char, rpn_mask);
29132 +static int rfcomm_recv_rls(struct rfcomm_session *s, int cr, struct sk_buff *skb)
29134 + struct rfcomm_rls *rls = (void *) skb->data;
29135 + u8 dlci = __get_dlci(rls->dlci);
29137 + BT_DBG("dlci %d cr %d status 0x%x", dlci, cr, rls->status);
29142 + /* FIXME: We should probably do something with this
29143 + information here. But for now it's sufficient just
29144 + to reply -- Bluetooth 1.1 says it's mandatory to
29145 + recognise and respond to RLS */
29147 + rfcomm_send_rls(s, 0, dlci, rls->status);
29152 +static int rfcomm_recv_msc(struct rfcomm_session *s, int cr, struct sk_buff *skb)
29154 + struct rfcomm_msc *msc = (void *) skb->data;
29155 + struct rfcomm_dlc *d;
29156 + u8 dlci = __get_dlci(msc->dlci);
29158 + BT_DBG("dlci %d cr %d v24 0x%x", dlci, cr, msc->v24_sig);
29160 + d = rfcomm_dlc_get(s, dlci);
29165 + if (msc->v24_sig & RFCOMM_V24_FC && !d->cfc)
29166 + set_bit(RFCOMM_TX_THROTTLED, &d->flags);
29168 + clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
29170 + rfcomm_dlc_lock(d);
29171 + if (d->modem_status)
29172 + d->modem_status(d, msc->v24_sig);
29173 + rfcomm_dlc_unlock(d);
29175 + rfcomm_send_msc(s, 0, dlci, msc->v24_sig);
29177 + d->mscex |= RFCOMM_MSCEX_RX;
29179 + d->mscex |= RFCOMM_MSCEX_TX;
29184 +static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb)
29186 + struct rfcomm_mcc *mcc = (void *) skb->data;
29187 + u8 type, cr, len;
29189 + cr = __test_cr(mcc->type);
29190 + type = __get_mcc_type(mcc->type);
29191 + len = __get_mcc_len(mcc->len);
29193 + BT_DBG("%p type 0x%x cr %d", s, type, cr);
29195 + skb_pull(skb, 2);
29199 + rfcomm_recv_pn(s, cr, skb);
29203 + rfcomm_recv_rpn(s, cr, len, skb);
29207 + rfcomm_recv_rls(s, cr, skb);
29211 + rfcomm_recv_msc(s, cr, skb);
29214 + case RFCOMM_FCOFF:
29216 + set_bit(RFCOMM_TX_THROTTLED, &s->flags);
29217 + rfcomm_send_fcoff(s, 0);
29221 + case RFCOMM_FCON:
29223 + clear_bit(RFCOMM_TX_THROTTLED, &s->flags);
29224 + rfcomm_send_fcon(s, 0);
29228 + case RFCOMM_TEST:
29230 + rfcomm_send_test(s, 0, skb->data, skb->len);
29237 + BT_ERR("Unknown control type 0x%02x", type);
29238 + rfcomm_send_nsc(s, cr, type);
29244 +static int rfcomm_recv_data(struct rfcomm_session *s, u8 dlci, int pf, struct sk_buff *skb)
29246 + struct rfcomm_dlc *d;
29248 + BT_DBG("session %p state %ld dlci %d pf %d", s, s->state, dlci, pf);
29250 + d = rfcomm_dlc_get(s, dlci);
29252 + rfcomm_send_dm(s, dlci);
29256 + if (pf && d->cfc) {
29257 + u8 credits = *(u8 *) skb->data; skb_pull(skb, 1);
29259 + d->tx_credits += credits;
29260 + if (d->tx_credits)
29261 + clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
29264 + if (skb->len && d->state == BT_CONNECTED) {
29265 + rfcomm_dlc_lock(d);
29267 + d->data_ready(d, skb);
29268 + rfcomm_dlc_unlock(d);
29277 +static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
29279 + struct rfcomm_hdr *hdr = (void *) skb->data;
29280 + u8 type, dlci, fcs;
29282 + dlci = __get_dlci(hdr->addr);
29283 + type = __get_type(hdr->ctrl);
29286 + skb->len--; skb->tail--;
29287 + fcs = *(u8 *) skb->tail;
29289 + if (__check_fcs(skb->data, type, fcs)) {
29290 + BT_ERR("bad checksum in packet");
29295 + if (__test_ea(hdr->len))
29296 + skb_pull(skb, 3);
29298 + skb_pull(skb, 4);
29301 + case RFCOMM_SABM:
29302 + if (__test_pf(hdr->ctrl))
29303 + rfcomm_recv_sabm(s, dlci);
29306 + case RFCOMM_DISC:
29307 + if (__test_pf(hdr->ctrl))
29308 + rfcomm_recv_disc(s, dlci);
29312 + if (__test_pf(hdr->ctrl))
29313 + rfcomm_recv_ua(s, dlci);
29317 + rfcomm_recv_dm(s, dlci);
29322 + return rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb);
29324 + rfcomm_recv_mcc(s, skb);
29328 + BT_ERR("Unknown packet type 0x%02x\n", type);
29335 +/* ---- Connection and data processing ---- */
29337 +static void rfcomm_process_connect(struct rfcomm_session *s)
29339 + struct rfcomm_dlc *d;
29340 + struct list_head *p, *n;
29342 + BT_DBG("session %p state %ld", s, s->state);
29344 + list_for_each_safe(p, n, &s->dlcs) {
29345 + d = list_entry(p, struct rfcomm_dlc, list);
29346 + if (d->state == BT_CONFIG) {
29348 + rfcomm_send_pn(s, 1, d);
29353 +/* Send data queued for the DLC.
29354 + * Return number of frames left in the queue.
29356 +static inline int rfcomm_process_tx(struct rfcomm_dlc *d)
29358 + struct sk_buff *skb;
29361 + BT_DBG("dlc %p state %ld cfc %d rx_credits %d tx_credits %d",
29362 + d, d->state, d->cfc, d->rx_credits, d->tx_credits);
29364 + /* Send pending MSC */
29365 + if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags))
29366 + rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
29370 + * Give them some credits */
29371 + if (!test_bit(RFCOMM_RX_THROTTLED, &d->flags) &&
29372 + d->rx_credits <= (d->cfc >> 2)) {
29373 + rfcomm_send_credits(d->session, d->addr, d->cfc - d->rx_credits);
29374 + d->rx_credits = d->cfc;
29378 + * Give ourselves some credits */
29379 + d->tx_credits = 5;
29382 + if (test_bit(RFCOMM_TX_THROTTLED, &d->flags))
29383 + return skb_queue_len(&d->tx_queue);
29385 + while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) {
29386 + err = rfcomm_send_frame(d->session, skb->data, skb->len);
29388 + skb_queue_head(&d->tx_queue, skb);
29395 + if (d->cfc && !d->tx_credits) {
29396 + /* We're out of TX credits.
29397 + * Set TX_THROTTLED flag to avoid unnesary wakeups by dlc_send. */
29398 + set_bit(RFCOMM_TX_THROTTLED, &d->flags);
29401 + return skb_queue_len(&d->tx_queue);
29404 +static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
29406 + struct rfcomm_dlc *d;
29407 + struct list_head *p, *n;
29409 + BT_DBG("session %p state %ld", s, s->state);
29411 + list_for_each_safe(p, n, &s->dlcs) {
29412 + d = list_entry(p, struct rfcomm_dlc, list);
29413 + if (test_bit(RFCOMM_TIMED_OUT, &d->flags)) {
29414 + __rfcomm_dlc_close(d, ETIMEDOUT);
29418 + if (test_bit(RFCOMM_TX_THROTTLED, &s->flags))
29421 + if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) &&
29422 + d->mscex == RFCOMM_MSCEX_OK)
29423 + rfcomm_process_tx(d);
29427 +static inline void rfcomm_process_rx(struct rfcomm_session *s)
29429 + struct socket *sock = s->sock;
29430 + struct sock *sk = sock->sk;
29431 + struct sk_buff *skb;
29433 + BT_DBG("session %p state %ld qlen %d", s, s->state, skb_queue_len(&sk->receive_queue));
29435 + /* Get data directly from socket receive queue without copying it. */
29436 + while ((skb = skb_dequeue(&sk->receive_queue))) {
29438 + rfcomm_recv_frame(s, skb);
29441 + if (sk->state == BT_CLOSED) {
29442 + if (!s->initiator)
29443 + rfcomm_session_put(s);
29445 + rfcomm_session_close(s, sk->err);
29449 +static inline void rfcomm_accept_connection(struct rfcomm_session *s)
29451 + struct socket *sock = s->sock, *nsock;
29454 + /* Fast check for a new connection.
29455 + * Avoids unnesesary socket allocations. */
29456 + if (list_empty(&bluez_pi(sock->sk)->accept_q))
29459 + BT_DBG("session %p", s);
29461 + nsock = sock_alloc();
29465 + nsock->type = sock->type;
29466 + nsock->ops = sock->ops;
29468 + err = sock->ops->accept(sock, nsock, O_NONBLOCK);
29470 + sock_release(nsock);
29474 + /* Set our callbacks */
29475 + nsock->sk->data_ready = rfcomm_l2data_ready;
29476 + nsock->sk->state_change = rfcomm_l2state_change;
29478 + s = rfcomm_session_add(nsock, BT_OPEN);
29480 + rfcomm_session_hold(s);
29481 + rfcomm_schedule(RFCOMM_SCHED_RX);
29483 + sock_release(nsock);
29486 +static inline void rfcomm_check_connection(struct rfcomm_session *s)
29488 + struct sock *sk = s->sock->sk;
29490 + BT_DBG("%p state %ld", s, s->state);
29492 + switch(sk->state) {
29493 + case BT_CONNECTED:
29494 + s->state = BT_CONNECT;
29496 + /* We can adjust MTU on outgoing sessions.
29497 + * L2CAP MTU minus UIH header and FCS. */
29498 + s->mtu = min(l2cap_pi(sk)->omtu, l2cap_pi(sk)->imtu) - 5;
29500 + rfcomm_send_sabm(s, 0);
29504 + s->state = BT_CLOSED;
29505 + rfcomm_session_close(s, sk->err);
29510 +static inline void rfcomm_process_sessions(void)
29512 + struct list_head *p, *n;
29516 + list_for_each_safe(p, n, &session_list) {
29517 + struct rfcomm_session *s;
29518 + s = list_entry(p, struct rfcomm_session, list);
29520 + if (s->state == BT_LISTEN) {
29521 + rfcomm_accept_connection(s);
29525 + rfcomm_session_hold(s);
29527 + switch (s->state) {
29529 + rfcomm_check_connection(s);
29533 + rfcomm_process_rx(s);
29537 + rfcomm_process_dlcs(s);
29539 + rfcomm_session_put(s);
29545 +static void rfcomm_worker(void)
29549 + daemonize(); reparent_to_init();
29550 + set_fs(KERNEL_DS);
29552 + while (!atomic_read(&terminate)) {
29553 + BT_DBG("worker loop event 0x%lx", rfcomm_event);
29555 + if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
29556 + /* No pending events. Let's sleep.
29557 + * Incomming connections and data will wake us up. */
29558 + set_current_state(TASK_INTERRUPTIBLE);
29562 + /* Process stuff */
29563 + clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
29564 + rfcomm_process_sessions();
29566 + set_current_state(TASK_RUNNING);
29570 +static int rfcomm_add_listener(bdaddr_t *ba)
29572 + struct sockaddr_l2 addr;
29573 + struct l2cap_options opts;
29574 + struct socket *sock;
29575 + struct rfcomm_session *s;
29576 + int size, err = 0;
29578 + /* Create socket */
29579 + err = rfcomm_l2sock_create(&sock);
29581 + BT_ERR("Create socket failed %d", err);
29585 + /* Bind socket */
29586 + bacpy(&addr.l2_bdaddr, ba);
29587 + addr.l2_family = AF_BLUETOOTH;
29588 + addr.l2_psm = htobs(RFCOMM_PSM);
29589 + err = sock->ops->bind(sock, (struct sockaddr *) &addr, sizeof(addr));
29591 + BT_ERR("Bind failed %d", err);
29595 + /* Set L2CAP options */
29596 + size = sizeof(opts);
29597 + sock->ops->getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, &size);
29599 + opts.imtu = RFCOMM_MAX_L2CAP_MTU;
29600 + sock->ops->setsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, size);
29602 + /* Start listening on the socket */
29603 + err = sock->ops->listen(sock, 10);
29605 + BT_ERR("Listen failed %d", err);
29609 + /* Add listening session */
29610 + s = rfcomm_session_add(sock, BT_LISTEN);
29614 + rfcomm_session_hold(s);
29617 + sock_release(sock);
29621 +static void rfcomm_kill_listener(void)
29623 + struct rfcomm_session *s;
29624 + struct list_head *p, *n;
29628 + list_for_each_safe(p, n, &session_list) {
29629 + s = list_entry(p, struct rfcomm_session, list);
29630 + rfcomm_session_del(s);
29634 +static int rfcomm_run(void *unused)
29636 + rfcomm_thread = current;
29638 + atomic_inc(&running);
29640 + daemonize(); reparent_to_init();
29642 + sigfillset(¤t->blocked);
29643 + set_fs(KERNEL_DS);
29645 + sprintf(current->comm, "krfcommd");
29649 + rfcomm_add_listener(BDADDR_ANY);
29653 + rfcomm_kill_listener();
29655 + atomic_dec(&running);
29659 +/* ---- Proc fs support ---- */
29660 +static int rfcomm_dlc_dump(char *buf)
29662 + struct rfcomm_session *s;
29664 + struct list_head *p, *pp;
29669 + list_for_each(p, &session_list) {
29670 + s = list_entry(p, struct rfcomm_session, list);
29671 + sk = s->sock->sk;
29673 + list_for_each(pp, &s->dlcs) {
29674 + struct rfcomm_dlc *d;
29675 + d = list_entry(pp, struct rfcomm_dlc, list);
29677 + ptr += sprintf(ptr, "dlc %s %s %ld %d %d %d %d\n",
29678 + batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
29679 + d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
29685 + return ptr - buf;
29688 +extern int rfcomm_sock_dump(char *buf);
29690 +static int rfcomm_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
29695 + BT_DBG("count %d, offset %ld", count, offset);
29697 + ptr += rfcomm_dlc_dump(ptr);
29698 + ptr += rfcomm_sock_dump(ptr);
29701 + if (len <= count + offset)
29704 + *start = buf + offset;
29715 +/* ---- Initialization ---- */
29716 +int __init rfcomm_init(void)
29720 + kernel_thread(rfcomm_run, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
29722 + rfcomm_init_sockets();
29724 +#ifdef CONFIG_BLUEZ_RFCOMM_TTY
29725 + rfcomm_init_ttys();
29728 + create_proc_read_entry("bluetooth/rfcomm", 0, 0, rfcomm_read_proc, NULL);
29730 + BT_INFO("BlueZ RFCOMM ver %s", VERSION);
29731 + BT_INFO("Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>");
29732 + BT_INFO("Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>");
29736 +void rfcomm_cleanup(void)
29738 + /* Terminate working thread.
29739 + * ie. Set terminate flag and wake it up */
29740 + atomic_inc(&terminate);
29741 + rfcomm_schedule(RFCOMM_SCHED_STATE);
29743 + /* Wait until thread is running */
29744 + while (atomic_read(&running))
29747 + remove_proc_entry("bluetooth/rfcomm", NULL);
29749 +#ifdef CONFIG_BLUEZ_RFCOMM_TTY
29750 + rfcomm_cleanup_ttys();
29753 + rfcomm_cleanup_sockets();
29757 +module_init(rfcomm_init);
29758 +module_exit(rfcomm_cleanup);
29760 +MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
29761 +MODULE_DESCRIPTION("BlueZ RFCOMM ver " VERSION);
29762 +MODULE_LICENSE("GPL");
29763 diff -urN linux-2.4.18/net/bluetooth/rfcomm/crc.c linux-2.4.18-mh15/net/bluetooth/rfcomm/crc.c
29764 --- linux-2.4.18/net/bluetooth/rfcomm/crc.c 1970-01-01 01:00:00.000000000 +0100
29765 +++ linux-2.4.18-mh15/net/bluetooth/rfcomm/crc.c 2004-08-01 16:26:23.000000000 +0200
29768 + RFCOMM implementation for Linux Bluetooth stack (BlueZ).
29769 + Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
29770 + Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
29772 + This program is free software; you can redistribute it and/or modify
29773 + it under the terms of the GNU General Public License version 2 as
29774 + published by the Free Software Foundation;
29776 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
29777 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29778 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
29779 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
29780 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
29781 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
29782 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
29783 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29785 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
29786 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
29787 + SOFTWARE IS DISCLAIMED.
29791 + * RFCOMM FCS calculation.
29793 + * $Id: crc.c,v 1.2 2002/09/21 09:54:32 holtmann Exp $
29796 +/* reversed, 8-bit, poly=0x07 */
29797 +unsigned char rfcomm_crc_table[256] = {
29798 + 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
29799 + 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
29800 + 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
29801 + 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
29803 + 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
29804 + 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
29805 + 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
29806 + 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
29808 + 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
29809 + 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
29810 + 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
29811 + 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
29813 + 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
29814 + 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
29815 + 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
29816 + 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
29818 + 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
29819 + 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
29820 + 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
29821 + 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
29823 + 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
29824 + 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
29825 + 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
29826 + 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
29828 + 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
29829 + 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
29830 + 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
29831 + 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
29833 + 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
29834 + 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
29835 + 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
29836 + 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
29838 diff -urN linux-2.4.18/net/bluetooth/rfcomm/Makefile linux-2.4.18-mh15/net/bluetooth/rfcomm/Makefile
29839 --- linux-2.4.18/net/bluetooth/rfcomm/Makefile 1970-01-01 01:00:00.000000000 +0100
29840 +++ linux-2.4.18-mh15/net/bluetooth/rfcomm/Makefile 2004-08-01 16:26:23.000000000 +0200
29843 +# Makefile for the Linux Bluetooth RFCOMM layer
29846 +O_TARGET := rfcomm.o
29848 +obj-y := core.o sock.o crc.o
29849 +obj-$(CONFIG_BLUEZ_RFCOMM_TTY) += tty.o
29850 +obj-m += $(O_TARGET)
29852 +include $(TOPDIR)/Rules.make
29853 diff -urN linux-2.4.18/net/bluetooth/rfcomm/sock.c linux-2.4.18-mh15/net/bluetooth/rfcomm/sock.c
29854 --- linux-2.4.18/net/bluetooth/rfcomm/sock.c 1970-01-01 01:00:00.000000000 +0100
29855 +++ linux-2.4.18-mh15/net/bluetooth/rfcomm/sock.c 2004-08-01 16:26:23.000000000 +0200
29858 + RFCOMM implementation for Linux Bluetooth stack (BlueZ).
29859 + Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
29860 + Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
29862 + This program is free software; you can redistribute it and/or modify
29863 + it under the terms of the GNU General Public License version 2 as
29864 + published by the Free Software Foundation;
29866 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
29867 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29868 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
29869 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
29870 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
29871 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
29872 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
29873 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29875 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
29876 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
29877 + SOFTWARE IS DISCLAIMED.
29881 + * RFCOMM sockets.
29883 + * $Id: sock.c,v 1.30 2002/10/18 20:12:12 maxk Exp $
29886 +#include <linux/config.h>
29887 +#include <linux/module.h>
29889 +#include <linux/types.h>
29890 +#include <linux/errno.h>
29891 +#include <linux/kernel.h>
29892 +#include <linux/major.h>
29893 +#include <linux/sched.h>
29894 +#include <linux/slab.h>
29895 +#include <linux/poll.h>
29896 +#include <linux/fcntl.h>
29897 +#include <linux/init.h>
29898 +#include <linux/skbuff.h>
29899 +#include <linux/interrupt.h>
29900 +#include <linux/socket.h>
29901 +#include <linux/skbuff.h>
29902 +#include <linux/list.h>
29903 +#include <net/sock.h>
29905 +#include <asm/system.h>
29906 +#include <asm/uaccess.h>
29908 +#include <net/bluetooth/bluetooth.h>
29909 +#include <net/bluetooth/rfcomm.h>
29911 +#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
29913 +#define BT_DBG(D...)
29916 +static struct proto_ops rfcomm_sock_ops;
29918 +static struct bluez_sock_list rfcomm_sk_list = {
29919 + lock: RW_LOCK_UNLOCKED
29922 +static void rfcomm_sock_close(struct sock *sk);
29923 +static void rfcomm_sock_kill(struct sock *sk);
29925 +/* ---- DLC callbacks ----
29927 + * called under rfcomm_dlc_lock()
29929 +static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb)
29931 + struct sock *sk = d->owner;
29935 + atomic_add(skb->len, &sk->rmem_alloc);
29936 + skb_queue_tail(&sk->receive_queue, skb);
29937 + sk->data_ready(sk, skb->len);
29939 + if (atomic_read(&sk->rmem_alloc) >= sk->rcvbuf)
29940 + rfcomm_dlc_throttle(d);
29943 +static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
29945 + struct sock *sk = d->owner, *parent;
29949 + BT_DBG("dlc %p state %ld err %d", d, d->state, err);
29951 + bh_lock_sock(sk);
29955 + sk->state = d->state;
29957 + parent = bluez_pi(sk)->parent;
29959 + if (d->state == BT_CONNECTED)
29960 + rfcomm_session_getaddr(d->session, &bluez_pi(sk)->src, NULL);
29961 + sk->state_change(sk);
29963 + parent->data_ready(parent, 0);
29965 + bh_unlock_sock(sk);
29968 +/* ---- Socket functions ---- */
29969 +static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
29973 + for (sk = rfcomm_sk_list.head; sk; sk = sk->next) {
29974 + if (rfcomm_pi(sk)->channel == channel &&
29975 + !bacmp(&bluez_pi(sk)->src, src))
29982 +/* Find socket with channel and source bdaddr.
29983 + * Returns closest match.
29985 +static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
29987 + struct sock *sk, *sk1 = NULL;
29989 + for (sk = rfcomm_sk_list.head; sk; sk = sk->next) {
29990 + if (state && sk->state != state)
29993 + if (rfcomm_pi(sk)->channel == channel) {
29994 + /* Exact match. */
29995 + if (!bacmp(&bluez_pi(sk)->src, src))
29998 + /* Closest match */
29999 + if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
30003 + return sk ? sk : sk1;
30006 +/* Find socket with given address (channel, src).
30007 + * Returns locked socket */
30008 +static inline struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
30011 + read_lock(&rfcomm_sk_list.lock);
30012 + s = __rfcomm_get_sock_by_channel(state, channel, src);
30013 + if (s) bh_lock_sock(s);
30014 + read_unlock(&rfcomm_sk_list.lock);
30018 +static void rfcomm_sock_destruct(struct sock *sk)
30020 + struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
30022 + BT_DBG("sk %p dlc %p", sk, d);
30024 + skb_queue_purge(&sk->receive_queue);
30025 + skb_queue_purge(&sk->write_queue);
30027 + rfcomm_dlc_lock(d);
30028 + rfcomm_pi(sk)->dlc = NULL;
30030 + /* Detach DLC if it's owned by this socket */
30031 + if (d->owner == sk)
30033 + rfcomm_dlc_unlock(d);
30035 + rfcomm_dlc_put(d);
30037 + MOD_DEC_USE_COUNT;
30040 +static void rfcomm_sock_cleanup_listen(struct sock *parent)
30044 + BT_DBG("parent %p", parent);
30046 + /* Close not yet accepted dlcs */
30047 + while ((sk = bluez_accept_dequeue(parent, NULL))) {
30048 + rfcomm_sock_close(sk);
30049 + rfcomm_sock_kill(sk);
30052 + parent->state = BT_CLOSED;
30053 + parent->zapped = 1;
30056 +/* Kill socket (only if zapped and orphan)
30057 + * Must be called on unlocked socket.
30059 +static void rfcomm_sock_kill(struct sock *sk)
30061 + if (!sk->zapped || sk->socket)
30064 + BT_DBG("sk %p state %d refcnt %d", sk, sk->state, atomic_read(&sk->refcnt));
30066 + /* Kill poor orphan */
30067 + bluez_sock_unlink(&rfcomm_sk_list, sk);
30072 +static void __rfcomm_sock_close(struct sock *sk)
30074 + struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
30076 + BT_DBG("sk %p state %d socket %p", sk, sk->state, sk->socket);
30078 + switch (sk->state) {
30080 + rfcomm_sock_cleanup_listen(sk);
30084 + case BT_CONNECT2:
30086 + case BT_CONNECTED:
30087 + rfcomm_dlc_close(d, 0);
30096 + * Must be called on unlocked socket.
30098 +static void rfcomm_sock_close(struct sock *sk)
30101 + __rfcomm_sock_close(sk);
30102 + release_sock(sk);
30105 +static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
30107 + BT_DBG("sk %p", sk);
30110 + sk->type = parent->type;
30113 +static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, int prio)
30115 + struct rfcomm_dlc *d;
30118 + sk = sk_alloc(PF_BLUETOOTH, prio, 1);
30122 + d = rfcomm_dlc_alloc(prio);
30127 + d->data_ready = rfcomm_sk_data_ready;
30128 + d->state_change = rfcomm_sk_state_change;
30130 + rfcomm_pi(sk)->dlc = d;
30133 + bluez_sock_init(sock, sk);
30137 + sk->destruct = rfcomm_sock_destruct;
30138 + sk->sndtimeo = RFCOMM_CONN_TIMEOUT;
30140 + sk->sndbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
30141 + sk->rcvbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
30143 + sk->protocol = proto;
30144 + sk->state = BT_OPEN;
30146 + bluez_sock_link(&rfcomm_sk_list, sk);
30148 + BT_DBG("sk %p", sk);
30150 + MOD_INC_USE_COUNT;
30154 +static int rfcomm_sock_create(struct socket *sock, int protocol)
30158 + BT_DBG("sock %p", sock);
30160 + sock->state = SS_UNCONNECTED;
30162 + if (sock->type != SOCK_STREAM && sock->type != SOCK_RAW)
30163 + return -ESOCKTNOSUPPORT;
30165 + sock->ops = &rfcomm_sock_ops;
30167 + if (!(sk = rfcomm_sock_alloc(sock, protocol, GFP_KERNEL)))
30170 + rfcomm_sock_init(sk, NULL);
30174 +static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
30176 + struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
30177 + struct sock *sk = sock->sk;
30180 + BT_DBG("sk %p %s", sk, batostr(&sa->rc_bdaddr));
30182 + if (!addr || addr->sa_family != AF_BLUETOOTH)
30187 + if (sk->state != BT_OPEN) {
30192 + write_lock_bh(&rfcomm_sk_list.lock);
30194 + if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
30195 + err = -EADDRINUSE;
30197 + /* Save source address */
30198 + bacpy(&bluez_pi(sk)->src, &sa->rc_bdaddr);
30199 + rfcomm_pi(sk)->channel = sa->rc_channel;
30200 + sk->state = BT_BOUND;
30203 + write_unlock_bh(&rfcomm_sk_list.lock);
30206 + release_sock(sk);
30210 +static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
30212 + struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
30213 + struct sock *sk = sock->sk;
30214 + struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
30217 + BT_DBG("sk %p", sk);
30219 + if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc))
30222 + if (sk->state != BT_OPEN && sk->state != BT_BOUND)
30225 + if (sk->type != SOCK_STREAM)
30230 + sk->state = BT_CONNECT;
30231 + bacpy(&bluez_pi(sk)->dst, &sa->rc_bdaddr);
30232 + rfcomm_pi(sk)->channel = sa->rc_channel;
30234 + err = rfcomm_dlc_open(d, &bluez_pi(sk)->src, &sa->rc_bdaddr, sa->rc_channel);
30236 + err = bluez_sock_wait_state(sk, BT_CONNECTED,
30237 + sock_sndtimeo(sk, flags & O_NONBLOCK));
30239 + release_sock(sk);
30243 +int rfcomm_sock_listen(struct socket *sock, int backlog)
30245 + struct sock *sk = sock->sk;
30248 + BT_DBG("sk %p backlog %d", sk, backlog);
30252 + if (sk->state != BT_BOUND) {
30257 + sk->max_ack_backlog = backlog;
30258 + sk->ack_backlog = 0;
30259 + sk->state = BT_LISTEN;
30262 + release_sock(sk);
30266 +int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags)
30268 + DECLARE_WAITQUEUE(wait, current);
30269 + struct sock *sk = sock->sk, *nsk;
30275 + if (sk->state != BT_LISTEN) {
30280 + timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
30282 + BT_DBG("sk %p timeo %ld", sk, timeo);
30284 + /* Wait for an incoming connection. (wake-one). */
30285 + add_wait_queue_exclusive(sk->sleep, &wait);
30286 + while (!(nsk = bluez_accept_dequeue(sk, newsock))) {
30287 + set_current_state(TASK_INTERRUPTIBLE);
30293 + release_sock(sk);
30294 + timeo = schedule_timeout(timeo);
30297 + if (sk->state != BT_LISTEN) {
30302 + if (signal_pending(current)) {
30303 + err = sock_intr_errno(timeo);
30307 + set_current_state(TASK_RUNNING);
30308 + remove_wait_queue(sk->sleep, &wait);
30313 + newsock->state = SS_CONNECTED;
30315 + BT_DBG("new socket %p", nsk);
30318 + release_sock(sk);
30322 +static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
30324 + struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
30325 + struct sock *sk = sock->sk;
30327 + BT_DBG("sock %p, sk %p", sock, sk);
30329 + sa->rc_family = AF_BLUETOOTH;
30330 + sa->rc_channel = rfcomm_pi(sk)->channel;
30332 + bacpy(&sa->rc_bdaddr, &bluez_pi(sk)->dst);
30334 + bacpy(&sa->rc_bdaddr, &bluez_pi(sk)->src);
30336 + *len = sizeof(struct sockaddr_rc);
30340 +static int rfcomm_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
30341 + struct scm_cookie *scm)
30343 + struct sock *sk = sock->sk;
30344 + struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
30345 + struct sk_buff *skb;
30349 + if (msg->msg_flags & MSG_OOB)
30350 + return -EOPNOTSUPP;
30352 + if (sk->shutdown & SEND_SHUTDOWN)
30355 + BT_DBG("sock %p, sk %p", sock, sk);
30360 + size = min_t(uint, len, d->mtu);
30362 + skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE,
30363 + msg->msg_flags & MSG_DONTWAIT, &err);
30366 + skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
30368 + err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
30375 + err = rfcomm_dlc_send(d, skb);
30385 + release_sock(sk);
30387 + return sent ? sent : err;
30390 +static long rfcomm_sock_data_wait(struct sock *sk, long timeo)
30392 + DECLARE_WAITQUEUE(wait, current);
30394 + add_wait_queue(sk->sleep, &wait);
30396 + set_current_state(TASK_INTERRUPTIBLE);
30398 + if (skb_queue_len(&sk->receive_queue) || sk->err || (sk->shutdown & RCV_SHUTDOWN) ||
30399 + signal_pending(current) || !timeo)
30402 + set_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
30403 + release_sock(sk);
30404 + timeo = schedule_timeout(timeo);
30406 + clear_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
30409 + __set_current_state(TASK_RUNNING);
30410 + remove_wait_queue(sk->sleep, &wait);
30414 +static int rfcomm_sock_recvmsg(struct socket *sock, struct msghdr *msg, int size,
30415 + int flags, struct scm_cookie *scm)
30417 + struct sock *sk = sock->sk;
30418 + int target, err = 0, copied = 0;
30421 + if (flags & MSG_OOB)
30422 + return -EOPNOTSUPP;
30424 + msg->msg_namelen = 0;
30426 + BT_DBG("sk %p size %d", sk, size);
30430 + target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
30431 + timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
30434 + struct sk_buff *skb;
30437 + skb = skb_dequeue(&sk->receive_queue);
30439 + if (copied >= target)
30442 + if ((err = sock_error(sk)) != 0)
30444 + if (sk->shutdown & RCV_SHUTDOWN)
30451 + timeo = rfcomm_sock_data_wait(sk, timeo);
30453 + if (signal_pending(current)) {
30454 + err = sock_intr_errno(timeo);
30460 + chunk = min_t(unsigned int, skb->len, size);
30461 + if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
30462 + skb_queue_head(&sk->receive_queue, skb);
30464 + copied = -EFAULT;
30470 + if (!(flags & MSG_PEEK)) {
30471 + atomic_sub(chunk, &sk->rmem_alloc);
30473 + skb_pull(skb, chunk);
30475 + skb_queue_head(&sk->receive_queue, skb);
30481 + /* put message back and return */
30482 + skb_queue_head(&sk->receive_queue, skb);
30488 + if (atomic_read(&sk->rmem_alloc) <= (sk->rcvbuf >> 2))
30489 + rfcomm_dlc_unthrottle(rfcomm_pi(sk)->dlc);
30491 + release_sock(sk);
30492 + return copied ? : err;
30495 +static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
30497 + struct sock *sk = sock->sk;
30500 + BT_DBG("sk %p", sk);
30504 + switch (optname) {
30506 + err = -ENOPROTOOPT;
30510 + release_sock(sk);
30514 +static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
30516 + struct sock *sk = sock->sk;
30517 + int len, err = 0;
30519 + BT_DBG("sk %p", sk);
30521 + if (get_user(len, optlen))
30526 + switch (optname) {
30528 + err = -ENOPROTOOPT;
30532 + release_sock(sk);
30536 +static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
30538 + struct sock *sk = sock->sk;
30543 +#ifdef CONFIG_BLUEZ_RFCOMM_TTY
30544 + err = rfcomm_dev_ioctl(sk, cmd, arg);
30546 + err = -EOPNOTSUPP;
30549 + release_sock(sk);
30554 +static int rfcomm_sock_shutdown(struct socket *sock, int how)
30556 + struct sock *sk = sock->sk;
30559 + BT_DBG("sock %p, sk %p", sock, sk);
30561 + if (!sk) return 0;
30564 + if (!sk->shutdown) {
30565 + sk->shutdown = SHUTDOWN_MASK;
30566 + __rfcomm_sock_close(sk);
30569 + err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
30571 + release_sock(sk);
30575 +static int rfcomm_sock_release(struct socket *sock)
30577 + struct sock *sk = sock->sk;
30580 + BT_DBG("sock %p, sk %p", sock, sk);
30585 + err = rfcomm_sock_shutdown(sock, 2);
30588 + rfcomm_sock_kill(sk);
30592 +/* ---- RFCOMM core layer callbacks ----
30594 + * called under rfcomm_lock()
30596 +int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d)
30598 + struct sock *sk, *parent;
30599 + bdaddr_t src, dst;
30602 + BT_DBG("session %p channel %d", s, channel);
30604 + rfcomm_session_getaddr(s, &src, &dst);
30606 + /* Check if we have socket listening on this channel */
30607 + parent = rfcomm_get_sock_by_channel(BT_LISTEN, channel, &src);
30611 + /* Check for backlog size */
30612 + if (parent->ack_backlog > parent->max_ack_backlog) {
30613 + BT_DBG("backlog full %d", parent->ack_backlog);
30617 + sk = rfcomm_sock_alloc(NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
30621 + rfcomm_sock_init(sk, parent);
30622 + bacpy(&bluez_pi(sk)->src, &src);
30623 + bacpy(&bluez_pi(sk)->dst, &dst);
30624 + rfcomm_pi(sk)->channel = channel;
30626 + sk->state = BT_CONFIG;
30627 + bluez_accept_enqueue(parent, sk);
30629 + /* Accept connection and return socket DLC */
30630 + *d = rfcomm_pi(sk)->dlc;
30634 + bh_unlock_sock(parent);
30638 +/* ---- Proc fs support ---- */
30639 +int rfcomm_sock_dump(char *buf)
30641 + struct bluez_sock_list *list = &rfcomm_sk_list;
30642 + struct rfcomm_pinfo *pi;
30646 + write_lock_bh(&list->lock);
30648 + for (sk = list->head; sk; sk = sk->next) {
30649 + pi = rfcomm_pi(sk);
30650 + ptr += sprintf(ptr, "sk %s %s %d %d\n",
30651 + batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
30652 + sk->state, rfcomm_pi(sk)->channel);
30655 + write_unlock_bh(&list->lock);
30657 + return ptr - buf;
30660 +static struct proto_ops rfcomm_sock_ops = {
30661 + family: PF_BLUETOOTH,
30662 + release: rfcomm_sock_release,
30663 + bind: rfcomm_sock_bind,
30664 + connect: rfcomm_sock_connect,
30665 + listen: rfcomm_sock_listen,
30666 + accept: rfcomm_sock_accept,
30667 + getname: rfcomm_sock_getname,
30668 + sendmsg: rfcomm_sock_sendmsg,
30669 + recvmsg: rfcomm_sock_recvmsg,
30670 + shutdown: rfcomm_sock_shutdown,
30671 + setsockopt: rfcomm_sock_setsockopt,
30672 + getsockopt: rfcomm_sock_getsockopt,
30673 + ioctl: rfcomm_sock_ioctl,
30674 + poll: bluez_sock_poll,
30675 + socketpair: sock_no_socketpair,
30676 + mmap: sock_no_mmap
30679 +static struct net_proto_family rfcomm_sock_family_ops = {
30680 + family: PF_BLUETOOTH,
30681 + create: rfcomm_sock_create
30684 +int rfcomm_init_sockets(void)
30688 + if ((err = bluez_sock_register(BTPROTO_RFCOMM, &rfcomm_sock_family_ops))) {
30689 + BT_ERR("Can't register RFCOMM socket layer");
30696 +void rfcomm_cleanup_sockets(void)
30700 + /* Unregister socket, protocol and notifier */
30701 + if ((err = bluez_sock_unregister(BTPROTO_RFCOMM)))
30702 + BT_ERR("Can't unregister RFCOMM socket layer %d", err);
30704 diff -urN linux-2.4.18/net/bluetooth/rfcomm/tty.c linux-2.4.18-mh15/net/bluetooth/rfcomm/tty.c
30705 --- linux-2.4.18/net/bluetooth/rfcomm/tty.c 1970-01-01 01:00:00.000000000 +0100
30706 +++ linux-2.4.18-mh15/net/bluetooth/rfcomm/tty.c 2004-08-01 16:26:23.000000000 +0200
30709 + RFCOMM implementation for Linux Bluetooth stack (BlueZ).
30710 + Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
30711 + Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
30713 + This program is free software; you can redistribute it and/or modify
30714 + it under the terms of the GNU General Public License version 2 as
30715 + published by the Free Software Foundation;
30717 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
30718 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30719 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
30720 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
30721 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
30722 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
30723 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
30724 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30726 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
30727 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
30728 + SOFTWARE IS DISCLAIMED.
30734 + * $Id: tty.c,v 1.26 2002/10/18 20:12:12 maxk Exp $
30737 +#include <linux/config.h>
30738 +#include <linux/module.h>
30740 +#include <linux/tty.h>
30741 +#include <linux/tty_driver.h>
30742 +#include <linux/tty_flip.h>
30744 +#include <linux/slab.h>
30745 +#include <linux/skbuff.h>
30747 +#include <net/bluetooth/bluetooth.h>
30748 +#include <net/bluetooth/rfcomm.h>
30750 +#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
30752 +#define BT_DBG(D...)
30755 +#define RFCOMM_TTY_MAGIC 0x6d02 /* magic number for rfcomm struct */
30756 +#define RFCOMM_TTY_PORTS RFCOMM_MAX_DEV /* whole lotta rfcomm devices */
30757 +#define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */
30758 +#define RFCOMM_TTY_MINOR 0
30760 +struct rfcomm_dev {
30761 + struct list_head list;
30766 + unsigned long flags;
30774 + uint modem_status;
30776 + struct rfcomm_dlc *dlc;
30777 + struct tty_struct *tty;
30778 + wait_queue_head_t wait;
30779 + struct tasklet_struct wakeup_task;
30781 + atomic_t wmem_alloc;
30784 +static LIST_HEAD(rfcomm_dev_list);
30785 +static rwlock_t rfcomm_dev_lock = RW_LOCK_UNLOCKED;
30787 +static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
30788 +static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
30789 +static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
30791 +static void rfcomm_tty_wakeup(unsigned long arg);
30793 +/* ---- Device functions ---- */
30794 +static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
30796 + struct rfcomm_dlc *dlc = dev->dlc;
30798 + BT_DBG("dev %p dlc %p", dev, dlc);
30800 + rfcomm_dlc_lock(dlc);
30801 + /* Detach DLC if it's owned by this dev */
30802 + if (dlc->owner == dev)
30803 + dlc->owner = NULL;
30804 + rfcomm_dlc_unlock(dlc);
30806 + rfcomm_dlc_put(dlc);
30809 + MOD_DEC_USE_COUNT;
30812 +static inline void rfcomm_dev_hold(struct rfcomm_dev *dev)
30814 + atomic_inc(&dev->refcnt);
30817 +static inline void rfcomm_dev_put(struct rfcomm_dev *dev)
30819 + /* The reason this isn't actually a race, as you no
30820 + doubt have a little voice screaming at you in your
30821 + head, is that the refcount should never actually
30822 + reach zero unless the device has already been taken
30823 + off the list, in rfcomm_dev_del(). And if that's not
30824 + true, we'll hit the BUG() in rfcomm_dev_destruct()
30826 + if (atomic_dec_and_test(&dev->refcnt))
30827 + rfcomm_dev_destruct(dev);
30830 +static struct rfcomm_dev *__rfcomm_dev_get(int id)
30832 + struct rfcomm_dev *dev;
30833 + struct list_head *p;
30835 + list_for_each(p, &rfcomm_dev_list) {
30836 + dev = list_entry(p, struct rfcomm_dev, list);
30837 + if (dev->id == id)
30844 +static inline struct rfcomm_dev *rfcomm_dev_get(int id)
30846 + struct rfcomm_dev *dev;
30848 + read_lock(&rfcomm_dev_lock);
30850 + dev = __rfcomm_dev_get(id);
30852 + rfcomm_dev_hold(dev);
30854 + read_unlock(&rfcomm_dev_lock);
30859 +static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
30861 + struct rfcomm_dev *dev;
30862 + struct list_head *head = &rfcomm_dev_list, *p;
30865 + BT_DBG("id %d channel %d", req->dev_id, req->channel);
30867 + dev = kmalloc(sizeof(struct rfcomm_dev), GFP_KERNEL);
30870 + memset(dev, 0, sizeof(struct rfcomm_dev));
30872 + write_lock_bh(&rfcomm_dev_lock);
30874 + if (req->dev_id < 0) {
30877 + list_for_each(p, &rfcomm_dev_list) {
30878 + if (list_entry(p, struct rfcomm_dev, list)->id != dev->id)
30885 + dev->id = req->dev_id;
30887 + list_for_each(p, &rfcomm_dev_list) {
30888 + struct rfcomm_dev *entry = list_entry(p, struct rfcomm_dev, list);
30890 + if (entry->id == dev->id) {
30891 + err = -EADDRINUSE;
30895 + if (entry->id > dev->id - 1)
30902 + if ((dev->id < 0) || (dev->id > RFCOMM_MAX_DEV - 1)) {
30907 + sprintf(dev->name, "rfcomm%d", dev->id);
30909 + list_add(&dev->list, head);
30910 + atomic_set(&dev->refcnt, 1);
30912 + bacpy(&dev->src, &req->src);
30913 + bacpy(&dev->dst, &req->dst);
30914 + dev->channel = req->channel;
30916 + dev->flags = req->flags &
30917 + ((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
30919 + init_waitqueue_head(&dev->wait);
30920 + tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev);
30922 + rfcomm_dlc_lock(dlc);
30923 + dlc->data_ready = rfcomm_dev_data_ready;
30924 + dlc->state_change = rfcomm_dev_state_change;
30925 + dlc->modem_status = rfcomm_dev_modem_status;
30927 + dlc->owner = dev;
30929 + rfcomm_dlc_unlock(dlc);
30931 + MOD_INC_USE_COUNT;
30934 + write_unlock_bh(&rfcomm_dev_lock);
30943 +static void rfcomm_dev_del(struct rfcomm_dev *dev)
30945 + BT_DBG("dev %p", dev);
30947 + write_lock_bh(&rfcomm_dev_lock);
30948 + list_del_init(&dev->list);
30949 + write_unlock_bh(&rfcomm_dev_lock);
30951 + rfcomm_dev_put(dev);
30954 +/* ---- Send buffer ---- */
30956 +static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc)
30958 + /* We can't let it be zero, because we don't get a callback
30959 + when tx_credits becomes nonzero, hence we'd never wake up */
30960 + return dlc->mtu * (dlc->tx_credits?:1);
30963 +static void rfcomm_wfree(struct sk_buff *skb)
30965 + struct rfcomm_dev *dev = (void *) skb->sk;
30966 + atomic_sub(skb->truesize, &dev->wmem_alloc);
30967 + if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags))
30968 + tasklet_schedule(&dev->wakeup_task);
30969 + rfcomm_dev_put(dev);
30972 +static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
30974 + rfcomm_dev_hold(dev);
30975 + atomic_add(skb->truesize, &dev->wmem_alloc);
30976 + skb->sk = (void *) dev;
30977 + skb->destructor = rfcomm_wfree;
30980 +static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, int force, int priority)
30982 + if (force || atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) {
30983 + struct sk_buff *skb = alloc_skb(size, priority);
30985 + rfcomm_set_owner_w(skb, dev);
30992 +/* ---- Device IOCTLs ---- */
30994 +#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
30996 +static int rfcomm_create_dev(struct sock *sk, unsigned long arg)
30998 + struct rfcomm_dev_req req;
30999 + struct rfcomm_dlc *dlc;
31002 + if (copy_from_user(&req, (void *) arg, sizeof(req)))
31005 + BT_DBG("sk %p dev_id %id flags 0x%x", sk, req.dev_id, req.flags);
31007 + if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
31010 + if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
31011 + /* Socket must be connected */
31012 + if (sk->state != BT_CONNECTED)
31015 + dlc = rfcomm_pi(sk)->dlc;
31016 + rfcomm_dlc_hold(dlc);
31018 + dlc = rfcomm_dlc_alloc(GFP_KERNEL);
31023 + id = rfcomm_dev_add(&req, dlc);
31025 + rfcomm_dlc_put(dlc);
31029 + if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
31030 + /* DLC is now used by device.
31031 + * Socket must be disconnected */
31032 + sk->state = BT_CLOSED;
31038 +static int rfcomm_release_dev(unsigned long arg)
31040 + struct rfcomm_dev_req req;
31041 + struct rfcomm_dev *dev;
31043 + if (copy_from_user(&req, (void *) arg, sizeof(req)))
31046 + BT_DBG("dev_id %id flags 0x%x", req.dev_id, req.flags);
31048 + if (!(dev = rfcomm_dev_get(req.dev_id)))
31051 + if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) {
31052 + rfcomm_dev_put(dev);
31056 + if (req.flags & (1 << RFCOMM_HANGUP_NOW))
31057 + rfcomm_dlc_close(dev->dlc, 0);
31059 + rfcomm_dev_del(dev);
31060 + rfcomm_dev_put(dev);
31064 +static int rfcomm_get_dev_list(unsigned long arg)
31066 + struct rfcomm_dev_list_req *dl;
31067 + struct rfcomm_dev_info *di;
31068 + struct list_head *p;
31069 + int n = 0, size, err;
31074 + if (get_user(dev_num, (u16 *) arg))
31077 + if (!dev_num || dev_num > (PAGE_SIZE * 4) / sizeof(*di))
31080 + size = sizeof(*dl) + dev_num * sizeof(*di);
31082 + if (!(dl = kmalloc(size, GFP_KERNEL)))
31085 + di = dl->dev_info;
31087 + read_lock_bh(&rfcomm_dev_lock);
31089 + list_for_each(p, &rfcomm_dev_list) {
31090 + struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list);
31091 + (di + n)->id = dev->id;
31092 + (di + n)->flags = dev->flags;
31093 + (di + n)->state = dev->dlc->state;
31094 + (di + n)->channel = dev->channel;
31095 + bacpy(&(di + n)->src, &dev->src);
31096 + bacpy(&(di + n)->dst, &dev->dst);
31097 + if (++n >= dev_num)
31101 + read_unlock_bh(&rfcomm_dev_lock);
31104 + size = sizeof(*dl) + n * sizeof(*di);
31106 + err = copy_to_user((void *) arg, dl, size);
31109 + return err ? -EFAULT : 0;
31112 +static int rfcomm_get_dev_info(unsigned long arg)
31114 + struct rfcomm_dev *dev;
31115 + struct rfcomm_dev_info di;
31120 + if (copy_from_user(&di, (void *)arg, sizeof(di)))
31123 + if (!(dev = rfcomm_dev_get(di.id)))
31126 + di.flags = dev->flags;
31127 + di.channel = dev->channel;
31128 + di.state = dev->dlc->state;
31129 + bacpy(&di.src, &dev->src);
31130 + bacpy(&di.dst, &dev->dst);
31132 + if (copy_to_user((void *)arg, &di, sizeof(di)))
31135 + rfcomm_dev_put(dev);
31139 +int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
31141 + BT_DBG("cmd %d arg %ld", cmd, arg);
31144 + case RFCOMMCREATEDEV:
31145 + return rfcomm_create_dev(sk, arg);
31147 + case RFCOMMRELEASEDEV:
31148 + return rfcomm_release_dev(arg);
31150 + case RFCOMMGETDEVLIST:
31151 + return rfcomm_get_dev_list(arg);
31153 + case RFCOMMGETDEVINFO:
31154 + return rfcomm_get_dev_info(arg);
31160 +/* ---- DLC callbacks ---- */
31161 +static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
31163 + struct rfcomm_dev *dev = dlc->owner;
31164 + struct tty_struct *tty;
31166 + if (!dev || !(tty = dev->tty)) {
31171 + BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len);
31173 + if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
31175 + for (i = 0; i < skb->len; i++) {
31176 + if (tty->flip.count >= TTY_FLIPBUF_SIZE)
31177 + tty_flip_buffer_push(tty);
31179 + tty_insert_flip_char(tty, skb->data[i], 0);
31181 + tty_flip_buffer_push(tty);
31183 + tty->ldisc.receive_buf(tty, skb->data, NULL, skb->len);
31188 +static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
31190 + struct rfcomm_dev *dev = dlc->owner;
31194 + BT_DBG("dlc %p dev %p err %d", dlc, dev, err);
31197 + wake_up_interruptible(&dev->wait);
31199 + if (dlc->state == BT_CLOSED) {
31201 + if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
31202 + rfcomm_dev_hold(dev);
31203 + rfcomm_dev_del(dev);
31205 + /* We have to drop DLC lock here, otherwise
31206 + rfcomm_dev_put() will dead lock if it's
31207 + the last reference. */
31208 + rfcomm_dlc_unlock(dlc);
31209 + rfcomm_dev_put(dev);
31210 + rfcomm_dlc_lock(dlc);
31213 + tty_hangup(dev->tty);
31217 +static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
31219 + struct rfcomm_dev *dev = dlc->owner;
31223 + BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig);
31225 + dev->modem_status =
31226 + ((v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0) |
31227 + ((v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0) |
31228 + ((v24_sig & RFCOMM_V24_IC) ? TIOCM_RI : 0) |
31229 + ((v24_sig & RFCOMM_V24_DV) ? TIOCM_CD : 0);
31232 +/* ---- TTY functions ---- */
31233 +static void rfcomm_tty_wakeup(unsigned long arg)
31235 + struct rfcomm_dev *dev = (void *) arg;
31236 + struct tty_struct *tty = dev->tty;
31240 + BT_DBG("dev %p tty %p", dev, tty);
31242 + if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
31243 + (tty->ldisc.write_wakeup)(tty);
31245 + wake_up_interruptible(&tty->write_wait);
31246 +#ifdef SERIAL_HAVE_POLL_WAIT
31247 + wake_up_interruptible(&tty->poll_wait);
31251 +static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
31253 + DECLARE_WAITQUEUE(wait, current);
31254 + struct rfcomm_dev *dev;
31255 + struct rfcomm_dlc *dlc;
31258 + id = MINOR(tty->device) - tty->driver.minor_start;
31260 + BT_DBG("tty %p id %d", tty, id);
31262 + /* We don't leak this refcount. For reasons which are not entirely
31263 + clear, the TTY layer will call our ->close() method even if the
31264 + open fails. We decrease the refcount there, and decreasing it
31265 + here too would cause breakage. */
31266 + dev = rfcomm_dev_get(id);
31270 + BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst), dev->channel, dev->opened);
31272 + if (dev->opened++ != 0)
31277 + /* Attach TTY and open DLC */
31279 + rfcomm_dlc_lock(dlc);
31280 + tty->driver_data = dev;
31282 + rfcomm_dlc_unlock(dlc);
31283 + set_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
31285 + err = rfcomm_dlc_open(dlc, &dev->src, &dev->dst, dev->channel);
31289 + /* Wait for DLC to connect */
31290 + add_wait_queue(&dev->wait, &wait);
31292 + set_current_state(TASK_INTERRUPTIBLE);
31294 + if (dlc->state == BT_CLOSED) {
31299 + if (dlc->state == BT_CONNECTED)
31302 + if (signal_pending(current)) {
31309 + set_current_state(TASK_RUNNING);
31310 + remove_wait_queue(&dev->wait, &wait);
31315 +static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
31317 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
31321 + BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, dev->opened);
31323 + if (--dev->opened == 0) {
31324 + /* Close DLC and dettach TTY */
31325 + rfcomm_dlc_close(dev->dlc, 0);
31327 + clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
31328 + tasklet_kill(&dev->wakeup_task);
31330 + rfcomm_dlc_lock(dev->dlc);
31331 + tty->driver_data = NULL;
31333 + rfcomm_dlc_unlock(dev->dlc);
31336 + rfcomm_dev_put(dev);
31339 +static int rfcomm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
31341 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
31342 + struct rfcomm_dlc *dlc = dev->dlc;
31343 + struct sk_buff *skb;
31344 + int err = 0, sent = 0, size;
31346 + BT_DBG("tty %p from_user %d count %d", tty, from_user, count);
31349 + size = min_t(uint, count, dlc->mtu);
31352 + skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, 0, GFP_KERNEL);
31354 + skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, 0, GFP_ATOMIC);
31359 + skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
31362 + copy_from_user(skb_put(skb, size), buf + sent, size);
31364 + memcpy(skb_put(skb, size), buf + sent, size);
31366 + if ((err = rfcomm_dlc_send(dlc, skb)) < 0) {
31375 + return sent ? sent : err;
31378 +static void rfcomm_tty_put_char(struct tty_struct *tty, unsigned char ch)
31380 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
31381 + struct rfcomm_dlc *dlc = dev->dlc;
31382 + struct sk_buff *skb;
31384 + BT_DBG("tty %p char %x", tty, ch);
31386 + skb = rfcomm_wmalloc(dev, 1 + RFCOMM_SKB_RESERVE, 1, GFP_ATOMIC);
31391 + skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
31393 + *(char *)skb_put(skb, 1) = ch;
31395 + if ((rfcomm_dlc_send(dlc, skb)) < 0)
31399 +static int rfcomm_tty_write_room(struct tty_struct *tty)
31401 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
31404 + BT_DBG("tty %p", tty);
31406 + room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc);
31413 +static int rfcomm_tty_set_modem_status(uint cmd, struct rfcomm_dlc *dlc, uint status)
31415 + u8 v24_sig, mask;
31417 + BT_DBG("dlc %p cmd 0x%02x", dlc, cmd);
31419 + if (cmd == TIOCMSET)
31422 + rfcomm_dlc_get_modem_status(dlc, &v24_sig);
31424 + mask = ((status & TIOCM_DSR) ? RFCOMM_V24_RTC : 0) |
31425 + ((status & TIOCM_DTR) ? RFCOMM_V24_RTC : 0) |
31426 + ((status & TIOCM_RTS) ? RFCOMM_V24_RTR : 0) |
31427 + ((status & TIOCM_CTS) ? RFCOMM_V24_RTR : 0) |
31428 + ((status & TIOCM_RI) ? RFCOMM_V24_IC : 0) |
31429 + ((status & TIOCM_CD) ? RFCOMM_V24_DV : 0);
31431 + if (cmd == TIOCMBIC)
31432 + v24_sig &= ~mask;
31436 + rfcomm_dlc_set_modem_status(dlc, v24_sig);
31440 +static int rfcomm_tty_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg)
31442 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
31443 + struct rfcomm_dlc *dlc = dev->dlc;
31447 + BT_DBG("tty %p cmd 0x%02x", tty, cmd);
31451 + BT_DBG("TCGETS is not supported");
31452 + return -ENOIOCTLCMD;
31455 + BT_DBG("TCSETS is not supported");
31456 + return -ENOIOCTLCMD;
31459 + BT_DBG("TIOCMGET");
31461 + return put_user(dev->modem_status, (unsigned int *)arg);
31463 + case TIOCMSET: /* Turns on and off the lines as specified by the mask */
31464 + case TIOCMBIS: /* Turns on the lines as specified by the mask */
31465 + case TIOCMBIC: /* Turns off the lines as specified by the mask */
31466 + if ((err = get_user(status, (unsigned int *)arg)))
31468 + return rfcomm_tty_set_modem_status(cmd, dlc, status);
31471 + BT_DBG("TIOCMIWAIT");
31474 + case TIOCGICOUNT:
31475 + BT_DBG("TIOCGICOUNT");
31478 + case TIOCGSERIAL:
31479 + BT_ERR("TIOCGSERIAL is not supported");
31480 + return -ENOIOCTLCMD;
31482 + case TIOCSSERIAL:
31483 + BT_ERR("TIOCSSERIAL is not supported");
31484 + return -ENOIOCTLCMD;
31486 + case TIOCSERGSTRUCT:
31487 + BT_ERR("TIOCSERGSTRUCT is not supported");
31488 + return -ENOIOCTLCMD;
31490 + case TIOCSERGETLSR:
31491 + BT_ERR("TIOCSERGETLSR is not supported");
31492 + return -ENOIOCTLCMD;
31494 + case TIOCSERCONFIG:
31495 + BT_ERR("TIOCSERCONFIG is not supported");
31496 + return -ENOIOCTLCMD;
31499 + return -ENOIOCTLCMD; /* ioctls which we must ignore */
31503 + return -ENOIOCTLCMD;
31506 +#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
31508 +static void rfcomm_tty_set_termios(struct tty_struct *tty, struct termios *old)
31510 + BT_DBG("tty %p", tty);
31512 + if ((tty->termios->c_cflag == old->c_cflag) &&
31513 + (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old->c_iflag)))
31516 + /* handle turning off CRTSCTS */
31517 + if ((old->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) {
31518 + BT_DBG("turning off CRTSCTS");
31522 +static void rfcomm_tty_throttle(struct tty_struct *tty)
31524 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
31526 + BT_DBG("tty %p dev %p", tty, dev);
31528 + rfcomm_dlc_throttle(dev->dlc);
31531 +static void rfcomm_tty_unthrottle(struct tty_struct *tty)
31533 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
31535 + BT_DBG("tty %p dev %p", tty, dev);
31537 + rfcomm_dlc_unthrottle(dev->dlc);
31540 +static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty)
31542 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
31543 + struct rfcomm_dlc *dlc = dev->dlc;
31545 + BT_DBG("tty %p dev %p", tty, dev);
31547 + if (skb_queue_len(&dlc->tx_queue))
31553 +static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
31555 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
31559 + BT_DBG("tty %p dev %p", tty, dev);
31561 + skb_queue_purge(&dev->dlc->tx_queue);
31563 + if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
31564 + tty->ldisc.write_wakeup(tty);
31567 +static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
31569 + BT_DBG("tty %p ch %c", tty, ch);
31572 +static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
31574 + BT_DBG("tty %p timeout %d", tty, timeout);
31577 +static void rfcomm_tty_hangup(struct tty_struct *tty)
31579 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
31583 + BT_DBG("tty %p dev %p", tty, dev);
31585 + rfcomm_tty_flush_buffer(tty);
31587 + if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
31588 + rfcomm_dev_del(dev);
31591 +static int rfcomm_tty_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *unused)
31596 +/* ---- TTY structure ---- */
31597 +static int rfcomm_tty_refcount; /* If we manage several devices */
31599 +static struct tty_struct *rfcomm_tty_table[RFCOMM_TTY_PORTS];
31600 +static struct termios *rfcomm_tty_termios[RFCOMM_TTY_PORTS];
31601 +static struct termios *rfcomm_tty_termios_locked[RFCOMM_TTY_PORTS];
31603 +static struct tty_driver rfcomm_tty_driver = {
31604 + magic: TTY_DRIVER_MAGIC,
31605 + driver_name: "rfcomm",
31606 +#ifdef CONFIG_DEVFS_FS
31607 + name: "bluetooth/rfcomm/%d",
31611 + major: RFCOMM_TTY_MAJOR,
31612 + minor_start: RFCOMM_TTY_MINOR,
31613 + num: RFCOMM_TTY_PORTS,
31614 + type: TTY_DRIVER_TYPE_SERIAL,
31615 + subtype: SERIAL_TYPE_NORMAL,
31616 + flags: TTY_DRIVER_REAL_RAW,
31618 + refcount: &rfcomm_tty_refcount,
31619 + table: rfcomm_tty_table,
31620 + termios: rfcomm_tty_termios,
31621 + termios_locked: rfcomm_tty_termios_locked,
31623 + open: rfcomm_tty_open,
31624 + close: rfcomm_tty_close,
31625 + put_char: rfcomm_tty_put_char,
31626 + write: rfcomm_tty_write,
31627 + write_room: rfcomm_tty_write_room,
31628 + chars_in_buffer: rfcomm_tty_chars_in_buffer,
31629 + flush_buffer: rfcomm_tty_flush_buffer,
31630 + ioctl: rfcomm_tty_ioctl,
31631 + throttle: rfcomm_tty_throttle,
31632 + unthrottle: rfcomm_tty_unthrottle,
31633 + set_termios: rfcomm_tty_set_termios,
31634 + send_xchar: rfcomm_tty_send_xchar,
31637 + hangup: rfcomm_tty_hangup,
31638 + wait_until_sent: rfcomm_tty_wait_until_sent,
31639 + read_proc: rfcomm_tty_read_proc,
31642 +int rfcomm_init_ttys(void)
31646 + /* Initalize our global data */
31647 + for (i = 0; i < RFCOMM_TTY_PORTS; i++)
31648 + rfcomm_tty_table[i] = NULL;
31650 + /* Register the TTY driver */
31651 + rfcomm_tty_driver.init_termios = tty_std_termios;
31652 + rfcomm_tty_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
31653 + rfcomm_tty_driver.flags = TTY_DRIVER_REAL_RAW;
31655 + if (tty_register_driver(&rfcomm_tty_driver)) {
31656 + BT_ERR("Can't register RFCOMM TTY driver");
31663 +void rfcomm_cleanup_ttys(void)
31665 + tty_unregister_driver(&rfcomm_tty_driver);
31668 diff -urN linux-2.4.18/net/bluetooth/sco.c linux-2.4.18-mh15/net/bluetooth/sco.c
31669 --- linux-2.4.18/net/bluetooth/sco.c 1970-01-01 01:00:00.000000000 +0100
31670 +++ linux-2.4.18-mh15/net/bluetooth/sco.c 2004-08-01 16:26:23.000000000 +0200
31673 + BlueZ - Bluetooth protocol stack for Linux
31674 + Copyright (C) 2000-2001 Qualcomm Incorporated
31676 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
31678 + This program is free software; you can redistribute it and/or modify
31679 + it under the terms of the GNU General Public License version 2 as
31680 + published by the Free Software Foundation;
31682 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
31683 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31684 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
31685 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
31686 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
31687 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
31688 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
31689 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
31691 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
31692 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
31693 + SOFTWARE IS DISCLAIMED.
31697 + * BlueZ SCO sockets.
31699 + * $Id: sco.c,v 1.4 2002/07/22 20:32:54 maxk Exp $
31701 +#define VERSION "0.3"
31703 +#include <linux/config.h>
31704 +#include <linux/module.h>
31706 +#include <linux/types.h>
31707 +#include <linux/errno.h>
31708 +#include <linux/kernel.h>
31709 +#include <linux/major.h>
31710 +#include <linux/sched.h>
31711 +#include <linux/slab.h>
31712 +#include <linux/poll.h>
31713 +#include <linux/fcntl.h>
31714 +#include <linux/init.h>
31715 +#include <linux/skbuff.h>
31716 +#include <linux/interrupt.h>
31717 +#include <linux/socket.h>
31718 +#include <linux/skbuff.h>
31719 +#include <linux/proc_fs.h>
31720 +#include <linux/list.h>
31721 +#include <net/sock.h>
31723 +#include <asm/system.h>
31724 +#include <asm/uaccess.h>
31726 +#include <net/bluetooth/bluetooth.h>
31727 +#include <net/bluetooth/hci_core.h>
31728 +#include <net/bluetooth/sco.h>
31732 +#define BT_DBG( A... )
31735 +static struct proto_ops sco_sock_ops;
31737 +static struct bluez_sock_list sco_sk_list = {
31738 + lock: RW_LOCK_UNLOCKED
31741 +static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
31742 +static void sco_chan_del(struct sock *sk, int err);
31743 +static inline struct sock * sco_chan_get(struct sco_conn *conn);
31745 +static int sco_conn_del(struct hci_conn *conn, int err);
31747 +static void sco_sock_close(struct sock *sk);
31748 +static void sco_sock_kill(struct sock *sk);
31750 +/* ----- SCO timers ------ */
31751 +static void sco_sock_timeout(unsigned long arg)
31753 + struct sock *sk = (struct sock *) arg;
31755 + BT_DBG("sock %p state %d", sk, sk->state);
31757 + bh_lock_sock(sk);
31758 + sk->err = ETIMEDOUT;
31759 + sk->state_change(sk);
31760 + bh_unlock_sock(sk);
31762 + sco_sock_kill(sk);
31766 +static void sco_sock_set_timer(struct sock *sk, long timeout)
31768 + BT_DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
31770 + if (!mod_timer(&sk->timer, jiffies + timeout))
31774 +static void sco_sock_clear_timer(struct sock *sk)
31776 + BT_DBG("sock %p state %d", sk, sk->state);
31778 + if (timer_pending(&sk->timer) && del_timer(&sk->timer))
31782 +static void sco_sock_init_timer(struct sock *sk)
31784 + init_timer(&sk->timer);
31785 + sk->timer.function = sco_sock_timeout;
31786 + sk->timer.data = (unsigned long)sk;
31789 +/* -------- SCO connections --------- */
31790 +static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status)
31792 + struct hci_dev *hdev = hcon->hdev;
31793 + struct sco_conn *conn;
31795 + if ((conn = hcon->sco_data))
31801 + if (!(conn = kmalloc(sizeof(struct sco_conn), GFP_ATOMIC)))
31803 + memset(conn, 0, sizeof(struct sco_conn));
31805 + spin_lock_init(&conn->lock);
31807 + hcon->sco_data = conn;
31808 + conn->hcon = hcon;
31810 + conn->src = &hdev->bdaddr;
31811 + conn->dst = &hcon->dst;
31813 + if (hdev->sco_mtu > 0)
31814 + conn->mtu = hdev->sco_mtu;
31818 + BT_DBG("hcon %p conn %p", hcon, conn);
31820 + MOD_INC_USE_COUNT;
31824 +static int sco_conn_del(struct hci_conn *hcon, int err)
31826 + struct sco_conn *conn;
31829 + if (!(conn = hcon->sco_data))
31832 + BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
31834 + /* Kill socket */
31835 + if ((sk = sco_chan_get(conn))) {
31836 + bh_lock_sock(sk);
31837 + sco_sock_clear_timer(sk);
31838 + sco_chan_del(sk, err);
31839 + bh_unlock_sock(sk);
31840 + sco_sock_kill(sk);
31843 + hcon->sco_data = NULL;
31846 + MOD_DEC_USE_COUNT;
31850 +int sco_connect(struct sock *sk)
31852 + bdaddr_t *src = &bluez_pi(sk)->src;
31853 + bdaddr_t *dst = &bluez_pi(sk)->dst;
31854 + struct sco_conn *conn;
31855 + struct hci_conn *hcon;
31856 + struct hci_dev *hdev;
31859 + BT_DBG("%s -> %s", batostr(src), batostr(dst));
31861 + if (!(hdev = hci_get_route(dst, src)))
31862 + return -EHOSTUNREACH;
31864 + hci_dev_lock_bh(hdev);
31868 + hcon = hci_connect(hdev, SCO_LINK, dst);
31872 + conn = sco_conn_add(hcon, 0);
31874 + hci_conn_put(hcon);
31878 + /* Update source addr of the socket */
31879 + bacpy(src, conn->src);
31881 + err = sco_chan_add(conn, sk, NULL);
31885 + if (hcon->state == BT_CONNECTED) {
31886 + sco_sock_clear_timer(sk);
31887 + sk->state = BT_CONNECTED;
31889 + sk->state = BT_CONNECT;
31890 + sco_sock_set_timer(sk, sk->sndtimeo);
31893 + hci_dev_unlock_bh(hdev);
31894 + hci_dev_put(hdev);
31898 +static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
31900 + struct sco_conn *conn = sco_pi(sk)->conn;
31901 + struct sk_buff *skb;
31904 + /* Check outgoing MTU */
31905 + if (len > conn->mtu)
31908 + BT_DBG("sk %p len %d", sk, len);
31910 + count = MIN(conn->mtu, len);
31911 + if (!(skb = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err)))
31914 + if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
31919 + if ((err = hci_send_sco(conn->hcon, skb)) < 0)
31929 +static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
31931 + struct sock *sk = sco_chan_get(conn);
31936 + BT_DBG("sk %p len %d", sk, skb->len);
31938 + if (sk->state != BT_CONNECTED)
31941 + if (!sock_queue_rcv_skb(sk, skb))
31949 +/* -------- Socket interface ---------- */
31950 +static struct sock *__sco_get_sock_by_addr(bdaddr_t *ba)
31954 + for (sk = sco_sk_list.head; sk; sk = sk->next) {
31955 + if (!bacmp(&bluez_pi(sk)->src, ba))
31962 +/* Find socket listening on source bdaddr.
31963 + * Returns closest match.
31965 +static struct sock *sco_get_sock_listen(bdaddr_t *src)
31967 + struct sock *sk, *sk1 = NULL;
31969 + read_lock(&sco_sk_list.lock);
31971 + for (sk = sco_sk_list.head; sk; sk = sk->next) {
31972 + if (sk->state != BT_LISTEN)
31975 + /* Exact match. */
31976 + if (!bacmp(&bluez_pi(sk)->src, src))
31979 + /* Closest match */
31980 + if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
31984 + read_unlock(&sco_sk_list.lock);
31986 + return sk ? sk : sk1;
31989 +static void sco_sock_destruct(struct sock *sk)
31991 + BT_DBG("sk %p", sk);
31993 + skb_queue_purge(&sk->receive_queue);
31994 + skb_queue_purge(&sk->write_queue);
31996 + MOD_DEC_USE_COUNT;
31999 +static void sco_sock_cleanup_listen(struct sock *parent)
32003 + BT_DBG("parent %p", parent);
32005 + /* Close not yet accepted channels */
32006 + while ((sk = bluez_accept_dequeue(parent, NULL))) {
32007 + sco_sock_close(sk);
32008 + sco_sock_kill(sk);
32011 + parent->state = BT_CLOSED;
32012 + parent->zapped = 1;
32015 +/* Kill socket (only if zapped and orphan)
32016 + * Must be called on unlocked socket.
32018 +static void sco_sock_kill(struct sock *sk)
32020 + if (!sk->zapped || sk->socket)
32023 + BT_DBG("sk %p state %d", sk, sk->state);
32025 + /* Kill poor orphan */
32026 + bluez_sock_unlink(&sco_sk_list, sk);
32032 + * Must be called on unlocked socket.
32034 +static void sco_sock_close(struct sock *sk)
32036 + struct sco_conn *conn;
32038 + sco_sock_clear_timer(sk);
32042 + conn = sco_pi(sk)->conn;
32044 + BT_DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
32046 + switch (sk->state) {
32048 + sco_sock_cleanup_listen(sk);
32051 + case BT_CONNECTED:
32055 + sco_chan_del(sk, ECONNRESET);
32063 + release_sock(sk);
32066 +static void sco_sock_init(struct sock *sk, struct sock *parent)
32068 + BT_DBG("sk %p", sk);
32071 + sk->type = parent->type;
32074 +static struct sock *sco_sock_alloc(struct socket *sock, int proto, int prio)
32078 + if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
32081 + bluez_sock_init(sock, sk);
32085 + sk->destruct = sco_sock_destruct;
32086 + sk->sndtimeo = SCO_CONN_TIMEOUT;
32088 + sk->protocol = proto;
32089 + sk->state = BT_OPEN;
32091 + sco_sock_init_timer(sk);
32093 + bluez_sock_link(&sco_sk_list, sk);
32095 + MOD_INC_USE_COUNT;
32099 +static int sco_sock_create(struct socket *sock, int protocol)
32103 + BT_DBG("sock %p", sock);
32105 + sock->state = SS_UNCONNECTED;
32107 + if (sock->type != SOCK_SEQPACKET)
32108 + return -ESOCKTNOSUPPORT;
32110 + sock->ops = &sco_sock_ops;
32112 + if (!(sk = sco_sock_alloc(sock, protocol, GFP_KERNEL)))
32115 + sco_sock_init(sk, NULL);
32119 +static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
32121 + struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
32122 + struct sock *sk = sock->sk;
32123 + bdaddr_t *src = &sa->sco_bdaddr;
32126 + BT_DBG("sk %p %s", sk, batostr(&sa->sco_bdaddr));
32128 + if (!addr || addr->sa_family != AF_BLUETOOTH)
32133 + if (sk->state != BT_OPEN) {
32138 + write_lock_bh(&sco_sk_list.lock);
32140 + if (bacmp(src, BDADDR_ANY) && __sco_get_sock_by_addr(src)) {
32141 + err = -EADDRINUSE;
32143 + /* Save source address */
32144 + bacpy(&bluez_pi(sk)->src, &sa->sco_bdaddr);
32145 + sk->state = BT_BOUND;
32148 + write_unlock_bh(&sco_sk_list.lock);
32151 + release_sock(sk);
32156 +static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
32158 + struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
32159 + struct sock *sk = sock->sk;
32163 + BT_DBG("sk %p", sk);
32165 + if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_sco))
32168 + if (sk->state != BT_OPEN && sk->state != BT_BOUND)
32171 + if (sk->type != SOCK_SEQPACKET)
32176 + /* Set destination address and psm */
32177 + bacpy(&bluez_pi(sk)->dst, &sa->sco_bdaddr);
32179 + if ((err = sco_connect(sk)))
32182 + err = bluez_sock_wait_state(sk, BT_CONNECTED,
32183 + sock_sndtimeo(sk, flags & O_NONBLOCK));
32186 + release_sock(sk);
32190 +int sco_sock_listen(struct socket *sock, int backlog)
32192 + struct sock *sk = sock->sk;
32195 + BT_DBG("sk %p backlog %d", sk, backlog);
32199 + if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
32204 + sk->max_ack_backlog = backlog;
32205 + sk->ack_backlog = 0;
32206 + sk->state = BT_LISTEN;
32209 + release_sock(sk);
32213 +int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags)
32215 + DECLARE_WAITQUEUE(wait, current);
32216 + struct sock *sk = sock->sk, *ch;
32222 + if (sk->state != BT_LISTEN) {
32227 + timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
32229 + BT_DBG("sk %p timeo %ld", sk, timeo);
32231 + /* Wait for an incoming connection. (wake-one). */
32232 + add_wait_queue_exclusive(sk->sleep, &wait);
32233 + while (!(ch = bluez_accept_dequeue(sk, newsock))) {
32234 + set_current_state(TASK_INTERRUPTIBLE);
32240 + release_sock(sk);
32241 + timeo = schedule_timeout(timeo);
32244 + if (sk->state != BT_LISTEN) {
32249 + if (signal_pending(current)) {
32250 + err = sock_intr_errno(timeo);
32254 + set_current_state(TASK_RUNNING);
32255 + remove_wait_queue(sk->sleep, &wait);
32260 + newsock->state = SS_CONNECTED;
32262 + BT_DBG("new socket %p", ch);
32265 + release_sock(sk);
32269 +static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
32271 + struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
32272 + struct sock *sk = sock->sk;
32274 + BT_DBG("sock %p, sk %p", sock, sk);
32276 + addr->sa_family = AF_BLUETOOTH;
32277 + *len = sizeof(struct sockaddr_sco);
32280 + bacpy(&sa->sco_bdaddr, &bluez_pi(sk)->dst);
32282 + bacpy(&sa->sco_bdaddr, &bluez_pi(sk)->src);
32287 +static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
32289 + struct sock *sk = sock->sk;
32292 + BT_DBG("sock %p, sk %p", sock, sk);
32295 + return sock_error(sk);
32297 + if (msg->msg_flags & MSG_OOB)
32298 + return -EOPNOTSUPP;
32302 + if (sk->state == BT_CONNECTED)
32303 + err = sco_send_frame(sk, msg, len);
32307 + release_sock(sk);
32311 +int sco_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
32313 + struct sock *sk = sock->sk;
32316 + BT_DBG("sk %p", sk);
32320 + switch (optname) {
32322 + err = -ENOPROTOOPT;
32326 + release_sock(sk);
32330 +int sco_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
32332 + struct sock *sk = sock->sk;
32333 + struct sco_options opts;
32334 + struct sco_conninfo cinfo;
32335 + int len, err = 0;
32337 + BT_DBG("sk %p", sk);
32339 + if (get_user(len, optlen))
32344 + switch (optname) {
32345 + case SCO_OPTIONS:
32346 + if (sk->state != BT_CONNECTED) {
32351 + opts.mtu = sco_pi(sk)->conn->mtu;
32353 + BT_DBG("mtu %d", opts.mtu);
32355 + len = MIN(len, sizeof(opts));
32356 + if (copy_to_user(optval, (char *)&opts, len))
32361 + case SCO_CONNINFO:
32362 + if (sk->state != BT_CONNECTED) {
32367 + cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
32369 + len = MIN(len, sizeof(cinfo));
32370 + if (copy_to_user(optval, (char *)&cinfo, len))
32376 + err = -ENOPROTOOPT;
32380 + release_sock(sk);
32384 +static int sco_sock_release(struct socket *sock)
32386 + struct sock *sk = sock->sk;
32389 + BT_DBG("sock %p, sk %p", sock, sk);
32394 + sco_sock_close(sk);
32395 + if (sk->linger) {
32397 + err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
32398 + release_sock(sk);
32402 + sco_sock_kill(sk);
32406 +static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
32408 + BT_DBG("conn %p", conn);
32410 + sco_pi(sk)->conn = conn;
32414 + bluez_accept_enqueue(parent, sk);
32417 +static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
32421 + sco_conn_lock(conn);
32425 + __sco_chan_add(conn, sk, parent);
32427 + sco_conn_unlock(conn);
32431 +static inline struct sock * sco_chan_get(struct sco_conn *conn)
32433 + struct sock *sk = NULL;
32434 + sco_conn_lock(conn);
32436 + sco_conn_unlock(conn);
32440 +/* Delete channel.
32441 + * Must be called on the locked socket. */
32442 +static void sco_chan_del(struct sock *sk, int err)
32444 + struct sco_conn *conn;
32446 + conn = sco_pi(sk)->conn;
32448 + BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
32451 + sco_conn_lock(conn);
32453 + sco_pi(sk)->conn = NULL;
32454 + sco_conn_unlock(conn);
32455 + hci_conn_put(conn->hcon);
32458 + sk->state = BT_CLOSED;
32460 + sk->state_change(sk);
32465 +static void sco_conn_ready(struct sco_conn *conn)
32467 + struct sock *parent, *sk;
32469 + BT_DBG("conn %p", conn);
32471 + sco_conn_lock(conn);
32473 + if ((sk = conn->sk)) {
32474 + sco_sock_clear_timer(sk);
32475 + bh_lock_sock(sk);
32476 + sk->state = BT_CONNECTED;
32477 + sk->state_change(sk);
32478 + bh_unlock_sock(sk);
32480 + parent = sco_get_sock_listen(conn->src);
32484 + bh_lock_sock(parent);
32486 + sk = sco_sock_alloc(NULL, BTPROTO_SCO, GFP_ATOMIC);
32488 + bh_unlock_sock(parent);
32492 + sco_sock_init(sk, parent);
32494 + bacpy(&bluez_pi(sk)->src, conn->src);
32495 + bacpy(&bluez_pi(sk)->dst, conn->dst);
32497 + hci_conn_hold(conn->hcon);
32498 + __sco_chan_add(conn, sk, parent);
32500 + sk->state = BT_CONNECTED;
32502 + /* Wake up parent */
32503 + parent->data_ready(parent, 1);
32505 + bh_unlock_sock(parent);
32509 + sco_conn_unlock(conn);
32512 +/* ----- SCO interface with lower layer (HCI) ----- */
32513 +int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
32515 + BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
32517 + /* Always accept connection */
32518 + return HCI_LM_ACCEPT;
32521 +int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
32523 + BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
32525 + if (hcon->type != SCO_LINK)
32529 + struct sco_conn *conn;
32531 + conn = sco_conn_add(hcon, status);
32533 + sco_conn_ready(conn);
32535 + sco_conn_del(hcon, bterr(status));
32540 +int sco_disconn_ind(struct hci_conn *hcon, __u8 reason)
32542 + BT_DBG("hcon %p reason %d", hcon, reason);
32544 + if (hcon->type != SCO_LINK)
32547 + sco_conn_del(hcon, bterr(reason));
32551 +int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
32553 + struct sco_conn *conn = hcon->sco_data;
32558 + BT_DBG("conn %p len %d", conn, skb->len);
32561 + sco_recv_frame(conn, skb);
32570 +/* ----- Proc fs support ------ */
32571 +static int sco_sock_dump(char *buf, struct bluez_sock_list *list)
32573 + struct sco_pinfo *pi;
32577 + write_lock_bh(&list->lock);
32579 + for (sk = list->head; sk; sk = sk->next) {
32581 + ptr += sprintf(ptr, "%s %s %d\n",
32582 + batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
32586 + write_unlock_bh(&list->lock);
32588 + ptr += sprintf(ptr, "\n");
32590 + return ptr - buf;
32593 +static int sco_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
32598 + BT_DBG("count %d, offset %ld", count, offset);
32600 + ptr += sco_sock_dump(ptr, &sco_sk_list);
32603 + if (len <= count + offset)
32606 + *start = buf + offset;
32617 +static struct proto_ops sco_sock_ops = {
32618 + family: PF_BLUETOOTH,
32619 + release: sco_sock_release,
32620 + bind: sco_sock_bind,
32621 + connect: sco_sock_connect,
32622 + listen: sco_sock_listen,
32623 + accept: sco_sock_accept,
32624 + getname: sco_sock_getname,
32625 + sendmsg: sco_sock_sendmsg,
32626 + recvmsg: bluez_sock_recvmsg,
32627 + poll: bluez_sock_poll,
32628 + socketpair: sock_no_socketpair,
32629 + ioctl: sock_no_ioctl,
32630 + shutdown: sock_no_shutdown,
32631 + setsockopt: sco_sock_setsockopt,
32632 + getsockopt: sco_sock_getsockopt,
32633 + mmap: sock_no_mmap
32636 +static struct net_proto_family sco_sock_family_ops = {
32637 + family: PF_BLUETOOTH,
32638 + create: sco_sock_create
32641 +static struct hci_proto sco_hci_proto = {
32643 + id: HCI_PROTO_SCO,
32644 + connect_ind: sco_connect_ind,
32645 + connect_cfm: sco_connect_cfm,
32646 + disconn_ind: sco_disconn_ind,
32647 + recv_scodata: sco_recv_scodata,
32650 +int __init sco_init(void)
32654 + if ((err = bluez_sock_register(BTPROTO_SCO, &sco_sock_family_ops))) {
32655 + BT_ERR("Can't register SCO socket layer");
32659 + if ((err = hci_register_proto(&sco_hci_proto))) {
32660 + BT_ERR("Can't register SCO protocol");
32664 + create_proc_read_entry("bluetooth/sco", 0, 0, sco_read_proc, NULL);
32666 + BT_INFO("BlueZ SCO ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
32667 + BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
32671 +void sco_cleanup(void)
32675 + remove_proc_entry("bluetooth/sco", NULL);
32677 + /* Unregister socket, protocol and notifier */
32678 + if ((err = bluez_sock_unregister(BTPROTO_SCO)))
32679 + BT_ERR("Can't unregister SCO socket layer %d", err);
32681 + if ((err = hci_unregister_proto(&sco_hci_proto)))
32682 + BT_ERR("Can't unregister SCO protocol %d", err);
32685 +module_init(sco_init);
32686 +module_exit(sco_cleanup);
32688 +MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
32689 +MODULE_DESCRIPTION("BlueZ SCO ver " VERSION);
32690 +MODULE_LICENSE("GPL");
32691 diff -urN linux-2.4.18/net/bluetooth/syms.c linux-2.4.18-mh15/net/bluetooth/syms.c
32692 --- linux-2.4.18/net/bluetooth/syms.c 2001-09-07 18:28:38.000000000 +0200
32693 +++ linux-2.4.18-mh15/net/bluetooth/syms.c 2004-08-01 16:26:23.000000000 +0200
32698 - * $Id: syms.c,v 1.1 2001/07/12 19:31:24 maxk Exp $
32699 + * $Id: syms.c,v 1.1 2002/03/08 21:06:59 maxk Exp $
32702 #include <linux/config.h>
32703 @@ -39,25 +39,28 @@
32704 #include <linux/socket.h>
32706 #include <net/bluetooth/bluetooth.h>
32707 -#include <net/bluetooth/bluez.h>
32708 #include <net/bluetooth/hci_core.h>
32711 EXPORT_SYMBOL(hci_register_dev);
32712 EXPORT_SYMBOL(hci_unregister_dev);
32713 +EXPORT_SYMBOL(hci_suspend_dev);
32714 +EXPORT_SYMBOL(hci_resume_dev);
32716 EXPORT_SYMBOL(hci_register_proto);
32717 EXPORT_SYMBOL(hci_unregister_proto);
32718 -EXPORT_SYMBOL(hci_register_notifier);
32719 -EXPORT_SYMBOL(hci_unregister_notifier);
32721 +EXPORT_SYMBOL(hci_get_route);
32722 EXPORT_SYMBOL(hci_connect);
32723 -EXPORT_SYMBOL(hci_disconnect);
32724 EXPORT_SYMBOL(hci_dev_get);
32725 +EXPORT_SYMBOL(hci_conn_auth);
32726 +EXPORT_SYMBOL(hci_conn_encrypt);
32728 EXPORT_SYMBOL(hci_recv_frame);
32729 EXPORT_SYMBOL(hci_send_acl);
32730 EXPORT_SYMBOL(hci_send_sco);
32731 -EXPORT_SYMBOL(hci_send_raw);
32732 +EXPORT_SYMBOL(hci_send_cmd);
32733 +EXPORT_SYMBOL(hci_si_event);
32736 EXPORT_SYMBOL(bluez_dump);
32738 /* BlueZ sockets */
32739 EXPORT_SYMBOL(bluez_sock_register);
32740 EXPORT_SYMBOL(bluez_sock_unregister);
32741 +EXPORT_SYMBOL(bluez_sock_init);
32742 EXPORT_SYMBOL(bluez_sock_link);
32743 EXPORT_SYMBOL(bluez_sock_unlink);
32744 +EXPORT_SYMBOL(bluez_sock_recvmsg);
32745 +EXPORT_SYMBOL(bluez_sock_poll);
32746 +EXPORT_SYMBOL(bluez_accept_enqueue);
32747 +EXPORT_SYMBOL(bluez_accept_dequeue);
32748 +EXPORT_SYMBOL(bluez_sock_wait_state);
32749 diff -urN linux-2.4.18/net/netsyms.c linux-2.4.18-mh15/net/netsyms.c
32750 --- linux-2.4.18/net/netsyms.c 2002-02-25 20:38:14.000000000 +0100
32751 +++ linux-2.4.18-mh15/net/netsyms.c 2004-08-01 16:26:23.000000000 +0200
32752 @@ -159,6 +159,7 @@
32753 EXPORT_SYMBOL(put_cmsg);
32754 EXPORT_SYMBOL(sock_kmalloc);
32755 EXPORT_SYMBOL(sock_kfree_s);
32756 +EXPORT_SYMBOL(sockfd_lookup);
32758 #ifdef CONFIG_FILTER
32759 EXPORT_SYMBOL(sk_run_filter);