Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Mon, 19 Feb 2007 20:59:55 +0000 (12:59 -0800)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Mon, 19 Feb 2007 20:59:55 +0000 (12:59 -0800)
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6:
  PCI: Make PCI device numa-node attribute visible in sysfs
  PCI: add systems for automatic breadth-first device sorting
  PCI: PCI devices get assigned redundant IRQs
  PCI: Make CARDBUS_MEM_SIZE and CARDBUS_IO_SIZE boot options
  PCI: pci.txt fix __devexit() usage
  PCI/sysfs/kobject kernel-doc fixes

130 files changed:
Documentation/acpi-hotkey.txt [deleted file]
Documentation/feature-removal-schedule.txt
Documentation/sony-laptop.txt [new file with mode: 0644]
MAINTAINERS
arch/i386/kernel/acpi/boot.c
arch/ia64/kernel/acpi.c
arch/x86_64/kernel/early-quirks.c
drivers/acpi/Kconfig
drivers/acpi/Makefile
drivers/acpi/ac.c
drivers/acpi/acpi_memhotplug.c
drivers/acpi/asus_acpi.c
drivers/acpi/battery.c
drivers/acpi/bay.c
drivers/acpi/bus.c
drivers/acpi/button.c
drivers/acpi/cm_sbs.c
drivers/acpi/container.c
drivers/acpi/debug.c
drivers/acpi/dispatcher/dsmethod.c
drivers/acpi/dock.c
drivers/acpi/ec.c
drivers/acpi/event.c
drivers/acpi/events/evgpe.c
drivers/acpi/events/evmisc.c
drivers/acpi/executer/exdump.c
drivers/acpi/executer/exmutex.c
drivers/acpi/fan.c
drivers/acpi/glue.c
drivers/acpi/hardware/hwsleep.c
drivers/acpi/hotkey.c [deleted file]
drivers/acpi/i2c_ec.c
drivers/acpi/ibm_acpi.c
drivers/acpi/numa.c
drivers/acpi/osl.c
drivers/acpi/pci_bind.c
drivers/acpi/pci_irq.c
drivers/acpi/pci_link.c
drivers/acpi/pci_root.c
drivers/acpi/power.c
drivers/acpi/processor_core.c
drivers/acpi/processor_idle.c
drivers/acpi/processor_perflib.c
drivers/acpi/processor_thermal.c
drivers/acpi/processor_throttling.c
drivers/acpi/sbs.c
drivers/acpi/scan.c
drivers/acpi/sleep/main.c
drivers/acpi/system.c
drivers/acpi/tables.c
drivers/acpi/tables/tbxface.c
drivers/acpi/thermal.c
drivers/acpi/toshiba_acpi.c
drivers/acpi/utilities/utdelete.c
drivers/acpi/utils.c
drivers/acpi/video.c
drivers/base/bus.c
drivers/base/class.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/asus-laptop.c
drivers/misc/sony-laptop.c [new file with mode: 0644]
drivers/pcmcia/at91_cf.c
drivers/pcmcia/soc_common.c
drivers/pnp/pnpacpi/Kconfig
drivers/scsi/sd.c
drivers/serial/serial_cs.c
drivers/usb/Makefile
drivers/usb/atm/ueagle-atm.c
drivers/usb/class/cdc-acm.c
drivers/usb/core/devices.c
drivers/usb/core/devio.c
drivers/usb/core/driver.c
drivers/usb/core/endpoint.c
drivers/usb/core/generic.c
drivers/usb/core/hub.c
drivers/usb/core/message.c
drivers/usb/core/otg_whitelist.h
drivers/usb/core/sysfs.c
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/serial.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/isp116x-hcd.c
drivers/usb/host/ohci-at91.c
drivers/usb/host/ohci-hcd.c
drivers/usb/input/hid-core.c
drivers/usb/misc/Kconfig
drivers/usb/misc/Makefile
drivers/usb/misc/appledisplay.c
drivers/usb/misc/berry_charge.c [new file with mode: 0644]
drivers/usb/net/Kconfig
drivers/usb/net/asix.c
drivers/usb/net/cdc_subset.c
drivers/usb/net/usbnet.c
drivers/usb/serial/airprime.c
drivers/usb/serial/cp2101.c
drivers/usb/serial/generic.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.h
drivers/usb/storage/scsiglue.c
drivers/usb/storage/unusual_devs.h
drivers/usb/usb-skeleton.c
fs/debugfs/file.c
fs/debugfs/inode.c
fs/partitions/check.c
include/acpi/acinterp.h
include/acpi/acobject.h
include/acpi/acpi_drivers.h
include/acpi/acpiosxf.h
include/asm-i386/acpi.h
include/linux/acpi.h
include/linux/debugfs.h
include/linux/device.h
include/linux/kmod.h
include/linux/module.h
include/linux/moduleparam.h
include/linux/usb.h
include/linux/usb/cdc.h
include/linux/usb/ch9.h
include/linux/usb/serial.h
include/linux/usb_usual.h
include/linux/usbdevice_fs.h
include/pcmcia/ciscode.h
include/scsi/scsi_device.h
kernel/kmod.c
kernel/module.c
kernel/params.c
lib/kobject.c

diff --git a/Documentation/acpi-hotkey.txt b/Documentation/acpi-hotkey.txt
deleted file mode 100644 (file)
index 38040fa..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-driver/acpi/hotkey.c implement:
-1. /proc/acpi/hotkey/event_config 
-(event based hotkey or event config interface):
-a. add a  event based hotkey(event) : 
-echo "0:bus::action:method:num:num" > event_config
-
-b. delete a event based hotkey(event): 
-echo "1:::::num:num" > event_config
-
-c.  modify a event based hotkey(event):    
-echo "2:bus::action:method:num:num" > event_config
-
-2. /proc/acpi/hotkey/poll_config 
-(polling based hotkey or event config interface):
-a.add a polling based hotkey(event) :  
-echo "0:bus:method:action:method:num" > poll_config
-this adding command will create a proc file 
-/proc/acpi/hotkey/method, which is used to get 
-result of polling.
-
-b.delete a polling based hotkey(event):        
-echo "1:::::num" > event_config
-
-c.modify a polling based hotkey(event):    
-echo "2:bus:method:action:method:num" > poll_config
-
-3./proc/acpi/hotkey/action 
-(interface to call aml method associated with a 
-specific hotkey(event))
-echo "event_num:event_type:event_argument" > 
-       /proc/acpi/hotkey/action.
-The result of the execution of this aml method is 
-attached to /proc/acpi/hotkey/poll_method, which is dynamically
-created.  Please use command "cat /proc/acpi/hotkey/polling_method" 
-to retrieve it.
-
-Note: Use cmdline "acpi_generic_hotkey" to over-ride
-platform-specific with generic driver.
index c585aa8..28f897f 100644 (file)
@@ -253,29 +253,6 @@ Who:       Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
 
 ---------------------------
 
-<<<<<<< test:Documentation/feature-removal-schedule.txt
-What:  ACPI hotkey driver (CONFIG_ACPI_HOTKEY)
-When:  2.6.21
-Why:   hotkey.c was an attempt to consolidate multiple drivers that use
-       ACPI to implement hotkeys.  However, hotkeys are not documented
-       in the ACPI specification, so the drivers used undocumented
-       vendor-specific hooks and turned out to be more different than
-       the same.
-
-       Further, the keys and the features supplied by each platform
-       are different, so there will always be a need for
-       platform-specific drivers.
-
-       So the new plan is to delete hotkey.c and instead, work on the
-       platform specific drivers to try to make them look the same
-       to the user when they supply the same features.
-
-       hotkey.c has always depended on CONFIG_EXPERIMENTAL
-
-Who:   Len Brown <len.brown@intel.com>
-
----------------------------
-
 What:  /sys/firmware/acpi/namespace
 When:  2.6.21
 Why:   The ACPI namespace is effectively the symbol list for
diff --git a/Documentation/sony-laptop.txt b/Documentation/sony-laptop.txt
new file mode 100644 (file)
index 0000000..dfd26df
--- /dev/null
@@ -0,0 +1,106 @@
+Sony Notebook Control Driver (SNC) Readme
+-----------------------------------------
+       Copyright (C) 2004- 2005 Stelian Pop <stelian@popies.net>
+       Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
+
+This mini-driver drives the SNC device present in the ACPI BIOS of
+the Sony Vaio laptops.
+
+It gives access to some extra laptop functionalities. In its current
+form, this driver let the user set or query the screen brightness
+through the backlight subsystem and remove/apply power to some devices.
+
+Backlight control:
+------------------
+If your laptop model supports it, you will find sysfs files in the
+/sys/class/backlight/sony/
+directory. You will be able to query and set the current screen
+brightness:
+       brightness              get/set screen brightness (an iteger
+                               between 0 and 7)
+       actual_brightness       reading from this file will query the HW
+                               to get real brightness value
+       max_brightness          the maximum brightness value
+
+
+Platform specific:
+------------------
+Loading the sony-laptop module will create a
+/sys/devices/platform/sony-laptop/
+directory populated with some files.
+
+You then read/write integer values from/to those files by using
+standard UNIX tools.
+
+The files are:
+       brightness_default      screen brightness which will be set
+                               when the laptop will be rebooted
+       cdpower                 power on/off the internal CD drive
+       audiopower              power on/off the internal sound card
+       lanpower                power on/off the internal ethernet card
+                               (only in debug mode)
+
+Note that some files may be missing if they are not supported
+by your particular laptop model.
+
+Example usage:
+       # echo "1" > /sys/devices/platform/sony-laptop/brightness_default
+sets the lowest screen brightness for the next and later reboots,
+       # echo "8" > /sys/devices/platform/sony-laptop/brightness_default
+sets the highest screen brightness for the next and later reboots,
+       # cat /sys/devices/platform/sony-laptop/brightness_default
+retrieves the value.
+
+       # echo "0" > /sys/devices/platform/sony-laptop/audiopower
+powers off the sound card,
+       # echo "1" > /sys/devices/platform/sony-laptop/audiopower
+powers on the sound card.
+
+Development:
+------------
+
+If you want to help with the development of this driver (and
+you are not afraid of any side effects doing strange things with
+your ACPI BIOS could have on your laptop), load the driver and
+pass the option 'debug=1'.
+
+REPEAT: DON'T DO THIS IF YOU DON'T LIKE RISKY BUSINESS.
+
+In your kernel logs you will find the list of all ACPI methods
+the SNC device has on your laptop. You can see the GCDP/GCDP methods
+used to pwer on/off the CD drive, but there are others.
+
+I HAVE NO IDEA WHAT THOSE METHODS DO.
+
+The sony-laptop driver creates, for some of those methods (the most
+current ones found on several Vaio models), an entry under
+/sys/devices/platform/sony-laptop, just like the 'cdpower' one.
+You can create other entries corresponding to your own laptop methods by
+further editing the source (see the 'sony_acpi_values' table, and add a new
+entry to this table with your get/set method names using the
+HANDLE_NAMES macro).
+
+Your mission, should you accept it, is to try finding out what
+those entries are for, by reading/writing random values from/to those
+files and find out what is the impact on your laptop.
+
+Should you find anything interesting, please report it back to me,
+I will not disavow all knowledge of your actions :)
+
+Bugs/Limitations:
+-----------------
+
+* This driver is not based on official documentation from Sony
+  (because there is none), so there is no guarantee this driver
+  will work at all, or do the right thing. Although this hasn't
+  happened to me, this driver could do very bad things to your
+  laptop, including permanent damage.
+
+* The sony-laptop and sonypi drivers do not interact at all. In the
+  future, sonypi could use sony-laptop to do (part of) its business.
+
+* spicctrl, which is the userspace tool used to communicate with the
+  sonypi driver (through /dev/sonypi) does not try to use the
+  sony-laptop driver. In the future, spicctrl could try sonypi first,
+  and if it isn't present, try sony-laptop instead.
+
index b0fd71b..a384551 100644 (file)
@@ -247,6 +247,13 @@ L: linux-acpi@vger.kernel.org
 W:     http://acpi.sourceforge.net/
 S:     Supported
 
+ACPI VIDEO DRIVER
+P:     Luming Yu
+M:     luming.yu@intel.com
+L:     linux-acpi@vger.kernel.org
+W:     http://acpi.sourceforge.net/
+S:     Supported
+
 AD1816 SOUND DRIVER
 P:     Thorsten Knabe
 M:     Thorsten Knabe <linux@thorsten-knabe.de>
@@ -3061,6 +3068,8 @@ S:        Maintained
 SONY VAIO CONTROL DEVICE DRIVER
 P:     Stelian Pop
 M:     stelian@popies.net
+P:     Mattia Dongili
+M:     malattia@linux.it
 W:     http://popies.net/sonypi/
 S:     Maintained
 
index fb3e723..e5eb97a 100644 (file)
@@ -850,10 +850,9 @@ static inline int acpi_parse_madt_ioapic_entries(void)
 static void __init acpi_process_madt(void)
 {
 #ifdef CONFIG_X86_LOCAL_APIC
-       int count, error;
+       int error;
 
-       count = acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt);
-       if (count >= 1) {
+       if (!acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) {
 
                /*
                 * Parse MADT LAPIC entries
index 9197d7b..3549c94 100644 (file)
@@ -651,7 +651,7 @@ int __init acpi_boot_init(void)
         * information -- the successor to MPS tables.
         */
 
-       if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt) < 1) {
+       if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) {
                printk(KERN_ERR PREFIX "Can't find MADT\n");
                goto skip_madt;
        }
@@ -702,7 +702,7 @@ int __init acpi_boot_init(void)
         * gets interrupts such as power and sleep buttons.  If it's not
         * on a Legacy interrupt, it needs to be setup.
         */
-       if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt) < 1)
+       if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt))
                printk(KERN_ERR PREFIX "Can't find FADT\n");
 
 #ifdef CONFIG_SMP
index bd30d13..8047ea8 100644 (file)
@@ -53,7 +53,9 @@ static void nvidia_bugs(void)
                return;
 
        nvidia_hpet_detected = 0;
-       acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check);
+       if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check))
+               return;
+
        if (nvidia_hpet_detected == 0) {
                acpi_skip_timer_override = 1;
                printk(KERN_INFO "Nvidia board "
index 20eacc2..e942ffe 100644 (file)
@@ -13,6 +13,7 @@ config ACPI
        depends on IA64 || X86
        depends on PCI
        depends on PM
+       select PNP
        default y
        ---help---
          Advanced Configuration and Power Interface (ACPI) support for 
@@ -132,15 +133,6 @@ config ACPI_VIDEO
          Note that this is an ref. implementation only.  It may or may not work
          for your integrated video device.
 
-config ACPI_HOTKEY
-       tristate "Generic Hotkey (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
-       depends on X86
-       default n
-       help
-         Experimental consolidated hotkey driver.
-         If you are unsure, say N.
-
 config ACPI_FAN
        tristate "Fan"
        default y
index 856c32b..5956e9f 100644 (file)
@@ -46,7 +46,6 @@ obj-$(CONFIG_ACPI_FAN)                += fan.o
 obj-$(CONFIG_ACPI_DOCK)                += dock.o
 obj-$(CONFIG_ACPI_BAY)         += bay.o
 obj-$(CONFIG_ACPI_VIDEO)       += video.o
-obj-$(CONFIG_ACPI_HOTKEY)      += hotkey.o
 obj-y                          += pci_root.o pci_link.o pci_irq.o pci_bind.o
 obj-$(CONFIG_ACPI_POWER)       += power.o
 obj-$(CONFIG_ACPI_PROCESSOR)   += processor.o
index 6daeace..37c7dc4 100644 (file)
@@ -35,7 +35,6 @@
 #define ACPI_AC_COMPONENT              0x00020000
 #define ACPI_AC_CLASS                  "ac_adapter"
 #define ACPI_AC_HID                    "ACPI0003"
-#define ACPI_AC_DRIVER_NAME            "ACPI AC Adapter Driver"
 #define ACPI_AC_DEVICE_NAME            "AC Adapter"
 #define ACPI_AC_FILE_STATE             "state"
 #define ACPI_AC_NOTIFY_STATUS          0x80
 #define ACPI_AC_STATUS_UNKNOWN         0xFF
 
 #define _COMPONENT             ACPI_AC_COMPONENT
-ACPI_MODULE_NAME("acpi_ac")
+ACPI_MODULE_NAME("ac");
 
-    MODULE_AUTHOR("Paul Diefenbaugh");
-MODULE_DESCRIPTION(ACPI_AC_DRIVER_NAME);
+MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_DESCRIPTION("ACPI AC Adapter Driver");
 MODULE_LICENSE("GPL");
 
 extern struct proc_dir_entry *acpi_lock_ac_dir(void);
@@ -58,7 +57,7 @@ static int acpi_ac_remove(struct acpi_device *device, int type);
 static int acpi_ac_open_fs(struct inode *inode, struct file *file);
 
 static struct acpi_driver acpi_ac_driver = {
-       .name = ACPI_AC_DRIVER_NAME,
+       .name = "ac",
        .class = ACPI_AC_CLASS,
        .ids = ACPI_AC_HID,
        .ops = {
index cd946ed..c261726 100644 (file)
 #define ACPI_MEMORY_DEVICE_COMPONENT           0x08000000UL
 #define ACPI_MEMORY_DEVICE_CLASS               "memory"
 #define ACPI_MEMORY_DEVICE_HID                 "PNP0C80"
-#define ACPI_MEMORY_DEVICE_DRIVER_NAME         "Hotplug Mem Driver"
 #define ACPI_MEMORY_DEVICE_NAME                        "Hotplug Mem Device"
 
 #define _COMPONENT             ACPI_MEMORY_DEVICE_COMPONENT
 
-ACPI_MODULE_NAME("acpi_memory")
-    MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>");
-MODULE_DESCRIPTION(ACPI_MEMORY_DEVICE_DRIVER_NAME);
+ACPI_MODULE_NAME("acpi_memhotplug");
+MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>");
+MODULE_DESCRIPTION("Hotplug Mem Driver");
 MODULE_LICENSE("GPL");
 
 /* ACPI _STA method values */
@@ -60,7 +59,7 @@ static int acpi_memory_device_remove(struct acpi_device *device, int type);
 static int acpi_memory_device_start(struct acpi_device *device);
 
 static struct acpi_driver acpi_memory_device_driver = {
-       .name = ACPI_MEMORY_DEVICE_DRIVER_NAME,
+       .name = "acpi_memhotplug",
        .class = ACPI_MEMORY_DEVICE_CLASS,
        .ids = ACPI_MEMORY_DEVICE_HID,
        .ops = {
index 31ad70a..772299f 100644 (file)
@@ -141,6 +141,7 @@ struct asus_hotk {
                W5A,            //W5A
                W3V,            //W3030V
                xxN,            //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N
+               A4S,            //Z81sp
                //(Centrino)
                END_MODEL
        } model;                //Models currently supported
@@ -397,7 +398,16 @@ static struct model_data model_conf[END_MODEL] = {
         .brightness_set = "SPLV",
         .brightness_get = "GPLV",
         .display_set = "SDSP",
-        .display_get = "\\ADVG"}
+       .display_get = "\\ADVG"},
+
+       {
+               .name              = "A4S",
+               .brightness_set    = "SPLV",
+               .brightness_get    = "GPLV",
+               .mt_bt_switch      = "BLED",
+               .mt_wled           = "WLED"
+       }
+
 };
 
 /* procdir we use */
@@ -421,7 +431,7 @@ static struct asus_hotk *hotk;
 static int asus_hotk_add(struct acpi_device *device);
 static int asus_hotk_remove(struct acpi_device *device, int type);
 static struct acpi_driver asus_hotk_driver = {
-       .name = ACPI_HOTK_NAME,
+       .name = "asus_acpi",
        .class = ACPI_HOTK_CLASS,
        .ids = ACPI_HOTK_HID,
        .ops = {
@@ -1117,6 +1127,8 @@ static int asus_model_match(char *model)
                return W3V;
        else if (strncmp(model, "W5A", 3) == 0)
                return W5A;
+       else if (strncmp(model, "A4S", 3) == 0)
+               return A4S;
        else
                return END_MODEL;
 }
@@ -1365,10 +1377,6 @@ static int __init asus_acpi_init(void)
        if (acpi_disabled)
                return -ENODEV;
 
-       if (!acpi_specific_hotkey_enabled) {
-               printk(KERN_ERR "Using generic hotkey driver\n");
-               return -ENODEV;
-       }
        asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir);
        if (!asus_proc_dir) {
                printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n");
index 2f4521a..e64c76c 100644 (file)
@@ -42,7 +42,6 @@
 #define ACPI_BATTERY_COMPONENT         0x00040000
 #define ACPI_BATTERY_CLASS             "battery"
 #define ACPI_BATTERY_HID               "PNP0C0A"
-#define ACPI_BATTERY_DRIVER_NAME       "ACPI Battery Driver"
 #define ACPI_BATTERY_DEVICE_NAME       "Battery"
 #define ACPI_BATTERY_FILE_INFO         "info"
 #define ACPI_BATTERY_FILE_STATUS       "state"
 #define ACPI_BATTERY_UNITS_AMPS                "mA"
 
 #define _COMPONENT             ACPI_BATTERY_COMPONENT
-ACPI_MODULE_NAME("acpi_battery")
+ACPI_MODULE_NAME("battery");
 
-    MODULE_AUTHOR("Paul Diefenbaugh");
-MODULE_DESCRIPTION(ACPI_BATTERY_DRIVER_NAME);
+MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_DESCRIPTION("ACPI Battery Driver");
 MODULE_LICENSE("GPL");
 
 extern struct proc_dir_entry *acpi_lock_battery_dir(void);
@@ -67,7 +66,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type);
 static int acpi_battery_resume(struct acpi_device *device);
 
 static struct acpi_driver acpi_battery_driver = {
-       .name = ACPI_BATTERY_DRIVER_NAME,
+       .name = "battery",
        .class = ACPI_BATTERY_CLASS,
        .ids = ACPI_BATTERY_HID,
        .ops = {
@@ -324,6 +323,13 @@ static int acpi_battery_check(struct acpi_battery *battery)
        return result;
 }
 
+static void acpi_battery_check_present(struct acpi_battery *battery)
+{
+       if (!battery->flags.present) {
+               acpi_battery_check(battery);
+       }
+}
+
 /* --------------------------------------------------------------------------
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
@@ -340,6 +346,8 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
        if (!battery)
                goto end;
 
+       acpi_battery_check_present(battery);
+
        if (battery->flags.present)
                seq_printf(seq, "present:                 yes\n");
        else {
@@ -424,6 +432,8 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
        if (!battery)
                goto end;
 
+       acpi_battery_check_present(battery);
+
        if (battery->flags.present)
                seq_printf(seq, "present:                 yes\n");
        else {
@@ -499,6 +509,8 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
        if (!battery)
                goto end;
 
+       acpi_battery_check_present(battery);
+
        if (!battery->flags.present) {
                seq_printf(seq, "present:                 no\n");
                goto end;
@@ -536,6 +548,8 @@ acpi_battery_write_alarm(struct file *file,
        if (!battery || (count > sizeof(alarm_string) - 1))
                return -EINVAL;
 
+       acpi_battery_check_present(battery);
+
        if (!battery->flags.present)
                return -ENODEV;
 
index 91082ce..fb3f31b 100644 (file)
 #include <asm/uaccess.h>
 #include <linux/platform_device.h>
 
-#define ACPI_BAY_DRIVER_NAME "ACPI Removable Drive Bay Driver"
-
-ACPI_MODULE_NAME("bay")
+ACPI_MODULE_NAME("bay");
 MODULE_AUTHOR("Kristen Carlson Accardi");
-MODULE_DESCRIPTION(ACPI_BAY_DRIVER_NAME);
+MODULE_DESCRIPTION("ACPI Removable Drive Bay Driver");
 MODULE_LICENSE("GPL");
 #define ACPI_BAY_CLASS "bay"
 #define ACPI_BAY_COMPONENT     0x10000000
@@ -47,18 +45,6 @@ MODULE_LICENSE("GPL");
        acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\
        printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); }
 static void bay_notify(acpi_handle handle, u32 event, void *data);
-static int acpi_bay_add(struct acpi_device *device);
-static int acpi_bay_remove(struct acpi_device *device, int type);
-
-static struct acpi_driver acpi_bay_driver = {
-       .name = ACPI_BAY_DRIVER_NAME,
-       .class = ACPI_BAY_CLASS,
-       .ids = ACPI_BAY_HID,
-       .ops = {
-               .add = acpi_bay_add,
-               .remove = acpi_bay_remove,
-               },
-};
 
 struct bay {
        acpi_handle handle;
@@ -234,14 +220,6 @@ int eject_removable_drive(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(eject_removable_drive);
 
-static int acpi_bay_add(struct acpi_device *device)
-{
-       bay_dprintk(device->handle, "adding bay device");
-       strcpy(acpi_device_name(device), "Dockable Bay");
-       strcpy(acpi_device_class(device), "bay");
-       return 0;
-}
-
 static int acpi_bay_add_fs(struct bay *bay)
 {
        int ret;
@@ -303,7 +281,7 @@ static int bay_add(acpi_handle handle, int id)
 
        /* initialize platform device stuff */
        pdev = platform_device_register_simple(ACPI_BAY_CLASS, id, NULL, 0);
-       if (pdev == NULL) {
+       if (IS_ERR(pdev)) {
                printk(KERN_ERR PREFIX "Error registering bay device\n");
                goto bay_add_err;
        }
@@ -339,52 +317,6 @@ bay_add_err:
        return -ENODEV;
 }
 
-static int acpi_bay_remove(struct acpi_device *device, int type)
-{
-       /*** FIXME: do something here */
-       return 0;
-}
-
-/**
- * bay_create_acpi_device - add new devices to acpi
- * @handle - handle of the device to add
- *
- *  This function will create a new acpi_device for the given
- *  handle if one does not exist already.  This should cause
- *  acpi to scan for drivers for the given devices, and call
- *  matching driver's add routine.
- *
- *  Returns a pointer to the acpi_device corresponding to the handle.
- */
-static struct acpi_device * bay_create_acpi_device(acpi_handle handle)
-{
-       struct acpi_device *device = NULL;
-       struct acpi_device *parent_device;
-       acpi_handle parent;
-       int ret;
-
-       bay_dprintk(handle, "Trying to get device");
-       if (acpi_bus_get_device(handle, &device)) {
-               /*
-                * no device created for this object,
-                * so we should create one.
-                */
-               bay_dprintk(handle, "No device for handle");
-               acpi_get_parent(handle, &parent);
-               if (acpi_bus_get_device(parent, &parent_device))
-                       parent_device = NULL;
-
-               ret = acpi_bus_add(&device, parent_device, handle,
-                       ACPI_BUS_TYPE_DEVICE);
-               if (ret) {
-                       pr_debug("error adding bus, %x\n",
-                               -ret);
-                       return NULL;
-               }
-       }
-       return device;
-}
-
 /**
  * bay_notify - act upon an acpi bay notification
  * @handle: the bay handle
@@ -394,38 +326,19 @@ static struct acpi_device * bay_create_acpi_device(acpi_handle handle)
  */
 static void bay_notify(acpi_handle handle, u32 event, void *data)
 {
-       struct acpi_device *dev;
+       struct bay *bay_dev = (struct bay *)data;
+       struct device *dev = &bay_dev->pdev->dev;
 
        bay_dprintk(handle, "Bay event");
 
        switch(event) {
        case ACPI_NOTIFY_BUS_CHECK:
-               printk("Bus Check\n");
        case ACPI_NOTIFY_DEVICE_CHECK:
-               printk("Device Check\n");
-               dev = bay_create_acpi_device(handle);
-               if (dev)
-                       acpi_bus_generate_event(dev, event, 0);
-               else
-                       printk("No device for generating event\n");
-               /* wouldn't it be a good idea to just rescan SATA
-                * right here?
-                */
-               break;
        case ACPI_NOTIFY_EJECT_REQUEST:
-               printk("Eject request\n");
-               dev = bay_create_acpi_device(handle);
-               if (dev)
-                       acpi_bus_generate_event(dev, event, 0);
-               else
-                       printk("No device for generating eventn");
-
-               /* wouldn't it be a good idea to just call the
-                * eject_device here if we were a SATA device?
-                */
+               kobject_uevent(&dev->kobj, KOBJ_CHANGE);
                break;
        default:
-               printk("unknown event %d\n", event);
+               printk(KERN_ERR PREFIX "Bay: unknown event %d\n", event);
        }
 }
 
@@ -457,10 +370,6 @@ static int __init bay_init(void)
        acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
                ACPI_UINT32_MAX, find_bay, &bays, NULL);
 
-       if (bays)
-               if ((acpi_bus_register_driver(&acpi_bay_driver) < 0))
-                       printk(KERN_ERR "Unable to register bay driver\n");
-
        if (!bays)
                return -ENODEV;
 
@@ -481,8 +390,6 @@ static void __exit bay_exit(void)
                kfree(bay->name);
                kfree(bay);
        }
-
-       acpi_bus_unregister_driver(&acpi_bay_driver);
 }
 
 postcore_initcall(bay_init);
index c26468d..dd49ea0 100644 (file)
@@ -39,7 +39,7 @@
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT             ACPI_BUS_COMPONENT
-ACPI_MODULE_NAME("acpi_bus")
+ACPI_MODULE_NAME("bus");
 #ifdef CONFIG_X86
 extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger);
 #endif
@@ -147,7 +147,7 @@ int acpi_bus_get_power(acpi_handle handle, int *state)
                        *state = ACPI_STATE_D0;
        } else {
                /*
-                * Get the device's power state either directly (via _PSC) or 
+                * Get the device's power state either directly (via _PSC) or
                 * indirectly (via power resources).
                 */
                if (device->power.flags.explicit_get) {
@@ -199,15 +199,14 @@ int acpi_bus_set_power(acpi_handle handle, int state)
         * Get device's current power state if it's unknown
         * This means device power state isn't initialized or previous setting failed
         */
-       if (!device->flags.force_power_state) {
-               if (device->power.state == ACPI_STATE_UNKNOWN)
-                       acpi_bus_get_power(device->handle, &device->power.state);
-               if (state == device->power.state) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
-                                         state));
-                       return 0;
-               }
+       if ((device->power.state == ACPI_STATE_UNKNOWN) || device->flags.force_power_state)
+               acpi_bus_get_power(device->handle, &device->power.state);
+       if ((state == device->power.state) && !device->flags.force_power_state) {
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
+                                 state));
+               return 0;
        }
