From fc255baf6a0e2fb6af147ae978e2abb0a652269a Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 16 Sep 2009 15:24:17 +0200 Subject: [PATCH] --- yaml --- r: 166918 b: refs/heads/master c: 77b1ab1732feb5e3dcbaf31d2f7547c5229f5f3a h: refs/heads/master v: v3 --- [refs] | 2 +- .../ABI/testing/sysfs-bus-pci-devices-cciss | 28 - trunk/Documentation/hwmon/ltc4215 | 7 +- trunk/Documentation/hwmon/ltc4245 | 7 +- .../{misc-devices => i2c/chips}/eeprom | 0 .../{misc-devices => i2c/chips}/max6875 | 6 +- trunk/Documentation/i2c/instantiating-devices | 2 +- trunk/Documentation/kernel-parameters.txt | 1 - trunk/Documentation/w1/masters/ds2482 | 6 +- trunk/MAINTAINERS | 7 - trunk/Makefile | 2 +- trunk/arch/m68knommu/kernel/asm-offsets.c | 28 +- trunk/arch/m68knommu/kernel/entry.S | 6 +- trunk/arch/m68knommu/mm/init.c | 2 +- trunk/arch/m68knommu/platform/5206e/config.c | 1 + trunk/arch/m68knommu/platform/68328/entry.S | 32 +- trunk/arch/m68knommu/platform/68360/entry.S | 16 +- .../arch/m68knommu/platform/coldfire/entry.S | 20 +- trunk/arch/microblaze/kernel/entry.S | 2 - .../microblaze/kernel/hw_exception_handler.S | 2 +- trunk/arch/microblaze/kernel/process.c | 2 - trunk/arch/sparc/include/asm/hardirq_32.h | 12 +- trunk/arch/sparc/include/asm/irq_32.h | 4 +- trunk/arch/sparc/include/asm/pgtable_64.h | 4 +- trunk/arch/sparc/kernel/ktlb.S | 8 +- trunk/arch/sparc/kernel/perf_event.c | 577 +------------- trunk/arch/sparc/oprofile/init.c | 1 - trunk/arch/x86/Kconfig | 4 + trunk/arch/x86/Kconfig.cpu | 3 +- trunk/arch/x86/ia32/ia32entry.S | 36 +- trunk/arch/x86/kernel/early_printk.c | 5 +- trunk/arch/x86/kernel/i386_ksyms_32.c | 2 - trunk/arch/x86/kvm/svm.c | 2 + trunk/arch/x86/lib/Makefile | 6 +- trunk/block/blk-barrier.c | 45 +- trunk/block/blk-core.c | 21 +- trunk/block/blk-merge.c | 2 +- trunk/block/blk-settings.c | 34 +- trunk/block/blk-sysfs.c | 11 +- trunk/block/cfq-iosched.c | 63 +- trunk/block/compat_ioctl.c | 13 - trunk/block/genhd.c | 4 +- trunk/block/ioctl.c | 17 +- trunk/drivers/acpi/Kconfig | 12 - trunk/drivers/acpi/Makefile | 2 - trunk/drivers/acpi/acpi_pad.c | 514 ------------ trunk/drivers/acpi/dock.c | 16 +- trunk/drivers/acpi/ec.c | 56 +- trunk/drivers/acpi/proc.c | 2 - trunk/drivers/acpi/processor_core.c | 7 + trunk/drivers/acpi/scan.c | 7 +- trunk/drivers/block/DAC960.c | 156 ++-- trunk/drivers/block/cciss.c | 753 +++++------------- trunk/drivers/block/cciss.h | 12 +- trunk/drivers/block/cpqarray.c | 63 +- trunk/drivers/char/dtlk.c | 1 - trunk/drivers/char/ipmi/ipmi_devintf.c | 1 - trunk/drivers/char/ipmi/ipmi_msghandler.c | 1 - trunk/drivers/firewire/core-cdev.c | 1 - trunk/drivers/firmware/iscsi_ibft.c | 2 +- trunk/drivers/firmware/iscsi_ibft_find.c | 4 +- trunk/drivers/hid/hidraw.c | 1 - trunk/drivers/hwmon/ltc4215.c | 47 +- trunk/drivers/hwmon/ltc4245.c | 131 ++- trunk/drivers/i2c/busses/i2c-amd756.c | 2 +- trunk/drivers/i2c/busses/i2c-amd8111.c | 4 +- trunk/drivers/i2c/busses/i2c-i801.c | 4 +- trunk/drivers/i2c/busses/i2c-isch.c | 2 +- trunk/drivers/i2c/busses/i2c-piix4.c | 4 +- trunk/drivers/i2c/busses/i2c-sis96x.c | 2 +- trunk/drivers/i2c/busses/i2c-viapro.c | 2 +- trunk/drivers/infiniband/core/ucm.c | 1 - trunk/drivers/infiniband/core/user_mad.c | 1 - trunk/drivers/infiniband/core/uverbs_main.c | 1 - trunk/drivers/input/evdev.c | 1 - trunk/drivers/input/input.c | 1 - trunk/drivers/input/joydev.c | 1 - trunk/drivers/input/misc/uinput.c | 1 - trunk/drivers/input/mousedev.c | 1 - trunk/drivers/isdn/divert/divert_procfs.c | 1 - trunk/drivers/leds/leds-pca9532.c | 3 + trunk/drivers/macintosh/therm_adt746x.c | 4 +- trunk/drivers/macintosh/therm_pm72.c | 4 +- .../drivers/macintosh/windfarm_lm75_sensor.c | 4 +- .../macintosh/windfarm_max6690_sensor.c | 4 +- trunk/drivers/macintosh/windfarm_smu_sat.c | 4 +- trunk/drivers/md/dm.c | 16 +- trunk/drivers/media/dvb/dvb-core/dmxdev.c | 1 - trunk/drivers/media/dvb/dvb-core/dvb_demux.c | 1 - trunk/drivers/media/radio/radio-cadet.c | 1 - trunk/drivers/media/video/cpia.c | 1 - trunk/drivers/mfd/ab3100-core.c | 4 +- trunk/drivers/mfd/ucb1400_core.c | 1 - trunk/drivers/misc/eeprom/max6875.c | 29 +- trunk/drivers/mtd/mtd_blkdevs.c | 19 +- trunk/drivers/platform/x86/sony-laptop.c | 127 +-- trunk/drivers/sfi/sfi_core.c | 17 +- trunk/drivers/staging/dst/dcore.c | 2 +- trunk/drivers/staging/iio/light/tsl2561.c | 4 + trunk/drivers/usb/gadget/inode.c | 1 - trunk/drivers/w1/masters/ds2482.c | 35 +- trunk/drivers/xen/xenfs/xenbus.c | 1 - trunk/fs/anon_inodes.c | 2 - trunk/fs/bio.c | 49 +- trunk/fs/coda/psdev.c | 1 - trunk/fs/partitions/check.c | 12 +- trunk/fs/select.c | 1 - trunk/include/linux/blkdev.h | 48 +- trunk/include/linux/blktrace_api.h | 2 - trunk/include/linux/fs.h | 4 - trunk/include/linux/genhd.h | 21 +- trunk/include/linux/poll.h | 2 +- trunk/include/trace/events/block.h | 33 - trunk/kernel/hrtimer.c | 2 + trunk/kernel/perf_event.c | 34 +- trunk/kernel/trace/blktrace.c | 39 - trunk/kernel/trace/ftrace.c | 4 - trunk/kernel/trace/kmemtrace.c | 2 +- trunk/mm/swapfile.c | 12 +- trunk/net/rfkill/core.c | 1 - .../perf/Documentation/perf-timechart.txt | 3 - trunk/tools/perf/Makefile | 2 +- trunk/tools/perf/builtin-timechart.c | 10 +- trunk/tools/perf/builtin-top.c | 1 - trunk/tools/perf/util/svghelper.c | 14 +- 125 files changed, 1019 insertions(+), 2434 deletions(-) rename trunk/Documentation/{misc-devices => i2c/chips}/eeprom (100%) rename trunk/Documentation/{misc-devices => i2c/chips}/max6875 (94%) delete mode 100644 trunk/drivers/acpi/acpi_pad.c diff --git a/[refs] b/[refs] index 3317154e351b..37383784e2e4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e8d809c61325a2f799dc753b0ac72ace6958b92c +refs/heads/master: 77b1ab1732feb5e3dcbaf31d2f7547c5229f5f3a diff --git a/trunk/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss b/trunk/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss index 4f29e5f1ebfa..0a92a7c93a62 100644 --- a/trunk/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss +++ b/trunk/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss @@ -31,31 +31,3 @@ Date: March 2009 Kernel Version: 2.6.30 Contact: iss_storagedev@hp.com Description: A symbolic link to /sys/block/cciss!cXdY - -Where: /sys/bus/pci/devices//ccissX/rescan -Date: August 2009 -Kernel Version: 2.6.31 -Contact: iss_storagedev@hp.com -Description: Kicks of a rescan of the controller to discover logical - drive topology changes. - -Where: /sys/bus/pci/devices//ccissX/cXdY/lunid -Date: August 2009 -Kernel Version: 2.6.31 -Contact: iss_storagedev@hp.com -Description: Displays the 8-byte LUN ID used to address logical - drive Y of controller X. - -Where: /sys/bus/pci/devices//ccissX/cXdY/raid_level -Date: August 2009 -Kernel Version: 2.6.31 -Contact: iss_storagedev@hp.com -Description: Displays the RAID level of logical drive Y of - controller X. - -Where: /sys/bus/pci/devices//ccissX/cXdY/usage_count -Date: August 2009 -Kernel Version: 2.6.31 -Contact: iss_storagedev@hp.com -Description: Displays the usage count (number of opens) of logical drive Y - of controller X. diff --git a/trunk/Documentation/hwmon/ltc4215 b/trunk/Documentation/hwmon/ltc4215 index c196a1846259..2e6a21eb656c 100644 --- a/trunk/Documentation/hwmon/ltc4215 +++ b/trunk/Documentation/hwmon/ltc4215 @@ -22,13 +22,12 @@ Usage Notes ----------- This driver does not probe for LTC4215 devices, due to the fact that some -of the possible addresses are unfriendly to probing. You will have to -instantiate the devices explicitly. +of the possible addresses are unfriendly to probing. You will need to use +the "force" parameter to tell the driver where to find the device. Example: the following will load the driver for an LTC4215 at address 0x44 on I2C bus #0: -$ modprobe ltc4215 -$ echo ltc4215 0x44 > /sys/bus/i2c/devices/i2c-0/new_device +$ modprobe ltc4215 force=0,0x44 Sysfs entries diff --git a/trunk/Documentation/hwmon/ltc4245 b/trunk/Documentation/hwmon/ltc4245 index 02838a47d862..bae7a3adc5d8 100644 --- a/trunk/Documentation/hwmon/ltc4245 +++ b/trunk/Documentation/hwmon/ltc4245 @@ -23,13 +23,12 @@ Usage Notes ----------- This driver does not probe for LTC4245 devices, due to the fact that some -of the possible addresses are unfriendly to probing. You will have to -instantiate the devices explicitly. +of the possible addresses are unfriendly to probing. You will need to use +the "force" parameter to tell the driver where to find the device. Example: the following will load the driver for an LTC4245 at address 0x23 on I2C bus #1: -$ modprobe ltc4245 -$ echo ltc4245 0x23 > /sys/bus/i2c/devices/i2c-1/new_device +$ modprobe ltc4245 force=1,0x23 Sysfs entries diff --git a/trunk/Documentation/misc-devices/eeprom b/trunk/Documentation/i2c/chips/eeprom similarity index 100% rename from trunk/Documentation/misc-devices/eeprom rename to trunk/Documentation/i2c/chips/eeprom diff --git a/trunk/Documentation/misc-devices/max6875 b/trunk/Documentation/i2c/chips/max6875 similarity index 94% rename from trunk/Documentation/misc-devices/max6875 rename to trunk/Documentation/i2c/chips/max6875 index 1e89ee3ccc1b..10ca43cd1a72 100644 --- a/trunk/Documentation/misc-devices/max6875 +++ b/trunk/Documentation/i2c/chips/max6875 @@ -42,12 +42,10 @@ General Remarks Valid addresses for the MAX6875 are 0x50 and 0x52. Valid addresses for the MAX6874 are 0x50, 0x52, 0x54 and 0x56. -The driver does not probe any address, so you explicitly instantiate the -devices. +The driver does not probe any address, so you must force the address. Example: -$ modprobe max6875 -$ echo max6875 0x50 > /sys/bus/i2c/devices/i2c-0/new_device +$ modprobe max6875 force=0,0x50 The MAX6874/MAX6875 ignores address bit 0, so this driver attaches to multiple addresses. For example, for address 0x50, it also reserves 0x51. diff --git a/trunk/Documentation/i2c/instantiating-devices b/trunk/Documentation/i2c/instantiating-devices index e89490270aba..c740b7b41088 100644 --- a/trunk/Documentation/i2c/instantiating-devices +++ b/trunk/Documentation/i2c/instantiating-devices @@ -188,7 +188,7 @@ segment, the address is sufficient to uniquely identify the device to be deleted. Example: -# echo eeprom 0x50 > /sys/bus/i2c/devices/i2c-3/new_device +# echo eeprom 0x50 > /sys/class/i2c-adapter/i2c-3/new_device While this interface should only be used when in-kernel device declaration can't be done, there is a variety of cases where it can be helpful: diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 9107b387e91f..6fa7292947e5 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -671,7 +671,6 @@ and is between 256 and 4096 characters. It is defined in the file earlyprintk= [X86,SH,BLACKFIN] earlyprintk=vga earlyprintk=serial[,ttySn[,baudrate]] - earlyprintk=ttySn[,baudrate] earlyprintk=dbgp[debugController#] Append ",keep" to not disable it when the real console diff --git a/trunk/Documentation/w1/masters/ds2482 b/trunk/Documentation/w1/masters/ds2482 index 299b91c7609f..9210d6fa5024 100644 --- a/trunk/Documentation/w1/masters/ds2482 +++ b/trunk/Documentation/w1/masters/ds2482 @@ -24,8 +24,8 @@ General Remarks Valid addresses are 0x18, 0x19, 0x1a, and 0x1b. However, the device cannot be detected without writing to the i2c bus, so no -detection is done. You should instantiate the device explicitly. +detection is done. +You should force the device address. -$ modprobe ds2482 -$ echo ds2482 0x18 > /sys/bus/i2c/devices/i2c-0/new_device +$ modprobe ds2482 force=0,0x18 diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 09a2028bab7f..737a9b2c532d 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -257,13 +257,6 @@ W: http://www.lesswatts.org/projects/acpi/ S: Supported F: drivers/acpi/fan.c -ACPI PROCESSOR AGGREGATOR DRIVER -M: Shaohua Li -L: linux-acpi@vger.kernel.org -W: http://www.lesswatts.org/projects/acpi/ -S: Supported -F: drivers/acpi/acpi_pad.c - ACPI THERMAL DRIVER M: Zhang Rui L: linux-acpi@vger.kernel.org diff --git a/trunk/Makefile b/trunk/Makefile index e50569ab5fe8..00444a8e304f 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 32 -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc2 NAME = Man-Eating Seals of Antiquity # *DOCUMENTATION* diff --git a/trunk/arch/m68knommu/kernel/asm-offsets.c b/trunk/arch/m68knommu/kernel/asm-offsets.c index 9a8876f715d8..594ee0e657fe 100644 --- a/trunk/arch/m68knommu/kernel/asm-offsets.c +++ b/trunk/arch/m68knommu/kernel/asm-offsets.c @@ -45,25 +45,25 @@ int main(void) DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate)); /* offsets into the pt_regs */ - DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0)); - DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0)); - DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1)); - DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2)); - DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3)); - DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4)); - DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5)); - DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0)); - DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1)); - DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2)); - DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc)); - DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr)); + DEFINE(PT_D0, offsetof(struct pt_regs, d0)); + DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0)); + DEFINE(PT_D1, offsetof(struct pt_regs, d1)); + DEFINE(PT_D2, offsetof(struct pt_regs, d2)); + DEFINE(PT_D3, offsetof(struct pt_regs, d3)); + DEFINE(PT_D4, offsetof(struct pt_regs, d4)); + DEFINE(PT_D5, offsetof(struct pt_regs, d5)); + DEFINE(PT_A0, offsetof(struct pt_regs, a0)); + DEFINE(PT_A1, offsetof(struct pt_regs, a1)); + DEFINE(PT_A2, offsetof(struct pt_regs, a2)); + DEFINE(PT_PC, offsetof(struct pt_regs, pc)); + DEFINE(PT_SR, offsetof(struct pt_regs, sr)); #ifdef CONFIG_COLDFIRE /* bitfields are a bit difficult */ - DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, sr) - 2); + DEFINE(PT_FORMATVEC, offsetof(struct pt_regs, sr) - 2); #else /* bitfields are a bit difficult */ - DEFINE(PT_OFF_VECTOR, offsetof(struct pt_regs, pc) + 4); + DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) + 4); #endif /* signal defines */ diff --git a/trunk/arch/m68knommu/kernel/entry.S b/trunk/arch/m68knommu/kernel/entry.S index 56043ade3941..f56faa5c9cd9 100644 --- a/trunk/arch/m68knommu/kernel/entry.S +++ b/trunk/arch/m68knommu/kernel/entry.S @@ -46,7 +46,7 @@ ENTRY(buserr) SAVE_ALL moveq #-1,%d0 - movel %d0,%sp@(PT_OFF_ORIG_D0) + movel %d0,%sp@(PT_ORIG_D0) movel %sp,%sp@- /* stack frame pointer argument */ jsr buserr_c addql #4,%sp @@ -55,7 +55,7 @@ ENTRY(buserr) ENTRY(trap) SAVE_ALL moveq #-1,%d0 - movel %d0,%sp@(PT_OFF_ORIG_D0) + movel %d0,%sp@(PT_ORIG_D0) movel %sp,%sp@- /* stack frame pointer argument */ jsr trap_c addql #4,%sp @@ -67,7 +67,7 @@ ENTRY(trap) ENTRY(dbginterrupt) SAVE_ALL moveq #-1,%d0 - movel %d0,%sp@(PT_OFF_ORIG_D0) + movel %d0,%sp@(PT_ORIG_D0) movel %sp,%sp@- /* stack frame pointer argument */ jsr dbginterrupt_c addql #4,%sp diff --git a/trunk/arch/m68knommu/mm/init.c b/trunk/arch/m68knommu/mm/init.c index f3236d0b522d..b1703c67a4f1 100644 --- a/trunk/arch/m68knommu/mm/init.c +++ b/trunk/arch/m68knommu/mm/init.c @@ -162,7 +162,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) totalram_pages++; pages++; } - printk (KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages * (PAGE_SIZE / 1024)); + printk (KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages); } #endif diff --git a/trunk/arch/m68knommu/platform/5206e/config.c b/trunk/arch/m68knommu/platform/5206e/config.c index 942397984c66..0f41ba82a3b5 100644 --- a/trunk/arch/m68knommu/platform/5206e/config.c +++ b/trunk/arch/m68knommu/platform/5206e/config.c @@ -17,6 +17,7 @@ #include #include #include +#include /***************************************************************************/ diff --git a/trunk/arch/m68knommu/platform/68328/entry.S b/trunk/arch/m68knommu/platform/68328/entry.S index 9d80d2c42866..b1aef72f3baf 100644 --- a/trunk/arch/m68knommu/platform/68328/entry.S +++ b/trunk/arch/m68knommu/platform/68328/entry.S @@ -39,17 +39,17 @@ .globl inthandler7 badsys: - movel #-ENOSYS,%sp@(PT_OFF_D0) + movel #-ENOSYS,%sp@(PT_D0) jra ret_from_exception do_trace: - movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/ + movel #-ENOSYS,%sp@(PT_D0) /* needed for strace*/ subql #4,%sp SAVE_SWITCH_STACK jbsr syscall_trace RESTORE_SWITCH_STACK addql #4,%sp - movel %sp@(PT_OFF_ORIG_D0),%d1 + movel %sp@(PT_ORIG_D0),%d1 movel #-ENOSYS,%d0 cmpl #NR_syscalls,%d1 jcc 1f @@ -57,7 +57,7 @@ do_trace: lea sys_call_table, %a0 jbsr %a0@(%d1) -1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */ +1: movel %d0,%sp@(PT_D0) /* save the return value */ subql #4,%sp /* dummy return address */ SAVE_SWITCH_STACK jbsr syscall_trace @@ -75,7 +75,7 @@ ENTRY(system_call) jbsr set_esp0 addql #4,%sp - movel %sp@(PT_OFF_ORIG_D0),%d0 + movel %sp@(PT_ORIG_D0),%d0 movel %sp,%d1 /* get thread_info pointer */ andl #-THREAD_SIZE,%d1 @@ -88,10 +88,10 @@ ENTRY(system_call) lea sys_call_table,%a0 movel %a0@(%d0), %a0 jbsr %a0@ - movel %d0,%sp@(PT_OFF_D0) /* save the return value*/ + movel %d0,%sp@(PT_D0) /* save the return value*/ ret_from_exception: - btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/ + btst #5,%sp@(PT_SR) /* check if returning to kernel*/ jeq Luser_return /* if so, skip resched, signals*/ Lkernel_return: @@ -133,7 +133,7 @@ Lreturn: */ inthandler1: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_VECTOR), %d0 and #0x3ff, %d0 movel %sp,%sp@- @@ -144,7 +144,7 @@ inthandler1: inthandler2: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_VECTOR), %d0 and #0x3ff, %d0 movel %sp,%sp@- @@ -155,7 +155,7 @@ inthandler2: inthandler3: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_VECTOR), %d0 and #0x3ff, %d0 movel %sp,%sp@- @@ -166,7 +166,7 @@ inthandler3: inthandler4: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_VECTOR), %d0 and #0x3ff, %d0 movel %sp,%sp@- @@ -177,7 +177,7 @@ inthandler4: inthandler5: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_VECTOR), %d0 and #0x3ff, %d0 movel %sp,%sp@- @@ -188,7 +188,7 @@ inthandler5: inthandler6: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_VECTOR), %d0 and #0x3ff, %d0 movel %sp,%sp@- @@ -199,7 +199,7 @@ inthandler6: inthandler7: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_VECTOR), %d0 and #0x3ff, %d0 movel %sp,%sp@- @@ -210,7 +210,7 @@ inthandler7: inthandler: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_VECTOR), %d0 and #0x3ff, %d0 movel %sp,%sp@- @@ -224,7 +224,7 @@ ret_from_interrupt: 2: RESTORE_ALL 1: - moveb %sp@(PT_OFF_SR), %d0 + moveb %sp@(PT_SR), %d0 and #7, %d0 jhi 2b diff --git a/trunk/arch/m68knommu/platform/68360/entry.S b/trunk/arch/m68knommu/platform/68360/entry.S index 6d3460a39cac..55dfefe38642 100644 --- a/trunk/arch/m68knommu/platform/68360/entry.S +++ b/trunk/arch/m68knommu/platform/68360/entry.S @@ -35,17 +35,17 @@ .globl inthandler badsys: - movel #-ENOSYS,%sp@(PT_OFF_D0) + movel #-ENOSYS,%sp@(PT_D0) jra ret_from_exception do_trace: - movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/ + movel #-ENOSYS,%sp@(PT_D0) /* needed for strace*/ subql #4,%sp SAVE_SWITCH_STACK jbsr syscall_trace RESTORE_SWITCH_STACK addql #4,%sp - movel %sp@(PT_OFF_ORIG_D0),%d1 + movel %sp@(PT_ORIG_D0),%d1 movel #-ENOSYS,%d0 cmpl #NR_syscalls,%d1 jcc 1f @@ -53,7 +53,7 @@ do_trace: lea sys_call_table, %a0 jbsr %a0@(%d1) -1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */ +1: movel %d0,%sp@(PT_D0) /* save the return value */ subql #4,%sp /* dummy return address */ SAVE_SWITCH_STACK jbsr syscall_trace @@ -79,10 +79,10 @@ ENTRY(system_call) lea sys_call_table,%a0 movel %a0@(%d0), %a0 jbsr %a0@ - movel %d0,%sp@(PT_OFF_D0) /* save the return value*/ + movel %d0,%sp@(PT_D0) /* save the return value*/ ret_from_exception: - btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/ + btst #5,%sp@(PT_SR) /* check if returning to kernel*/ jeq Luser_return /* if so, skip resched, signals*/ Lkernel_return: @@ -124,7 +124,7 @@ Lreturn: */ inthandler: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_VECTOR), %d0 and.l #0x3ff, %d0 lsr.l #0x02, %d0 @@ -139,7 +139,7 @@ ret_from_interrupt: 2: RESTORE_ALL 1: - moveb %sp@(PT_OFF_SR), %d0 + moveb %sp@(PT_SR), %d0 and #7, %d0 jhi 2b /* check if we need to do software interrupts */ diff --git a/trunk/arch/m68knommu/platform/coldfire/entry.S b/trunk/arch/m68knommu/platform/coldfire/entry.S index dd7d591f70ea..3b471c0da24a 100644 --- a/trunk/arch/m68knommu/platform/coldfire/entry.S +++ b/trunk/arch/m68knommu/platform/coldfire/entry.S @@ -81,11 +81,11 @@ ENTRY(system_call) movel %d3,%a0 jbsr %a0@ - movel %d0,%sp@(PT_OFF_D0) /* save the return value */ + movel %d0,%sp@(PT_D0) /* save the return value */ jra ret_from_exception 1: - movel #-ENOSYS,%d2 /* strace needs -ENOSYS in PT_OFF_D0 */ - movel %d2,PT_OFF_D0(%sp) /* on syscall entry */ + movel #-ENOSYS,%d2 /* strace needs -ENOSYS in PT_D0 */ + movel %d2,PT_D0(%sp) /* on syscall entry */ subql #4,%sp SAVE_SWITCH_STACK jbsr syscall_trace @@ -93,7 +93,7 @@ ENTRY(system_call) addql #4,%sp movel %d3,%a0 jbsr %a0@ - movel %d0,%sp@(PT_OFF_D0) /* save the return value */ + movel %d0,%sp@(PT_D0) /* save the return value */ subql #4,%sp /* dummy return address */ SAVE_SWITCH_STACK jbsr syscall_trace @@ -104,7 +104,7 @@ ret_from_signal: ret_from_exception: move #0x2700,%sr /* disable intrs */ - btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel */ + btst #5,%sp@(PT_SR) /* check if returning to kernel */ jeq Luser_return /* if so, skip resched, signals */ #ifdef CONFIG_PREEMPT @@ -142,8 +142,8 @@ Luser_return: Lreturn: move #0x2700,%sr /* disable intrs */ movel sw_usp,%a0 /* get usp */ - movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */ - movel %sp@(PT_OFF_FORMATVEC),%a0@- /* copy exception format/vector/sr */ + movel %sp@(PT_PC),%a0@- /* copy exception program counter */ + movel %sp@(PT_FORMATVEC),%a0@-/* copy exception format/vector/sr */ moveml %sp@,%d1-%d5/%a0-%a2 lea %sp@(32),%sp /* space for 8 regs */ movel %sp@+,%d0 @@ -181,9 +181,9 @@ Lsignal_return: ENTRY(inthandler) SAVE_ALL moveq #-1,%d0 - movel %d0,%sp@(PT_OFF_ORIG_D0) + movel %d0,%sp@(PT_ORIG_D0) - movew %sp@(PT_OFF_FORMATVEC),%d0 /* put exception # in d0 */ + movew %sp@(PT_FORMATVEC),%d0 /* put exception # in d0 */ andl #0x03fc,%d0 /* mask out vector only */ movel %sp,%sp@- /* push regs arg */ @@ -203,7 +203,7 @@ ENTRY(inthandler) ENTRY(fasthandler) SAVE_LOCAL - movew %sp@(PT_OFF_FORMATVEC),%d0 + movew %sp@(PT_FORMATVEC),%d0 andl #0x03fc,%d0 /* mask out vector only */ movel %sp,%sp@- /* push regs arg */ diff --git a/trunk/arch/microblaze/kernel/entry.S b/trunk/arch/microblaze/kernel/entry.S index e3ecb36dd554..acc1f05d1e2c 100644 --- a/trunk/arch/microblaze/kernel/entry.S +++ b/trunk/arch/microblaze/kernel/entry.S @@ -592,8 +592,6 @@ C_ENTRY(full_exception_trap): nop mfs r7, rfsr; /* save FSR */ nop - mts rfsr, r0; /* Clear sticky fsr */ - nop la r12, r0, full_exception set_vms; rtbd r12, 0; diff --git a/trunk/arch/microblaze/kernel/hw_exception_handler.S b/trunk/arch/microblaze/kernel/hw_exception_handler.S index 2b86c03aa841..6b0288ebccd6 100644 --- a/trunk/arch/microblaze/kernel/hw_exception_handler.S +++ b/trunk/arch/microblaze/kernel/hw_exception_handler.S @@ -384,7 +384,7 @@ handle_other_ex: /* Handle Other exceptions here */ addk r8, r17, r0; /* Load exception address */ bralid r15, full_exception; /* Branch to the handler */ nop; - mts rfsr, r0; /* Clear sticky fsr */ + mts r0, rfsr; /* Clear sticky fsr */ nop /* diff --git a/trunk/arch/microblaze/kernel/process.c b/trunk/arch/microblaze/kernel/process.c index c592d475b3d8..4201c743cc9f 100644 --- a/trunk/arch/microblaze/kernel/process.c +++ b/trunk/arch/microblaze/kernel/process.c @@ -235,9 +235,7 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp) regs->pc = pc; regs->r1 = usp; regs->pt_mode = 0; -#ifdef CONFIG_MMU regs->msr |= MSR_UMS; -#endif } #ifdef CONFIG_MMU diff --git a/trunk/arch/sparc/include/asm/hardirq_32.h b/trunk/arch/sparc/include/asm/hardirq_32.h index 162007643cdc..4f63ed8df551 100644 --- a/trunk/arch/sparc/include/asm/hardirq_32.h +++ b/trunk/arch/sparc/include/asm/hardirq_32.h @@ -7,7 +7,17 @@ #ifndef __SPARC_HARDIRQ_H #define __SPARC_HARDIRQ_H +#include +#include +#include + +/* entry.S is sensitive to the offsets of these fields */ /* XXX P3 Is it? */ +typedef struct { + unsigned int __softirq_pending; +} ____cacheline_aligned irq_cpustat_t; + +#include /* Standard mappings for irq_cpustat_t above */ + #define HARDIRQ_BITS 8 -#include #endif /* __SPARC_HARDIRQ_H */ diff --git a/trunk/arch/sparc/include/asm/irq_32.h b/trunk/arch/sparc/include/asm/irq_32.h index cbf4801deaaf..ea43057d4763 100644 --- a/trunk/arch/sparc/include/asm/irq_32.h +++ b/trunk/arch/sparc/include/asm/irq_32.h @@ -6,10 +6,10 @@ #ifndef _SPARC_IRQ_H #define _SPARC_IRQ_H -#define NR_IRQS 16 - #include +#define NR_IRQS 16 + #define irq_canonicalize(irq) (irq) extern void __init init_IRQ(void); diff --git a/trunk/arch/sparc/include/asm/pgtable_64.h b/trunk/arch/sparc/include/asm/pgtable_64.h index f3cb790fa2ae..0ff92fa22064 100644 --- a/trunk/arch/sparc/include/asm/pgtable_64.h +++ b/trunk/arch/sparc/include/asm/pgtable_64.h @@ -41,8 +41,8 @@ #define LOW_OBP_ADDRESS _AC(0x00000000f0000000,UL) #define HI_OBP_ADDRESS _AC(0x0000000100000000,UL) #define VMALLOC_START _AC(0x0000000100000000,UL) -#define VMALLOC_END _AC(0x0000010000000000,UL) -#define VMEMMAP_BASE _AC(0x0000010000000000,UL) +#define VMALLOC_END _AC(0x0000000200000000,UL) +#define VMEMMAP_BASE _AC(0x0000000200000000,UL) #define vmemmap ((struct page *)VMEMMAP_BASE) diff --git a/trunk/arch/sparc/kernel/ktlb.S b/trunk/arch/sparc/kernel/ktlb.S index 1d361477d7d6..3ea6e8cde8c5 100644 --- a/trunk/arch/sparc/kernel/ktlb.S +++ b/trunk/arch/sparc/kernel/ktlb.S @@ -280,8 +280,8 @@ kvmap_dtlb_nonlinear: #ifdef CONFIG_SPARSEMEM_VMEMMAP /* Do not use the TSB for vmemmap. */ - mov (VMEMMAP_BASE >> 40), %g5 - sllx %g5, 40, %g5 + mov (VMEMMAP_BASE >> 24), %g5 + sllx %g5, 24, %g5 cmp %g4,%g5 bgeu,pn %xcc, kvmap_vmemmap nop @@ -293,8 +293,8 @@ kvmap_dtlb_tsbmiss: sethi %hi(MODULES_VADDR), %g5 cmp %g4, %g5 blu,pn %xcc, kvmap_dtlb_longpath - mov (VMALLOC_END >> 40), %g5 - sllx %g5, 40, %g5 + mov (VMALLOC_END >> 24), %g5 + sllx %g5, 24, %g5 cmp %g4, %g5 bgeu,pn %xcc, kvmap_dtlb_longpath nop diff --git a/trunk/arch/sparc/kernel/perf_event.c b/trunk/arch/sparc/kernel/perf_event.c index 04db92743896..2d6a1b10c81d 100644 --- a/trunk/arch/sparc/kernel/perf_event.c +++ b/trunk/arch/sparc/kernel/perf_event.c @@ -56,8 +56,7 @@ struct cpu_hw_events { struct perf_event *events[MAX_HWEVENTS]; unsigned long used_mask[BITS_TO_LONGS(MAX_HWEVENTS)]; unsigned long active_mask[BITS_TO_LONGS(MAX_HWEVENTS)]; - u64 pcr; - int enabled; + int enabled; }; DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, }; @@ -69,30 +68,8 @@ struct perf_event_map { #define PIC_LOWER 0x02 }; -static unsigned long perf_event_encode(const struct perf_event_map *pmap) -{ - return ((unsigned long) pmap->encoding << 16) | pmap->pic_mask; -} - -static void perf_event_decode(unsigned long val, u16 *enc, u8 *msk) -{ - *msk = val & 0xff; - *enc = val >> 16; -} - -#define C(x) PERF_COUNT_HW_CACHE_##x - -#define CACHE_OP_UNSUPPORTED 0xfffe -#define CACHE_OP_NONSENSE 0xffff - -typedef struct perf_event_map cache_map_t - [PERF_COUNT_HW_CACHE_MAX] - [PERF_COUNT_HW_CACHE_OP_MAX] - [PERF_COUNT_HW_CACHE_RESULT_MAX]; - struct sparc_pmu { const struct perf_event_map *(*event_map)(int); - const cache_map_t *cache_map; int max_events; int upper_shift; int lower_shift; @@ -103,109 +80,21 @@ struct sparc_pmu { int lower_nop; }; -static const struct perf_event_map ultra3_perfmon_event_map[] = { +static const struct perf_event_map ultra3i_perfmon_event_map[] = { [PERF_COUNT_HW_CPU_CYCLES] = { 0x0000, PIC_UPPER | PIC_LOWER }, [PERF_COUNT_HW_INSTRUCTIONS] = { 0x0001, PIC_UPPER | PIC_LOWER }, [PERF_COUNT_HW_CACHE_REFERENCES] = { 0x0009, PIC_LOWER }, [PERF_COUNT_HW_CACHE_MISSES] = { 0x0009, PIC_UPPER }, }; -static const struct perf_event_map *ultra3_event_map(int event_id) +static const struct perf_event_map *ultra3i_event_map(int event_id) { - return &ultra3_perfmon_event_map[event_id]; + return &ultra3i_perfmon_event_map[event_id]; } -static const cache_map_t ultra3_cache_map = { -[C(L1D)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x09, PIC_LOWER, }, - [C(RESULT_MISS)] = { 0x09, PIC_UPPER, }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { 0x0a, PIC_LOWER }, - [C(RESULT_MISS)] = { 0x0a, PIC_UPPER }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, - }, -}, -[C(L1I)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x09, PIC_LOWER, }, - [C(RESULT_MISS)] = { 0x09, PIC_UPPER, }, - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_NONSENSE }, - [ C(RESULT_MISS) ] = { CACHE_OP_NONSENSE }, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, -}, -[C(LL)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x0c, PIC_LOWER, }, - [C(RESULT_MISS)] = { 0x0c, PIC_UPPER, }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { 0x0c, PIC_LOWER }, - [C(RESULT_MISS)] = { 0x0c, PIC_UPPER }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, - }, -}, -[C(DTLB)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { 0x12, PIC_UPPER, }, - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, -}, -[C(ITLB)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { 0x11, PIC_UPPER, }, - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, -}, -[C(BPU)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, -}, -}; - -static const struct sparc_pmu ultra3_pmu = { - .event_map = ultra3_event_map, - .cache_map = &ultra3_cache_map, - .max_events = ARRAY_SIZE(ultra3_perfmon_event_map), +static const struct sparc_pmu ultra3i_pmu = { + .event_map = ultra3i_event_map, + .max_events = ARRAY_SIZE(ultra3i_perfmon_event_map), .upper_shift = 11, .lower_shift = 4, .event_mask = 0x3f, @@ -213,121 +102,6 @@ static const struct sparc_pmu ultra3_pmu = { .lower_nop = 0x14, }; -/* Niagara1 is very limited. The upper PIC is hard-locked to count - * only instructions, so it is free running which creates all kinds of - * problems. Some hardware designs make one wonder if the creator - * even looked at how this stuff gets used by software. - */ -static const struct perf_event_map niagara1_perfmon_event_map[] = { - [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, PIC_UPPER }, - [PERF_COUNT_HW_INSTRUCTIONS] = { 0x00, PIC_UPPER }, - [PERF_COUNT_HW_CACHE_REFERENCES] = { 0, PIC_NONE }, - [PERF_COUNT_HW_CACHE_MISSES] = { 0x03, PIC_LOWER }, -}; - -static const struct perf_event_map *niagara1_event_map(int event_id) -{ - return &niagara1_perfmon_event_map[event_id]; -} - -static const cache_map_t niagara1_cache_map = { -[C(L1D)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { 0x03, PIC_LOWER, }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { 0x03, PIC_LOWER, }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, - }, -}, -[C(L1I)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x00, PIC_UPPER }, - [C(RESULT_MISS)] = { 0x02, PIC_LOWER, }, - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_NONSENSE }, - [ C(RESULT_MISS) ] = { CACHE_OP_NONSENSE }, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, -}, -[C(LL)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { 0x07, PIC_LOWER, }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { 0x07, PIC_LOWER, }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, - }, -}, -[C(DTLB)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { 0x05, PIC_LOWER, }, - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, -}, -[C(ITLB)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { 0x04, PIC_LOWER, }, - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, -}, -[C(BPU)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, -}, -}; - -static const struct sparc_pmu niagara1_pmu = { - .event_map = niagara1_event_map, - .cache_map = &niagara1_cache_map, - .max_events = ARRAY_SIZE(niagara1_perfmon_event_map), - .upper_shift = 0, - .lower_shift = 4, - .event_mask = 0x7, - .upper_nop = 0x0, - .lower_nop = 0x0, -}; - static const struct perf_event_map niagara2_perfmon_event_map[] = { [PERF_COUNT_HW_CPU_CYCLES] = { 0x02ff, PIC_UPPER | PIC_LOWER }, [PERF_COUNT_HW_INSTRUCTIONS] = { 0x02ff, PIC_UPPER | PIC_LOWER }, @@ -342,96 +116,8 @@ static const struct perf_event_map *niagara2_event_map(int event_id) return &niagara2_perfmon_event_map[event_id]; } -static const cache_map_t niagara2_cache_map = { -[C(L1D)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x0208, PIC_UPPER | PIC_LOWER, }, - [C(RESULT_MISS)] = { 0x0302, PIC_UPPER | PIC_LOWER, }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { 0x0210, PIC_UPPER | PIC_LOWER, }, - [C(RESULT_MISS)] = { 0x0302, PIC_UPPER | PIC_LOWER, }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, - }, -}, -[C(L1I)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x02ff, PIC_UPPER | PIC_LOWER, }, - [C(RESULT_MISS)] = { 0x0301, PIC_UPPER | PIC_LOWER, }, - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_NONSENSE }, - [ C(RESULT_MISS) ] = { CACHE_OP_NONSENSE }, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, -}, -[C(LL)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x0208, PIC_UPPER | PIC_LOWER, }, - [C(RESULT_MISS)] = { 0x0330, PIC_UPPER | PIC_LOWER, }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { 0x0210, PIC_UPPER | PIC_LOWER, }, - [C(RESULT_MISS)] = { 0x0320, PIC_UPPER | PIC_LOWER, }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, - }, -}, -[C(DTLB)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { 0x0b08, PIC_UPPER | PIC_LOWER, }, - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, -}, -[C(ITLB)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { 0xb04, PIC_UPPER | PIC_LOWER, }, - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, -}, -[C(BPU)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, - [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, - [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, - }, -}, -}; - static const struct sparc_pmu niagara2_pmu = { .event_map = niagara2_event_map, - .cache_map = &niagara2_cache_map, .max_events = ARRAY_SIZE(niagara2_perfmon_event_map), .upper_shift = 19, .lower_shift = 6, @@ -465,30 +151,23 @@ static u64 nop_for_index(int idx) sparc_pmu->lower_nop, idx); } -static inline void sparc_pmu_enable_event(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc, int idx) +static inline void sparc_pmu_enable_event(struct hw_perf_event *hwc, + int idx) { u64 val, mask = mask_for_index(idx); - val = cpuc->pcr; - val &= ~mask; - val |= hwc->config; - cpuc->pcr = val; - - pcr_ops->write(cpuc->pcr); + val = pcr_ops->read(); + pcr_ops->write((val & ~mask) | hwc->config); } -static inline void sparc_pmu_disable_event(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc, int idx) +static inline void sparc_pmu_disable_event(struct hw_perf_event *hwc, + int idx) { u64 mask = mask_for_index(idx); u64 nop = nop_for_index(idx); - u64 val; + u64 val = pcr_ops->read(); - val = cpuc->pcr; - val &= ~mask; - val |= nop; - cpuc->pcr = val; - - pcr_ops->write(cpuc->pcr); + pcr_ops->write((val & ~mask) | nop); } void hw_perf_enable(void) @@ -503,7 +182,7 @@ void hw_perf_enable(void) cpuc->enabled = 1; barrier(); - val = cpuc->pcr; + val = pcr_ops->read(); for (i = 0; i < MAX_HWEVENTS; i++) { struct perf_event *cp = cpuc->events[i]; @@ -515,9 +194,7 @@ void hw_perf_enable(void) val |= hwc->config_base; } - cpuc->pcr = val; - - pcr_ops->write(cpuc->pcr); + pcr_ops->write(val); } void hw_perf_disable(void) @@ -530,12 +207,10 @@ void hw_perf_disable(void) cpuc->enabled = 0; - val = cpuc->pcr; + val = pcr_ops->read(); val &= ~(PCR_UTRACE | PCR_STRACE | sparc_pmu->hv_bit | sparc_pmu->irq_bit); - cpuc->pcr = val; - - pcr_ops->write(cpuc->pcr); + pcr_ops->write(val); } static u32 read_pmc(int idx) @@ -567,7 +242,7 @@ static void write_pmc(int idx, u64 val) } static int sparc_perf_event_set_period(struct perf_event *event, - struct hw_perf_event *hwc, int idx) + struct hw_perf_event *hwc, int idx) { s64 left = atomic64_read(&hwc->period_left); s64 period = hwc->sample_period; @@ -607,19 +282,19 @@ static int sparc_pmu_enable(struct perf_event *event) if (test_and_set_bit(idx, cpuc->used_mask)) return -EAGAIN; - sparc_pmu_disable_event(cpuc, hwc, idx); + sparc_pmu_disable_event(hwc, idx); cpuc->events[idx] = event; set_bit(idx, cpuc->active_mask); sparc_perf_event_set_period(event, hwc, idx); - sparc_pmu_enable_event(cpuc, hwc, idx); + sparc_pmu_enable_event(hwc, idx); perf_event_update_userpage(event); return 0; } static u64 sparc_perf_event_update(struct perf_event *event, - struct hw_perf_event *hwc, int idx) + struct hw_perf_event *hwc, int idx) { int shift = 64 - 32; u64 prev_raw_count, new_raw_count; @@ -649,7 +324,7 @@ static void sparc_pmu_disable(struct perf_event *event) int idx = hwc->idx; clear_bit(idx, cpuc->active_mask); - sparc_pmu_disable_event(cpuc, hwc, idx); + sparc_pmu_disable_event(hwc, idx); barrier(); @@ -663,29 +338,18 @@ static void sparc_pmu_disable(struct perf_event *event) static void sparc_pmu_read(struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; - sparc_perf_event_update(event, hwc, hwc->idx); } static void sparc_pmu_unthrottle(struct perf_event *event) { - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); struct hw_perf_event *hwc = &event->hw; - - sparc_pmu_enable_event(cpuc, hwc, hwc->idx); + sparc_pmu_enable_event(hwc, hwc->idx); } static atomic_t active_events = ATOMIC_INIT(0); static DEFINE_MUTEX(pmc_grab_mutex); -static void perf_stop_nmi_watchdog(void *unused) -{ - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - - stop_nmi_watchdog(NULL); - cpuc->pcr = pcr_ops->read(); -} - void perf_event_grab_pmc(void) { if (atomic_inc_not_zero(&active_events)) @@ -694,7 +358,7 @@ void perf_event_grab_pmc(void) mutex_lock(&pmc_grab_mutex); if (atomic_read(&active_events) == 0) { if (atomic_read(&nmi_active) > 0) { - on_each_cpu(perf_stop_nmi_watchdog, NULL, 1); + on_each_cpu(stop_nmi_watchdog, NULL, 1); BUG_ON(atomic_read(&nmi_active) != 0); } atomic_inc(&active_events); @@ -711,160 +375,30 @@ void perf_event_release_pmc(void) } } -static const struct perf_event_map *sparc_map_cache_event(u64 config) -{ - unsigned int cache_type, cache_op, cache_result; - const struct perf_event_map *pmap; - - if (!sparc_pmu->cache_map) - return ERR_PTR(-ENOENT); - - cache_type = (config >> 0) & 0xff; - if (cache_type >= PERF_COUNT_HW_CACHE_MAX) - return ERR_PTR(-EINVAL); - - cache_op = (config >> 8) & 0xff; - if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX) - return ERR_PTR(-EINVAL); - - cache_result = (config >> 16) & 0xff; - if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX) - return ERR_PTR(-EINVAL); - - pmap = &((*sparc_pmu->cache_map)[cache_type][cache_op][cache_result]); - - if (pmap->encoding == CACHE_OP_UNSUPPORTED) - return ERR_PTR(-ENOENT); - - if (pmap->encoding == CACHE_OP_NONSENSE) - return ERR_PTR(-EINVAL); - - return pmap; -} - static void hw_perf_event_destroy(struct perf_event *event) { perf_event_release_pmc(); } -/* Make sure all events can be scheduled into the hardware at - * the same time. This is simplified by the fact that we only - * need to support 2 simultaneous HW events. - */ -static int sparc_check_constraints(unsigned long *events, int n_ev) -{ - if (n_ev <= perf_max_events) { - u8 msk1, msk2; - u16 dummy; - - if (n_ev == 1) - return 0; - BUG_ON(n_ev != 2); - perf_event_decode(events[0], &dummy, &msk1); - perf_event_decode(events[1], &dummy, &msk2); - - /* If both events can go on any counter, OK. */ - if (msk1 == (PIC_UPPER | PIC_LOWER) && - msk2 == (PIC_UPPER | PIC_LOWER)) - return 0; - - /* If one event is limited to a specific counter, - * and the other can go on both, OK. - */ - if ((msk1 == PIC_UPPER || msk1 == PIC_LOWER) && - msk2 == (PIC_UPPER | PIC_LOWER)) - return 0; - if ((msk2 == PIC_UPPER || msk2 == PIC_LOWER) && - msk1 == (PIC_UPPER | PIC_LOWER)) - return 0; - - /* If the events are fixed to different counters, OK. */ - if ((msk1 == PIC_UPPER && msk2 == PIC_LOWER) || - (msk1 == PIC_LOWER && msk2 == PIC_UPPER)) - return 0; - - /* Otherwise, there is a conflict. */ - } - - return -1; -} - -static int check_excludes(struct perf_event **evts, int n_prev, int n_new) -{ - int eu = 0, ek = 0, eh = 0; - struct perf_event *event; - int i, n, first; - - n = n_prev + n_new; - if (n <= 1) - return 0; - - first = 1; - for (i = 0; i < n; i++) { - event = evts[i]; - if (first) { - eu = event->attr.exclude_user; - ek = event->attr.exclude_kernel; - eh = event->attr.exclude_hv; - first = 0; - } else if (event->attr.exclude_user != eu || - event->attr.exclude_kernel != ek || - event->attr.exclude_hv != eh) { - return -EAGAIN; - } - } - - return 0; -} - -static int collect_events(struct perf_event *group, int max_count, - struct perf_event *evts[], unsigned long *events) -{ - struct perf_event *event; - int n = 0; - - if (!is_software_event(group)) { - if (n >= max_count) - return -1; - evts[n] = group; - events[n++] = group->hw.event_base; - } - list_for_each_entry(event, &group->sibling_list, group_entry) { - if (!is_software_event(event) && - event->state != PERF_EVENT_STATE_OFF) { - if (n >= max_count) - return -1; - evts[n] = event; - events[n++] = event->hw.event_base; - } - } - return n; -} - static int __hw_perf_event_init(struct perf_event *event) { struct perf_event_attr *attr = &event->attr; - struct perf_event *evts[MAX_HWEVENTS]; struct hw_perf_event *hwc = &event->hw; - unsigned long events[MAX_HWEVENTS]; const struct perf_event_map *pmap; u64 enc; - int n; if (atomic_read(&nmi_active) < 0) return -ENODEV; - if (attr->type == PERF_TYPE_HARDWARE) { - if (attr->config >= sparc_pmu->max_events) - return -EINVAL; - pmap = sparc_pmu->event_map(attr->config); - } else if (attr->type == PERF_TYPE_HW_CACHE) { - pmap = sparc_map_cache_event(attr->config); - if (IS_ERR(pmap)) - return PTR_ERR(pmap); - } else + if (attr->type != PERF_TYPE_HARDWARE) return -EOPNOTSUPP; + if (attr->config >= sparc_pmu->max_events) + return -EINVAL; + + perf_event_grab_pmc(); + event->destroy = hw_perf_event_destroy; + /* We save the enable bits in the config_base. So to * turn off sampling just write 'config', and to enable * things write 'config | config_base'. @@ -877,39 +411,15 @@ static int __hw_perf_event_init(struct perf_event *event) if (!attr->exclude_hv) hwc->config_base |= sparc_pmu->hv_bit; - hwc->event_base = perf_event_encode(pmap); - - enc = pmap->encoding; - - n = 0; - if (event->group_leader != event) { - n = collect_events(event->group_leader, - perf_max_events - 1, - evts, events); - if (n < 0) - return -EINVAL; - } - events[n] = hwc->event_base; - evts[n] = event; - - if (check_excludes(evts, n, 1)) - return -EINVAL; - - if (sparc_check_constraints(events, n + 1)) - return -EINVAL; - - /* Try to do all error checking before this point, as unwinding - * state after grabbing the PMC is difficult. - */ - perf_event_grab_pmc(); - event->destroy = hw_perf_event_destroy; - if (!hwc->sample_period) { hwc->sample_period = MAX_PERIOD; hwc->last_period = hwc->sample_period; atomic64_set(&hwc->period_left, hwc->sample_period); } + pmap = sparc_pmu->event_map(attr->config); + + enc = pmap->encoding; if (pmap->pic_mask & PIC_UPPER) { hwc->idx = PIC_UPPER_INDEX; enc <<= sparc_pmu->upper_shift; @@ -962,7 +472,7 @@ void perf_event_print_debug(void) } static int __kprobes perf_event_nmi_handler(struct notifier_block *self, - unsigned long cmd, void *__args) + unsigned long cmd, void *__args) { struct die_args *args = __args; struct perf_sample_data data; @@ -1003,7 +513,7 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self, continue; if (perf_event_overflow(event, 1, &data, regs)) - sparc_pmu_disable_event(cpuc, hwc, idx); + sparc_pmu_disable_event(hwc, idx); } return NOTIFY_STOP; @@ -1015,15 +525,8 @@ static __read_mostly struct notifier_block perf_event_nmi_notifier = { static bool __init supported_pmu(void) { - if (!strcmp(sparc_pmu_type, "ultra3") || - !strcmp(sparc_pmu_type, "ultra3+") || - !strcmp(sparc_pmu_type, "ultra3i") || - !strcmp(sparc_pmu_type, "ultra4+")) { - sparc_pmu = &ultra3_pmu; - return true; - } - if (!strcmp(sparc_pmu_type, "niagara")) { - sparc_pmu = &niagara1_pmu; + if (!strcmp(sparc_pmu_type, "ultra3i")) { + sparc_pmu = &ultra3i_pmu; return true; } if (!strcmp(sparc_pmu_type, "niagara2")) { diff --git a/trunk/arch/sparc/oprofile/init.c b/trunk/arch/sparc/oprofile/init.c index f9024bccff16..f97cb8b6ee5f 100644 --- a/trunk/arch/sparc/oprofile/init.c +++ b/trunk/arch/sparc/oprofile/init.c @@ -11,7 +11,6 @@ #include #include #include -#include /* for HZ */ #ifdef CONFIG_SPARC64 #include diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index c876bace8fdc..8da93745c087 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -86,6 +86,10 @@ config STACKTRACE_SUPPORT config HAVE_LATENCYTOP_SUPPORT def_bool y +config FAST_CMPXCHG_LOCAL + bool + default y + config MMU def_bool y diff --git a/trunk/arch/x86/Kconfig.cpu b/trunk/arch/x86/Kconfig.cpu index f2824fb8c79c..527519b8a9f9 100644 --- a/trunk/arch/x86/Kconfig.cpu +++ b/trunk/arch/x86/Kconfig.cpu @@ -400,7 +400,7 @@ config X86_TSC config X86_CMPXCHG64 def_bool y - depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM + depends on X86_PAE || X86_64 # this should be set for all -march=.. options where the compiler # generates cmov. @@ -412,7 +412,6 @@ config X86_MINIMUM_CPU_FAMILY int default "64" if X86_64 default "6" if X86_32 && X86_P6_NOP - default "5" if X86_32 && X86_CMPXCHG64 default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK) default "3" diff --git a/trunk/arch/x86/ia32/ia32entry.S b/trunk/arch/x86/ia32/ia32entry.S index 1733f9f65e82..74619c4f9fda 100644 --- a/trunk/arch/x86/ia32/ia32entry.S +++ b/trunk/arch/x86/ia32/ia32entry.S @@ -21,8 +21,8 @@ #define __AUDIT_ARCH_LE 0x40000000 #ifndef CONFIG_AUDITSYSCALL -#define sysexit_audit ia32_ret_from_sys_call -#define sysretl_audit ia32_ret_from_sys_call +#define sysexit_audit int_ret_from_sys_call +#define sysretl_audit int_ret_from_sys_call #endif #define IA32_NR_syscalls ((ia32_syscall_end - ia32_sys_call_table)/8) @@ -39,12 +39,12 @@ .endm /* clobbers %eax */ - .macro CLEAR_RREGS offset=0, _r9=rax + .macro CLEAR_RREGS _r9=rax xorl %eax,%eax - movq %rax,\offset+R11(%rsp) - movq %rax,\offset+R10(%rsp) - movq %\_r9,\offset+R9(%rsp) - movq %rax,\offset+R8(%rsp) + movq %rax,R11(%rsp) + movq %rax,R10(%rsp) + movq %\_r9,R9(%rsp) + movq %rax,R8(%rsp) .endm /* @@ -172,10 +172,6 @@ sysexit_from_sys_call: movl RIP-R11(%rsp),%edx /* User %eip */ CFI_REGISTER rip,rdx RESTORE_ARGS 1,24,1,1,1,1 - xorq %r8,%r8 - xorq %r9,%r9 - xorq %r10,%r10 - xorq %r11,%r11 popfq CFI_ADJUST_CFA_OFFSET -8 /*CFI_RESTORE rflags*/ @@ -206,7 +202,7 @@ sysexit_from_sys_call: .macro auditsys_exit exit,ebpsave=RBP testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags(%r10) - jnz ia32_ret_from_sys_call + jnz int_ret_from_sys_call TRACE_IRQS_ON sti movl %eax,%esi /* second arg, syscall return value */ @@ -222,9 +218,8 @@ sysexit_from_sys_call: cli TRACE_IRQS_OFF testl %edi,TI_flags(%r10) - jz \exit - CLEAR_RREGS -ARGOFFSET - jmp int_with_check + jnz int_with_check + jmp \exit .endm sysenter_auditsys: @@ -334,9 +329,6 @@ sysretl_from_sys_call: CFI_REGISTER rip,rcx movl EFLAGS-ARGOFFSET(%rsp),%r11d /*CFI_REGISTER rflags,r11*/ - xorq %r10,%r10 - xorq %r9,%r9 - xorq %r8,%r8 TRACE_IRQS_ON movl RSP-ARGOFFSET(%rsp),%esp CFI_RESTORE rsp @@ -361,7 +353,7 @@ cstar_tracesys: #endif xchgl %r9d,%ebp SAVE_REST - CLEAR_RREGS 0, r9 + CLEAR_RREGS r9 movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */ movq %rsp,%rdi /* &pt_regs -> arg1 */ call syscall_trace_enter @@ -433,8 +425,6 @@ ia32_do_call: call *ia32_sys_call_table(,%rax,8) # xxx: rip relative ia32_sysret: movq %rax,RAX-ARGOFFSET(%rsp) -ia32_ret_from_sys_call: - CLEAR_RREGS -ARGOFFSET jmp int_ret_from_sys_call ia32_tracesys: @@ -452,8 +442,8 @@ END(ia32_syscall) ia32_badsys: movq $0,ORIG_RAX-ARGOFFSET(%rsp) - movq $-ENOSYS,%rax - jmp ia32_sysret + movq $-ENOSYS,RAX-ARGOFFSET(%rsp) + jmp int_ret_from_sys_call quiet_ni_syscall: movq $-ENOSYS,%rax diff --git a/trunk/arch/x86/kernel/early_printk.c b/trunk/arch/x86/kernel/early_printk.c index b9c830c12b4a..41fd965c80c6 100644 --- a/trunk/arch/x86/kernel/early_printk.c +++ b/trunk/arch/x86/kernel/early_printk.c @@ -206,11 +206,8 @@ static int __init setup_early_printk(char *buf) while (*buf != '\0') { if (!strncmp(buf, "serial", 6)) { - buf += 6; - early_serial_init(buf); + early_serial_init(buf + 6); early_console_register(&early_serial_console, keep); - if (!strncmp(buf, ",ttyS", 5)) - buf += 5; } if (!strncmp(buf, "ttyS", 4)) { early_serial_init(buf + 4); diff --git a/trunk/arch/x86/kernel/i386_ksyms_32.c b/trunk/arch/x86/kernel/i386_ksyms_32.c index 9c3bd4a2050e..1736c5a725aa 100644 --- a/trunk/arch/x86/kernel/i386_ksyms_32.c +++ b/trunk/arch/x86/kernel/i386_ksyms_32.c @@ -15,10 +15,8 @@ EXPORT_SYMBOL(mcount); * the export, but dont use it from C code, it is used * by assembly code and is not using C calling convention! */ -#ifndef CONFIG_X86_CMPXCHG64 extern void cmpxchg8b_emu(void); EXPORT_SYMBOL(cmpxchg8b_emu); -#endif /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy_generic); diff --git a/trunk/arch/x86/kvm/svm.c b/trunk/arch/x86/kvm/svm.c index 944cc9c04b3c..bf5799dc4f9f 100644 --- a/trunk/arch/x86/kvm/svm.c +++ b/trunk/arch/x86/kvm/svm.c @@ -767,6 +767,8 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) rdtscll(tsc_this); delta = vcpu->arch.host_tsc - tsc_this; svm->vmcb->control.tsc_offset += delta; + if (is_nested(svm)) + svm->nested.hsave->control.tsc_offset += delta; vcpu->cpu = cpu; kvm_migrate_timers(vcpu); svm->asid_generation = 0; diff --git a/trunk/arch/x86/lib/Makefile b/trunk/arch/x86/lib/Makefile index 85f5db95c60f..3e549b8ec8c9 100644 --- a/trunk/arch/x86/lib/Makefile +++ b/trunk/arch/x86/lib/Makefile @@ -15,10 +15,8 @@ ifeq ($(CONFIG_X86_32),y) obj-y += atomic64_32.o lib-y += checksum_32.o lib-y += strstr_32.o - lib-y += semaphore_32.o string_32.o -ifneq ($(CONFIG_X86_CMPXCHG64),y) - lib-y += cmpxchg8b_emu.o -endif + lib-y += semaphore_32.o string_32.o cmpxchg8b_emu.o + lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o else obj-y += io_64.o iomap_copy_64.o diff --git a/trunk/block/blk-barrier.c b/trunk/block/blk-barrier.c index 8873b9b439ff..6593ab39cfe9 100644 --- a/trunk/block/blk-barrier.c +++ b/trunk/block/blk-barrier.c @@ -350,7 +350,6 @@ static void blkdev_discard_end_io(struct bio *bio, int err) if (bio->bi_private) complete(bio->bi_private); - __free_page(bio_page(bio)); bio_put(bio); } @@ -373,50 +372,30 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, struct request_queue *q = bdev_get_queue(bdev); int type = flags & DISCARD_FL_BARRIER ? DISCARD_BARRIER : DISCARD_NOBARRIER; - struct bio *bio; - struct page *page; int ret = 0; if (!q) return -ENXIO; - if (!blk_queue_discard(q)) + if (!q->prepare_discard_fn) return -EOPNOTSUPP; while (nr_sects && !ret) { - unsigned int sector_size = q->limits.logical_block_size; - unsigned int max_discard_sectors = - min(q->limits.max_discard_sectors, UINT_MAX >> 9); - - bio = bio_alloc(gfp_mask, 1); + struct bio *bio = bio_alloc(gfp_mask, 0); if (!bio) - goto out; - bio->bi_sector = sector; + return -ENOMEM; + bio->bi_end_io = blkdev_discard_end_io; bio->bi_bdev = bdev; if (flags & DISCARD_FL_WAIT) bio->bi_private = &wait; - /* - * Add a zeroed one-sector payload as that's what - * our current implementations need. If we'll ever need - * more the interface will need revisiting. - */ - page = alloc_page(GFP_KERNEL | __GFP_ZERO); - if (!page) - goto out_free_bio; - if (bio_add_pc_page(q, bio, page, sector_size, 0) < sector_size) - goto out_free_page; + bio->bi_sector = sector; - /* - * And override the bio size - the way discard works we - * touch many more blocks on disk than the actual payload - * length. - */ - if (nr_sects > max_discard_sectors) { - bio->bi_size = max_discard_sectors << 9; - nr_sects -= max_discard_sectors; - sector += max_discard_sectors; + if (nr_sects > queue_max_hw_sectors(q)) { + bio->bi_size = queue_max_hw_sectors(q) << 9; + nr_sects -= queue_max_hw_sectors(q); + sector += queue_max_hw_sectors(q); } else { bio->bi_size = nr_sects << 9; nr_sects = 0; @@ -435,11 +414,5 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, bio_put(bio); } return ret; -out_free_page: - __free_page(page); -out_free_bio: - bio_put(bio); -out: - return -ENOMEM; } EXPORT_SYMBOL(blkdev_issue_discard); diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index 81f34311659a..8135228e4b29 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -34,7 +34,6 @@ #include "blk.h" EXPORT_TRACEPOINT_SYMBOL_GPL(block_remap); -EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap); EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete); static int __make_request(struct request_queue *q, struct bio *bio); @@ -70,7 +69,7 @@ static void drive_stat_acct(struct request *rq, int new_io) part_stat_inc(cpu, part, merges[rw]); else { part_round_stats(cpu, part); - part_inc_in_flight(part); + part_inc_in_flight(part, rw); } part_stat_unlock(); @@ -1032,7 +1031,7 @@ static void part_round_stats_single(int cpu, struct hd_struct *part, if (part->in_flight) { __part_stat_add(cpu, part, time_in_queue, - part->in_flight * (now - part->stamp)); + part_in_flight(part) * (now - part->stamp)); __part_stat_add(cpu, part, io_ticks, (now - part->stamp)); } part->stamp = now; @@ -1125,6 +1124,7 @@ void init_request_from_bio(struct request *req, struct bio *bio) req->cmd_flags |= REQ_DISCARD; if (bio_rw_flagged(bio, BIO_RW_BARRIER)) req->cmd_flags |= REQ_SOFTBARRIER; + req->q->prepare_discard_fn(req->q, req); } else if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) req->cmd_flags |= REQ_HARDBARRIER; @@ -1437,8 +1437,7 @@ static inline void __generic_make_request(struct bio *bio) goto end_io; } - if (unlikely(!bio_rw_flagged(bio, BIO_RW_DISCARD) && - nr_sectors > queue_max_hw_sectors(q))) { + if (unlikely(nr_sectors > queue_max_hw_sectors(q))) { printk(KERN_ERR "bio too big device %s (%u > %u)\n", bdevname(bio->bi_bdev, b), bio_sectors(bio), @@ -1471,7 +1470,7 @@ static inline void __generic_make_request(struct bio *bio) goto end_io; if (bio_rw_flagged(bio, BIO_RW_DISCARD) && - !blk_queue_discard(q)) { + !q->prepare_discard_fn) { err = -EOPNOTSUPP; goto end_io; } @@ -1739,7 +1738,7 @@ static void blk_account_io_done(struct request *req) part_stat_inc(cpu, part, ios[rw]); part_stat_add(cpu, part, ticks[rw], duration); part_round_stats(cpu, part); - part_dec_in_flight(part); + part_dec_in_flight(part, rw); part_stat_unlock(); } @@ -2492,14 +2491,6 @@ int kblockd_schedule_work(struct request_queue *q, struct work_struct *work) } EXPORT_SYMBOL(kblockd_schedule_work); -int kblockd_schedule_delayed_work(struct request_queue *q, - struct delayed_work *work, - unsigned long delay) -{ - return queue_delayed_work(kblockd_workqueue, work, delay); -} -EXPORT_SYMBOL(kblockd_schedule_delayed_work); - int __init blk_dev_init(void) { BUILD_BUG_ON(__REQ_NR_BITS > 8 * diff --git a/trunk/block/blk-merge.c b/trunk/block/blk-merge.c index b0de8574fdc8..99cb5cf1f447 100644 --- a/trunk/block/blk-merge.c +++ b/trunk/block/blk-merge.c @@ -351,7 +351,7 @@ static void blk_account_io_merge(struct request *req) part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req)); part_round_stats(cpu, part); - part_dec_in_flight(part); + part_dec_in_flight(part, rq_data_dir(req)); part_stat_unlock(); } diff --git a/trunk/block/blk-settings.c b/trunk/block/blk-settings.c index e0695bca7027..83413ff83739 100644 --- a/trunk/block/blk-settings.c +++ b/trunk/block/blk-settings.c @@ -33,6 +33,23 @@ void blk_queue_prep_rq(struct request_queue *q, prep_rq_fn *pfn) } EXPORT_SYMBOL(blk_queue_prep_rq); +/** + * blk_queue_set_discard - set a discard_sectors function for queue + * @q: queue + * @dfn: prepare_discard function + * + * It's possible for a queue to register a discard callback which is used + * to transform a discard request into the appropriate type for the + * hardware. If none is registered, then discard requests are failed + * with %EOPNOTSUPP. + * + */ +void blk_queue_set_discard(struct request_queue *q, prepare_discard_fn *dfn) +{ + q->prepare_discard_fn = dfn; +} +EXPORT_SYMBOL(blk_queue_set_discard); + /** * blk_queue_merge_bvec - set a merge_bvec function for queue * @q: queue @@ -94,9 +111,7 @@ void blk_set_default_limits(struct queue_limits *lim) lim->max_hw_segments = MAX_HW_SEGMENTS; lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK; lim->max_segment_size = MAX_SEGMENT_SIZE; - lim->max_sectors = BLK_DEF_MAX_SECTORS; - lim->max_hw_sectors = INT_MAX; - lim->max_discard_sectors = SAFE_MAX_SECTORS; + lim->max_sectors = lim->max_hw_sectors = SAFE_MAX_SECTORS; lim->logical_block_size = lim->physical_block_size = lim->io_min = 512; lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT); lim->alignment_offset = 0; @@ -149,7 +164,6 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn) q->unplug_timer.data = (unsigned long)q; blk_set_default_limits(&q->limits); - blk_queue_max_sectors(q, SAFE_MAX_SECTORS); /* * If the caller didn't supply a lock, fall back to our embedded @@ -239,18 +253,6 @@ void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_sectors) } EXPORT_SYMBOL(blk_queue_max_hw_sectors); -/** - * blk_queue_max_discard_sectors - set max sectors for a single discard - * @q: the request queue for the device - * @max_discard: maximum number of sectors to discard - **/ -void blk_queue_max_discard_sectors(struct request_queue *q, - unsigned int max_discard_sectors) -{ - q->limits.max_discard_sectors = max_discard_sectors; -} -EXPORT_SYMBOL(blk_queue_max_discard_sectors); - /** * blk_queue_max_phys_segments - set max phys segments for a request for this queue * @q: the request queue for the device diff --git a/trunk/block/blk-sysfs.c b/trunk/block/blk-sysfs.c index 8a6d81afb284..b78c9c3e2670 100644 --- a/trunk/block/blk-sysfs.c +++ b/trunk/block/blk-sysfs.c @@ -452,7 +452,6 @@ int blk_register_queue(struct gendisk *disk) if (ret) { kobject_uevent(&q->kobj, KOBJ_REMOVE); kobject_del(&q->kobj); - blk_trace_remove_sysfs(disk_to_dev(disk)); return ret; } @@ -466,11 +465,11 @@ void blk_unregister_queue(struct gendisk *disk) if (WARN_ON(!q)) return; - if (q->request_fn) + if (q->request_fn) { elv_unregister_queue(q); - kobject_uevent(&q->kobj, KOBJ_REMOVE); - kobject_del(&q->kobj); - blk_trace_remove_sysfs(disk_to_dev(disk)); - kobject_put(&disk_to_dev(disk)->kobj); + kobject_uevent(&q->kobj, KOBJ_REMOVE); + kobject_del(&q->kobj); + kobject_put(&disk_to_dev(disk)->kobj); + } } diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index 9c4b679908f4..1ca813b16e78 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -150,7 +150,7 @@ struct cfq_data { * idle window management */ struct timer_list idle_slice_timer; - struct delayed_work unplug_work; + struct work_struct unplug_work; struct cfq_queue *active_queue; struct cfq_io_context *active_cic; @@ -173,7 +173,6 @@ struct cfq_data { unsigned int cfq_slice[2]; unsigned int cfq_slice_async_rq; unsigned int cfq_slice_idle; - unsigned int cfq_latency; struct list_head cic_list; @@ -181,8 +180,6 @@ struct cfq_data { * Fallback dummy cfqq for extreme OOM conditions */ struct cfq_queue oom_cfqq; - - unsigned long last_end_sync_rq; }; enum cfqq_state_flags { @@ -268,13 +265,11 @@ static inline int cfq_bio_sync(struct bio *bio) * scheduler run of queue, if there are requests pending and no one in the * driver that will restart queueing */ -static inline void cfq_schedule_dispatch(struct cfq_data *cfqd, - unsigned long delay) +static inline void cfq_schedule_dispatch(struct cfq_data *cfqd) { if (cfqd->busy_queues) { cfq_log(cfqd, "schedule dispatch"); - kblockd_schedule_delayed_work(cfqd->queue, &cfqd->unplug_work, - delay); + kblockd_schedule_work(cfqd->queue, &cfqd->unplug_work); } } @@ -1331,30 +1326,12 @@ static int cfq_dispatch_requests(struct request_queue *q, int force) return 0; /* - * Sole queue user, allow bigger slice + * we are the only queue, allow up to 4 times of 'quantum' */ - max_dispatch *= 4; - } - - /* - * Async queues must wait a bit before being allowed dispatch. - * We also ramp up the dispatch depth gradually for async IO, - * based on the last sync IO we serviced - */ - if (!cfq_cfqq_sync(cfqq) && cfqd->cfq_latency) { - unsigned long last_sync = jiffies - cfqd->last_end_sync_rq; - unsigned int depth; - - depth = last_sync / cfqd->cfq_slice[1]; - if (!depth && !cfqq->dispatched) - depth = 1; - if (depth < max_dispatch) - max_dispatch = depth; + if (cfqq->dispatched >= 4 * max_dispatch) + return 0; } - if (cfqq->dispatched >= max_dispatch) - return 0; - /* * Dispatch a request from this cfqq */ @@ -1399,7 +1376,7 @@ static void cfq_put_queue(struct cfq_queue *cfqq) if (unlikely(cfqd->active_queue == cfqq)) { __cfq_slice_expired(cfqd, cfqq, 0); - cfq_schedule_dispatch(cfqd, 0); + cfq_schedule_dispatch(cfqd); } kmem_cache_free(cfq_pool, cfqq); @@ -1494,7 +1471,7 @@ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) { if (unlikely(cfqq == cfqd->active_queue)) { __cfq_slice_expired(cfqd, cfqq, 0); - cfq_schedule_dispatch(cfqd, 0); + cfq_schedule_dispatch(cfqd); } cfq_put_queue(cfqq); @@ -1974,7 +1951,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq, enable_idle = old_idle = cfq_cfqq_idle_window(cfqq); if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle || - (!cfqd->cfq_latency && cfqd->hw_tag && CIC_SEEKY(cic))) + (cfqd->hw_tag && CIC_SEEKY(cic))) enable_idle = 0; else if (sample_valid(cic->ttime_samples)) { if (cic->ttime_mean > cfqd->cfq_slice_idle) @@ -2180,10 +2157,8 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) if (cfq_cfqq_sync(cfqq)) cfqd->sync_flight--; - if (sync) { + if (sync) RQ_CIC(rq)->last_end_request = now; - cfqd->last_end_sync_rq = now; - } /* * If this is the active queue, check if it needs to be expired, @@ -2211,7 +2186,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) } if (!rq_in_driver(cfqd)) - cfq_schedule_dispatch(cfqd, 0); + cfq_schedule_dispatch(cfqd); } /* @@ -2341,7 +2316,7 @@ cfq_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask) if (cic) put_io_context(cic->ioc); - cfq_schedule_dispatch(cfqd, 0); + cfq_schedule_dispatch(cfqd); spin_unlock_irqrestore(q->queue_lock, flags); cfq_log(cfqd, "set_request fail"); return 1; @@ -2350,7 +2325,7 @@ cfq_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask) static void cfq_kick_queue(struct work_struct *work) { struct cfq_data *cfqd = - container_of(work, struct cfq_data, unplug_work.work); + container_of(work, struct cfq_data, unplug_work); struct request_queue *q = cfqd->queue; spin_lock_irq(q->queue_lock); @@ -2404,7 +2379,7 @@ static void cfq_idle_slice_timer(unsigned long data) expire: cfq_slice_expired(cfqd, timed_out); out_kick: - cfq_schedule_dispatch(cfqd, 0); + cfq_schedule_dispatch(cfqd); out_cont: spin_unlock_irqrestore(cfqd->queue->queue_lock, flags); } @@ -2412,7 +2387,7 @@ static void cfq_idle_slice_timer(unsigned long data) static void cfq_shutdown_timer_wq(struct cfq_data *cfqd) { del_timer_sync(&cfqd->idle_slice_timer); - cancel_delayed_work_sync(&cfqd->unplug_work); + cancel_work_sync(&cfqd->unplug_work); } static void cfq_put_async_queues(struct cfq_data *cfqd) @@ -2494,7 +2469,7 @@ static void *cfq_init_queue(struct request_queue *q) cfqd->idle_slice_timer.function = cfq_idle_slice_timer; cfqd->idle_slice_timer.data = (unsigned long) cfqd; - INIT_DELAYED_WORK(&cfqd->unplug_work, cfq_kick_queue); + INIT_WORK(&cfqd->unplug_work, cfq_kick_queue); cfqd->cfq_quantum = cfq_quantum; cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0]; @@ -2505,9 +2480,8 @@ static void *cfq_init_queue(struct request_queue *q) cfqd->cfq_slice[1] = cfq_slice_sync; cfqd->cfq_slice_async_rq = cfq_slice_async_rq; cfqd->cfq_slice_idle = cfq_slice_idle; - cfqd->cfq_latency = 1; cfqd->hw_tag = 1; - cfqd->last_end_sync_rq = jiffies; + return cfqd; } @@ -2575,7 +2549,6 @@ SHOW_FUNCTION(cfq_slice_idle_show, cfqd->cfq_slice_idle, 1); SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1); SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1); SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0); -SHOW_FUNCTION(cfq_low_latency_show, cfqd->cfq_latency, 0); #undef SHOW_FUNCTION #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ @@ -2607,7 +2580,6 @@ STORE_FUNCTION(cfq_slice_sync_store, &cfqd->cfq_slice[1], 1, UINT_MAX, 1); STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1); STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, UINT_MAX, 0); -STORE_FUNCTION(cfq_low_latency_store, &cfqd->cfq_latency, 0, 1, 0); #undef STORE_FUNCTION #define CFQ_ATTR(name) \ @@ -2623,7 +2595,6 @@ static struct elv_fs_entry cfq_attrs[] = { CFQ_ATTR(slice_async), CFQ_ATTR(slice_async_rq), CFQ_ATTR(slice_idle), - CFQ_ATTR(low_latency), __ATTR_NULL }; diff --git a/trunk/block/compat_ioctl.c b/trunk/block/compat_ioctl.c index 9bd086c1a4d5..7865a34e0faa 100644 --- a/trunk/block/compat_ioctl.c +++ b/trunk/block/compat_ioctl.c @@ -21,11 +21,6 @@ static int compat_put_int(unsigned long arg, int val) return put_user(val, (compat_int_t __user *)compat_ptr(arg)); } -static int compat_put_uint(unsigned long arg, unsigned int val) -{ - return put_user(val, (compat_uint_t __user *)compat_ptr(arg)); -} - static int compat_put_long(unsigned long arg, long val) { return put_user(val, (compat_long_t __user *)compat_ptr(arg)); @@ -739,14 +734,6 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) switch (cmd) { case HDIO_GETGEO: return compat_hdio_getgeo(disk, bdev, compat_ptr(arg)); - case BLKPBSZGET: - return compat_put_uint(arg, bdev_physical_block_size(bdev)); - case BLKIOMIN: - return compat_put_uint(arg, bdev_io_min(bdev)); - case BLKIOOPT: - return compat_put_uint(arg, bdev_io_opt(bdev)); - case BLKALIGNOFF: - return compat_put_int(arg, bdev_alignment_offset(bdev)); case BLKFLSBUF: case BLKROSET: case BLKDISCARD: diff --git a/trunk/block/genhd.c b/trunk/block/genhd.c index 5a0861da324d..517e4332cb37 100644 --- a/trunk/block/genhd.c +++ b/trunk/block/genhd.c @@ -869,6 +869,7 @@ static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); static DEVICE_ATTR(alignment_offset, S_IRUGO, disk_alignment_offset_show, NULL); static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL); static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); +static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL); #ifdef CONFIG_FAIL_MAKE_REQUEST static struct device_attribute dev_attr_fail = __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store); @@ -888,6 +889,7 @@ static struct attribute *disk_attrs[] = { &dev_attr_alignment_offset.attr, &dev_attr_capability.attr, &dev_attr_stat.attr, + &dev_attr_inflight.attr, #ifdef CONFIG_FAIL_MAKE_REQUEST &dev_attr_fail.attr, #endif @@ -1053,7 +1055,7 @@ static int diskstats_show(struct seq_file *seqf, void *v) part_stat_read(hd, merges[1]), (unsigned long long)part_stat_read(hd, sectors[1]), jiffies_to_msecs(part_stat_read(hd, ticks[1])), - hd->in_flight, + part_in_flight(hd), jiffies_to_msecs(part_stat_read(hd, io_ticks)), jiffies_to_msecs(part_stat_read(hd, time_in_queue)) ); diff --git a/trunk/block/ioctl.c b/trunk/block/ioctl.c index 1f4d1de12b09..d3e6b5827a34 100644 --- a/trunk/block/ioctl.c +++ b/trunk/block/ioctl.c @@ -138,11 +138,6 @@ static int put_int(unsigned long arg, int val) return put_user(val, (int __user *)arg); } -static int put_uint(unsigned long arg, unsigned int val) -{ - return put_user(val, (unsigned int __user *)arg); -} - static int put_long(unsigned long arg, long val) { return put_user(val, (long __user *)arg); @@ -268,18 +263,10 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512); case BLKROGET: return put_int(arg, bdev_read_only(bdev) != 0); - case BLKBSZGET: /* get block device soft block size (cf. BLKSSZGET) */ + case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */ return put_int(arg, block_size(bdev)); - case BLKSSZGET: /* get block device logical block size */ + case BLKSSZGET: /* get block device hardware sector size */ return put_int(arg, bdev_logical_block_size(bdev)); - case BLKPBSZGET: /* get block device physical block size */ - return put_uint(arg, bdev_physical_block_size(bdev)); - case BLKIOMIN: - return put_uint(arg, bdev_io_min(bdev)); - case BLKIOOPT: - return put_uint(arg, bdev_io_opt(bdev)); - case BLKALIGNOFF: - return put_int(arg, bdev_alignment_offset(bdev)); case BLKSECTGET: return put_ushort(arg, queue_max_sectors(bdev_get_queue(bdev))); case BLKRASET: diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index 0ed42d8870c7..dd8729d674e5 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -211,18 +211,6 @@ config ACPI_HOTPLUG_CPU select ACPI_CONTAINER default y -config ACPI_PROCESSOR_AGGREGATOR - tristate "Processor Aggregator" - depends on ACPI_PROCESSOR - depends on EXPERIMENTAL - depends on X86 - help - ACPI 4.0 defines processor Aggregator, which enables OS to perform - specfic processor configuration and control that applies to all - processors in the platform. Currently only logical processor idling - is defined, which is to reduce power consumption. This driver - support the new device. - config ACPI_THERMAL tristate "Thermal Zone" depends on ACPI_PROCESSOR diff --git a/trunk/drivers/acpi/Makefile b/trunk/drivers/acpi/Makefile index 7702118509a0..82cd49dc603b 100644 --- a/trunk/drivers/acpi/Makefile +++ b/trunk/drivers/acpi/Makefile @@ -62,5 +62,3 @@ obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o processor-y := processor_core.o processor_throttling.o processor-y += processor_idle.o processor_thermal.o processor-$(CONFIG_CPU_FREQ) += processor_perflib.o - -obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o diff --git a/trunk/drivers/acpi/acpi_pad.c b/trunk/drivers/acpi/acpi_pad.c deleted file mode 100644 index 0d2cdb86158b..000000000000 --- a/trunk/drivers/acpi/acpi_pad.c +++ /dev/null @@ -1,514 +0,0 @@ -/* - * acpi_pad.c ACPI Processor Aggregator Driver - * - * Copyright (c) 2009, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ACPI_PROCESSOR_AGGREGATOR_CLASS "processor_aggregator" -#define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" -#define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80 -static DEFINE_MUTEX(isolated_cpus_lock); - -#define MWAIT_SUBSTATE_MASK (0xf) -#define MWAIT_CSTATE_MASK (0xf) -#define MWAIT_SUBSTATE_SIZE (4) -#define CPUID_MWAIT_LEAF (5) -#define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1) -#define CPUID5_ECX_INTERRUPT_BREAK (0x2) -static unsigned long power_saving_mwait_eax; -static void power_saving_mwait_init(void) -{ - unsigned int eax, ebx, ecx, edx; - unsigned int highest_cstate = 0; - unsigned int highest_subcstate = 0; - int i; - - if (!boot_cpu_has(X86_FEATURE_MWAIT)) - return; - if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) - return; - - cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx); - - if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) || - !(ecx & CPUID5_ECX_INTERRUPT_BREAK)) - return; - - edx >>= MWAIT_SUBSTATE_SIZE; - for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) { - if (edx & MWAIT_SUBSTATE_MASK) { - highest_cstate = i; - highest_subcstate = edx & MWAIT_SUBSTATE_MASK; - } - } - power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) | - (highest_subcstate - 1); - - for_each_online_cpu(i) - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &i); - -#if defined(CONFIG_GENERIC_TIME) && defined(CONFIG_X86) - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - case X86_VENDOR_INTEL: - /* - * AMD Fam10h TSC will tick in all - * C/P/S0/S1 states when this bit is set. - */ - if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) - return; - - /*FALL THROUGH*/ - default: - /* TSC could halt in idle, so notify users */ - mark_tsc_unstable("TSC halts in idle"); - } -#endif -} - -static unsigned long cpu_weight[NR_CPUS]; -static int tsk_in_cpu[NR_CPUS] = {[0 ... NR_CPUS-1] = -1}; -static DECLARE_BITMAP(pad_busy_cpus_bits, NR_CPUS); -static void round_robin_cpu(unsigned int tsk_index) -{ - struct cpumask *pad_busy_cpus = to_cpumask(pad_busy_cpus_bits); - cpumask_var_t tmp; - int cpu; - unsigned long min_weight = -1, preferred_cpu; - - if (!alloc_cpumask_var(&tmp, GFP_KERNEL)) - return; - - mutex_lock(&isolated_cpus_lock); - cpumask_clear(tmp); - for_each_cpu(cpu, pad_busy_cpus) - cpumask_or(tmp, tmp, topology_thread_cpumask(cpu)); - cpumask_andnot(tmp, cpu_online_mask, tmp); - /* avoid HT sibilings if possible */ - if (cpumask_empty(tmp)) - cpumask_andnot(tmp, cpu_online_mask, pad_busy_cpus); - if (cpumask_empty(tmp)) { - mutex_unlock(&isolated_cpus_lock); - return; - } - for_each_cpu(cpu, tmp) { - if (cpu_weight[cpu] < min_weight) { - min_weight = cpu_weight[cpu]; - preferred_cpu = cpu; - } - } - - if (tsk_in_cpu[tsk_index] != -1) - cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus); - tsk_in_cpu[tsk_index] = preferred_cpu; - cpumask_set_cpu(preferred_cpu, pad_busy_cpus); - cpu_weight[preferred_cpu]++; - mutex_unlock(&isolated_cpus_lock); - - set_cpus_allowed_ptr(current, cpumask_of(preferred_cpu)); -} - -static void exit_round_robin(unsigned int tsk_index) -{ - struct cpumask *pad_busy_cpus = to_cpumask(pad_busy_cpus_bits); - cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus); - tsk_in_cpu[tsk_index] = -1; -} - -static unsigned int idle_pct = 5; /* percentage */ -static unsigned int round_robin_time = 10; /* second */ -static int power_saving_thread(void *data) -{ - struct sched_param param = {.sched_priority = 1}; - int do_sleep; - unsigned int tsk_index = (unsigned long)data; - u64 last_jiffies = 0; - - sched_setscheduler(current, SCHED_RR, ¶m); - - while (!kthread_should_stop()) { - int cpu; - u64 expire_time; - - try_to_freeze(); - - /* round robin to cpus */ - if (last_jiffies + round_robin_time * HZ < jiffies) { - last_jiffies = jiffies; - round_robin_cpu(tsk_index); - } - - do_sleep = 0; - - current_thread_info()->status &= ~TS_POLLING; - /* - * TS_POLLING-cleared state must be visible before we test - * NEED_RESCHED: - */ - smp_mb(); - - expire_time = jiffies + HZ * (100 - idle_pct) / 100; - - while (!need_resched()) { - local_irq_disable(); - cpu = smp_processor_id(); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, - &cpu); - stop_critical_timings(); - - __monitor((void *)¤t_thread_info()->flags, 0, 0); - smp_mb(); - if (!need_resched()) - __mwait(power_saving_mwait_eax, 1); - - start_critical_timings(); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, - &cpu); - local_irq_enable(); - - if (jiffies > expire_time) { - do_sleep = 1; - break; - } - } - - current_thread_info()->status |= TS_POLLING; - - /* - * current sched_rt has threshold for rt task running time. - * When a rt task uses 95% CPU time, the rt thread will be - * scheduled out for 5% CPU time to not starve other tasks. But - * the mechanism only works when all CPUs have RT task running, - * as if one CPU hasn't RT task, RT task from other CPUs will - * borrow CPU time from this CPU and cause RT task use > 95% - * CPU time. To make 'avoid staration' work, takes a nap here. - */ - if (do_sleep) - schedule_timeout_killable(HZ * idle_pct / 100); - } - - exit_round_robin(tsk_index); - return 0; -} - -static struct task_struct *ps_tsks[NR_CPUS]; -static unsigned int ps_tsk_num; -static int create_power_saving_task(void) -{ - ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread, - (void *)(unsigned long)ps_tsk_num, - "power_saving/%d", ps_tsk_num); - if (ps_tsks[ps_tsk_num]) { - ps_tsk_num++; - return 0; - } - return -EINVAL; -} - -static void destroy_power_saving_task(void) -{ - if (ps_tsk_num > 0) { - ps_tsk_num--; - kthread_stop(ps_tsks[ps_tsk_num]); - } -} - -static void set_power_saving_task_num(unsigned int num) -{ - if (num > ps_tsk_num) { - while (ps_tsk_num < num) { - if (create_power_saving_task()) - return; - } - } else if (num < ps_tsk_num) { - while (ps_tsk_num > num) - destroy_power_saving_task(); - } -} - -static int acpi_pad_idle_cpus(unsigned int num_cpus) -{ - get_online_cpus(); - - num_cpus = min_t(unsigned int, num_cpus, num_online_cpus()); - set_power_saving_task_num(num_cpus); - - put_online_cpus(); - return 0; -} - -static uint32_t acpi_pad_idle_cpus_num(void) -{ - return ps_tsk_num; -} - -static ssize_t acpi_pad_rrtime_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned long num; - if (strict_strtoul(buf, 0, &num)) - return -EINVAL; - if (num < 1 || num >= 100) - return -EINVAL; - mutex_lock(&isolated_cpus_lock); - round_robin_time = num; - mutex_unlock(&isolated_cpus_lock); - return count; -} - -static ssize_t acpi_pad_rrtime_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return scnprintf(buf, PAGE_SIZE, "%d", round_robin_time); -} -static DEVICE_ATTR(rrtime, S_IRUGO|S_IWUSR, - acpi_pad_rrtime_show, - acpi_pad_rrtime_store); - -static ssize_t acpi_pad_idlepct_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned long num; - if (strict_strtoul(buf, 0, &num)) - return -EINVAL; - if (num < 1 || num >= 100) - return -EINVAL; - mutex_lock(&isolated_cpus_lock); - idle_pct = num; - mutex_unlock(&isolated_cpus_lock); - return count; -} - -static ssize_t acpi_pad_idlepct_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return scnprintf(buf, PAGE_SIZE, "%d", idle_pct); -} -static DEVICE_ATTR(idlepct, S_IRUGO|S_IWUSR, - acpi_pad_idlepct_show, - acpi_pad_idlepct_store); - -static ssize_t acpi_pad_idlecpus_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned long num; - if (strict_strtoul(buf, 0, &num)) - return -EINVAL; - mutex_lock(&isolated_cpus_lock); - acpi_pad_idle_cpus(num); - mutex_unlock(&isolated_cpus_lock); - return count; -} - -static ssize_t acpi_pad_idlecpus_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return cpumask_scnprintf(buf, PAGE_SIZE, - to_cpumask(pad_busy_cpus_bits)); -} -static DEVICE_ATTR(idlecpus, S_IRUGO|S_IWUSR, - acpi_pad_idlecpus_show, - acpi_pad_idlecpus_store); - -static int acpi_pad_add_sysfs(struct acpi_device *device) -{ - int result; - - result = device_create_file(&device->dev, &dev_attr_idlecpus); - if (result) - return -ENODEV; - result = device_create_file(&device->dev, &dev_attr_idlepct); - if (result) { - device_remove_file(&device->dev, &dev_attr_idlecpus); - return -ENODEV; - } - result = device_create_file(&device->dev, &dev_attr_rrtime); - if (result) { - device_remove_file(&device->dev, &dev_attr_idlecpus); - device_remove_file(&device->dev, &dev_attr_idlepct); - return -ENODEV; - } - return 0; -} - -static void acpi_pad_remove_sysfs(struct acpi_device *device) -{ - device_remove_file(&device->dev, &dev_attr_idlecpus); - device_remove_file(&device->dev, &dev_attr_idlepct); - device_remove_file(&device->dev, &dev_attr_rrtime); -} - -/* Query firmware how many CPUs should be idle */ -static int acpi_pad_pur(acpi_handle handle, int *num_cpus) -{ - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - acpi_status status; - union acpi_object *package; - int rev, num, ret = -EINVAL; - - status = acpi_evaluate_object(handle, "_PUR", NULL, &buffer); - if (ACPI_FAILURE(status)) - return -EINVAL; - package = buffer.pointer; - if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2) - goto out; - rev = package->package.elements[0].integer.value; - num = package->package.elements[1].integer.value; - if (rev != 1) - goto out; - *num_cpus = num; - ret = 0; -out: - kfree(buffer.pointer); - return ret; -} - -/* Notify firmware how many CPUs are idle */ -static void acpi_pad_ost(acpi_handle handle, int stat, - uint32_t idle_cpus) -{ - union acpi_object params[3] = { - {.type = ACPI_TYPE_INTEGER,}, - {.type = ACPI_TYPE_INTEGER,}, - {.type = ACPI_TYPE_BUFFER,}, - }; - struct acpi_object_list arg_list = {3, params}; - - params[0].integer.value = ACPI_PROCESSOR_AGGREGATOR_NOTIFY; - params[1].integer.value = stat; - params[2].buffer.length = 4; - params[2].buffer.pointer = (void *)&idle_cpus; - acpi_evaluate_object(handle, "_OST", &arg_list, NULL); -} - -static void acpi_pad_handle_notify(acpi_handle handle) -{ - int num_cpus, ret; - uint32_t idle_cpus; - - mutex_lock(&isolated_cpus_lock); - if (acpi_pad_pur(handle, &num_cpus)) { - mutex_unlock(&isolated_cpus_lock); - return; - } - ret = acpi_pad_idle_cpus(num_cpus); - idle_cpus = acpi_pad_idle_cpus_num(); - if (!ret) - acpi_pad_ost(handle, 0, idle_cpus); - else - acpi_pad_ost(handle, 1, 0); - mutex_unlock(&isolated_cpus_lock); -} - -static void acpi_pad_notify(acpi_handle handle, u32 event, - void *data) -{ - struct acpi_device *device = data; - - switch (event) { - case ACPI_PROCESSOR_AGGREGATOR_NOTIFY: - acpi_pad_handle_notify(handle); - acpi_bus_generate_proc_event(device, event, 0); - acpi_bus_generate_netlink_event(device->pnp.device_class, - dev_name(&device->dev), event, 0); - break; - default: - printk(KERN_WARNING"Unsupported event [0x%x]\n", event); - break; - } -} - -static int acpi_pad_add(struct acpi_device *device) -{ - acpi_status status; - - strcpy(acpi_device_name(device), ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME); - strcpy(acpi_device_class(device), ACPI_PROCESSOR_AGGREGATOR_CLASS); - - if (acpi_pad_add_sysfs(device)) - return -ENODEV; - - status = acpi_install_notify_handler(device->handle, - ACPI_DEVICE_NOTIFY, acpi_pad_notify, device); - if (ACPI_FAILURE(status)) { - acpi_pad_remove_sysfs(device); - return -ENODEV; - } - - return 0; -} - -static int acpi_pad_remove(struct acpi_device *device, - int type) -{ - mutex_lock(&isolated_cpus_lock); - acpi_pad_idle_cpus(0); - mutex_unlock(&isolated_cpus_lock); - - acpi_remove_notify_handler(device->handle, - ACPI_DEVICE_NOTIFY, acpi_pad_notify); - acpi_pad_remove_sysfs(device); - return 0; -} - -static const struct acpi_device_id pad_device_ids[] = { - {"ACPI000C", 0}, - {"", 0}, -}; -MODULE_DEVICE_TABLE(acpi, pad_device_ids); - -static struct acpi_driver acpi_pad_driver = { - .name = "processor_aggregator", - .class = ACPI_PROCESSOR_AGGREGATOR_CLASS, - .ids = pad_device_ids, - .ops = { - .add = acpi_pad_add, - .remove = acpi_pad_remove, - }, -}; - -static int __init acpi_pad_init(void) -{ - power_saving_mwait_init(); - if (power_saving_mwait_eax == 0) - return -EINVAL; - - return acpi_bus_register_driver(&acpi_pad_driver); -} - -static void __exit acpi_pad_exit(void) -{ - acpi_bus_unregister_driver(&acpi_pad_driver); -} - -module_init(acpi_pad_init); -module_exit(acpi_pad_exit); -MODULE_AUTHOR("Shaohua Li"); -MODULE_DESCRIPTION("ACPI Processor Aggregator Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/acpi/dock.c b/trunk/drivers/acpi/dock.c index 7338b6a3e049..3a2cfefc71ab 100644 --- a/trunk/drivers/acpi/dock.c +++ b/trunk/drivers/acpi/dock.c @@ -67,7 +67,7 @@ struct dock_station { struct list_head dependent_devices; struct list_head hotplug_devices; - struct list_head sibling; + struct list_head sibiling; struct platform_device *dock_device; }; static LIST_HEAD(dock_stations); @@ -275,7 +275,7 @@ int is_dock_device(acpi_handle handle) if (is_dock(handle)) return 1; - list_for_each_entry(dock_station, &dock_stations, sibling) { + list_for_each_entry(dock_station, &dock_stations, sibiling) { if (find_dock_dependent_device(dock_station, handle)) return 1; } @@ -619,7 +619,7 @@ register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops, * make sure this handle is for a device dependent on the dock, * this would include the dock station itself */ - list_for_each_entry(dock_station, &dock_stations, sibling) { + list_for_each_entry(dock_station, &dock_stations, sibiling) { /* * An ATA bay can be in a dock and itself can be ejected * seperately, so there are two 'dock stations' which need the @@ -651,7 +651,7 @@ void unregister_hotplug_dock_device(acpi_handle handle) if (!dock_station_count) return; - list_for_each_entry(dock_station, &dock_stations, sibling) { + list_for_each_entry(dock_station, &dock_stations, sibiling) { dd = find_dock_dependent_device(dock_station, handle); if (dd) dock_del_hotplug_device(dock_station, dd); @@ -787,7 +787,7 @@ static int acpi_dock_notifier_call(struct notifier_block *this, if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK && event != ACPI_NOTIFY_EJECT_REQUEST) return 0; - list_for_each_entry(dock_station, &dock_stations, sibling) { + list_for_each_entry(dock_station, &dock_stations, sibiling) { if (dock_station->handle == handle) { struct dock_data *dock_data; @@ -958,7 +958,7 @@ static int dock_add(acpi_handle handle) dock_station->last_dock_time = jiffies - HZ; INIT_LIST_HEAD(&dock_station->dependent_devices); INIT_LIST_HEAD(&dock_station->hotplug_devices); - INIT_LIST_HEAD(&dock_station->sibling); + INIT_LIST_HEAD(&dock_station->sibiling); spin_lock_init(&dock_station->dd_lock); mutex_init(&dock_station->hp_lock); ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); @@ -1044,7 +1044,7 @@ static int dock_add(acpi_handle handle) add_dock_dependent_device(dock_station, dd); dock_station_count++; - list_add(&dock_station->sibling, &dock_stations); + list_add(&dock_station->sibiling, &dock_stations); return 0; dock_add_err_unregister: @@ -1149,7 +1149,7 @@ static void __exit dock_exit(void) struct dock_station *tmp; unregister_acpi_bus_notifier(&dock_acpi_notifier); - list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibling) + list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibiling) dock_remove(dock_station); } diff --git a/trunk/drivers/acpi/ec.c b/trunk/drivers/acpi/ec.c index baef28c1e630..f70796081c4c 100644 --- a/trunk/drivers/acpi/ec.c +++ b/trunk/drivers/acpi/ec.c @@ -119,8 +119,6 @@ static struct acpi_ec { } *boot_ec, *first_ec; static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ -static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ -static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */ /* -------------------------------------------------------------------------- Transaction Management @@ -234,8 +232,10 @@ static int ec_poll(struct acpi_ec *ec) } advance_transaction(ec, acpi_ec_read_status(ec)); } while (time_before(jiffies, delay)); - if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) + if (!ec->curr->irq_count || + (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)) break; + /* try restart command if we get any false interrupts */ pr_debug(PREFIX "controller reset, restart transaction\n"); spin_lock_irqsave(&ec->curr_lock, flags); start_transaction(ec); @@ -899,44 +899,6 @@ static const struct acpi_device_id ec_device_ids[] = { {"", 0}, }; -/* Some BIOS do not survive early DSDT scan, skip it */ -static int ec_skip_dsdt_scan(const struct dmi_system_id *id) -{ - EC_FLAGS_SKIP_DSDT_SCAN = 1; - return 0; -} - -/* ASUStek often supplies us with broken ECDT, validate it */ -static int ec_validate_ecdt(const struct dmi_system_id *id) -{ - EC_FLAGS_VALIDATE_ECDT = 1; - return 0; -} - -/* MSI EC needs special treatment, enable it */ -static int ec_flag_msi(const struct dmi_system_id *id) -{ - EC_FLAGS_MSI = 1; - EC_FLAGS_VALIDATE_ECDT = 1; - return 0; -} - -static struct dmi_system_id __initdata ec_dmi_table[] = { - { - ec_skip_dsdt_scan, "Compal JFL92", { - DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), - DMI_MATCH(DMI_BOARD_NAME, "JFL92") }, NULL}, - { - ec_flag_msi, "MSI hardware", { - DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star"), - DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star") }, NULL}, - { - ec_validate_ecdt, "ASUS hardware", { - DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, - {}, -}; - - int __init acpi_ec_ecdt_probe(void) { acpi_status status; @@ -949,7 +911,11 @@ int __init acpi_ec_ecdt_probe(void) /* * Generate a boot ec context */ - dmi_check_system(ec_dmi_table); + if (dmi_name_in_vendors("Micro-Star") || + dmi_name_in_vendors("Notebook")) { + pr_info(PREFIX "Enabling special treatment for EC from MSI.\n"); + EC_FLAGS_MSI = 1; + } status = acpi_get_table(ACPI_SIG_ECDT, 1, (struct acpi_table_header **)&ecdt_ptr); if (ACPI_SUCCESS(status)) { @@ -960,7 +926,7 @@ int __init acpi_ec_ecdt_probe(void) boot_ec->handle = ACPI_ROOT_OBJECT; acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); /* Don't trust ECDT, which comes from ASUSTek */ - if (!EC_FLAGS_VALIDATE_ECDT) + if (!dmi_name_in_vendors("ASUS") && EC_FLAGS_MSI == 0) goto install; saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); if (!saved_ec) @@ -968,10 +934,6 @@ int __init acpi_ec_ecdt_probe(void) memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec)); /* fall through */ } - - if (EC_FLAGS_SKIP_DSDT_SCAN) - return -ENODEV; - /* This workaround is needed only on some broken machines, * which require early EC, but fail to provide ECDT */ printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); diff --git a/trunk/drivers/acpi/proc.c b/trunk/drivers/acpi/proc.c index f8b6f555ba52..d0d550d22a6d 100644 --- a/trunk/drivers/acpi/proc.c +++ b/trunk/drivers/acpi/proc.c @@ -398,8 +398,6 @@ acpi_system_write_wakeup_device(struct file *file, if (len > 4) len = 4; - if (len < 0) - return -EFAULT; if (copy_from_user(strbuf, buffer, len)) return -EFAULT; diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c index c567b46dfa0f..c2d4d6e09364 100644 --- a/trunk/drivers/acpi/processor_core.c +++ b/trunk/drivers/acpi/processor_core.c @@ -863,6 +863,13 @@ static int acpi_processor_add(struct acpi_device *device) goto err_remove_sysfs; } + if (pr->flags.throttling) { + printk(KERN_INFO PREFIX "%s [%s] (supports", + acpi_device_name(device), acpi_device_bid(device)); + printk(" %d throttling states", pr->throttling.state_count); + printk(")\n"); + } + return 0; err_remove_sysfs: diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index 14a7481c97d7..468921bed22f 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -1052,8 +1052,6 @@ static void acpi_device_set_id(struct acpi_device *device) device->flags.bus_address = 1; } - kfree(info); - /* * Some devices don't reliably have _HIDs & _CIDs, so add * synthetic HIDs to make sure drivers can find them. @@ -1327,8 +1325,13 @@ static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops, struct acpi_device **child) { acpi_status status; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; void *device = NULL; + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); + printk(KERN_INFO PREFIX "Enumerating devices from [%s]\n", + (char *) buffer.pointer); + status = acpi_bus_check_add(handle, 0, ops, &device); if (ACPI_SUCCESS(status)) acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, diff --git a/trunk/drivers/block/DAC960.c b/trunk/drivers/block/DAC960.c index eb4fa1943944..6fa7b0fdbdfd 100644 --- a/trunk/drivers/block/DAC960.c +++ b/trunk/drivers/block/DAC960.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -6423,10 +6422,16 @@ static bool DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller, return true; } -static int dac960_proc_show(struct seq_file *m, void *v) + +/* + DAC960_ProcReadStatus implements reading /proc/rd/status. +*/ + +static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset, + int Count, int *EOF, void *Data) { unsigned char *StatusMessage = "OK\n"; - int ControllerNumber; + int ControllerNumber, BytesAvailable; for (ControllerNumber = 0; ControllerNumber < DAC960_ControllerCount; ControllerNumber++) @@ -6439,49 +6444,52 @@ static int dac960_proc_show(struct seq_file *m, void *v) break; } } - seq_puts(m, StatusMessage); - return 0; + BytesAvailable = strlen(StatusMessage) - Offset; + if (Count >= BytesAvailable) + { + Count = BytesAvailable; + *EOF = true; + } + if (Count <= 0) return 0; + *Start = Page; + memcpy(Page, &StatusMessage[Offset], Count); + return Count; } -static int dac960_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, dac960_proc_show, NULL); -} -static const struct file_operations dac960_proc_fops = { - .owner = THIS_MODULE, - .open = dac960_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +/* + DAC960_ProcReadInitialStatus implements reading /proc/rd/cN/initial_status. +*/ -static int dac960_initial_status_proc_show(struct seq_file *m, void *v) +static int DAC960_ProcReadInitialStatus(char *Page, char **Start, off_t Offset, + int Count, int *EOF, void *Data) { - DAC960_Controller_T *Controller = (DAC960_Controller_T *)m->private; - seq_printf(m, "%.*s", Controller->InitialStatusLength, Controller->CombinedStatusBuffer); - return 0; + DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data; + int BytesAvailable = Controller->InitialStatusLength - Offset; + if (Count >= BytesAvailable) + { + Count = BytesAvailable; + *EOF = true; + } + if (Count <= 0) return 0; + *Start = Page; + memcpy(Page, &Controller->CombinedStatusBuffer[Offset], Count); + return Count; } -static int dac960_initial_status_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, dac960_initial_status_proc_show, PDE(inode)->data); -} -static const struct file_operations dac960_initial_status_proc_fops = { - .owner = THIS_MODULE, - .open = dac960_initial_status_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +/* + DAC960_ProcReadCurrentStatus implements reading /proc/rd/cN/current_status. +*/ -static int dac960_current_status_proc_show(struct seq_file *m, void *v) +static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset, + int Count, int *EOF, void *Data) { - DAC960_Controller_T *Controller = (DAC960_Controller_T *) m->private; + DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data; unsigned char *StatusMessage = "No Rebuild or Consistency Check in Progress\n"; int ProgressMessageLength = strlen(StatusMessage); + int BytesAvailable; if (jiffies != Controller->LastCurrentStatusTime) { Controller->CurrentStatusLength = 0; @@ -6505,41 +6513,49 @@ static int dac960_current_status_proc_show(struct seq_file *m, void *v) } Controller->LastCurrentStatusTime = jiffies; } - seq_printf(m, "%.*s", Controller->CurrentStatusLength, Controller->CurrentStatusBuffer); - return 0; + BytesAvailable = Controller->CurrentStatusLength - Offset; + if (Count >= BytesAvailable) + { + Count = BytesAvailable; + *EOF = true; + } + if (Count <= 0) return 0; + *Start = Page; + memcpy(Page, &Controller->CurrentStatusBuffer[Offset], Count); + return Count; } -static int dac960_current_status_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, dac960_current_status_proc_show, PDE(inode)->data); -} -static const struct file_operations dac960_current_status_proc_fops = { - .owner = THIS_MODULE, - .open = dac960_current_status_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +/* + DAC960_ProcReadUserCommand implements reading /proc/rd/cN/user_command. +*/ -static int dac960_user_command_proc_show(struct seq_file *m, void *v) +static int DAC960_ProcReadUserCommand(char *Page, char **Start, off_t Offset, + int Count, int *EOF, void *Data) { - DAC960_Controller_T *Controller = (DAC960_Controller_T *)m->private; - - seq_printf(m, "%.*s", Controller->UserStatusLength, Controller->UserStatusBuffer); - return 0; + DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data; + int BytesAvailable = Controller->UserStatusLength - Offset; + if (Count >= BytesAvailable) + { + Count = BytesAvailable; + *EOF = true; + } + if (Count <= 0) return 0; + *Start = Page; + memcpy(Page, &Controller->UserStatusBuffer[Offset], Count); + return Count; } -static int dac960_user_command_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, dac960_user_command_proc_show, PDE(inode)->data); -} -static ssize_t dac960_user_command_proc_write(struct file *file, +/* + DAC960_ProcWriteUserCommand implements writing /proc/rd/cN/user_command. +*/ + +static int DAC960_ProcWriteUserCommand(struct file *file, const char __user *Buffer, - size_t Count, loff_t *pos) + unsigned long Count, void *Data) { - DAC960_Controller_T *Controller = (DAC960_Controller_T *) PDE(file->f_path.dentry->d_inode)->data; + DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data; unsigned char CommandBuffer[80]; int Length; if (Count > sizeof(CommandBuffer)-1) return -EINVAL; @@ -6556,14 +6572,6 @@ static ssize_t dac960_user_command_proc_write(struct file *file, ? Count : -EBUSY); } -static const struct file_operations dac960_user_command_proc_fops = { - .owner = THIS_MODULE, - .open = dac960_user_command_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = dac960_user_command_proc_write, -}; /* DAC960_CreateProcEntries creates the /proc/rd/... entries for the @@ -6578,17 +6586,23 @@ static void DAC960_CreateProcEntries(DAC960_Controller_T *Controller) if (DAC960_ProcDirectoryEntry == NULL) { DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL); - StatusProcEntry = proc_create("status", 0, + StatusProcEntry = create_proc_read_entry("status", 0, DAC960_ProcDirectoryEntry, - &dac960_proc_fops); + DAC960_ProcReadStatus, NULL); } sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber); ControllerProcEntry = proc_mkdir(Controller->ControllerName, DAC960_ProcDirectoryEntry); - proc_create_data("initial_status", 0, ControllerProcEntry, &dac960_initial_status_proc_fops, Controller); - proc_create_data("current_status", 0, ControllerProcEntry, &dac960_current_status_proc_fops, Controller); - UserCommandProcEntry = proc_create_data("user_command", S_IWUSR | S_IRUSR, ControllerProcEntry, &dac960_user_command_proc_fops, Controller); + create_proc_read_entry("initial_status", 0, ControllerProcEntry, + DAC960_ProcReadInitialStatus, Controller); + create_proc_read_entry("current_status", 0, ControllerProcEntry, + DAC960_ProcReadCurrentStatus, Controller); + UserCommandProcEntry = + create_proc_read_entry("user_command", S_IWUSR | S_IRUSR, + ControllerProcEntry, DAC960_ProcReadUserCommand, + Controller); + UserCommandProcEntry->write_proc = DAC960_ProcWriteUserCommand; Controller->ControllerProcEntry = ControllerProcEntry; } diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index fb5be2d95d52..1ece0b47b581 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -36,11 +36,9 @@ #include #include #include -#include #include #include #include -#include #include #include @@ -157,10 +155,6 @@ static struct board_type products[] = { static ctlr_info_t *hba[MAX_CTLR]; -static struct task_struct *cciss_scan_thread; -static DEFINE_MUTEX(scan_mutex); -static LIST_HEAD(scan_q); - static void do_cciss_request(struct request_queue *q); static irqreturn_t do_cciss_intr(int irq, void *dev_id); static int cciss_open(struct block_device *bdev, fmode_t mode); @@ -170,9 +164,9 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); static int cciss_revalidate(struct gendisk *disk); -static int rebuild_lun_table(ctlr_info_t *h, int first_time, int via_ioctl); +static int rebuild_lun_table(ctlr_info_t *h, int first_time); static int deregister_disk(ctlr_info_t *h, int drv_index, - int clear_all, int via_ioctl); + int clear_all); static void cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, unsigned int *block_size); @@ -195,13 +189,8 @@ static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c, static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c); static void fail_all_cmds(unsigned long ctlr); -static int add_to_scan_list(struct ctlr_info *h); static int scan_thread(void *data); static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c); -static void cciss_hba_release(struct device *dev); -static void cciss_device_release(struct device *dev); -static void cciss_free_gendisk(ctlr_info_t *h, int drv_index); -static void cciss_free_drive_info(ctlr_info_t *h, int drv_index); #ifdef CONFIG_PROC_FS static void cciss_procinit(int i); @@ -256,10 +245,7 @@ static inline void removeQ(CommandList_struct *c) #include "cciss_scsi.c" /* For SCSI tape support */ -static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", - "UNKNOWN" -}; -#define RAID_UNKNOWN (sizeof(raid_label) / sizeof(raid_label[0])-1) +#define RAID_UNKNOWN 6 #ifdef CONFIG_PROC_FS @@ -269,6 +255,9 @@ static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", #define ENG_GIG 1000000000 #define ENG_GIG_FACTOR (ENG_GIG/512) #define ENGAGE_SCSI "engage scsi" +static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", + "UNKNOWN" +}; static struct proc_dir_entry *proc_cciss; @@ -329,7 +318,7 @@ static int cciss_seq_show(struct seq_file *seq, void *v) ctlr_info_t *h = seq->private; unsigned ctlr = h->ctlr; loff_t *pos = v; - drive_info_struct *drv = h->drv[*pos]; + drive_info_struct *drv = &h->drv[*pos]; if (*pos > h->highest_lun) return 0; @@ -342,7 +331,7 @@ static int cciss_seq_show(struct seq_file *seq, void *v) vol_sz_frac *= 100; sector_div(vol_sz_frac, ENG_GIG_FACTOR); - if (drv->raid_level < 0 || drv->raid_level > RAID_UNKNOWN) + if (drv->raid_level > 5) drv->raid_level = RAID_UNKNOWN; seq_printf(seq, "cciss/c%dd%d:" "\t%4u.%02uGB\tRAID %s\n", @@ -465,19 +454,9 @@ static void __devinit cciss_procinit(int i) #define to_hba(n) container_of(n, struct ctlr_info, dev) #define to_drv(n) container_of(n, drive_info_struct, dev) -static ssize_t host_store_rescan(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct ctlr_info *h = to_hba(dev); - - add_to_scan_list(h); - wake_up_process(cciss_scan_thread); - wait_for_completion_interruptible(&h->scan_wait); - - return count; -} -DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan); +static struct device_type cciss_host_type = { + .name = "cciss_host", +}; static ssize_t dev_show_unique_id(struct device *dev, struct device_attribute *attr, @@ -581,101 +560,11 @@ static ssize_t dev_show_rev(struct device *dev, } DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL); -static ssize_t cciss_show_lunid(struct device *dev, - struct device_attribute *attr, char *buf) -{ - drive_info_struct *drv = to_drv(dev); - struct ctlr_info *h = to_hba(drv->dev.parent); - unsigned long flags; - unsigned char lunid[8]; - - spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); - if (h->busy_configuring) { - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); - return -EBUSY; - } - if (!drv->heads) { - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); - return -ENOTTY; - } - memcpy(lunid, drv->LunID, sizeof(lunid)); - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); - return snprintf(buf, 20, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", - lunid[0], lunid[1], lunid[2], lunid[3], - lunid[4], lunid[5], lunid[6], lunid[7]); -} -DEVICE_ATTR(lunid, S_IRUGO, cciss_show_lunid, NULL); - -static ssize_t cciss_show_raid_level(struct device *dev, - struct device_attribute *attr, char *buf) -{ - drive_info_struct *drv = to_drv(dev); - struct ctlr_info *h = to_hba(drv->dev.parent); - int raid; - unsigned long flags; - - spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); - if (h->busy_configuring) { - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); - return -EBUSY; - } - raid = drv->raid_level; - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); - if (raid < 0 || raid > RAID_UNKNOWN) - raid = RAID_UNKNOWN; - - return snprintf(buf, strlen(raid_label[raid]) + 7, "RAID %s\n", - raid_label[raid]); -} -DEVICE_ATTR(raid_level, S_IRUGO, cciss_show_raid_level, NULL); - -static ssize_t cciss_show_usage_count(struct device *dev, - struct device_attribute *attr, char *buf) -{ - drive_info_struct *drv = to_drv(dev); - struct ctlr_info *h = to_hba(drv->dev.parent); - unsigned long flags; - int count; - - spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); - if (h->busy_configuring) { - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); - return -EBUSY; - } - count = drv->usage_count; - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); - return snprintf(buf, 20, "%d\n", count); -} -DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL); - -static struct attribute *cciss_host_attrs[] = { - &dev_attr_rescan.attr, - NULL -}; - -static struct attribute_group cciss_host_attr_group = { - .attrs = cciss_host_attrs, -}; - -static const struct attribute_group *cciss_host_attr_groups[] = { - &cciss_host_attr_group, - NULL -}; - -static struct device_type cciss_host_type = { - .name = "cciss_host", - .groups = cciss_host_attr_groups, - .release = cciss_hba_release, -}; - static struct attribute *cciss_dev_attrs[] = { &dev_attr_unique_id.attr, &dev_attr_model.attr, &dev_attr_vendor.attr, &dev_attr_rev.attr, - &dev_attr_lunid.attr, - &dev_attr_raid_level.attr, - &dev_attr_usage_count.attr, NULL }; @@ -691,24 +580,12 @@ static const struct attribute_group *cciss_dev_attr_groups[] = { static struct device_type cciss_dev_type = { .name = "cciss_device", .groups = cciss_dev_attr_groups, - .release = cciss_device_release, }; static struct bus_type cciss_bus_type = { .name = "cciss", }; -/* - * cciss_hba_release is called when the reference count - * of h->dev goes to zero. - */ -static void cciss_hba_release(struct device *dev) -{ - /* - * nothing to do, but need this to avoid a warning - * about not having a release handler from lib/kref.c. - */ -} /* * Initialize sysfs entry for each controller. This sets up and registers @@ -732,16 +609,6 @@ static int cciss_create_hba_sysfs_entry(struct ctlr_info *h) static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h) { device_del(&h->dev); - put_device(&h->dev); /* final put. */ -} - -/* cciss_device_release is called when the reference count - * of h->drv[x]dev goes to zero. - */ -static void cciss_device_release(struct device *dev) -{ - drive_info_struct *drv = to_drv(dev); - kfree(drv); } /* @@ -750,39 +617,24 @@ static void cciss_device_release(struct device *dev) * /sys/bus/pci/devices/drv[drv_index]->device_initialized) - return 0; - - dev = &h->drv[drv_index]->dev; - device_initialize(dev); - dev->type = &cciss_dev_type; - dev->bus = &cciss_bus_type; - dev_set_name(dev, "c%dd%d", h->ctlr, drv_index); - dev->parent = &h->dev; - h->drv[drv_index]->device_initialized = 1; - return device_add(dev); + device_initialize(&drv->dev); + drv->dev.type = &cciss_dev_type; + drv->dev.bus = &cciss_bus_type; + dev_set_name(&drv->dev, "c%dd%d", h->ctlr, drv_index); + drv->dev.parent = &h->dev; + return device_add(&drv->dev); } /* * Remove sysfs entries for a logical drive. */ -static void cciss_destroy_ld_sysfs_entry(struct ctlr_info *h, int drv_index, - int ctlr_exiting) +static void cciss_destroy_ld_sysfs_entry(drive_info_struct *drv) { - struct device *dev = &h->drv[drv_index]->dev; - - /* special case for c*d0, we only destroy it on controller exit */ - if (drv_index == 0 && !ctlr_exiting) - return; - - device_del(dev); - put_device(dev); /* the "final" put. */ - h->drv[drv_index] = NULL; + device_del(&drv->dev); } /* @@ -899,7 +751,7 @@ static int cciss_open(struct block_device *bdev, fmode_t mode) printk(KERN_DEBUG "cciss_open %s\n", bdev->bd_disk->disk_name); #endif /* CCISS_DEBUG */ - if (drv->busy_configuring) + if (host->busy_initializing || drv->busy_configuring) return -EBUSY; /* * Root is allowed to open raw volume zero even if it's not configured @@ -915,8 +767,7 @@ static int cciss_open(struct block_device *bdev, fmode_t mode) if (MINOR(bdev->bd_dev) & 0x0f) { return -ENXIO; /* if it is, make sure we have a LUN ID */ - } else if (memcmp(drv->LunID, CTLR_LUNID, - sizeof(drv->LunID))) { + } else if (drv->LunID == 0) { return -ENXIO; } } @@ -1281,13 +1132,12 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, case CCISS_DEREGDISK: case CCISS_REGNEWD: case CCISS_REVALIDVOLS: - return rebuild_lun_table(host, 0, 1); + return rebuild_lun_table(host, 0); case CCISS_GETLUNINFO:{ LogvolInfo_struct luninfo; - memcpy(&luninfo.LunID, drv->LunID, - sizeof(luninfo.LunID)); + luninfo.LunID = drv->LunID; luninfo.num_opens = drv->usage_count; luninfo.num_parts = 0; if (copy_to_user(argp, &luninfo, @@ -1625,10 +1475,7 @@ static void cciss_check_queues(ctlr_info_t *h) /* make sure the disk has been added and the drive is real * because this can be called from the middle of init_one. */ - if (!h->drv[curr_queue]) - continue; - if (!(h->drv[curr_queue]->queue) || - !(h->drv[curr_queue]->heads)) + if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads)) continue; blk_start_queue(h->gendisk[curr_queue]->queue); @@ -1685,11 +1532,13 @@ static void cciss_softirq_done(struct request *rq) spin_unlock_irqrestore(&h->lock, flags); } -static inline void log_unit_to_scsi3addr(ctlr_info_t *h, - unsigned char scsi3addr[], uint32_t log_unit) +static void log_unit_to_scsi3addr(ctlr_info_t *h, unsigned char scsi3addr[], + uint32_t log_unit) { - memcpy(scsi3addr, h->drv[log_unit]->LunID, - sizeof(h->drv[log_unit]->LunID)); + log_unit = h->drv[log_unit].LunID & 0x03fff; + memset(&scsi3addr[4], 0, 4); + memcpy(&scsi3addr[0], &log_unit, 4); + scsi3addr[3] |= 0x40; } /* This function gets the SCSI vendor, model, and revision of a logical drive @@ -1766,23 +1615,16 @@ static void cciss_get_serial_no(int ctlr, int logvol, int withirq, return; } -/* - * cciss_add_disk sets up the block device queue for a logical drive - */ -static int cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, +static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, int drv_index) { disk->queue = blk_init_queue(do_cciss_request, &h->lock); - if (!disk->queue) - goto init_queue_failure; sprintf(disk->disk_name, "cciss/c%dd%d", h->ctlr, drv_index); disk->major = h->major; disk->first_minor = drv_index << NWD_SHIFT; disk->fops = &cciss_fops; - if (cciss_create_ld_sysfs_entry(h, drv_index)) - goto cleanup_queue; - disk->private_data = h->drv[drv_index]; - disk->driverfs_dev = &h->drv[drv_index]->dev; + disk->private_data = &h->drv[drv_index]; + disk->driverfs_dev = &h->drv[drv_index].dev; /* Set up queue information */ blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); @@ -1800,21 +1642,14 @@ static int cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, disk->queue->queuedata = h; blk_queue_logical_block_size(disk->queue, - h->drv[drv_index]->block_size); + h->drv[drv_index].block_size); /* Make sure all queue data is written out before */ - /* setting h->drv[drv_index]->queue, as setting this */ + /* setting h->drv[drv_index].queue, as setting this */ /* allows the interrupt handler to start the queue */ wmb(); - h->drv[drv_index]->queue = disk->queue; + h->drv[drv_index].queue = disk->queue; add_disk(disk); - return 0; - -cleanup_queue: - blk_cleanup_queue(disk->queue); - disk->queue = NULL; -init_queue_failure: - return -1; } /* This function will check the usage_count of the drive to be updated/added. @@ -1827,8 +1662,7 @@ static int cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, * is also the controller node. Any changes to disk 0 will show up on * the next reboot. */ -static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, - int via_ioctl) +static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) { ctlr_info_t *h = hba[ctlr]; struct gendisk *disk; @@ -1838,13 +1672,21 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, unsigned long flags = 0; int ret = 0; drive_info_struct *drvinfo; + int was_only_controller_node; /* Get information about the disk and modify the driver structure */ inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); - drvinfo = kzalloc(sizeof(*drvinfo), GFP_KERNEL); + drvinfo = kmalloc(sizeof(*drvinfo), GFP_KERNEL); if (inq_buff == NULL || drvinfo == NULL) goto mem_msg; + /* See if we're trying to update the "controller node" + * this will happen the when the first logical drive gets + * created by ACU. + */ + was_only_controller_node = (drv_index == 0 && + h->drv[0].raid_level == -1); + /* testing to see if 16-byte CDBs are already being used */ if (h->cciss_read == CCISS_READ_16) { cciss_read_capacity_16(h->ctlr, drv_index, 1, @@ -1877,19 +1719,16 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, drvinfo->model, drvinfo->rev); cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no, sizeof(drvinfo->serial_no)); - /* Save the lunid in case we deregister the disk, below. */ - memcpy(drvinfo->LunID, h->drv[drv_index]->LunID, - sizeof(drvinfo->LunID)); /* Is it the same disk we already know, and nothing's changed? */ - if (h->drv[drv_index]->raid_level != -1 && + if (h->drv[drv_index].raid_level != -1 && ((memcmp(drvinfo->serial_no, - h->drv[drv_index]->serial_no, 16) == 0) && - drvinfo->block_size == h->drv[drv_index]->block_size && - drvinfo->nr_blocks == h->drv[drv_index]->nr_blocks && - drvinfo->heads == h->drv[drv_index]->heads && - drvinfo->sectors == h->drv[drv_index]->sectors && - drvinfo->cylinders == h->drv[drv_index]->cylinders)) + h->drv[drv_index].serial_no, 16) == 0) && + drvinfo->block_size == h->drv[drv_index].block_size && + drvinfo->nr_blocks == h->drv[drv_index].nr_blocks && + drvinfo->heads == h->drv[drv_index].heads && + drvinfo->sectors == h->drv[drv_index].sectors && + drvinfo->cylinders == h->drv[drv_index].cylinders)) /* The disk is unchanged, nothing to update */ goto freeret; @@ -1899,17 +1738,18 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, * If the disk already exists then deregister it before proceeding * (unless it's the first disk (for the controller node). */ - if (h->drv[drv_index]->raid_level != -1 && drv_index != 0) { + if (h->drv[drv_index].raid_level != -1 && drv_index != 0) { printk(KERN_WARNING "disk %d has changed.\n", drv_index); spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); - h->drv[drv_index]->busy_configuring = 1; + h->drv[drv_index].busy_configuring = 1; spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); - /* deregister_disk sets h->drv[drv_index]->queue = NULL + /* deregister_disk sets h->drv[drv_index].queue = NULL * which keeps the interrupt handler from starting * the queue. */ - ret = deregister_disk(h, drv_index, 0, via_ioctl); + ret = deregister_disk(h, drv_index, 0); + h->drv[drv_index].busy_configuring = 0; } /* If the disk is in use return */ @@ -1917,31 +1757,22 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, goto freeret; /* Save the new information from cciss_geometry_inquiry - * and serial number inquiry. If the disk was deregistered - * above, then h->drv[drv_index] will be NULL. + * and serial number inquiry. */ - if (h->drv[drv_index] == NULL) { - drvinfo->device_initialized = 0; - h->drv[drv_index] = drvinfo; - drvinfo = NULL; /* so it won't be freed below. */ - } else { - /* special case for cxd0 */ - h->drv[drv_index]->block_size = drvinfo->block_size; - h->drv[drv_index]->nr_blocks = drvinfo->nr_blocks; - h->drv[drv_index]->heads = drvinfo->heads; - h->drv[drv_index]->sectors = drvinfo->sectors; - h->drv[drv_index]->cylinders = drvinfo->cylinders; - h->drv[drv_index]->raid_level = drvinfo->raid_level; - memcpy(h->drv[drv_index]->serial_no, drvinfo->serial_no, 16); - memcpy(h->drv[drv_index]->vendor, drvinfo->vendor, - VENDOR_LEN + 1); - memcpy(h->drv[drv_index]->model, drvinfo->model, MODEL_LEN + 1); - memcpy(h->drv[drv_index]->rev, drvinfo->rev, REV_LEN + 1); - } + h->drv[drv_index].block_size = drvinfo->block_size; + h->drv[drv_index].nr_blocks = drvinfo->nr_blocks; + h->drv[drv_index].heads = drvinfo->heads; + h->drv[drv_index].sectors = drvinfo->sectors; + h->drv[drv_index].cylinders = drvinfo->cylinders; + h->drv[drv_index].raid_level = drvinfo->raid_level; + memcpy(h->drv[drv_index].serial_no, drvinfo->serial_no, 16); + memcpy(h->drv[drv_index].vendor, drvinfo->vendor, VENDOR_LEN + 1); + memcpy(h->drv[drv_index].model, drvinfo->model, MODEL_LEN + 1); + memcpy(h->drv[drv_index].rev, drvinfo->rev, REV_LEN + 1); ++h->num_luns; disk = h->gendisk[drv_index]; - set_capacity(disk, h->drv[drv_index]->nr_blocks); + set_capacity(disk, h->drv[drv_index].nr_blocks); /* If it's not disk 0 (drv_index != 0) * or if it was disk 0, but there was previously @@ -1949,15 +1780,8 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, * (raid_leve == -1) then we want to update the * logical drive's information. */ - if (drv_index || first_time) { - if (cciss_add_disk(h, disk, drv_index) != 0) { - cciss_free_gendisk(h, drv_index); - cciss_free_drive_info(h, drv_index); - printk(KERN_WARNING "cciss:%d could not update " - "disk %d\n", h->ctlr, drv_index); - --h->num_luns; - } - } + if (drv_index || first_time) + cciss_add_disk(h, disk, drv_index); freeret: kfree(inq_buff); @@ -1969,70 +1793,28 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, } /* This function will find the first index of the controllers drive array - * that has a null drv pointer and allocate the drive info struct and - * will return that index This is where new drives will be added. - * If the index to be returned is greater than the highest_lun index for - * the controller then highest_lun is set * to this new index. - * If there are no available indexes or if tha allocation fails, then -1 - * is returned. * "controller_node" is used to know if this is a real - * logical drive, or just the controller node, which determines if this - * counts towards highest_lun. + * that has a -1 for the raid_level and will return that index. This is + * where new drives will be added. If the index to be returned is greater + * than the highest_lun index for the controller then highest_lun is set + * to this new index. If there are no available indexes then -1 is returned. + * "controller_node" is used to know if this is a real logical drive, or just + * the controller node, which determines if this counts towards highest_lun. */ -static int cciss_alloc_drive_info(ctlr_info_t *h, int controller_node) +static int cciss_find_free_drive_index(int ctlr, int controller_node) { int i; - drive_info_struct *drv; - /* Search for an empty slot for our drive info */ for (i = 0; i < CISS_MAX_LUN; i++) { - - /* if not cxd0 case, and it's occupied, skip it. */ - if (h->drv[i] && i != 0) - continue; - /* - * If it's cxd0 case, and drv is alloc'ed already, and a - * disk is configured there, skip it. - */ - if (i == 0 && h->drv[i] && h->drv[i]->raid_level != -1) - continue; - - /* - * We've found an empty slot. Update highest_lun - * provided this isn't just the fake cxd0 controller node. - */ - if (i > h->highest_lun && !controller_node) - h->highest_lun = i; - - /* If adding a real disk at cxd0, and it's already alloc'ed */ - if (i == 0 && h->drv[i] != NULL) + if (hba[ctlr]->drv[i].raid_level == -1) { + if (i > hba[ctlr]->highest_lun) + if (!controller_node) + hba[ctlr]->highest_lun = i; return i; - - /* - * Found an empty slot, not already alloc'ed. Allocate it. - * Mark it with raid_level == -1, so we know it's new later on. - */ - drv = kzalloc(sizeof(*drv), GFP_KERNEL); - if (!drv) - return -1; - drv->raid_level = -1; /* so we know it's new */ - h->drv[i] = drv; - return i; + } } return -1; } -static void cciss_free_drive_info(ctlr_info_t *h, int drv_index) -{ - kfree(h->drv[drv_index]); - h->drv[drv_index] = NULL; -} - -static void cciss_free_gendisk(ctlr_info_t *h, int drv_index) -{ - put_disk(h->gendisk[drv_index]); - h->gendisk[drv_index] = NULL; -} - /* cciss_add_gendisk finds a free hba[]->drv structure * and allocates a gendisk if needed, and sets the lunid * in the drvinfo structure. It returns the index into @@ -2042,15 +1824,13 @@ static void cciss_free_gendisk(ctlr_info_t *h, int drv_index) * a means to talk to the controller in case no logical * drives have yet been configured. */ -static int cciss_add_gendisk(ctlr_info_t *h, unsigned char lunid[], - int controller_node) +static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) { int drv_index; - drv_index = cciss_alloc_drive_info(h, controller_node); + drv_index = cciss_find_free_drive_index(h->ctlr, controller_node); if (drv_index == -1) return -1; - /*Check if the gendisk needs to be allocated */ if (!h->gendisk[drv_index]) { h->gendisk[drv_index] = @@ -2059,24 +1839,23 @@ static int cciss_add_gendisk(ctlr_info_t *h, unsigned char lunid[], printk(KERN_ERR "cciss%d: could not " "allocate a new disk %d\n", h->ctlr, drv_index); - goto err_free_drive_info; + return -1; } } - memcpy(h->drv[drv_index]->LunID, lunid, - sizeof(h->drv[drv_index]->LunID)); - if (cciss_create_ld_sysfs_entry(h, drv_index)) + h->drv[drv_index].LunID = lunid; + if (cciss_create_ld_sysfs_entry(h, &h->drv[drv_index], drv_index)) goto err_free_disk; + /* Don't need to mark this busy because nobody */ /* else knows about this disk yet to contend */ /* for access to it. */ - h->drv[drv_index]->busy_configuring = 0; + h->drv[drv_index].busy_configuring = 0; wmb(); return drv_index; err_free_disk: - cciss_free_gendisk(h, drv_index); -err_free_drive_info: - cciss_free_drive_info(h, drv_index); + put_disk(h->gendisk[drv_index]); + h->gendisk[drv_index] = NULL; return -1; } @@ -2093,25 +1872,21 @@ static void cciss_add_controller_node(ctlr_info_t *h) if (h->gendisk[0] != NULL) /* already did this? Then bail. */ return; - drv_index = cciss_add_gendisk(h, CTLR_LUNID, 1); - if (drv_index == -1) - goto error; - h->drv[drv_index]->block_size = 512; - h->drv[drv_index]->nr_blocks = 0; - h->drv[drv_index]->heads = 0; - h->drv[drv_index]->sectors = 0; - h->drv[drv_index]->cylinders = 0; - h->drv[drv_index]->raid_level = -1; - memset(h->drv[drv_index]->serial_no, 0, 16); - disk = h->gendisk[drv_index]; - if (cciss_add_disk(h, disk, drv_index) == 0) + drv_index = cciss_add_gendisk(h, 0, 1); + if (drv_index == -1) { + printk(KERN_WARNING "cciss%d: could not " + "add disk 0.\n", h->ctlr); return; - cciss_free_gendisk(h, drv_index); - cciss_free_drive_info(h, drv_index); -error: - printk(KERN_WARNING "cciss%d: could not " - "add disk 0.\n", h->ctlr); - return; + } + h->drv[drv_index].block_size = 512; + h->drv[drv_index].nr_blocks = 0; + h->drv[drv_index].heads = 0; + h->drv[drv_index].sectors = 0; + h->drv[drv_index].cylinders = 0; + h->drv[drv_index].raid_level = -1; + memset(h->drv[drv_index].serial_no, 0, 16); + disk = h->gendisk[drv_index]; + cciss_add_disk(h, disk, drv_index); } /* This function will add and remove logical drives from the Logical @@ -2122,8 +1897,7 @@ static void cciss_add_controller_node(ctlr_info_t *h) * INPUT * h = The controller to perform the operations on */ -static int rebuild_lun_table(ctlr_info_t *h, int first_time, - int via_ioctl) +static int rebuild_lun_table(ctlr_info_t *h, int first_time) { int ctlr = h->ctlr; int num_luns; @@ -2133,7 +1907,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, int i; int drv_found; int drv_index = 0; - unsigned char lunid[8] = CTLR_LUNID; + __u32 lunid = 0; unsigned long flags; if (!capable(CAP_SYS_RAWIO)) @@ -2186,13 +1960,13 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, drv_found = 0; /* skip holes in the array from already deleted drives */ - if (h->drv[i] == NULL) + if (h->drv[i].raid_level == -1) continue; for (j = 0; j < num_luns; j++) { - memcpy(lunid, &ld_buff->LUN[j][0], sizeof(lunid)); - if (memcmp(h->drv[i]->LunID, lunid, - sizeof(lunid)) == 0) { + memcpy(&lunid, &ld_buff->LUN[j][0], 4); + lunid = le32_to_cpu(lunid); + if (h->drv[i].LunID == lunid) { drv_found = 1; break; } @@ -2200,11 +1974,11 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, if (!drv_found) { /* Deregister it from the OS, it's gone. */ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); - h->drv[i]->busy_configuring = 1; + h->drv[i].busy_configuring = 1; spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); - return_code = deregister_disk(h, i, 1, via_ioctl); - if (h->drv[i] != NULL) - h->drv[i]->busy_configuring = 0; + return_code = deregister_disk(h, i, 1); + cciss_destroy_ld_sysfs_entry(&h->drv[i]); + h->drv[i].busy_configuring = 0; } } @@ -2218,16 +1992,17 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, drv_found = 0; - memcpy(lunid, &ld_buff->LUN[i][0], sizeof(lunid)); + memcpy(&lunid, &ld_buff->LUN[i][0], 4); + lunid = le32_to_cpu(lunid); + /* Find if the LUN is already in the drive array * of the driver. If so then update its info * if not in use. If it does not exist then find * the first free index and add it. */ for (j = 0; j <= h->highest_lun; j++) { - if (h->drv[j] != NULL && - memcmp(h->drv[j]->LunID, lunid, - sizeof(h->drv[j]->LunID)) == 0) { + if (h->drv[j].raid_level != -1 && + h->drv[j].LunID == lunid) { drv_index = j; drv_found = 1; break; @@ -2240,8 +2015,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, if (drv_index == -1) goto freeret; } - cciss_update_drive_info(ctlr, drv_index, first_time, - via_ioctl); + cciss_update_drive_info(ctlr, drv_index, first_time); } /* end for */ freeret: @@ -2258,25 +2032,6 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, goto freeret; } -static void cciss_clear_drive_info(drive_info_struct *drive_info) -{ - /* zero out the disk size info */ - drive_info->nr_blocks = 0; - drive_info->block_size = 0; - drive_info->heads = 0; - drive_info->sectors = 0; - drive_info->cylinders = 0; - drive_info->raid_level = -1; - memset(drive_info->serial_no, 0, sizeof(drive_info->serial_no)); - memset(drive_info->model, 0, sizeof(drive_info->model)); - memset(drive_info->rev, 0, sizeof(drive_info->rev)); - memset(drive_info->vendor, 0, sizeof(drive_info->vendor)); - /* - * don't clear the LUNID though, we need to remember which - * one this one is. - */ -} - /* This function will deregister the disk and it's queue from the * kernel. It must be called with the controller lock held and the * drv structures busy_configuring flag set. It's parameters are: @@ -2291,48 +2046,43 @@ static void cciss_clear_drive_info(drive_info_struct *drive_info) * the disk in preparation for re-adding it. In this case * the highest_lun should be left unchanged and the LunID * should not be cleared. - * via_ioctl - * This indicates whether we've reached this path via ioctl. - * This affects the maximum usage count allowed for c0d0 to be messed with. - * If this path is reached via ioctl(), then the max_usage_count will - * be 1, as the process calling ioctl() has got to have the device open. - * If we get here via sysfs, then the max usage count will be zero. */ static int deregister_disk(ctlr_info_t *h, int drv_index, - int clear_all, int via_ioctl) + int clear_all) { int i; struct gendisk *disk; drive_info_struct *drv; - int recalculate_highest_lun; if (!capable(CAP_SYS_RAWIO)) return -EPERM; - drv = h->drv[drv_index]; + drv = &h->drv[drv_index]; disk = h->gendisk[drv_index]; /* make sure logical volume is NOT is use */ if (clear_all || (h->gendisk[0] == disk)) { - if (drv->usage_count > via_ioctl) + if (drv->usage_count > 1) return -EBUSY; } else if (drv->usage_count > 0) return -EBUSY; - recalculate_highest_lun = (drv == h->drv[h->highest_lun]); - /* invalidate the devices and deregister the disk. If it is disk * zero do not deregister it but just zero out it's values. This * allows us to delete disk zero but keep the controller registered. */ if (h->gendisk[0] != disk) { struct request_queue *q = disk->queue; - if (disk->flags & GENHD_FL_UP) { - cciss_destroy_ld_sysfs_entry(h, drv_index, 0); + if (disk->flags & GENHD_FL_UP) del_gendisk(disk); - } - if (q) + if (q) { blk_cleanup_queue(q); + /* Set drv->queue to NULL so that we do not try + * to call blk_start_queue on this queue in the + * interrupt handler + */ + drv->queue = NULL; + } /* If clear_all is set then we are deleting the logical * drive, not just refreshing its info. For drives * other than disk 0 we will call put_disk. We do not @@ -2355,20 +2105,34 @@ static int deregister_disk(ctlr_info_t *h, int drv_index, } } else { set_capacity(disk, 0); - cciss_clear_drive_info(drv); } --h->num_luns; - - /* if it was the last disk, find the new hightest lun */ - if (clear_all && recalculate_highest_lun) { - int i, newhighest = -1; - for (i = 0; i <= h->highest_lun; i++) { - /* if the disk has size > 0, it is available */ - if (h->drv[i] && h->drv[i]->heads) - newhighest = i; + /* zero out the disk size info */ + drv->nr_blocks = 0; + drv->block_size = 0; + drv->heads = 0; + drv->sectors = 0; + drv->cylinders = 0; + drv->raid_level = -1; /* This can be used as a flag variable to + * indicate that this element of the drive + * array is free. + */ + + if (clear_all) { + /* check to see if it was the last disk */ + if (drv == h->drv + h->highest_lun) { + /* if so, find the new hightest lun */ + int i, newhighest = -1; + for (i = 0; i <= h->highest_lun; i++) { + /* if the disk has size > 0, it is available */ + if (h->drv[i].heads) + newhighest = i; + } + h->highest_lun = newhighest; } - h->highest_lun = newhighest; + + drv->LunID = 0; } return 0; } @@ -2715,6 +2479,8 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, } else { /* Get geometry failed */ printk(KERN_WARNING "cciss: reading geometry failed\n"); } + printk(KERN_INFO " heads=%d, sectors=%d, cylinders=%d\n\n", + drv->heads, drv->sectors, drv->cylinders); } static void @@ -2748,6 +2514,9 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, *total_size = 0; *block_size = BLOCK_SIZE; } + if (*total_size != 0) + printk(KERN_INFO " blocks= %llu block_size= %d\n", + (unsigned long long)*total_size+1, *block_size); kfree(buf); } @@ -2799,8 +2568,7 @@ static int cciss_revalidate(struct gendisk *disk) InquiryData_struct *inq_buff = NULL; for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { - if (memcmp(h->drv[logvol]->LunID, drv->LunID, - sizeof(drv->LunID)) == 0) { + if (h->drv[logvol].LunID == drv->LunID) { FOUND = 1; break; } @@ -3285,7 +3053,8 @@ static void do_cciss_request(struct request_queue *q) /* The first 2 bits are reserved for controller error reporting. */ c->Header.Tag.lower = (c->cmdindex << 3); c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */ - memcpy(&c->Header.LUN, drv->LunID, sizeof(drv->LunID)); + c->Header.LUN.LogDev.VolId = drv->LunID; + c->Header.LUN.LogDev.Mode = 1; c->Request.CDBLen = 10; // 12 byte commands not in FW yet; c->Request.Type.Type = TYPE_CMD; // It is a command. c->Request.Type.Attribute = ATTR_SIMPLE; @@ -3463,121 +3232,20 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id) return IRQ_HANDLED; } -/** - * add_to_scan_list() - add controller to rescan queue - * @h: Pointer to the controller. - * - * Adds the controller to the rescan queue if not already on the queue. - * - * returns 1 if added to the queue, 0 if skipped (could be on the - * queue already, or the controller could be initializing or shutting - * down). - **/ -static int add_to_scan_list(struct ctlr_info *h) -{ - struct ctlr_info *test_h; - int found = 0; - int ret = 0; - - if (h->busy_initializing) - return 0; - - if (!mutex_trylock(&h->busy_shutting_down)) - return 0; - - mutex_lock(&scan_mutex); - list_for_each_entry(test_h, &scan_q, scan_list) { - if (test_h == h) { - found = 1; - break; - } - } - if (!found && !h->busy_scanning) { - INIT_COMPLETION(h->scan_wait); - list_add_tail(&h->scan_list, &scan_q); - ret = 1; - } - mutex_unlock(&scan_mutex); - mutex_unlock(&h->busy_shutting_down); - - return ret; -} - -/** - * remove_from_scan_list() - remove controller from rescan queue - * @h: Pointer to the controller. - * - * Removes the controller from the rescan queue if present. Blocks if - * the controller is currently conducting a rescan. - **/ -static void remove_from_scan_list(struct ctlr_info *h) -{ - struct ctlr_info *test_h, *tmp_h; - int scanning = 0; - - mutex_lock(&scan_mutex); - list_for_each_entry_safe(test_h, tmp_h, &scan_q, scan_list) { - if (test_h == h) { - list_del(&h->scan_list); - complete_all(&h->scan_wait); - mutex_unlock(&scan_mutex); - return; - } - } - if (&h->busy_scanning) - scanning = 0; - mutex_unlock(&scan_mutex); - - if (scanning) - wait_for_completion(&h->scan_wait); -} - -/** - * scan_thread() - kernel thread used to rescan controllers - * @data: Ignored. - * - * A kernel thread used scan for drive topology changes on - * controllers. The thread processes only one controller at a time - * using a queue. Controllers are added to the queue using - * add_to_scan_list() and removed from the queue either after done - * processing or using remove_from_scan_list(). - * - * returns 0. - **/ static int scan_thread(void *data) { - struct ctlr_info *h; + ctlr_info_t *h = data; + int rc; + DECLARE_COMPLETION_ONSTACK(wait); + h->rescan_wait = &wait; - while (1) { - set_current_state(TASK_INTERRUPTIBLE); - schedule(); + for (;;) { + rc = wait_for_completion_interruptible(&wait); if (kthread_should_stop()) break; - - while (1) { - mutex_lock(&scan_mutex); - if (list_empty(&scan_q)) { - mutex_unlock(&scan_mutex); - break; - } - - h = list_entry(scan_q.next, - struct ctlr_info, - scan_list); - list_del(&h->scan_list); - h->busy_scanning = 1; - mutex_unlock(&scan_mutex); - - if (h) { - rebuild_lun_table(h, 0, 0); - complete_all(&h->scan_wait); - mutex_lock(&scan_mutex); - h->busy_scanning = 0; - mutex_unlock(&scan_mutex); - } - } + if (!rc) + rebuild_lun_table(h, 0); } - return 0; } @@ -3600,8 +3268,8 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c) case REPORT_LUNS_CHANGED: printk(KERN_WARNING "cciss%d: report LUN data " "changed\n", h->ctlr); - add_to_scan_list(h); - wake_up_process(cciss_scan_thread); + if (h->rescan_wait) + complete(h->rescan_wait); return 1; break; case POWER_OR_RESET: @@ -3821,7 +3489,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) if (scratchpad == CCISS_FIRMWARE_READY) break; set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(msecs_to_jiffies(100)); /* wait 100ms */ + schedule_timeout(HZ / 10); /* wait 100ms */ } if (scratchpad != CCISS_FIRMWARE_READY) { printk(KERN_WARNING "cciss: Board not ready. Timed out.\n"); @@ -3947,7 +3615,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) break; /* delay and try again */ set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(msecs_to_jiffies(1)); + schedule_timeout(10); } #ifdef CCISS_DEBUG @@ -4001,16 +3669,15 @@ static int alloc_cciss_hba(void) return -1; } -static void free_hba(int n) +static void free_hba(int i) { - ctlr_info_t *h = hba[n]; - int i; + ctlr_info_t *p = hba[i]; + int n; - hba[n] = NULL; - for (i = 0; i < h->highest_lun + 1; i++) - if (h->gendisk[i] != NULL) - put_disk(h->gendisk[i]); - kfree(h); + hba[i] = NULL; + for (n = 0; n < CISS_MAX_LUN; n++) + put_disk(p->gendisk[n]); + kfree(p); } /* Send a message CDB to the firmware. */ @@ -4251,7 +3918,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, hba[i]->busy_initializing = 1; INIT_HLIST_HEAD(&hba[i]->cmpQ); INIT_HLIST_HEAD(&hba[i]->reqQ); - mutex_init(&hba[i]->busy_shutting_down); if (cciss_pci_init(hba[i], pdev) != 0) goto clean0; @@ -4260,8 +3926,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, hba[i]->ctlr = i; hba[i]->pdev = pdev; - init_completion(&hba[i]->scan_wait); - if (cciss_create_hba_sysfs_entry(hba[i])) goto clean0; @@ -4337,7 +4001,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, hba[i]->num_luns = 0; hba[i]->highest_lun = -1; for (j = 0; j < CISS_MAX_LUN; j++) { - hba[i]->drv[j] = NULL; + hba[i]->drv[j].raid_level = -1; + hba[i]->drv[j].queue = NULL; hba[i]->gendisk[j] = NULL; } @@ -4370,8 +4035,14 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, hba[i]->cciss_max_sectors = 2048; - rebuild_lun_table(hba[i], 1, 0); hba[i]->busy_initializing = 0; + + rebuild_lun_table(hba[i], 1); + hba[i]->cciss_scan_thread = kthread_run(scan_thread, hba[i], + "cciss_scan%02d", i); + if (IS_ERR(hba[i]->cciss_scan_thread)) + return PTR_ERR(hba[i]->cciss_scan_thread); + return 1; clean4: @@ -4392,7 +4063,12 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, cciss_destroy_hba_sysfs_entry(hba[i]); clean0: hba[i]->busy_initializing = 0; - + /* cleanup any queues that may have been initialized */ + for (j=0; j <= hba[i]->highest_lun; j++){ + drive_info_struct *drv = &(hba[i]->drv[j]); + if (drv->queue) + blk_cleanup_queue(drv->queue); + } /* * Deliberately omit pci_disable_device(): it does something nasty to * Smart Array controllers that pci_enable_device does not undo @@ -4449,9 +4125,8 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) return; } - mutex_lock(&hba[i]->busy_shutting_down); + kthread_stop(hba[i]->cciss_scan_thread); - remove_from_scan_list(hba[i]); remove_proc_entry(hba[i]->devname, proc_cciss); unregister_blkdev(hba[i]->major, hba[i]->devname); @@ -4461,10 +4136,8 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) if (disk) { struct request_queue *q = disk->queue; - if (disk->flags & GENHD_FL_UP) { - cciss_destroy_ld_sysfs_entry(hba[i], j, 1); + if (disk->flags & GENHD_FL_UP) del_gendisk(disk); - } if (q) blk_cleanup_queue(q); } @@ -4497,7 +4170,6 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); cciss_destroy_hba_sysfs_entry(hba[i]); - mutex_unlock(&hba[i]->busy_shutting_down); free_hba(i); } @@ -4530,25 +4202,15 @@ static int __init cciss_init(void) if (err) return err; - /* Start the scan thread */ - cciss_scan_thread = kthread_run(scan_thread, NULL, "cciss_scan"); - if (IS_ERR(cciss_scan_thread)) { - err = PTR_ERR(cciss_scan_thread); - goto err_bus_unregister; - } - /* Register for our PCI devices */ err = pci_register_driver(&cciss_pci_driver); if (err) - goto err_thread_stop; + goto err_bus_register; - return err; + return 0; -err_thread_stop: - kthread_stop(cciss_scan_thread); -err_bus_unregister: +err_bus_register: bus_unregister(&cciss_bus_type); - return err; } @@ -4565,7 +4227,6 @@ static void __exit cciss_cleanup(void) cciss_remove_one(hba[i]->pdev); } } - kthread_stop(cciss_scan_thread); remove_proc_entry("driver/cciss", NULL); bus_unregister(&cciss_bus_type); } diff --git a/trunk/drivers/block/cciss.h b/trunk/drivers/block/cciss.h index 31524cf42c77..06a5db25b298 100644 --- a/trunk/drivers/block/cciss.h +++ b/trunk/drivers/block/cciss.h @@ -2,7 +2,6 @@ #define CCISS_H #include -#include #include "cciss_cmd.h" @@ -30,7 +29,7 @@ struct access_method { }; typedef struct _drive_info_struct { - unsigned char LunID[8]; + __u32 LunID; int usage_count; struct request_queue *queue; sector_t nr_blocks; @@ -52,7 +51,6 @@ typedef struct _drive_info_struct char vendor[VENDOR_LEN + 1]; /* SCSI vendor string */ char model[MODEL_LEN + 1]; /* SCSI model string */ char rev[REV_LEN + 1]; /* SCSI revision string */ - char device_initialized; /* indicates whether dev is initialized */ } drive_info_struct; struct ctlr_info @@ -88,7 +86,7 @@ struct ctlr_info BYTE cciss_read_capacity; // information about each logical volume - drive_info_struct *drv[CISS_MAX_LUN]; + drive_info_struct drv[CISS_MAX_LUN]; struct access_method access; @@ -110,8 +108,6 @@ struct ctlr_info int nr_frees; int busy_configuring; int busy_initializing; - int busy_scanning; - struct mutex busy_shutting_down; /* This element holds the zero based queue number of the last * queue to be started. It is used for fairness. @@ -126,8 +122,8 @@ struct ctlr_info /* and saved for later processing */ #endif unsigned char alive; - struct list_head scan_list; - struct completion scan_wait; + struct completion *rescan_wait; + struct task_struct *cciss_scan_thread; struct device dev; }; diff --git a/trunk/drivers/block/cpqarray.c b/trunk/drivers/block/cpqarray.c index 6422651ec364..b82d438e2607 100644 --- a/trunk/drivers/block/cpqarray.c +++ b/trunk/drivers/block/cpqarray.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -178,6 +177,7 @@ static int cpqarray_register_ctlr(int ctlr, struct pci_dev *pdev); #ifdef CONFIG_PROC_FS static void ida_procinit(int i); +static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data); #else static void ida_procinit(int i) {} #endif @@ -206,7 +206,6 @@ static const struct block_device_operations ida_fops = { #ifdef CONFIG_PROC_FS static struct proc_dir_entry *proc_array; -static const struct file_operations ida_proc_fops; /* * Get us a file in /proc/array that says something about each controller. @@ -219,16 +218,19 @@ static void __init ida_procinit(int i) if (!proc_array) return; } - proc_create_data(hba[i]->devname, 0, proc_array, &ida_proc_fops, hba[i]); + create_proc_read_entry(hba[i]->devname, 0, proc_array, + ida_proc_get_info, hba[i]); } /* * Report information about this controller. */ -static int ida_proc_show(struct seq_file *m, void *v) +static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data) { - int i, ctlr; - ctlr_info_t *h = (ctlr_info_t*)m->private; + off_t pos = 0; + off_t len = 0; + int size, i, ctlr; + ctlr_info_t *h = (ctlr_info_t*)data; drv_info_t *drv; #ifdef CPQ_PROC_PRINT_QUEUES cmdlist_t *c; @@ -236,7 +238,7 @@ static int ida_proc_show(struct seq_file *m, void *v) #endif ctlr = h->ctlr; - seq_printf(m, "%s: Compaq %s Controller\n" + size = sprintf(buffer, "%s: Compaq %s Controller\n" " Board ID: 0x%08lx\n" " Firmware Revision: %c%c%c%c\n" " Controller Sig: 0x%08lx\n" @@ -256,54 +258,55 @@ static int ida_proc_show(struct seq_file *m, void *v) h->log_drives, h->phys_drives, h->Qdepth, h->maxQsinceinit); - seq_puts(m, "Logical Drive Info:\n"); + pos += size; len += size; + + size = sprintf(buffer+len, "Logical Drive Info:\n"); + pos += size; len += size; for(i=0; ilog_drives; i++) { drv = &h->drv[i]; - seq_printf(m, "ida/c%dd%d: blksz=%d nr_blks=%d\n", + size = sprintf(buffer+len, "ida/c%dd%d: blksz=%d nr_blks=%d\n", ctlr, i, drv->blk_size, drv->nr_blks); + pos += size; len += size; } #ifdef CPQ_PROC_PRINT_QUEUES spin_lock_irqsave(IDA_LOCK(h->ctlr), flags); - seq_puts(m, "\nCurrent Queues:\n"); + size = sprintf(buffer+len, "\nCurrent Queues:\n"); + pos += size; len += size; c = h->reqQ; - seq_printf(m, "reqQ = %p", c); + size = sprintf(buffer+len, "reqQ = %p", c); pos += size; len += size; if (c) c=c->next; while(c && c != h->reqQ) { - seq_printf(m, "->%p", c); + size = sprintf(buffer+len, "->%p", c); + pos += size; len += size; c=c->next; } c = h->cmpQ; - seq_printf(m, "\ncmpQ = %p", c); + size = sprintf(buffer+len, "\ncmpQ = %p", c); pos += size; len += size; if (c) c=c->next; while(c && c != h->cmpQ) { - seq_printf(m, "->%p", c); + size = sprintf(buffer+len, "->%p", c); + pos += size; len += size; c=c->next; } - seq_putc(m, '\n'); + size = sprintf(buffer+len, "\n"); pos += size; len += size; spin_unlock_irqrestore(IDA_LOCK(h->ctlr), flags); #endif - seq_printf(m, "nr_allocs = %d\nnr_frees = %d\n", + size = sprintf(buffer+len, "nr_allocs = %d\nnr_frees = %d\n", h->nr_allocs, h->nr_frees); - return 0; -} - -static int ida_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, ida_proc_show, PDE(inode)->data); + pos += size; len += size; + + *eof = 1; + *start = buffer+offset; + len -= offset; + if (len>length) + len = length; + return len; } - -static const struct file_operations ida_proc_fops = { - .owner = THIS_MODULE, - .open = ida_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; #endif /* CONFIG_PROC_FS */ module_param_array(eisa, int, NULL, 0); diff --git a/trunk/drivers/char/dtlk.c b/trunk/drivers/char/dtlk.c index 045c930e6320..52e06589821d 100644 --- a/trunk/drivers/char/dtlk.c +++ b/trunk/drivers/char/dtlk.c @@ -56,7 +56,6 @@ #include /* for -EBUSY */ #include /* for request_region */ #include /* for loops_per_jiffy */ -#include #include /* cycle_kernel_lock() */ #include /* for inb_p, outb_p, inb, outb, etc. */ #include /* for get_user, etc. */ diff --git a/trunk/drivers/char/ipmi/ipmi_devintf.c b/trunk/drivers/char/ipmi/ipmi_devintf.c index 65545de3dbf4..41fc11dc921c 100644 --- a/trunk/drivers/char/ipmi/ipmi_devintf.c +++ b/trunk/drivers/char/ipmi/ipmi_devintf.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/ipmi/ipmi_msghandler.c b/trunk/drivers/char/ipmi/ipmi_msghandler.c index ec5e3f8df648..09050797c76a 100644 --- a/trunk/drivers/char/ipmi/ipmi_msghandler.c +++ b/trunk/drivers/char/ipmi/ipmi_msghandler.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/firewire/core-cdev.c b/trunk/drivers/firewire/core-cdev.c index 5089331544ed..ced186d7e9a9 100644 --- a/trunk/drivers/firewire/core-cdev.c +++ b/trunk/drivers/firewire/core-cdev.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/firmware/iscsi_ibft.c b/trunk/drivers/firmware/iscsi_ibft.c index 051d1ebbd287..420a96e7f2db 100644 --- a/trunk/drivers/firmware/iscsi_ibft.c +++ b/trunk/drivers/firmware/iscsi_ibft.c @@ -939,7 +939,7 @@ static int __init ibft_init(void) if (ibft_addr) { printk(KERN_INFO "iBFT detected at 0x%llx.\n", - (u64)isa_virt_to_bus(ibft_addr)); + (u64)virt_to_phys((void *)ibft_addr)); rc = ibft_check_device(); if (rc) diff --git a/trunk/drivers/firmware/iscsi_ibft_find.c b/trunk/drivers/firmware/iscsi_ibft_find.c index dfb15c06c88f..d53fbbfefa3e 100644 --- a/trunk/drivers/firmware/iscsi_ibft_find.c +++ b/trunk/drivers/firmware/iscsi_ibft_find.c @@ -65,10 +65,10 @@ void __init reserve_ibft_region(void) * so skip that area */ if (pos == VGA_MEM) pos += VGA_SIZE; - virt = isa_bus_to_virt(pos); + virt = phys_to_virt(pos); if (memcmp(virt, IBFT_SIGN, IBFT_SIGN_LEN) == 0) { unsigned long *addr = - (unsigned long *)isa_bus_to_virt(pos + 4); + (unsigned long *)phys_to_virt(pos + 4); len = *addr; /* if the length of the table extends past 1M, * the table cannot be valid. */ diff --git a/trunk/drivers/hid/hidraw.c b/trunk/drivers/hid/hidraw.c index ba05275e5104..0c6639ea03dd 100644 --- a/trunk/drivers/hid/hidraw.c +++ b/trunk/drivers/hid/hidraw.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/hwmon/ltc4215.c b/trunk/drivers/hwmon/ltc4215.c index 00d975eb5b83..6c9a04136e0a 100644 --- a/trunk/drivers/hwmon/ltc4215.c +++ b/trunk/drivers/hwmon/ltc4215.c @@ -20,6 +20,11 @@ #include #include +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +/* Insmod parameters */ +I2C_CLIENT_INSMOD_1(ltc4215); + /* Here are names of the chip's registers (a.k.a. commands) */ enum ltc4215_cmd { LTC4215_CONTROL = 0x00, /* rw */ @@ -241,13 +246,9 @@ static const struct attribute_group ltc4215_group = { static int ltc4215_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct i2c_adapter *adapter = client->adapter; struct ltc4215_data *data; int ret; - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; - data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) { ret = -ENOMEM; @@ -293,20 +294,56 @@ static int ltc4215_remove(struct i2c_client *client) return 0; } +static int ltc4215_detect(struct i2c_client *client, + int kind, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + if (kind < 0) { /* probed detection - check the chip type */ + s32 v; /* 8 bits from the chip, or -ERRNO */ + + /* + * Register 0x01 bit b7 is reserved, expect 0 + * Register 0x03 bit b6 and b7 are reserved, expect 0 + */ + v = i2c_smbus_read_byte_data(client, LTC4215_ALERT); + if (v < 0 || (v & (1 << 7)) != 0) + return -ENODEV; + + v = i2c_smbus_read_byte_data(client, LTC4215_FAULT); + if (v < 0 || (v & ((1 << 6) | (1 << 7))) != 0) + return -ENODEV; + } + + strlcpy(info->type, "ltc4215", I2C_NAME_SIZE); + dev_info(&adapter->dev, "ltc4215 %s at address 0x%02x\n", + kind < 0 ? "probed" : "forced", + client->addr); + + return 0; +} + static const struct i2c_device_id ltc4215_id[] = { - { "ltc4215", 0 }, + { "ltc4215", ltc4215 }, { } }; MODULE_DEVICE_TABLE(i2c, ltc4215_id); /* This is the driver that will be inserted */ static struct i2c_driver ltc4215_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "ltc4215", }, .probe = ltc4215_probe, .remove = ltc4215_remove, .id_table = ltc4215_id, + .detect = ltc4215_detect, + .address_data = &addr_data, }; static int __init ltc4215_init(void) diff --git a/trunk/drivers/hwmon/ltc4245.c b/trunk/drivers/hwmon/ltc4245.c index 65c232a9d0c5..e38964333612 100644 --- a/trunk/drivers/hwmon/ltc4245.c +++ b/trunk/drivers/hwmon/ltc4245.c @@ -22,6 +22,15 @@ #include #include +/* Valid addresses are 0x20 - 0x3f + * + * For now, we do not probe, since some of these addresses + * are known to be unfriendly to probing */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +/* Insmod parameters */ +I2C_CLIENT_INSMOD_1(ltc4245); + /* Here are names of the chip's registers (a.k.a. commands) */ enum ltc4245_cmd { LTC4245_STATUS = 0x00, /* readonly */ @@ -360,13 +369,9 @@ static const struct attribute_group ltc4245_group = { static int ltc4245_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct i2c_adapter *adapter = client->adapter; struct ltc4245_data *data; int ret; - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; - data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) { ret = -ENOMEM; @@ -413,20 +418,136 @@ static int ltc4245_remove(struct i2c_client *client) return 0; } +/* Check that some bits in a control register appear at all possible + * locations without changing value + * + * @client: the i2c client to use + * @reg: the register to read + * @bits: the bits to check (0xff checks all bits, + * 0x03 checks only the last two bits) + * + * return -ERRNO if the register read failed + * return -ENODEV if the register value doesn't stay constant at all + * possible addresses + * + * return 0 for success + */ +static int ltc4245_check_control_reg(struct i2c_client *client, u8 reg, u8 bits) +{ + int i; + s32 v, voff1, voff2; + + /* Read register and check for error */ + v = i2c_smbus_read_byte_data(client, reg); + if (v < 0) + return v; + + v &= bits; + + for (i = 0x00; i < 0xff; i += 0x20) { + + voff1 = i2c_smbus_read_byte_data(client, reg + i); + if (voff1 < 0) + return voff1; + + voff2 = i2c_smbus_read_byte_data(client, reg + i + 0x08); + if (voff2 < 0) + return voff2; + + voff1 &= bits; + voff2 &= bits; + + if (v != voff1 || v != voff2) + return -ENODEV; + } + + return 0; +} + +static int ltc4245_detect(struct i2c_client *client, + int kind, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + if (kind < 0) { /* probed detection - check the chip type */ + s32 v; /* 8 bits from the chip, or -ERRNO */ + + /* Chip registers 0x00-0x07 are control registers + * Chip registers 0x10-0x1f are data registers + * + * Address bits b7-b5 are ignored. This makes the chip "repeat" + * in steps of 0x20. Any control registers should appear with + * the same values across all duplicated addresses. + * + * Register 0x02 bit b2 is reserved, expect 0 + * Register 0x07 bits b7 to b4 are reserved, expect 0 + * + * Registers 0x01, 0x02 are control registers and should not + * change on their own. + * + * Register 0x06 bits b6 and b7 are control bits, and should + * not change on their own. + * + * Register 0x07 bits b3 to b0 are control bits, and should + * not change on their own. + */ + + /* read register 0x02 reserved bit, expect 0 */ + v = i2c_smbus_read_byte_data(client, LTC4245_CONTROL); + if (v < 0 || (v & 0x04) != 0) + return -ENODEV; + + /* read register 0x07 reserved bits, expect 0 */ + v = i2c_smbus_read_byte_data(client, LTC4245_ADCADR); + if (v < 0 || (v & 0xf0) != 0) + return -ENODEV; + + /* check that the alert register appears at all locations */ + if (ltc4245_check_control_reg(client, LTC4245_ALERT, 0xff)) + return -ENODEV; + + /* check that the control register appears at all locations */ + if (ltc4245_check_control_reg(client, LTC4245_CONTROL, 0xff)) + return -ENODEV; + + /* check that register 0x06 bits b6 and b7 stay constant */ + if (ltc4245_check_control_reg(client, LTC4245_GPIO, 0xc0)) + return -ENODEV; + + /* check that register 0x07 bits b3-b0 stay constant */ + if (ltc4245_check_control_reg(client, LTC4245_ADCADR, 0x0f)) + return -ENODEV; + } + + strlcpy(info->type, "ltc4245", I2C_NAME_SIZE); + dev_info(&adapter->dev, "ltc4245 %s at address 0x%02x\n", + kind < 0 ? "probed" : "forced", + client->addr); + + return 0; +} + static const struct i2c_device_id ltc4245_id[] = { - { "ltc4245", 0 }, + { "ltc4245", ltc4245 }, { } }; MODULE_DEVICE_TABLE(i2c, ltc4245_id); /* This is the driver that will be inserted */ static struct i2c_driver ltc4245_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "ltc4245", }, .probe = ltc4245_probe, .remove = ltc4245_remove, .id_table = ltc4245_id, + .detect = ltc4245_detect, + .address_data = &addr_data, }; static int __init ltc4245_init(void) diff --git a/trunk/drivers/i2c/busses/i2c-amd756.c b/trunk/drivers/i2c/busses/i2c-amd756.c index 8f0b90ef8c76..f7d6fe9c49ba 100644 --- a/trunk/drivers/i2c/busses/i2c-amd756.c +++ b/trunk/drivers/i2c/busses/i2c-amd756.c @@ -364,7 +364,7 @@ static int __devinit amd756_probe(struct pci_dev *pdev, error = acpi_check_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name); if (error) - return -ENODEV; + return error; if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) { dev_err(&pdev->dev, "SMB region 0x%x already in use!\n", diff --git a/trunk/drivers/i2c/busses/i2c-amd8111.c b/trunk/drivers/i2c/busses/i2c-amd8111.c index 5b4ad86ca166..a7c59908c457 100644 --- a/trunk/drivers/i2c/busses/i2c-amd8111.c +++ b/trunk/drivers/i2c/busses/i2c-amd8111.c @@ -376,10 +376,8 @@ static int __devinit amd8111_probe(struct pci_dev *dev, smbus->size = pci_resource_len(dev, 0); error = acpi_check_resource_conflict(&dev->resource[0]); - if (error) { - error = -ENODEV; + if (error) goto out_kfree; - } if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) { error = -EBUSY; diff --git a/trunk/drivers/i2c/busses/i2c-i801.c b/trunk/drivers/i2c/busses/i2c-i801.c index 55edcfe5b851..9d2c5adf5d4f 100644 --- a/trunk/drivers/i2c/busses/i2c-i801.c +++ b/trunk/drivers/i2c/busses/i2c-i801.c @@ -732,10 +732,8 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id } err = acpi_check_resource_conflict(&dev->resource[SMBBAR]); - if (err) { - err = -ENODEV; + if (err) goto exit; - } err = pci_request_region(dev, SMBBAR, i801_driver.name); if (err) { diff --git a/trunk/drivers/i2c/busses/i2c-isch.c b/trunk/drivers/i2c/busses/i2c-isch.c index dba6eb053e2f..9f6b8e0f8632 100644 --- a/trunk/drivers/i2c/busses/i2c-isch.c +++ b/trunk/drivers/i2c/busses/i2c-isch.c @@ -281,7 +281,7 @@ static int __devinit sch_probe(struct pci_dev *dev, return -ENODEV; } if (acpi_check_region(sch_smba, SMBIOSIZE, sch_driver.name)) - return -ENODEV; + return -EBUSY; if (!request_region(sch_smba, SMBIOSIZE, sch_driver.name)) { dev_err(&dev->dev, "SMBus region 0x%x already in use!\n", sch_smba); diff --git a/trunk/drivers/i2c/busses/i2c-piix4.c b/trunk/drivers/i2c/busses/i2c-piix4.c index d26a972aacaa..a782c7a08f9e 100644 --- a/trunk/drivers/i2c/busses/i2c-piix4.c +++ b/trunk/drivers/i2c/busses/i2c-piix4.c @@ -169,7 +169,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, } if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) - return -ENODEV; + return -EBUSY; if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n", @@ -260,7 +260,7 @@ static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev, piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0; if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) - return -ENODEV; + return -EBUSY; if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n", diff --git a/trunk/drivers/i2c/busses/i2c-sis96x.c b/trunk/drivers/i2c/busses/i2c-sis96x.c index 1649963b00dc..8295885b2fdb 100644 --- a/trunk/drivers/i2c/busses/i2c-sis96x.c +++ b/trunk/drivers/i2c/busses/i2c-sis96x.c @@ -280,7 +280,7 @@ static int __devinit sis96x_probe(struct pci_dev *dev, retval = acpi_check_resource_conflict(&dev->resource[SIS96x_BAR]); if (retval) - return -ENODEV; + return retval; /* Everything is happy, let's grab the memory and set things up. */ if (!request_region(sis96x_smbus_base, SMB_IOSIZE, diff --git a/trunk/drivers/i2c/busses/i2c-viapro.c b/trunk/drivers/i2c/busses/i2c-viapro.c index e4b1543015af..54d810a4d00f 100644 --- a/trunk/drivers/i2c/busses/i2c-viapro.c +++ b/trunk/drivers/i2c/busses/i2c-viapro.c @@ -365,7 +365,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev, found: error = acpi_check_region(vt596_smba, 8, vt596_driver.name); if (error) - return -ENODEV; + return error; if (!request_region(vt596_smba, 8, vt596_driver.name)) { dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n", diff --git a/trunk/drivers/infiniband/core/ucm.c b/trunk/drivers/infiniband/core/ucm.c index f504c9b00c1b..51bd9669cb1f 100644 --- a/trunk/drivers/infiniband/core/ucm.c +++ b/trunk/drivers/infiniband/core/ucm.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/infiniband/core/user_mad.c b/trunk/drivers/infiniband/core/user_mad.c index 7de02969ed7d..8c46f2257098 100644 --- a/trunk/drivers/infiniband/core/user_mad.c +++ b/trunk/drivers/infiniband/core/user_mad.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/infiniband/core/uverbs_main.c b/trunk/drivers/infiniband/core/uverbs_main.c index aec0fbdfe7f0..d3fff9e008a3 100644 --- a/trunk/drivers/infiniband/core/uverbs_main.c +++ b/trunk/drivers/infiniband/core/uverbs_main.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/input/evdev.c b/trunk/drivers/input/evdev.c index dee6706038aa..1148140d08a1 100644 --- a/trunk/drivers/input/evdev.c +++ b/trunk/drivers/input/evdev.c @@ -13,7 +13,6 @@ #define EVDEV_BUFFER_SIZE 64 #include -#include #include #include #include diff --git a/trunk/drivers/input/input.c b/trunk/drivers/input/input.c index c6f88ebb40c7..16ec33f27c5d 100644 --- a/trunk/drivers/input/input.c +++ b/trunk/drivers/input/input.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/input/joydev.c b/trunk/drivers/input/joydev.c index b1bd6dd32286..901b2525993e 100644 --- a/trunk/drivers/input/joydev.c +++ b/trunk/drivers/input/joydev.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/input/misc/uinput.c b/trunk/drivers/input/misc/uinput.c index d3f57245420a..c5a49aba418f 100644 --- a/trunk/drivers/input/misc/uinput.c +++ b/trunk/drivers/input/misc/uinput.c @@ -30,7 +30,6 @@ * - first public version */ #include -#include #include #include #include diff --git a/trunk/drivers/input/mousedev.c b/trunk/drivers/input/mousedev.c index a13d80f7da17..966b8868f792 100644 --- a/trunk/drivers/input/mousedev.c +++ b/trunk/drivers/input/mousedev.c @@ -13,7 +13,6 @@ #define MOUSEDEV_MINORS 32 #define MOUSEDEV_MIX 31 -#include #include #include #include diff --git a/trunk/drivers/isdn/divert/divert_procfs.c b/trunk/drivers/isdn/divert/divert_procfs.c index 3697c409bec6..8b256a617c8a 100644 --- a/trunk/drivers/isdn/divert/divert_procfs.c +++ b/trunk/drivers/isdn/divert/divert_procfs.c @@ -16,7 +16,6 @@ #else #include #endif -#include #include #include #include "isdn_divert.h" diff --git a/trunk/drivers/leds/leds-pca9532.c b/trunk/drivers/leds/leds-pca9532.c index adc561eb59d2..708a8017c21d 100644 --- a/trunk/drivers/leds/leds-pca9532.c +++ b/trunk/drivers/leds/leds-pca9532.c @@ -19,6 +19,9 @@ #include #include +static const unsigned short normal_i2c[] = { /*0x60,*/ I2C_CLIENT_END}; +I2C_CLIENT_INSMOD_1(pca9532); + #define PCA9532_REG_PSC(i) (0x2+(i)*2) #define PCA9532_REG_PWM(i) (0x3+(i)*2) #define PCA9532_REG_LS0 0x6 diff --git a/trunk/drivers/macintosh/therm_adt746x.c b/trunk/drivers/macintosh/therm_adt746x.c index 556f0feaa4df..fde377c60cca 100644 --- a/trunk/drivers/macintosh/therm_adt746x.c +++ b/trunk/drivers/macintosh/therm_adt746x.c @@ -124,8 +124,6 @@ read_reg(struct thermostat* th, int reg) return data; } -static struct i2c_driver thermostat_driver; - static int attach_thermostat(struct i2c_adapter *adapter) { @@ -150,7 +148,7 @@ attach_thermostat(struct i2c_adapter *adapter) * Let i2c-core delete that device on driver removal. * This is safe because i2c-core holds the core_lock mutex for us. */ - list_add_tail(&client->detected, &thermostat_driver.clients); + list_add_tail(&client->detected, &client->driver->clients); return 0; } diff --git a/trunk/drivers/macintosh/therm_pm72.c b/trunk/drivers/macintosh/therm_pm72.c index ea32c7e5a9af..a028598af2d3 100644 --- a/trunk/drivers/macintosh/therm_pm72.c +++ b/trunk/drivers/macintosh/therm_pm72.c @@ -286,8 +286,6 @@ struct fcu_fan_table fcu_fans[] = { }, }; -static struct i2c_driver therm_pm72_driver; - /* * Utility function to create an i2c_client structure and * attach it to one of u3 adapters @@ -320,7 +318,7 @@ static struct i2c_client *attach_i2c_chip(int id, const char *name) * Let i2c-core delete that device on driver removal. * This is safe because i2c-core holds the core_lock mutex for us. */ - list_add_tail(&clt->detected, &therm_pm72_driver.clients); + list_add_tail(&clt->detected, &clt->driver->clients); return clt; } diff --git a/trunk/drivers/macintosh/windfarm_lm75_sensor.c b/trunk/drivers/macintosh/windfarm_lm75_sensor.c index ed6426a10773..529886c7a826 100644 --- a/trunk/drivers/macintosh/windfarm_lm75_sensor.c +++ b/trunk/drivers/macintosh/windfarm_lm75_sensor.c @@ -115,8 +115,6 @@ static int wf_lm75_probe(struct i2c_client *client, return rc; } -static struct i2c_driver wf_lm75_driver; - static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter, u8 addr, int ds1775, const char *loc) @@ -159,7 +157,7 @@ static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter, * Let i2c-core delete that device on driver removal. * This is safe because i2c-core holds the core_lock mutex for us. */ - list_add_tail(&client->detected, &wf_lm75_driver.clients); + list_add_tail(&client->detected, &client->driver->clients); return client; fail: return NULL; diff --git a/trunk/drivers/macintosh/windfarm_max6690_sensor.c b/trunk/drivers/macintosh/windfarm_max6690_sensor.c index a67b349319e9..e2a55ecda2b2 100644 --- a/trunk/drivers/macintosh/windfarm_max6690_sensor.c +++ b/trunk/drivers/macintosh/windfarm_max6690_sensor.c @@ -88,8 +88,6 @@ static int wf_max6690_probe(struct i2c_client *client, return rc; } -static struct i2c_driver wf_max6690_driver; - static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter, u8 addr, const char *loc) { @@ -121,7 +119,7 @@ static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter, * Let i2c-core delete that device on driver removal. * This is safe because i2c-core holds the core_lock mutex for us. */ - list_add_tail(&client->detected, &wf_max6690_driver.clients); + list_add_tail(&client->detected, &client->driver->clients); return client; fail: diff --git a/trunk/drivers/macintosh/windfarm_smu_sat.c b/trunk/drivers/macintosh/windfarm_smu_sat.c index e20330a28959..5da729e58f99 100644 --- a/trunk/drivers/macintosh/windfarm_smu_sat.c +++ b/trunk/drivers/macintosh/windfarm_smu_sat.c @@ -194,8 +194,6 @@ static struct wf_sensor_ops wf_sat_ops = { .owner = THIS_MODULE, }; -static struct i2c_driver wf_sat_driver; - static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) { struct i2c_board_info info; @@ -224,7 +222,7 @@ static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) * Let i2c-core delete that device on driver removal. * This is safe because i2c-core holds the core_lock mutex for us. */ - list_add_tail(&client->detected, &wf_sat_driver.clients); + list_add_tail(&client->detected, &client->driver->clients); } static int wf_sat_probe(struct i2c_client *client, diff --git a/trunk/drivers/md/dm.c b/trunk/drivers/md/dm.c index 23e76fe0d359..376f1ab48a24 100644 --- a/trunk/drivers/md/dm.c +++ b/trunk/drivers/md/dm.c @@ -130,7 +130,7 @@ struct mapped_device { /* * A list of ios that arrived while we were suspended. */ - atomic_t pending; + atomic_t pending[2]; wait_queue_head_t wait; struct work_struct work; struct bio_list deferred; @@ -453,13 +453,14 @@ static void start_io_acct(struct dm_io *io) { struct mapped_device *md = io->md; int cpu; + int rw = bio_data_dir(io->bio); io->start_time = jiffies; cpu = part_stat_lock(); part_round_stats(cpu, &dm_disk(md)->part0); part_stat_unlock(); - dm_disk(md)->part0.in_flight = atomic_inc_return(&md->pending); + dm_disk(md)->part0.in_flight[rw] = atomic_inc_return(&md->pending[rw]); } static void end_io_acct(struct dm_io *io) @@ -479,8 +480,9 @@ static void end_io_acct(struct dm_io *io) * After this is decremented the bio must not be touched if it is * a barrier. */ - dm_disk(md)->part0.in_flight = pending = - atomic_dec_return(&md->pending); + dm_disk(md)->part0.in_flight[rw] = pending = + atomic_dec_return(&md->pending[rw]); + pending += atomic_read(&md->pending[rw^0x1]); /* nudge anyone waiting on suspend queue */ if (!pending) @@ -1785,7 +1787,8 @@ static struct mapped_device *alloc_dev(int minor) if (!md->disk) goto bad_disk; - atomic_set(&md->pending, 0); + atomic_set(&md->pending[0], 0); + atomic_set(&md->pending[1], 0); init_waitqueue_head(&md->wait); INIT_WORK(&md->work, dm_wq_work); init_waitqueue_head(&md->eventq); @@ -2088,7 +2091,8 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible) break; } spin_unlock_irqrestore(q->queue_lock, flags); - } else if (!atomic_read(&md->pending)) + } else if (!atomic_read(&md->pending[0]) && + !atomic_read(&md->pending[1])) break; if (interruptible == TASK_INTERRUPTIBLE && diff --git a/trunk/drivers/media/dvb/dvb-core/dmxdev.c b/trunk/drivers/media/dvb/dvb-core/dmxdev.c index c37790ad92d0..516414983593 100644 --- a/trunk/drivers/media/dvb/dvb-core/dmxdev.c +++ b/trunk/drivers/media/dvb/dvb-core/dmxdev.c @@ -20,7 +20,6 @@ * */ -#include #include #include #include diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_demux.c b/trunk/drivers/media/dvb/dvb-core/dvb_demux.c index 91c537bca8ad..eef6d3616626 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_demux.c @@ -21,7 +21,6 @@ * */ -#include #include #include #include diff --git a/trunk/drivers/media/radio/radio-cadet.c b/trunk/drivers/media/radio/radio-cadet.c index 482d0f3be5ff..8b1440136c45 100644 --- a/trunk/drivers/media/radio/radio-cadet.c +++ b/trunk/drivers/media/radio/radio-cadet.c @@ -38,7 +38,6 @@ #include /* V4L2 API defs */ #include #include -#include #include /* outb, outb_p */ #include #include diff --git a/trunk/drivers/media/video/cpia.c b/trunk/drivers/media/video/cpia.c index 2377313c041a..43ab0adf3b61 100644 --- a/trunk/drivers/media/video/cpia.c +++ b/trunk/drivers/media/video/cpia.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/mfd/ab3100-core.c b/trunk/drivers/mfd/ab3100-core.c index 613481028272..5447da16a170 100644 --- a/trunk/drivers/mfd/ab3100-core.c +++ b/trunk/drivers/mfd/ab3100-core.c @@ -57,6 +57,8 @@ * The AB3100 is usually assigned address 0x48 (7-bit) * The chip is defined in the platform i2c_board_data section. */ +static unsigned short normal_i2c[] = { 0x48, I2C_CLIENT_END }; +I2C_CLIENT_INSMOD_1(ab3100); u8 ab3100_get_chip_type(struct ab3100 *ab3100) { @@ -964,7 +966,7 @@ static int __exit ab3100_remove(struct i2c_client *client) } static const struct i2c_device_id ab3100_id[] = { - { "ab3100", 0 }, + { "ab3100", ab3100 }, { } }; MODULE_DEVICE_TABLE(i2c, ab3100_id); diff --git a/trunk/drivers/mfd/ucb1400_core.c b/trunk/drivers/mfd/ucb1400_core.c index fa294b6d600a..2afc08006e6d 100644 --- a/trunk/drivers/mfd/ucb1400_core.c +++ b/trunk/drivers/mfd/ucb1400_core.c @@ -21,7 +21,6 @@ */ #include -#include #include unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel, diff --git a/trunk/drivers/misc/eeprom/max6875.c b/trunk/drivers/misc/eeprom/max6875.c index 5a6b2bce8ad5..3c0c58eed347 100644 --- a/trunk/drivers/misc/eeprom/max6875.c +++ b/trunk/drivers/misc/eeprom/max6875.c @@ -33,6 +33,12 @@ #include #include +/* Do not scan - the MAX6875 access method will write to some EEPROM chips */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +/* Insmod parameters */ +I2C_CLIENT_INSMOD_1(max6875); + /* The MAX6875 can only read/write 16 bytes at a time */ #define SLICE_SIZE 16 #define SLICE_BITS 4 @@ -140,21 +146,31 @@ static struct bin_attribute user_eeprom_attr = { .read = max6875_read, }; -static int max6875_probe(struct i2c_client *client, - const struct i2c_device_id *id) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int max6875_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; - struct max6875_data *data; - int err; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA | I2C_FUNC_SMBUS_READ_BYTE)) return -ENODEV; - /* Only bind to even addresses */ + /* Only check even addresses */ if (client->addr & 1) return -ENODEV; + strlcpy(info->type, "max6875", I2C_NAME_SIZE); + + return 0; +} + +static int max6875_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct max6875_data *data; + int err; + if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL))) return -ENOMEM; @@ -206,6 +222,9 @@ static struct i2c_driver max6875_driver = { .probe = max6875_probe, .remove = max6875_remove, .id_table = max6875_id, + + .detect = max6875_detect, + .address_data = &addr_data, }; static int __init max6875_init(void) diff --git a/trunk/drivers/mtd/mtd_blkdevs.c b/trunk/drivers/mtd/mtd_blkdevs.c index 8ca17a3e96ea..0acbf4f5be50 100644 --- a/trunk/drivers/mtd/mtd_blkdevs.c +++ b/trunk/drivers/mtd/mtd_blkdevs.c @@ -32,6 +32,14 @@ struct mtd_blkcore_priv { spinlock_t queue_lock; }; +static int blktrans_discard_request(struct request_queue *q, + struct request *req) +{ + req->cmd_type = REQ_TYPE_LINUX_BLOCK; + req->cmd[0] = REQ_LB_OP_DISCARD; + return 0; +} + static int do_blktrans_request(struct mtd_blktrans_ops *tr, struct mtd_blktrans_dev *dev, struct request *req) @@ -44,6 +52,10 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr, buf = req->buffer; + if (req->cmd_type == REQ_TYPE_LINUX_BLOCK && + req->cmd[0] == REQ_LB_OP_DISCARD) + return tr->discard(dev, block, nsect); + if (!blk_fs_request(req)) return -EIO; @@ -51,9 +63,6 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr, get_capacity(req->rq_disk)) return -EIO; - if (blk_discard_rq(req)) - return tr->discard(dev, block, nsect); - switch(rq_data_dir(req)) { case READ: for (; nsect > 0; nsect--, block++, buf += tr->blksize) @@ -371,8 +380,8 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) tr->blkcore_priv->rq->queuedata = tr; blk_queue_logical_block_size(tr->blkcore_priv->rq, tr->blksize); if (tr->discard) - queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, - tr->blkcore_priv->rq); + blk_queue_set_discard(tr->blkcore_priv->rq, + blktrans_discard_request); tr->blkshift = ffs(tr->blksize) - 1; diff --git a/trunk/drivers/platform/x86/sony-laptop.c b/trunk/drivers/platform/x86/sony-laptop.c index a2a742c8ff7e..afdbdaaf80cb 100644 --- a/trunk/drivers/platform/x86/sony-laptop.c +++ b/trunk/drivers/platform/x86/sony-laptop.c @@ -1211,6 +1211,15 @@ static int sony_nc_add(struct acpi_device *device) } } + /* try to _INI the device if such method exists (ACPI spec 3.0-6.5.1 + * should be respected as we already checked for the device presence above */ + if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, METHOD_NAME__INI, &handle))) { + dprintk("Invoking _INI\n"); + if (ACPI_FAILURE(acpi_evaluate_object(sony_nc_acpi_handle, METHOD_NAME__INI, + NULL, NULL))) + dprintk("_INI Method failed\n"); + } + if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON", &handle))) { if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL)) @@ -1390,20 +1399,27 @@ struct sonypi_eventtypes { struct sonypi_event *events; }; -struct sony_pic_dev { - struct acpi_device *acpi_dev; - struct sony_pic_irq *cur_irq; - struct sony_pic_ioport *cur_ioport; - struct list_head interrupts; - struct list_head ioports; - struct mutex lock; - struct sonypi_eventtypes *event_types; - int (*handle_irq)(const u8, const u8); +struct device_ctrl { int model; + int (*handle_irq)(const u8, const u8); u16 evport_offset; - u8 camera_power; - u8 bluetooth_power; - u8 wwan_power; + u8 has_camera; + u8 has_bluetooth; + u8 has_wwan; + struct sonypi_eventtypes *event_types; +}; + +struct sony_pic_dev { + struct device_ctrl *control; + struct acpi_device *acpi_dev; + struct sony_pic_irq *cur_irq; + struct sony_pic_ioport *cur_ioport; + struct list_head interrupts; + struct list_head ioports; + struct mutex lock; + u8 camera_power; + u8 bluetooth_power; + u8 wwan_power; }; static struct sony_pic_dev spic_dev = { @@ -1411,8 +1427,6 @@ static struct sony_pic_dev spic_dev = { .ioports = LIST_HEAD_INIT(spic_dev.ioports), }; -static int spic_drv_registered; - /* Event masks */ #define SONYPI_JOGGER_MASK 0x00000001 #define SONYPI_CAPTURE_MASK 0x00000002 @@ -1710,6 +1724,27 @@ static int type3_handle_irq(const u8 data_mask, const u8 ev) return 1; } +static struct device_ctrl spic_types[] = { + { + .model = SONYPI_DEVICE_TYPE1, + .handle_irq = NULL, + .evport_offset = SONYPI_TYPE1_OFFSET, + .event_types = type1_events, + }, + { + .model = SONYPI_DEVICE_TYPE2, + .handle_irq = NULL, + .evport_offset = SONYPI_TYPE2_OFFSET, + .event_types = type2_events, + }, + { + .model = SONYPI_DEVICE_TYPE3, + .handle_irq = type3_handle_irq, + .evport_offset = SONYPI_TYPE3_OFFSET, + .event_types = type3_events, + }, +}; + static void sony_pic_detect_device_type(struct sony_pic_dev *dev) { struct pci_dev *pcidev; @@ -1717,63 +1752,48 @@ static void sony_pic_detect_device_type(struct sony_pic_dev *dev) pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL); if (pcidev) { - dev->model = SONYPI_DEVICE_TYPE1; - dev->evport_offset = SONYPI_TYPE1_OFFSET; - dev->event_types = type1_events; + dev->control = &spic_types[0]; goto out; } pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, NULL); if (pcidev) { - dev->model = SONYPI_DEVICE_TYPE2; - dev->evport_offset = SONYPI_TYPE2_OFFSET; - dev->event_types = type2_events; + dev->control = &spic_types[2]; goto out; } pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, NULL); if (pcidev) { - dev->model = SONYPI_DEVICE_TYPE3; - dev->handle_irq = type3_handle_irq; - dev->evport_offset = SONYPI_TYPE3_OFFSET; - dev->event_types = type3_events; + dev->control = &spic_types[2]; goto out; } pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_4, NULL); if (pcidev) { - dev->model = SONYPI_DEVICE_TYPE3; - dev->handle_irq = type3_handle_irq; - dev->evport_offset = SONYPI_TYPE3_OFFSET; - dev->event_types = type3_events; + dev->control = &spic_types[2]; goto out; } pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_1, NULL); if (pcidev) { - dev->model = SONYPI_DEVICE_TYPE3; - dev->handle_irq = type3_handle_irq; - dev->evport_offset = SONYPI_TYPE3_OFFSET; - dev->event_types = type3_events; + dev->control = &spic_types[2]; goto out; } /* default */ - dev->model = SONYPI_DEVICE_TYPE2; - dev->evport_offset = SONYPI_TYPE2_OFFSET; - dev->event_types = type2_events; + dev->control = &spic_types[1]; out: if (pcidev) pci_dev_put(pcidev); printk(KERN_INFO DRV_PFX "detected Type%d model\n", - dev->model == SONYPI_DEVICE_TYPE1 ? 1 : - dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3); + dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 : + dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 : 3); } /* camera tests and poweron/poweroff */ @@ -2546,7 +2566,7 @@ static int sony_pic_enable(struct acpi_device *device, buffer.pointer = resource; /* setup Type 1 resources */ - if (spic_dev.model == SONYPI_DEVICE_TYPE1) { + if (spic_dev.control->model == SONYPI_DEVICE_TYPE1) { /* setup io resources */ resource->res1.type = ACPI_RESOURCE_TYPE_IO; @@ -2629,28 +2649,29 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id) data_mask = inb_p(dev->cur_ioport->io2.minimum); else data_mask = inb_p(dev->cur_ioport->io1.minimum + - dev->evport_offset); + dev->control->evport_offset); dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", ev, data_mask, dev->cur_ioport->io1.minimum, - dev->evport_offset); + dev->control->evport_offset); if (ev == 0x00 || ev == 0xff) return IRQ_HANDLED; - for (i = 0; dev->event_types[i].mask; i++) { + for (i = 0; dev->control->event_types[i].mask; i++) { - if ((data_mask & dev->event_types[i].data) != - dev->event_types[i].data) + if ((data_mask & dev->control->event_types[i].data) != + dev->control->event_types[i].data) continue; - if (!(mask & dev->event_types[i].mask)) + if (!(mask & dev->control->event_types[i].mask)) continue; - for (j = 0; dev->event_types[i].events[j].event; j++) { - if (ev == dev->event_types[i].events[j].data) { + for (j = 0; dev->control->event_types[i].events[j].event; j++) { + if (ev == dev->control->event_types[i].events[j].data) { device_event = - dev->event_types[i].events[j].event; + dev->control-> + event_types[i].events[j].event; goto found; } } @@ -2658,12 +2679,13 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id) /* Still not able to decode the event try to pass * it over to the minidriver */ - if (dev->handle_irq && dev->handle_irq(data_mask, ev) == 0) + if (dev->control->handle_irq && + dev->control->handle_irq(data_mask, ev) == 0) return IRQ_HANDLED; dprintk("unknown event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", ev, data_mask, dev->cur_ioport->io1.minimum, - dev->evport_offset); + dev->control->evport_offset); return IRQ_HANDLED; found: @@ -2794,7 +2816,7 @@ static int sony_pic_add(struct acpi_device *device) /* request IRQ */ list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) { if (!request_irq(irq->irq.interrupts[0], sony_pic_irq, - IRQF_DISABLED, "sony-laptop", &spic_dev)) { + IRQF_SHARED, "sony-laptop", &spic_dev)) { dprintk("IRQ: %d - triggering: %d - " "polarity: %d - shr: %d\n", irq->irq.interrupts[0], @@ -2927,7 +2949,6 @@ static int __init sony_laptop_init(void) "Unable to register SPIC driver."); goto out; } - spic_drv_registered = 1; } result = acpi_bus_register_driver(&sony_nc_driver); @@ -2939,7 +2960,7 @@ static int __init sony_laptop_init(void) return 0; out_unregister_pic: - if (spic_drv_registered) + if (!no_spic) acpi_bus_unregister_driver(&sony_pic_driver); out: return result; @@ -2948,7 +2969,7 @@ static int __init sony_laptop_init(void) static void __exit sony_laptop_exit(void) { acpi_bus_unregister_driver(&sony_nc_driver); - if (spic_drv_registered) + if (!no_spic) acpi_bus_unregister_driver(&sony_pic_driver); } diff --git a/trunk/drivers/sfi/sfi_core.c b/trunk/drivers/sfi/sfi_core.c index b204a0929139..d3b496800477 100644 --- a/trunk/drivers/sfi/sfi_core.c +++ b/trunk/drivers/sfi/sfi_core.c @@ -90,11 +90,7 @@ static struct sfi_table_simple *syst_va __read_mostly; */ static u32 sfi_use_ioremap __read_mostly; -/* - * sfi_un/map_memory calls early_ioremap/iounmap which is a __init function - * and introduces section mismatch. So use __ref to make it calm. - */ -static void __iomem * __ref sfi_map_memory(u64 phys, u32 size) +static void __iomem *sfi_map_memory(u64 phys, u32 size) { if (!phys || !size) return NULL; @@ -105,7 +101,7 @@ static void __iomem * __ref sfi_map_memory(u64 phys, u32 size) return early_ioremap(phys, size); } -static void __ref sfi_unmap_memory(void __iomem *virt, u32 size) +static void sfi_unmap_memory(void __iomem *virt, u32 size) { if (!virt || !size) return; @@ -129,7 +125,7 @@ static void sfi_print_table_header(unsigned long long pa, * sfi_verify_table() * Sanity check table lengh, calculate checksum */ -static int sfi_verify_table(struct sfi_table_header *table) +static __init int sfi_verify_table(struct sfi_table_header *table) { u8 checksum = 0; @@ -217,17 +213,12 @@ static int sfi_table_check_key(struct sfi_table_header *th, * the mapped virt address will be returned, and the virt space * will be released by call sfi_put_table() later * - * This two cases are from two different functions with two different - * sections and causes section mismatch warning. So use __ref to tell - * modpost not to make any noise. - * * Return value: * NULL: when can't find a table matching the key * ERR_PTR(error): error value * virt table address: when a matched table is found */ -struct sfi_table_header * - __ref sfi_check_table(u64 pa, struct sfi_table_key *key) +struct sfi_table_header *sfi_check_table(u64 pa, struct sfi_table_key *key) { struct sfi_table_header *th; void *ret = NULL; diff --git a/trunk/drivers/staging/dst/dcore.c b/trunk/drivers/staging/dst/dcore.c index c24e4e0367a2..ee1601026fb0 100644 --- a/trunk/drivers/staging/dst/dcore.c +++ b/trunk/drivers/staging/dst/dcore.c @@ -102,7 +102,7 @@ static int dst_request(struct request_queue *q, struct bio *bio) struct dst_node *n = q->queuedata; int err = -EIO; - if (bio_empty_barrier(bio) && !blk_queue_discard(q)) { + if (bio_empty_barrier(bio) && !q->prepare_discard_fn) { /* * This is a dirty^Wnice hack, but if we complete this * operation with -EOPNOTSUPP like intended, XFS diff --git a/trunk/drivers/staging/iio/light/tsl2561.c b/trunk/drivers/staging/iio/light/tsl2561.c index fc2107f4c049..ea8a5efc19bc 100644 --- a/trunk/drivers/staging/iio/light/tsl2561.c +++ b/trunk/drivers/staging/iio/light/tsl2561.c @@ -239,6 +239,10 @@ static int __devexit tsl2561_remove(struct i2c_client *client) return tsl2561_powerdown(client); } +static unsigned short normal_i2c[] = { 0x29, 0x39, 0x49, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; + static const struct i2c_device_id tsl2561_id[] = { { "tsl2561", 0 }, { } diff --git a/trunk/drivers/usb/gadget/inode.c b/trunk/drivers/usb/gadget/inode.c index bf0f6520c6df..c44367fea185 100644 --- a/trunk/drivers/usb/gadget/inode.c +++ b/trunk/drivers/usb/gadget/inode.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/w1/masters/ds2482.c b/trunk/drivers/w1/masters/ds2482.c index 406caa6a71cb..df52cb355f7d 100644 --- a/trunk/drivers/w1/masters/ds2482.c +++ b/trunk/drivers/w1/masters/ds2482.c @@ -23,6 +23,19 @@ #include "../w1.h" #include "../w1_int.h" +/** + * Address is selected using 2 pins, resulting in 4 possible addresses. + * 0x18, 0x19, 0x1a, 0x1b + * However, the chip cannot be detected without doing an i2c write, + * so use the force module parameter. + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +/** + * Insmod parameters + */ +I2C_CLIENT_INSMOD_1(ds2482); + /** * The DS2482 registers - there are 3 registers that are addressed by a read * pointer. The read pointer is set by the last command executed. @@ -83,6 +96,8 @@ static const u8 ds2482_chan_rd[8] = static int ds2482_probe(struct i2c_client *client, const struct i2c_device_id *id); +static int ds2482_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); static int ds2482_remove(struct i2c_client *client); @@ -102,6 +117,8 @@ static struct i2c_driver ds2482_driver = { .probe = ds2482_probe, .remove = ds2482_remove, .id_table = ds2482_id, + .detect = ds2482_detect, + .address_data = &addr_data, }; /* @@ -408,6 +425,19 @@ static u8 ds2482_w1_reset_bus(void *data) } +static int ds2482_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) +{ + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_BYTE_DATA | + I2C_FUNC_SMBUS_BYTE)) + return -ENODEV; + + strlcpy(info->type, "ds2482", I2C_NAME_SIZE); + + return 0; +} + static int ds2482_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -416,11 +446,6 @@ static int ds2482_probe(struct i2c_client *client, int temp1; int idx; - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_WRITE_BYTE_DATA | - I2C_FUNC_SMBUS_BYTE)) - return -ENODEV; - if (!(data = kzalloc(sizeof(struct ds2482_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; diff --git a/trunk/drivers/xen/xenfs/xenbus.c b/trunk/drivers/xen/xenfs/xenbus.c index 6c4269b836b7..a9592d981b10 100644 --- a/trunk/drivers/xen/xenfs/xenbus.c +++ b/trunk/drivers/xen/xenfs/xenbus.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/anon_inodes.c b/trunk/fs/anon_inodes.c index 2ca7a7cafdbf..d11c51fc2a3f 100644 --- a/trunk/fs/anon_inodes.c +++ b/trunk/fs/anon_inodes.c @@ -8,10 +8,8 @@ * */ -#include #include #include -#include #include #include #include diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index 402cb84a92a1..76738005c8e8 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -249,7 +249,6 @@ void bio_free(struct bio *bio, struct bio_set *bs) mempool_free(p, bs->bio_pool); } -EXPORT_SYMBOL(bio_free); void bio_init(struct bio *bio) { @@ -258,7 +257,6 @@ void bio_init(struct bio *bio) bio->bi_comp_cpu = -1; atomic_set(&bio->bi_cnt, 1); } -EXPORT_SYMBOL(bio_init); /** * bio_alloc_bioset - allocate a bio for I/O @@ -313,7 +311,6 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) mempool_free(p, bs->bio_pool); return NULL; } -EXPORT_SYMBOL(bio_alloc_bioset); static void bio_fs_destructor(struct bio *bio) { @@ -340,7 +337,6 @@ struct bio *bio_alloc(gfp_t gfp_mask, int nr_iovecs) return bio; } -EXPORT_SYMBOL(bio_alloc); static void bio_kmalloc_destructor(struct bio *bio) { @@ -384,7 +380,6 @@ struct bio *bio_kmalloc(gfp_t gfp_mask, int nr_iovecs) return bio; } -EXPORT_SYMBOL(bio_kmalloc); void zero_fill_bio(struct bio *bio) { @@ -421,7 +416,6 @@ void bio_put(struct bio *bio) bio->bi_destructor(bio); } } -EXPORT_SYMBOL(bio_put); inline int bio_phys_segments(struct request_queue *q, struct bio *bio) { @@ -430,7 +424,6 @@ inline int bio_phys_segments(struct request_queue *q, struct bio *bio) return bio->bi_phys_segments; } -EXPORT_SYMBOL(bio_phys_segments); /** * __bio_clone - clone a bio @@ -458,7 +451,6 @@ void __bio_clone(struct bio *bio, struct bio *bio_src) bio->bi_size = bio_src->bi_size; bio->bi_idx = bio_src->bi_idx; } -EXPORT_SYMBOL(__bio_clone); /** * bio_clone - clone a bio @@ -490,7 +482,6 @@ struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask) return b; } -EXPORT_SYMBOL(bio_clone); /** * bio_get_nr_vecs - return approx number of vecs @@ -514,7 +505,6 @@ int bio_get_nr_vecs(struct block_device *bdev) return nr_pages; } -EXPORT_SYMBOL(bio_get_nr_vecs); static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page *page, unsigned int len, unsigned int offset, @@ -645,7 +635,6 @@ int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page *page, return __bio_add_page(q, bio, page, len, offset, queue_max_hw_sectors(q)); } -EXPORT_SYMBOL(bio_add_pc_page); /** * bio_add_page - attempt to add page to bio @@ -666,7 +655,6 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len, struct request_queue *q = bdev_get_queue(bio->bi_bdev); return __bio_add_page(q, bio, page, len, offset, queue_max_sectors(q)); } -EXPORT_SYMBOL(bio_add_page); struct bio_map_data { struct bio_vec *iovecs; @@ -788,7 +776,6 @@ int bio_uncopy_user(struct bio *bio) bio_put(bio); return ret; } -EXPORT_SYMBOL(bio_uncopy_user); /** * bio_copy_user_iov - copy user data to bio @@ -933,7 +920,6 @@ struct bio *bio_copy_user(struct request_queue *q, struct rq_map_data *map_data, return bio_copy_user_iov(q, map_data, &iov, 1, write_to_vm, gfp_mask); } -EXPORT_SYMBOL(bio_copy_user); static struct bio *__bio_map_user_iov(struct request_queue *q, struct block_device *bdev, @@ -1064,7 +1050,6 @@ struct bio *bio_map_user(struct request_queue *q, struct block_device *bdev, return bio_map_user_iov(q, bdev, &iov, 1, write_to_vm, gfp_mask); } -EXPORT_SYMBOL(bio_map_user); /** * bio_map_user_iov - map user sg_iovec table into bio @@ -1132,13 +1117,13 @@ void bio_unmap_user(struct bio *bio) __bio_unmap_user(bio); bio_put(bio); } -EXPORT_SYMBOL(bio_unmap_user); static void bio_map_kern_endio(struct bio *bio, int err) { bio_put(bio); } + static struct bio *__bio_map_kern(struct request_queue *q, void *data, unsigned int len, gfp_t gfp_mask) { @@ -1204,7 +1189,6 @@ struct bio *bio_map_kern(struct request_queue *q, void *data, unsigned int len, bio_put(bio); return ERR_PTR(-EINVAL); } -EXPORT_SYMBOL(bio_map_kern); static void bio_copy_kern_endio(struct bio *bio, int err) { @@ -1266,7 +1250,6 @@ struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len, return bio; } -EXPORT_SYMBOL(bio_copy_kern); /* * bio_set_pages_dirty() and bio_check_pages_dirty() are support functions @@ -1417,7 +1400,6 @@ void bio_endio(struct bio *bio, int error) if (bio->bi_end_io) bio->bi_end_io(bio, error); } -EXPORT_SYMBOL(bio_endio); void bio_pair_release(struct bio_pair *bp) { @@ -1428,7 +1410,6 @@ void bio_pair_release(struct bio_pair *bp) mempool_free(bp, bp->bio2.bi_private); } } -EXPORT_SYMBOL(bio_pair_release); static void bio_pair_end_1(struct bio *bi, int err) { @@ -1496,7 +1477,6 @@ struct bio_pair *bio_split(struct bio *bi, int first_sectors) return bp; } -EXPORT_SYMBOL(bio_split); /** * bio_sector_offset - Find hardware sector offset in bio @@ -1567,7 +1547,6 @@ void bioset_free(struct bio_set *bs) kfree(bs); } -EXPORT_SYMBOL(bioset_free); /** * bioset_create - Create a bio_set @@ -1613,7 +1592,6 @@ struct bio_set *bioset_create(unsigned int pool_size, unsigned int front_pad) bioset_free(bs); return NULL; } -EXPORT_SYMBOL(bioset_create); static void __init biovec_init_slabs(void) { @@ -1658,4 +1636,29 @@ static int __init init_bio(void) return 0; } + subsys_initcall(init_bio); + +EXPORT_SYMBOL(bio_alloc); +EXPORT_SYMBOL(bio_kmalloc); +EXPORT_SYMBOL(bio_put); +EXPORT_SYMBOL(bio_free); +EXPORT_SYMBOL(bio_endio); +EXPORT_SYMBOL(bio_init); +EXPORT_SYMBOL(__bio_clone); +EXPORT_SYMBOL(bio_clone); +EXPORT_SYMBOL(bio_phys_segments); +EXPORT_SYMBOL(bio_add_page); +EXPORT_SYMBOL(bio_add_pc_page); +EXPORT_SYMBOL(bio_get_nr_vecs); +EXPORT_SYMBOL(bio_map_user); +EXPORT_SYMBOL(bio_unmap_user); +EXPORT_SYMBOL(bio_map_kern); +EXPORT_SYMBOL(bio_copy_kern); +EXPORT_SYMBOL(bio_pair_release); +EXPORT_SYMBOL(bio_split); +EXPORT_SYMBOL(bio_copy_user); +EXPORT_SYMBOL(bio_uncopy_user); +EXPORT_SYMBOL(bioset_create); +EXPORT_SYMBOL(bioset_free); +EXPORT_SYMBOL(bio_alloc_bioset); diff --git a/trunk/fs/coda/psdev.c b/trunk/fs/coda/psdev.c index be4392ca2098..0376ac66c44a 100644 --- a/trunk/fs/coda/psdev.c +++ b/trunk/fs/coda/psdev.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/partitions/check.c b/trunk/fs/partitions/check.c index f38fee0311a7..7b685e10cbad 100644 --- a/trunk/fs/partitions/check.c +++ b/trunk/fs/partitions/check.c @@ -248,11 +248,19 @@ ssize_t part_stat_show(struct device *dev, part_stat_read(p, merges[WRITE]), (unsigned long long)part_stat_read(p, sectors[WRITE]), jiffies_to_msecs(part_stat_read(p, ticks[WRITE])), - p->in_flight, + part_in_flight(p), jiffies_to_msecs(part_stat_read(p, io_ticks)), jiffies_to_msecs(part_stat_read(p, time_in_queue))); } +ssize_t part_inflight_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct hd_struct *p = dev_to_part(dev); + + return sprintf(buf, "%8u %8u\n", p->in_flight[0], p->in_flight[1]); +} + #ifdef CONFIG_FAIL_MAKE_REQUEST ssize_t part_fail_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -281,6 +289,7 @@ static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL); static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL); static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); +static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL); #ifdef CONFIG_FAIL_MAKE_REQUEST static struct device_attribute dev_attr_fail = __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store); @@ -292,6 +301,7 @@ static struct attribute *part_attrs[] = { &dev_attr_size.attr, &dev_attr_alignment_offset.attr, &dev_attr_stat.attr, + &dev_attr_inflight.attr, #ifdef CONFIG_FAIL_MAKE_REQUEST &dev_attr_fail.attr, #endif diff --git a/trunk/fs/select.c b/trunk/fs/select.c index fd38ce2e32e3..a201fc370223 100644 --- a/trunk/fs/select.c +++ b/trunk/fs/select.c @@ -15,7 +15,6 @@ */ #include -#include #include #include #include diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h index 25119041e034..e23a86cae5ac 100644 --- a/trunk/include/linux/blkdev.h +++ b/trunk/include/linux/blkdev.h @@ -82,6 +82,7 @@ enum rq_cmd_type_bits { enum { REQ_LB_OP_EJECT = 0x40, /* eject request */ REQ_LB_OP_FLUSH = 0x41, /* flush request */ + REQ_LB_OP_DISCARD = 0x42, /* discard sectors */ }; /* @@ -260,6 +261,7 @@ typedef void (request_fn_proc) (struct request_queue *q); typedef int (make_request_fn) (struct request_queue *q, struct bio *bio); typedef int (prep_rq_fn) (struct request_queue *, struct request *); typedef void (unplug_fn) (struct request_queue *); +typedef int (prepare_discard_fn) (struct request_queue *, struct request *); struct bio_vec; struct bvec_merge_data { @@ -311,7 +313,6 @@ struct queue_limits { unsigned int alignment_offset; unsigned int io_min; unsigned int io_opt; - unsigned int max_discard_sectors; unsigned short logical_block_size; unsigned short max_hw_segments; @@ -339,6 +340,7 @@ struct request_queue make_request_fn *make_request_fn; prep_rq_fn *prep_rq_fn; unplug_fn *unplug_fn; + prepare_discard_fn *prepare_discard_fn; merge_bvec_fn *merge_bvec_fn; prepare_flush_fn *prepare_flush_fn; softirq_done_fn *softirq_done_fn; @@ -458,7 +460,6 @@ struct request_queue #define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */ #define QUEUE_FLAG_IO_STAT 15 /* do IO stats */ #define QUEUE_FLAG_CQ 16 /* hardware does queuing */ -#define QUEUE_FLAG_DISCARD 17 /* supports DISCARD */ #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ (1 << QUEUE_FLAG_CLUSTER) | \ @@ -590,7 +591,6 @@ enum { #define blk_queue_flushing(q) ((q)->ordseq) #define blk_queue_stackable(q) \ test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags) -#define blk_queue_discard(q) test_bit(QUEUE_FLAG_DISCARD, &(q)->queue_flags) #define blk_fs_request(rq) ((rq)->cmd_type == REQ_TYPE_FS) #define blk_pc_request(rq) ((rq)->cmd_type == REQ_TYPE_BLOCK_PC) @@ -929,8 +929,6 @@ extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int); extern void blk_queue_max_phys_segments(struct request_queue *, unsigned short); extern void blk_queue_max_hw_segments(struct request_queue *, unsigned short); extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); -extern void blk_queue_max_discard_sectors(struct request_queue *q, - unsigned int max_discard_sectors); extern void blk_queue_logical_block_size(struct request_queue *, unsigned short); extern void blk_queue_physical_block_size(struct request_queue *, unsigned short); extern void blk_queue_alignment_offset(struct request_queue *q, @@ -957,6 +955,7 @@ extern void blk_queue_merge_bvec(struct request_queue *, merge_bvec_fn *); extern void blk_queue_dma_alignment(struct request_queue *, int); extern void blk_queue_update_dma_alignment(struct request_queue *, int); extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *); +extern void blk_queue_set_discard(struct request_queue *, prepare_discard_fn *); extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *); extern void blk_queue_rq_timeout(struct request_queue *, unsigned int); extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); @@ -1081,37 +1080,25 @@ static inline unsigned int queue_physical_block_size(struct request_queue *q) return q->limits.physical_block_size; } -static inline int bdev_physical_block_size(struct block_device *bdev) -{ - return queue_physical_block_size(bdev_get_queue(bdev)); -} - static inline unsigned int queue_io_min(struct request_queue *q) { return q->limits.io_min; } -static inline int bdev_io_min(struct block_device *bdev) -{ - return queue_io_min(bdev_get_queue(bdev)); -} - static inline unsigned int queue_io_opt(struct request_queue *q) { return q->limits.io_opt; } -static inline int bdev_io_opt(struct block_device *bdev) -{ - return queue_io_opt(bdev_get_queue(bdev)); -} - static inline int queue_alignment_offset(struct request_queue *q) { - if (q->limits.misaligned) + if (q && q->limits.misaligned) return -1; - return q->limits.alignment_offset; + if (q && q->limits.alignment_offset) + return q->limits.alignment_offset; + + return 0; } static inline int queue_sector_alignment_offset(struct request_queue *q, @@ -1121,19 +1108,6 @@ static inline int queue_sector_alignment_offset(struct request_queue *q, & (q->limits.io_min - 1); } -static inline int bdev_alignment_offset(struct block_device *bdev) -{ - struct request_queue *q = bdev_get_queue(bdev); - - if (q->limits.misaligned) - return -1; - - if (bdev != bdev->bd_contains) - return bdev->bd_part->alignment_offset; - - return q->limits.alignment_offset; -} - static inline int queue_dma_alignment(struct request_queue *q) { return q ? q->dma_alignment : 511; @@ -1172,11 +1146,7 @@ static inline void put_dev_sector(Sector p) } struct work_struct; -struct delayed_work; int kblockd_schedule_work(struct request_queue *q, struct work_struct *work); -int kblockd_schedule_delayed_work(struct request_queue *q, - struct delayed_work *work, - unsigned long delay); #define MODULE_ALIAS_BLOCKDEV(major,minor) \ MODULE_ALIAS("block-major-" __stringify(major) "-" __stringify(minor)) diff --git a/trunk/include/linux/blktrace_api.h b/trunk/include/linux/blktrace_api.h index 3b73b9992b26..7e4350ece0f8 100644 --- a/trunk/include/linux/blktrace_api.h +++ b/trunk/include/linux/blktrace_api.h @@ -198,7 +198,6 @@ extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, char __user *arg); extern int blk_trace_startstop(struct request_queue *q, int start); extern int blk_trace_remove(struct request_queue *q); -extern void blk_trace_remove_sysfs(struct device *dev); extern int blk_trace_init_sysfs(struct device *dev); extern struct attribute_group blk_trace_attr_group; @@ -212,7 +211,6 @@ extern struct attribute_group blk_trace_attr_group; # define blk_trace_startstop(q, start) (-ENOTTY) # define blk_trace_remove(q) (-ENOTTY) # define blk_add_trace_msg(q, fmt, ...) do { } while (0) -# define blk_trace_remove_sysfs(dev) do { } while (0) static inline int blk_trace_init_sysfs(struct device *dev) { return 0; diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 2620a8c63571..a1e6899d4b6c 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -300,10 +300,6 @@ struct inodes_stat_t { #define BLKTRACESTOP _IO(0x12,117) #define BLKTRACETEARDOWN _IO(0x12,118) #define BLKDISCARD _IO(0x12,119) -#define BLKIOMIN _IO(0x12,120) -#define BLKIOOPT _IO(0x12,121) -#define BLKALIGNOFF _IO(0x12,122) -#define BLKPBSZGET _IO(0x12,123) #define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ #define FIBMAP _IO(0x00,1) /* bmap access */ diff --git a/trunk/include/linux/genhd.h b/trunk/include/linux/genhd.h index 7beaa21b3880..297df45ffd0a 100644 --- a/trunk/include/linux/genhd.h +++ b/trunk/include/linux/genhd.h @@ -98,7 +98,7 @@ struct hd_struct { int make_it_fail; #endif unsigned long stamp; - int in_flight; + int in_flight[2]; #ifdef CONFIG_SMP struct disk_stats *dkstats; #else @@ -322,18 +322,23 @@ static inline void free_part_stats(struct hd_struct *part) #define part_stat_sub(cpu, gendiskp, field, subnd) \ part_stat_add(cpu, gendiskp, field, -subnd) -static inline void part_inc_in_flight(struct hd_struct *part) +static inline void part_inc_in_flight(struct hd_struct *part, int rw) { - part->in_flight++; + part->in_flight[rw]++; if (part->partno) - part_to_disk(part)->part0.in_flight++; + part_to_disk(part)->part0.in_flight[rw]++; } -static inline void part_dec_in_flight(struct hd_struct *part) +static inline void part_dec_in_flight(struct hd_struct *part, int rw) { - part->in_flight--; + part->in_flight[rw]--; if (part->partno) - part_to_disk(part)->part0.in_flight--; + part_to_disk(part)->part0.in_flight[rw]--; +} + +static inline int part_in_flight(struct hd_struct *part) +{ + return part->in_flight[0] + part->in_flight[1]; } /* block/blk-core.c */ @@ -546,6 +551,8 @@ extern ssize_t part_size_show(struct device *dev, struct device_attribute *attr, char *buf); extern ssize_t part_stat_show(struct device *dev, struct device_attribute *attr, char *buf); +extern ssize_t part_inflight_show(struct device *dev, + struct device_attribute *attr, char *buf); #ifdef CONFIG_FAIL_MAKE_REQUEST extern ssize_t part_fail_show(struct device *dev, struct device_attribute *attr, char *buf); diff --git a/trunk/include/linux/poll.h b/trunk/include/linux/poll.h index 6673743946f7..fa287f25138d 100644 --- a/trunk/include/linux/poll.h +++ b/trunk/include/linux/poll.h @@ -6,10 +6,10 @@ #ifdef __KERNEL__ #include -#include #include #include #include +#include #include /* ~832 bytes of stack space used max in sys_select/sys_poll before allocating diff --git a/trunk/include/trace/events/block.h b/trunk/include/trace/events/block.h index 00405b5f624a..d86af94691c2 100644 --- a/trunk/include/trace/events/block.h +++ b/trunk/include/trace/events/block.h @@ -488,39 +488,6 @@ TRACE_EVENT(block_remap, (unsigned long long)__entry->old_sector) ); -TRACE_EVENT(block_rq_remap, - - TP_PROTO(struct request_queue *q, struct request *rq, dev_t dev, - sector_t from), - - TP_ARGS(q, rq, dev, from), - - TP_STRUCT__entry( - __field( dev_t, dev ) - __field( sector_t, sector ) - __field( unsigned int, nr_sector ) - __field( dev_t, old_dev ) - __field( sector_t, old_sector ) - __array( char, rwbs, 6 ) - ), - - TP_fast_assign( - __entry->dev = disk_devt(rq->rq_disk); - __entry->sector = blk_rq_pos(rq); - __entry->nr_sector = blk_rq_sectors(rq); - __entry->old_dev = dev; - __entry->old_sector = from; - blk_fill_rwbs_rq(__entry->rwbs, rq); - ), - - TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu", - MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs, - (unsigned long long)__entry->sector, - __entry->nr_sector, - MAJOR(__entry->old_dev), MINOR(__entry->old_dev), - (unsigned long long)__entry->old_sector) -); - #endif /* _TRACE_BLOCK_H */ /* This part must be outside protection */ diff --git a/trunk/kernel/hrtimer.c b/trunk/kernel/hrtimer.c index 3e1c36e7998f..6d7020490f94 100644 --- a/trunk/kernel/hrtimer.c +++ b/trunk/kernel/hrtimer.c @@ -726,6 +726,8 @@ static int hrtimer_switch_to_hres(void) /* "Retrigger" the interrupt to get things going */ retrigger_next_event(NULL); local_irq_restore(flags); + printk(KERN_DEBUG "Switched to high resolution mode on CPU %d\n", + smp_processor_id()); return 1; } diff --git a/trunk/kernel/perf_event.c b/trunk/kernel/perf_event.c index e491fb087939..0f86feb6db0c 100644 --- a/trunk/kernel/perf_event.c +++ b/trunk/kernel/perf_event.c @@ -1030,10 +1030,14 @@ void __perf_event_sched_out(struct perf_event_context *ctx, update_context_time(ctx); perf_disable(); - if (ctx->nr_active) - list_for_each_entry(event, &ctx->group_list, group_entry) - group_sched_out(event, cpuctx, ctx); - + if (ctx->nr_active) { + list_for_each_entry(event, &ctx->group_list, group_entry) { + if (event != event->group_leader) + event_sched_out(event, cpuctx, ctx); + else + group_sched_out(event, cpuctx, ctx); + } + } perf_enable(); out: spin_unlock(&ctx->lock); @@ -1254,8 +1258,12 @@ __perf_event_sched_in(struct perf_event_context *ctx, if (event->cpu != -1 && event->cpu != cpu) continue; - if (group_can_go_on(event, cpuctx, 1)) - group_sched_in(event, cpuctx, ctx, cpu); + if (event != event->group_leader) + event_sched_in(event, cpuctx, ctx, cpu); + else { + if (group_can_go_on(event, cpuctx, 1)) + group_sched_in(event, cpuctx, ctx, cpu); + } /* * If this pinned group hasn't been scheduled, @@ -1283,9 +1291,15 @@ __perf_event_sched_in(struct perf_event_context *ctx, if (event->cpu != -1 && event->cpu != cpu) continue; - if (group_can_go_on(event, cpuctx, can_add_hw)) - if (group_sched_in(event, cpuctx, ctx, cpu)) + if (event != event->group_leader) { + if (event_sched_in(event, cpuctx, ctx, cpu)) can_add_hw = 0; + } else { + if (group_can_go_on(event, cpuctx, can_add_hw)) { + if (group_sched_in(event, cpuctx, ctx, cpu)) + can_add_hw = 0; + } + } } perf_enable(); out: @@ -4767,7 +4781,9 @@ int perf_event_init_task(struct task_struct *child) * We dont have to disable NMIs - we are only looking at * the list, not manipulating it: */ - list_for_each_entry(event, &parent_ctx->group_list, group_entry) { + list_for_each_entry_rcu(event, &parent_ctx->event_list, event_entry) { + if (event != event->group_leader) + continue; if (!event->attr.inherit) { inherited_all = 0; diff --git a/trunk/kernel/trace/blktrace.c b/trunk/kernel/trace/blktrace.c index d9d6206e0b14..3eb159c277c8 100644 --- a/trunk/kernel/trace/blktrace.c +++ b/trunk/kernel/trace/blktrace.c @@ -855,37 +855,6 @@ static void blk_add_trace_remap(struct request_queue *q, struct bio *bio, sizeof(r), &r); } -/** - * blk_add_trace_rq_remap - Add a trace for a request-remap operation - * @q: queue the io is for - * @rq: the source request - * @dev: target device - * @from: source sector - * - * Description: - * Device mapper remaps request to other devices. - * Add a trace for that action. - * - **/ -static void blk_add_trace_rq_remap(struct request_queue *q, - struct request *rq, dev_t dev, - sector_t from) -{ - struct blk_trace *bt = q->blk_trace; - struct blk_io_trace_remap r; - - if (likely(!bt)) - return; - - r.device_from = cpu_to_be32(dev); - r.device_to = cpu_to_be32(disk_devt(rq->rq_disk)); - r.sector_from = cpu_to_be64(from); - - __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq), - rq_data_dir(rq), BLK_TA_REMAP, !!rq->errors, - sizeof(r), &r); -} - /** * blk_add_driver_data - Add binary message with driver-specific data * @q: queue the io is for @@ -953,13 +922,10 @@ static void blk_register_tracepoints(void) WARN_ON(ret); ret = register_trace_block_remap(blk_add_trace_remap); WARN_ON(ret); - ret = register_trace_block_rq_remap(blk_add_trace_rq_remap); - WARN_ON(ret); } static void blk_unregister_tracepoints(void) { - unregister_trace_block_rq_remap(blk_add_trace_rq_remap); unregister_trace_block_remap(blk_add_trace_remap); unregister_trace_block_split(blk_add_trace_split); unregister_trace_block_unplug_io(blk_add_trace_unplug_io); @@ -1691,11 +1657,6 @@ int blk_trace_init_sysfs(struct device *dev) return sysfs_create_group(&dev->kobj, &blk_trace_attr_group); } -void blk_trace_remove_sysfs(struct device *dev) -{ - sysfs_remove_group(&dev->kobj, &blk_trace_attr_group); -} - #endif /* CONFIG_BLK_DEV_IO_TRACE */ #ifdef CONFIG_EVENT_TRACING diff --git a/trunk/kernel/trace/ftrace.c b/trunk/kernel/trace/ftrace.c index 3724756e41ca..46592feab5a6 100644 --- a/trunk/kernel/trace/ftrace.c +++ b/trunk/kernel/trace/ftrace.c @@ -225,11 +225,7 @@ static void ftrace_update_pid_func(void) if (ftrace_trace_function == ftrace_stub) return; -#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST func = ftrace_trace_function; -#else - func = __ftrace_trace_function; -#endif if (ftrace_pid_trace) { set_ftrace_pid_function(func); diff --git a/trunk/kernel/trace/kmemtrace.c b/trunk/kernel/trace/kmemtrace.c index a91da69f153a..81b1645c8549 100644 --- a/trunk/kernel/trace/kmemtrace.c +++ b/trunk/kernel/trace/kmemtrace.c @@ -501,7 +501,7 @@ static int __init init_kmem_tracer(void) return 1; } - if (register_tracer(&kmem_tracer) != 0) { + if (!register_tracer(&kmem_tracer)) { pr_warning("Warning: could not register the kmem tracer\n"); return 1; } diff --git a/trunk/mm/swapfile.c b/trunk/mm/swapfile.c index a1bc6b9af9a2..4de7f02f820b 100644 --- a/trunk/mm/swapfile.c +++ b/trunk/mm/swapfile.c @@ -1974,14 +1974,12 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) goto bad_swap; } - if (p->bdev) { - if (blk_queue_nonrot(bdev_get_queue(p->bdev))) { - p->flags |= SWP_SOLIDSTATE; - p->cluster_next = 1 + (random32() % p->highest_bit); - } - if (discard_swap(p) == 0) - p->flags |= SWP_DISCARDABLE; + if (blk_queue_nonrot(bdev_get_queue(p->bdev))) { + p->flags |= SWP_SOLIDSTATE; + p->cluster_next = 1 + (random32() % p->highest_bit); } + if (discard_swap(p) == 0) + p->flags |= SWP_DISCARDABLE; mutex_lock(&swapon_mutex); spin_lock(&swap_lock); diff --git a/trunk/net/rfkill/core.c b/trunk/net/rfkill/core.c index ba2efb960c60..dbeaf2983822 100644 --- a/trunk/net/rfkill/core.c +++ b/trunk/net/rfkill/core.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/tools/perf/Documentation/perf-timechart.txt b/trunk/tools/perf/Documentation/perf-timechart.txt index a7910099d6fd..1c2ed3090cce 100644 --- a/trunk/tools/perf/Documentation/perf-timechart.txt +++ b/trunk/tools/perf/Documentation/perf-timechart.txt @@ -31,9 +31,6 @@ OPTIONS -w:: --width=:: Select the width of the SVG file (default: 1000) --p:: ---power-only:: - Only output the CPU power section of the diagram SEE ALSO diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile index 5881943f0c34..b5f1953b6144 100644 --- a/trunk/tools/perf/Makefile +++ b/trunk/tools/perf/Makefile @@ -728,7 +728,7 @@ $(BUILT_INS): perf$X common-cmds.h: util/generate-cmdlist.sh command-list.txt common-cmds.h: $(wildcard Documentation/perf-*.txt) - $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@ + $(QUIET_GEN)util/generate-cmdlist.sh > $@+ && mv $@+ $@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh $(QUIET_GEN)$(RM) $@ $@+ && \ diff --git a/trunk/tools/perf/builtin-timechart.c b/trunk/tools/perf/builtin-timechart.c index 702d8fe58fbc..4405681b3134 100644 --- a/trunk/tools/perf/builtin-timechart.c +++ b/trunk/tools/perf/builtin-timechart.c @@ -46,8 +46,6 @@ static u64 turbo_frequency; static u64 first_time, last_time; -static int power_only; - static struct perf_header *header; @@ -549,7 +547,7 @@ static void end_sample_processing(void) u64 cpu; struct power_event *pwr; - for (cpu = 0; cpu <= numcpus; cpu++) { + for (cpu = 0; cpu < numcpus; cpu++) { pwr = malloc(sizeof(struct power_event)); if (!pwr) return; @@ -873,7 +871,7 @@ static int determine_display_tasks(u64 threshold) /* no exit marker, task kept running to the end */ if (p->end_time == 0) p->end_time = last_time; - if (p->total_time >= threshold && !power_only) + if (p->total_time >= threshold) p->display = 1; c = p->all; @@ -884,7 +882,7 @@ static int determine_display_tasks(u64 threshold) if (c->start_time == 1) c->start_time = first_time; - if (c->total_time >= threshold && !power_only) { + if (c->total_time >= threshold) { c->display = 1; count++; } @@ -1136,8 +1134,6 @@ static const struct option options[] = { "output file name"), OPT_INTEGER('w', "width", &svg_page_width, "page width"), - OPT_BOOLEAN('p', "power-only", &power_only, - "output power data only"), OPT_END() }; diff --git a/trunk/tools/perf/builtin-top.c b/trunk/tools/perf/builtin-top.c index 37512e936235..1ca88896eee4 100644 --- a/trunk/tools/perf/builtin-top.c +++ b/trunk/tools/perf/builtin-top.c @@ -782,7 +782,6 @@ static const char *skip_symbols[] = { "exit_idle", "mwait_idle", "mwait_idle_with_hints", - "poll_idle", "ppc64_runlatch_off", "pseries_dedicated_idle_sleep", NULL diff --git a/trunk/tools/perf/util/svghelper.c b/trunk/tools/perf/util/svghelper.c index 856655d8b0b8..a778fd0f4ae4 100644 --- a/trunk/tools/perf/util/svghelper.c +++ b/trunk/tools/perf/util/svghelper.c @@ -28,7 +28,7 @@ static u64 turbo_frequency, max_freq; int svg_page_width = 1000; -#define MIN_TEXT_SIZE 0.01 +#define MIN_TEXT_SIZE 0.001 static u64 total_height; static FILE *svgfile; @@ -217,18 +217,6 @@ static char *cpu_model(void) } fclose(file); } - - /* CPU type */ - file = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies", "r"); - if (file) { - while (fgets(buf, 255, file)) { - unsigned int freq; - freq = strtoull(buf, NULL, 10); - if (freq > max_freq) - max_freq = freq; - } - fclose(file); - } return cpu_m; }