diff options
3 files changed, 8 insertions, 31398 deletions
diff --git a/packages/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bluetooth-2.4.18-mh11.patch b/packages/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bluetooth-2.4.18-mh11.patch deleted file mode 100644 index ff3582ab7b..0000000000 --- a/packages/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bluetooth-2.4.18-mh11.patch +++ /dev/null @@ -1,31393 +0,0 @@ - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - ---- linux/arch/alpha/config.in~bluetooth-2.4.18-mh11 2004-01-25 23:28:10.000000000 +0100 -+++ linux/arch/alpha/config.in 2004-01-25 23:37:39.000000000 +0100 -@@ -372,9 +372,7 @@ - source drivers/usb/Config.in - source drivers/input/Config.in - --if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -- source net/bluetooth/Config.in --fi -+source net/bluetooth/Config.in - - mainmenu_option next_comment - comment 'Kernel hacking' ---- linux/arch/arm/config.in~bluetooth-2.4.18-mh11 2004-01-25 23:28:31.000000000 +0100 -+++ linux/arch/arm/config.in 2004-01-25 23:37:39.000000000 +0100 -@@ -796,9 +796,7 @@ - - source drivers/usb/Config.in - --if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -- source net/bluetooth/Config.in --fi -+source net/bluetooth/Config.in - - mainmenu_option next_comment - comment 'Kernel hacking' ---- linux/arch/i386/config.in~bluetooth-2.4.18-mh11 2004-01-25 23:28:31.000000000 +0100 -+++ linux/arch/i386/config.in 2004-01-25 23:37:39.000000000 +0100 -@@ -415,9 +415,7 @@ - - source drivers/usb/Config.in - --if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -- source net/bluetooth/Config.in --fi -+source net/bluetooth/Config.in - - mainmenu_option next_comment - comment 'Kernel hacking' ---- linux/arch/ppc/config.in~bluetooth-2.4.18-mh11 2004-01-25 23:28:11.000000000 +0100 -+++ linux/arch/ppc/config.in 2004-01-25 23:37:39.000000000 +0100 -@@ -390,9 +390,7 @@ - - source drivers/usb/Config.in - --if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -- source net/bluetooth/Config.in --fi -+source net/bluetooth/Config.in - - mainmenu_option next_comment - comment 'Kernel hacking' ---- linux/arch/sparc/config.in~bluetooth-2.4.18-mh11 2004-01-25 23:28:11.000000000 +0100 -+++ linux/arch/sparc/config.in 2004-01-25 23:37:39.000000000 +0100 -@@ -252,9 +252,7 @@ - - source fs/Config.in - --if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -- source net/bluetooth/Config.in --fi -+source net/bluetooth/Config.in - - mainmenu_option next_comment - comment 'Watchdog' ---- linux/arch/sparc64/config.in~bluetooth-2.4.18-mh11 2004-01-25 23:28:11.000000000 +0100 -+++ linux/arch/sparc64/config.in 2004-01-25 23:37:39.000000000 +0100 -@@ -284,9 +284,7 @@ - - source drivers/usb/Config.in - --if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -- source net/bluetooth/Config.in --fi -+source net/bluetooth/Config.in - - mainmenu_option next_comment - comment 'Watchdog' ---- linux/arch/sparc64/kernel/ioctl32.c~bluetooth-2.4.18-mh11 2002-02-25 20:37:56.000000000 +0100 -+++ linux/arch/sparc64/kernel/ioctl32.c 2004-01-25 23:37:39.000000000 +0100 -@@ -92,6 +92,7 @@ - - #include <net/bluetooth/bluetooth.h> - #include <net/bluetooth/hci.h> -+#include <net/bluetooth/rfcomm.h> - - #include <linux/usb.h> - #include <linux/usbdevice_fs.h> -@@ -3822,6 +3823,15 @@ - return err; - } - -+/* Bluetooth ioctls */ -+#define HCIUARTSETPROTO _IOW('U', 200, int) -+#define HCIUARTGETPROTO _IOR('U', 201, int) -+ -+#define BNEPCONNADD _IOW('B', 200, int) -+#define BNEPCONNDEL _IOW('B', 201, int) -+#define BNEPGETCONNLIST _IOR('B', 210, int) -+#define BNEPGETCONNINFO _IOR('B', 211, int) -+ - struct mtd_oob_buf32 { - u32 start; - u32 length; -@@ -3878,6 +3888,11 @@ - return ((0 == ret) ? 0 : -EFAULT); - } - -+#define CMTPCONNADD _IOW('C', 200, int) -+#define CMTPCONNDEL _IOW('C', 201, int) -+#define CMTPGETCONNLIST _IOR('C', 210, int) -+#define CMTPGETCONNINFO _IOR('C', 211, int) -+ - struct ioctl_trans { - unsigned int cmd; - unsigned int handler; -@@ -4540,6 +4555,21 @@ - COMPATIBLE_IOCTL(HCISETSCAN) - COMPATIBLE_IOCTL(HCISETAUTH) - COMPATIBLE_IOCTL(HCIINQUIRY) -+COMPATIBLE_IOCTL(HCIUARTSETPROTO) -+COMPATIBLE_IOCTL(HCIUARTGETPROTO) -+COMPATIBLE_IOCTL(RFCOMMCREATEDEV) -+COMPATIBLE_IOCTL(RFCOMMRELEASEDEV) -+COMPATIBLE_IOCTL(RFCOMMGETDEVLIST) -+COMPATIBLE_IOCTL(RFCOMMGETDEVINFO) -+COMPATIBLE_IOCTL(RFCOMMSTEALDLC) -+COMPATIBLE_IOCTL(BNEPCONNADD) -+COMPATIBLE_IOCTL(BNEPCONNDEL) -+COMPATIBLE_IOCTL(BNEPGETCONNLIST) -+COMPATIBLE_IOCTL(BNEPGETCONNINFO) -+COMPATIBLE_IOCTL(CMTPCONNADD) -+COMPATIBLE_IOCTL(CMTPCONNDEL) -+COMPATIBLE_IOCTL(CMTPGETCONNLIST) -+COMPATIBLE_IOCTL(CMTPGETCONNINFO) - /* Misc. */ - COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */ - COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */ ---- linux/CREDITS~bluetooth-2.4.18-mh11 2004-01-25 23:28:29.000000000 +0100 -+++ linux/CREDITS 2004-01-25 23:37:39.000000000 +0100 -@@ -1317,6 +1317,15 @@ - S: Provo, Utah 84606-5607 - S: USA - -+N: Marcel Holtmann -+E: marcel@holtmann.org -+W: http://www.holtmann.org -+D: Maintainer of the Linux Bluetooth Subsystem -+D: Author and maintainer of the various Bluetooth HCI drivers -+D: Author and maintainer of the CAPI message transport protocol driver -+D: Various other Bluetooth related patches, cleanups and fixes -+S: Germany -+ - N: Rob W. W. Hooft - E: hooft@EMBL-Heidelberg.DE - D: Shared libs for graphics-tools and for the f2c compiler -@@ -2555,6 +2564,7 @@ - N: Aristeu Sergio Rozanski Filho - E: aris@conectiva.com.br - D: Support for EtherExpress 10 ISA (i82595) in eepro driver -+D: User level driver support for input - S: Conectiva S.A. - S: R. Tocantins, 89 - Cristo Rei - S: 80050-430 - Curitiba - Paraná ---- linux/Documentation/Configure.help~bluetooth-2.4.18-mh11 2004-01-25 23:28:31.000000000 +0100 -+++ linux/Documentation/Configure.help 2004-01-25 23:37:39.000000000 +0100 -@@ -2847,14 +2847,6 @@ - - If unsure, say N. - --HCI EMU (virtual device) driver --CONFIG_BLUEZ_HCIEMU -- Bluetooth Virtual HCI device driver. -- This driver is required if you want to use HCI Emulation software. -- -- Say Y here to compile support for Virtual HCI devices into the -- kernel or say M to compile it as module (hci_usb.o). -- - # Choice: alphatype - Alpha system type - CONFIG_ALPHA_GENERIC -@@ -11067,6 +11059,12 @@ - - If unsure, say N. - -+Hotplug firmware loading support (EXPERIMENTAL) -+CONFIG_FW_LOADER -+ This option is provided for the case where no in-kernel-tree modules require -+ hotplug firmware loading support, but a module built outside the kernel tree -+ does. -+ - Use PCI shared memory for NIC registers - CONFIG_TULIP_MMIO - Use PCI shared memory for the NIC registers, rather than going through -@@ -12967,6 +12965,15 @@ - accessible under char device 13:64+ - /dev/input/eventX in a generic - way. This is the future ... - -+CONFIG_INPUT_UINPUT -+ Say Y here if you want to support user level drivers for input -+ subsystem accessible under char device 10:223 - /dev/input/uinput. -+ -+ This driver is also available as a module ( = code which can be -+ inserted in and removed from the running kernel whenever you want). -+ The module will be called uinput.o. If you want to compile it as a -+ module, say M here and read <file:Documentation/modules.txt>. -+ - USB Scanner support - CONFIG_USB_SCANNER - Say Y here if you want to connect a USB scanner to your computer's -@@ -19986,11 +19993,15 @@ - Bluetooth can be found at <http://www.bluetooth.com/>. - - Linux Bluetooth subsystem consist of several layers: -- HCI Core (device and connection manager, scheduler) -+ BlueZ Core (HCI device and connection manager, scheduler) - HCI Device drivers (interface to the hardware) - L2CAP Module (L2CAP protocol) -+ SCO Module (SCO links) -+ RFCOMM Module (RFCOMM protocol) -+ BNEP Module (BNEP protocol) -+ CMTP Module (CMTP protocol) - -- Say Y here to enable Linux Bluetooth support and to build HCI Core -+ Say Y here to enable Linux Bluetooth support and to build BlueZ Core - layer. - - To use Linux Bluetooth subsystem, you will need several user-space -@@ -19998,7 +20009,7 @@ - Bluetooth kernel modules are provided in the BlueZ package. - For more information, see <http://bluez.sourceforge.net/>. - -- If you want to compile HCI Core as module (hci.o) say M here. -+ If you want to compile BlueZ Core as module (bluez.o) say M here. - - L2CAP protocol support - CONFIG_BLUEZ_L2CAP -@@ -20009,15 +20020,91 @@ - Say Y here to compile L2CAP support into the kernel or say M to - compile it as module (l2cap.o). - -+SCO links support -+CONFIG_BLUEZ_SCO -+ SCO link provides voice transport over Bluetooth. SCO support is -+ required for voice applications like Headset and Audio. -+ -+ Say Y here to compile SCO support into the kernel or say M to -+ compile it as module (sco.o). -+ -+RFCOMM protocol support -+CONFIG_BLUEZ_RFCOMM -+ RFCOMM provides connection oriented stream transport. RFCOMM -+ support is required for Dialup Networking, OBEX and other Bluetooth -+ applications. -+ -+ Say Y here to compile RFCOMM support into the kernel or say M to -+ compile it as module (rfcomm.o). -+ -+RFCOMM TTY emulation support -+CONFIG_BLUEZ_RFCOMM_TTY -+ This option enables TTY emulation support for RFCOMM channels. -+ -+BNEP protocol support -+CONFIG_BLUEZ_BNEP -+ BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet -+ emulation layer on top of Bluetooth. BNEP is required for Bluetooth -+ PAN (Personal Area Network). -+ -+ To use BNEP, you will need user-space utilities provided in the -+ BlueZ-PAN package. -+ For more information, see <http://bluez.sourceforge.net>. -+ -+ Say Y here to compile BNEP support into the kernel or say M to -+ compile it as module (bnep.o). -+ -+CMTP protocol support -+CONFIG_BLUEZ_CMTP -+ CMTP (CAPI Message Transport Protocol) is a transport layer -+ for CAPI messages. CMTP is required for the Bluetooth Common -+ ISDN Access Profile. -+ -+ Say Y here to compile CMTP support into the kernel or say M to -+ compile it as module (cmtp.o). -+ -+BNEP multicast filter support -+CONFIG_BLUEZ_BNEP_MC_FILTER -+ This option enables the multicast filter support for BNEP. -+ -+BNEP protocol filter support -+CONFIG_BLUEZ_BNEP_PROTO_FILTER -+ This option enables the protocol filter support for BNEP. -+ - HCI UART driver - CONFIG_BLUEZ_HCIUART - Bluetooth HCI UART driver. - This driver is required if you want to use Bluetooth devices with -- serial port interface. -+ serial port interface. You will also need this driver if you have -+ UART based Bluetooth PCMCIA and CF devices like Xircom Credit Card -+ adapter and BrainBoxes Bluetooth PC Card. - - Say Y here to compile support for Bluetooth UART devices into the - kernel or say M to compile it as module (hci_uart.o). - -+HCI UART (H4) protocol support -+CONFIG_BLUEZ_HCIUART_H4 -+ UART (H4) is serial protocol for communication between Bluetooth -+ device and host. This protocol is required for most Bluetooth devices -+ with UART interface, including PCMCIA and CF cards. -+ -+ Say Y here to compile support for HCI UART (H4) protocol. -+ -+HCI BCSP protocol support -+CONFIG_BLUEZ_HCIUART_BCSP -+ BCSP (BlueCore Serial Protocol) is serial protocol for communication -+ between Bluetooth device and host. This protocol is required for non -+ USB Bluetooth devices based on CSR BlueCore chip, including PCMCIA and -+ CF cards. -+ -+ Say Y here to compile support for HCI BCSP protocol. -+ -+HCI BCSP transmit CRC with every BCSP packet -+CONFIG_BLUEZ_HCIUART_BCSP_TXCRC -+ If you say Y here, a 16-bit CRC checksum will be transmitted along with -+ every BCSP (BlueCore Serial Protocol) packet sent to the Bluetooth chip. -+ This increases reliability, but slightly reduces efficiency. -+ - HCI USB driver - CONFIG_BLUEZ_HCIUSB - Bluetooth HCI USB driver. -@@ -20027,7 +20114,16 @@ - Say Y here to compile support for Bluetooth USB devices into the - kernel or say M to compile it as module (hci_usb.o). - --HCI VHCI virtual HCI device driver -+HCI USB SCO (voice) support -+CONFIG_BLUEZ_HCIUSB_SCO -+ This option enables the SCO support in the HCI USB driver. You need this -+ to transmit voice data with your Bluetooth USB device. And your device -+ must also support sending SCO data over the HCI layer, because some of -+ them sends the SCO data to an internal PCM adapter. -+ -+ Say Y here to compile support for HCI SCO data. -+ -+HCI VHCI Virtual HCI device driver - CONFIG_BLUEZ_HCIVHCI - Bluetooth Virtual HCI device driver. - This driver is required if you want to use HCI Emulation software. -@@ -20035,6 +20131,66 @@ - Say Y here to compile support for virtual HCI devices into the - kernel or say M to compile it as module (hci_vhci.o). - -+HCI BFUSB device driver -+CONFIG_BLUEZ_HCIBFUSB -+ Bluetooth HCI BlueFRITZ! USB driver. -+ This driver provides support for Bluetooth USB devices with AVM -+ interface: -+ AVM BlueFRITZ! USB -+ -+ Say Y here to compile support for HCI BFUSB devices into the -+ kernel or say M to compile it as module (bfusb.o). -+ -+HCI DTL1 (PC Card) device driver -+CONFIG_BLUEZ_HCIDTL1 -+ Bluetooth HCI DTL1 (PC Card) driver. -+ This driver provides support for Bluetooth PCMCIA devices with -+ Nokia DTL1 interface: -+ Nokia Bluetooth Card -+ Socket Bluetooth CF Card -+ -+ Say Y here to compile support for HCI DTL1 devices into the -+ kernel or say M to compile it as module (dtl1_cs.o). -+ -+HCI BT3C (PC Card) device driver -+CONFIG_BLUEZ_HCIBT3C -+ Bluetooth HCI BT3C (PC Card) driver. -+ This driver provides support for Bluetooth PCMCIA devices with -+ 3Com BT3C interface: -+ 3Com Bluetooth Card (3CRWB6096) -+ HP Bluetooth Card -+ -+ The HCI BT3C driver uses external firmware loader program provided in -+ the BlueFW package. For more information, see <http://bluez.sf.net>. -+ -+ Say Y here to compile support for HCI BT3C devices into the -+ kernel or say M to compile it as module (bt3c_cs.o). -+ -+HCI BlueCard (PC Card) device driver -+CONFIG_BLUEZ_HCIBLUECARD -+ Bluetooth HCI BlueCard (PC Card) driver. -+ This driver provides support for Bluetooth PCMCIA devices with -+ Anycom BlueCard interface: -+ Anycom Bluetooth PC Card -+ Anycom Bluetooth CF Card -+ -+ Say Y here to compile support for HCI BlueCard devices into the -+ kernel or say M to compile it as module (bluecard_cs.o). -+ -+HCI UART (PC Card) device driver -+CONFIG_BLUEZ_HCIBTUART -+ Bluetooth HCI UART (PC Card) driver. -+ This driver provides support for Bluetooth PCMCIA devices with -+ an UART interface: -+ Xircom CreditCard Bluetooth Adapter -+ Xircom RealPort2 Bluetooth Adapter -+ Sphinx PICO Card -+ H-Soft blue+Card -+ Cyber-blue Compact Flash Card -+ -+ Say Y here to compile support for HCI UART devices into the -+ kernel or say M to compile it as module (btuart_cs.o). -+ - # The following options are for Linux when running on the Hitachi - # SuperH family of RISC microprocessors. - ---- linux/Documentation/devices.txt~bluetooth-2.4.18-mh11 2001-11-07 23:46:01.000000000 +0100 -+++ linux/Documentation/devices.txt 2004-01-25 23:37:39.000000000 +0100 -@@ -419,6 +419,7 @@ - 220 = /dev/mptctl Message passing technology (MPT) control - 221 = /dev/mvista/hssdsi Montavista PICMG hot swap system driver - 222 = /dev/mvista/hasi Montavista PICMG high availability -+ 223 = /dev/input/uinput User level driver support for input - 240-255 Reserved for local use - - 11 char Raw keyboard device ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/firmware_class/firmware_sample_driver.c 2004-01-25 23:37:39.000000000 +0100 -@@ -0,0 +1,121 @@ -+/* -+ * firmware_sample_driver.c - -+ * -+ * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org> -+ * -+ * Sample code on how to use request_firmware() from drivers. -+ * -+ * Note that register_firmware() is currently useless. -+ * -+ */ -+ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/string.h> -+ -+#include "linux/firmware.h" -+ -+#define WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE -+#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE -+char __init inkernel_firmware[] = "let's say that this is firmware\n"; -+#endif -+ -+static char ghost_device[] = "ghost0"; -+ -+static void sample_firmware_load(char *firmware, int size) -+{ -+ u8 buf[size+1]; -+ memcpy(buf, firmware, size); -+ buf[size] = '\0'; -+ printk("firmware_sample_driver: firmware: %s\n", buf); -+} -+ -+static void sample_probe_default(void) -+{ -+ /* uses the default method to get the firmware */ -+ const struct firmware *fw_entry; -+ printk("firmware_sample_driver: a ghost device got inserted :)\n"); -+ -+ if(request_firmware(&fw_entry, "sample_driver_fw", ghost_device)!=0) -+ { -+ printk(KERN_ERR -+ "firmware_sample_driver: Firmware not available\n"); -+ return; -+ } -+ -+ sample_firmware_load(fw_entry->data, fw_entry->size); -+ -+ release_firmware(fw_entry); -+ -+ /* finish setting up the device */ -+} -+static void sample_probe_specific(void) -+{ -+ /* Uses some specific hotplug support to get the firmware from -+ * userspace directly into the hardware, or via some sysfs file */ -+ -+ /* NOTE: This currently doesn't work */ -+ -+ printk("firmware_sample_driver: a ghost device got inserted :)\n"); -+ -+ if(request_firmware(NULL, "sample_driver_fw", ghost_device)!=0) -+ { -+ printk(KERN_ERR -+ "firmware_sample_driver: Firmware load failed\n"); -+ return; -+ } -+ -+ /* request_firmware blocks until userspace finished, so at -+ * this point the firmware should be already in the device */ -+ -+ /* finish setting up the device */ -+} -+static void sample_probe_async_cont(const struct firmware *fw, void *context) -+{ -+ if(!fw){ -+ printk(KERN_ERR -+ "firmware_sample_driver: firmware load failed\n"); -+ return; -+ } -+ -+ printk("firmware_sample_driver: device pointer \"%s\"\n", -+ (char *)context); -+ sample_firmware_load(fw->data, fw->size); -+} -+static void sample_probe_async(void) -+{ -+ /* Let's say that I can't sleep */ -+ int error; -+ error = request_firmware_nowait (THIS_MODULE, -+ "sample_driver_fw", ghost_device, -+ "my device pointer", -+ sample_probe_async_cont); -+ if(error){ -+ printk(KERN_ERR -+ "firmware_sample_driver:" -+ " request_firmware_nowait failed\n"); -+ } -+} -+ -+static int sample_init(void) -+{ -+#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE -+ register_firmware("sample_driver_fw", inkernel_firmware, -+ sizeof(inkernel_firmware)); -+#endif -+ /* since there is no real hardware insertion I just call the -+ * sample probe functions here */ -+ sample_probe_specific(); -+ sample_probe_default(); -+ sample_probe_async(); -+ return 0; -+} -+static void __exit sample_exit(void) -+{ -+} -+ -+module_init (sample_init); -+module_exit (sample_exit); -+ -+MODULE_LICENSE("GPL"); ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/firmware_class/hotplug-script 2004-01-25 23:37:39.000000000 +0100 -@@ -0,0 +1,16 @@ -+#!/bin/sh -+ -+# Simple hotplug script sample: -+# -+# Both $DEVPATH and $FIRMWARE are already provided in the environment. -+ -+HOTPLUG_FW_DIR=/usr/lib/hotplug/firmware/ -+ -+echo 1 > /sysfs/$DEVPATH/loading -+cat $HOTPLUG_FW_DIR/$FIRMWARE > /sysfs/$DEVPATH/data -+echo 0 > /sysfs/$DEVPATH/loading -+ -+# To cancel the load in case of error: -+# -+# echo -1 > /sysfs/$DEVPATH/loading -+# ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/firmware_class/README 2004-01-25 23:37:39.000000000 +0100 -@@ -0,0 +1,58 @@ -+ -+ request_firmware() hotplug interface: -+ ------------------------------------ -+ Copyright (C) 2003 Manuel Estrada Sainz <ranty@debian.org> -+ -+ Why: -+ --- -+ -+ Today, the most extended way to use firmware in the Linux kernel is linking -+ it statically in a header file. Which has political and technical issues: -+ -+ 1) Some firmware is not legal to redistribute. -+ 2) The firmware occupies memory permanently, even though it often is just -+ used once. -+ 3) Some people, like the Debian crowd, don't consider some firmware free -+ enough and remove entire drivers (e.g.: keyspan). -+ -+ about in-kernel persistence: -+ --------------------------- -+ Under some circumstances, as explained below, it would be interesting to keep -+ firmware images in non-swappable kernel memory or even in the kernel image -+ (probably within initramfs). -+ -+ Note that this functionality has not been implemented. -+ -+ - Why OPTIONAL in-kernel persistence may be a good idea sometimes: -+ -+ - If the device that needs the firmware is needed to access the -+ filesystem. When upon some error the device has to be reset and the -+ firmware reloaded, it won't be possible to get it from userspace. -+ e.g.: -+ - A diskless client with a network card that needs firmware. -+ - The filesystem is stored in a disk behind an scsi device -+ that needs firmware. -+ - Replacing buggy DSDT/SSDT ACPI tables on boot. -+ Note: this would require the persistent objects to be included -+ within the kernel image, probably within initramfs. -+ -+ And the same device can be needed to access the filesystem or not depending -+ on the setup, so I think that the choice on what firmware to make -+ persistent should be left to userspace. -+ -+ - Why register_firmware()+__init can be useful: -+ - For boot devices needing firmware. -+ - To make the transition easier: -+ The firmware can be declared __init and register_firmware() -+ called on module_init. Then the firmware is warranted to be -+ there even if "firmware hotplug userspace" is not there yet or -+ it doesn't yet provide the needed firmware. -+ Once the firmware is widely available in userspace, it can be -+ removed from the kernel. Or made optional (CONFIG_.*_FIRMWARE). -+ -+ In either case, if firmware hotplug support is there, it can move the -+ firmware out of kernel memory into the real filesystem for later -+ usage. -+ -+ Note: If persistence is implemented on top of initramfs, -+ register_firmware() may not be appropriate. ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ linux/drivers/bluetooth/bfusb.c 2004-01-25 23:37:39.000000000 +0100 -@@ -0,0 +1,781 @@ -+/* -+ * -+ * AVM BlueFRITZ! USB driver -+ * -+ * Copyright (C) 2003 Marcel Holtmann <marcel@holtmann.org> -+ * -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ */ -+ -+#include <linux/config.h> -+#include <linux/module.h> -+ -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/slab.h> -+#include <linux/types.h> -+#include <linux/sched.h> -+#include <linux/errno.h> -+#include <linux/skbuff.h> -+ -+#include <linux/firmware.h> -+#include <linux/usb.h> -+ -+#include <net/bluetooth/bluetooth.h> -+#include <net/bluetooth/hci_core.h> -+ -+#ifndef CONFIG_BLUEZ_HCIBFUSB_DEBUG -+#undef BT_DBG -+#define BT_DBG(D...) -+#endif -+ -+#define VERSION "1.1" -+ -+static struct usb_device_id bfusb_table[] = { -+ /* AVM BlueFRITZ! USB */ -+ { USB_DEVICE(0x057c, 0x2200) }, -+ -+ { } /* Terminating entry */ -+}; -+ -+MODULE_DEVICE_TABLE(usb, bfusb_table); -+ -+ -+#define BFUSB_MAX_BLOCK_SIZE 256 -+ -+#define BFUSB_BLOCK_TIMEOUT (HZ * 3) -+ -+#define BFUSB_TX_PROCESS 1 -+#define BFUSB_TX_WAKEUP 2 -+ -+#define BFUSB_MAX_BULK_TX 1 -+#define BFUSB_MAX_BULK_RX 1 -+ -+struct bfusb { -+ struct hci_dev hdev; -+ -+ unsigned long state; -+ -+ struct usb_device *udev; -+ -+ unsigned int bulk_in_ep; -+ unsigned int bulk_out_ep; -+ unsigned int bulk_pkt_size; -+ -+ rwlock_t lock; -+ -+ struct sk_buff_head transmit_q; -+ -+ struct sk_buff *reassembly; -+ -+ atomic_t pending_tx; -+ struct sk_buff_head pending_q; -+ struct sk_buff_head completed_q; -+}; -+ -+struct bfusb_scb { -+ struct urb *urb; -+}; -+ -+static void bfusb_tx_complete(struct urb *urb); -+static void bfusb_rx_complete(struct urb *urb); -+ -+static struct urb *bfusb_get_completed(struct bfusb *bfusb) -+{ -+ struct sk_buff *skb; -+ struct urb *urb = NULL; -+ -+ BT_DBG("bfusb %p", bfusb); -+ -+ skb = skb_dequeue(&bfusb->completed_q); -+ if (skb) { -+ urb = ((struct bfusb_scb *) skb->cb)->urb; -+ kfree_skb(skb); -+ } -+ -+ return urb; -+} -+ -+static inline void bfusb_unlink_urbs(struct bfusb *bfusb) -+{ -+ struct sk_buff *skb; -+ struct urb *urb; -+ -+ BT_DBG("bfusb %p", bfusb); -+ -+ while ((skb = skb_dequeue(&bfusb->pending_q))) { -+ urb = ((struct bfusb_scb *) skb->cb)->urb; -+ usb_unlink_urb(urb); -+ skb_queue_tail(&bfusb->completed_q, skb); -+ } -+ -+ while ((urb = bfusb_get_completed(bfusb))) -+ usb_free_urb(urb); -+} -+ -+ -+static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb) -+{ -+ struct bfusb_scb *scb = (void *) skb->cb; -+ struct urb *urb = bfusb_get_completed(bfusb); -+ int err, pipe; -+ -+ BT_DBG("bfusb %p skb %p len %d", bfusb, skb, skb->len); -+ -+ if (!urb && !(urb = usb_alloc_urb(0))) -+ return -ENOMEM; -+ -+ pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep); -+ -+ FILL_BULK_URB(urb, bfusb->udev, pipe, skb->data, skb->len, -+ bfusb_tx_complete, skb); -+ -+ urb->transfer_flags = USB_QUEUE_BULK; -+ -+ scb->urb = urb; -+ -+ skb_queue_tail(&bfusb->pending_q, skb); -+ -+ err = usb_submit_urb(urb); -+ if (err) { -+ BT_ERR("%s bulk tx submit failed urb %p err %d", -+ bfusb->hdev.name, urb, err); -+ skb_unlink(skb); -+ usb_free_urb(urb); -+ } else -+ atomic_inc(&bfusb->pending_tx); -+ -+ return err; -+} -+ -+static void bfusb_tx_wakeup(struct bfusb *bfusb) -+{ -+ struct sk_buff *skb; -+ -+ BT_DBG("bfusb %p", bfusb); -+ -+ if (test_and_set_bit(BFUSB_TX_PROCESS, &bfusb->state)) { -+ set_bit(BFUSB_TX_WAKEUP, &bfusb->state); -+ return; -+ } -+ -+ do { -+ clear_bit(BFUSB_TX_WAKEUP, &bfusb->state); -+ -+ while ((atomic_read(&bfusb->pending_tx) < BFUSB_MAX_BULK_TX) && -+ (skb = skb_dequeue(&bfusb->transmit_q))) { -+ if (bfusb_send_bulk(bfusb, skb) < 0) { -+ skb_queue_head(&bfusb->transmit_q, skb); -+ break; -+ } -+ } -+ -+ } while (test_bit(BFUSB_TX_WAKEUP, &bfusb->state)); -+ -+ clear_bit(BFUSB_TX_PROCESS, &bfusb->state); -+} -+ -+static void bfusb_tx_complete(struct urb *urb) -+{ -+ struct sk_buff *skb = (struct sk_buff *) urb->context; -+ struct bfusb *bfusb = (struct bfusb *) skb->dev; -+ -+ BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len); -+ -+ atomic_dec(&bfusb->pending_tx); -+ -+ if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags)) -+ return; -+ -+ if (!urb->status) -+ bfusb->hdev.stat.byte_tx += skb->len; -+ else -+ bfusb->hdev.stat.err_tx++; -+ -+ read_lock(&bfusb->lock); -+ -+ skb_unlink(skb); -+ skb_queue_tail(&bfusb->completed_q, skb); -+ -+ bfusb_tx_wakeup(bfusb); -+ -+ read_unlock(&bfusb->lock); -+} -+ -+ -+static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb) -+{ -+ struct bfusb_scb *scb; -+ struct sk_buff *skb; -+ int err, pipe, size = HCI_MAX_FRAME_SIZE + 32; -+ -+ BT_DBG("bfusb %p urb %p", bfusb, urb); -+ -+ if (!urb && !(urb = usb_alloc_urb(0))) -+ return -ENOMEM; -+ -+ if (!(skb = bluez_skb_alloc(size, GFP_ATOMIC))) { -+ usb_free_urb(urb); -+ return -ENOMEM; -+ } -+ -+ skb->dev = (void *) bfusb; -+ -+ scb = (struct bfusb_scb *) skb->cb; -+ scb->urb = urb; -+ -+ pipe = usb_rcvbulkpipe(bfusb->udev, bfusb->bulk_in_ep); -+ -+ FILL_BULK_URB(urb, bfusb->udev, pipe, skb->data, size, -+ bfusb_rx_complete, skb); -+ -+ urb->transfer_flags = USB_QUEUE_BULK; -+ -+ skb_queue_tail(&bfusb->pending_q, skb); -+ -+ err = usb_submit_urb(urb); -+ if (err) { -+ BT_ERR("%s bulk rx submit failed urb %p err %d", -+ bfusb->hdev.name, urb, err); -+ skb_unlink(skb); -+ kfree_skb(skb); -+ usb_free_urb(urb); -+ } -+ -+ return err; -+} -+ -+static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *data, int len) -+{ -+ BT_DBG("bfusb %p hdr 0x%02x data %p len %d", bfusb, hdr, data, len); -+ -+ if (hdr & 0x10) { -+ BT_ERR("%s error in block", bfusb->hdev.name); -+ if (bfusb->reassembly) -+ kfree_skb(bfusb->reassembly); -+ bfusb->reassembly = NULL; -+ return -EIO; -+ } -+ -+ if (hdr & 0x04) { -+ struct sk_buff *skb; -+ unsigned char pkt_type; -+ int pkt_len = 0; -+ -+ if (bfusb->reassembly) { -+ BT_ERR("%s unexpected start block", bfusb->hdev.name); -+ kfree_skb(bfusb->reassembly); -+ bfusb->reassembly = NULL; -+ } -+ -+ if (len < 1) { -+ BT_ERR("%s no packet type found", bfusb->hdev.name); -+ return -EPROTO; -+ } -+ -+ pkt_type = *data++; len--; -+ -+ switch (pkt_type) { -+ case HCI_EVENT_PKT: -+ if (len >= HCI_EVENT_HDR_SIZE) { -+ hci_event_hdr *hdr = (hci_event_hdr *) data; -+ pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen; -+ } else { -+ BT_ERR("%s event block is too short", bfusb->hdev.name); -+ return -EILSEQ; -+ } -+ break; -+ -+ case HCI_ACLDATA_PKT: -+ if (len >= HCI_ACL_HDR_SIZE) { -+ hci_acl_hdr *hdr = (hci_acl_hdr *) data; -+ pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen); -+ } else { -+ BT_ERR("%s data block is too short", bfusb->hdev.name); -+ return -EILSEQ; -+ } -+ break; -+ -+ case HCI_SCODATA_PKT: -+ if (len >= HCI_SCO_HDR_SIZE) { -+ hci_sco_hdr *hdr = (hci_sco_hdr *) data; -+ pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen; -+ } else { -+ BT_ERR("%s audio block is too short", bfusb->hdev.name); -+ return -EILSEQ; -+ } -+ break; -+ } -+ -+ skb = bluez_skb_alloc(pkt_len, GFP_ATOMIC); -+ if (!skb) { -+ BT_ERR("%s no memory for the packet", bfusb->hdev.name); -+ return -ENOMEM; -+ } -+ -+ skb->dev = (void *) &bfusb->hdev; -+ skb->pkt_type = pkt_type; -+ -+ bfusb->reassembly = skb; -+ } else { -+ if (!bfusb->reassembly) { -+ BT_ERR("%s unexpected continuation block", bfusb->hdev.name); -+ return -EIO; -+ } -+ } -+ -+ if (len > 0) -+ memcpy(skb_put(bfusb->reassembly, len), data, len); -+ -+ if (hdr & 0x08) { -+ hci_recv_frame(bfusb->reassembly); -+ bfusb->reassembly = NULL; -+ } -+ -+ return 0; -+} -+ -+static void bfusb_rx_complete(struct urb *urb) -+{ -+ struct sk_buff *skb = (struct sk_buff *) urb->context; -+ struct bfusb *bfusb = (struct bfusb *) skb->dev; -+ unsigned char *buf = urb->transfer_buffer; -+ int count = urb->actual_length; -+ int err, hdr, len; -+ -+ BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len); -+ -+ if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags)) -+ return; -+ -+ read_lock(&bfusb->lock); -+ -+ if (urb->status || !count) -+ goto resubmit; -+ -+ bfusb->hdev.stat.byte_rx += count; -+ -+ skb_put(skb, count); -+ -+ while (count) { -+ hdr = buf[0] | (buf[1] << 8); -+ -+ if (hdr & 0x4000) { -+ len = 0; -+ count -= 2; -+ buf += 2; -+ } else { -+ len = (buf[2] == 0) ? 256 : buf[2]; -+ count -= 3; -+ buf += 3; -+ } -+ -+ if (count < len) { -+ BT_ERR("%s block extends over URB buffer ranges", -+ bfusb->hdev.name); -+ } -+ -+ if ((hdr & 0xe1) == 0xc1) -+ bfusb_recv_block(bfusb, hdr, buf, len); -+ -+ count -= len; -+ buf += len; -+ } -+ -+ skb_unlink(skb); -+ kfree_skb(skb); -+ -+ bfusb_rx_submit(bfusb, urb); -+ -+ read_unlock(&bfusb->lock); -+ -+ return; -+ -+resubmit: -+ urb->dev = bfusb->udev; -+ -+ err = usb_submit_urb(urb); -+ if (err) { -+ BT_ERR("%s bulk resubmit failed urb %p err %d", -+ bfusb->hdev.name, urb, err); -+ } -+ -+ read_unlock(&bfusb->lock); -+} -+ -+ -+static int bfusb_open(struct hci_dev *hdev) -+{ -+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; -+ unsigned long flags; -+ int i, err; -+ -+ BT_DBG("hdev %p bfusb %p", hdev, bfusb); -+ -+ if (test_and_set_bit(HCI_RUNNING, &hdev->flags)) -+ return 0; -+ -+ MOD_INC_USE_COUNT; -+ -+ write_lock_irqsave(&bfusb->lock, flags); -+ -+ err = bfusb_rx_submit(bfusb, NULL); -+ if (!err) { -+ for (i = 1; i < BFUSB_MAX_BULK_RX; i++) -+ bfusb_rx_submit(bfusb, NULL); -+ } else { -+ clear_bit(HCI_RUNNING, &hdev->flags); -+ MOD_DEC_USE_COUNT; -+ } -+ -+ write_unlock_irqrestore(&bfusb->lock, flags); -+ -+ return err; -+} -+ -+static int bfusb_flush(struct hci_dev *hdev) -+{ -+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; -+ -+ BT_DBG("hdev %p bfusb %p", hdev, bfusb); -+ -+ skb_queue_purge(&bfusb->transmit_q); -+ -+ return 0; -+} -+ -+static int bfusb_close(struct hci_dev *hdev) -+{ -+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; -+ unsigned long flags; -+ -+ BT_DBG("hdev %p bfusb %p", hdev, bfusb); -+ -+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) -+ return 0; -+ -+ write_lock_irqsave(&bfusb->lock, flags); -+ -+ bfusb_unlink_urbs(bfusb); -+ bfusb_flush(hdev); -+ -+ write_unlock_irqrestore(&bfusb->lock, flags); -+ -+ MOD_DEC_USE_COUNT; -+ -+ return 0; -+} -+ -+static int bfusb_send_frame(struct sk_buff *skb) -+{ -+ struct hci_dev *hdev = (struct hci_dev *) skb->dev; -+ struct bfusb *bfusb; -+ struct sk_buff *nskb; -+ unsigned char buf[3]; -+ int sent = 0, size, count; -+ -+ BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, skb->pkt_type, skb->len); -+ |