+
        if (!device->power.states[state].flags.valid) {
                printk(KERN_WARNING PREFIX "Device does not support D%d\n", state);
                return -ENODEV;
@@ -462,7 +461,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
                                  "Received BUS CHECK notification for device [%s]\n",
                                  device->pnp.bus_id));
                result = acpi_bus_check_scope(device);
-               /* 
+               /*
                 * TBD: We'll need to outsource certain events to non-ACPI
                 *      drivers via the device manager (device.c).
                 */
@@ -473,7 +472,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
                                  "Received DEVICE CHECK notification for device [%s]\n",
                                  device->pnp.bus_id));
                result = acpi_bus_check_device(device, NULL);
-               /* 
+               /*
                 * TBD: We'll need to outsource certain events to non-ACPI
                 *      drivers via the device manager (device.c).
                 */
@@ -543,7 +542,7 @@ static int __init acpi_bus_init_irq(void)
        char *message = NULL;
 
 
-       /* 
+       /*
         * Let the system know what interrupt model we are using by
         * evaluating the \_PIC object, if exists.
         */
@@ -684,7 +683,7 @@ static int __init acpi_bus_init(void)
         * the EC device is found in the namespace (i.e. before acpi_initialize_objects()
         * is called).
         *
-        * This is accomplished by looking for the ECDT table, and getting 
+        * This is accomplished by looking for the ECDT table, and getting
         * the EC parameters out of that.
         */
        status = acpi_ec_ecdt_probe();
@@ -699,6 +698,9 @@ static int __init acpi_bus_init(void)
 
        printk(KERN_INFO PREFIX "Interpreter enabled\n");
 
+       /* Initialize sleep structures */
+       acpi_sleep_init();
+
        /*
         * Get the system interrupt model and evaluate \_PIC.
         */
index c726612..cb4110b 100644 (file)
@@ -34,7 +34,6 @@
 #include <acpi/acpi_drivers.h>
 
 #define ACPI_BUTTON_COMPONENT          0x00080000
-#define ACPI_BUTTON_DRIVER_NAME                "ACPI Button Driver"
 #define ACPI_BUTTON_CLASS              "button"
 #define ACPI_BUTTON_FILE_INFO          "info"
 #define ACPI_BUTTON_FILE_STATE         "state"
 #define ACPI_BUTTON_TYPE_LID           0x05
 
 #define _COMPONENT             ACPI_BUTTON_COMPONENT
-ACPI_MODULE_NAME("acpi_button")
+ACPI_MODULE_NAME("button");
 
 MODULE_AUTHOR("Paul Diefenbaugh");
-MODULE_DESCRIPTION(ACPI_BUTTON_DRIVER_NAME);
+MODULE_DESCRIPTION("ACPI Button Driver");
 MODULE_LICENSE("GPL");
 
 static int acpi_button_add(struct acpi_device *device);
@@ -73,7 +72,7 @@ static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
 static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
 
 static struct acpi_driver acpi_button_driver = {
-       .name = ACPI_BUTTON_DRIVER_NAME,
+       .name = "button",
        .class = ACPI_BUTTON_CLASS,
        .ids = "button_power,button_sleep,PNP0C0D,PNP0C0C,PNP0C0E",
        .ops = {
index 4a9b7bf..f9db4f4 100644 (file)
@@ -31,7 +31,7 @@
 #include <acpi/actypes.h>
 #include <acpi/acutils.h>
 
-ACPI_MODULE_NAME("cm_sbs")
+ACPI_MODULE_NAME("cm_sbs");
 #define ACPI_AC_CLASS          "ac_adapter"
 #define ACPI_BATTERY_CLASS     "battery"
 #define ACPI_SBS_COMPONENT     0x00080000
index 69a68fd..0930d94 100644 (file)
@@ -35,7 +35,6 @@
 #include <acpi/acpi_drivers.h>
 #include <acpi/container.h>
 
-#define ACPI_CONTAINER_DRIVER_NAME     "ACPI container driver"
 #define ACPI_CONTAINER_DEVICE_NAME     "ACPI container device"
 #define ACPI_CONTAINER_CLASS           "container"
 
 
 #define ACPI_CONTAINER_COMPONENT       0x01000000
 #define _COMPONENT                     ACPI_CONTAINER_COMPONENT
-ACPI_MODULE_NAME("acpi_container")
+ACPI_MODULE_NAME("container");
 
-    MODULE_AUTHOR("Anil S Keshavamurthy");
-MODULE_DESCRIPTION(ACPI_CONTAINER_DRIVER_NAME);
+MODULE_AUTHOR("Anil S Keshavamurthy");
+MODULE_DESCRIPTION("ACPI container driver");
 MODULE_LICENSE("GPL");
 
 #define ACPI_STA_PRESENT               (0x00000001)
@@ -56,7 +55,7 @@ static int acpi_container_add(struct acpi_device *device);
 static int acpi_container_remove(struct acpi_device *device, int type);
 
 static struct acpi_driver acpi_container_driver = {
-       .name = ACPI_CONTAINER_DRIVER_NAME,
+       .name = "container",
        .class = ACPI_CONTAINER_CLASS,
        .ids = "ACPI0004,PNP0A05,PNP0A06",
        .ops = {
index d48f65a..bf513e0 100644 (file)
@@ -12,7 +12,7 @@
 #include <acpi/acglobal.h>
 
 #define _COMPONENT             ACPI_SYSTEM_COMPONENT
-ACPI_MODULE_NAME("debug")
+ACPI_MODULE_NAME("debug");
 
 #ifdef MODULE_PARAM_PREFIX
 #undef MODULE_PARAM_PREFIX
index 1cbe619..1683e5c 100644 (file)
@@ -231,10 +231,8 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
                 * Obtain the method mutex if necessary. Do not acquire mutex for a
                 * recursive call.
                 */
-               if (!walk_state ||
-                   !obj_desc->method.mutex->mutex.owner_thread ||
-                   (walk_state->thread !=
-                    obj_desc->method.mutex->mutex.owner_thread)) {
+               if (acpi_os_get_thread_id() !=
+                   obj_desc->method.mutex->mutex.owner_thread_id) {
                        /*
                         * Acquire the method mutex. This releases the interpreter if we
                         * block (and reacquires it before it returns)
@@ -248,14 +246,14 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
                        }
 
                        /* Update the mutex and walk info and save the original sync_level */
+                       obj_desc->method.mutex->mutex.owner_thread_id =
+                               acpi_os_get_thread_id();
 
                        if (walk_state) {
                                obj_desc->method.mutex->mutex.
                                    original_sync_level =
                                    walk_state->thread->current_sync_level;
 
-                               obj_desc->method.mutex->mutex.owner_thread =
-                                   walk_state->thread;
                                walk_state->thread->current_sync_level =
                                    obj_desc->method.sync_level;
                        } else {
@@ -569,7 +567,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
 
                        acpi_os_release_mutex(method_desc->method.mutex->mutex.
                                              os_mutex);
-                       method_desc->method.mutex->mutex.owner_thread = NULL;
+                       method_desc->method.mutex->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED;
                }
        }
 
index 688e83a..54a697f 100644 (file)
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
-#define ACPI_DOCK_DRIVER_NAME "ACPI Dock Station Driver"
+#define ACPI_DOCK_DRIVER_DESCRIPTION "ACPI Dock Station Driver"
 
-ACPI_MODULE_NAME("dock")
+ACPI_MODULE_NAME("dock");
 MODULE_AUTHOR("Kristen Carlson Accardi");
-MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_NAME);
+MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION);
 MODULE_LICENSE("GPL");
 
 static struct atomic_notifier_head dock_notifier_list;
@@ -741,7 +741,7 @@ static int dock_add(acpi_handle handle)
                goto dock_add_err;
        }
 
-       printk(KERN_INFO PREFIX "%s \n", ACPI_DOCK_DRIVER_NAME);
+       printk(KERN_INFO PREFIX "%s \n", ACPI_DOCK_DRIVER_DESCRIPTION);
 
        return 0;
 
index 743ce27..ab68883 100644 (file)
 #include <acpi/actypes.h>
 
 #define _COMPONENT             ACPI_EC_COMPONENT
-ACPI_MODULE_NAME("acpi_ec")
+ACPI_MODULE_NAME("ec");
 #define ACPI_EC_COMPONENT              0x00100000
 #define ACPI_EC_CLASS                  "embedded_controller"
 #define ACPI_EC_HID                    "PNP0C09"
-#define ACPI_EC_DRIVER_NAME            "ACPI Embedded Controller Driver"
 #define ACPI_EC_DEVICE_NAME            "Embedded Controller"
 #define ACPI_EC_FILE_INFO              "info"
 #undef PREFIX
@@ -80,7 +79,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type);
 static int acpi_ec_add(struct acpi_device *device);
 
 static struct acpi_driver acpi_ec_driver = {
-       .name = ACPI_EC_DRIVER_NAME,
+       .name = "ec",
        .class = ACPI_EC_CLASS,
        .ids = ACPI_EC_HID,
        .ops = {
@@ -280,8 +279,10 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
        mutex_lock(&ec->lock);
        if (ec->global_lock) {
                status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
-               if (ACPI_FAILURE(status))
+               if (ACPI_FAILURE(status)) {
+                       mutex_unlock(&ec->lock);
                        return -ENODEV;
+               }
        }
 
        /* Make sure GPE is enabled before doing transaction */
index 959a893..3b23562 100644 (file)
@@ -13,7 +13,7 @@
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT             ACPI_SYSTEM_COMPONENT
-ACPI_MODULE_NAME("event")
+ACPI_MODULE_NAME("event");
 
 /* Global vars for handling event proc entry */
 static DEFINE_SPINLOCK(acpi_system_event_lock);
index dfac3ec..635ba44 100644 (file)
@@ -636,17 +636,6 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
                }
        }
 
-       if (!acpi_gbl_system_awake_and_running) {
-               /*
-                * We just woke up because of a wake GPE. Disable any further GPEs
-                * until we are fully up and running (Only wake GPEs should be enabled
-                * at this time, but we just brute-force disable them all.)
-                * 1) We must disable this particular wake GPE so it won't fire again
-                * 2) We want to disable all wake GPEs, since we are now awake
-                */
-               (void)acpi_hw_disable_all_gpes();
-       }
-
        /*
         * Dispatch the GPE to either an installed handler, or the control method
         * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke
index 1b784ff..d572700 100644 (file)
@@ -196,12 +196,11 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
                notify_info->notify.value = (u16) notify_value;
                notify_info->notify.handler_obj = handler_obj;
 
-               status =
-                   acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch,
-                                   notify_info);
-               if (ACPI_FAILURE(status)) {
-                       acpi_ut_delete_generic_state(notify_info);
-               }
+               acpi_ex_relinquish_interpreter();
+
+               acpi_ev_notify_dispatch(notify_info);
+
+               acpi_ex_reacquire_interpreter();
        }
 
        if (!handler_obj) {
index 68d283f..1a73c14 100644 (file)
@@ -134,7 +134,7 @@ static struct acpi_exdump_info acpi_ex_dump_method[8] = {
 static struct acpi_exdump_info acpi_ex_dump_mutex[5] = {
        {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL},
        {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"},
-       {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"},
+       {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread_id), "Owner Thread"},
        {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth),
         "Acquire Depth"},
        {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.os_mutex), "OsMutex"}
index 5101bad..4eb883b 100644 (file)
@@ -66,10 +66,9 @@ acpi_ex_link_mutex(union acpi_operand_object *obj_desc,
  *
  ******************************************************************************/
 
-void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc)
+void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc,
+                         struct acpi_thread_state *thread)
 {
-       struct acpi_thread_state *thread = obj_desc->mutex.owner_thread;
-
        if (!thread) {
                return;
        }
@@ -174,16 +173,13 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
 
        /* Support for multiple acquires by the owning thread */
 
-       if (obj_desc->mutex.owner_thread) {
-               if (obj_desc->mutex.owner_thread->thread_id ==
-                   walk_state->thread->thread_id) {
-                       /*
-                        * The mutex is already owned by this thread, just increment the
-                        * acquisition depth
-                        */
-                       obj_desc->mutex.acquisition_depth++;
-                       return_ACPI_STATUS(AE_OK);
-               }
+       if (obj_desc->mutex.owner_thread_id == acpi_os_get_thread_id()) {
+               /*
+                * The mutex is already owned by this thread, just increment the
+                * acquisition depth
+                */
+               obj_desc->mutex.acquisition_depth++;
+               return_ACPI_STATUS(AE_OK);
        }
 
        /* Acquire the mutex, wait if necessary. Special case for Global Lock */
@@ -206,7 +202,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
 
        /* Have the mutex: update mutex and walk info and save the sync_level */
 
-       obj_desc->mutex.owner_thread = walk_state->thread;
+       obj_desc->mutex.owner_thread_id = acpi_os_get_thread_id();
        obj_desc->mutex.acquisition_depth = 1;
        obj_desc->mutex.original_sync_level =
            walk_state->thread->current_sync_level;
@@ -246,7 +242,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
 
        /* The mutex must have been previously acquired in order to release it */
 
-       if (!obj_desc->mutex.owner_thread) {
+       if (!obj_desc->mutex.owner_thread_id) {
                ACPI_ERROR((AE_INFO,
                            "Cannot release Mutex [%4.4s], not acquired",
                            acpi_ut_get_node_name(obj_desc->mutex.node)));
@@ -266,14 +262,14 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
         * The Mutex is owned, but this thread must be the owner.
         * Special case for Global Lock, any thread can release
         */
-       if ((obj_desc->mutex.owner_thread->thread_id !=
+       if ((obj_desc->mutex.owner_thread_id !=
             walk_state->thread->thread_id)
            && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) {
                ACPI_ERROR((AE_INFO,
                            "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX",
                            (unsigned long)walk_state->thread->thread_id,
                            acpi_ut_get_node_name(obj_desc->mutex.node),
-                           (unsigned long)obj_desc->mutex.owner_thread->thread_id));
+                           (unsigned long)obj_desc->mutex.owner_thread_id));
                return_ACPI_STATUS(AE_AML_NOT_OWNER);
        }
 
@@ -300,7 +296,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
 
        /* Unlink the mutex from the owner's list */
 
-       acpi_ex_unlink_mutex(obj_desc);
+       acpi_ex_unlink_mutex(obj_desc, walk_state->thread);
 
        /* Release the mutex, special case for Global Lock */
 
@@ -312,7 +308,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
 
        /* Update the mutex and restore sync_level */
 
-       obj_desc->mutex.owner_thread = NULL;
+       obj_desc->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED;
        walk_state->thread->current_sync_level =
            obj_desc->mutex.original_sync_level;
 
@@ -367,7 +363,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread)
 
                /* Mark mutex unowned */
 
-               obj_desc->mutex.owner_thread = NULL;
+               obj_desc->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED;
 
                /* Update Thread sync_level (Last mutex is the important one) */
 
index af22fdf..ec655c5 100644 (file)
 
 #define ACPI_FAN_COMPONENT             0x00200000
 #define ACPI_FAN_CLASS                 "fan"
-#define ACPI_FAN_DRIVER_NAME           "ACPI Fan Driver"
 #define ACPI_FAN_FILE_STATE            "state"
 
 #define _COMPONENT             ACPI_FAN_COMPONENT
-ACPI_MODULE_NAME("acpi_fan")
+ACPI_MODULE_NAME("fan");
 
-    MODULE_AUTHOR("Paul Diefenbaugh");
-MODULE_DESCRIPTION(ACPI_FAN_DRIVER_NAME);
+MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_DESCRIPTION("ACPI Fan Driver");
 MODULE_LICENSE("GPL");
 
 static int acpi_fan_add(struct acpi_device *device);
@@ -52,7 +51,7 @@ static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state);
 static int acpi_fan_resume(struct acpi_device *device);
 
 static struct acpi_driver acpi_fan_driver = {
-       .name = ACPI_FAN_DRIVER_NAME,
+       .name = "fan",
        .class = ACPI_FAN_CLASS,
        .ids = "PNP0C0B",
        .ops = {
index 7b6c9ff..4334c20 100644 (file)
@@ -241,3 +241,65 @@ static int __init init_acpi_device_notify(void)
 }
 
 arch_initcall(init_acpi_device_notify);
+
+
+#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
+
+/* Every ACPI platform has a mc146818 compatible "cmos rtc".  Here we find
+ * its device node and pass extra config data.  This helps its driver use
+ * capabilities that the now-obsolete mc146818 didn't have, and informs it
+ * that this board's RTC is wakeup-capable (per ACPI spec).
+ */
+#include <linux/mc146818rtc.h>
+
+static struct cmos_rtc_board_info rtc_info;
+
+
+/* PNP devices are registered in a subsys_initcall();
+ * ACPI specifies the PNP IDs to use.
+ */
+#include <linux/pnp.h>
+
+static int __init pnp_match(struct device *dev, void *data)
+{
+       static const char *ids[] = { "PNP0b00", "PNP0b01", "PNP0b02", };
+       struct pnp_dev *pnp = to_pnp_dev(dev);
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(ids); i++) {
+               if (compare_pnp_id(pnp->id, ids[i]) != 0)
+                       return 1;
+       }
+       return 0;
+}
+
+static struct device *__init get_rtc_dev(void)
+{
+       return bus_find_device(&pnp_bus_type, NULL, NULL, pnp_match);
+}
+
+static int __init acpi_rtc_init(void)
+{
+       struct device *dev = get_rtc_dev();
+
+       if (dev) {
+               rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
+               rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
+               rtc_info.rtc_century = acpi_gbl_FADT.century;
+
+               /* NOTE:  acpi_gbl_FADT->rtcs4 is NOT currently useful */
+
+               dev->platform_data = &rtc_info;
+
+               /* RTC always wakes from S1/S2/S3, and often S4/STD */
+               device_init_wakeup(dev, 1);
+
+               put_device(dev);
+       } else
+               pr_debug("ACPI: RTC unavailable?\n");
+       return 0;
+}
+/* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */
+fs_initcall(acpi_rtc_init);
+
+#endif
index 57901ca..8fa9312 100644 (file)
@@ -235,6 +235,14 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
                                "While executing method _SST"));
        }
 
+       /*
+        * 1) Disable/Clear all GPEs
+        */
+       status = acpi_hw_disable_all_gpes();
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
        return_ACPI_STATUS(AE_OK);
 }
 
@@ -290,13 +298,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
        }
 
        /*
-        * 1) Disable/Clear all GPEs
         * 2) Enable all wakeup GPEs
         */
-       status = acpi_hw_disable_all_gpes();
-       if (ACPI_FAILURE(status)) {
-               return_ACPI_STATUS(status);
-       }
        acpi_gbl_system_awake_and_running = FALSE;
 
        status = acpi_hw_enable_all_wakeup_gpes();
diff --git a/drivers/acpi/hotkey.c b/drivers/acpi/hotkey.c
deleted file mode 100644 (file)
index 8edfb92..0000000
+++ /dev/null
@@ -1,1042 +0,0 @@
-/*
- *  hotkey.c - ACPI Hotkey Driver ($Revision: 0.2 $)
- *
- *  Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  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/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/sched.h>
-#include <linux/kmod.h>
-#include <linux/seq_file.h>
-#include <acpi/acpi_drivers.h>
-#include <acpi/acpi_bus.h>
-#include <asm/uaccess.h>
-
-#define HOTKEY_ACPI_VERSION "0.1"
-
-#define HOTKEY_PROC "hotkey"
-#define HOTKEY_EV_CONFIG    "event_config"
-#define HOTKEY_PL_CONFIG    "poll_config"
-#define HOTKEY_ACTION   "action"
-#define HOTKEY_INFO "info"
-
-#define ACPI_HOTK_NAME          "Generic Hotkey Driver"
-#define ACPI_HOTK_CLASS         "Hotkey"
-#define ACPI_HOTK_DEVICE_NAME   "Hotkey"
-#define ACPI_HOTK_HID           "Unknown?"
-#define ACPI_HOTKEY_COMPONENT   0x20000000
-
-#define ACPI_HOTKEY_EVENT   0x1
-#define ACPI_HOTKEY_POLLING 0x2
-#define ACPI_UNDEFINED_EVENT    0xf
-
-#define RESULT_STR_LEN     80
-
-#define ACTION_METHOD  0
-#define POLL_METHOD    1
-
-#define IS_EVENT(e)            ((e) <= 10000 && (e) >0)
-#define IS_POLL(e)             ((e) > 10000)
-#define IS_OTHERS(e)           ((e)<=0 || (e)>=20000)
-#define _COMPONENT              ACPI_HOTKEY_COMPONENT
-ACPI_MODULE_NAME("acpi_hotkey")
-
-    MODULE_AUTHOR("luming.yu@intel.com");
-MODULE_DESCRIPTION(ACPI_HOTK_NAME);
-MODULE_LICENSE("GPL");
-
-/*  standardized internal hotkey number/event  */
-enum {
-       /* Video Extension event */
-       HK_EVENT_CYCLE_OUTPUT_DEVICE = 0x80,
-       HK_EVENT_OUTPUT_DEVICE_STATUS_CHANGE,
-       HK_EVENT_CYCLE_DISPLAY_OUTPUT,
-       HK_EVENT_NEXT_DISPLAY_OUTPUT,
-       HK_EVENT_PREVIOUS_DISPLAY_OUTPUT,
-       HK_EVENT_CYCLE_BRIGHTNESS,
-       HK_EVENT_INCREASE_BRIGHTNESS,
-       HK_EVENT_DECREASE_BRIGHTNESS,
-       HK_EVENT_ZERO_BRIGHTNESS,
-       HK_EVENT_DISPLAY_DEVICE_OFF,
-
-       /* Snd Card event */
-       HK_EVENT_VOLUME_MUTE,
-       HK_EVENT_VOLUME_INCLREASE,
-       HK_EVENT_VOLUME_DECREASE,
-
-       /* running state control */
-       HK_EVENT_ENTERRING_S3,
-       HK_EVENT_ENTERRING_S4,
-       HK_EVENT_ENTERRING_S5,
-};
-
-enum conf_entry_enum {
-       bus_handle = 0,
-       bus_method = 1,
-       action_handle = 2,
-       method = 3,
-       LAST_CONF_ENTRY
-};
-
-/*  procdir we use */
-static struct proc_dir_entry *hotkey_proc_dir;
-static struct proc_dir_entry *hotkey_config;
-static struct proc_dir_entry *hotkey_poll_config;
-static struct proc_dir_entry *hotkey_action;
-static struct proc_dir_entry *hotkey_info;
-
-/* linkage for all type of hotkey */
-struct acpi_hotkey_link {
-       struct list_head entries;
-       int hotkey_type;        /* event or polling based hotkey  */
-       int hotkey_standard_num;        /* standardized hotkey(event) number */
-};
-
-/* event based hotkey */
-struct acpi_event_hotkey {
-       struct acpi_hotkey_link hotkey_link;
-       int flag;
-       acpi_handle bus_handle; /* bus to install notify handler */
-       int external_hotkey_num;        /* external hotkey/event number */
-       acpi_handle action_handle;      /* acpi handle attached aml action method */
-       char *action_method;    /* action method */
-};
-
-/*
- * There are two ways to poll status
- * 1. directy call read_xxx method, without any arguments passed in
- * 2. call write_xxx method, with arguments passed in, you need
- * the result is saved in acpi_polling_hotkey.poll_result.
- * anthoer read command through polling interface.
- *
- */
-
-/* polling based hotkey */
-struct acpi_polling_hotkey {
-       struct acpi_hotkey_link hotkey_link;
-       int flag;
-       acpi_handle poll_handle;        /* acpi handle attached polling method */
-       char *poll_method;      /* poll method */
-       acpi_handle action_handle;      /* acpi handle attached action method */
-       char *action_method;    /* action method */
-       union acpi_object *poll_result; /* polling_result */
-       struct proc_dir_entry *proc;
-};
-
-/* hotkey object union */
-union acpi_hotkey {
-       struct list_head entries;
-       struct acpi_hotkey_link link;
-       struct acpi_event_hotkey event_hotkey;
-       struct acpi_polling_hotkey poll_hotkey;
-};
-
-/* hotkey object list */
-struct acpi_hotkey_list {
-       struct list_head *entries;
-       int count;
-};
-
-static int auto_hotkey_add(struct acpi_device *device);
-static int auto_hotkey_remove(struct acpi_device *device, int type);
-
-static struct acpi_driver hotkey_driver = {
-       .name = ACPI_HOTK_NAME,
-       .class = ACPI_HOTK_CLASS,
-       .ids = ACPI_HOTK_HID,
-       .ops = {
-               .add = auto_hotkey_add,
-               .remove = auto_hotkey_remove,
-               },
-};
-
-static void free_hotkey_device(union acpi_hotkey *key);
-static void free_hotkey_buffer(union acpi_hotkey *key);
-static void free_poll_hotkey_buffer(union acpi_hotkey *key);
-static int hotkey_open_config(struct inode *inode, struct file *file);
-static int hotkey_poll_open_config(struct inode *inode, struct file *file);
-static ssize_t hotkey_write_config(struct file *file,
-                                  const char __user * buffer,
-                                  size_t count, loff_t * data);
-static int hotkey_info_open_fs(struct inode *inode, struct file *file);
-static int hotkey_action_open_fs(struct inode *inode, struct file *file);
-static ssize_t hotkey_execute_aml_method(struct file *file,
-                                        const char __user * buffer,
-                                        size_t count, loff_t * data);
-static int hotkey_config_seq_show(struct seq_file *seq, void *offset);
-static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset);
-static int hotkey_polling_open_fs(struct inode *inode, struct file *file);
-static union acpi_hotkey *get_hotkey_by_event(struct
-                                             acpi_hotkey_list
-                                             *hotkey_list, int event);
-
-/* event based config */
-static const struct file_operations hotkey_config_fops = {
-       .open = hotkey_open_config,
-       .read = seq_read,
-       .write = hotkey_write_config,
-       .llseek = seq_lseek,
-       .release = single_release,
-};
-
-/* polling based config */
-static const struct file_operations hotkey_poll_config_fops = {
-       .open = hotkey_poll_open_config,
-       .read = seq_read,
-       .write = hotkey_write_config,
-       .llseek = seq_lseek,
-       .release = single_release,
-};
-
-/* hotkey driver info */
-static const struct file_operations hotkey_info_fops = {
-       .open = hotkey_info_open_fs,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-};
-
-/* action */
-static const struct file_operations hotkey_action_fops = {
-       .open = hotkey_action_open_fs,
-       .read = seq_read,
-       .write = hotkey_execute_aml_method,
-       .llseek = seq_lseek,
-       .release = single_release,
-};
-
-/* polling results */
-static const struct file_operations hotkey_polling_fops = {
-       .open = hotkey_polling_open_fs,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-};
-
-struct acpi_hotkey_list global_hotkey_list;    /* link all ev or pl hotkey  */
-struct list_head hotkey_entries;       /* head of the list of hotkey_list */
-
-static int hotkey_info_seq_show(struct seq_file *seq, void *offset)
-{
-
-       seq_printf(seq, "Hotkey generic driver ver: %s\n", HOTKEY_ACPI_VERSION);
-
-       return 0;
-}
-
-static int hotkey_info_open_fs(struct inode *inode, struct file *file)
-{
-       return single_open(file, hotkey_info_seq_show, PDE(inode)->data);
-}
-
-static char *format_result(union acpi_object *object)
-{
-       char *buf;
-
-       buf = kzalloc(RESULT_STR_LEN, GFP_KERNEL);
-       if (!buf)
-               return NULL;
-       /* Now, just support integer type */
-       if (object->type == ACPI_TYPE_INTEGER)
-               sprintf(buf, "%d\n", (u32) object->integer.value);
-       return buf;
-}
-
-static int hotkey_polling_seq_show(struct seq_file *seq, void *offset)
-{
-       struct acpi_polling_hotkey *poll_hotkey = seq->private;
-       char *buf;
-
-
-       if (poll_hotkey->poll_result) {
-               buf = format_result(poll_hotkey->poll_result);
-               if (buf)
-                       seq_printf(seq, "%s", buf);
-               kfree(buf);
-       }
-       return 0;
-}
-
-static int hotkey_polling_open_fs(struct inode *inode, struct file *file)
-{
-       return single_open(file, hotkey_polling_seq_show, PDE(inode)->data);
-}
-
-static int hotkey_action_open_fs(struct inode *inode, struct file *file)
-{
-       return single_open(file, hotkey_info_seq_show, PDE(inode)->data);
-}
-
-/* Mapping external hotkey number to standardized hotkey event num */
-static int hotkey_get_internal_event(int event, struct acpi_hotkey_list *list)
-{
-       struct list_head *entries;
-       int val = -1;
-
-
-       list_for_each(entries, list->entries) {
-               union acpi_hotkey *key =
-                   container_of(entries, union acpi_hotkey, entries);
-               if (key->link.hotkey_type == ACPI_HOTKEY_EVENT
-                   && key->event_hotkey.external_hotkey_num == event) {
-                       val = key->link.hotkey_standard_num;
-                       break;
-               }
-       }
-
-       return val;
-}
-
-static void
-acpi_hotkey_notify_handler(acpi_handle handle, u32 event, void *data)
-{
-       struct acpi_device *device = NULL;
-       u32 internal_event;
-
-
-       if (acpi_bus_get_device(handle, &device))
-               return;
-
-       internal_event = hotkey_get_internal_event(event, &global_hotkey_list);
-       acpi_bus_generate_event(device, internal_event, 0);
-
-       return;
-}
-
-/* Need to invent automatically hotkey add method */
-static int auto_hotkey_add(struct acpi_device *device)
-{
-       /* Implement me */
-       return 0;
-}
-
-/* Need to invent automatically hotkey remove method */
-static int auto_hotkey_remove(struct acpi_device *device, int type)
-{
-       /* Implement me */
-       return 0;
-}
-
-/* Create a proc file for each polling method */
-static int create_polling_proc(union acpi_hotkey *device)
-{
-       struct proc_dir_entry *proc;
-       char proc_name[80];
-       mode_t mode;
-
-       mode = S_IFREG | S_IRUGO | S_IWUGO;
-
-       sprintf(proc_name, "%d", device->link.hotkey_standard_num);
-       /*
-          strcat(proc_name, device->poll_hotkey.poll_method);
-        */
-       proc = create_proc_entry(proc_name, mode, hotkey_proc_dir);
-
-       if (!proc) {
-               return -ENODEV;
-       } else {
-               proc->proc_fops = &hotkey_polling_fops;
-               proc->owner = THIS_MODULE;
-               proc->data = device;
-               proc->uid = 0;
-               proc->gid = 0;
-               device->poll_hotkey.proc = proc;
-       }
-       return 0;
-}
-
-static int hotkey_add(union acpi_hotkey *device)
-{
-       int status = 0;
-       struct acpi_device *dev = NULL;
-
-
-       if (device->link.hotkey_type == ACPI_HOTKEY_EVENT) {
-               acpi_bus_get_device(device->event_hotkey.bus_handle, &dev);
-               status = acpi_install_notify_handler(dev->handle,
-                                                    ACPI_DEVICE_NOTIFY,
-                                                    acpi_hotkey_notify_handler,
-                                                    dev);
-       } else                  /* Add polling hotkey */
-               create_polling_proc(device);
-
-       global_hotkey_list.count++;
-
-       list_add_tail(&device->link.entries, global_hotkey_list.entries);
-
-       return status;
-}
-
-static int hotkey_remove(union acpi_hotkey *device)
-{
-       struct list_head *entries, *next;
-
-
-       list_for_each_safe(entries, next, global_hotkey_list.entries) {
-               union acpi_hotkey *key =
-                   container_of(entries, union acpi_hotkey, entries);
-               if (key->link.hotkey_standard_num ==
-                   device->link.hotkey_standard_num) {
-                       list_del(&key->link.entries);
-                       free_hotkey_device(key);
-                       global_hotkey_list.count--;
-                       break;
-               }
-       }
-       kfree(device);
-       return 0;
-}
-
-static int hotkey_update(union acpi_hotkey *key)
-{
-       struct list_head *entries;
-
-
-       list_for_each(entries, global_hotkey_list.entries) {
-               union acpi_hotkey *tmp =
-                   container_of(entries, union acpi_hotkey, entries);
-               if (tmp->link.hotkey_standard_num ==
-                   key->link.hotkey_standard_num) {
-                       if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
-                               free_hotkey_buffer(tmp);
-                               tmp->event_hotkey.bus_handle =
-                                   key->event_hotkey.bus_handle;
-                               tmp->event_hotkey.external_hotkey_num =
-                                   key->event_hotkey.external_hotkey_num;
-                               tmp->event_hotkey.action_handle =
-                                   key->event_hotkey.action_handle;
-                               tmp->event_hotkey.action_method =
-                                   key->event_hotkey.action_method;
-                               kfree(key);
-                       } else {
-                               /*
-                                  char  proc_name[80];
-
-                                  sprintf(proc_name, "%d", tmp->link.hotkey_standard_num);
-                                  strcat(proc_name, tmp->poll_hotkey.poll_method);
-                                  remove_proc_entry(proc_name,hotkey_proc_dir);
-                                */
-                               free_poll_hotkey_buffer(tmp);
-                               tmp->poll_hotkey.poll_handle =
-                                   key->poll_hotkey.poll_handle;
-                               tmp->poll_hotkey.poll_method =
-                                   key->poll_hotkey.poll_method;
-                               tmp->poll_hotkey.action_handle =
-                                   key->poll_hotkey.action_handle;
-                               tmp->poll_hotkey.action_method =
-                                   key->poll_hotkey.action_method;
-                               tmp->poll_hotkey.poll_result =
-                                   key->poll_hotkey.poll_result;
-                               /*
-                                  create_polling_proc(tmp);
-                                */
-                               kfree(key);
-                       }
-                       return 0;
-                       break;
-               }
-       }
-
-       return -ENODEV;
-}
-
-static void free_hotkey_device(union acpi_hotkey *key)
-{
-       struct acpi_device *dev;
-
-
-       if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
-               acpi_bus_get_device(key->event_hotkey.bus_handle, &dev);
-               if (dev->handle)
-                       acpi_remove_notify_handler(dev->handle,
-                                                  ACPI_DEVICE_NOTIFY,
-                                                  acpi_hotkey_notify_handler);
-               free_hotkey_buffer(key);
-       } else {
-               char proc_name[80];
-
-               sprintf(proc_name, "%d", key->link.hotkey_standard_num);
-               /*
-                  strcat(proc_name, key->poll_hotkey.poll_method);
-                */
-               remove_proc_entry(proc_name, hotkey_proc_dir);
-               free_poll_hotkey_buffer(key);
-       }
-       kfree(key);
-       return;
-}
-
-static void free_hotkey_buffer(union acpi_hotkey *key)
-{
-       /* key would never be null, action method could be */
-       kfree(key->event_hotkey.action_method);
-}
-
-static void free_poll_hotkey_buffer(union acpi_hotkey *key)
-{
-       /* key would never be null, others could be*/
-       kfree(key->poll_hotkey.action_method);
-       kfree(key->poll_hotkey.poll_method);
-       kfree(key->poll_hotkey.poll_result);
-}
-static int
-init_hotkey_device(union acpi_hotkey *key, char **config_entry,
-                  int std_num, int external_num)
-{
-       acpi_handle tmp_handle;
-       acpi_status status = AE_OK;
-
-       if (std_num < 0 || IS_POLL(std_num) || !key)
-               goto do_fail;
-
-       if (!config_entry[bus_handle] || !config_entry[action_handle]
-                       || !config_entry[method])
-               goto do_fail;
-
-       key->link.hotkey_type = ACPI_HOTKEY_EVENT;
-       key->link.hotkey_standard_num = std_num;
-       key->event_hotkey.flag = 0;
-       key->event_hotkey.action_method = config_entry[method];
-
-       status = acpi_get_handle(NULL, config_entry[bus_handle],
-                          &(key->event_hotkey.bus_handle));
-       if (ACPI_FAILURE(status))
-               goto do_fail_zero;
-       key->event_hotkey.external_hotkey_num = external_num;
-       status = acpi_get_handle(NULL, config_entry[action_handle],
-                           &(key->event_hotkey.action_handle));
-       if (ACPI_FAILURE(status))
-               goto do_fail_zero;
-       status = acpi_get_handle(key->event_hotkey.action_handle,
-                                config_entry[method], &tmp_handle);
-       if (ACPI_FAILURE(status))
-               goto do_fail_zero;
-       return AE_OK;
-do_fail_zero:
-       key->event_hotkey.action_method = NULL;
-do_fail:
-       return -ENODEV;
-}
-
-static int
-init_poll_hotkey_device(union acpi_hotkey *key, char **config_entry,
-                       int std_num)
-{
-       acpi_status status = AE_OK;
-       acpi_handle tmp_handle;
-
-       if (std_num < 0 || IS_EVENT(std_num) || !key)
-               goto do_fail;
-       if (!config_entry[bus_handle] ||!config_entry[bus_method] ||
-               !config_entry[action_handle] || !config_entry[method])
-               goto do_fail;
-
-       key->link.hotkey_type = ACPI_HOTKEY_POLLING;
-       key->link.hotkey_standard_num = std_num;
-       key->poll_hotkey.flag = 0;
-       key->poll_hotkey.poll_method = config_entry[bus_method];
-       key->poll_hotkey.action_method = config_entry[method];
-
-       status = acpi_get_handle(NULL, config_entry[bus_handle],
-                     &(key->poll_hotkey.poll_handle));
-       if (ACPI_FAILURE(status))
-               goto do_fail_zero;
-       status = acpi_get_handle(key->poll_hotkey.poll_handle,
-                                config_entry[bus_method], &tmp_handle);
-       if (ACPI_FAILURE(status))
-               goto do_fail_zero;
-       status =
-           acpi_get_handle(NULL, config_entry[action_handle],
-                           &(key->poll_hotkey.action_handle));
-       if (ACPI_FAILURE(status))
-               goto do_fail_zero;
-       status = acpi_get_handle(key->poll_hotkey.action_handle,
-                                config_entry[method], &tmp_handle);
-       if (ACPI_FAILURE(status))
-               goto do_fail_zero;
-       key->poll_hotkey.poll_result =
-           kmalloc(sizeof(union acpi_object), GFP_KERNEL);
-       if (!key->poll_hotkey.poll_result)
-               goto do_fail_zero;
-       return AE_OK;
-
-do_fail_zero:
-       key->poll_hotkey.poll_method = NULL;
-       key->poll_hotkey.action_method = NULL;
-do_fail:
-       return -ENODEV;
-}
-
-static int hotkey_open_config(struct inode *inode, struct file *file)
-{
-       return (single_open
-                    (file, hotkey_config_seq_show, PDE(inode)->data));
-}
-
-static int hotkey_poll_open_config(struct inode *inode, struct file *file)
-{
-       return (single_open
-                    (file, hotkey_poll_config_seq_show, PDE(inode)->data));
-}
-
-static int hotkey_config_seq_show(struct seq_file *seq, void *offset)
-{
-       struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
-       struct list_head *entries;
-       char bus_name[ACPI_PATHNAME_MAX] = { 0 };
-       char action_name[ACPI_PATHNAME_MAX] = { 0 };
-       struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
-       struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name };
-
-
-       list_for_each(entries, hotkey_list->entries) {
-               union acpi_hotkey *key =
-                   container_of(entries, union acpi_hotkey, entries);
-               if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
-                       acpi_get_name(key->event_hotkey.bus_handle,
-                                     ACPI_NAME_TYPE_MAX, &bus);
-                       acpi_get_name(key->event_hotkey.action_handle,
-                                     ACPI_NAME_TYPE_MAX, &act);
-                       seq_printf(seq, "%s:%s:%s:%d:%d\n", bus_name,
-                                  action_name,
-                                  key->event_hotkey.action_method,
-                                  key->link.hotkey_standard_num,
-                                  key->event_hotkey.external_hotkey_num);
-               }
-       }
-       seq_puts(seq, "\n");
-       return 0;
-}
-
-static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset)
-{
-       struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
-       struct list_head *entries;
-       char bus_name[ACPI_PATHNAME_MAX] = { 0 };
-       char action_name[ACPI_PATHNAME_MAX] = { 0 };
-       struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
-       struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name };
-
-
-       list_for_each(entries, hotkey_list->entries) {
-               union acpi_hotkey *key =
-                   container_of(entries, union acpi_hotkey, entries);
-               if (key->link.hotkey_type == ACPI_HOTKEY_POLLING) {
-                       acpi_get_name(key->poll_hotkey.poll_handle,
-                                     ACPI_NAME_TYPE_MAX, &bus);
-                       acpi_get_name(key->poll_hotkey.action_handle,
-                                     ACPI_NAME_TYPE_MAX, &act);
-                       seq_printf(seq, "%s:%s:%s:%s:%d\n", bus_name,
-                                  key->poll_hotkey.poll_method,
-                                  action_name,
-                                  key->poll_hotkey.action_method,
-                                  key->link.hotkey_standard_num);
-               }
-       }
-       seq_puts(seq, "\n");
-       return 0;
-}
-
-static int
-get_parms(char *config_record, int *cmd, char **config_entry,
-              int *internal_event_num, int *external_event_num)
-{
-/* the format of *config_record =
- * "1:\d+:*" : "cmd:internal_event_num"
- * "\d+:\w+:\w+:\w+:\w+:\d+:\d+" :
- * "cmd:bus_handle:bus_method:action_handle:method:internal_event_num:external_event_num"
- */
-       char *tmp, *tmp1, count;
-       int i;
-
-       sscanf(config_record, "%d", cmd);
-       if (*cmd == 1) {
-               if (sscanf(config_record, "%d:%d", cmd, internal_event_num) !=
-                   2)
-                       goto do_fail;
-               else
-                       return (6);
-       }
-       tmp = strchr(config_record, ':');
-       if (!tmp)
-               goto do_fail;
-       tmp++;
-       for (i = 0; i < LAST_CONF_ENTRY; i++) {
-               tmp1 = strchr(tmp, ':');
-               if (!tmp1) {
-                       goto do_fail;
-               }
-               count = tmp1 - tmp;
-               config_entry[i] = kzalloc(count + 1, GFP_KERNEL);
-               if (!config_entry[i])
-                       goto handle_failure;
-               strncpy(config_entry[i], tmp, count);
-               tmp = tmp1 + 1;
-       }
-       if (sscanf(tmp, "%d:%d", internal_event_num, external_event_num) <= 0)
-               goto handle_failure;
-       if (!IS_OTHERS(*internal_event_num)) {
-               return 6;
-       }
-handle_failure:
-       while (i-- > 0)
-               kfree(config_entry[i]);
-do_fail:
-       return -1;
-}
-
-/*  count is length for one input record */
-static ssize_t hotkey_write_config(struct file *file,
-                                  const char __user * buffer,
-                                  size_t count, loff_t * data)
-{
-       char *config_record = NULL;
-       char *config_entry[LAST_CONF_ENTRY];
-       int cmd, internal_event_num, external_event_num;
-       int ret = 0;
-       union acpi_hotkey *key = kzalloc(sizeof(union acpi_hotkey), GFP_KERNEL);
-
-       if (!key)
-               return -ENOMEM;
-
-       config_record = kzalloc(count + 1, GFP_KERNEL);
-       if (!config_record) {
-               kfree(key);
-               return -ENOMEM;
-       }
-
-       if (copy_from_user(config_record, buffer, count)) {
-               kfree(config_record);
-               kfree(key);
-               printk(KERN_ERR PREFIX "Invalid data\n");
-               return -EINVAL;
-       }
-       ret = get_parms(config_record, &cmd, config_entry,
-                      &internal_event_num, &external_event_num);
-       kfree(config_record);
-       if (ret != 6) {
-               printk(KERN_ERR PREFIX "Invalid data format ret=%d\n", ret);
-               return -EINVAL;
-       }
-
-       if (cmd == 1) {
-               union acpi_hotkey *tmp = NULL;
-               tmp = get_hotkey_by_event(&global_hotkey_list,
-                                         internal_event_num);
-               if (!tmp)
-                       printk(KERN_ERR PREFIX "Invalid key\n");
-               else
-                       memcpy(key, tmp, sizeof(union acpi_hotkey));
-               goto cont_cmd;
-       }
-       if (IS_EVENT(internal_event_num)) {
-               if (init_hotkey_device(key, config_entry,
-                       internal_event_num, external_event_num))
-                       goto init_hotkey_fail;
-       } else {
-               if (init_poll_hotkey_device(key, config_entry,
-                              internal_event_num))
-                       goto init_poll_hotkey_fail;
-       }
-cont_cmd:
-       switch (cmd) {
-       case 0:
-               if (get_hotkey_by_event(&global_hotkey_list,
-                               key->link.hotkey_standard_num))
-                       goto fail_out;
-               else
-                       hotkey_add(key);
-               break;
-       case 1:
-               hotkey_remove(key);
-               break;
-       case 2:
-               /* key is kfree()ed if matched*/
-               if (hotkey_update(key))
-                       goto fail_out;
-               break;
-       default:
-               goto fail_out;
-               break;
-       }
-       return count;
-
-init_poll_hotkey_fail:         /* failed init_poll_hotkey_device */
-       kfree(config_entry[bus_method]);
-       config_entry[bus_method] = NULL;
-init_hotkey_fail:              /* failed init_hotkey_device */
-       kfree(config_entry[method]);
-fail_out:
-       kfree(config_entry[bus_handle]);
-       kfree(config_entry[action_handle]);
-       /* No double free since elements =NULL for error cases */
-       if (IS_EVENT(internal_event_num)) {
-               if (config_entry[bus_method])
-                       kfree(config_entry[bus_method]);
-               free_hotkey_buffer(key);        /* frees [method] */
-       } else
-               free_poll_hotkey_buffer(key);  /* frees [bus_method]+[method] */
-       kfree(key);
-       printk(KERN_ERR PREFIX "invalid key\n");
-       return -EINVAL;
-}
-
-/*
- * This function evaluates an ACPI method, given an int as parameter, the
- * method is searched within the scope of the handle, can be NULL. The output
- * of the method is written is output, which can also be NULL
- *
- * returns 1 if write is successful, 0 else.
- */
-static int write_acpi_int(acpi_handle handle, const char *method, int val,
-                         struct acpi_buffer *output)
-{
-       struct acpi_object_list params; /* list of input parameters (an int here) */
-       union acpi_object in_obj;       /* the only param we use */
-       acpi_status status;
-
-       params.count = 1;
-       params.pointer = &in_obj;
-       in_obj.type = ACPI_TYPE_INTEGER;
-       in_obj.integer.value = val;
-
-       status = acpi_evaluate_object(handle, (char *)method, &params, output);
-
-       return (status == AE_OK);
-}
-
-static int read_acpi_int(acpi_handle handle, const char *method,
-                        union acpi_object *val)
-{
-       struct acpi_buffer output;
-       union acpi_object out_obj;
-       acpi_status status;
-
-       output.length = sizeof(out_obj);
-       output.pointer = &out_obj;
-
-       status = acpi_evaluate_object(handle, (char *)method, NULL, &output);
-       if (val) {
-               val->integer.value = out_obj.integer.value;
-               val->type = out_obj.type;
-       } else
-               printk(KERN_ERR PREFIX "null val pointer\n");
-       return ((status == AE_OK)
-                    && (out_obj.type == ACPI_TYPE_INTEGER));
-}
-
-static union acpi_hotkey *get_hotkey_by_event(struct
-                                             acpi_hotkey_list
-                                             *hotkey_list, int event)
-{
-       struct list_head *entries;
-
-       list_for_each(entries, hotkey_list->entries) {
-               union acpi_hotkey *key =
-                   container_of(entries, union acpi_hotkey, entries);
-               if (key->link.hotkey_standard_num == event) {
-                       return (key);
-               }
-       }
-       return (NULL);
-}
-
-/*
- * user call AML method interface:
- * Call convention:
- * echo "event_num: arg type : value"
- * example: echo "1:1:30" > /proc/acpi/action
- * Just support 1 integer arg passing to AML method
- */
-
-static ssize_t hotkey_execute_aml_method(struct file *file,
-                                        const char __user * buffer,
-                                        size_t count, loff_t * data)
-{
-       struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
-       char *arg;
-       int event, method_type, type, value;
-       union acpi_hotkey *key;
-
-
-       arg = kzalloc(count + 1, GFP_KERNEL);
-       if (!arg)
-               return -ENOMEM;
-
-       if (copy_from_user(arg, buffer, count)) {
-               kfree(arg);
-               printk(KERN_ERR PREFIX "Invalid argument 2\n");
-               return -EINVAL;
-       }
-
-       if (sscanf(arg, "%d:%d:%d:%d", &event, &method_type, &type, &value) !=
-           4) {
-               kfree(arg);
-               printk(KERN_ERR PREFIX "Invalid argument 3\n");
-               return -EINVAL;
-       }
-       kfree(arg);
-       if (type == ACPI_TYPE_INTEGER) {
-               key = get_hotkey_by_event(hotkey_list, event);
-               if (!key)
-                       goto do_fail;
-               if (IS_EVENT(event))
-                       write_acpi_int(key->event_hotkey.action_handle,
-                                      key->event_hotkey.action_method, value,
-                                      NULL);
-               else if (IS_POLL(event)) {
-                       if (method_type == POLL_METHOD)
-                               read_acpi_int(key->poll_hotkey.poll_handle,
-                                             key->poll_hotkey.poll_method,
-                                             key->poll_hotkey.poll_result);
-                       else if (method_type == ACTION_METHOD)
-                               write_acpi_int(key->poll_hotkey.action_handle,
-                                              key->poll_hotkey.action_method,
-                                              value, NULL);
-                       else
-                               goto do_fail;
-
-               }
-       } else {
-               printk(KERN_WARNING "Not supported\n");
-               return -EINVAL;
-       }
-       return count;
-      do_fail:
-       return -EINVAL;
-
-}
-
-static int __init hotkey_init(void)
-{
-       int result;
-       mode_t mode = S_IFREG | S_IRUGO | S_IWUGO;
-
-
-       if (acpi_disabled)
-               return -ENODEV;
-
-       if (acpi_specific_hotkey_enabled) {
-               printk("Using specific hotkey driver\n");
-               return -ENODEV;
-       }
-
-       hotkey_proc_dir = proc_mkdir(HOTKEY_PROC, acpi_root_dir);
-       if (!hotkey_proc_dir) {
-               return (-ENODEV);
-       }
-       hotkey_proc_dir->owner = THIS_MODULE;
-
-       hotkey_config =
-           create_proc_entry(HOTKEY_EV_CONFIG, mode, hotkey_proc_dir);
-       if (!hotkey_config) {
-               goto do_fail1;
-       } else {
-               hotkey_config->proc_fops = &hotkey_config_fops;
-               hotkey_config->data = &global_hotkey_list;
-               hotkey_config->owner = THIS_MODULE;
-               hotkey_config->uid = 0;
-               hotkey_config->gid = 0;
-       }
-
-       hotkey_poll_config =
-           create_proc_entry(HOTKEY_PL_CONFIG, mode, hotkey_proc_dir);
-       if (!hotkey_poll_config) {
-               goto do_fail2;
-       } else {
-               hotkey_poll_config->proc_fops = &hotkey_poll_config_fops;
-               hotkey_poll_config->data = &global_hotkey_list;
-               hotkey_poll_config->owner = THIS_MODULE;
-               hotkey_poll_config->uid = 0;
-               hotkey_poll_config->gid = 0;
-       }
-
-       hotkey_action = create_proc_entry(HOTKEY_ACTION, mode, hotkey_proc_dir);
-       if (!hotkey_action) {
-               goto do_fail3;
-       } else {
-               hotkey_action->proc_fops = &hotkey_action_fops;
-               hotkey_action->owner = THIS_MODULE;
-               hotkey_action->uid = 0;
-               hotkey_action->gid = 0;
-       }
-
-       hotkey_info = create_proc_entry(HOTKEY_INFO, mode, hotkey_proc_dir);
-       if (!hotkey_info) {
-               goto do_fail4;
-       } else {
-               hotkey_info->proc_fops = &hotkey_info_fops;
-               hotkey_info->owner = THIS_MODULE;
-               hotkey_info->uid = 0;
-               hotkey_info->gid = 0;
-       }
-
-       result = acpi_bus_register_driver(&hotkey_driver);
-       if (result < 0)
-               goto do_fail5;
-       global_hotkey_list.count = 0;
-       global_hotkey_list.entries = &hotkey_entries;
-
-       INIT_LIST_HEAD(&hotkey_entries);
-
-       return (0);
-
-      do_fail5:
-       remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir);
-      do_fail4:
-       remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir);
-      do_fail3:
-       remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir);
-      do_fail2:
-       remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir);
-      do_fail1:
-       remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
-       return (-ENODEV);
-}
-
-static void __exit hotkey_exit(void)
-{
-       struct list_head *entries, *next;
-
-
-       list_for_each_safe(entries, next, global_hotkey_list.entries) {
-               union acpi_hotkey *key =
-                   container_of(entries, union acpi_hotkey, entries);
-
-               acpi_os_wait_events_complete(NULL);
-               list_del(&key->link.entries);
-               global_hotkey_list.count--;
-               free_hotkey_device(key);
-       }
-       acpi_bus_unregister_driver(&hotkey_driver);
-       remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir);
-       remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir);
-       remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir);
-       remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir);
-       remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
-       return;
-}
-
-module_init(hotkey_init);
-module_exit(hotkey_exit);
index 76ec8b6..acab4a4 100644 (file)
 #define ACPI_EC_HC_COMPONENT   0x00080000
 #define ACPI_EC_HC_CLASS       "ec_hc_smbus"
 #define ACPI_EC_HC_HID         "ACPI0001"
-#define ACPI_EC_HC_DRIVER_NAME "ACPI EC HC smbus driver"
 #define ACPI_EC_HC_DEVICE_NAME "EC HC smbus"
 
 #define _COMPONENT             ACPI_EC_HC_COMPONENT
 
-ACPI_MODULE_NAME("acpi_smbus")
+ACPI_MODULE_NAME("i2c_ec");
 
 static int acpi_ec_hc_add(struct acpi_device *device);
 static int acpi_ec_hc_remove(struct acpi_device *device, int type);
 
 static struct acpi_driver acpi_ec_hc_driver = {
-       .name = ACPI_EC_HC_DRIVER_NAME,
+       .name = "i2c_ec",
        .class = ACPI_EC_HC_CLASS,
        .ids = ACPI_EC_HC_HID,
        .ops = {
index c6144ca..1a0ed3d 100644 (file)
@@ -496,6 +496,10 @@ static int ibm_acpi_driver_init(void)
        printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
        printk(IBM_INFO "%s\n", IBM_URL);
 
+       if (ibm_thinkpad_ec_found)
+               printk(IBM_INFO "ThinkPad EC firmware %s\n",
+                      ibm_thinkpad_ec_found);
+
        return 0;
 }
 
@@ -2617,7 +2621,7 @@ static void __init ibm_handle_init(char *name,
        ibm_handle_init(#object, &object##_handle, *object##_parent,    \
                object##_paths, ARRAY_SIZE(object##_paths), &object##_path)
 
-static int set_ibm_param(const char *val, struct kernel_param *kp)
+static int __init set_ibm_param(const char *val, struct kernel_param *kp)
 {
        unsigned int i;
 
@@ -2659,7 +2663,8 @@ static void acpi_ibm_exit(void)
        for (i = ARRAY_SIZE(ibms) - 1; i >= 0; i--)
                ibm_exit(&ibms[i]);
 
-       remove_proc_entry(IBM_DIR, acpi_root_dir);
+       if (proc_dir)
+               remove_proc_entry(IBM_DIR, acpi_root_dir);
 
        if (ibm_thinkpad_ec_found)
                kfree(ibm_thinkpad_ec_found);
@@ -2696,11 +2701,6 @@ static int __init acpi_ibm_init(void)
        if (acpi_disabled)
                return -ENODEV;
 
-       if (!acpi_specific_hotkey_enabled) {
-               printk(IBM_ERR "using generic hotkey driver\n");
-               return -ENODEV;
-       }
-
        /* ec is required because many other handles are relative to it */
        IBM_HANDLE_INIT(ec);
        if (!ec_handle) {
@@ -2710,9 +2710,6 @@ static int __init acpi_ibm_init(void)
 
        /* Models with newer firmware report the EC in DMI */
        ibm_thinkpad_ec_found = check_dmi_for_ec();
-       if (ibm_thinkpad_ec_found)
-               printk(IBM_INFO "ThinkPad EC firmware %s\n",
-                      ibm_thinkpad_ec_found);
 
        /* these handles are not required */
        IBM_HANDLE_INIT(vid);
@@ -2742,6 +2739,7 @@ static int __init acpi_ibm_init(void)
        proc_dir = proc_mkdir(IBM_DIR, acpi_root_dir);
        if (!proc_dir) {
                printk(IBM_ERR "unable to create proc dir %s", IBM_DIR);
+               acpi_ibm_exit();
                return -ENODEV;
        }
        proc_dir->owner = THIS_MODULE;
index 4a9faff..8fcd6a1 100644 (file)
@@ -33,7 +33,7 @@
 
 #define ACPI_NUMA      0x80000000
 #define _COMPONENT     ACPI_NUMA
-ACPI_MODULE_NAME("numa")
+ACPI_MODULE_NAME("numa");
 
 static nodemask_t nodes_found_map = NODE_MASK_NONE;
 #define PXM_INVAL      -1
@@ -45,12 +45,6 @@ int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS]
 int __cpuinitdata node_to_pxm_map[MAX_NUMNODES]
                                = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
 
-extern int __init acpi_table_parse_madt_family(char *id,
-                                              unsigned long madt_size,
-                                              int entry_id,
-                                              acpi_madt_entry_handler handler,
-                                              unsigned int max_entries);
-
 int __cpuinit pxm_to_node(int pxm)
 {
        if (pxm < 0)
@@ -208,9 +202,9 @@ static int __init acpi_parse_srat(struct acpi_table_header *table)
 
 int __init
 acpi_table_parse_srat(enum acpi_srat_type id,
-                     acpi_madt_entry_handler handler, unsigned int max_entries)
+                     acpi_table_entry_handler handler, unsigned int max_entries)
 {
-       return acpi_table_parse_madt_family(ACPI_SIG_SRAT,
+       return acpi_table_parse_entries(ACPI_SIG_SRAT,
                                            sizeof(struct acpi_table_srat), id,
                                            handler, max_entries);
 }
@@ -220,9 +214,7 @@ int __init acpi_numa_init(void)
        int result;
 
        /* SRAT: Static Resource Affinity Table */
-       result = acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat);
-
-       if (result > 0) {
+       if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
                result = acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
                                               acpi_parse_processor_affinity,
                                               NR_CPUS);
@@ -230,7 +222,7 @@ int __init acpi_numa_init(void)
        }
 
        /* SLIT: System Locality Information Table */
-       result = acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
+       acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
 
        acpi_numa_arch_fixup();
        return 0;
index 0f6f3bc..971eca4 100644 (file)
@@ -46,7 +46,7 @@
 #include <linux/efi.h>
 
 #define _COMPONENT             ACPI_OS_SERVICES
-ACPI_MODULE_NAME("osl")
+ACPI_MODULE_NAME("osl");
 #define PREFIX         "ACPI: "
 struct acpi_os_dpc {
        acpi_osd_exec_callback function;
@@ -68,9 +68,6 @@ EXPORT_SYMBOL(acpi_in_debugger);
 extern char line_buf[80];
 #endif                         /*ENABLE_DEBUGGER */
 
-int acpi_specific_hotkey_enabled = TRUE;
-EXPORT_SYMBOL(acpi_specific_hotkey_enabled);
-
 static unsigned int acpi_irq_irq;
 static acpi_osd_handler acpi_irq_handler;
 static void *acpi_irq_context;
@@ -205,7 +202,7 @@ void __iomem *acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
 {
        if (phys > ULONG_MAX) {
                printk(KERN_ERR PREFIX "Cannot map memory that high\n");
-               return 0;
+               return NULL;
        }
        if (acpi_gbl_permanent_mmap)
                /*
@@ -890,26 +887,6 @@ u32 acpi_os_get_line(char *buffer)
 }
 #endif                         /*  ACPI_FUTURE_USAGE  */
 
-/* Assumes no unreadable holes inbetween */
-u8 acpi_os_readable(void *ptr, acpi_size len)
-{
-#if defined(__i386__) || defined(__x86_64__)
-       char tmp;
-       return !__get_user(tmp, (char __user *)ptr)
-           && !__get_user(tmp, (char __user *)ptr + len - 1);
-#endif
-       return 1;
-}
-
-#ifdef ACPI_FUTURE_USAGE
-u8 acpi_os_writable(void *ptr, acpi_size len)
-{
-       /* could do dummy write (racy) or a kernel page table lookup.
-          The later may be difficult at early boot when kmap doesn't work yet. */
-       return 1;
-}
-#endif
-
 acpi_status acpi_os_signal(u32 function, void *info)
 {
        switch (function) {
@@ -1012,14 +989,6 @@ static int __init acpi_wake_gpes_always_on_setup(char *str)
 
 __setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
 
-static int __init acpi_hotkey_setup(char *str)
-{
-       acpi_specific_hotkey_enabled = FALSE;
-       return 1;
-}
-
-__setup("acpi_generic_hotkey", acpi_hotkey_setup);
-
 /*
  * max_cstate is defined in the base kernel so modules can
  * change it w/o depending on the state of the processor module.
index 55f57a6..0289693 100644 (file)
@@ -36,7 +36,7 @@
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT             ACPI_PCI_COMPONENT
-ACPI_MODULE_NAME("pci_bind")
+ACPI_MODULE_NAME("pci_bind");
 
 struct acpi_pci_data {
        struct acpi_pci_id id;
index fe7d007..dd3186a 100644 (file)
@@ -38,7 +38,7 @@
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT             ACPI_PCI_COMPONENT
-ACPI_MODULE_NAME("pci_irq")
+ACPI_MODULE_NAME("pci_irq");
 
 static struct acpi_prt_list acpi_prt;
 static DEFINE_SPINLOCK(acpi_prt_lock);
index 0f683c8..acc5947 100644 (file)
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT             ACPI_PCI_COMPONENT
-ACPI_MODULE_NAME("pci_link")
+ACPI_MODULE_NAME("pci_link");
 #define ACPI_PCI_LINK_CLASS            "pci_irq_routing"
 #define ACPI_PCI_LINK_HID              "PNP0C0F"
-#define ACPI_PCI_LINK_DRIVER_NAME      "ACPI PCI Interrupt Link Driver"
 #define ACPI_PCI_LINK_DEVICE_NAME      "PCI Interrupt Link"
 #define ACPI_PCI_LINK_FILE_INFO                "info"
 #define ACPI_PCI_LINK_FILE_STATUS      "state"
@@ -56,7 +55,7 @@ static int acpi_pci_link_add(struct acpi_device *device);
 static int acpi_pci_link_remove(struct acpi_device *device, int type);
 
 static struct acpi_driver acpi_pci_link_driver = {
-       .name = ACPI_PCI_LINK_DRIVER_NAME,
+       .name = "pci_link",
        .class = ACPI_PCI_LINK_CLASS,
        .ids = ACPI_PCI_LINK_HID,
        .ops = {
index 4ecf701..ad4145a 100644 (file)
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT             ACPI_PCI_COMPONENT
-ACPI_MODULE_NAME("pci_root")
+ACPI_MODULE_NAME("pci_root");
 #define ACPI_PCI_ROOT_CLASS            "pci_bridge"
 #define ACPI_PCI_ROOT_HID              "PNP0A03"
-#define ACPI_PCI_ROOT_DRIVER_NAME      "ACPI PCI Root Bridge Driver"
 #define ACPI_PCI_ROOT_DEVICE_NAME      "PCI Root Bridge"
 static int acpi_pci_root_add(struct acpi_device *device);
 static int acpi_pci_root_remove(struct acpi_device *device, int type);
 static int acpi_pci_root_start(struct acpi_device *device);
 
 static struct acpi_driver acpi_pci_root_driver = {
-       .name = ACPI_PCI_ROOT_DRIVER_NAME,
+       .name = "pci_root",
        .class = ACPI_PCI_ROOT_CLASS,
        .ids = ACPI_PCI_ROOT_HID,
        .ops = {
index 0ba7dfb..1ef3385 100644 (file)
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT             ACPI_POWER_COMPONENT
-ACPI_MODULE_NAME("acpi_power")
+ACPI_MODULE_NAME("power");
 #define ACPI_POWER_COMPONENT           0x00800000
 #define ACPI_POWER_CLASS               "power_resource"
-#define ACPI_POWER_DRIVER_NAME         "ACPI Power Resource Driver"
 #define ACPI_POWER_DEVICE_NAME         "Power Resource"
 #define ACPI_POWER_FILE_INFO           "info"
 #define ACPI_POWER_FILE_STATUS         "state"
@@ -57,25 +56,33 @@ ACPI_MODULE_NAME("acpi_power")
 #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
 static int acpi_power_add(struct acpi_device *device);
 static int acpi_power_remove(struct acpi_device *device, int type);
+static int acpi_power_resume(struct acpi_device *device);
 static int acpi_power_open_fs(struct inode *inode, struct file *file);
 
 static struct acpi_driver acpi_power_driver = {
-       .name = ACPI_POWER_DRIVER_NAME,
+       .name = "power",
        .class = ACPI_POWER_CLASS,
        .ids = ACPI_POWER_HID,
        .ops = {
                .add = acpi_power_add,
                .remove = acpi_power_remove,
+               .resume = acpi_power_resume,
                },
 };
 
+struct acpi_power_reference {
+       struct list_head node;
+       struct acpi_device *device;
+};
+
 struct acpi_power_resource {
        struct acpi_device * device;
        acpi_bus_id name;
        u32 system_level;
        u32 order;
        int state;
-       int references;
+       struct mutex resource_lock;
+       struct list_head reference;
 };
 
 static struct list_head acpi_power_resource_list;
@@ -171,22 +178,47 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
        return result;
 }
 
-static int acpi_power_on(acpi_handle handle)
+static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
 {
        int result = 0;
+       int found = 0;
        acpi_status status = AE_OK;
-       struct acpi_device *device = NULL;
        struct acpi_power_resource *resource = NULL;
+       struct list_head *node, *next;
+       struct acpi_power_reference *ref;
 
 
        result = acpi_power_get_context(handle, &resource);
        if (result)
                return result;
 
-       resource->references++;
+       mutex_lock(&resource->resource_lock);
+       list_for_each_safe(node, next, &resource->reference) {
+               ref = container_of(node, struct acpi_power_reference, node);
+               if (dev->handle == ref->device->handle) {
+                       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] already referenced by resource [%s]\n",
+                                 dev->pnp.bus_id, resource->name));
+                       found = 1;
+                       break;
+               }
+       }
+
+       if (!found) {
+               ref = kmalloc(sizeof (struct acpi_power_reference),
+                   irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
+               if (!ref) {
+                       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "kmalloc() failed\n"));
+                       mutex_unlock(&resource->resource_lock);
+                       return -ENOMEM;
+               }
+               list_add_tail(&ref->node, &resource->reference);
+               ref->device = dev;
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] added to resource [%s] references\n",
+                         dev->pnp.bus_id, resource->name));
+       }
+       mutex_unlock(&resource->resource_lock);
 
-       if ((resource->references > 1)
-           || (resource->state == ACPI_POWER_RESOURCE_STATE_ON)) {
+       if (resource->state == ACPI_POWER_RESOURCE_STATE_ON) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already on\n",
                                  resource->name));
                return 0;
@@ -203,38 +235,49 @@ static int acpi_power_on(acpi_handle handle)
                return -ENOEXEC;
 
        /* Update the power resource's _device_ power state */
-       device = resource->device;
        resource->device->power.state = ACPI_STATE_D0;
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned on\n",
                          resource->name));
-
        return 0;
 }
 
-static int acpi_power_off_device(acpi_handle handle)
+static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
 {
        int result = 0;
        acpi_status status = AE_OK;
        struct acpi_power_resource *resource = NULL;
+       struct list_head *node, *next;
+       struct acpi_power_reference *ref;
+
 
        result = acpi_power_get_context(handle, &resource);
        if (result)
                return result;
 
-       if (resource->references)
-               resource->references--;
+       mutex_lock(&resource->resource_lock);
+       list_for_each_safe(node, next, &resource->reference) {
+               ref = container_of(node, struct acpi_power_reference, node);
+               if (dev->handle == ref->device->handle) {
+                       list_del(&ref->node);
+                       kfree(ref);
+                       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] removed from resource [%s] references\n",
+                           dev->pnp.bus_id, resource->name));
+                       break;
+               }
+       }
 
-       if (resource->references) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                 "Resource [%s] is still in use, dereferencing\n",
-                                 resource->device->pnp.bus_id));
+       if (!list_empty(&resource->reference)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cannot turn resource [%s] off - resource is in use\n",
+                   resource->name));
+               mutex_unlock(&resource->resource_lock);
                return 0;
        }
+       mutex_unlock(&resource->resource_lock);
 
        if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n",
-                                 resource->device->pnp.bus_id));
+                                 resource->name));
                return 0;
        }
 
@@ -276,7 +319,7 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev)
        arg.integer.value = 1;
        /* Open power resource */
        for (i = 0; i < dev->wakeup.resources.count; i++) {
-               ret = acpi_power_on(dev->wakeup.resources.handles[i]);
+               ret = acpi_power_on(dev->wakeup.resources.handles[i], dev);
                if (ret) {
                        printk(KERN_ERR PREFIX "Transition power state\n");
                        dev->wakeup.flags.valid = 0;
@@ -323,7 +366,7 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
 
        /* Close power resource */
        for (i = 0; i < dev->wakeup.resources.count; i++) {
-               ret = acpi_power_off_device(dev->wakeup.resources.handles[i]);
+               ret = acpi_power_off_device(dev->wakeup.resources.handles[i], dev);
                if (ret) {
                        printk(KERN_ERR PREFIX "Transition power state\n");
                        dev->wakeup.flags.valid = 0;
@@ -407,16 +450,20 @@ int acpi_power_transition(struct acpi_device *device, int state)
         * (e.g. so the device doesn't lose power while transitioning).
         */
        for (i = 0; i < tl->count; i++) {
-               result = acpi_power_on(tl->handles[i]);
+               result = acpi_power_on(tl->handles[i], device);
                if (result)
                        goto end;
        }
 
+       if (device->power.state == state) {
+               goto end;
+       }
+
        /*
         * Then we dereference all power resources used in the current list.
         */
        for (i = 0; i < cl->count; i++) {
-               result = acpi_power_off_device(cl->handles[i]);
+               result = acpi_power_off_device(cl->handles[i], device);
                if (result)
                        goto end;
        }
@@ -439,7 +486,11 @@ static struct proc_dir_entry *acpi_power_dir;
 
 static int acpi_power_seq_show(struct seq_file *seq, void *offset)
 {
+       int count = 0;
+       int result = 0;
        struct acpi_power_resource *resource = NULL;
+       struct list_head *node, *next;
+       struct acpi_power_reference *ref;
 
 
        resource = seq->private;
@@ -447,6 +498,10 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset)
        if (!resource)
                goto end;
 
+       result = acpi_power_get_state(resource);
+       if (result)
+               goto end;
+
        seq_puts(seq, "state:                   ");
        switch (resource->state) {
        case ACPI_POWER_RESOURCE_STATE_ON:
@@ -460,11 +515,18 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset)
                break;
        }
 
+       mutex_lock(&resource->resource_lock);
+       list_for_each_safe(node, next, &resource->reference) {
+               ref = container_of(node, struct acpi_power_reference, node);
+               count++;
+       }
+       mutex_unlock(&resource->resource_lock);
+
        seq_printf(seq, "system level:            S%d\n"
                   "order:                   %d\n"
                   "reference count:         %d\n",
                   resource->system_level,
-                  resource->order, resource->references);
+                  resource->order, count);
 
       end:
        return 0;
@@ -537,6 +599,8 @@ static int acpi_power_add(struct acpi_device *device)
                return -ENOMEM;
 
        resource->device = device;
+       mutex_init(&resource->resource_lock);
+       INIT_LIST_HEAD(&resource->reference);
        strcpy(resource->name, device->pnp.bus_id);
        strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
@@ -584,6 +648,7 @@ static int acpi_power_add(struct acpi_device *device)
 static int acpi_power_remove(struct acpi_device *device, int type)
 {
        struct acpi_power_resource *resource = NULL;
+       struct list_head *node, *next;
 
 
        if (!device || !acpi_driver_data(device))
@@ -593,11 +658,54 @@ static int acpi_power_remove(struct acpi_device *device, int type)
 
        acpi_power_remove_fs(device);
 
+       mutex_lock(&resource->resource_lock);
+       list_for_each_safe(node, next, &resource->reference) {
+               struct acpi_power_reference *ref = container_of(node, struct acpi_power_reference, node);
+               list_del(&ref->node);
+               kfree(ref);
+       }
+       mutex_unlock(&resource->resource_lock);
+
        kfree(resource);
 
        return 0;
 }
 
+static int acpi_power_resume(struct acpi_device *device)
+{
+       int result = 0;
+       struct acpi_power_resource *resource = NULL;
+       struct acpi_power_reference *ref;
+
+       if (!device || !acpi_driver_data(device))
+               return -EINVAL;
+
+       resource = (struct acpi_power_resource *)acpi_driver_data(device);
+
+       result = acpi_power_get_state(resource);
+       if (result)
+               return result;
+
+       mutex_lock(&resource->resource_lock);
+       if ((resource->state == ACPI_POWER_RESOURCE_STATE_ON) &&
+           list_empty(&resource->reference)) {
+               mutex_unlock(&resource->resource_lock);
+               result = acpi_power_off_device(device->handle, NULL);
+               return result;
+       }
+
+       if ((resource->state == ACPI_POWER_RESOURCE_STATE_OFF) &&
+           !list_empty(&resource->reference)) {
+               ref = container_of(resource->reference.next, struct acpi_power_reference, node);
+               mutex_unlock(&resource->resource_lock);
+               result = acpi_power_on(device->handle, ref->device);
+               return result;
+       }
+
+       mutex_unlock(&resource->resource_lock);
+       return 0;
+}
+
 static int __init acpi_power_init(void)
 {
        int result = 0;
index 0079bc5..99d1516 100644 (file)
@@ -60,7 +60,6 @@
 
 #define ACPI_PROCESSOR_COMPONENT       0x01000000
 #define ACPI_PROCESSOR_CLASS           "processor"
-#define ACPI_PROCESSOR_DRIVER_NAME     "ACPI Processor Driver"
 #define ACPI_PROCESSOR_DEVICE_NAME     "Processor"
 #define ACPI_PROCESSOR_FILE_INFO       "info"
 #define ACPI_PROCESSOR_FILE_THROTTLING "throttling"
 #define ACPI_STA_PRESENT 0x00000001
 
 #define _COMPONENT             ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME("acpi_processor")
+ACPI_MODULE_NAME("processor_core");
 
-    MODULE_AUTHOR("Paul Diefenbaugh");
-MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME);
+MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_DESCRIPTION("ACPI Processor Driver");
 MODULE_LICENSE("GPL");
 
 static int acpi_processor_add(struct acpi_device *device);
@@ -89,7 +88,7 @@ static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
 static int acpi_processor_handle_eject(struct acpi_processor *pr);
 
 static struct acpi_driver acpi_processor_driver = {
-       .name = ACPI_PROCESSOR_DRIVER_NAME,
+       .name = "processor",
        .class = ACPI_PROCESSOR_CLASS,
        .ids = ACPI_PROCESSOR_HID,
        .ops = {
@@ -404,7 +403,7 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
        if (lsapic->lapic_flags & ACPI_MADT_ENABLED) {
                /* First check against id */
                if (lsapic->processor_id == acpi_id) {
-                       *apic_id = lsapic->id;
+                       *apic_id = (lsapic->id << 8) | lsapic->eid;
                        return 1;
                /* Check against optional uid */
                } else if (entry->length >= 16 &&
@@ -1005,7 +1004,7 @@ static int __init acpi_processor_init(void)
 #ifdef CONFIG_SMP
        if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0,
                                (struct acpi_table_header **)&madt)))
-               madt = 0;
+               madt = NULL;
 #endif
 
        acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
index 8206fc1..6077300 100644 (file)
 #include <asm/apic.h>
 #endif
 
+/*
+ * Include the apic definitions for x86 to have the APIC timer related defines
+ * available also for UP (on SMP it gets magically included via linux/smp.h).
+ */
+#ifdef CONFIG_X86
+#include <asm/apic.h>
+#endif
+
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
@@ -59,9 +67,8 @@
 
 #define ACPI_PROCESSOR_COMPONENT        0x01000000
 #define ACPI_PROCESSOR_CLASS            "processor"
-#define ACPI_PROCESSOR_DRIVER_NAME      "ACPI Processor Driver"
 #define _COMPONENT              ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME("acpi_processor")
+ACPI_MODULE_NAME("processor_idle");
 #define ACPI_PROCESSOR_FILE_POWER      "power"
 #define US_TO_PM_TIMER_TICKS(t)                ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
 #define C2_OVERHEAD                    4       /* 1us (3.579 ticks per us) */
index 058f13c..2f2e796 100644 (file)
 
 #define ACPI_PROCESSOR_COMPONENT       0x01000000
 #define ACPI_PROCESSOR_CLASS           "processor"
-#define ACPI_PROCESSOR_DRIVER_NAME     "ACPI Processor Driver"
 #define ACPI_PROCESSOR_FILE_PERFORMANCE        "performance"
 #define _COMPONENT             ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME("acpi_processor")
+ACPI_MODULE_NAME("processor_perflib");
 
 static DEFINE_MUTEX(performance_mutex);
 
index 40fecd6..06e6f3f 100644 (file)
@@ -41,9 +41,8 @@
 
 #define ACPI_PROCESSOR_COMPONENT        0x01000000
 #define ACPI_PROCESSOR_CLASS            "processor"
-#define ACPI_PROCESSOR_DRIVER_NAME      "ACPI Processor Driver"
 #define _COMPONENT              ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME("acpi_processor")
+ACPI_MODULE_NAME("processor_thermal");
 
 /* --------------------------------------------------------------------------
                                  Limit Interface
index 89dff36..b334860 100644 (file)
@@ -41,9 +41,8 @@
 
 #define ACPI_PROCESSOR_COMPONENT        0x01000000
 #define ACPI_PROCESSOR_CLASS            "processor"
-#define ACPI_PROCESSOR_DRIVER_NAME      "ACPI Processor Driver"
 #define _COMPONENT              ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME("acpi_processor")
+ACPI_MODULE_NAME("processor_throttling");
 
 /* --------------------------------------------------------------------------
                               Throttling Control
index f58fc74..59640d9 100644 (file)
@@ -59,7 +59,6 @@ extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
 #define ACPI_AC_CLASS                  "ac_adapter"
 #define ACPI_BATTERY_CLASS             "battery"
 #define ACPI_SBS_HID                   "ACPI0002"
-#define ACPI_SBS_DRIVER_NAME           "ACPI Smart Battery System Driver"
 #define ACPI_SBS_DEVICE_NAME           "Smart Battery System"
 #define ACPI_SBS_FILE_INFO             "info"
 #define ACPI_SBS_FILE_STATE            "state"
@@ -78,7 +77,7 @@ extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
 #define        MAX_SBS_BAT                     4
 #define        MAX_SMBUS_ERR                   1
 
-ACPI_MODULE_NAME("acpi_sbs");
+ACPI_MODULE_NAME("sbs");
 
 MODULE_AUTHOR("Rich Townsend");
 MODULE_DESCRIPTION("Smart Battery System ACPI interface driver");
@@ -110,7 +109,7 @@ static void acpi_battery_smbus_err_handler(struct acpi_ec_smbus *smbus);
 static void acpi_sbs_update_queue(void *data);
 
 static struct acpi_driver acpi_sbs_driver = {
-       .name = ACPI_SBS_DRIVER_NAME,
+       .name = "sbs",
        .class = ACPI_SBS_CLASS,
        .ids = ACPI_SBS_HID,
        .ops = {
@@ -1034,21 +1033,19 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
        } else {
                seq_printf(seq, "capacity state:          ok\n");
        }
+
+       foo = (s16) battery->state.amperage * battery->info.ipscale;
+       if (battery->info.capacity_mode) {
+               foo = foo * battery->info.design_voltage / 1000;
+       }
        if (battery->state.amperage < 0) {
                seq_printf(seq, "charging state:          discharging\n");
-               foo = battery->state.remaining_capacity * cscale * 60 /
-                   (battery->state.average_time_to_empty == 0 ? 1 :
-                    battery->state.average_time_to_empty);
-               seq_printf(seq, "present rate:            %i%s\n",
-                          foo, battery->info.capacity_mode ? "0 mW" : " mA");
+               seq_printf(seq, "present rate:            %d %s\n",
+                          -foo, battery->info.capacity_mode ? "mW" : "mA");
        } else if (battery->state.amperage > 0) {
                seq_printf(seq, "charging state:          charging\n");
-               foo = (battery->info.full_charge_capacity -
-                      battery->state.remaining_capacity) * cscale * 60 /
-                   (battery->state.average_time_to_full == 0 ? 1 :
-                    battery->state.average_time_to_full);
-               seq_printf(seq, "present rate:            %i%s\n",
-                          foo, battery->info.capacity_mode ? "0 mW" : " mA");
+               seq_printf(seq, "present rate:            %d %s\n",
+                          foo, battery->info.capacity_mode ? "mW" : "mA");
        } else {
                seq_printf(seq, "charging state:          charged\n");
                seq_printf(seq, "present rate:            0 %s\n",
index 64f26db..bb0e0da 100644 (file)
 #include <acpi/acinterp.h>     /* for acpi_ex_eisa_id_to_string() */
 
 #define _COMPONENT             ACPI_BUS_COMPONENT
-ACPI_MODULE_NAME("scan")
+ACPI_MODULE_NAME("scan");
 #define STRUCT_TO_INT(s)       (*((int*)&s))
 extern struct acpi_device *acpi_root;
 
 #define ACPI_BUS_CLASS                 "system_bus"
 #define ACPI_BUS_HID                   "ACPI_BUS"
-#define ACPI_BUS_DRIVER_NAME           "ACPI Bus Driver"
 #define ACPI_BUS_DEVICE_NAME           "System Bus"
 
 static LIST_HEAD(acpi_device_list);
index 62ce87d..37a0930 100644 (file)
@@ -200,7 +200,7 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
        {},
 };
 
-static int __init acpi_sleep_init(void)
+int __init acpi_sleep_init(void)
 {
        int i = 0;
 
@@ -229,4 +229,3 @@ static int __init acpi_sleep_init(void)
        return 0;
 }
 
-late_initcall(acpi_sleep_init);
index 7147b0b..83a8d30 100644 (file)
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT             ACPI_SYSTEM_COMPONENT
-ACPI_MODULE_NAME("acpi_system")
+ACPI_MODULE_NAME("system");
 #ifdef MODULE_PARAM_PREFIX
 #undef MODULE_PARAM_PREFIX
 #endif
 #define MODULE_PARAM_PREFIX "acpi."
 
 #define ACPI_SYSTEM_CLASS              "system"
-#define ACPI_SYSTEM_DRIVER_NAME                "ACPI System Driver"
 #define ACPI_SYSTEM_DEVICE_NAME                "System"
 #define ACPI_SYSTEM_FILE_INFO          "info"
 #define ACPI_SYSTEM_FILE_EVENT         "event"
index 45bd173..849e2c3 100644 (file)
@@ -169,40 +169,40 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header * header)
 
 
 int __init
-acpi_table_parse_madt_family(char *id,
-                            unsigned long madt_size,
+acpi_table_parse_entries(char *id,
+                            unsigned long table_size,
                             int entry_id,
-                            acpi_madt_entry_handler handler,
+                            acpi_table_entry_handler handler,
                             unsigned int max_entries)
 {
-       struct acpi_table_header *madt = NULL;
+       struct acpi_table_header *table_header = NULL;
        struct acpi_subtable_header *entry;
        unsigned int count = 0;
-       unsigned long madt_end;
+       unsigned long table_end;
 
        if (!handler)
                return -EINVAL;
 
-       /* Locate the MADT (if exists). There should only be one. */
-       acpi_get_table(id, 0, &madt);
+       /* Locate the table (if exists). There should only be one. */
+       acpi_get_table(id, 0, &table_header);
 
-       if (!madt) {
+       if (!table_header) {
                printk(KERN_WARNING PREFIX "%4.4s not present\n", id);
                return -ENODEV;
        }
 
-       madt_end = (unsigned long)madt + madt->length;
+       table_end = (unsigned long)table_header + table_header->length;
 
        /* Parse all entries looking for a match. */
 
        entry = (struct acpi_subtable_header *)
-           ((unsigned long)madt + madt_size);
+           ((unsigned long)table_header + table_size);
 
        while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
-              madt_end) {
+              table_end) {
                if (entry->type == entry_id
                    && (!max_entries || count++ < max_entries))
-                       if (handler(entry, madt_end))
+                       if (handler(entry, table_end))
                                return -EINVAL;
 
                entry = (struct acpi_subtable_header *)
@@ -218,13 +218,22 @@ acpi_table_parse_madt_family(char *id,
 
 int __init
 acpi_table_parse_madt(enum acpi_madt_type id,
-                     acpi_madt_entry_handler handler, unsigned int max_entries)
+                     acpi_table_entry_handler handler, unsigned int max_entries)
 {
-       return acpi_table_parse_madt_family(ACPI_SIG_MADT,
+       return acpi_table_parse_entries(ACPI_SIG_MADT,
                                            sizeof(struct acpi_table_madt), id,
                                            handler, max_entries);
 }
 
+/**
+ * acpi_table_parse - find table with @id, run @handler on it
+ *
+ * @id: table id to find
+ * @handler: handler to run
+ *
+ * Scan the ACPI System Descriptor Table (STD) for a table matching @id,
+ * run @handler on it.  Return 0 if table found, return on if not.
+ */
 int __init acpi_table_parse(char *id, acpi_table_handler handler)
 {
        struct acpi_table_header *table = NULL;
@@ -234,9 +243,9 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler)
        acpi_get_table(id, 0, &table);
        if (table) {
                handler(table);
-               return 1;
-       } else
                return 0;
+       } else
+               return 1;
 }
 
 /*
index 807978d..417ef5f 100644 (file)
@@ -338,9 +338,9 @@ acpi_status acpi_unload_table_id(acpi_owner_id id)
        int i;
        acpi_status status = AE_NOT_EXIST;
 
-       ACPI_FUNCTION_TRACE(acpi_unload_table);
+       ACPI_FUNCTION_TRACE(acpi_unload_table_id);
 
-       /* Find table from the requested type list */
+       /* Find table in the global table list */
        for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
                if (id != acpi_gbl_root_table_list.tables[i].owner_id) {
                        continue;
@@ -352,8 +352,9 @@ acpi_status acpi_unload_table_id(acpi_owner_id id)
                * simply a position within the hierarchy
                */
                acpi_tb_delete_namespace_by_owner(i);
-               acpi_tb_release_owner_id(i);
+               status = acpi_tb_release_owner_id(i);
                acpi_tb_set_table_loaded_flag(i, FALSE);
+               break;
        }
        return_ACPI_STATUS(status);
 }
@@ -408,7 +409,7 @@ acpi_get_table(char *signature,
                }
 
                if (!acpi_gbl_permanent_mmap) {
-                       acpi_gbl_root_table_list.tables[i].pointer = 0;
+                       acpi_gbl_root_table_list.tables[i].pointer = NULL;
                }
 
                return (status);
index 986afd4..0ae8b93 100644 (file)
@@ -47,7 +47,6 @@
 
 #define ACPI_THERMAL_COMPONENT         0x04000000
 #define ACPI_THERMAL_CLASS             "thermal_zone"
-#define ACPI_THERMAL_DRIVER_NAME       "ACPI Thermal Zone Driver"
 #define ACPI_THERMAL_DEVICE_NAME       "Thermal Zone"
 #define ACPI_THERMAL_FILE_STATE                "state"
 #define ACPI_THERMAL_FILE_TEMPERATURE  "temperature"
 #define CELSIUS_TO_KELVIN(t)   ((t+273)*10)
 
 #define _COMPONENT             ACPI_THERMAL_COMPONENT
-ACPI_MODULE_NAME("acpi_thermal")
+ACPI_MODULE_NAME("thermal");
 
 MODULE_AUTHOR("Paul Diefenbaugh");
-MODULE_DESCRIPTION(ACPI_THERMAL_DRIVER_NAME);
+MODULE_DESCRIPTION("ACPI Thermal Zone Driver");
 MODULE_LICENSE("GPL");
 
 static int tzp;
@@ -99,7 +98,7 @@ static ssize_t acpi_thermal_write_polling(struct file *, const char __user *,
                                          size_t, loff_t *);
 
 static struct acpi_driver acpi_thermal_driver = {
-       .name = ACPI_THERMAL_DRIVER_NAME,
+       .name = "thermal",
        .class = ACPI_THERMAL_CLASS,
        .ids = ACPI_THERMAL_HID,
        .ops = {
@@ -270,7 +269,7 @@ static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds)
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                          "Polling frequency set to %lu seconds\n",
-                         tz->polling_frequency));
+                         tz->polling_frequency/10));
 
        return 0;
 }
@@ -1357,28 +1356,32 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
 static int acpi_thermal_resume(struct acpi_device *device)
 {
        struct acpi_thermal *tz = NULL;
-       int i;
+       int i, j, power_state, result;
+
 
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
 
        tz = acpi_driver_data(device);
 
-       acpi_thermal_get_temperature(tz);
-
        for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
-               if (tz->trips.active[i].flags.valid) {
-                       tz->temperature = tz->trips.active[i].temperature;
-                       tz->trips.active[i].flags.enabled = 0;
-
-                       acpi_thermal_active(tz);
-
-                       tz->state.active |= tz->trips.active[i].flags.enabled;
-                       tz->state.active_index = i;
+               if (!(&tz->trips.active[i]))
+                       break;
+               if (!tz->trips.active[i].flags.valid)
+                       break;
+               tz->trips.active[i].flags.enabled = 1;
+               for (j = 0; j < tz->trips.active[i].devices.count; j++) {
+                       result = acpi_bus_get_power(tz->trips.active[i].devices.
+                           handles[j], &power_state);
+                       if (result || (power_state != ACPI_STATE_D0)) {
+                               tz->trips.active[i].flags.enabled = 0;
+                               break;
+                       }
                }
+               tz->state.active |= tz->trips.active[i].flags.enabled;
        }
 
-       acpi_thermal_check(tz);
+       acpi_thermal_check(tz);
 
        return AE_OK;
 }
index d9b651f..faf8a52 100644 (file)
@@ -125,7 +125,7 @@ static int write_acpi_int(const char *methodName, int val)
        union acpi_object in_objs[1];
        acpi_status status;
 
-       params.count = sizeof(in_objs) / sizeof(in_objs[0]);
+       params.count = ARRAY_SIZE(in_objs);
        params.pointer = in_objs;
        in_objs[0].type = ACPI_TYPE_INTEGER;
        in_objs[0].integer.value = val;
@@ -561,10 +561,6 @@ static int __init toshiba_acpi_init(void)
        if (acpi_disabled)
                return -ENODEV;
 
-       if (!acpi_specific_hotkey_enabled) {
-               printk(MY_INFO "Using generic hotkey driver\n");
-               return -ENODEV;
-       }
        /* simple device detection: look for HCI method */
        if (is_valid_acpi_path(METHOD_HCI_1))
                method_hci = METHOD_HCI_1;
index f777ceb..673a0ca 100644 (file)
@@ -170,7 +170,6 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
                        acpi_os_delete_mutex(object->mutex.os_mutex);
                        acpi_gbl_global_lock_mutex = NULL;
                } else {
-                       acpi_ex_unlink_mutex(object);
                        acpi_os_delete_mutex(object->mutex.os_mutex);
                }
                break;
index 68a809f..34f1575 100644 (file)
@@ -31,7 +31,7 @@
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT             ACPI_BUS_COMPONENT
-ACPI_MODULE_NAME("acpi_utils")
+ACPI_MODULE_NAME("utils");
 
 /* --------------------------------------------------------------------------
                             Object Evaluation Helpers
index e0b97ad..bf525cc 100644 (file)
@@ -40,7 +40,6 @@
 
 #define ACPI_VIDEO_COMPONENT           0x08000000
 #define ACPI_VIDEO_CLASS               "video"
-#define ACPI_VIDEO_DRIVER_NAME         "ACPI Video Driver"
 #define ACPI_VIDEO_BUS_NAME            "Video Bus"
 #define ACPI_VIDEO_DEVICE_NAME         "Video Device"
 #define ACPI_VIDEO_NOTIFY_SWITCH       0x80
 #define ACPI_VIDEO_DISPLAY_LCD 4
 
 #define _COMPONENT             ACPI_VIDEO_COMPONENT
-ACPI_MODULE_NAME("acpi_video")
+ACPI_MODULE_NAME("video");
 
-    MODULE_AUTHOR("Bruno Ducrot");
-MODULE_DESCRIPTION(ACPI_VIDEO_DRIVER_NAME);
+MODULE_AUTHOR("Bruno Ducrot");
+MODULE_DESCRIPTION("ACPI Video Driver");
 MODULE_LICENSE("GPL");
 
 static int acpi_video_bus_add(struct acpi_device *device);
 static int acpi_video_bus_remove(struct acpi_device *device, int type);
 
 static struct acpi_driver acpi_video_bus = {
-       .name = ACPI_VIDEO_DRIVER_NAME,
+       .name = "video",
        .class = ACPI_VIDEO_CLASS,
        .ids = ACPI_VIDEO_HID,
        .ops = {
index 472810f..253868e 100644 (file)
@@ -324,27 +324,25 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
        return error;
 }
 
-static int device_add_attrs(struct bus_type * bus, struct device * dev)
+static int device_add_attrs(struct bus_type *bus, struct device *dev)
 {
        int error = 0;
        int i;
 
-       if (bus->dev_attrs) {
-               for (i = 0; attr_name(bus->dev_attrs[i]); i++) {
-                       error = device_create_file(dev,&bus->dev_attrs[i]);
-                       if (error)
-                               goto Err;
+       if (!bus->dev_attrs)
+               return 0;
+
+       for (i = 0; attr_name(bus->dev_attrs[i]); i++) {
+               error = device_create_file(dev,&bus->dev_attrs[i]);
+               if (error) {
+                       while (--i >= 0)
+                               device_remove_file(dev, &bus->dev_attrs[i]);
+                       break;
                }
        }
- Done:
        return error;
- Err:
-       while (--i >= 0)
-               device_remove_file(dev,&bus->dev_attrs[i]);
-       goto Done;
 }
 
-
 static void device_remove_attrs(struct bus_type * bus, struct device * dev)
 {
        int i;
index 96def1d..1417e5c 100644 (file)
@@ -163,8 +163,7 @@ int class_register(struct class * cls)
 void class_unregister(struct class * cls)
 {
        pr_debug("device class '%s': unregistering\n", cls->name);
-       if (cls->virtual_dir)
-               kobject_unregister(cls->virtual_dir);
+       kobject_unregister(cls->virtual_dir);
        remove_class_attrs(cls);
        subsystem_unregister(&cls->subsys);
 }
index bedae4a..80b199f 100644 (file)
@@ -107,4 +107,19 @@ config MSI_LAPTOP
 
          If you have an MSI S270 laptop, say Y or M here.
 
+config SONY_LAPTOP
+       tristate "Sony Laptop Extras"
+       depends on X86 && ACPI
+       select BACKLIGHT_CLASS_DEVICE
+         ---help---
+         This mini-driver drives the SNC device present in the ACPI BIOS of
+         the Sony Vaio laptops.
+
+         It gives access to some extra laptop functionalities. In its current
+         form, this driver let the user set or query the screen brightness
+         through the backlight subsystem and remove/apply power to some
+         devices.
+
+         Read <file:Documentation/sony-laptop.txt> for more information.
+
 endmenu
index 35da53c..7793ccd 100644 (file)
@@ -11,3 +11,4 @@ obj-$(CONFIG_LKDTM)           += lkdtm.o
 obj-$(CONFIG_TIFM_CORE)        += tifm_core.o
 obj-$(CONFIG_TIFM_7XX1)        += tifm_7xx1.o
 obj-$(CONFIG_SGI_IOC4)         += ioc4.o
+obj-$(CONFIG_SONY_LAPTOP)      += sony-laptop.o
index 861c399..e4e2b70 100644 (file)
@@ -1088,11 +1088,6 @@ static int __init asus_laptop_init(void)
        if (acpi_disabled)
                return -ENODEV;
 
-       if (!acpi_specific_hotkey_enabled) {
-               printk(ASUS_ERR "Using generic hotkey driver\n");
-               return -ENODEV;
-       }
-
        result = acpi_bus_register_driver(&asus_hotk_driver);
        if (result < 0)
                return result;
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
new file mode 100644 (file)
index 0000000..cabbed0
--- /dev/null
@@ -0,0 +1,562 @@
+/*
+ * ACPI Sony Notebook Control Driver (SNC)
+ *
+ * Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net>
+ * Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
+ *
+ * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c
+ * which are copyrighted by their respective authors.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/backlight.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acpi_bus.h>
+#include <asm/uaccess.h>
+
+#define ACPI_SNC_CLASS         "sony"
+#define ACPI_SNC_HID           "SNY5001"
+#define ACPI_SNC_DRIVER_NAME   "ACPI Sony Notebook Control Driver v0.4"
+
+/* the device uses 1-based values, while the backlight subsystem uses
+   0-based values */
+#define SONY_MAX_BRIGHTNESS    8
+
+#define LOG_PFX                        KERN_WARNING "sony-laptop: "
+
+MODULE_AUTHOR("Stelian Pop, Mattia Dongili");
+MODULE_DESCRIPTION(ACPI_SNC_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+static int debug;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "set this to 1 (and RTFM) if you want to help "
+                "the development of this driver");
+
+static ssize_t sony_acpi_show(struct device *, struct device_attribute *,
+                             char *);
+static ssize_t sony_acpi_store(struct device *, struct device_attribute *,
+                              const char *, size_t);
+static int boolean_validate(const int, const int);
+static int brightness_default_validate(const int, const int);
+
+#define SNC_VALIDATE_IN                0
+#define SNC_VALIDATE_OUT       1
+
+struct sony_acpi_value {
+       char *name;             /* name of the entry */
+       char **acpiget;         /* names of the ACPI get function */
+       char **acpiset;         /* names of the ACPI set function */
+       int (*validate)(const int, const int);  /* input/output validation */
+       int value;              /* current setting */
+       int valid;              /* Has ever been set */
+       int debug;              /* active only in debug mode ? */
+       struct device_attribute devattr;        /* sysfs atribute */
+};
+
+#define HANDLE_NAMES(_name, _values...) \
+       static char *snc_##_name[] = { _values, NULL }
+
+#define SONY_ACPI_VALUE(_name, _getters, _setters, _validate, _debug) \
+       { \
+               .name           = __stringify(_name), \
+               .acpiget        = _getters, \
+               .acpiset        = _setters, \
+               .validate       = _validate, \
+               .debug          = _debug, \
+               .devattr        = __ATTR(_name, 0, sony_acpi_show, sony_acpi_store), \
+       }
+
+#define SONY_ACPI_VALUE_NULL   { .name = NULL }
+
+HANDLE_NAMES(fnkey_get, "GHKE");
+
+HANDLE_NAMES(brightness_def_get, "GPBR");
+HANDLE_NAMES(brightness_def_set, "SPBR");
+
+HANDLE_NAMES(cdpower_get, "GCDP");
+HANDLE_NAMES(cdpower_set, "SCDP", "CDPW");
+
+HANDLE_NAMES(audiopower_get, "GAZP");
+HANDLE_NAMES(audiopower_set, "AZPW");
+
+HANDLE_NAMES(lanpower_get, "GLNP");
+HANDLE_NAMES(lanpower_set, "LNPW");
+
+HANDLE_NAMES(PID_get, "GPID");
+
+HANDLE_NAMES(CTR_get, "GCTR");
+HANDLE_NAMES(CTR_set, "SCTR");
+
+HANDLE_NAMES(PCR_get, "GPCR");
+HANDLE_NAMES(PCR_set, "SPCR");
+
+HANDLE_NAMES(CMI_get, "GCMI");
+HANDLE_NAMES(CMI_set, "SCMI");
+
+static struct sony_acpi_value sony_acpi_values[] = {
+       SONY_ACPI_VALUE(brightness_default, snc_brightness_def_get,
+                       snc_brightness_def_set, brightness_default_validate, 0),
+       SONY_ACPI_VALUE(fnkey, snc_fnkey_get, NULL, NULL, 0),
+       SONY_ACPI_VALUE(cdpower, snc_cdpower_get, snc_cdpower_set, boolean_validate, 0),
+       SONY_ACPI_VALUE(audiopower, snc_audiopower_get, snc_audiopower_set,
+                       boolean_validate, 0),
+       SONY_ACPI_VALUE(lanpower, snc_lanpower_get, snc_lanpower_set,
+                       boolean_validate, 1),
+       /* unknown methods */
+       SONY_ACPI_VALUE(PID, snc_PID_get, NULL, NULL, 1),
+       SONY_ACPI_VALUE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1),
+       SONY_ACPI_VALUE(PCR, snc_PCR_get, snc_PCR_set, NULL, 1),
+       SONY_ACPI_VALUE(CMI, snc_CMI_get, snc_CMI_set, NULL, 1),
+       SONY_ACPI_VALUE_NULL
+};
+
+static acpi_handle sony_acpi_handle;
+static struct acpi_device *sony_acpi_acpi_device = NULL;
+
+/*
+ * acpi_evaluate_object wrappers
+ */
+static int acpi_callgetfunc(acpi_handle handle, char *name, int *result)
+{
+       struct acpi_buffer output;
+       union acpi_object out_obj;
+       acpi_status status;
+
+       output.length = sizeof(out_obj);
+       output.pointer = &out_obj;
+
+       status = acpi_evaluate_object(handle, name, NULL, &output);
+       if ((status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER)) {
+               *result = out_obj.integer.value;
+               return 0;
+       }
+
+       printk(LOG_PFX "acpi_callreadfunc failed\n");
+
+       return -1;
+}
+
+static int acpi_callsetfunc(acpi_handle handle, char *name, int value,
+                           int *result)
+{
+       struct acpi_object_list params;
+       union acpi_object in_obj;
+       struct acpi_buffer output;
+       union acpi_object out_obj;
+       acpi_status status;
+
+       params.count = 1;
+       params.pointer = &in_obj;
+       in_obj.type = ACPI_TYPE_INTEGER;
+       in_obj.integer.value = value;
+
+       output.length = sizeof(out_obj);
+       output.pointer = &out_obj;
+
+       status = acpi_evaluate_object(handle, name, &params, &output);
+       if (status == AE_OK) {
+               if (result != NULL) {
+                       if (out_obj.type != ACPI_TYPE_INTEGER) {
+                               printk(LOG_PFX "acpi_evaluate_object bad "
+                                      "return type\n");
+                               return -1;
+                       }
+                       *result = out_obj.integer.value;
+               }
+               return 0;
+       }
+
+       printk(LOG_PFX "acpi_evaluate_object failed\n");
+
+       return -1;
+}
+
+/*
+ * sony_acpi_values input/output validate functions
+ */
+
+/* brightness_default_validate:
+ *
+ * manipulate input output values to keep consistency with the
+ * backlight framework for which brightness values are 0-based.
+ */
+static int brightness_default_validate(const int direction, const int value)
+{
+       switch (direction) {
+               case SNC_VALIDATE_OUT:
+                       return value - 1;
+               case SNC_VALIDATE_IN:
+                       if (value >= 0 && value < SONY_MAX_BRIGHTNESS)
+                               return value + 1;
+       }
+       return -EINVAL;
+}
+
+/* boolean_validate:
+ *
+ * on input validate boolean values 0/1, on output just pass the
+ * received value.
+ */
+static int boolean_validate(const int direction, const int value)
+{
+       if (direction == SNC_VALIDATE_IN) {
+               if (value != 0 && value != 1)
+                       return -EINVAL;
+       }
+       return value;
+}
+
+/*
+ * Sysfs show/store common to all sony_acpi_values
+ */
+static ssize_t sony_acpi_show(struct device *dev, struct device_attribute *attr,
+                             char *buffer)
+{
+       int value;
+       struct sony_acpi_value *item =
+           container_of(attr, struct sony_acpi_value, devattr);
+
+       if (!*item->acpiget)
+               return -EIO;
+
+       if (acpi_callgetfunc(sony_acpi_handle, *item->acpiget, &value) < 0)
+               return -EIO;
+
+       if (item->validate)
+               value = item->validate(SNC_VALIDATE_OUT, value);
+
+       return snprintf(buffer, PAGE_SIZE, "%d\n", value);
+}
+
+static ssize_t sony_acpi_store(struct device *dev,
+                              struct device_attribute *attr,
+                              const char *buffer, size_t count)
+{
+       int value;
+       struct sony_acpi_value *item =
+           container_of(attr, struct sony_acpi_value, devattr);
+
+       if (!item->acpiset)
+               return -EIO;
+
+       if (count > 31)
+               return -EINVAL;
+
+       value = simple_strtoul(buffer, NULL, 10);
+
+       if (item->validate)
+               value = item->validate(SNC_VALIDATE_IN, value);
+
+       if (value < 0)
+               return value;
+
+       if (acpi_callsetfunc(sony_acpi_handle, *item->acpiset, value, NULL) < 0)
+               return -EIO;
+       item->value = value;
+       item->valid = 1;
+       return count;
+}
+
+/*
+ * Platform device
+ */
+static struct platform_driver sncpf_driver = {
+       .driver = {
+                  .name = "sony-laptop",
+                  .owner = THIS_MODULE,
+                  }
+};
+static struct platform_device *sncpf_device;
+
+static int sony_snc_pf_add(void)
+{
+       acpi_handle handle;
+       struct sony_acpi_value *item;
+       int ret = 0;
+
+       ret = platform_driver_register(&sncpf_driver);
+       if (ret)
+               goto out;
+
+       sncpf_device = platform_device_alloc("sony-laptop", -1);
+       if (!sncpf_device) {
+               ret = -ENOMEM;
+               goto out_platform_registered;
+       }
+
+       ret = platform_device_add(sncpf_device);
+       if (ret)
+               goto out_platform_alloced;
+
+       for (item = sony_acpi_values; item->name; ++item) {
+
+               if (!debug && item->debug)
+                       continue;
+
+               /* find the available acpiget as described in the DSDT */
+               for (; item->acpiget && *item->acpiget; ++item->acpiget) {
+                       if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle,
+                                                        *item->acpiget,
+                                                        &handle))) {
+                               if (debug)
+                                       printk(LOG_PFX "Found %s getter: %s\n",
+                                              item->name, *item->acpiget);
+                               item->devattr.attr.mode |= S_IRUGO;
+                               break;
+                       }
+               }
+
+               /* find the available acpiset as described in the DSDT */
+               for (; item->acpiset && *item->acpiset; ++item->acpiset) {
+                       if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle,
+                                                        *item->acpiset,
+                                                        &handle))) {
+                               if (debug)
+                                       printk(LOG_PFX "Found %s setter: %s\n",
+                                              item->name, *item->acpiset);
+                               item->devattr.attr.mode |= S_IWUSR;
+                               break;
+                       }
+               }
+
+               if (item->devattr.attr.mode != 0) {
+                       ret =
+                           device_create_file(&sncpf_device->dev,
+                                              &item->devattr);
+                       if (ret)
+                               goto out_sysfs;
+               }
+       }
+
+       return 0;
+
+      out_sysfs:
+       for (item = sony_acpi_values; item->name; ++item) {
+               device_remove_file(&sncpf_device->dev, &item->devattr);
+       }
+       platform_device_del(sncpf_device);
+      out_platform_alloced:
+       platform_device_put(sncpf_device);
+      out_platform_registered:
+       platform_driver_unregister(&sncpf_driver);
+      out:
+       return ret;
+}
+
+static void sony_snc_pf_remove(void)
+{
+       struct sony_acpi_value *item;
+
+       for (item = sony_acpi_values; item->name; ++item) {
+               device_remove_file(&sncpf_device->dev, &item->devattr);
+       }
+
+       platform_device_del(sncpf_device);
+       platform_device_put(sncpf_device);
+       platform_driver_unregister(&sncpf_driver);
+}
+
+/*
+ * Backlight device
+ */
+static int sony_backlight_update_status(struct backlight_device *bd)
+{
+       return acpi_callsetfunc(sony_acpi_handle, "SBRT",
+                               bd->props->brightness + 1, NULL);
+}
+
+static int sony_backlight_get_brightness(struct backlight_device *bd)
+{
+       int value;
+
+       if (acpi_callgetfunc(sony_acpi_handle, "GBRT", &value))
+               return 0;
+       /* brightness levels are 1-based, while backlight ones are 0-based */
+       return value - 1;
+}
+
+static struct backlight_device *sony_backlight_device;
+static struct backlight_properties sony_backlight_properties = {
+       .owner = THIS_MODULE,
+       .update_status = sony_backlight_update_status,
+       .get_brightness = sony_backlight_get_brightness,
+       .max_brightness = SONY_MAX_BRIGHTNESS - 1,
+};
+
+/*
+ * ACPI callbacks
+ */
+static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
+{
+       if (debug)
+               printk(LOG_PFX "sony_acpi_notify, event: %d\n", event);
+       acpi_bus_generate_event(sony_acpi_acpi_device, 1, event);
+}
+
+static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
+                                     void *context, void **return_value)
+{
+       struct acpi_namespace_node *node;
+       union acpi_operand_object *operand;
+
+       node = (struct acpi_namespace_node *)handle;
+       operand = (union acpi_operand_object *)node->object;
+
+       printk(LOG_PFX "method: name: %4.4s, args %X\n", node->name.ascii,
+              (u32) operand->method.param_count);
+
+       return AE_OK;
+}
+
+/*
+ * ACPI device
+ */
+static int sony_acpi_resume(struct acpi_device *device)
+{
+       struct sony_acpi_value *item;
+
+       for (item = sony_acpi_values; item->name; item++) {
+               int ret;
+
+               if (!item->valid)
+                       continue;
+               ret = acpi_callsetfunc(sony_acpi_handle, *item->acpiset,
+                                      item->value, NULL);
+               if (ret < 0) {
+                       printk("%s: %d\n", __FUNCTION__, ret);
+                       break;
+               }
+       }
+       return 0;
+}
+
+static int sony_acpi_add(struct acpi_device *device)
+{
+       acpi_status status;
+       int result;
+       acpi_handle handle;
+
+       sony_acpi_acpi_device = device;
+
+       sony_acpi_handle = device->handle;
+
+       if (debug) {
+               status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_acpi_handle,
+                                            1, sony_walk_callback, NULL, NULL);
+               if (ACPI_FAILURE(status)) {
+                       printk(LOG_PFX "unable to walk acpi resources\n");
+                       result = -ENODEV;
+                       goto outwalk;
+               }
+       }
+
+       status = acpi_install_notify_handler(sony_acpi_handle,
+                                            ACPI_DEVICE_NOTIFY,
+                                            sony_acpi_notify, NULL);
+       if (ACPI_FAILURE(status)) {
+               printk(LOG_PFX "unable to install notify handler\n");
+               result = -ENODEV;
+               goto outwalk;
+       }
+
+       if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, "GBRT", &handle))) {
+               sony_backlight_device = backlight_device_register("sony", NULL,
+                                                                 NULL,
+                                                                 &sony_backlight_properties);
+
+               if (IS_ERR(sony_backlight_device)) {
+                       printk(LOG_PFX "unable to register backlight device\n");
+                       sony_backlight_device = NULL;
+               } else
+                       sony_backlight_properties.brightness =
+                           sony_backlight_get_brightness
+                           (sony_backlight_device);
+       }
+
+       if (sony_snc_pf_add())
+               goto outbacklight;
+
+       printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully installed\n");
+
+       return 0;
+
+      outbacklight:
+       if (sony_backlight_device)
+               backlight_device_unregister(sony_backlight_device);
+
+       status = acpi_remove_notify_handler(sony_acpi_handle,
+                                           ACPI_DEVICE_NOTIFY,
+                                           sony_acpi_notify);
+       if (ACPI_FAILURE(status))
+               printk(LOG_PFX "unable to remove notify handler\n");
+      outwalk:
+       return result;
+}
+
+static int sony_acpi_remove(struct acpi_device *device, int type)
+{
+       acpi_status status;
+
+       if (sony_backlight_device)
+               backlight_device_unregister(sony_backlight_device);
+
+       sony_acpi_acpi_device = NULL;
+
+       status = acpi_remove_notify_handler(sony_acpi_handle,
+                                           ACPI_DEVICE_NOTIFY,
+                                           sony_acpi_notify);
+       if (ACPI_FAILURE(status))
+               printk(LOG_PFX "unable to remove notify handler\n");
+
+       sony_snc_pf_remove();
+
+       printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully removed\n");
+
+       return 0;
+}
+
+static struct acpi_driver sony_acpi_driver = {
+       .name = ACPI_SNC_DRIVER_NAME,
+       .class = ACPI_SNC_CLASS,
+       .ids = ACPI_SNC_HID,
+       .ops = {
+               .add = sony_acpi_add,
+               .remove = sony_acpi_remove,
+               .resume = sony_acpi_resume,
+               },
+};
+
+static int __init sony_acpi_init(void)
+{
+       return acpi_bus_register_driver(&sony_acpi_driver);
+}
+
+static void __exit sony_acpi_exit(void)
+{
+       acpi_bus_unregister_driver(&sony_acpi_driver);
+}
+
+module_init(sony_acpi_init);
+module_exit(sony_acpi_exit);
index b318628..99baabc 100644 (file)
@@ -277,7 +277,7 @@ static int __init at91_cf_probe(struct platform_device *pdev)
                board->det_pin, board->irq_pin);
 
        cf->socket.owner = THIS_MODULE;
-       cf->socket.dev.dev = &pdev->dev;
+       cf->socket.dev.parent = &pdev->dev;
        cf->socket.ops = &at91_cf_ops;
        cf->socket.resource_ops = &pccard_static_ops;
        cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
index d2a3bea..aa7779d 100644 (file)
@@ -478,7 +478,7 @@ dump_bits(char **p, const char *prefix, unsigned int val, struct bittbl *bits, i
  *
  * Returns: the number of characters added to the buffer
  */
-static ssize_t show_status(struct device *dev, char *buf)
+static ssize_t show_status(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct soc_pcmcia_socket *skt =
                container_of(dev, struct soc_pcmcia_socket, socket.dev);
@@ -501,7 +501,7 @@ static ssize_t show_status(struct device *dev, char *buf)
 
        return p-buf;
 }
-static CLASS_DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
+static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
 
 
 static struct pccard_operations soc_common_pcmcia_operations = {
@@ -660,7 +660,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
 
                skt->socket.ops = &soc_common_pcmcia_operations;
                skt->socket.owner = ops->owner;
-               skt->socket.dev.dev = dev;
+               skt->socket.dev.parent = dev;
 
                init_timer(&skt->poll_timer);
                skt->poll_timer.function = soc_common_pcmcia_poll_event;
@@ -747,7 +747,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
 
                add_timer(&skt->poll_timer);
 
-               device_create_file(&skt->socket.dev, &device_attr_status);
+               device_create_file(&skt->socket.dev, &dev_attr_status);
        }
 
        dev_set_drvdata(dev, sinfo);
index ad27e5e..b04767c 100644 (file)
@@ -2,17 +2,5 @@
 # Plug and Play ACPI configuration
 #
 config PNPACPI
-       bool "Plug and Play ACPI support"
-       depends on PNP && ACPI
-       default y
-       ---help---
-         Linux uses the PNPACPI to autodetect built-in
-         mainboard resources (e.g. parallel port resources).
-
-          Some features (e.g. real hotplug) are not currently
-          implemented.
-
-          If you would like the kernel to detect and allocate resources to
-          your mainboard devices (on some systems they are disabled by the
-          BIOS) say Y here.  Also the PNPACPI can help prevent resource
-          conflicts between mainboard devices and other bus devices.
+       bool
+       default (PNP && ACPI)
index 3f048bd..5a8f55f 100644 (file)
@@ -1269,9 +1269,18 @@ repeat:
 
        /* Some devices return the total number of sectors, not the
         * highest sector number.  Make the necessary adjustment. */
-       if (sdp->fix_capacity)
+       if (sdp->fix_capacity) {
                --sdkp->capacity;
 
+       /* Some devices have version which report the correct sizes
+        * and others which do not. We guess size according to a heuristic
+        * and err on the side of lowering the capacity. */
+       } else {
+               if (sdp->guess_capacity)
+                       if (sdkp->capacity & 0x01) /* odd sizes are odd */
+                               --sdkp->capacity;
+       }
+
 got_data:
        if (sector_size == 0) {
                sector_size = 512;
index c2f1012..6b76bab 100644 (file)
@@ -246,6 +246,10 @@ static const struct serial_quirk quirks[] = {
                .manfid = MANFID_QUATECH,
                .prodid = PRODID_QUATECH_DUAL_RS232_D1,
                .multi  = 2,
+       }, {
+               .manfid = MANFID_QUATECH,
+               .prodid = PRODID_QUATECH_DUAL_RS232_G,
+               .multi  = 2,
        }, {
                .manfid = MANFID_QUATECH,
                .prodid = PRODID_QUATECH_QUAD_RS232,
@@ -891,6 +895,7 @@ static struct pcmcia_device_id serial_ids[] = {
        PCMCIA_DEVICE_PROD_ID12("OEM      ", "C288MX     ", 0xb572d360, 0xd2385b7a),
        PCMCIA_DEVICE_PROD_ID12("PCMCIA   ", "C336MX     ", 0x99bcafe9, 0xaa25bcab),
        PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f),
+       PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d),
        PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"),
        PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"),
        PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"),
index 825bf88..8b7ff46 100644 (file)
@@ -51,6 +51,7 @@ obj-$(CONFIG_USB_SERIAL)      += serial/
 obj-$(CONFIG_USB_ADUTUX)       += misc/
 obj-$(CONFIG_USB_APPLEDISPLAY) += misc/
 obj-$(CONFIG_USB_AUERSWALD)    += misc/
+obj-$(CONFIG_USB_BERRY_CHARGE) += misc/
 obj-$(CONFIG_USB_CYPRESS_CY7C63)+= misc/
 obj-$(CONFIG_USB_CYTHERM)      += misc/
 obj-$(CONFIG_USB_EMI26)                += misc/
index dae4ef1..4973e14 100644 (file)
@@ -61,6 +61,7 @@
 #include <linux/usb.h>
 #include <linux/firmware.h>
 #include <linux/ctype.h>
+#include <linux/sched.h>
 #include <linux/kthread.h>
 #include <linux/version.h>
 #include <linux/mutex.h>
index 9819962..d38a25f 100644 (file)
@@ -326,10 +326,16 @@ static void acm_rx_tasklet(unsigned long _acm)
        struct tty_struct *tty = acm->tty;
        struct acm_ru *rcv;
        unsigned long flags;
-       int i = 0;
+       unsigned char throttled;
        dbg("Entering acm_rx_tasklet");
 
-       if (!ACM_READY(acm) || acm->throttle)
+       if (!ACM_READY(acm))
+               return;
+
+       spin_lock(&acm->throttle_lock);
+       throttled = acm->throttle;
+       spin_unlock(&acm->throttle_lock);
+       if (throttled)
                return;
 
 next_buffer:
@@ -346,22 +352,20 @@ next_buffer:
        dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size);
 
        tty_buffer_request_room(tty, buf->size);
-       if (!acm->throttle)
+       spin_lock(&acm->throttle_lock);
+       throttled = acm->throttle;
+       spin_unlock(&acm->throttle_lock);
+       if (!throttled)
                tty_insert_flip_string(tty, buf->base, buf->size);
        tty_flip_buffer_push(tty);
 
-       spin_lock(&acm->throttle_lock);
-       if (acm->throttle) {
-               dbg("Throtteling noticed");
-               memmove(buf->base, buf->base + i, buf->size - i);
-               buf->size -= i;
-               spin_unlock(&acm->throttle_lock);
+       if (throttled) {
+               dbg("Throttling noticed");
                spin_lock_irqsave(&acm->read_lock, flags);
                list_add(&buf->list, &acm->filled_read_bufs);
                spin_unlock_irqrestore(&acm->read_lock, flags);
                return;
        }
-       spin_unlock(&acm->throttle_lock);
 
        spin_lock_irqsave(&acm->read_lock, flags);
        list_add(&buf->list, &acm->spare_read_bufs);
@@ -467,7 +471,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
                goto bail_out;
        }
 
-       if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS))
+       if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) &&
+           (acm->ctrl_caps & USB_CDC_CAP_LINE))
                goto full_bailout;
 
        INIT_LIST_HEAD(&acm->spare_read_urbs);
@@ -480,6 +485,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
                list_add(&(acm->rb[i].list), &acm->spare_read_bufs);
        }
 
+       acm->throttle = 0;
+
        tasklet_schedule(&acm->urb_task);
 
 done:
@@ -1092,6 +1099,10 @@ static struct usb_device_id acm_ids[] = {
        { USB_DEVICE(0x0ace, 0x1611), /* ZyDAS 56K USB MODEM - new version */
        .driver_info = SINGLE_RX_URB, /* firmware bug */
        },
+       { USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */
+       .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+       },
+
        /* control interfaces with various AT-command sets */
        { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
                USB_CDC_ACM_PROTO_AT_V25TER) },
index a47c30b..aefc798 100644 (file)
@@ -604,10 +604,6 @@ static unsigned int usb_device_poll(struct file *file, struct poll_table_struct
        lock_kernel();
        if (!st) {
                st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL);
-               if (!st) {
-                       unlock_kernel();
-                       return POLLIN;
-               }
 
                /* we may have dropped BKL - need to check for having lost the race */
                if (file->private_data) {
@@ -615,6 +611,11 @@ static unsigned int usb_device_poll(struct file *file, struct poll_table_struct
                        st = file->private_data;
                        goto lost_race;
                }
+               /* we haven't lost - check for allocation failure now */
+               if (!st) {
+                       unlock_kernel();
+                       return POLLIN;
+               }
 
                /*
                 * need to prevent the module from being unloaded, since
index 2087766..274f14f 100644 (file)
@@ -857,11 +857,11 @@ static int proc_setintf(struct dev_state *ps, void __user *arg)
 
 static int proc_setconfig(struct dev_state *ps, void __user *arg)
 {
-       unsigned int u;
+       int u;
        int status = 0;
        struct usb_host_config *actconfig;
 
-       if (get_user(u, (unsigned int __user *)arg))
+       if (get_user(u, (int __user *)arg))
                return -EFAULT;
 
        actconfig = ps->dev->actconfig;
index 600d1bc..2aded26 100644 (file)
@@ -743,6 +743,7 @@ EXPORT_SYMBOL_GPL(usb_deregister_device_driver);
  * usb_register_driver - register a USB interface driver
  * @new_driver: USB operations for the interface driver
  * @owner: module owner of this driver.
+ * @mod_name: module name string
  *
  * Registers a USB interface driver with the USB core.  The list of
  * unattached interfaces will be rescanned whenever a new driver is
index 5e628ae..e0ec704 100644 (file)
@@ -229,7 +229,7 @@ static int init_endpoint_class(void)
        kref_init(&ep_class->kref);
        ep_class->class = class_create(THIS_MODULE, "usb_endpoint");
        if (IS_ERR(ep_class->class)) {
-               result = IS_ERR(ep_class->class);
+               result = PTR_ERR(ep_class->class);
                goto class_create_error;
        }
 
index b531a4f..9bbcb20 100644 (file)
@@ -184,7 +184,7 @@ static void generic_disconnect(struct usb_device *udev)
        /* if this is only an unbind, not a physical disconnect, then
         * unconfigure the device */
        if (udev->actconfig)
-               usb_set_configuration(udev, 0);
+               usb_set_configuration(udev, -1);
 
        usb_remove_sysfs_dev_files(udev);
 }
index 590ec82..50c0db1 100644 (file)
@@ -44,6 +44,7 @@ struct usb_hub {
                struct usb_hub_status   hub;
                struct usb_port_status  port;
        }                       *status;        /* buffer for status reports */
+       struct mutex            status_mutex;   /* for the status buffer */
 
        int                     error;          /* last reported error */
        int                     nerrors;        /* track consecutive errors */
@@ -535,6 +536,7 @@ static int hub_hub_status(struct usb_hub *hub,
 {
        int ret;
 
+       mutex_lock(&hub->status_mutex);
        ret = get_hub_status(hub->hdev, &hub->status->hub);
        if (ret < 0)
                dev_err (hub->intfdev,
@@ -544,6 +546,7 @@ static int hub_hub_status(struct usb_hub *hub,
                *change = le16_to_cpu(hub->status->hub.wHubChange); 
                ret = 0;
        }
+       mutex_unlock(&hub->status_mutex);
        return ret;
 }
 
@@ -617,6 +620,7 @@ static int hub_configure(struct usb_hub *hub,
                ret = -ENOMEM;
                goto fail;
        }
+       mutex_init(&hub->status_mutex);
 
        hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
        if (!hub->descriptor) {
@@ -1396,6 +1400,7 @@ static int hub_port_status(struct usb_hub *hub, int port1,
 {
        int ret;
 
+       mutex_lock(&hub->status_mutex);
        ret = get_port_status(hub->hdev, port1, &hub->status->port);
        if (ret < 4) {
                dev_err (hub->intfdev,
@@ -1407,6 +1412,7 @@ static int hub_port_status(struct usb_hub *hub, int port1,
                *change = le16_to_cpu(hub->status->port.wPortChange); 
                ret = 0;
        }
+       mutex_unlock(&hub->status_mutex);
        return ret;
 }
 
@@ -1904,6 +1910,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
        struct usb_hub          *hub = usb_get_intfdata (intf);
        struct usb_device       *hdev = hub->hdev;
        unsigned                port1;
+       int                     status = 0;
 
        /* fail if children aren't already suspended */
        for (port1 = 1; port1 <= hdev->maxchild; port1++) {
@@ -1927,24 +1934,18 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
 
        dev_dbg(&intf->dev, "%s\n", __FUNCTION__);
 
+       /* stop khubd and related activity */
+       hub_quiesce(hub);
+
        /* "global suspend" of the downstream HC-to-USB interface */
        if (!hdev->parent) {
-               struct usb_bus  *bus = hdev->bus;
-               if (bus) {
-                       int     status = hcd_bus_suspend (bus);
-
-                       if (status != 0) {
-                               dev_dbg(&hdev->dev, "'global' suspend %d\n",
-                                       status);
-                               return status;
-                       }
-               } else
-                       return -EOPNOTSUPP;
+               status = hcd_bus_suspend(hdev->bus);
+               if (status != 0) {
+                       dev_dbg(&hdev->dev, "'global' suspend %d\n", status);
+                       hub_activate(hub);
+               }
        }
-
-       /* stop khubd and related activity */
-       hub_quiesce(hub);
-       return 0;
+       return status;
 }
 
 static int hub_resume(struct usb_interface *intf)
index 8aca357..74edaea 100644 (file)
@@ -1316,6 +1316,14 @@ static void release_interface(struct device *dev)
  * use this kind of configurability; many devices only have one
  * configuration.
  *
+ * @configuration is the value of the configuration to be installed.
+ * According to the USB spec (e.g. section 9.1.1.5), configuration values
+ * must be non-zero; a value of zero indicates that the device in
+ * unconfigured.  However some devices erroneously use 0 as one of their
+ * configuration values.  To help manage such devices, this routine will
+ * accept @configuration = -1 as indicating the device should be put in
+ * an unconfigured state.
+ *
  * USB device configurations may affect Linux interoperability,
  * power consumption and the functionality available.  For example,
  * the default configuration is limited to using 100mA of bus power,
@@ -1347,10 +1355,15 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
        struct usb_interface **new_interfaces = NULL;
        int n, nintf;
 
-       for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
-               if (dev->config[i].desc.bConfigurationValue == configuration) {
-                       cp = &dev->config[i];
-                       break;
+       if (configuration == -1)
+               configuration = 0;
+       else {
+               for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
+                       if (dev->config[i].desc.bConfigurationValue ==
+                                       configuration) {
+                               cp = &dev->config[i];
+                               break;
+                       }
                }
        }
        if ((!cp && configuration != 0))
@@ -1359,6 +1372,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
        /* The USB spec says configuration 0 means unconfigured.
         * But if a device includes a configuration numbered 0,
         * we will accept it as a correctly configured state.
+        * Use -1 if you really want to unconfigure the device.
         */
        if (cp && configuration == 0)
                dev_warn(&dev->dev, "config 0 descriptor??\n");
index 627a5a2..7f31a49 100644 (file)
@@ -31,7 +31,7 @@ static struct usb_device_id whitelist_table [] = {
 { USB_DEVICE_INFO(7, 1, 3) },
 #endif
 
-#ifdef CONFIG_USB_CDCETHER
+#ifdef CONFIG_USB_NET_CDCETHER
 /* Linux-USB CDC Ethernet gadget */
 { USB_DEVICE(0x0525, 0xa4a1), },
 /* Linux-USB CDC Ethernet + RNDIS gadget */
index 4eaa0ee..0edfbaf 100644 (file)
@@ -63,7 +63,7 @@ set_bConfigurationValue(struct device *dev, struct device_attribute *attr,
        struct usb_device       *udev = to_usb_device(dev);
        int                     config, value;
 
-       if (sscanf(buf, "%u", &config) != 1 || config > 255)
+       if (sscanf(buf, "%d", &config) != 1 || config < -1 || config > 255)
                return -EINVAL;
        usb_lock_device(udev);
        value = usb_set_configuration(udev, config);
index 36b36e0..82369c4 100644 (file)
@@ -784,7 +784,7 @@ static int at91_ep_set_halt(struct usb_ep *_ep, int value)
        return status;
 }
 
-static struct usb_ep_ops at91_ep_ops = {
+static const struct usb_ep_ops at91_ep_ops = {
        .enable         = at91_ep_enable,
        .disable        = at91_ep_disable,
        .alloc_request  = at91_ep_alloc_request,
@@ -1651,7 +1651,7 @@ static void at91udc_shutdown(struct platform_device *dev)
        pullup(platform_get_drvdata(dev), 0);
 }
 
-static int __devinit at91udc_probe(struct platform_device *pdev)
+static int __init at91udc_probe(struct platform_device *pdev)
 {
        struct device   *dev = &pdev->dev;
        struct at91_udc *udc;
@@ -1762,7 +1762,7 @@ fail0:
        return retval;
 }
 
-static int __devexit at91udc_remove(struct platform_device *pdev)
+static int __exit at91udc_remove(struct platform_device *pdev)
 {
        struct at91_udc *udc = platform_get_drvdata(pdev);
        struct resource *res;
@@ -1836,8 +1836,7 @@ static int at91udc_resume(struct platform_device *pdev)
 #endif
 
 static struct platform_driver at91_udc = {
-       .probe          = at91udc_probe,
-       .remove         = __devexit_p(at91udc_remove),
+       .remove         = __exit_p(at91udc_remove),
        .shutdown       = at91udc_shutdown,
        .suspend        = at91udc_suspend,
        .resume         = at91udc_resume,
@@ -1847,13 +1846,13 @@ static struct platform_driver at91_udc = {
        },
 };
 
-static int __devinit udc_init_module(void)
+static int __init udc_init_module(void)
 {
-       return platform_driver_register(&at91_udc);
+       return platform_driver_probe(&at91_udc, at91udc_probe);
 }
 module_init(udc_init_module);
 
-static void __devexit udc_exit_module(void)
+static void __exit udc_exit_module(void)
 {
        platform_driver_unregister(&at91_udc);
 }
index e6c19aa..e552668 100644 (file)
@@ -1699,6 +1699,7 @@ static int gs_setup_class(struct usb_gadget *gadget,
                        memcpy(&port->port_line_coding, req->buf, ret);
                        spin_unlock(&port->port_lock);
                }
+               ret = 0;
                break;
 
        case USB_CDC_REQ_GET_LINE_CODING:
index 185721d..a740564 100644 (file)
@@ -42,6 +42,9 @@
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/unaligned.h>
+#ifdef CONFIG_PPC_PS3
+#include <asm/firmware.h>
+#endif
 
 
 /*-------------------------------------------------------------------------*/
@@ -299,6 +302,19 @@ static void ehci_watchdog (unsigned long param)
        spin_unlock_irqrestore (&ehci->lock, flags);
 }
 
+/* On some systems, leaving remote wakeup enabled prevents system shutdown.
+ * The firmware seems to think that powering off is a wakeup event!
+ * This routine turns off remote wakeup and everything else, on all ports.
+ */
+static void ehci_turn_off_all_ports(struct ehci_hcd *ehci)
+{
+       int     port = HCS_N_PORTS(ehci->hcs_params);
+
+       while (port--)
+               ehci_writel(ehci, PORT_RWC_BITS,
+                               &ehci->regs->port_status[port]);
+}
+
 /* ehci_shutdown kick in for silicon on any bus (not just pci, etc).
  * This forcibly disables dma and IRQs, helping kexec and other cases
  * where the next system software may expect clean state.
@@ -310,9 +326,13 @@ ehci_shutdown (struct usb_hcd *hcd)
 
        ehci = hcd_to_ehci (hcd);
        (void) ehci_halt (ehci);
+       ehci_turn_off_all_ports(ehci);
 
        /* make BIOS/etc use companion controller during reboot */
        ehci_writel(ehci, 0, &ehci->regs->configured_flag);
+
+       /* unblock posted writes */
+       ehci_readl(ehci, &ehci->regs->configured_flag);
 }
 
 static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
@@ -951,15 +971,18 @@ static int __init ehci_hcd_init(void)
 #endif
 
 #ifdef PS3_SYSTEM_BUS_DRIVER
-       retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER);
-       if (retval < 0) {
+       if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
+               retval = ps3_system_bus_driver_register(
+                               &PS3_SYSTEM_BUS_DRIVER);
+               if (retval < 0) {
 #ifdef PLATFORM_DRIVER
-               platform_driver_unregister(&PLATFORM_DRIVER);
+                       platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
 #ifdef PCI_DRIVER
-               pci_unregister_driver(&PCI_DRIVER);
+                       pci_unregister_driver(&PCI_DRIVER);
 #endif
-               return retval;
+                       return retval;
+               }
        }
 #endif
 
@@ -976,7 +999,8 @@ static void __exit ehci_hcd_cleanup(void)
        pci_unregister_driver(&PCI_DRIVER);
 #endif
 #ifdef PS3_SYSTEM_BUS_DRIVER
-       ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
+       if (firmware_has_feature(FW_FEATURE_PS3_LV1))
+               ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
 #endif
 }
 module_exit(ehci_hcd_cleanup);
index 0d83c6d..9af529d 100644 (file)
@@ -36,6 +36,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
        int                     port;
        int                     mask;
 
+       ehci_dbg(ehci, "suspend root hub\n");
+
        if (time_before (jiffies, ehci->next_statechange))
                msleep(5);
 
index 2718b5d..46873f2 100644 (file)
@@ -1577,7 +1577,7 @@ static int isp116x_remove(struct platform_device *pdev)
 
 #define resource_len(r) (((r)->end - (r)->start) + 1)
 
-static int __init isp116x_probe(struct platform_device *pdev)
+static int __devinit isp116x_probe(struct platform_device *pdev)
 {
        struct usb_hcd *hcd;
        struct isp116x *isp116x;
index 9303464..d849c80 100644 (file)
 #include <asm/mach-types.h>
 #include <asm/hardware.h>
 #include <asm/arch/board.h>
+#include <asm/arch/cpu.h>
 
 #ifndef CONFIG_ARCH_AT91
 #error "CONFIG_ARCH_AT91 must be defined."
 #endif
 
-/* interface and function clocks */
-static struct clk *iclk, *fclk;
+/* interface and function clocks; sometimes also an AHB clock */
+static struct clk *iclk, *fclk, *hclk;
 static int clocked;
 
 extern int usb_disabled(void);
 
 /*-------------------------------------------------------------------------*/
 
+static void at91_start_clock(void)
+{
+       if (cpu_is_at91sam9261())
+               clk_enable(hclk);
+       clk_enable(iclk);
+       clk_enable(fclk);
+       clocked = 1;
+}
+
+static void at91_stop_clock(void)
+{
+       clk_disable(fclk);
+       clk_disable(iclk);
+       if (cpu_is_at91sam9261())
+               clk_disable(hclk);
+       clocked = 0;
+}
+
 static void at91_start_hc(struct platform_device *pdev)
 {
        struct usb_hcd *hcd = platform_get_drvdata(pdev);
@@ -41,9 +60,7 @@ static void at91_start_hc(struct platform_device *pdev)
        /*
         * Start the USB clocks.
         */
-       clk_enable(iclk);
-       clk_enable(fclk);
-       clocked = 1;
+       at91_start_clock();
 
        /*
         * The USB host controller must remain in reset.
@@ -66,9 +83,7 @@ static void at91_stop_hc(struct platform_device *pdev)
        /*
         * Stop the USB clocks.
         */
-       clk_disable(fclk);
-       clk_disable(iclk);
-       clocked = 0;
+       at91_stop_clock();
 }
 
 
@@ -126,6 +141,8 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
 
        iclk = clk_get(&pdev->dev, "ohci_clk");
        fclk = clk_get(&pdev->dev, "uhpck");
+       if (cpu_is_at91sam9261())
+               hclk = clk_get(&pdev->dev, "hck0");
 
        at91_start_hc(pdev);
        ohci_hcd_init(hcd_to_ohci(hcd));
@@ -137,6 +154,8 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
        /* Error handling */
        at91_stop_hc(pdev);
 
+       if (cpu_is_at91sam9261())
+               clk_put(hclk);
        clk_put(fclk);
        clk_put(iclk);
 
@@ -171,9 +190,11 @@ static int usb_hcd_at91_remove(struct usb_hcd *hcd,
        iounmap(hcd->regs);
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 
+       if (cpu_is_at91sam9261())
+               clk_put(hclk);
        clk_put(fclk);
        clk_put(iclk);
-       fclk = iclk = NULL;
+       fclk = iclk = hclk = NULL;
 
        dev_set_drvdata(&pdev->dev, NULL);
        return 0;
@@ -280,9 +301,7 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
         */
        if (at91_suspend_entering_slow_clock()) {
                ohci_usb_reset (ohci);
-               clk_disable(fclk);
-               clk_disable(iclk);
-               clocked = 0;
+               at91_stop_clock();
        }
 
        return 0;
@@ -295,11 +314,8 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
        if (device_may_wakeup(&pdev->dev))
                disable_irq_wake(hcd->irq);
 
-       if (!clocked) {
-               clk_enable(iclk);
-               clk_enable(fclk);
-               clocked = 1;
-       }
+       if (!clocked)
+               at91_start_clock();
 
        return 0;
 }
index fa6a7ce..f0d29ed 100644 (file)
@@ -42,6 +42,9 @@
 #include <asm/system.h>
 #include <asm/unaligned.h>
 #include <asm/byteorder.h>
+#ifdef CONFIG_PPC_PS3
+#include <asm/firmware.h>
+#endif
 
 #include "../core/hcd.h"
 
@@ -944,9 +947,12 @@ static int __init ohci_hcd_mod_init(void)
                sizeof (struct ed), sizeof (struct td));
 
 #ifdef PS3_SYSTEM_BUS_DRIVER
-       retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER);
-       if (retval < 0)
-               goto error_ps3;
+       if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
+               retval = ps3_system_bus_driver_register(
+                               &PS3_SYSTEM_BUS_DRIVER);
+               if (retval < 0)
+                       goto error_ps3;
+       }
 #endif
 
 #ifdef PLATFORM_DRIVER
@@ -992,7 +998,8 @@ static int __init ohci_hcd_mod_init(void)
  error_platform:
 #endif
 #ifdef PS3_SYSTEM_BUS_DRIVER
-       ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
+       if (firmware_has_feature(FW_FEATURE_PS3_LV1))
+               ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
  error_ps3:
 #endif
        return retval;
@@ -1014,7 +1021,8 @@ static void __exit ohci_hcd_mod_exit(void)
        platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
 #ifdef PS3_SYSTEM_BUS_DRIVER
-       ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
+       if (firmware_has_feature(FW_FEATURE_PS3_LV1))
+               ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
 #endif
 }
 module_exit(ohci_hcd_mod_exit);
index 4d8ed3d..ef09952 100644 (file)
@@ -515,6 +515,7 @@ void usbhid_close(struct hid_device *hid)
 
 #define USB_VENDOR_ID_TURBOX           0x062a
 #define USB_DEVICE_ID_TURBOX_KEYBOARD  0x0201
+#define USB_VENDOR_ID_CIDC             0x1677
 
 /*
  * Initialize all reports
@@ -548,7 +549,6 @@ void usbhid_init_reports(struct hid_device *hid)
 }
 
 #define USB_VENDOR_ID_GTCO             0x078c
-#define USB_VENDOR_ID_GTCO_IPANEL_2     0x5543
 #define USB_DEVICE_ID_GTCO_90          0x0090
 #define USB_DEVICE_ID_GTCO_100         0x0100
 #define USB_DEVICE_ID_GTCO_101         0x0101
@@ -594,8 +594,6 @@ void usbhid_init_reports(struct hid_device *hid)
 #define USB_DEVICE_ID_GTCO_1004                0x1004
 #define USB_DEVICE_ID_GTCO_1005                0x1005
 #define USB_DEVICE_ID_GTCO_1006                0x1006
-#define USB_DEVICE_ID_GTCO_8           0x0008
-#define USB_DEVICE_ID_GTCO_d            0x000d
 
 #define USB_VENDOR_ID_WACOM            0x056a
 
@@ -854,8 +852,6 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006, HID_QUIRK_IGNORE },
-       { USB_VENDOR_ID_GTCO_IPANEL_2, USB_DEVICE_ID_GTCO_8, HID_QUIRK_IGNORE },
-       { USB_VENDOR_ID_GTCO_IPANEL_2, USB_DEVICE_ID_GTCO_d, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY, HID_QUIRK_IGNORE },
@@ -953,6 +949,8 @@ static const struct hid_blacklist {
 
        { USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER },
 
+       { USB_VENDOR_ID_CIDC, 0x0103, HID_QUIRK_IGNORE },
+
        { 0, 0 }
 };
 
index a74bf86..4907e8b 100644 (file)
@@ -88,6 +88,17 @@ config USB_LCD
          To compile this driver as a module, choose M here: the
          module will be called usblcd.
 
+config USB_BERRY_CHARGE
+       tristate "USB BlackBerry recharge support"
+       depends on USB
+       help
+         Say Y here if you want to connect a BlackBerry device to your
+         computer's USB port and have it automatically switch to "recharge"
+         mode.
+
+         To compile this driver as a module, choose M here: the
+         module will be called berry_charge.
+
 config USB_LED
        tristate "USB LED driver support"
        depends on USB
index 2cba07d..dac2d5b 100644 (file)
@@ -6,6 +6,7 @@
 obj-$(CONFIG_USB_ADUTUX)       += adutux.o
 obj-$(CONFIG_USB_APPLEDISPLAY) += appledisplay.o
 obj-$(CONFIG_USB_AUERSWALD)    += auerswald.o
+obj-$(CONFIG_USB_BERRY_CHARGE) += berry_charge.o
 obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o
 obj-$(CONFIG_USB_CYTHERM)      += cytherm.o
 obj-$(CONFIG_USB_EMI26)                += emi26.o
index 32f0e3a..e573c8b 100644 (file)
@@ -281,8 +281,8 @@ static int appledisplay_probe(struct usb_interface *iface,
        /* Register backlight device */
        snprintf(bl_name, sizeof(bl_name), "appledisplay%d",
                atomic_inc_return(&count_displays) - 1);
-       pdata->bd = backlight_device_register(bl_name, NULL,
-               pdata, &appledisplay_bl_data);
+       pdata->bd = backlight_device_register(bl_name, NULL, pdata,
+                                               &appledisplay_bl_data);
        if (IS_ERR(pdata->bd)) {
                err("appledisplay: Backlight registration failed");
                goto error;
diff --git a/drivers/usb/misc/berry_charge.c b/drivers/usb/misc/berry_charge.c
new file mode 100644 (file)
index 0000000..60893c6
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * USB BlackBerry charging module
+ *
+ * Copyright (C) 2007 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ *     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, version 2.
+ *
+ * Information on how to switch configs was taken by the bcharge.cc file
+ * created by the barry.sf.net project.
+ *
+ * bcharge.cc has the following copyright:
+ *     Copyright (C) 2006, Net Direct Inc. (http://www.netdirect.ca/)
+ * and is released under the GPLv2.
+ *
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#define RIM_VENDOR             0x0fca
+#define BLACKBERRY             0x0001
+
+static int debug;
+
+#ifdef dbg
+#undef dbg
+#endif
+#define dbg(dev, format, arg...)                               \
+       if (debug)                                              \
+               dev_printk(KERN_DEBUG , dev , format , ## arg)
+
+static struct usb_device_id id_table [] = {
+       { USB_DEVICE(RIM_VENDOR, BLACKBERRY) },
+       { },                                    /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static int magic_charge(struct usb_device *udev)
+{
+       char *dummy_buffer = kzalloc(2, GFP_KERNEL);
+       int retval;
+
+       if (!dummy_buffer)
+               return -ENOMEM;
+
+       /* send two magic commands and then set the configuration.  The device
+        * will then reset itself with the new power usage and should start
+        * charging. */
+
+       /* Note, with testing, it only seems that the first message is really
+        * needed (at least for the 8700c), but to be safe, we emulate what
+        * other operating systems seem to be sending to their device.  We
+        * really need to get some specs for this device to be sure about what
+        * is going on here.
+        */
+       dbg(&udev->dev, "Sending first magic command\n");
+       retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+                                0xa5, 0xc0, 0, 1, dummy_buffer, 2, 100);
+       if (retval != 2) {
+               dev_err(&udev->dev, "First magic command failed: %d.\n",
+                       retval);
+               return retval;
+       }
+
+       dbg(&udev->dev, "Sending first magic command\n");
+       retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+                                0xa2, 0x40, 0, 1, dummy_buffer, 0, 100);
+       if (retval != 0) {
+               dev_err(&udev->dev, "Second magic command failed: %d.\n",
+                       retval);
+               return retval;
+       }
+
+       dbg(&udev->dev, "Calling set_configuration\n");
+       retval = usb_driver_set_configuration(udev, 1);
+       if (retval)
+               dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval);
+
+       return retval;
+}
+
+static int berry_probe(struct usb_interface *intf,
+                      const struct usb_device_id *id)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+
+       dbg(&udev->dev, "Power is set to %dmA\n",
+           udev->actconfig->desc.bMaxPower * 2);
+
+       /* check the power usage so we don't try to enable something that is
+        * already enabled */
+       if ((udev->actconfig->desc.bMaxPower * 2) == 500) {
+               dbg(&udev->dev, "device is already charging, power is "
+                   "set to %dmA\n", udev->actconfig->desc.bMaxPower * 2);
+               return -ENODEV;
+       }
+
+       /* turn the power on */
+       magic_charge(udev);
+
+       /* we don't really want to bind to the device, userspace programs can
+        * handle the syncing just fine, so get outta here. */
+       return -ENODEV;
+}
+
+static void berry_disconnect(struct usb_interface *intf)
+{
+}
+
+static struct usb_driver berry_driver = {
+       .name =         "berry_charge",
+       .probe =        berry_probe,
+       .disconnect =   berry_disconnect,
+       .id_table =     id_table,
+};
+
+static int __init berry_init(void)
+{
+       return usb_register(&berry_driver);
+}
+
+static void __exit berry_exit(void)
+{
+       usb_deregister(&berry_driver);
+}
+
+module_init(berry_init);
+module_exit(berry_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>");
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
index a2b94ef..0f3d7db 100644 (file)
@@ -84,6 +84,7 @@ config USB_PEGASUS
 config USB_RTL8150
        tristate "USB RTL8150 based ethernet device support (EXPERIMENTAL)"
        depends on EXPERIMENTAL
+       select MII
        help
          Say Y here if you have RTL8150 based usb-ethernet adapter.
          Send me <petkan@users.sourceforge.net> any comments you may have.
@@ -98,7 +99,7 @@ config USB_USBNET_MII
 
 config USB_USBNET
        tristate "Multi-purpose USB Networking Framework"
-       select MII if USBNET_MII != n
+       select MII if USB_USBNET_MII != n
        ---help---
          This driver supports several kinds of network links over USB,
          with "minidrivers" built around a common network driver core
@@ -239,6 +240,7 @@ config USB_NET_RNDIS_HOST
 config USB_NET_CDC_SUBSET
        tristate "Simple USB Network Links (CDC Ethernet subset)"
        depends on USB_USBNET
+       default y
        help
          This driver module supports USB network devices that can work
          without any device-specific information.  Select it if you have
@@ -298,6 +300,13 @@ config USB_EPSON2888
          Choose this option to support the usb networking links used
          by some sample firmware from Epson.
 
+config USB_KC2190
+       boolean "KT Technology KC2190 based cables (InstaNet)"
+       depends on USB_NET_CDC_SUBSET && EXPERIMENTAL
+       help
+        Â Choose this option if you're using a host-to-host cable
+        Â with one of these chips.
+
 config USB_NET_ZAURUS
        tristate "Sharp Zaurus (stock ROMs) and compatible"
        depends on USB_USBNET
index bd357e1..7ef2e4b 100644 (file)
@@ -351,9 +351,11 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
 
        skb_push(skb, 4);
        packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4);
+       cpu_to_le32s(&packet_len);
        memcpy(skb->data, &packet_len, sizeof(packet_len));
 
        if ((skb->len % 512) == 0) {
+               cpu_to_le32s(&padbytes);
                memcpy( skb->tail, &padbytes, sizeof(padbytes));
                skb_put(skb, sizeof(padbytes));
        }
index ae8fb06..bc62b01 100644 (file)
@@ -79,13 +79,19 @@ static int always_connected (struct usbnet *dev)
  *
  * ALi M5632 driver ... does high speed
  *
+ * NOTE that the MS-Windows drivers for this chip use some funky and
+ * (naturally) undocumented 7-byte prefix to each packet, so this is a
+ * case where we don't currently interoperate.  Also, once you unplug
+ * one end of the cable, you need to replug the other end too ... since
+ * chip docs are unavailable, there's no way to reset the relevant state
+ * short of a power cycle.
+ *
  *-------------------------------------------------------------------------*/
 
 static const struct driver_info        ali_m5632_info = {
        .description =  "ALi M5632",
 };
 
-
 #endif
 
 \f
@@ -159,6 +165,11 @@ static const struct driver_info    epson2888_info = {
 #endif /* CONFIG_USB_EPSON2888 */
 
 \f
+/*-------------------------------------------------------------------------
+ *
+ * info from Jonathan McDowell <noodles@earth.li>
+ *
+ *-------------------------------------------------------------------------*/
 #ifdef CONFIG_USB_KC2190
 #define HAVE_HARDWARE
 static const struct driver_info kc2190_info = {
@@ -223,6 +234,10 @@ static const struct usb_device_id  products [] = {
        USB_DEVICE (0x0402, 0x5632),    // ALi defaults
        .driver_info =  (unsigned long) &ali_m5632_info,
 },
+{
+       USB_DEVICE (0x182d,0x207c),     // SiteCom CN-124
+       .driver_info =  (unsigned long) &ali_m5632_info,
+},
 #endif
 
 #ifdef CONFIG_USB_AN2720
@@ -314,13 +329,13 @@ static struct usb_driver cdc_subset_driver = {
 
 static int __init cdc_subset_init(void)
 {
-       return usb_register(&cdc_subset_driver);
+       return usb_register(&cdc_subset_driver);
 }
 module_init(cdc_subset_init);
 
 static void __exit cdc_subset_exit(void)
 {
-       usb_deregister(&cdc_subset_driver);
+       usb_deregister(&cdc_subset_driver);
 }
 module_exit(cdc_subset_exit);
 
index 43ba61a..de69b18 100644 (file)
@@ -147,7 +147,7 @@ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf)
                if (tmp < 0)
                        return tmp;
        }
-       
+
        dev->in = usb_rcvbulkpipe (dev->udev,
                        in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
        dev->out = usb_sndbulkpipe (dev->udev,
@@ -327,7 +327,7 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
        if (netif_running (dev->net)
                        && netif_device_present (dev->net)
                        && !test_bit (EVENT_RX_HALT, &dev->flags)) {
-               switch (retval = usb_submit_urb (urb, GFP_ATOMIC)){ 
+               switch (retval = usb_submit_urb (urb, GFP_ATOMIC)){
                case -EPIPE:
                        usbnet_defer_kevent (dev, EVENT_RX_HALT);
                        break;
@@ -443,7 +443,7 @@ block:
            case -EOVERFLOW:
                dev->stats.rx_over_errors++;
                // FALLTHROUGH
-           
+
            default:
                entry->state = rx_cleanup;
                dev->stats.rx_errors++;
@@ -560,7 +560,7 @@ static int usbnet_stop (struct net_device *net)
 
        if (netif_msg_ifdown (dev))
                devinfo (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld",
-                       dev->stats.rx_packets, dev->stats.tx_packets, 
+                       dev->stats.rx_packets, dev->stats.tx_packets,
                        dev->stats.rx_errors, dev->stats.tx_errors
                        );
 
@@ -578,7 +578,7 @@ static int usbnet_stop (struct net_device *net)
                        devdbg (dev, "waited for %d urb completions", temp);
        }
        dev->wait = NULL;
-       remove_wait_queue (&unlink_wakeup, &wait); 
+       remove_wait_queue (&unlink_wakeup, &wait);
 
        usb_kill_urb(dev->interrupt);
 
@@ -834,7 +834,7 @@ kevent (struct work_struct *work)
        }
 
        if (test_bit (EVENT_LINK_RESET, &dev->flags)) {
-               struct driver_info      *info = dev->driver_info;
+               struct driver_info      *info = dev->driver_info;
                int                     retval = 0;
 
                clear_bit (EVENT_LINK_RESET, &dev->flags);
@@ -1066,7 +1066,7 @@ static void usbnet_bh (unsigned long param)
  * USB Device Driver support
  *
  *-------------------------------------------------------------------------*/
+
 // precondition: never called in_interrupt
 
 void usbnet_disconnect (struct usb_interface *intf)
@@ -1087,7 +1087,7 @@ void usbnet_disconnect (struct usb_interface *intf)
                        intf->dev.driver->name,
                        xdev->bus->bus_name, xdev->devpath,
                        dev->driver_info->description);
-       
+
        net = dev->net;
        unregister_netdev (net);
 
@@ -1111,7 +1111,7 @@ int
 usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 {
        struct usbnet                   *dev;
-       struct net_device               *net;
+       struct net_device               *net;
        struct usb_host_interface       *interface;
        struct driver_info              *info;
        struct usb_device               *xdev;
@@ -1181,6 +1181,9 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
        // NOTE net->name still not usable ...
        if (info->bind) {
                status = info->bind (dev, udev);
+               if (status < 0)
+                       goto out1;
+
                // heuristic:  "usb%d" for links we know are two-host,
                // else "eth%d" when there's reasonable doubt.  userspace
                // can rename the link if it knows better.
@@ -1207,12 +1210,12 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
        if (status == 0 && dev->status)
                status = init_status (dev, udev);
        if (status < 0)
-               goto out1;
+               goto out3;
 
        if (!dev->rx_urb_size)
                dev->rx_urb_size = dev->hard_mtu;
        dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1);
-       
+
        SET_NETDEV_DEV(net, &udev->dev);
        status = register_netdev (net);
        if (status)
@@ -1255,7 +1258,7 @@ EXPORT_SYMBOL_GPL(usbnet_probe);
 int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
 {
        struct usbnet           *dev = usb_get_intfdata(intf);
-       
+
        /* accelerate emptying of the rx and queues, to avoid
         * having everything error out.
         */
@@ -1286,7 +1289,7 @@ static int __init usbnet_init(void)
                        < sizeof (struct skb_data));
 
        random_ether_addr(node_id);
-       return 0;
+       return 0;
 }
 module_init(usbnet_init);
 
index 0af42e3..18816bf 100644 (file)
@@ -58,11 +58,6 @@ static void airprime_read_bulk_callback(struct urb *urb)
        if (urb->status) {
                dbg("%s - nonzero read bulk status received: %d",
                    __FUNCTION__, urb->status);
-               /* something happened, so free up the memory for this urb */
-               if (urb->transfer_buffer) {
-                       kfree (urb->transfer_buffer);
-                       urb->transfer_buffer = NULL;
-               }
                return;
        }
        usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
@@ -146,6 +141,8 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp)
                                  airprime_read_bulk_callback, port);
                result = usb_submit_urb(urb, GFP_KERNEL);
                if (result) {
+                       usb_free_urb(urb);
+                       kfree(buffer);
                        dev_err(&port->dev,
                                "%s - failed submitting read urb %d for port %d, error %d\n",
                                __FUNCTION__, i, port->number, result);
@@ -160,27 +157,12 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp)
        /* some error happened, cancel any submitted urbs and clean up anything that
           got allocated successfully */
 
-       for ( ; i >= 0; --i) {
+       while (i-- != 0) {
                urb = priv->read_urbp[i];
-               if (urb) {
-                       /* This urb was submitted successfully. So we have to
-                          cancel it.
-                          Unlinking the urb will invoke read_bulk_callback()
-                          with an error status, so its transfer buffer will
-                          be freed there */
-                       if (usb_unlink_urb (urb) != -EINPROGRESS) {
-                               /* comments in drivers/usb/core/urb.c say this
-                                  can only happen if the urb was never submitted,
-                                  or has completed already.
-                                  Either way we may have to free the transfer
-                                  buffer here. */
-                               if (urb->transfer_buffer) {
-                                       kfree (urb->transfer_buffer);
-                                       urb->transfer_buffer = NULL;
-                               }
-                       }
-                       usb_free_urb (urb);
-               }
+               buffer = urb->transfer_buffer;
+               usb_kill_urb (urb);
+               usb_free_urb (urb);
+               kfree (buffer);
        }
 
  out:
@@ -194,10 +176,9 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp)
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       /* killing the urb will invoke read_bulk_callback() with an error status,
-          so the transfer buffer will be freed there */
        for (i = 0; i < NUM_READ_URBS; ++i) {
                usb_kill_urb (priv->read_urbp[i]);
+               kfree (priv->read_urbp[i]->transfer_buffer);
                usb_free_urb (priv->read_urbp[i]);
        }
 
index 3ec2487..db623e7 100644 (file)
@@ -69,6 +69,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
        { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
+       { USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */
        { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
        { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
        { } /* Terminating Entry */
index 601e064..53baeec 100644 (file)
@@ -66,6 +66,8 @@ struct usb_serial_driver usb_serial_generic_device = {
        .num_bulk_out =         NUM_DONT_CARE,
        .num_ports =            1,
        .shutdown =             usb_serial_generic_shutdown,
+       .throttle =             usb_serial_generic_throttle,
+       .unthrottle =           usb_serial_generic_unthrottle,
 };
 
 static int generic_probe(struct usb_interface *interface,
@@ -115,6 +117,7 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial *serial = port->serial;
        int result = 0;
+       unsigned long flags;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -124,7 +127,13 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp)
        if (port->tty)
                port->tty->low_latency = 1;
 
-       /* if we have a bulk interrupt, start reading from it */
+       /* clear the throttle flags */
+       spin_lock_irqsave(&port->lock, flags);
+       port->throttled = 0;
+       port->throttle_req = 0;
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       /* if we have a bulk endpoint, start reading from it */
        if (serial->num_bulk_in) {
                /* Start reading from the device */
                usb_fill_bulk_urb (port->read_urb, serial->dev,
@@ -253,31 +262,22 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port)
        return (chars);
 }
 
-void usb_serial_generic_read_bulk_callback (struct urb *urb)
+/* Push data to tty layer and resubmit the bulk read URB */
+static void flush_and_resubmit_read_urb (struct usb_serial_port *port)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct usb_serial *serial = port->serial;
-       struct tty_struct *tty;
-       unsigned char *data = urb->transfer_buffer;
+       struct urb *urb = port->read_urb;
+       struct tty_struct *tty = port->tty;
        int result;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
-
-       if (urb->status) {
-               dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
-               return;
-       }
-
-       usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
-
-       tty = port->tty;
+       /* Push data to tty */
        if (tty && urb->actual_length) {
                tty_buffer_request_room(tty, urb->actual_length);
-               tty_insert_flip_string(tty, data, urb->actual_length);
-               tty_flip_buffer_push(tty);
+               tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length);
+               tty_flip_buffer_push(tty); /* is this allowed from an URB callback ? */
        }
 
-       /* Continue trying to always read  */
+       /* Continue reading from device */
        usb_fill_bulk_urb (port->read_urb, serial->dev,
                           usb_rcvbulkpipe (serial->dev,
                                            port->bulk_in_endpointAddress),
@@ -290,6 +290,40 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb)
        if (result)
                dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
 }
+
+void usb_serial_generic_read_bulk_callback (struct urb *urb)
+{
+       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       unsigned char *data = urb->transfer_buffer;
+       int is_throttled;
+       unsigned long flags;
+
+       dbg("%s - port %d", __FUNCTION__, port->number);
+
+       if (urb->status) {
+               dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
+               return;
+       }
+
+       usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
+
+       /* Throttle the device if requested by tty */
+       if (urb->actual_length) {
+               spin_lock_irqsave(&port->lock, flags);
+               is_throttled = port->throttled = port->throttle_req;
+               spin_unlock_irqrestore(&port->lock, flags);
+               if (is_throttled) {
+                       /* Let the received data linger in the read URB;
+                        * usb_serial_generic_unthrottle() will pick it
+                        * up later. */
+                       dbg("%s - throttling device", __FUNCTION__);
+                       return;
+               }
+       }
+
+       /* Handle data and continue reading from device */
+       flush_and_resubmit_read_urb(port);
+}
 EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
 
 void usb_serial_generic_write_bulk_callback (struct urb *urb)
@@ -308,6 +342,38 @@ void usb_serial_generic_write_bulk_callback (struct urb *urb)
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
 
+void usb_serial_generic_throttle (struct usb_serial_port *port)
+{
+       unsigned long flags;
+
+       dbg("%s - port %d", __FUNCTION__, port->number);
+
+       /* Set the throttle request flag. It will be picked up
+        * by usb_serial_generic_read_bulk_callback(). */
+       spin_lock_irqsave(&port->lock, flags);
+       port->throttle_req = 1;
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+void usb_serial_generic_unthrottle (struct usb_serial_port *port)
+{
+       int was_throttled;
+       unsigned long flags;
+
+       dbg("%s - port %d", __FUNCTION__, port->number);
+
+       /* Clear the throttle flags */
+       spin_lock_irqsave(&port->lock, flags);
+       was_throttled = port->throttled;
+       port->throttled = port->throttle_req = 0;
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       if (was_throttled) {
+               /* Handle pending data and resume reading from device */
+               flush_and_resubmit_read_urb(port);
+       }
+}
+
 void usb_serial_generic_shutdown (struct usb_serial *serial)
 {
        int i;
index ced9f32..9963a8b 100644 (file)
@@ -69,7 +69,6 @@ static int  option_send_setup(struct usb_serial_port *port);
 /* Vendor and product IDs */
 #define OPTION_VENDOR_ID                0x0AF0
 #define HUAWEI_VENDOR_ID                0x12D1
-#define AUDIOVOX_VENDOR_ID              0x0F3D
 #define NOVATELWIRELESS_VENDOR_ID       0x1410
 #define ANYDATA_VENDOR_ID               0x16d5
 
@@ -81,7 +80,6 @@ static int  option_send_setup(struct usb_serial_port *port);
 #define OPTION_PRODUCT_GTMAX36          0x6701
 #define HUAWEI_PRODUCT_E600             0x1001
 #define HUAWEI_PRODUCT_E220             0x1003
-#define AUDIOVOX_PRODUCT_AIRCARD        0x0112
 #define NOVATELWIRELESS_PRODUCT_U740    0x1400
 #define ANYDATA_PRODUCT_ID              0x6501
 
@@ -94,7 +92,6 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) },
        { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
        { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
-       { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
        { } /* Terminating entry */
@@ -109,7 +106,6 @@ static struct usb_device_id option_ids1[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) },
        { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
        { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
-       { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
        { } /* Terminating entry */
index 6c083d4..83dfae9 100644 (file)
@@ -83,6 +83,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) },
        { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },
        { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) },
+       { USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },
        { }                                     /* Terminating entry */
 };
 
index 65a5039..f9a71d0 100644 (file)
@@ -97,3 +97,8 @@
 /* Huawei E620 UMTS/HSDPA card (ID: 12d1:1001) */
 #define HUAWEI_VENDOR_ID       0x12d1
 #define HUAWEI_PRODUCT_ID      0x1001
+
+/* Willcom WS002IN Data Driver (by NetIndex Inc.) */
+#define WS002IN_VENDOR_ID      0x11f6
+#define WS002IN_PRODUCT_ID     0x2001
+
index 70234f5..e227f64 100644 (file)
@@ -153,6 +153,12 @@ static int slave_configure(struct scsi_device *sdev)
                if (us->flags & US_FL_FIX_CAPACITY)
                        sdev->fix_capacity = 1;
 
+               /* A few disks have two indistinguishable version, one of
+                * which reports the correct capacity and the other does not.
+                * The sd driver has to guess which is the case. */
+               if (us->flags & US_FL_CAPACITY_HEURISTICS)
+                       sdev->guess_capacity = 1;
+
                /* Some devices report a SCSI revision level above 2 but are
                 * unable to handle the REPORT LUNS command (for which
                 * support is mandatory at level 3).  Since we already have
index f49a62f..9644a8e 100644 (file)
@@ -1101,6 +1101,15 @@ UNUSUAL_DEV(  0x08bd, 0x1100, 0x0000, 0x0000,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_SINGLE_LUN),
 
+/* Submitted by Dylan Taft <d13f00l@gmail.com>
+ * US_FL_IGNORE_RESIDUE Needed
+ */
+UNUSUAL_DEV(  0x08ca, 0x3103, 0x0100, 0x0100,
+                "AIPTEK",
+                "Aiptek USB Keychain MP3 Player",
+                US_SC_DEVICE, US_PR_DEVICE, NULL,
+                US_FL_IGNORE_RESIDUE),
+
 /* Entry needed for flags. Moreover, all devices with this ID use
  * bulk-only transport, but _some_ falsely report Control/Bulk instead.
  * One example is "Trumpion Digital Research MYMP3".
@@ -1311,12 +1320,13 @@ UNUSUAL_DEV(  0x0fce, 0xd008, 0x0000, 0x0000,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_NO_WP_DETECT ),
 
-/* Reported by Jan Mate <mate@fiit.stuba.sk> */
+/* Reported by Jan Mate <mate@fiit.stuba.sk>
+ * and by Soeren Sonnenburg <kernel@nn7.de> */
 UNUSUAL_DEV(  0x0fce, 0xe030, 0x0000, 0x0000,
                "Sony Ericsson",
                "P990i",
                US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY ),
+               US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ),
 
 /* Reported by Emmanuel Vasilakis <evas@forthnet.gr> */
 UNUSUAL_DEV(  0x0fce, 0xe031, 0x0000, 0x0000,
@@ -1385,6 +1395,16 @@ UNUSUAL_DEV(  0x1652, 0x6600, 0x0201, 0x0201,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_IGNORE_RESIDUE ),
 
+/* Reported by Thomas Baechler <thomas@archlinux.org>
+ * Fixes I/O errors with Teac HD-35PU devices
+ */
+
+UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201,
+               "Super Top",
+               "USB 2.0  IDE DEVICE",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_IGNORE_RESIDUE),
+
 /* patch submitted by Davide Perini <perini.davide@dpsoftware.org>
  * and Renato Perini <rperini@email.it>
  */
@@ -1423,7 +1443,7 @@ UNUSUAL_DEV(  0xed06, 0x4500, 0x0001, 0x0001,
                "DataStor",
                "USB4500 FW1.04",
                US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY),
+               US_FL_CAPACITY_HEURISTICS),
 
 /* Control/Bulk transport for all SubClass values */
 USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR),
index 296b091..46929a1 100644 (file)
@@ -90,13 +90,15 @@ static int skel_open(struct inode *inode, struct file *file)
                goto exit;
        }
 
+       /* increment our usage count for the device */
+       kref_get(&dev->kref);
+
        /* prevent the device from being autosuspended */
        retval = usb_autopm_get_interface(interface);
-       if (retval)
+       if (retval) {
+               kref_put(&dev->kref, skel_delete);
                goto exit;
-
-       /* increment our usage count for the device */
-       kref_get(&dev->kref);
+       }
 
        /* save our object in the file's private structure */
        file->private_data = dev;
index 8d130cc..682f928 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
+#include <linux/namei.h>
 #include <linux/debugfs.h>
 
 static ssize_t default_read_file(struct file *file, char __user *buf,
@@ -44,6 +45,17 @@ const struct file_operations debugfs_file_operations = {
        .open =         default_open,
 };
 
+static void *debugfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+       nd_set_link(nd, dentry->d_inode->i_private);
+       return NULL;
+}
+
+const struct inode_operations debugfs_link_operations = {
+       .readlink       = generic_readlink,
+       .follow_link    = debugfs_follow_link,
+};
+
 static void debugfs_u8_set(void *data, u64 val)
 {
        *(u8 *)data = val;
index c692487..7b324cf 100644 (file)
 #include <linux/namei.h>
 #include <linux/debugfs.h>
 #include <linux/fsnotify.h>
+#include <linux/string.h>
 
 #define DEBUGFS_MAGIC  0x64626720
 
 /* declared over in file.c */
 extern struct file_operations debugfs_file_operations;
+extern struct inode_operations debugfs_link_operations;
 
 static struct vfsmount *debugfs_mount;
 static int debugfs_mount_count;
@@ -51,6 +53,9 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d
                case S_IFREG:
                        inode->i_fop = &debugfs_file_operations;
                        break;
+               case S_IFLNK:
+                       inode->i_op = &debugfs_link_operations;
+                       break;
                case S_IFDIR:
                        inode->i_op = &simple_dir_inode_operations;
                        inode->i_fop = &simple_dir_operations;
@@ -96,6 +101,12 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        return res;
 }
 
+static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode)
+{
+       mode = (mode & S_IALLUGO) | S_IFLNK;
+       return debugfs_mknod(dir, dentry, mode, 0);
+}
+
 static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode)
 {
        int res;
@@ -158,10 +169,17 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
        mutex_lock(&parent->d_inode->i_mutex);
        *dentry = lookup_one_len(name, parent, strlen(name));
        if (!IS_ERR(*dentry)) {
-               if ((mode & S_IFMT) == S_IFDIR)
+               switch (mode & S_IFMT) {
+               case S_IFDIR:
                        error = debugfs_mkdir(parent->d_inode, *dentry, mode);
-               else 
+                       break;
+               case S_IFLNK:
+                       error = debugfs_link(parent->d_inode, *dentry, mode);
+                       break;
+               default:
                        error = debugfs_create(parent->d_inode, *dentry, mode);
+                       break;
+               }
                dput(*dentry);
        } else
                error = PTR_ERR(*dentry);
@@ -194,9 +212,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
  * you are responsible here.)  If an error occurs, %NULL will be returned.
  *
  * If debugfs is not enabled in the kernel, the value -%ENODEV will be
- * returned.  It is not wise to check for this value, but rather, check for
- * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
- * code.
+ * returned.
  */
 struct dentry *debugfs_create_file(const char *name, mode_t mode,
                                   struct dentry *parent, void *data,
@@ -246,9 +262,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_file);
  * you are responsible here.)  If an error occurs, %NULL will be returned.
  *
  * If debugfs is not enabled in the kernel, the value -%ENODEV will be
- * returned.  It is not wise to check for this value, but rather, check for
- * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
- * code.
+ * returned.
  */
 struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
 {
@@ -258,6 +272,47 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
 }
 EXPORT_SYMBOL_GPL(debugfs_create_dir);
 
+/**
+ * debugfs_create_symlink- create a symbolic link in the debugfs filesystem
+ * @name: a pointer to a string containing the name of the symbolic link to
+ *        create.
+ * @parent: a pointer to the parent dentry for this symbolic link.  This
+ *          should be a directory dentry if set.  If this paramater is NULL,
+ *          then the symbolic link will be created in the root of the debugfs
+ *          filesystem.
+ * @target: a pointer to a string containing the path to the target of the
+ *          symbolic link.
+ *
+ * This function creates a symbolic link with the given name in debugfs that
+ * links to the given target path.
+ *
+ * This function will return a pointer to a dentry if it succeeds.  This
+ * pointer must be passed to the debugfs_remove() function when the symbolic
+ * link is to be removed (no automatic cleanup happens if your module is
+ * unloaded, you are responsible here.)  If an error occurs, %NULL will be
+ * returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be
+ * returned.
+ */
+struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
+                                     const char *target)
+{
+       struct dentry *result;
+       char *link;
+
+       link = kstrdup(target, GFP_KERNEL);
+       if (!link)
+               return NULL;
+
+       result = debugfs_create_file(name, S_IFLNK | S_IRWXUGO, parent, link,
+                                    NULL);
+       if (!result)
+               kfree(link);
+       return result;
+}
+EXPORT_SYMBOL_GPL(debugfs_create_symlink);
+
 /**
  * debugfs_remove - removes a file or directory from the debugfs filesystem
  * @dentry: a pointer to a the dentry of the file or directory to be
@@ -287,15 +342,22 @@ void debugfs_remove(struct dentry *dentry)
        if (debugfs_positive(dentry)) {
                if (dentry->d_inode) {
                        dget(dentry);
-                       if (S_ISDIR(dentry->d_inode->i_mode)) {
+                       switch (dentry->d_inode->i_mode & S_IFMT) {
+                       case S_IFDIR:
                                ret = simple_rmdir(parent->d_inode, dentry);
                                if (ret)
                                        printk(KERN_ERR
                                                "DebugFS rmdir on %s failed : "
                                                "directory not empty.\n",
                                                dentry->d_name.name);
-                       } else
+                               break;
+                       case S_IFLNK:
+                               kfree(dentry->d_inode->i_private);
+                               /* fall through */
+                       default:
                                simple_unlink(parent->d_inode, dentry);
+                               break;
+                       }
                        if (!ret)
                                d_delete(dentry);
                        dput(dentry);
index ac32a2e..22d38ff 100644 (file)
@@ -358,8 +358,7 @@ void delete_partition(struct gendisk *disk, int part)
        p->ios[0] = p->ios[1] = 0;
        p->sectors[0] = p->sectors[1] = 0;
        sysfs_remove_link(&p->kobj, "subsystem");
-       if (p->holder_dir)
-               kobject_unregister(p->holder_dir);
+       kobject_unregister(p->holder_dir);
        kobject_uevent(&p->kobj, KOBJ_REMOVE);
        kobject_del(&p->kobj);
        kobject_put(&p->kobj);
@@ -603,10 +602,8 @@ void del_gendisk(struct gendisk *disk)
        disk->stamp = 0;
 
        kobject_uevent(&disk->kobj, KOBJ_REMOVE);
-       if (disk->holder_dir)
-               kobject_unregister(disk->holder_dir);
-       if (disk->slave_dir)
-               kobject_unregister(disk->slave_dir);
+       kobject_unregister(disk->holder_dir);
+       kobject_unregister(disk->slave_dir);
        if (disk->driverfs_dev) {
                char *disk_name = make_block_name(disk);
                sysfs_remove_link(&disk->kobj, "device");
index ce7c9d6..73967c8 100644 (file)
@@ -253,7 +253,8 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
 
 void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread);
 
-void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc);
+void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc,
+                         struct acpi_thread_state *thread);
 
 /*
  * exprep - ACPI AML execution - prep utilities
index 04e9735..5206d61 100644 (file)
@@ -155,7 +155,7 @@ struct acpi_object_event {
 struct acpi_object_mutex {
        ACPI_OBJECT_COMMON_HEADER u8 sync_level;        /* 0-15, specified in Mutex() call */
        u16 acquisition_depth;  /* Allow multiple Acquires, same thread */
-       struct acpi_thread_state *owner_thread; /* Current owner of the mutex */
+       acpi_thread_id owner_thread_id; /* Current owner of the mutex */
        acpi_mutex os_mutex;    /* Actual OS synchronization object */
        union acpi_operand_object *prev;        /* Link for list of acquired mutexes */
        union acpi_operand_object *next;        /* Link for list of acquired mutexes */
index 4dc8a50..f6275b0 100644 (file)
@@ -105,12 +105,6 @@ int acpi_ec_ecdt_probe(void);
 
 int acpi_processor_set_thermal_limit(acpi_handle handle, int type);
 
-/* --------------------------------------------------------------------------
-                                    Hot Keys
-   -------------------------------------------------------------------------- */
-
-extern int acpi_specific_hotkey_enabled;
-
 /*--------------------------------------------------------------------------
                                   Dock Station
   -------------------------------------------------------------------------- */
@@ -122,10 +116,34 @@ extern int register_hotplug_dock_device(acpi_handle handle,
        acpi_notify_handler handler, void *context);
 extern void unregister_hotplug_dock_device(acpi_handle handle);
 #else
-#define is_dock_device(h)                      (0)
-#define register_dock_notifier(nb)             (-ENODEV)
-#define unregister_dock_notifier(nb)                   do { } while(0)
-#define register_hotplug_dock_device(h1, h2, c)        (-ENODEV)
-#define unregister_hotplug_dock_device(h)       do { } while(0)
+static inline int is_dock_device(acpi_handle handle)
+{
+       return 0;
+}
+static inline int register_dock_notifier(struct notifier_block *nb)
+{
+       return -ENODEV;
+}
+static inline void unregister_dock_notifier(struct notifier_block *nb)
+{
+}
+static inline int register_hotplug_dock_device(acpi_handle handle,
+                               acpi_notify_handler handler, void *context)
+{
+       return -ENODEV;
+}
+static inline void unregister_hotplug_dock_device(acpi_handle handle)
+{
+}
+#endif
+
+/*--------------------------------------------------------------------------
+                                  Suspend/Resume
+  -------------------------------------------------------------------------- */
+#ifdef CONFIG_ACPI_SLEEP
+extern int acpi_sleep_init(void);
+#else
+#define acpi_sleep_init() do {} while (0)
 #endif
+
 #endif /*__ACPI_DRIVERS_H__*/
index 781394b..2785058 100644 (file)
@@ -240,12 +240,6 @@ acpi_status
 acpi_os_validate_address(u8 space_id,
                         acpi_physical_address address, acpi_size length);
 
-u8 acpi_os_readable(void *pointer, acpi_size length);
-
-#ifdef ACPI_FUTURE_USAGE
-u8 acpi_os_writable(void *pointer, acpi_size length);
-#endif
-
 u64 acpi_os_get_timer(void);
 
 acpi_status acpi_os_signal(u32 function, void *info);
index 5e657eb..449f3f2 100644 (file)
@@ -127,6 +127,7 @@ extern int acpi_irq_balance_set(char *str);
 #define acpi_ioapic 0
 static inline void acpi_noirq_set(void) { }
 static inline void acpi_disable_pci(void) { }
+static inline void disable_acpi(void) { }
 
 #endif /* !CONFIG_ACPI */
 
index 815f1fb..8bcfaa4 100644 (file)
@@ -75,7 +75,7 @@ enum acpi_address_range_id {
 
 typedef int (*acpi_table_handler) (struct acpi_table_header *table);
 
-typedef int (*acpi_madt_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
+typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
 
 char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
 unsigned long acpi_find_rsdp (void);
@@ -85,8 +85,10 @@ int acpi_numa_init (void);
 
 int acpi_table_init (void);
 int acpi_table_parse (char *id, acpi_table_handler handler);
-int acpi_table_parse_madt (enum acpi_madt_type id, acpi_madt_entry_handler handler, unsigned int max_entries);
-int acpi_table_parse_srat (enum acpi_srat_type id, acpi_madt_entry_handler handler, unsigned int max_entries);
+int __init acpi_table_parse_entries(char *id, unsigned long table_size,
+       int entry_id, acpi_table_entry_handler handler, unsigned int max_entries);
+int acpi_table_parse_madt (enum acpi_madt_type id, acpi_table_entry_handler handler, unsigned int max_entries);
+int acpi_table_parse_srat (enum acpi_srat_type id, acpi_table_entry_handler handler, unsigned int max_entries);
 int acpi_parse_mcfg (struct acpi_table_header *header);
 void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
 void acpi_table_print_srat_entry (struct acpi_subtable_header *srat);
index 047567d..9fa0983 100644 (file)
@@ -33,6 +33,9 @@ struct dentry *debugfs_create_file(const char *name, mode_t mode,
 
 struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);
 
+struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
+                                     const char *dest);
+
 void debugfs_remove(struct dentry *dentry);
 
 struct dentry *debugfs_create_u8(const char *name, mode_t mode,
@@ -70,6 +73,13 @@ static inline struct dentry *debugfs_create_dir(const char *name,
        return ERR_PTR(-ENODEV);
 }
 
+static inline struct dentry *debugfs_create_symlink(const char *name,
+                                                   struct dentry *parent,
+                                                   const char *dest)
+{
+       return ERR_PTR(-ENODEV);
+}
+
 static inline void debugfs_remove(struct dentry *dentry)
 { }
 
index 26e4692..d5b1b7b 100644 (file)
@@ -2,6 +2,7 @@
  * device.h - generic, centralized driver model
  *
  * Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org>
+ * Copyright (c) 2004-2007 Greg Kroah-Hartman <gregkh@suse.de>
  *
  * This file is released under the GPLv2
  *
index 10f505c..cc8e674 100644 (file)
 #ifdef CONFIG_KMOD
 /* modprobe exit status on success, -ve on error.  Return value
  * usually useless though. */
+extern void kmod_sysfs_init(void);
 extern int request_module(const char * name, ...) __attribute__ ((format (printf, 1, 2)));
 #else
+static inline void kmod_sysfs_init(void) {};
 static inline int request_module(const char * name, ...) { return -ENOSYS; }
 #endif
 
index 419d3ef..95679eb 100644 (file)
@@ -76,8 +76,6 @@ void sort_extable(struct exception_table_entry *start,
                  struct exception_table_entry *finish);
 void sort_main_extable(void);
 
-extern struct subsystem module_subsys;
-
 #ifdef MODULE
 #define MODULE_GENERIC_TABLE(gtype,name)                       \
 extern const struct gtype##_id __mod_##gtype##_table           \
@@ -467,10 +465,6 @@ int unregister_module_notifier(struct notifier_block * nb);
 
 extern void print_modules(void);
 
-struct device_driver;
-void module_add_driver(struct module *, struct device_driver *);
-void module_remove_driver(struct device_driver *);
-
 #else /* !CONFIG_MODULES... */
 #define EXPORT_SYMBOL(sym)
 #define EXPORT_SYMBOL_GPL(sym)
@@ -568,18 +562,59 @@ static inline void print_modules(void)
 {
 }
 
+#endif /* CONFIG_MODULES */
+
 struct device_driver;
+#ifdef CONFIG_SYSFS
 struct module;
 
-static inline void module_add_driver(struct module *module, struct device_driver *driver)
+extern struct subsystem module_subsys;
+
+int mod_sysfs_init(struct module *mod);
+int mod_sysfs_setup(struct module *mod,
+                          struct kernel_param *kparam,
+                          unsigned int num_params);
+int module_add_modinfo_attrs(struct module *mod);
+void module_remove_modinfo_attrs(struct module *mod);
+
+#else /* !CONFIG_SYSFS */
+
+static inline int mod_sysfs_init(struct module *mod)
 {
+       return 0;
 }
 
-static inline void module_remove_driver(struct device_driver *driver)
+static inline int mod_sysfs_setup(struct module *mod,
+                          struct kernel_param *kparam,
+                          unsigned int num_params)
 {
+       return 0;
 }
 
-#endif /* CONFIG_MODULES */
+static inline int module_add_modinfo_attrs(struct module *mod)
+{
+       return 0;
+}
+
+static inline void module_remove_modinfo_attrs(struct module *mod)
+{ }
+
+#endif /* CONFIG_SYSFS */
+
+#if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES)
+
+void module_add_driver(struct module *mod, struct device_driver *drv);
+void module_remove_driver(struct device_driver *drv);
+
+#else /* not both CONFIG_SYSFS && CONFIG_MODULES */
+
+static inline void module_add_driver(struct module *mod, struct device_driver *drv)
+{ }
+
+static inline void module_remove_driver(struct device_driver *drv)
+{ }
+
+#endif
 
 #define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x)
 
index 4a189da..b26b2e5 100644 (file)
@@ -169,10 +169,22 @@ extern int param_get_string(char *buffer, struct kernel_param *kp);
 
 struct module;
 
+#if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES)
 extern int module_param_sysfs_setup(struct module *mod,
                                    struct kernel_param *kparam,
                                    unsigned int num_params);
 
 extern void module_param_sysfs_remove(struct module *mod);
+#else
+static inline int module_param_sysfs_setup(struct module *mod,
+                            struct kernel_param *kparam,
+                            unsigned int num_params)
+{
+       return 0;
+}
+
+static inline void module_param_sysfs_remove(struct module *mod)
+{ }
+#endif
 
 #endif /* _LINUX_MODULE_PARAMS_H */
index b5c226a..a8e8d1e 100644 (file)
@@ -935,7 +935,7 @@ struct usb_iso_packet_descriptor {
        unsigned int offset;
        unsigned int length;            /* expected length */
        unsigned int actual_length;
-       unsigned int status;
+       int status;
 };
 
 struct urb;
index ba617c3..956edf3 100644 (file)
@@ -73,6 +73,13 @@ struct usb_cdc_acm_descriptor {
        __u8    bmCapabilities;
 } __attribute__ ((packed));
 
+/* capabilities from 5.2.3.3 */
+
+#define USB_CDC_COMM_FEATURE   0x01
+#define USB_CDC_CAP_LINE       0x02
+#define USB_CDC_CAP_BRK        0x04
+#define USB_CDC_CAP_NOTIFY     0x08
+
 /* "Union Functional Descriptor" from CDC spec 5.2.3.8 */
 struct usb_cdc_union_desc {
        __u8    bLength;
index ae78337..245c725 100644 (file)
@@ -367,7 +367,7 @@ struct usb_debug_descriptor {
        /* bulk endpoints with 8 byte maxpacket */
        __u8  bDebugInEndpoint;
        __u8  bDebugOutEndpoint;
-};
+} __attribute__((packed));
 
 /*-------------------------------------------------------------------------*/
 
@@ -396,7 +396,7 @@ struct usb_security_descriptor {
 
        __le16 wTotalLength;
        __u8  bNumEncryptionTypes;
-};
+} __attribute__((packed));
 
 /*-------------------------------------------------------------------------*/
 
@@ -410,7 +410,7 @@ struct usb_key_descriptor {
        __u8  tTKID[3];
        __u8  bReserved;
        __u8  bKeyData[0];
-};
+} __attribute__((packed));
 
 /*-------------------------------------------------------------------------*/
 
@@ -426,7 +426,7 @@ struct usb_encryption_descriptor {
 #define        USB_ENC_TYPE_RSA_1              3       /* rsa3072/sha1 auth */
        __u8  bEncryptionValue;         /* use in SET_ENCRYPTION */
        __u8  bAuthKeyIndex;
-};
+} __attribute__((packed));
 
 
 /*-------------------------------------------------------------------------*/
@@ -438,7 +438,7 @@ struct usb_bos_descriptor {
 
        __le16 wTotalLength;
        __u8  bNumDeviceCaps;
-};
+} __attribute__((packed));
 
 /*-------------------------------------------------------------------------*/
 
@@ -447,7 +447,7 @@ struct usb_dev_cap_header {
        __u8  bLength;
        __u8  bDescriptorType;
        __u8  bDevCapabilityType;
-};
+} __attribute__((packed));
 
 #define        USB_CAP_TYPE_WIRELESS_USB       1
 
@@ -475,7 +475,7 @@ struct usb_wireless_cap_descriptor {        /* Ultra Wide Band */
        __u8  bmFFITXPowerInfo; /* FFI power levels */
        __le16 bmBandGroup;
        __u8  bReserved;
-};
+} __attribute__((packed));
 
 /*-------------------------------------------------------------------------*/
 
@@ -496,7 +496,7 @@ struct usb_wireless_ep_comp_descriptor {
 #define USB_ENDPOINT_SWITCH_NO         0
 #define USB_ENDPOINT_SWITCH_SWITCH     1
 #define USB_ENDPOINT_SWITCH_SCALE      2
-};
+} __attribute__((packed));
 
 /*-------------------------------------------------------------------------*/
 
@@ -512,7 +512,7 @@ struct usb_handshake {
        __u8 CDID[16];
        __u8 nonce[16];
        __u8 MIC[8];
-};
+} __attribute__((packed));
 
 /*-------------------------------------------------------------------------*/
 
@@ -524,7 +524,7 @@ struct usb_connection_context {
        __u8 CHID[16];          /* persistent host id */
        __u8 CDID[16];          /* device id (unique w/in host context) */
        __u8 CK[16];            /* connection key */
-};
+} __attribute__((packed));
 
 /*-------------------------------------------------------------------------*/
 
index 33dcd85..32acbae 100644 (file)
@@ -54,6 +54,8 @@
  * @write_wait: a wait_queue_head_t used by the port.
  * @work: work queue entry for the line discipline waking up.
  * @open_count: number of times this port has been opened.
+ * @throttled: nonzero if the read urb is inactive to throttle the device
+ * @throttle_req: nonzero if the tty wants to throttle us
  *
  * This structure is used by the usb-serial core and drivers for the specific
  * ports of a device.
@@ -88,6 +90,8 @@ struct usb_serial_port {
        wait_queue_head_t       write_wait;
        struct work_struct      work;
        int                     open_count;
+       char                    throttled;
+       char                    throttle_req;
        struct device           dev;
 };
 #define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev)
@@ -269,6 +273,8 @@ extern int usb_serial_generic_write_room (struct usb_serial_port *port);
 extern int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port);
 extern void usb_serial_generic_read_bulk_callback (struct urb *urb);
 extern void usb_serial_generic_write_bulk_callback (struct urb *urb);
+extern void usb_serial_generic_throttle (struct usb_serial_port *port);
+extern void usb_serial_generic_unthrottle (struct usb_serial_port *port);
 extern void usb_serial_generic_shutdown (struct usb_serial *serial);
 extern int usb_serial_generic_register (int debug);
 extern void usb_serial_generic_deregister (void);
index 2ae76fe..1b792b9 100644 (file)
@@ -46,7 +46,9 @@
        US_FLAG(MAX_SECTORS_64, 0x00000400)                     \
                /* Sets max_sectors to 64    */                 \
        US_FLAG(IGNORE_DEVICE,  0x00000800)                     \
-               /* Don't claim device */
+               /* Don't claim device */                        \
+       US_FLAG(CAPACITY_HEURISTICS,    0x00001000)             \
+               /* sometimes sizes is too big */
 
 #define US_FLAG(name, value)   US_FL_##name = value ,
 enum { US_DO_ALL_FLAGS };
index 617d8a1..342dd5a 100644 (file)
@@ -159,9 +159,9 @@ struct usbdevfs_ioctl32 {
 #define USBDEVFS_SUBMITURB32       _IOR('U', 10, struct usbdevfs_urb32)
 #define USBDEVFS_DISCARDURB        _IO('U', 11)
 #define USBDEVFS_REAPURB           _IOW('U', 12, void *)
-#define USBDEVFS_REAPURB32         _IOW('U', 12, u32)
+#define USBDEVFS_REAPURB32         _IOW('U', 12, __u32)
 #define USBDEVFS_REAPURBNDELAY     _IOW('U', 13, void *)
-#define USBDEVFS_REAPURBNDELAY32   _IOW('U', 13, u32)
+#define USBDEVFS_REAPURBNDELAY32   _IOW('U', 13, __u32)
 #define USBDEVFS_DISCSIGNAL        _IOR('U', 14, struct usbdevfs_disconnectsignal)
 #define USBDEVFS_CLAIMINTERFACE    _IOR('U', 15, unsigned int)
 #define USBDEVFS_RELEASEINTERFACE  _IOR('U', 16, unsigned int)
index c1da855..eae7e2e 100644 (file)
@@ -95,6 +95,7 @@
 #define PRODID_QUATECH_DUAL_RS232      0x0012
 #define PRODID_QUATECH_DUAL_RS232_D1   0x0007
 #define PRODID_QUATECH_DUAL_RS232_D2   0x0052
+#define PRODID_QUATECH_DUAL_RS232_G    0x004d
 #define PRODID_QUATECH_QUAD_RS232      0x001b
 #define PRODID_QUATECH_DUAL_RS422      0x000e
 #define PRODID_QUATECH_QUAD_RS422      0x0045
index ebf31b1..9dd37e2 100644 (file)
@@ -122,6 +122,7 @@ struct scsi_device {
        unsigned no_uld_attach:1; /* disable connecting to upper level drivers */
        unsigned select_no_atn:1;
        unsigned fix_capacity:1;        /* READ_CAPACITY is too high by 1 */
+       unsigned guess_capacity:1;      /* READ_CAPACITY might be too high by 1 */
        unsigned retry_hwerror:1;       /* Retry HARDWARE_ERROR */
 
        unsigned int device_blocked;    /* Device returned QUEUE_FULL. */
index 7962761..9f923f8 100644 (file)
@@ -36,6 +36,8 @@
 #include <linux/resource.h>
 #include <asm/uaccess.h>
 
+extern int delete_module(const char *name, unsigned int flags);
+
 extern int max_threads;
 
 static struct workqueue_struct *khelper_wq;
@@ -46,6 +48,7 @@ static struct workqueue_struct *khelper_wq;
        modprobe_path is set via /proc/sys.
 */
 char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
+struct module_kobject kmod_mk;
 
 /**
  * request_module - try to load a kernel module
@@ -75,6 +78,11 @@ int request_module(const char *fmt, ...)
        static atomic_t kmod_concurrent = ATOMIC_INIT(0);
 #define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */
        static int kmod_loop_msg;
+       char modalias[16 + MODULE_NAME_LEN] = "MODALIAS=";
+       char *uevent_envp[2] = {
+               modalias,
+               NULL
+       };
 
        va_start(args, fmt);
        ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args);
@@ -82,6 +90,12 @@ int request_module(const char *fmt, ...)
        if (ret >= MODULE_NAME_LEN)
                return -ENAMETOOLONG;
 
+       strcpy(&modalias[strlen("MODALIAS=")], module_name);
+       kobject_uevent_env(&kmod_mk.kobj, KOBJ_CHANGE, uevent_envp);
+
+       if (modprobe_path[0] == '\0')
+               goto out;
+
        /* If modprobe needs a service that is in a module, we get a recursive
         * loop.  Limit the number of running kmod threads to max_threads/2 or
         * MAX_KMOD_CONCURRENT, whichever is the smaller.  A cleaner method
@@ -108,9 +122,115 @@ int request_module(const char *fmt, ...)
 
        ret = call_usermodehelper(modprobe_path, argv, envp, 1);
        atomic_dec(&kmod_concurrent);
+out:
        return ret;
 }
 EXPORT_SYMBOL(request_module);
+
+static ssize_t store_mod_request(struct module_attribute *mattr,
+                                struct module *mod,
+                             const char *buffer, size_t count)
+{
+       char name[MODULE_NAME_LEN];
+       int ret;
+
+       if (count < 1 || count+1 > MODULE_NAME_LEN)
+               return -EINVAL;
+       memcpy(name, buffer, count);
+       name[count] = '\0';
+       if (name[count-1] == '\n')
+               name[count-1] = '\0';
+
+       ret = request_module(name);
+       if (ret < 0)
+               return ret;
+       return count;
+}
+
+static struct module_attribute mod_request = {
+       .attr = { .name = "mod_request", .mode = S_IWUSR, .owner = THIS_MODULE },
+       .store = store_mod_request,
+};
+
+#ifdef CONFIG_MODULE_UNLOAD
+static ssize_t store_mod_unload(struct module_attribute *mattr,
+                           struct module *mod,
+                           const char *buffer, size_t count)
+{
+       char name[MODULE_NAME_LEN];
+       int ret;
+
+       if (count < 1 || count+1 > MODULE_NAME_LEN)
+               return -EINVAL;
+       memcpy(name, buffer, count);
+       name[count] = '\0';
+       if (name[count-1] == '\n')
+               name[count-1] = '\0';
+
+       ret = delete_module(name, O_NONBLOCK);
+       if (ret < 0)
+               return ret;
+       return count;
+}
+
+static struct module_attribute mod_unload = {
+       .attr = { .name = "mod_unload", .mode = S_IWUSR, .owner = THIS_MODULE },
+       .store = store_mod_unload,
+};
+#endif
+
+static ssize_t show_mod_request_helper(struct module_attribute *mattr,
+                                      struct module *mod,
+                                      char *buffer)
+{
+       return sprintf(buffer, "%s\n", modprobe_path);
+}
+
+static ssize_t store_mod_request_helper(struct module_attribute *mattr,
+                                       struct module *mod,
+                                       const char *buffer, size_t count)
+{
+       if (count < 1 || count+1 > KMOD_PATH_LEN)
+               return -EINVAL;
+       memcpy(modprobe_path, buffer, count);
+       modprobe_path[count] = '\0';
+       if (modprobe_path[count-1] == '\n')
+               modprobe_path[count-1] = '\0';
+       return count;
+}
+
+static struct module_attribute mod_request_helper = {
+       .attr = {
+               .name = "mod_request_helper",
+               .mode = S_IWUSR | S_IRUGO,
+               .owner = THIS_MODULE
+       },
+       .show = show_mod_request_helper,
+       .store = store_mod_request_helper,
+};
+
+void __init kmod_sysfs_init(void)
+{
+       int ret;
+
+       kmod_mk.mod = THIS_MODULE;
+       kobj_set_kset_s(&kmod_mk, module_subsys);
+       kobject_set_name(&kmod_mk.kobj, "kmod");
+       kobject_init(&kmod_mk.kobj);
+       ret = kobject_add(&kmod_mk.kobj);
+       if (ret < 0)
+               goto out;
+
+       ret = sysfs_create_file(&kmod_mk.kobj, &mod_request_helper.attr);
+       ret = sysfs_create_file(&kmod_mk.kobj, &mod_request.attr);
+#ifdef CONFIG_MODULE_UNLOAD
+       ret = sysfs_create_file(&kmod_mk.kobj, &mod_unload.attr);
+#endif
+
+       kobject_uevent(&kmod_mk.kobj, KOBJ_ADD);
+out:
+       return;
+}
 #endif /* CONFIG_KMOD */
 
 struct subprocess_info {
index 8a94e05..8c25b1a 100644 (file)
@@ -653,20 +653,11 @@ static void wait_for_zero_refcount(struct module *mod)
        mutex_lock(&module_mutex);
 }
 
-asmlinkage long
-sys_delete_module(const char __user *name_user, unsigned int flags)
+int delete_module(const char *name, unsigned int flags)
 {
        struct module *mod;
-       char name[MODULE_NAME_LEN];
        int ret, forced = 0;
 
-       if (!capable(CAP_SYS_MODULE))
-               return -EPERM;
-
-       if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
-               return -EFAULT;
-       name[MODULE_NAME_LEN-1] = '\0';
-
        if (mutex_lock_interruptible(&module_mutex) != 0)
                return -EINTR;
 
@@ -727,6 +718,21 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
        return ret;
 }
 
+asmlinkage long
+sys_delete_module(const char __user *name_user, unsigned int flags)
+{
+       char name[MODULE_NAME_LEN];
+
+       if (!capable(CAP_SYS_MODULE))
+               return -EPERM;
+
+       if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
+               return -EFAULT;
+       name[MODULE_NAME_LEN-1] = '\0';
+
+       return delete_module(name, flags);
+}
+
 static void print_unload_info(struct seq_file *m, struct module *mod)
 {
        struct module_use *use;
@@ -1068,7 +1074,8 @@ static inline void remove_sect_attrs(struct module *mod)
 }
 #endif /* CONFIG_KALLSYMS */
 
-static int module_add_modinfo_attrs(struct module *mod)
+#ifdef CONFIG_SYSFS
+int module_add_modinfo_attrs(struct module *mod)
 {
        struct module_attribute *attr;
        struct module_attribute *temp_attr;
@@ -1094,7 +1101,7 @@ static int module_add_modinfo_attrs(struct module *mod)
        return error;
 }
 
-static void module_remove_modinfo_attrs(struct module *mod)
+void module_remove_modinfo_attrs(struct module *mod)
 {
        struct module_attribute *attr;
        int i;
@@ -1109,8 +1116,10 @@ static void module_remove_modinfo_attrs(struct module *mod)
        }
        kfree(mod->modinfo_attrs);
 }
+#endif
 
-static int mod_sysfs_init(struct module *mod)
+#ifdef CONFIG_SYSFS
+int mod_sysfs_init(struct module *mod)
 {
        int err;
 
@@ -1133,7 +1142,7 @@ out:
        return err;
 }
 
-static int mod_sysfs_setup(struct module *mod,
+int mod_sysfs_setup(struct module *mod,
                           struct kernel_param *kparam,
                           unsigned int num_params)
 {
@@ -1169,16 +1178,14 @@ out_unreg:
 out:
        return err;
 }
+#endif
 
 static void mod_kobject_remove(struct module *mod)
 {
        module_remove_modinfo_attrs(mod);
        module_param_sysfs_remove(mod);
-       if (mod->mkobj.drivers_dir)
-               kobject_unregister(mod->mkobj.drivers_dir);
-       if (mod->holders_dir)
-               kobject_unregister(mod->holders_dir);
-
+       kobject_unregister(mod->mkobj.drivers_dir);
+       kobject_unregister(mod->holders_dir);
        kobject_unregister(&mod->mkobj.kobj);
 }
 
@@ -2345,6 +2352,7 @@ void print_modules(void)
        printk("\n");
 }
 
+#ifdef CONFIG_SYSFS
 static char *make_driver_name(struct device_driver *drv)
 {
        char *driver_name;
@@ -2419,6 +2427,7 @@ void module_remove_driver(struct device_driver *drv)
        }
 }
 EXPORT_SYMBOL(module_remove_driver);
+#endif
 
 #ifdef CONFIG_MODVERSIONS
 /* Generate the signature for struct module here, too, for modversions. */
index 553cf7d..7a75157 100644 (file)
@@ -30,8 +30,6 @@
 #define DEBUGP(fmt, a...)
 #endif
 
-static struct kobj_type module_ktype;
-
 static inline char dash2underscore(char c)
 {
        if (c == '-')
@@ -391,6 +389,7 @@ struct module_param_attrs
        struct param_attribute attrs[0];
 };
 
+#ifdef CONFIG_SYSFS
 #define to_param_attr(n) container_of(n, struct param_attribute, mattr);
 
 static ssize_t param_attr_show(struct module_attribute *mattr,
@@ -426,6 +425,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
                return len;
        return err;
 }
+#endif
 
 #ifdef CONFIG_MODULES
 #define __modinit
@@ -433,6 +433,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
 #define __modinit __init
 #endif
 
+#ifdef CONFIG_SYSFS
 /*
  * param_sysfs_setup - setup sysfs support for one module or KBUILD_MODNAME
  * @mk: struct module_kobject (contains parent kobject)
@@ -500,9 +501,7 @@ param_sysfs_setup(struct module_kobject *mk,
        return mp;
 }
 
-
 #ifdef CONFIG_MODULES
-
 /*
  * module_param_sysfs_setup - setup sysfs support for one module
  * @mod: module
@@ -625,7 +624,6 @@ static void __init param_sysfs_builtin(void)
 
 
 /* module-related sysfs stuff */
-#ifdef CONFIG_SYSFS
 
 #define to_module_attr(n) container_of(n, struct module_attribute, attr);
 #define to_module_kobject(n) container_of(n, struct module_kobject, kobj);
@@ -673,6 +671,8 @@ static struct sysfs_ops module_sysfs_ops = {
        .store = module_attr_store,
 };
 
+static struct kobj_type module_ktype;
+
 static int uevent_filter(struct kset *kset, struct kobject *kobj)
 {
        struct kobj_type *ktype = get_ktype(kobj);
@@ -686,19 +686,12 @@ static struct kset_uevent_ops module_uevent_ops = {
        .filter = uevent_filter,
 };
 
-#else
-static struct sysfs_ops module_sysfs_ops = {
-       .show = NULL,
-       .store = NULL,
-};
-#endif
+decl_subsys(module, &module_ktype, &module_uevent_ops);
 
 static struct kobj_type module_ktype = {
        .sysfs_ops =    &module_sysfs_ops,
 };
 
-decl_subsys(module, &module_ktype, &module_uevent_ops);
-
 /*
  * param_sysfs_init - wrapper for built-in params support
  */
@@ -714,11 +707,21 @@ static int __init param_sysfs_init(void)
        }
 
        param_sysfs_builtin();
+       kmod_sysfs_init();
 
        return 0;
 }
 subsys_initcall(param_sysfs_init);
 
+#else
+#if 0
+static struct sysfs_ops module_sysfs_ops = {
+       .show = NULL,
+       .store = NULL,
+};
+#endif
+#endif
+
 EXPORT_SYMBOL(param_set_byte);
 EXPORT_SYMBOL(param_get_byte);
 EXPORT_SYMBOL(param_set_short);
index 4572809..f4f6176 100644 (file)
@@ -171,7 +171,7 @@ int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent)
                return -ENOENT;
        if (!kobj->k_name)
                kobj->k_name = kobj->name;
-       if (!kobj->k_name) {
+       if (!*kobj->k_name) {
                pr_debug("kobject attempted to be registered with no name!\n");
                WARN_ON(1);
                return -EINVAL;