diff options
123 files changed, 2433 insertions, 1016 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss index 0a92a7c93a62..4f29e5f1ebfa 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss +++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss | |||
| @@ -31,3 +31,31 @@ Date: March 2009 | |||
| 31 | Kernel Version: 2.6.30 | 31 | Kernel Version: 2.6.30 |
| 32 | Contact: iss_storagedev@hp.com | 32 | Contact: iss_storagedev@hp.com |
| 33 | Description: A symbolic link to /sys/block/cciss!cXdY | 33 | Description: A symbolic link to /sys/block/cciss!cXdY |
| 34 | |||
| 35 | Where: /sys/bus/pci/devices/<dev>/ccissX/rescan | ||
| 36 | Date: August 2009 | ||
| 37 | Kernel Version: 2.6.31 | ||
| 38 | Contact: iss_storagedev@hp.com | ||
| 39 | Description: Kicks of a rescan of the controller to discover logical | ||
| 40 | drive topology changes. | ||
| 41 | |||
| 42 | Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/lunid | ||
| 43 | Date: August 2009 | ||
| 44 | Kernel Version: 2.6.31 | ||
| 45 | Contact: iss_storagedev@hp.com | ||
| 46 | Description: Displays the 8-byte LUN ID used to address logical | ||
| 47 | drive Y of controller X. | ||
| 48 | |||
| 49 | Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/raid_level | ||
| 50 | Date: August 2009 | ||
| 51 | Kernel Version: 2.6.31 | ||
| 52 | Contact: iss_storagedev@hp.com | ||
| 53 | Description: Displays the RAID level of logical drive Y of | ||
| 54 | controller X. | ||
| 55 | |||
| 56 | Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/usage_count | ||
| 57 | Date: August 2009 | ||
| 58 | Kernel Version: 2.6.31 | ||
| 59 | Contact: iss_storagedev@hp.com | ||
| 60 | Description: Displays the usage count (number of opens) of logical drive Y | ||
| 61 | of controller X. | ||
diff --git a/Documentation/hwmon/ltc4215 b/Documentation/hwmon/ltc4215 index 2e6a21eb656c..c196a1846259 100644 --- a/Documentation/hwmon/ltc4215 +++ b/Documentation/hwmon/ltc4215 | |||
| @@ -22,12 +22,13 @@ Usage Notes | |||
| 22 | ----------- | 22 | ----------- |
| 23 | 23 | ||
| 24 | This driver does not probe for LTC4215 devices, due to the fact that some | 24 | This driver does not probe for LTC4215 devices, due to the fact that some |
| 25 | of the possible addresses are unfriendly to probing. You will need to use | 25 | of the possible addresses are unfriendly to probing. You will have to |
| 26 | the "force" parameter to tell the driver where to find the device. | 26 | instantiate the devices explicitly. |
| 27 | 27 | ||
| 28 | Example: the following will load the driver for an LTC4215 at address 0x44 | 28 | Example: the following will load the driver for an LTC4215 at address 0x44 |
| 29 | on I2C bus #0: | 29 | on I2C bus #0: |
| 30 | $ modprobe ltc4215 force=0,0x44 | 30 | $ modprobe ltc4215 |
| 31 | $ echo ltc4215 0x44 > /sys/bus/i2c/devices/i2c-0/new_device | ||
| 31 | 32 | ||
| 32 | 33 | ||
| 33 | Sysfs entries | 34 | Sysfs entries |
diff --git a/Documentation/hwmon/ltc4245 b/Documentation/hwmon/ltc4245 index bae7a3adc5d8..02838a47d862 100644 --- a/Documentation/hwmon/ltc4245 +++ b/Documentation/hwmon/ltc4245 | |||
| @@ -23,12 +23,13 @@ Usage Notes | |||
| 23 | ----------- | 23 | ----------- |
| 24 | 24 | ||
| 25 | This driver does not probe for LTC4245 devices, due to the fact that some | 25 | This driver does not probe for LTC4245 devices, due to the fact that some |
| 26 | of the possible addresses are unfriendly to probing. You will need to use | 26 | of the possible addresses are unfriendly to probing. You will have to |
| 27 | the "force" parameter to tell the driver where to find the device. | 27 | instantiate the devices explicitly. |
| 28 | 28 | ||
| 29 | Example: the following will load the driver for an LTC4245 at address 0x23 | 29 | Example: the following will load the driver for an LTC4245 at address 0x23 |
| 30 | on I2C bus #1: | 30 | on I2C bus #1: |
| 31 | $ modprobe ltc4245 force=1,0x23 | 31 | $ modprobe ltc4245 |
| 32 | $ echo ltc4245 0x23 > /sys/bus/i2c/devices/i2c-1/new_device | ||
| 32 | 33 | ||
| 33 | 34 | ||
| 34 | Sysfs entries | 35 | Sysfs entries |
diff --git a/Documentation/i2c/instantiating-devices b/Documentation/i2c/instantiating-devices index c740b7b41088..e89490270aba 100644 --- a/Documentation/i2c/instantiating-devices +++ b/Documentation/i2c/instantiating-devices | |||
| @@ -188,7 +188,7 @@ segment, the address is sufficient to uniquely identify the device to be | |||
| 188 | deleted. | 188 | deleted. |
| 189 | 189 | ||
| 190 | Example: | 190 | Example: |
| 191 | # echo eeprom 0x50 > /sys/class/i2c-adapter/i2c-3/new_device | 191 | # echo eeprom 0x50 > /sys/bus/i2c/devices/i2c-3/new_device |
| 192 | 192 | ||
| 193 | While this interface should only be used when in-kernel device declaration | 193 | While this interface should only be used when in-kernel device declaration |
| 194 | can't be done, there is a variety of cases where it can be helpful: | 194 | can't be done, there is a variety of cases where it can be helpful: |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 6fa7292947e5..9107b387e91f 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
| @@ -671,6 +671,7 @@ and is between 256 and 4096 characters. It is defined in the file | |||
| 671 | earlyprintk= [X86,SH,BLACKFIN] | 671 | earlyprintk= [X86,SH,BLACKFIN] |
| 672 | earlyprintk=vga | 672 | earlyprintk=vga |
| 673 | earlyprintk=serial[,ttySn[,baudrate]] | 673 | earlyprintk=serial[,ttySn[,baudrate]] |
| 674 | earlyprintk=ttySn[,baudrate] | ||
| 674 | earlyprintk=dbgp[debugController#] | 675 | earlyprintk=dbgp[debugController#] |
| 675 | 676 | ||
| 676 | Append ",keep" to not disable it when the real console | 677 | Append ",keep" to not disable it when the real console |
diff --git a/Documentation/i2c/chips/eeprom b/Documentation/misc-devices/eeprom index f7e8104b5764..f7e8104b5764 100644 --- a/Documentation/i2c/chips/eeprom +++ b/Documentation/misc-devices/eeprom | |||
diff --git a/Documentation/i2c/chips/max6875 b/Documentation/misc-devices/max6875 index 10ca43cd1a72..1e89ee3ccc1b 100644 --- a/Documentation/i2c/chips/max6875 +++ b/Documentation/misc-devices/max6875 | |||
| @@ -42,10 +42,12 @@ General Remarks | |||
| 42 | 42 | ||
| 43 | Valid addresses for the MAX6875 are 0x50 and 0x52. | 43 | Valid addresses for the MAX6875 are 0x50 and 0x52. |
| 44 | Valid addresses for the MAX6874 are 0x50, 0x52, 0x54 and 0x56. | 44 | Valid addresses for the MAX6874 are 0x50, 0x52, 0x54 and 0x56. |
| 45 | The driver does not probe any address, so you must force the address. | 45 | The driver does not probe any address, so you explicitly instantiate the |
| 46 | devices. | ||
| 46 | 47 | ||
| 47 | Example: | 48 | Example: |
| 48 | $ modprobe max6875 force=0,0x50 | 49 | $ modprobe max6875 |
| 50 | $ echo max6875 0x50 > /sys/bus/i2c/devices/i2c-0/new_device | ||
| 49 | 51 | ||
| 50 | The MAX6874/MAX6875 ignores address bit 0, so this driver attaches to multiple | 52 | The MAX6874/MAX6875 ignores address bit 0, so this driver attaches to multiple |
| 51 | addresses. For example, for address 0x50, it also reserves 0x51. | 53 | addresses. For example, for address 0x50, it also reserves 0x51. |
diff --git a/Documentation/w1/masters/ds2482 b/Documentation/w1/masters/ds2482 index 9210d6fa5024..299b91c7609f 100644 --- a/Documentation/w1/masters/ds2482 +++ b/Documentation/w1/masters/ds2482 | |||
| @@ -24,8 +24,8 @@ General Remarks | |||
| 24 | 24 | ||
| 25 | Valid addresses are 0x18, 0x19, 0x1a, and 0x1b. | 25 | Valid addresses are 0x18, 0x19, 0x1a, and 0x1b. |
| 26 | However, the device cannot be detected without writing to the i2c bus, so no | 26 | However, the device cannot be detected without writing to the i2c bus, so no |
| 27 | detection is done. | 27 | detection is done. You should instantiate the device explicitly. |
| 28 | You should force the device address. | ||
| 29 | 28 | ||
| 30 | $ modprobe ds2482 force=0,0x18 | 29 | $ modprobe ds2482 |
| 30 | $ echo ds2482 0x18 > /sys/bus/i2c/devices/i2c-0/new_device | ||
| 31 | 31 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 737a9b2c532d..09a2028bab7f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -257,6 +257,13 @@ W: http://www.lesswatts.org/projects/acpi/ | |||
| 257 | S: Supported | 257 | S: Supported |
| 258 | F: drivers/acpi/fan.c | 258 | F: drivers/acpi/fan.c |
| 259 | 259 | ||
| 260 | ACPI PROCESSOR AGGREGATOR DRIVER | ||
| 261 | M: Shaohua Li <shaohua.li@intel.com> | ||
| 262 | L: linux-acpi@vger.kernel.org | ||
| 263 | W: http://www.lesswatts.org/projects/acpi/ | ||
| 264 | S: Supported | ||
| 265 | F: drivers/acpi/acpi_pad.c | ||
| 266 | |||
| 260 | ACPI THERMAL DRIVER | 267 | ACPI THERMAL DRIVER |
| 261 | M: Zhang Rui <rui.zhang@intel.com> | 268 | M: Zhang Rui <rui.zhang@intel.com> |
| 262 | L: linux-acpi@vger.kernel.org | 269 | L: linux-acpi@vger.kernel.org |
| @@ -1,7 +1,7 @@ | |||
| 1 | VERSION = 2 | 1 | VERSION = 2 |
| 2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
| 3 | SUBLEVEL = 32 | 3 | SUBLEVEL = 32 |
| 4 | EXTRAVERSION = -rc2 | 4 | EXTRAVERSION = -rc3 |
| 5 | NAME = Man-Eating Seals of Antiquity | 5 | NAME = Man-Eating Seals of Antiquity |
| 6 | 6 | ||
| 7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/m68knommu/kernel/asm-offsets.c b/arch/m68knommu/kernel/asm-offsets.c index 594ee0e657fe..9a8876f715d8 100644 --- a/arch/m68knommu/kernel/asm-offsets.c +++ b/arch/m68knommu/kernel/asm-offsets.c | |||
| @@ -45,25 +45,25 @@ int main(void) | |||
| 45 | DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate)); | 45 | DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate)); |
| 46 | 46 | ||
| 47 | /* offsets into the pt_regs */ | 47 | /* offsets into the pt_regs */ |
| 48 | DEFINE(PT_D0, offsetof(struct pt_regs, d0)); | 48 | DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0)); |
| 49 | DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0)); | 49 | DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0)); |
| 50 | DEFINE(PT_D1, offsetof(struct pt_regs, d1)); | 50 | DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1)); |
| 51 | DEFINE(PT_D2, offsetof(struct pt_regs, d2)); | 51 | DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2)); |
| 52 | DEFINE(PT_D3, offsetof(struct pt_regs, d3)); | 52 | DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3)); |
| 53 | DEFINE(PT_D4, offsetof(struct pt_regs, d4)); | 53 | DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4)); |
| 54 | DEFINE(PT_D5, offsetof(struct pt_regs, d5)); | 54 | DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5)); |
| 55 | DEFINE(PT_A0, offsetof(struct pt_regs, a0)); | 55 | DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0)); |
| 56 | DEFINE(PT_A1, offsetof(struct pt_regs, a1)); | 56 | DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1)); |
| 57 | DEFINE(PT_A2, offsetof(struct pt_regs, a2)); | 57 | DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2)); |
| 58 | DEFINE(PT_PC, offsetof(struct pt_regs, pc)); | 58 | DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc)); |
| 59 | DEFINE(PT_SR, offsetof(struct pt_regs, sr)); | 59 | DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr)); |
| 60 | 60 | ||
| 61 | #ifdef CONFIG_COLDFIRE | 61 | #ifdef CONFIG_COLDFIRE |
| 62 | /* bitfields are a bit difficult */ | 62 | /* bitfields are a bit difficult */ |
| 63 | DEFINE(PT_FORMATVEC, offsetof(struct pt_regs, sr) - 2); | 63 | DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, sr) - 2); |
| 64 | #else | 64 | #else |
| 65 | /* bitfields are a bit difficult */ | 65 | /* bitfields are a bit difficult */ |
| 66 | DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) + 4); | 66 | DEFINE(PT_OFF_VECTOR, offsetof(struct pt_regs, pc) + 4); |
| 67 | #endif | 67 | #endif |
| 68 | 68 | ||
| 69 | /* signal defines */ | 69 | /* signal defines */ |
diff --git a/arch/m68knommu/kernel/entry.S b/arch/m68knommu/kernel/entry.S index f56faa5c9cd9..56043ade3941 100644 --- a/arch/m68knommu/kernel/entry.S +++ b/arch/m68knommu/kernel/entry.S | |||
| @@ -46,7 +46,7 @@ | |||
| 46 | ENTRY(buserr) | 46 | ENTRY(buserr) |
| 47 | SAVE_ALL | 47 | SAVE_ALL |
| 48 | moveq #-1,%d0 | 48 | moveq #-1,%d0 |
| 49 | movel %d0,%sp@(PT_ORIG_D0) | 49 | movel %d0,%sp@(PT_OFF_ORIG_D0) |
| 50 | movel %sp,%sp@- /* stack frame pointer argument */ | 50 | movel %sp,%sp@- /* stack frame pointer argument */ |
| 51 | jsr buserr_c | 51 | jsr buserr_c |
| 52 | addql #4,%sp | 52 | addql #4,%sp |
| @@ -55,7 +55,7 @@ ENTRY(buserr) | |||
| 55 | ENTRY(trap) | 55 | ENTRY(trap) |
| 56 | SAVE_ALL | 56 | SAVE_ALL |
| 57 | moveq #-1,%d0 | 57 | moveq #-1,%d0 |
| 58 | movel %d0,%sp@(PT_ORIG_D0) | 58 | movel %d0,%sp@(PT_OFF_ORIG_D0) |
| 59 | movel %sp,%sp@- /* stack frame pointer argument */ | 59 | movel %sp,%sp@- /* stack frame pointer argument */ |
| 60 | jsr trap_c | 60 | jsr trap_c |
| 61 | addql #4,%sp | 61 | addql #4,%sp |
| @@ -67,7 +67,7 @@ ENTRY(trap) | |||
| 67 | ENTRY(dbginterrupt) | 67 | ENTRY(dbginterrupt) |
| 68 | SAVE_ALL | 68 | SAVE_ALL |
| 69 | moveq #-1,%d0 | 69 | moveq #-1,%d0 |
| 70 | movel %d0,%sp@(PT_ORIG_D0) | 70 | movel %d0,%sp@(PT_OFF_ORIG_D0) |
| 71 | movel %sp,%sp@- /* stack frame pointer argument */ | 71 | movel %sp,%sp@- /* stack frame pointer argument */ |
| 72 | jsr dbginterrupt_c | 72 | jsr dbginterrupt_c |
| 73 | addql #4,%sp | 73 | addql #4,%sp |
diff --git a/arch/m68knommu/mm/init.c b/arch/m68knommu/mm/init.c index b1703c67a4f1..f3236d0b522d 100644 --- a/arch/m68knommu/mm/init.c +++ b/arch/m68knommu/mm/init.c | |||
| @@ -162,7 +162,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) | |||
| 162 | totalram_pages++; | 162 | totalram_pages++; |
| 163 | pages++; | 163 | pages++; |
| 164 | } | 164 | } |
| 165 | printk (KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages); | 165 | printk (KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages * (PAGE_SIZE / 1024)); |
| 166 | } | 166 | } |
| 167 | #endif | 167 | #endif |
| 168 | 168 | ||
diff --git a/arch/m68knommu/platform/5206e/config.c b/arch/m68knommu/platform/5206e/config.c index 0f41ba82a3b5..942397984c66 100644 --- a/arch/m68knommu/platform/5206e/config.c +++ b/arch/m68knommu/platform/5206e/config.c | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | #include <asm/mcfsim.h> | 17 | #include <asm/mcfsim.h> |
| 18 | #include <asm/mcfuart.h> | 18 | #include <asm/mcfuart.h> |
| 19 | #include <asm/mcfdma.h> | 19 | #include <asm/mcfdma.h> |
| 20 | #include <asm/mcfuart.h> | ||
| 21 | 20 | ||
| 22 | /***************************************************************************/ | 21 | /***************************************************************************/ |
| 23 | 22 | ||
diff --git a/arch/m68knommu/platform/68328/entry.S b/arch/m68knommu/platform/68328/entry.S index b1aef72f3baf..9d80d2c42866 100644 --- a/arch/m68knommu/platform/68328/entry.S +++ b/arch/m68knommu/platform/68328/entry.S | |||
| @@ -39,17 +39,17 @@ | |||
| 39 | .globl inthandler7 | 39 | .globl inthandler7 |
| 40 | 40 | ||
| 41 | badsys: | 41 | badsys: |
| 42 | movel #-ENOSYS,%sp@(PT_D0) | 42 | movel #-ENOSYS,%sp@(PT_OFF_D0) |
| 43 | jra ret_from_exception | 43 | jra ret_from_exception |
| 44 | 44 | ||
| 45 | do_trace: | 45 | do_trace: |
| 46 | movel #-ENOSYS,%sp@(PT_D0) /* needed for strace*/ | 46 | movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/ |
| 47 | subql #4,%sp | 47 | subql #4,%sp |
| 48 | SAVE_SWITCH_STACK | 48 | SAVE_SWITCH_STACK |
| 49 | jbsr syscall_trace | 49 | jbsr syscall_trace |
| 50 | RESTORE_SWITCH_STACK | 50 | RESTORE_SWITCH_STACK |
| 51 | addql #4,%sp | 51 | addql #4,%sp |
| 52 | movel %sp@(PT_ORIG_D0),%d1 | 52 | movel %sp@(PT_OFF_ORIG_D0),%d1 |
| 53 | movel #-ENOSYS,%d0 | 53 | movel #-ENOSYS,%d0 |
| 54 | cmpl #NR_syscalls,%d1 | 54 | cmpl #NR_syscalls,%d1 |
| 55 | jcc 1f | 55 | jcc 1f |
| @@ -57,7 +57,7 @@ do_trace: | |||
| 57 | lea sys_call_table, %a0 | 57 | lea sys_call_table, %a0 |
| 58 | jbsr %a0@(%d1) | 58 | jbsr %a0@(%d1) |
| 59 | 59 | ||
| 60 | 1: movel %d0,%sp@(PT_D0) /* save the return value */ | 60 | 1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */ |
| 61 | subql #4,%sp /* dummy return address */ | 61 | subql #4,%sp /* dummy return address */ |
| 62 | SAVE_SWITCH_STACK | 62 | SAVE_SWITCH_STACK |
| 63 | jbsr syscall_trace | 63 | jbsr syscall_trace |
| @@ -75,7 +75,7 @@ ENTRY(system_call) | |||
| 75 | jbsr set_esp0 | 75 | jbsr set_esp0 |
| 76 | addql #4,%sp | 76 | addql #4,%sp |
| 77 | 77 | ||
| 78 | movel %sp@(PT_ORIG_D0),%d0 | 78 | movel %sp@(PT_OFF_ORIG_D0),%d0 |
| 79 | 79 | ||
| 80 | movel %sp,%d1 /* get thread_info pointer */ | 80 | movel %sp,%d1 /* get thread_info pointer */ |
| 81 | andl #-THREAD_SIZE,%d1 | 81 | andl #-THREAD_SIZE,%d1 |
| @@ -88,10 +88,10 @@ ENTRY(system_call) | |||
| 88 | lea sys_call_table,%a0 | 88 | lea sys_call_table,%a0 |
| 89 | movel %a0@(%d0), %a0 | 89 | movel %a0@(%d0), %a0 |
| 90 | jbsr %a0@ | 90 | jbsr %a0@ |
| 91 | movel %d0,%sp@(PT_D0) /* save the return value*/ | 91 | movel %d0,%sp@(PT_OFF_D0) /* save the return value*/ |
| 92 | 92 | ||
| 93 | ret_from_exception: | 93 | ret_from_exception: |
| 94 | btst #5,%sp@(PT_SR) /* check if returning to kernel*/ | 94 | btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/ |
| 95 | jeq Luser_return /* if so, skip resched, signals*/ | 95 | jeq Luser_return /* if so, skip resched, signals*/ |
| 96 | 96 | ||
| 97 | Lkernel_return: | 97 | Lkernel_return: |
| @@ -133,7 +133,7 @@ Lreturn: | |||
| 133 | */ | 133 | */ |
| 134 | inthandler1: | 134 | inthandler1: |
| 135 | SAVE_ALL | 135 | SAVE_ALL |
| 136 | movew %sp@(PT_VECTOR), %d0 | 136 | movew %sp@(PT_OFF_VECTOR), %d0 |
| 137 | and #0x3ff, %d0 | 137 | and #0x3ff, %d0 |
| 138 | 138 | ||
| 139 | movel %sp,%sp@- | 139 | movel %sp,%sp@- |
| @@ -144,7 +144,7 @@ inthandler1: | |||
| 144 | 144 | ||
| 145 | inthandler2: | 145 | inthandler2: |
| 146 | SAVE_ALL | 146 | SAVE_ALL |
| 147 | movew %sp@(PT_VECTOR), %d0 | 147 | movew %sp@(PT_OFF_VECTOR), %d0 |
| 148 | and #0x3ff, %d0 | 148 | and #0x3ff, %d0 |
| 149 | 149 | ||
| 150 | movel %sp,%sp@- | 150 | movel %sp,%sp@- |
| @@ -155,7 +155,7 @@ inthandler2: | |||
| 155 | 155 | ||
| 156 | inthandler3: | 156 | inthandler3: |
| 157 | SAVE_ALL | 157 | SAVE_ALL |
| 158 | movew %sp@(PT_VECTOR), %d0 | 158 | movew %sp@(PT_OFF_VECTOR), %d0 |
| 159 | and #0x3ff, %d0 | 159 | and #0x3ff, %d0 |
| 160 | 160 | ||
| 161 | movel %sp,%sp@- | 161 | movel %sp,%sp@- |
| @@ -166,7 +166,7 @@ inthandler3: | |||
| 166 | 166 | ||
| 167 | inthandler4: | 167 | inthandler4: |
| 168 | SAVE_ALL | 168 | SAVE_ALL |
| 169 | movew %sp@(PT_VECTOR), %d0 | 169 | movew %sp@(PT_OFF_VECTOR), %d0 |
| 170 | and #0x3ff, %d0 | 170 | and #0x3ff, %d0 |
| 171 | 171 | ||
| 172 | movel %sp,%sp@- | 172 | movel %sp,%sp@- |
| @@ -177,7 +177,7 @@ inthandler4: | |||
| 177 | 177 | ||
| 178 | inthandler5: | 178 | inthandler5: |
| 179 | SAVE_ALL | 179 | SAVE_ALL |
| 180 | movew %sp@(PT_VECTOR), %d0 | 180 | movew %sp@(PT_OFF_VECTOR), %d0 |
| 181 | and #0x3ff, %d0 | 181 | and #0x3ff, %d0 |
| 182 | 182 | ||
| 183 | movel %sp,%sp@- | 183 | movel %sp,%sp@- |
| @@ -188,7 +188,7 @@ inthandler5: | |||
| 188 | 188 | ||
| 189 | inthandler6: | 189 | inthandler6: |
| 190 | SAVE_ALL | 190 | SAVE_ALL |
| 191 | movew %sp@(PT_VECTOR), %d0 | 191 | movew %sp@(PT_OFF_VECTOR), %d0 |
| 192 | and #0x3ff, %d0 | 192 | and #0x3ff, %d0 |
| 193 | 193 | ||
| 194 | movel %sp,%sp@- | 194 | movel %sp,%sp@- |
| @@ -199,7 +199,7 @@ inthandler6: | |||
| 199 | 199 | ||
| 200 | inthandler7: | 200 | inthandler7: |
| 201 | SAVE_ALL | 201 | SAVE_ALL |
| 202 | movew %sp@(PT_VECTOR), %d0 | 202 | movew %sp@(PT_OFF_VECTOR), %d0 |
| 203 | and #0x3ff, %d0 | 203 | and #0x3ff, %d0 |
| 204 | 204 | ||
| 205 | movel %sp,%sp@- | 205 | movel %sp,%sp@- |
| @@ -210,7 +210,7 @@ inthandler7: | |||
| 210 | 210 | ||
| 211 | inthandler: | 211 | inthandler: |
| 212 | SAVE_ALL | 212 | SAVE_ALL |
| 213 | movew %sp@(PT_VECTOR), %d0 | 213 | movew %sp@(PT_OFF_VECTOR), %d0 |
| 214 | and #0x3ff, %d0 | 214 | and #0x3ff, %d0 |
| 215 | 215 | ||
| 216 | movel %sp,%sp@- | 216 | movel %sp,%sp@- |
| @@ -224,7 +224,7 @@ ret_from_interrupt: | |||
| 224 | 2: | 224 | 2: |
| 225 | RESTORE_ALL | 225 | RESTORE_ALL |
| 226 | 1: | 226 | 1: |
| 227 | moveb %sp@(PT_SR), %d0 | 227 | moveb %sp@(PT_OFF_SR), %d0 |
| 228 | and #7, %d0 | 228 | and #7, %d0 |
| 229 | jhi 2b | 229 | jhi 2b |
| 230 | 230 | ||
diff --git a/arch/m68knommu/platform/68360/entry.S b/arch/m68knommu/platform/68360/entry.S index 55dfefe38642..6d3460a39cac 100644 --- a/arch/m68knommu/platform/68360/entry.S +++ b/arch/m68knommu/platform/68360/entry.S | |||
| @@ -35,17 +35,17 @@ | |||
| 35 | .globl inthandler | 35 | .globl inthandler |
| 36 | 36 | ||
| 37 | badsys: | 37 | badsys: |
| 38 | movel #-ENOSYS,%sp@(PT_D0) | 38 | movel #-ENOSYS,%sp@(PT_OFF_D0) |
| 39 | jra ret_from_exception | 39 | jra ret_from_exception |
| 40 | 40 | ||
| 41 | do_trace: | 41 | do_trace: |
| 42 | movel #-ENOSYS,%sp@(PT_D0) /* needed for strace*/ | 42 | movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/ |
| 43 | subql #4,%sp | 43 | subql #4,%sp |
| 44 | SAVE_SWITCH_STACK | 44 | SAVE_SWITCH_STACK |
| 45 | jbsr syscall_trace | 45 | jbsr syscall_trace |
| 46 | RESTORE_SWITCH_STACK | 46 | RESTORE_SWITCH_STACK |
| 47 | addql #4,%sp | 47 | addql #4,%sp |
| 48 | movel %sp@(PT_ORIG_D0),%d1 | 48 | movel %sp@(PT_OFF_ORIG_D0),%d1 |
| 49 | movel #-ENOSYS,%d0 | 49 | movel #-ENOSYS,%d0 |
| 50 | cmpl #NR_syscalls,%d1 | 50 | cmpl #NR_syscalls,%d1 |
| 51 | jcc 1f | 51 | jcc 1f |
| @@ -53,7 +53,7 @@ do_trace: | |||
| 53 | lea sys_call_table, %a0 | 53 | lea sys_call_table, %a0 |
| 54 | jbsr %a0@(%d1) | 54 | jbsr %a0@(%d1) |
| 55 | 55 | ||
| 56 | 1: movel %d0,%sp@(PT_D0) /* save the return value */ | 56 | 1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */ |
| 57 | subql #4,%sp /* dummy return address */ | 57 | subql #4,%sp /* dummy return address */ |
| 58 | SAVE_SWITCH_STACK | 58 | SAVE_SWITCH_STACK |
| 59 | jbsr syscall_trace | 59 | jbsr syscall_trace |
| @@ -79,10 +79,10 @@ ENTRY(system_call) | |||
| 79 | lea sys_call_table,%a0 | 79 | lea sys_call_table,%a0 |
| 80 | movel %a0@(%d0), %a0 | 80 | movel %a0@(%d0), %a0 |
| 81 | jbsr %a0@ | 81 | jbsr %a0@ |
| 82 | movel %d0,%sp@(PT_D0) /* save the return value*/ | 82 | movel %d0,%sp@(PT_OFF_D0) /* save the return value*/ |
| 83 | 83 | ||
| 84 | ret_from_exception: | 84 | ret_from_exception: |
| 85 | btst #5,%sp@(PT_SR) /* check if returning to kernel*/ | 85 | btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/ |
| 86 | jeq Luser_return /* if so, skip resched, signals*/ | 86 | jeq Luser_return /* if so, skip resched, signals*/ |
| 87 | 87 | ||
| 88 | Lkernel_return: | 88 | Lkernel_return: |
| @@ -124,7 +124,7 @@ Lreturn: | |||
| 124 | */ | 124 | */ |
| 125 | inthandler: | 125 | inthandler: |
| 126 | SAVE_ALL | 126 | SAVE_ALL |
| 127 | movew %sp@(PT_VECTOR), %d0 | 127 | movew %sp@(PT_OFF_VECTOR), %d0 |
| 128 | and.l #0x3ff, %d0 | 128 | and.l #0x3ff, %d0 |
| 129 | lsr.l #0x02, %d0 | 129 | lsr.l #0x02, %d0 |
| 130 | 130 | ||
| @@ -139,7 +139,7 @@ ret_from_interrupt: | |||
| 139 | 2: | 139 | 2: |
| 140 | RESTORE_ALL | 140 | RESTORE_ALL |
| 141 | 1: | 141 | 1: |
| 142 | moveb %sp@(PT_SR), %d0 | 142 | moveb %sp@(PT_OFF_SR), %d0 |
| 143 | and #7, %d0 | 143 | and #7, %d0 |
| 144 | jhi 2b | 144 | jhi 2b |
| 145 | /* check if we need to do software interrupts */ | 145 | /* check if we need to do software interrupts */ |
diff --git a/arch/m68knommu/platform/coldfire/entry.S b/arch/m68knommu/platform/coldfire/entry.S index 3b471c0da24a..dd7d591f70ea 100644 --- a/arch/m68knommu/platform/coldfire/entry.S +++ b/arch/m68knommu/platform/coldfire/entry.S | |||
| @@ -81,11 +81,11 @@ ENTRY(system_call) | |||
| 81 | 81 | ||
| 82 | movel %d3,%a0 | 82 | movel %d3,%a0 |
| 83 | jbsr %a0@ | 83 | jbsr %a0@ |
| 84 | movel %d0,%sp@(PT_D0) /* save the return value */ | 84 | movel %d0,%sp@(PT_OFF_D0) /* save the return value */ |
| 85 | jra ret_from_exception | 85 | jra ret_from_exception |
| 86 | 1: | 86 | 1: |
| 87 | movel #-ENOSYS,%d2 /* strace needs -ENOSYS in PT_D0 */ | 87 | movel #-ENOSYS,%d2 /* strace needs -ENOSYS in PT_OFF_D0 */ |
| 88 | movel %d2,PT_D0(%sp) /* on syscall entry */ | 88 | movel %d2,PT_OFF_D0(%sp) /* on syscall entry */ |
| 89 | subql #4,%sp | 89 | subql #4,%sp |
| 90 | SAVE_SWITCH_STACK | 90 | SAVE_SWITCH_STACK |
| 91 | jbsr syscall_trace | 91 | jbsr syscall_trace |
| @@ -93,7 +93,7 @@ ENTRY(system_call) | |||
| 93 | addql #4,%sp | 93 | addql #4,%sp |
| 94 | movel %d3,%a0 | 94 | movel %d3,%a0 |
| 95 | jbsr %a0@ | 95 | jbsr %a0@ |
| 96 | movel %d0,%sp@(PT_D0) /* save the return value */ | 96 | movel %d0,%sp@(PT_OFF_D0) /* save the return value */ |
| 97 | subql #4,%sp /* dummy return address */ | 97 | subql #4,%sp /* dummy return address */ |
| 98 | SAVE_SWITCH_STACK | 98 | SAVE_SWITCH_STACK |
| 99 | jbsr syscall_trace | 99 | jbsr syscall_trace |
| @@ -104,7 +104,7 @@ ret_from_signal: | |||
| 104 | 104 | ||
| 105 | ret_from_exception: | 105 | ret_from_exception: |
| 106 | move #0x2700,%sr /* disable intrs */ | 106 | move #0x2700,%sr /* disable intrs */ |
| 107 | btst #5,%sp@(PT_SR) /* check if returning to kernel */ | 107 | btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel */ |
| 108 | jeq Luser_return /* if so, skip resched, signals */ | 108 | jeq Luser_return /* if so, skip resched, signals */ |
| 109 | 109 | ||
| 110 | #ifdef CONFIG_PREEMPT | 110 | #ifdef CONFIG_PREEMPT |
| @@ -142,8 +142,8 @@ Luser_return: | |||
| 142 | Lreturn: | 142 | Lreturn: |
| 143 | move #0x2700,%sr /* disable intrs */ | 143 | move #0x2700,%sr /* disable intrs */ |
| 144 | movel sw_usp,%a0 /* get usp */ | 144 | movel sw_usp,%a0 /* get usp */ |
| 145 | movel %sp@(PT_PC),%a0@- /* copy exception program counter */ | 145 | movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */ |
| 146 | movel %sp@(PT_FORMATVEC),%a0@-/* copy exception format/vector/sr */ | 146 | movel %sp@(PT_OFF_FORMATVEC),%a0@- /* copy exception format/vector/sr */ |
| 147 | moveml %sp@,%d1-%d5/%a0-%a2 | 147 | moveml %sp@,%d1-%d5/%a0-%a2 |
| 148 | lea %sp@(32),%sp /* space for 8 regs */ | 148 | lea %sp@(32),%sp /* space for 8 regs */ |
| 149 | movel %sp@+,%d0 | 149 | movel %sp@+,%d0 |
| @@ -181,9 +181,9 @@ Lsignal_return: | |||
| 181 | ENTRY(inthandler) | 181 | ENTRY(inthandler) |
| 182 | SAVE_ALL | 182 | SAVE_ALL |
| 183 | moveq #-1,%d0 | 183 | moveq #-1,%d0 |
| 184 | movel %d0,%sp@(PT_ORIG_D0) | 184 | movel %d0,%sp@(PT_OFF_ORIG_D0) |
| 185 | 185 | ||
| 186 | movew %sp@(PT_FORMATVEC),%d0 /* put exception # in d0 */ | 186 | movew %sp@(PT_OFF_FORMATVEC),%d0 /* put exception # in d0 */ |
| 187 | andl #0x03fc,%d0 /* mask out vector only */ | 187 | andl #0x03fc,%d0 /* mask out vector only */ |
| 188 | 188 | ||
| 189 | movel %sp,%sp@- /* push regs arg */ | 189 | movel %sp,%sp@- /* push regs arg */ |
| @@ -203,7 +203,7 @@ ENTRY(inthandler) | |||
| 203 | ENTRY(fasthandler) | 203 | ENTRY(fasthandler) |
| 204 | SAVE_LOCAL | 204 | SAVE_LOCAL |
| 205 | 205 | ||
| 206 | movew %sp@(PT_FORMATVEC),%d0 | 206 | movew %sp@(PT_OFF_FORMATVEC),%d0 |
| 207 | andl #0x03fc,%d0 /* mask out vector only */ | 207 | andl #0x03fc,%d0 /* mask out vector only */ |
| 208 | 208 | ||
| 209 | movel %sp,%sp@- /* push regs arg */ | 209 | movel %sp,%sp@- /* push regs arg */ |
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S index acc1f05d1e2c..e3ecb36dd554 100644 --- a/arch/microblaze/kernel/entry.S +++ b/arch/microblaze/kernel/entry.S | |||
| @@ -592,6 +592,8 @@ C_ENTRY(full_exception_trap): | |||
| 592 | nop | 592 | nop |
| 593 | mfs r7, rfsr; /* save FSR */ | 593 | mfs r7, rfsr; /* save FSR */ |
| 594 | nop | 594 | nop |
| 595 | mts rfsr, r0; /* Clear sticky fsr */ | ||
| 596 | nop | ||
| 595 | la r12, r0, full_exception | 597 | la r12, r0, full_exception |
| 596 | set_vms; | 598 | set_vms; |
| 597 | rtbd r12, 0; | 599 | rtbd r12, 0; |
diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S index 6b0288ebccd6..2b86c03aa841 100644 --- a/arch/microblaze/kernel/hw_exception_handler.S +++ b/arch/microblaze/kernel/hw_exception_handler.S | |||
| @@ -384,7 +384,7 @@ handle_other_ex: /* Handle Other exceptions here */ | |||
| 384 | addk r8, r17, r0; /* Load exception address */ | 384 | addk r8, r17, r0; /* Load exception address */ |
| 385 | bralid r15, full_exception; /* Branch to the handler */ | 385 | bralid r15, full_exception; /* Branch to the handler */ |
| 386 | nop; | 386 | nop; |
| 387 | mts r0, rfsr; /* Clear sticky fsr */ | 387 | mts rfsr, r0; /* Clear sticky fsr */ |
| 388 | nop | 388 | nop |
| 389 | 389 | ||
| 390 | /* | 390 | /* |
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c index 4201c743cc9f..c592d475b3d8 100644 --- a/arch/microblaze/kernel/process.c +++ b/arch/microblaze/kernel/process.c | |||
| @@ -235,7 +235,9 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp) | |||
| 235 | regs->pc = pc; | 235 | regs->pc = pc; |
| 236 | regs->r1 = usp; | 236 | regs->r1 = usp; |
| 237 | regs->pt_mode = 0; | 237 | regs->pt_mode = 0; |
| 238 | #ifdef CONFIG_MMU | ||
| 238 | regs->msr |= MSR_UMS; | 239 | regs->msr |= MSR_UMS; |
| 240 | #endif | ||
| 239 | } | 241 | } |
| 240 | 242 | ||
| 241 | #ifdef CONFIG_MMU | 243 | #ifdef CONFIG_MMU |
diff --git a/arch/sparc/include/asm/hardirq_32.h b/arch/sparc/include/asm/hardirq_32.h index 4f63ed8df551..162007643cdc 100644 --- a/arch/sparc/include/asm/hardirq_32.h +++ b/arch/sparc/include/asm/hardirq_32.h | |||
| @@ -7,17 +7,7 @@ | |||
| 7 | #ifndef __SPARC_HARDIRQ_H | 7 | #ifndef __SPARC_HARDIRQ_H |
| 8 | #define __SPARC_HARDIRQ_H | 8 | #define __SPARC_HARDIRQ_H |
| 9 | 9 | ||
| 10 | #include <linux/threads.h> | ||
| 11 | #include <linux/spinlock.h> | ||
| 12 | #include <linux/cache.h> | ||
| 13 | |||
| 14 | /* entry.S is sensitive to the offsets of these fields */ /* XXX P3 Is it? */ | ||
| 15 | typedef struct { | ||
| 16 | unsigned int __softirq_pending; | ||
| 17 | } ____cacheline_aligned irq_cpustat_t; | ||
| 18 | |||
| 19 | #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ | ||
| 20 | |||
| 21 | #define HARDIRQ_BITS 8 | 10 | #define HARDIRQ_BITS 8 |
| 11 | #include <asm-generic/hardirq.h> | ||
| 22 | 12 | ||
| 23 | #endif /* __SPARC_HARDIRQ_H */ | 13 | #endif /* __SPARC_HARDIRQ_H */ |
diff --git a/arch/sparc/include/asm/irq_32.h b/arch/sparc/include/asm/irq_32.h index ea43057d4763..cbf4801deaaf 100644 --- a/arch/sparc/include/asm/irq_32.h +++ b/arch/sparc/include/asm/irq_32.h | |||
| @@ -6,10 +6,10 @@ | |||
| 6 | #ifndef _SPARC_IRQ_H | 6 | #ifndef _SPARC_IRQ_H |
| 7 | #define _SPARC_IRQ_H | 7 | #define _SPARC_IRQ_H |
| 8 | 8 | ||
| 9 | #include <linux/interrupt.h> | ||
| 10 | |||
| 11 | #define NR_IRQS 16 | 9 | #define NR_IRQS 16 |
| 12 | 10 | ||
| 11 | #include <linux/interrupt.h> | ||
| 12 | |||
| 13 | #define irq_canonicalize(irq) (irq) | 13 | #define irq_canonicalize(irq) (irq) |
| 14 | 14 | ||
| 15 | extern void __init init_IRQ(void); | 15 | extern void __init init_IRQ(void); |
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 0ff92fa22064..f3cb790fa2ae 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h | |||
| @@ -41,8 +41,8 @@ | |||
| 41 | #define LOW_OBP_ADDRESS _AC(0x00000000f0000000,UL) | 41 | #define LOW_OBP_ADDRESS _AC(0x00000000f0000000,UL) |
| 42 | #define HI_OBP_ADDRESS _AC(0x0000000100000000,UL) | 42 | #define HI_OBP_ADDRESS _AC(0x0000000100000000,UL) |
| 43 | #define VMALLOC_START _AC(0x0000000100000000,UL) | 43 | #define VMALLOC_START _AC(0x0000000100000000,UL) |
| 44 | #define VMALLOC_END _AC(0x0000000200000000,UL) | 44 | #define VMALLOC_END _AC(0x0000010000000000,UL) |
| 45 | #define VMEMMAP_BASE _AC(0x0000000200000000,UL) | 45 | #define VMEMMAP_BASE _AC(0x0000010000000000,UL) |
| 46 | 46 | ||
| 47 | #define vmemmap ((struct page *)VMEMMAP_BASE) | 47 | #define vmemmap ((struct page *)VMEMMAP_BASE) |
| 48 | 48 | ||
diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S index 3ea6e8cde8c5..1d361477d7d6 100644 --- a/arch/sparc/kernel/ktlb.S +++ b/arch/sparc/kernel/ktlb.S | |||
| @@ -280,8 +280,8 @@ kvmap_dtlb_nonlinear: | |||
| 280 | 280 | ||
| 281 | #ifdef CONFIG_SPARSEMEM_VMEMMAP | 281 | #ifdef CONFIG_SPARSEMEM_VMEMMAP |
| 282 | /* Do not use the TSB for vmemmap. */ | 282 | /* Do not use the TSB for vmemmap. */ |
| 283 | mov (VMEMMAP_BASE >> 24), %g5 | 283 | mov (VMEMMAP_BASE >> 40), %g5 |
| 284 | sllx %g5, 24, %g5 | 284 | sllx %g5, 40, %g5 |
| 285 | cmp %g4,%g5 | 285 | cmp %g4,%g5 |
| 286 | bgeu,pn %xcc, kvmap_vmemmap | 286 | bgeu,pn %xcc, kvmap_vmemmap |
| 287 | nop | 287 | nop |
| @@ -293,8 +293,8 @@ kvmap_dtlb_tsbmiss: | |||
| 293 | sethi %hi(MODULES_VADDR), %g5 | 293 | sethi %hi(MODULES_VADDR), %g5 |
| 294 | cmp %g4, %g5 | 294 | cmp %g4, %g5 |
| 295 | blu,pn %xcc, kvmap_dtlb_longpath | 295 | blu,pn %xcc, kvmap_dtlb_longpath |
| 296 | mov (VMALLOC_END >> 24), %g5 | 296 | mov (VMALLOC_END >> 40), %g5 |
| 297 | sllx %g5, 24, %g5 | 297 | sllx %g5, 40, %g5 |
| 298 | cmp %g4, %g5 | 298 | cmp %g4, %g5 |
| 299 | bgeu,pn %xcc, kvmap_dtlb_longpath | 299 | bgeu,pn %xcc, kvmap_dtlb_longpath |
| 300 | nop | 300 | nop |
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 2d6a1b10c81d..04db92743896 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c | |||
| @@ -56,7 +56,8 @@ struct cpu_hw_events { | |||
| 56 | struct perf_event *events[MAX_HWEVENTS]; | 56 | struct perf_event *events[MAX_HWEVENTS]; |
| 57 | unsigned long used_mask[BITS_TO_LONGS(MAX_HWEVENTS)]; | 57 | unsigned long used_mask[BITS_TO_LONGS(MAX_HWEVENTS)]; |
| 58 | unsigned long active_mask[BITS_TO_LONGS(MAX_HWEVENTS)]; | 58 | unsigned long active_mask[BITS_TO_LONGS(MAX_HWEVENTS)]; |
| 59 | int enabled; | 59 | u64 pcr; |
| 60 | int enabled; | ||
| 60 | }; | 61 | }; |
| 61 | DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, }; | 62 | DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, }; |
| 62 | 63 | ||
| @@ -68,8 +69,30 @@ struct perf_event_map { | |||
| 68 | #define PIC_LOWER 0x02 | 69 | #define PIC_LOWER 0x02 |
| 69 | }; | 70 | }; |
| 70 | 71 | ||
| 72 | static unsigned long perf_event_encode(const struct perf_event_map *pmap) | ||
| 73 | { | ||
| 74 | return ((unsigned long) pmap->encoding << 16) | pmap->pic_mask; | ||
| 75 | } | ||
| 76 | |||
| 77 | static void perf_event_decode(unsigned long val, u16 *enc, u8 *msk) | ||
| 78 | { | ||
| 79 | *msk = val & 0xff; | ||
| 80 | *enc = val >> 16; | ||
| 81 | } | ||
| 82 | |||
| 83 | #define C(x) PERF_COUNT_HW_CACHE_##x | ||
| 84 | |||
| 85 | #define CACHE_OP_UNSUPPORTED 0xfffe | ||
| 86 | #define CACHE_OP_NONSENSE 0xffff | ||
| 87 | |||
| 88 | typedef struct perf_event_map cache_map_t | ||
| 89 | [PERF_COUNT_HW_CACHE_MAX] | ||
| 90 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
| 91 | [PERF_COUNT_HW_CACHE_RESULT_MAX]; | ||
| 92 | |||
| 71 | struct sparc_pmu { | 93 | struct sparc_pmu { |
| 72 | const struct perf_event_map *(*event_map)(int); | 94 | const struct perf_event_map *(*event_map)(int); |
| 95 | const cache_map_t *cache_map; | ||
| 73 | int max_events; | 96 | int max_events; |
| 74 | int upper_shift; | 97 | int upper_shift; |
| 75 | int lower_shift; | 98 | int lower_shift; |
| @@ -80,21 +103,109 @@ struct sparc_pmu { | |||
| 80 | int lower_nop; | 103 | int lower_nop; |
| 81 | }; | 104 | }; |
| 82 | 105 | ||
| 83 | static const struct perf_event_map ultra3i_perfmon_event_map[] = { | 106 | static const struct perf_event_map ultra3_perfmon_event_map[] = { |
| 84 | [PERF_COUNT_HW_CPU_CYCLES] = { 0x0000, PIC_UPPER | PIC_LOWER }, | 107 | [PERF_COUNT_HW_CPU_CYCLES] = { 0x0000, PIC_UPPER | PIC_LOWER }, |
| 85 | [PERF_COUNT_HW_INSTRUCTIONS] = { 0x0001, PIC_UPPER | PIC_LOWER }, | 108 | [PERF_COUNT_HW_INSTRUCTIONS] = { 0x0001, PIC_UPPER | PIC_LOWER }, |
| 86 | [PERF_COUNT_HW_CACHE_REFERENCES] = { 0x0009, PIC_LOWER }, | 109 | [PERF_COUNT_HW_CACHE_REFERENCES] = { 0x0009, PIC_LOWER }, |
| 87 | [PERF_COUNT_HW_CACHE_MISSES] = { 0x0009, PIC_UPPER }, | 110 | [PERF_COUNT_HW_CACHE_MISSES] = { 0x0009, PIC_UPPER }, |
| 88 | }; | 111 | }; |
| 89 | 112 | ||
| 90 | static const struct perf_event_map *ultra3i_event_map(int event_id) | 113 | static const struct perf_event_map *ultra3_event_map(int event_id) |
| 91 | { | 114 | { |
| 92 | return &ultra3i_perfmon_event_map[event_id]; | 115 | return &ultra3_perfmon_event_map[event_id]; |
| 93 | } | 116 | } |
| 94 | 117 | ||
| 95 | static const struct sparc_pmu ultra3i_pmu = { | 118 | static const cache_map_t ultra3_cache_map = { |
| 96 | .event_map = ultra3i_event_map, | 119 | [C(L1D)] = { |
| 97 | .max_events = ARRAY_SIZE(ultra3i_perfmon_event_map), | 120 | [C(OP_READ)] = { |
| 121 | [C(RESULT_ACCESS)] = { 0x09, PIC_LOWER, }, | ||
| 122 | [C(RESULT_MISS)] = { 0x09, PIC_UPPER, }, | ||
| 123 | }, | ||
| 124 | [C(OP_WRITE)] = { | ||
| 125 | [C(RESULT_ACCESS)] = { 0x0a, PIC_LOWER }, | ||
| 126 | [C(RESULT_MISS)] = { 0x0a, PIC_UPPER }, | ||
| 127 | }, | ||
| 128 | [C(OP_PREFETCH)] = { | ||
| 129 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 130 | [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 131 | }, | ||
| 132 | }, | ||
| 133 | [C(L1I)] = { | ||
| 134 | [C(OP_READ)] = { | ||
| 135 | [C(RESULT_ACCESS)] = { 0x09, PIC_LOWER, }, | ||
| 136 | [C(RESULT_MISS)] = { 0x09, PIC_UPPER, }, | ||
| 137 | }, | ||
| 138 | [ C(OP_WRITE) ] = { | ||
| 139 | [ C(RESULT_ACCESS) ] = { CACHE_OP_NONSENSE }, | ||
| 140 | [ C(RESULT_MISS) ] = { CACHE_OP_NONSENSE }, | ||
| 141 | }, | ||
| 142 | [ C(OP_PREFETCH) ] = { | ||
| 143 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 144 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 145 | }, | ||
| 146 | }, | ||
| 147 | [C(LL)] = { | ||
| 148 | [C(OP_READ)] = { | ||
| 149 | [C(RESULT_ACCESS)] = { 0x0c, PIC_LOWER, }, | ||
| 150 | [C(RESULT_MISS)] = { 0x0c, PIC_UPPER, }, | ||
| 151 | }, | ||
| 152 | [C(OP_WRITE)] = { | ||
| 153 | [C(RESULT_ACCESS)] = { 0x0c, PIC_LOWER }, | ||
| 154 | [C(RESULT_MISS)] = { 0x0c, PIC_UPPER }, | ||
| 155 | }, | ||
| 156 | [C(OP_PREFETCH)] = { | ||
| 157 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 158 | [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 159 | }, | ||
| 160 | }, | ||
| 161 | [C(DTLB)] = { | ||
| 162 | [C(OP_READ)] = { | ||
| 163 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 164 | [C(RESULT_MISS)] = { 0x12, PIC_UPPER, }, | ||
| 165 | }, | ||
| 166 | [ C(OP_WRITE) ] = { | ||
| 167 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 168 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 169 | }, | ||
| 170 | [ C(OP_PREFETCH) ] = { | ||
| 171 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 172 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 173 | }, | ||
| 174 | }, | ||
| 175 | [C(ITLB)] = { | ||
| 176 | [C(OP_READ)] = { | ||
| 177 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 178 | [C(RESULT_MISS)] = { 0x11, PIC_UPPER, }, | ||
| 179 | }, | ||
| 180 | [ C(OP_WRITE) ] = { | ||
| 181 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 182 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 183 | }, | ||
| 184 | [ C(OP_PREFETCH) ] = { | ||
| 185 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 186 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 187 | }, | ||
| 188 | }, | ||
| 189 | [C(BPU)] = { | ||
| 190 | [C(OP_READ)] = { | ||
| 191 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 192 | [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 193 | }, | ||
| 194 | [ C(OP_WRITE) ] = { | ||
| 195 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 196 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 197 | }, | ||
| 198 | [ C(OP_PREFETCH) ] = { | ||
| 199 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 200 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 201 | }, | ||
| 202 | }, | ||
| 203 | }; | ||
| 204 | |||
| 205 | static const struct sparc_pmu ultra3_pmu = { | ||
| 206 | .event_map = ultra3_event_map, | ||
| 207 | .cache_map = &ultra3_cache_map, | ||
| 208 | .max_events = ARRAY_SIZE(ultra3_perfmon_event_map), | ||
| 98 | .upper_shift = 11, | 209 | .upper_shift = 11, |
| 99 | .lower_shift = 4, | 210 | .lower_shift = 4, |
| 100 | .event_mask = 0x3f, | 211 | .event_mask = 0x3f, |
| @@ -102,6 +213,121 @@ static const struct sparc_pmu ultra3i_pmu = { | |||
| 102 | .lower_nop = 0x14, | 213 | .lower_nop = 0x14, |
| 103 | }; | 214 | }; |
| 104 | 215 | ||
| 216 | /* Niagara1 is very limited. The upper PIC is hard-locked to count | ||
| 217 | * only instructions, so it is free running which creates all kinds of | ||
| 218 | * problems. Some hardware designs make one wonder if the creator | ||
| 219 | * even looked at how this stuff gets used by software. | ||
| 220 | */ | ||
| 221 | static const struct perf_event_map niagara1_perfmon_event_map[] = { | ||
| 222 | [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, PIC_UPPER }, | ||
| 223 | [PERF_COUNT_HW_INSTRUCTIONS] = { 0x00, PIC_UPPER }, | ||
| 224 | [PERF_COUNT_HW_CACHE_REFERENCES] = { 0, PIC_NONE }, | ||
| 225 | [PERF_COUNT_HW_CACHE_MISSES] = { 0x03, PIC_LOWER }, | ||
| 226 | }; | ||
| 227 | |||
| 228 | static const struct perf_event_map *niagara1_event_map(int event_id) | ||
| 229 | { | ||
| 230 | return &niagara1_perfmon_event_map[event_id]; | ||
| 231 | } | ||
| 232 | |||
| 233 | static const cache_map_t niagara1_cache_map = { | ||
| 234 | [C(L1D)] = { | ||
| 235 | [C(OP_READ)] = { | ||
| 236 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 237 | [C(RESULT_MISS)] = { 0x03, PIC_LOWER, }, | ||
| 238 | }, | ||
| 239 | [C(OP_WRITE)] = { | ||
| 240 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 241 | [C(RESULT_MISS)] = { 0x03, PIC_LOWER, }, | ||
| 242 | }, | ||
| 243 | [C(OP_PREFETCH)] = { | ||
| 244 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 245 | [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 246 | }, | ||
| 247 | }, | ||
| 248 | [C(L1I)] = { | ||
| 249 | [C(OP_READ)] = { | ||
| 250 | [C(RESULT_ACCESS)] = { 0x00, PIC_UPPER }, | ||
| 251 | [C(RESULT_MISS)] = { 0x02, PIC_LOWER, }, | ||
| 252 | }, | ||
| 253 | [ C(OP_WRITE) ] = { | ||
| 254 | [ C(RESULT_ACCESS) ] = { CACHE_OP_NONSENSE }, | ||
| 255 | [ C(RESULT_MISS) ] = { CACHE_OP_NONSENSE }, | ||
| 256 | }, | ||
| 257 | [ C(OP_PREFETCH) ] = { | ||
| 258 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 259 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 260 | }, | ||
| 261 | }, | ||
| 262 | [C(LL)] = { | ||
| 263 | [C(OP_READ)] = { | ||
| 264 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 265 | [C(RESULT_MISS)] = { 0x07, PIC_LOWER, }, | ||
| 266 | }, | ||
| 267 | [C(OP_WRITE)] = { | ||
| 268 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 269 | [C(RESULT_MISS)] = { 0x07, PIC_LOWER, }, | ||
| 270 | }, | ||
| 271 | [C(OP_PREFETCH)] = { | ||
| 272 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 273 | [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 274 | }, | ||
| 275 | }, | ||
| 276 | [C(DTLB)] = { | ||
| 277 | [C(OP_READ)] = { | ||
| 278 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 279 | [C(RESULT_MISS)] = { 0x05, PIC_LOWER, }, | ||
| 280 | }, | ||
| 281 | [ C(OP_WRITE) ] = { | ||
| 282 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 283 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 284 | }, | ||
| 285 | [ C(OP_PREFETCH) ] = { | ||
| 286 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 287 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 288 | }, | ||
| 289 | }, | ||
| 290 | [C(ITLB)] = { | ||
| 291 | [C(OP_READ)] = { | ||
| 292 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 293 | [C(RESULT_MISS)] = { 0x04, PIC_LOWER, }, | ||
| 294 | }, | ||
| 295 | [ C(OP_WRITE) ] = { | ||
| 296 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 297 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 298 | }, | ||
| 299 | [ C(OP_PREFETCH) ] = { | ||
| 300 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 301 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 302 | }, | ||
| 303 | }, | ||
| 304 | [C(BPU)] = { | ||
| 305 | [C(OP_READ)] = { | ||
| 306 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 307 | [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 308 | }, | ||
| 309 | [ C(OP_WRITE) ] = { | ||
| 310 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 311 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 312 | }, | ||
| 313 | [ C(OP_PREFETCH) ] = { | ||
| 314 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 315 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 316 | }, | ||
| 317 | }, | ||
| 318 | }; | ||
| 319 | |||
| 320 | static const struct sparc_pmu niagara1_pmu = { | ||
| 321 | .event_map = niagara1_event_map, | ||
| 322 | .cache_map = &niagara1_cache_map, | ||
| 323 | .max_events = ARRAY_SIZE(niagara1_perfmon_event_map), | ||
| 324 | .upper_shift = 0, | ||
| 325 | .lower_shift = 4, | ||
| 326 | .event_mask = 0x7, | ||
| 327 | .upper_nop = 0x0, | ||
| 328 | .lower_nop = 0x0, | ||
| 329 | }; | ||
| 330 | |||
| 105 | static const struct perf_event_map niagara2_perfmon_event_map[] = { | 331 | static const struct perf_event_map niagara2_perfmon_event_map[] = { |
| 106 | [PERF_COUNT_HW_CPU_CYCLES] = { 0x02ff, PIC_UPPER | PIC_LOWER }, | 332 | [PERF_COUNT_HW_CPU_CYCLES] = { 0x02ff, PIC_UPPER | PIC_LOWER }, |
| 107 | [PERF_COUNT_HW_INSTRUCTIONS] = { 0x02ff, PIC_UPPER | PIC_LOWER }, | 333 | [PERF_COUNT_HW_INSTRUCTIONS] = { 0x02ff, PIC_UPPER | PIC_LOWER }, |
| @@ -116,8 +342,96 @@ static const struct perf_event_map *niagara2_event_map(int event_id) | |||
| 116 | return &niagara2_perfmon_event_map[event_id]; | 342 | return &niagara2_perfmon_event_map[event_id]; |
| 117 | } | 343 | } |
| 118 | 344 | ||
| 345 | static const cache_map_t niagara2_cache_map = { | ||
| 346 | [C(L1D)] = { | ||
| 347 | [C(OP_READ)] = { | ||
| 348 | [C(RESULT_ACCESS)] = { 0x0208, PIC_UPPER | PIC_LOWER, }, | ||
| 349 | [C(RESULT_MISS)] = { 0x0302, PIC_UPPER | PIC_LOWER, }, | ||
| 350 | }, | ||
| 351 | [C(OP_WRITE)] = { | ||
| 352 | [C(RESULT_ACCESS)] = { 0x0210, PIC_UPPER | PIC_LOWER, }, | ||
| 353 | [C(RESULT_MISS)] = { 0x0302, PIC_UPPER | PIC_LOWER, }, | ||
| 354 | }, | ||
| 355 | [C(OP_PREFETCH)] = { | ||
| 356 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 357 | [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 358 | }, | ||
| 359 | }, | ||
| 360 | [C(L1I)] = { | ||
| 361 | [C(OP_READ)] = { | ||
| 362 | [C(RESULT_ACCESS)] = { 0x02ff, PIC_UPPER | PIC_LOWER, }, | ||
| 363 | [C(RESULT_MISS)] = { 0x0301, PIC_UPPER | PIC_LOWER, }, | ||
| 364 | }, | ||
| 365 | [ C(OP_WRITE) ] = { | ||
| 366 | [ C(RESULT_ACCESS) ] = { CACHE_OP_NONSENSE }, | ||
| 367 | [ C(RESULT_MISS) ] = { CACHE_OP_NONSENSE }, | ||
| 368 | }, | ||
| 369 | [ C(OP_PREFETCH) ] = { | ||
| 370 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 371 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 372 | }, | ||
| 373 | }, | ||
| 374 | [C(LL)] = { | ||
| 375 | [C(OP_READ)] = { | ||
| 376 | [C(RESULT_ACCESS)] = { 0x0208, PIC_UPPER | PIC_LOWER, }, | ||
| 377 | [C(RESULT_MISS)] = { 0x0330, PIC_UPPER | PIC_LOWER, }, | ||
| 378 | }, | ||
| 379 | [C(OP_WRITE)] = { | ||
| 380 | [C(RESULT_ACCESS)] = { 0x0210, PIC_UPPER | PIC_LOWER, }, | ||
| 381 | [C(RESULT_MISS)] = { 0x0320, PIC_UPPER | PIC_LOWER, }, | ||
| 382 | }, | ||
| 383 | [C(OP_PREFETCH)] = { | ||
| 384 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 385 | [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 386 | }, | ||
| 387 | }, | ||
| 388 | [C(DTLB)] = { | ||
| 389 | [C(OP_READ)] = { | ||
| 390 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 391 | [C(RESULT_MISS)] = { 0x0b08, PIC_UPPER | PIC_LOWER, }, | ||
| 392 | }, | ||
| 393 | [ C(OP_WRITE) ] = { | ||
| 394 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 395 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 396 | }, | ||
| 397 | [ C(OP_PREFETCH) ] = { | ||
| 398 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 399 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 400 | }, | ||
| 401 | }, | ||
| 402 | [C(ITLB)] = { | ||
| 403 | [C(OP_READ)] = { | ||
| 404 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 405 | [C(RESULT_MISS)] = { 0xb04, PIC_UPPER | PIC_LOWER, }, | ||
| 406 | }, | ||
| 407 | [ C(OP_WRITE) ] = { | ||
| 408 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 409 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 410 | }, | ||
| 411 | [ C(OP_PREFETCH) ] = { | ||
| 412 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 413 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 414 | }, | ||
| 415 | }, | ||
| 416 | [C(BPU)] = { | ||
| 417 | [C(OP_READ)] = { | ||
| 418 | [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 419 | [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED }, | ||
| 420 | }, | ||
| 421 | [ C(OP_WRITE) ] = { | ||
| 422 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 423 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 424 | }, | ||
| 425 | [ C(OP_PREFETCH) ] = { | ||
| 426 | [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 427 | [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED }, | ||
| 428 | }, | ||
| 429 | }, | ||
| 430 | }; | ||
| 431 | |||
| 119 | static const struct sparc_pmu niagara2_pmu = { | 432 | static const struct sparc_pmu niagara2_pmu = { |
| 120 | .event_map = niagara2_event_map, | 433 | .event_map = niagara2_event_map, |
| 434 | .cache_map = &niagara2_cache_map, | ||
| 121 | .max_events = ARRAY_SIZE(niagara2_perfmon_event_map), | 435 | .max_events = ARRAY_SIZE(niagara2_perfmon_event_map), |
| 122 | .upper_shift = 19, | 436 | .upper_shift = 19, |
| 123 | .lower_shift = 6, | 437 | .lower_shift = 6, |
| @@ -151,23 +465,30 @@ static u64 nop_for_index(int idx) | |||
| 151 | sparc_pmu->lower_nop, idx); | 465 | sparc_pmu->lower_nop, idx); |
| 152 | } | 466 | } |
| 153 | 467 | ||
| 154 | static inline void sparc_pmu_enable_event(struct hw_perf_event *hwc, | 468 | static inline void sparc_pmu_enable_event(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc, int idx) |
| 155 | int idx) | ||
| 156 | { | 469 | { |
| 157 | u64 val, mask = mask_for_index(idx); | 470 | u64 val, mask = mask_for_index(idx); |
| 158 | 471 | ||
| 159 | val = pcr_ops->read(); | 472 | val = cpuc->pcr; |
| 160 | pcr_ops->write((val & ~mask) | hwc->config); | 473 | val &= ~mask; |
| 474 | val |= hwc->config; | ||
| 475 | cpuc->pcr = val; | ||
| 476 | |||
| 477 | pcr_ops->write(cpuc->pcr); | ||
| 161 | } | 478 | } |
| 162 | 479 | ||
| 163 | static inline void sparc_pmu_disable_event(struct hw_perf_event *hwc, | 480 | static inline void sparc_pmu_disable_event(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc, int idx) |
| 164 | int idx) | ||
| 165 | { | 481 | { |
| 166 | u64 mask = mask_for_index(idx); | 482 | u64 mask = mask_for_index(idx); |
| 167 | u64 nop = nop_for_index(idx); | 483 | u64 nop = nop_for_index(idx); |
| 168 | u64 val = pcr_ops->read(); | 484 | u64 val; |
| 169 | 485 | ||
| 170 | pcr_ops->write((val & ~mask) | nop); | 486 | val = cpuc->pcr; |
| 487 | val &= ~mask; | ||
| 488 | val |= nop; | ||
| 489 | cpuc->pcr = val; | ||
| 490 | |||
| 491 | pcr_ops->write(cpuc->pcr); | ||
| 171 | } | 492 | } |
| 172 | 493 | ||
| 173 | void hw_perf_enable(void) | 494 | void hw_perf_enable(void) |
| @@ -182,7 +503,7 @@ void hw_perf_enable(void) | |||
| 182 | cpuc->enabled = 1; | 503 | cpuc->enabled = 1; |
| 183 | barrier(); | 504 | barrier(); |
| 184 | 505 | ||
| 185 | val = pcr_ops->read(); | 506 | val = cpuc->pcr; |
| 186 | 507 | ||
| 187 | for (i = 0; i < MAX_HWEVENTS; i++) { | 508 | for (i = 0; i < MAX_HWEVENTS; i++) { |
| 188 | struct perf_event *cp = cpuc->events[i]; | 509 | struct perf_event *cp = cpuc->events[i]; |
| @@ -194,7 +515,9 @@ void hw_perf_enable(void) | |||
| 194 | val |= hwc->config_base; | 515 | val |= hwc->config_base; |
| 195 | } | 516 | } |
| 196 | 517 | ||
| 197 | pcr_ops->write(val); | 518 | cpuc->pcr = val; |
| 519 | |||
| 520 | pcr_ops->write(cpuc->pcr); | ||
| 198 | } | 521 | } |
| 199 | 522 | ||
| 200 | void hw_perf_disable(void) | 523 | void hw_perf_disable(void) |
| @@ -207,10 +530,12 @@ void hw_perf_disable(void) | |||
| 207 | 530 | ||
| 208 | cpuc->enabled = 0; | 531 | cpuc->enabled = 0; |
| 209 | 532 | ||
| 210 | val = pcr_ops->read(); | 533 | val = cpuc->pcr; |
| 211 | val &= ~(PCR_UTRACE | PCR_STRACE | | 534 | val &= ~(PCR_UTRACE | PCR_STRACE | |
| 212 | sparc_pmu->hv_bit | sparc_pmu->irq_bit); | 535 | sparc_pmu->hv_bit | sparc_pmu->irq_bit); |
| 213 | pcr_ops->write(val); | 536 | cpuc->pcr = val; |
| 537 | |||
| 538 | pcr_ops->write(cpuc->pcr); | ||
| 214 | } | 539 | } |
| 215 | 540 | ||
| 216 | static u32 read_pmc(int idx) | 541 | static u32 read_pmc(int idx) |
| @@ -242,7 +567,7 @@ static void write_pmc(int idx, u64 val) | |||
| 242 | } | 567 | } |
| 243 | 568 | ||
| 244 | static int sparc_perf_event_set_period(struct perf_event *event, | 569 | static int sparc_perf_event_set_period(struct perf_event *event, |
| 245 | struct hw_perf_event *hwc, int idx) | 570 | struct hw_perf_event *hwc, int idx) |
| 246 | { | 571 | { |
| 247 | s64 left = atomic64_read(&hwc->period_left); | 572 | s64 left = atomic64_read(&hwc->period_left); |
| 248 | s64 period = hwc->sample_period; | 573 | s64 period = hwc->sample_period; |
| @@ -282,19 +607,19 @@ static int sparc_pmu_enable(struct perf_event *event) | |||
| 282 | if (test_and_set_bit(idx, cpuc->used_mask)) | 607 | if (test_and_set_bit(idx, cpuc->used_mask)) |
| 283 | return -EAGAIN; | 608 | return -EAGAIN; |
| 284 | 609 | ||
| 285 | sparc_pmu_disable_event(hwc, idx); | 610 | sparc_pmu_disable_event(cpuc, hwc, idx); |
| 286 | 611 | ||
| 287 | cpuc->events[idx] = event; | 612 | cpuc->events[idx] = event; |
| 288 | set_bit(idx, cpuc->active_mask); | 613 | set_bit(idx, cpuc->active_mask); |
| 289 | 614 | ||
| 290 | sparc_perf_event_set_period(event, hwc, idx); | 615 | sparc_perf_event_set_period(event, hwc, idx); |
| 291 | sparc_pmu_enable_event(hwc, idx); | 616 | sparc_pmu_enable_event(cpuc, hwc, idx); |
| 292 | perf_event_update_userpage(event); | 617 | perf_event_update_userpage(event); |
| 293 | return 0; | 618 | return 0; |
| 294 | } | 619 | } |
| 295 | 620 | ||
| 296 | static u64 sparc_perf_event_update(struct perf_event *event, | 621 | static u64 sparc_perf_event_update(struct perf_event *event, |
| 297 | struct hw_perf_event *hwc, int idx) | 622 | struct hw_perf_event *hwc, int idx) |
| 298 | { | 623 | { |
| 299 | int shift = 64 - 32; | 624 | int shift = 64 - 32; |
| 300 | u64 prev_raw_count, new_raw_count; | 625 | u64 prev_raw_count, new_raw_count; |
| @@ -324,7 +649,7 @@ static void sparc_pmu_disable(struct perf_event *event) | |||
| 324 | int idx = hwc->idx; | 649 | int idx = hwc->idx; |
| 325 | 650 | ||
| 326 | clear_bit(idx, cpuc->active_mask); | 651 | clear_bit(idx, cpuc->active_mask); |
| 327 | sparc_pmu_disable_event(hwc, idx); | 652 | sparc_pmu_disable_event(cpuc, hwc, idx); |
| 328 | 653 | ||
| 329 | barrier(); | 654 | barrier(); |
| 330 | 655 | ||
| @@ -338,18 +663,29 @@ static void sparc_pmu_disable(struct perf_event *event) | |||
| 338 | static void sparc_pmu_read(struct perf_event *event) | 663 | static void sparc_pmu_read(struct perf_event *event) |
| 339 | { | 664 | { |
| 340 | struct hw_perf_event *hwc = &event->hw; | 665 | struct hw_perf_event *hwc = &event->hw; |
| 666 | |||
| 341 | sparc_perf_event_update(event, hwc, hwc->idx); | 667 | sparc_perf_event_update(event, hwc, hwc->idx); |
| 342 | } | 668 | } |
| 343 | 669 | ||
| 344 | static void sparc_pmu_unthrottle(struct perf_event *event) | 670 | static void sparc_pmu_unthrottle(struct perf_event *event) |
| 345 | { | 671 | { |
| 672 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
| 346 | struct hw_perf_event *hwc = &event->hw; | 673 | struct hw_perf_event *hwc = &event->hw; |
| 347 | sparc_pmu_enable_event(hwc, hwc->idx); | 674 | |
| 675 | sparc_pmu_enable_event(cpuc, hwc, hwc->idx); | ||
| 348 | } | 676 | } |
| 349 | 677 | ||
| 350 | static atomic_t active_events = ATOMIC_INIT(0); | 678 | static atomic_t active_events = ATOMIC_INIT(0); |
| 351 | static DEFINE_MUTEX(pmc_grab_mutex); | 679 | static DEFINE_MUTEX(pmc_grab_mutex); |
| 352 | 680 | ||
| 681 | static void perf_stop_nmi_watchdog(void *unused) | ||
| 682 | { | ||
| 683 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
| 684 | |||
| 685 | stop_nmi_watchdog(NULL); | ||
| 686 | cpuc->pcr = pcr_ops->read(); | ||
| 687 | } | ||
| 688 | |||
| 353 | void perf_event_grab_pmc(void) | 689 | void perf_event_grab_pmc(void) |
| 354 | { | 690 | { |
| 355 | if (atomic_inc_not_zero(&active_events)) | 691 | if (atomic_inc_not_zero(&active_events)) |
| @@ -358,7 +694,7 @@ void perf_event_grab_pmc(void) | |||
| 358 | mutex_lock(&pmc_grab_mutex); | 694 | mutex_lock(&pmc_grab_mutex); |
| 359 | if (atomic_read(&active_events) == 0) { | 695 | if (atomic_read(&active_events) == 0) { |
| 360 | if (atomic_read(&nmi_active) > 0) { | 696 | if (atomic_read(&nmi_active) > 0) { |
| 361 | on_each_cpu(stop_nmi_watchdog, NULL, 1); | 697 | on_each_cpu(perf_stop_nmi_watchdog, NULL, 1); |
| 362 | BUG_ON(atomic_read(&nmi_active) != 0); | 698 | BUG_ON(atomic_read(&nmi_active) != 0); |
| 363 | } | 699 | } |
| 364 | atomic_inc(&active_events); | 700 | atomic_inc(&active_events); |
| @@ -375,30 +711,160 @@ void perf_event_release_pmc(void) | |||
| 375 | } | 711 | } |
| 376 | } | 712 | } |
| 377 | 713 | ||
| 714 | static const struct perf_event_map *sparc_map_cache_event(u64 config) | ||
| 715 | { | ||
| 716 | unsigned int cache_type, cache_op, cache_result; | ||
| 717 | const struct perf_event_map *pmap; | ||
| 718 | |||
| 719 | if (!sparc_pmu->cache_map) | ||
| 720 | return ERR_PTR(-ENOENT); | ||
| 721 | |||
| 722 | cache_type = (config >> 0) & 0xff; | ||
| 723 | if (cache_type >= PERF_COUNT_HW_CACHE_MAX) | ||
| 724 | return ERR_PTR(-EINVAL); | ||
| 725 | |||
| 726 | cache_op = (config >> 8) & 0xff; | ||
| 727 | if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX) | ||
| 728 | return ERR_PTR(-EINVAL); | ||
| 729 | |||
| 730 | cache_result = (config >> 16) & 0xff; | ||
| 731 | if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX) | ||
| 732 | return ERR_PTR(-EINVAL); | ||
| 733 | |||
| 734 | pmap = &((*sparc_pmu->cache_map)[cache_type][cache_op][cache_result]); | ||
| 735 | |||
| 736 | if (pmap->encoding == CACHE_OP_UNSUPPORTED) | ||
| 737 | return ERR_PTR(-ENOENT); | ||
| 738 | |||
| 739 | if (pmap->encoding == CACHE_OP_NONSENSE) | ||
| 740 | return ERR_PTR(-EINVAL); | ||
| 741 | |||
| 742 | return pmap; | ||
| 743 | } | ||
| 744 | |||
| 378 | static void hw_perf_event_destroy(struct perf_event *event) | 745 | static void hw_perf_event_destroy(struct perf_event *event) |
| 379 | { | 746 | { |
| 380 | perf_event_release_pmc(); | 747 | perf_event_release_pmc(); |
| 381 | } | 748 | } |
| 382 | 749 | ||
| 750 | /* Make sure all events can be scheduled into the hardware at | ||
| 751 | * the same time. This is simplified by the fact that we only | ||
| 752 | * need to support 2 simultaneous HW events. | ||
| 753 | */ | ||
| 754 | static int sparc_check_constraints(unsigned long *events, int n_ev) | ||
| 755 | { | ||
| 756 | if (n_ev <= perf_max_events) { | ||
| 757 | u8 msk1, msk2; | ||
| 758 | u16 dummy; | ||
| 759 | |||
| 760 | if (n_ev == 1) | ||
| 761 | return 0; | ||
| 762 | BUG_ON(n_ev != 2); | ||
| 763 | perf_event_decode(events[0], &dummy, &msk1); | ||
| 764 | perf_event_decode(events[1], &dummy, &msk2); | ||
| 765 | |||
| 766 | /* If both events can go on any counter, OK. */ | ||
| 767 | if (msk1 == (PIC_UPPER | PIC_LOWER) && | ||
| 768 | msk2 == (PIC_UPPER | PIC_LOWER)) | ||
| 769 | return 0; | ||
| 770 | |||
| 771 | /* If one event is limited to a specific counter, | ||
| 772 | * and the other can go on both, OK. | ||
| 773 | */ | ||
| 774 | if ((msk1 == PIC_UPPER || msk1 == PIC_LOWER) && | ||
| 775 | msk2 == (PIC_UPPER | PIC_LOWER)) | ||
| 776 | return 0; | ||
| 777 | if ((msk2 == PIC_UPPER || msk2 == PIC_LOWER) && | ||
| 778 | msk1 == (PIC_UPPER | PIC_LOWER)) | ||
| 779 | return 0; | ||
| 780 | |||
| 781 | /* If the events are fixed to different counters, OK. */ | ||
| 782 | if ((msk1 == PIC_UPPER && msk2 == PIC_LOWER) || | ||
| 783 | (msk1 == PIC_LOWER && msk2 == PIC_UPPER)) | ||
| 784 | return 0; | ||
| 785 | |||
| 786 | /* Otherwise, there is a conflict. */ | ||
| 787 | } | ||
| 788 | |||
| 789 | return -1; | ||
| 790 | } | ||
| 791 | |||
| 792 | static int check_excludes(struct perf_event **evts, int n_prev, int n_new) | ||
| 793 | { | ||
| 794 | int eu = 0, ek = 0, eh = 0; | ||
| 795 | struct perf_event *event; | ||
| 796 | int i, n, first; | ||
| 797 | |||
| 798 | n = n_prev + n_new; | ||
| 799 | if (n <= 1) | ||
| 800 | return 0; | ||
| 801 | |||
| 802 | first = 1; | ||
| 803 | for (i = 0; i < n; i++) { | ||
| 804 | event = evts[i]; | ||
| 805 | if (first) { | ||
| 806 | eu = event->attr.exclude_user; | ||
| 807 | ek = event->attr.exclude_kernel; | ||
| 808 | eh = event->attr.exclude_hv; | ||
| 809 | first = 0; | ||
| 810 | } else if (event->attr.exclude_user != eu || | ||
| 811 | event->attr.exclude_kernel != ek || | ||
| 812 | event->attr.exclude_hv != eh) { | ||
| 813 | return -EAGAIN; | ||
| 814 | } | ||
| 815 | } | ||
| 816 | |||
| 817 | return 0; | ||
| 818 | } | ||
| 819 | |||
| 820 | static int collect_events(struct perf_event *group, int max_count, | ||
| 821 | struct perf_event *evts[], unsigned long *events) | ||
| 822 | { | ||
| 823 | struct perf_event *event; | ||
| 824 | int n = 0; | ||
| 825 | |||
| 826 | if (!is_software_event(group)) { | ||
| 827 | if (n >= max_count) | ||
| 828 | return -1; | ||
| 829 | evts[n] = group; | ||
| 830 | events[n++] = group->hw.event_base; | ||
| 831 | } | ||
| 832 | list_for_each_entry(event, &group->sibling_list, group_entry) { | ||
| 833 | if (!is_software_event(event) && | ||
| 834 | event->state != PERF_EVENT_STATE_OFF) { | ||
| 835 | if (n >= max_count) | ||
| 836 | return -1; | ||
| 837 | evts[n] = event; | ||
| 838 | events[n++] = event->hw.event_base; | ||
| 839 | } | ||
| 840 | } | ||
| 841 | return n; | ||
| 842 | } | ||
| 843 | |||
| 383 | static int __hw_perf_event_init(struct perf_event *event) | 844 | static int __hw_perf_event_init(struct perf_event *event) |
| 384 | { | 845 | { |
| 385 | struct perf_event_attr *attr = &event->attr; | 846 | struct perf_event_attr *attr = &event->attr; |
| 847 | struct perf_event *evts[MAX_HWEVENTS]; | ||
| 386 | struct hw_perf_event *hwc = &event->hw; | 848 | struct hw_perf_event *hwc = &event->hw; |
| 849 | unsigned long events[MAX_HWEVENTS]; | ||
| 387 | const struct perf_event_map *pmap; | 850 | const struct perf_event_map *pmap; |
| 388 | u64 enc; | 851 | u64 enc; |
| 852 | int n; | ||
| 389 | 853 | ||
| 390 | if (atomic_read(&nmi_active) < 0) | 854 | if (atomic_read(&nmi_active) < 0) |
| 391 | return -ENODEV; | 855 | return -ENODEV; |
| 392 | 856 | ||
| 393 | if (attr->type != PERF_TYPE_HARDWARE) | 857 | if (attr->type == PERF_TYPE_HARDWARE) { |
| 858 | if (attr->config >= sparc_pmu->max_events) | ||
| 859 | return -EINVAL; | ||
| 860 | pmap = sparc_pmu->event_map(attr->config); | ||
| 861 | } else if (attr->type == PERF_TYPE_HW_CACHE) { | ||
| 862 | pmap = sparc_map_cache_event(attr->config); | ||
| 863 | if (IS_ERR(pmap)) | ||
| 864 | return PTR_ERR(pmap); | ||
| 865 | } else | ||
| 394 | return -EOPNOTSUPP; | 866 | return -EOPNOTSUPP; |
| 395 | 867 | ||
| 396 | if (attr->config >= sparc_pmu->max_events) | ||
| 397 | return -EINVAL; | ||
| 398 | |||
| 399 | perf_event_grab_pmc(); | ||
| 400 | event->destroy = hw_perf_event_destroy; | ||
| 401 | |||
| 402 | /* We save the enable bits in the config_base. So to | 868 | /* We save the enable bits in the config_base. So to |
| 403 | * turn off sampling just write 'config', and to enable | 869 | * turn off sampling just write 'config', and to enable |
| 404 | * things write 'config | config_base'. | 870 | * things write 'config | config_base'. |
| @@ -411,15 +877,39 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
| 411 | if (!attr->exclude_hv) | 877 | if (!attr->exclude_hv) |
| 412 | hwc->config_base |= sparc_pmu->hv_bit; | 878 | hwc->config_base |= sparc_pmu->hv_bit; |
| 413 | 879 | ||
| 880 | hwc->event_base = perf_event_encode(pmap); | ||
| 881 | |||
| 882 | enc = pmap->encoding; | ||
| 883 | |||
| 884 | n = 0; | ||
| 885 | if (event->group_leader != event) { | ||
| 886 | n = collect_events(event->group_leader, | ||
| 887 | perf_max_events - 1, | ||
| 888 | evts, events); | ||
| 889 | if (n < 0) | ||
| 890 | return -EINVAL; | ||
| 891 | } | ||
| 892 | events[n] = hwc->event_base; | ||
| 893 | evts[n] = event; | ||
| 894 | |||
| 895 | if (check_excludes(evts, n, 1)) | ||
| 896 | return -EINVAL; | ||
| 897 | |||
| 898 | if (sparc_check_constraints(events, n + 1)) | ||
| 899 | return -EINVAL; | ||
| 900 | |||
| 901 | /* Try to do all error checking before this point, as unwinding | ||
| 902 | * state after grabbing the PMC is difficult. | ||
| 903 | */ | ||
| 904 | perf_event_grab_pmc(); | ||
| 905 | event->destroy = hw_perf_event_destroy; | ||
| 906 | |||
| 414 | if (!hwc->sample_period) { | 907 | if (!hwc->sample_period) { |
| 415 | hwc->sample_period = MAX_PERIOD; | 908 | hwc->sample_period = MAX_PERIOD; |
| 416 | hwc->last_period = hwc->sample_period; | 909 | hwc->last_period = hwc->sample_period; |
| 417 | atomic64_set(&hwc->period_left, hwc->sample_period); | 910 | atomic64_set(&hwc->period_left, hwc->sample_period); |
| 418 | } | 911 | } |
| 419 | 912 | ||
| 420 | pmap = sparc_pmu->event_map(attr->config); | ||
| 421 | |||
| 422 | enc = pmap->encoding; | ||
| 423 | if (pmap->pic_mask & PIC_UPPER) { | 913 | if (pmap->pic_mask & PIC_UPPER) { |
| 424 | hwc->idx = PIC_UPPER_INDEX; | 914 | hwc->idx = PIC_UPPER_INDEX; |
| 425 | enc <<= sparc_pmu->upper_shift; | 915 | enc <<= sparc_pmu->upper_shift; |
| @@ -472,7 +962,7 @@ void perf_event_print_debug(void) | |||
| 472 | } | 962 | } |
| 473 | 963 | ||
| 474 | static int __kprobes perf_event_nmi_handler(struct notifier_block *self, | 964 | static int __kprobes perf_event_nmi_handler(struct notifier_block *self, |
| 475 | unsigned long cmd, void *__args) | 965 | unsigned long cmd, void *__args) |
| 476 | { | 966 | { |
| 477 | struct die_args *args = __args; | 967 | struct die_args *args = __args; |
| 478 | struct perf_sample_data data; | 968 | struct perf_sample_data data; |
| @@ -513,7 +1003,7 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self, | |||
| 513 | continue; | 1003 | continue; |
| 514 | 1004 | ||
| 515 | if (perf_event_overflow(event, 1, &data, regs)) | 1005 | if (perf_event_overflow(event, 1, &data, regs)) |
| 516 | sparc_pmu_disable_event(hwc, idx); | 1006 | sparc_pmu_disable_event(cpuc, hwc, idx); |
| 517 | } | 1007 | } |
| 518 | 1008 | ||
| 519 | return NOTIFY_STOP; | 1009 | return NOTIFY_STOP; |
| @@ -525,8 +1015,15 @@ static __read_mostly struct notifier_block perf_event_nmi_notifier = { | |||
| 525 | 1015 | ||
| 526 | static bool __init supported_pmu(void) | 1016 | static bool __init supported_pmu(void) |
| 527 | { | 1017 | { |
| 528 | if (!strcmp(sparc_pmu_type, "ultra3i")) { | 1018 | if (!strcmp(sparc_pmu_type, "ultra3") || |
| 529 | sparc_pmu = &ultra3i_pmu; | 1019 | !strcmp(sparc_pmu_type, "ultra3+") || |
| 1020 | !strcmp(sparc_pmu_type, "ultra3i") || | ||
| 1021 | !strcmp(sparc_pmu_type, "ultra4+")) { | ||
| 1022 | sparc_pmu = &ultra3_pmu; | ||
| 1023 | return true; | ||
| 1024 | } | ||
| 1025 | if (!strcmp(sparc_pmu_type, "niagara")) { | ||
| 1026 | sparc_pmu = &niagara1_pmu; | ||
| 530 | return true; | 1027 | return true; |
| 531 | } | 1028 | } |
| 532 | if (!strcmp(sparc_pmu_type, "niagara2")) { | 1029 | if (!strcmp(sparc_pmu_type, "niagara2")) { |
diff --git a/arch/sparc/oprofile/init.c b/arch/sparc/oprofile/init.c index f97cb8b6ee5f..f9024bccff16 100644 --- a/arch/sparc/oprofile/init.c +++ b/arch/sparc/oprofile/init.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <linux/oprofile.h> | 11 | #include <linux/oprofile.h> |
| 12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/param.h> /* for HZ */ | ||
| 14 | 15 | ||
| 15 | #ifdef CONFIG_SPARC64 | 16 | #ifdef CONFIG_SPARC64 |
| 16 | #include <linux/notifier.h> | 17 | #include <linux/notifier.h> |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 8da93745c087..c876bace8fdc 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -86,10 +86,6 @@ config STACKTRACE_SUPPORT | |||
| 86 | config HAVE_LATENCYTOP_SUPPORT | 86 | config HAVE_LATENCYTOP_SUPPORT |
| 87 | def_bool y | 87 | def_bool y |
| 88 | 88 | ||
| 89 | config FAST_CMPXCHG_LOCAL | ||
| 90 | bool | ||
| 91 | default y | ||
| 92 | |||
| 93 | config MMU | 89 | config MMU |
| 94 | def_bool y | 90 | def_bool y |
| 95 | 91 | ||
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index 527519b8a9f9..f2824fb8c79c 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu | |||
| @@ -400,7 +400,7 @@ config X86_TSC | |||
| 400 | 400 | ||
| 401 | config X86_CMPXCHG64 | 401 | config X86_CMPXCHG64 |
| 402 | def_bool y | 402 | def_bool y |
| 403 | depends on X86_PAE || X86_64 | 403 | depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM |
| 404 | 404 | ||
| 405 | # this should be set for all -march=.. options where the compiler | 405 | # this should be set for all -march=.. options where the compiler |
| 406 | # generates cmov. | 406 | # generates cmov. |
| @@ -412,6 +412,7 @@ config X86_MINIMUM_CPU_FAMILY | |||
| 412 | int | 412 | int |
| 413 | default "64" if X86_64 | 413 | default "64" if X86_64 |
| 414 | default "6" if X86_32 && X86_P6_NOP | 414 | default "6" if X86_32 && X86_P6_NOP |
| 415 | default "5" if X86_32 && X86_CMPXCHG64 | ||
| 415 | default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK) | 416 | default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK) |
| 416 | default "3" | 417 | default "3" |
| 417 | 418 | ||
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 74619c4f9fda..1733f9f65e82 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S | |||
| @@ -21,8 +21,8 @@ | |||
| 21 | #define __AUDIT_ARCH_LE 0x40000000 | 21 | #define __AUDIT_ARCH_LE 0x40000000 |
| 22 | 22 | ||
| 23 | #ifndef CONFIG_AUDITSYSCALL | 23 | #ifndef CONFIG_AUDITSYSCALL |
| 24 | #define sysexit_audit int_ret_from_sys_call | 24 | #define sysexit_audit ia32_ret_from_sys_call |
| 25 | #define sysretl_audit int_ret_from_sys_call | 25 | #define sysretl_audit ia32_ret_from_sys_call |
| 26 | #endif | 26 | #endif |
| 27 | 27 | ||
| 28 | #define IA32_NR_syscalls ((ia32_syscall_end - ia32_sys_call_table)/8) | 28 | #define IA32_NR_syscalls ((ia32_syscall_end - ia32_sys_call_table)/8) |
| @@ -39,12 +39,12 @@ | |||
| 39 | .endm | 39 | .endm |
| 40 | 40 | ||
| 41 | /* clobbers %eax */ | 41 | /* clobbers %eax */ |
| 42 | .macro CLEAR_RREGS _r9=rax | 42 | .macro CLEAR_RREGS offset=0, _r9=rax |
| 43 | xorl %eax,%eax | 43 | xorl %eax,%eax |
| 44 | movq %rax,R11(%rsp) | 44 | movq %rax,\offset+R11(%rsp) |
| 45 | movq %rax,R10(%rsp) | 45 | movq %rax,\offset+R10(%rsp) |
| 46 | movq %\_r9,R9(%rsp) | 46 | movq %\_r9,\offset+R9(%rsp) |
| 47 | movq %rax,R8(%rsp) | 47 | movq %rax,\offset+R8(%rsp) |
| 48 | .endm | 48 | .endm |
| 49 | 49 | ||
| 50 | /* | 50 | /* |
| @@ -172,6 +172,10 @@ sysexit_from_sys_call: | |||
| 172 | movl RIP-R11(%rsp),%edx /* User %eip */ | 172 | movl RIP-R11(%rsp),%edx /* User %eip */ |
| 173 | CFI_REGISTER rip,rdx | 173 | CFI_REGISTER rip,rdx |
| 174 | RESTORE_ARGS 1,24,1,1,1,1 | 174 | RESTORE_ARGS 1,24,1,1,1,1 |
| 175 | xorq %r8,%r8 | ||
| 176 | xorq %r9,%r9 | ||
| 177 | xorq %r10,%r10 | ||
| 178 | xorq %r11,%r11 | ||
| 175 | popfq | 179 | popfq |
| 176 | CFI_ADJUST_CFA_OFFSET -8 | 180 | CFI_ADJUST_CFA_OFFSET -8 |
| 177 | /*CFI_RESTORE rflags*/ | 181 | /*CFI_RESTORE rflags*/ |
| @@ -202,7 +206,7 @@ sysexit_from_sys_call: | |||
| 202 | 206 | ||
| 203 | .macro auditsys_exit exit,ebpsave=RBP | 207 | .macro auditsys_exit exit,ebpsave=RBP |
| 204 | testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags(%r10) | 208 | testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags(%r10) |
| 205 | jnz int_ret_from_sys_call | 209 | jnz ia32_ret_from_sys_call |
| 206 | TRACE_IRQS_ON | 210 | TRACE_IRQS_ON |
| 207 | sti | 211 | sti |
| 208 | movl %eax,%esi /* second arg, syscall return value */ | 212 | movl %eax,%esi /* second arg, syscall return value */ |
| @@ -218,8 +222,9 @@ sysexit_from_sys_call: | |||
| 218 | cli | 222 | cli |
| 219 | TRACE_IRQS_OFF | 223 | TRACE_IRQS_OFF |
| 220 | testl %edi,TI_flags(%r10) | 224 | testl %edi,TI_flags(%r10) |
| 221 | jnz int_with_check | 225 | jz \exit |
| 222 | jmp \exit | 226 | CLEAR_RREGS -ARGOFFSET |
| 227 | jmp int_with_check | ||
| 223 | .endm | 228 | .endm |
| 224 | 229 | ||
| 225 | sysenter_auditsys: | 230 | sysenter_auditsys: |
| @@ -329,6 +334,9 @@ sysretl_from_sys_call: | |||
| 329 | CFI_REGISTER rip,rcx | 334 | CFI_REGISTER rip,rcx |
| 330 | movl EFLAGS-ARGOFFSET(%rsp),%r11d | 335 | movl EFLAGS-ARGOFFSET(%rsp),%r11d |
| 331 | /*CFI_REGISTER rflags,r11*/ | 336 | /*CFI_REGISTER rflags,r11*/ |
| 337 | xorq %r10,%r10 | ||
| 338 | xorq %r9,%r9 | ||
| 339 | xorq %r8,%r8 | ||
| 332 | TRACE_IRQS_ON | 340 | TRACE_IRQS_ON |
| 333 | movl RSP-ARGOFFSET(%rsp),%esp | 341 | movl RSP-ARGOFFSET(%rsp),%esp |
| 334 | CFI_RESTORE rsp | 342 | CFI_RESTORE rsp |
| @@ -353,7 +361,7 @@ cstar_tracesys: | |||
| 353 | #endif | 361 | #endif |
| 354 | xchgl %r9d,%ebp | 362 | xchgl %r9d,%ebp |
| 355 | SAVE_REST | 363 | SAVE_REST |
| 356 | CLEAR_RREGS r9 | 364 | CLEAR_RREGS 0, r9 |
| 357 | movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */ | 365 | movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */ |
| 358 | movq %rsp,%rdi /* &pt_regs -> arg1 */ | 366 | movq %rsp,%rdi /* &pt_regs -> arg1 */ |
| 359 | call syscall_trace_enter | 367 | call syscall_trace_enter |
| @@ -425,6 +433,8 @@ ia32_do_call: | |||
| 425 | call *ia32_sys_call_table(,%rax,8) # xxx: rip relative | 433 | call *ia32_sys_call_table(,%rax,8) # xxx: rip relative |
| 426 | ia32_sysret: | 434 | ia32_sysret: |
| 427 | movq %rax,RAX-ARGOFFSET(%rsp) | 435 | movq %rax,RAX-ARGOFFSET(%rsp) |
| 436 | ia32_ret_from_sys_call: | ||
| 437 | CLEAR_RREGS -ARGOFFSET | ||
| 428 | jmp int_ret_from_sys_call | 438 | jmp int_ret_from_sys_call |
| 429 | 439 | ||
| 430 | ia32_tracesys: | 440 | ia32_tracesys: |
| @@ -442,8 +452,8 @@ END(ia32_syscall) | |||
| 442 | 452 | ||
| 443 | ia32_badsys: | 453 | ia32_badsys: |
| 444 | movq $0,ORIG_RAX-ARGOFFSET(%rsp) | 454 | movq $0,ORIG_RAX-ARGOFFSET(%rsp) |
| 445 | movq $-ENOSYS,RAX-ARGOFFSET(%rsp) | 455 | movq $-ENOSYS,%rax |
| 446 | jmp int_ret_from_sys_call | 456 | jmp ia32_sysret |
| 447 | 457 | ||
| 448 | quiet_ni_syscall: | 458 | quiet_ni_syscall: |
| 449 | movq $-ENOSYS,%rax | 459 | movq $-ENOSYS,%rax |
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index 41fd965c80c6..b9c830c12b4a 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c | |||
| @@ -206,8 +206,11 @@ static int __init setup_early_printk(char *buf) | |||
| 206 | 206 | ||
| 207 | while (*buf != '\0') { | 207 | while (*buf != '\0') { |
| 208 | if (!strncmp(buf, "serial", 6)) { | 208 | if (!strncmp(buf, "serial", 6)) { |
| 209 | early_serial_init(buf + 6); | 209 | buf += 6; |
| 210 | early_serial_init(buf); | ||
| 210 | early_console_register(&early_serial_console, keep); | 211 | early_console_register(&early_serial_console, keep); |
| 212 | if (!strncmp(buf, ",ttyS", 5)) | ||
| 213 | buf += 5; | ||
| 211 | } | 214 | } |
| 212 | if (!strncmp(buf, "ttyS", 4)) { | 215 | if (!strncmp(buf, "ttyS", 4)) { |
| 213 | early_serial_init(buf + 4); | 216 | early_serial_init(buf + 4); |
diff --git a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c index 1736c5a725aa..9c3bd4a2050e 100644 --- a/arch/x86/kernel/i386_ksyms_32.c +++ b/arch/x86/kernel/i386_ksyms_32.c | |||
| @@ -15,8 +15,10 @@ EXPORT_SYMBOL(mcount); | |||
| 15 | * the export, but dont use it from C code, it is used | 15 | * the export, but dont use it from C code, it is used |
| 16 | * by assembly code and is not using C calling convention! | 16 | * by assembly code and is not using C calling convention! |
| 17 | */ | 17 | */ |
| 18 | #ifndef CONFIG_X86_CMPXCHG64 | ||
| 18 | extern void cmpxchg8b_emu(void); | 19 | extern void cmpxchg8b_emu(void); |
| 19 | EXPORT_SYMBOL(cmpxchg8b_emu); | 20 | EXPORT_SYMBOL(cmpxchg8b_emu); |
| 21 | #endif | ||
| 20 | 22 | ||
| 21 | /* Networking helper routines. */ | 23 | /* Networking helper routines. */ |
| 22 | EXPORT_SYMBOL(csum_partial_copy_generic); | 24 | EXPORT_SYMBOL(csum_partial_copy_generic); |
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 3e549b8ec8c9..85f5db95c60f 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile | |||
| @@ -15,8 +15,10 @@ ifeq ($(CONFIG_X86_32),y) | |||
| 15 | obj-y += atomic64_32.o | 15 | obj-y += atomic64_32.o |
| 16 | lib-y += checksum_32.o | 16 | lib-y += checksum_32.o |
| 17 | lib-y += strstr_32.o | 17 | lib-y += strstr_32.o |
| 18 | lib-y += semaphore_32.o string_32.o cmpxchg8b_emu.o | 18 | lib-y += semaphore_32.o string_32.o |
| 19 | 19 | ifneq ($(CONFIG_X86_CMPXCHG64),y) | |
| 20 | lib-y += cmpxchg8b_emu.o | ||
| 21 | endif | ||
| 20 | lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o | 22 | lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o |
| 21 | else | 23 | else |
| 22 | obj-y += io_64.o iomap_copy_64.o | 24 | obj-y += io_64.o iomap_copy_64.o |
diff --git a/block/blk-barrier.c b/block/blk-barrier.c index 6593ab39cfe9..8873b9b439ff 100644 --- a/block/blk-barrier.c +++ b/block/blk-barrier.c | |||
| @@ -350,6 +350,7 @@ static void blkdev_discard_end_io(struct bio *bio, int err) | |||
| 350 | 350 | ||
| 351 | if (bio->bi_private) | 351 | if (bio->bi_private) |
| 352 | complete(bio->bi_private); | 352 | complete(bio->bi_private); |
| 353 | __free_page(bio_page(bio)); | ||
| 353 | 354 | ||
| 354 | bio_put(bio); | 355 | bio_put(bio); |
| 355 | } | 356 | } |
| @@ -372,30 +373,50 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, | |||
| 372 | struct request_queue *q = bdev_get_queue(bdev); | 373 | struct request_queue *q = bdev_get_queue(bdev); |
| 373 | int type = flags & DISCARD_FL_BARRIER ? | 374 | int type = flags & DISCARD_FL_BARRIER ? |
| 374 | DISCARD_BARRIER : DISCARD_NOBARRIER; | 375 | DISCARD_BARRIER : DISCARD_NOBARRIER; |
| 376 | struct bio *bio; | ||
| 377 | struct page *page; | ||
| 375 | int ret = 0; | 378 | int ret = 0; |
| 376 | 379 | ||
| 377 | if (!q) | 380 | if (!q) |
| 378 | return -ENXIO; | 381 | return -ENXIO; |
| 379 | 382 | ||
| 380 | if (!q->prepare_discard_fn) | 383 | if (!blk_queue_discard(q)) |
| 381 | return -EOPNOTSUPP; | 384 | return -EOPNOTSUPP; |
| 382 | 385 | ||
| 383 | while (nr_sects && !ret) { | 386 | while (nr_sects && !ret) { |
| 384 | struct bio *bio = bio_alloc(gfp_mask, 0); | 387 | unsigned int sector_size = q->limits.logical_block_size; |
| 385 | if (!bio) | 388 | unsigned int max_discard_sectors = |
| 386 | return -ENOMEM; | 389 | min(q->limits.max_discard_sectors, UINT_MAX >> 9); |
| 387 | 390 | ||
| 391 | bio = bio_alloc(gfp_mask, 1); | ||
| 392 | if (!bio) | ||
| 393 | goto out; | ||
| 394 | bio->bi_sector = sector; | ||
| 388 | bio->bi_end_io = blkdev_discard_end_io; | 395 | bio->bi_end_io = blkdev_discard_end_io; |
| 389 | bio->bi_bdev = bdev; | 396 | bio->bi_bdev = bdev; |
| 390 | if (flags & DISCARD_FL_WAIT) | 397 | if (flags & DISCARD_FL_WAIT) |
| 391 | bio->bi_private = &wait; | 398 | bio->bi_private = &wait; |
| 392 | 399 | ||
| 393 | bio->bi_sector = sector; | 400 | /* |
| 401 | * Add a zeroed one-sector payload as that's what | ||
| 402 | * our current implementations need. If we'll ever need | ||
| 403 | * more the interface will need revisiting. | ||
| 404 | */ | ||
| 405 | page = alloc_page(GFP_KERNEL | __GFP_ZERO); | ||
| 406 | if (!page) | ||
| 407 | goto out_free_bio; | ||
| 408 | if (bio_add_pc_page(q, bio, page, sector_size, 0) < sector_size) | ||
| 409 | goto out_free_page; | ||
| 394 | 410 | ||
| 395 | if (nr_sects > queue_max_hw_sectors(q)) { | 411 | /* |
| 396 | bio->bi_size = queue_max_hw_sectors(q) << 9; | 412 | * And override the bio size - the way discard works we |
| 397 | nr_sects -= queue_max_hw_sectors(q); | 413 | * touch many more blocks on disk than the actual payload |
| 398 | sector += queue_max_hw_sectors(q); | 414 | * length. |
| 415 | */ | ||
| 416 | if (nr_sects > max_discard_sectors) { | ||
| 417 | bio->bi_size = max_discard_sectors << 9; | ||
| 418 | nr_sects -= max_discard_sectors; | ||
| 419 | sector += max_discard_sectors; | ||
| 399 | } else { | 420 | } else { |
| 400 | bio->bi_size = nr_sects << 9; | 421 | bio->bi_size = nr_sects << 9; |
| 401 | nr_sects = 0; | 422 | nr_sects = 0; |
| @@ -414,5 +435,11 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, | |||
| 414 | bio_put(bio); | 435 | bio_put(bio); |
| 415 | } | 436 | } |
| 416 | return ret; | 437 | return ret; |
| 438 | out_free_page: | ||
| 439 | __free_page(page); | ||
| 440 | out_free_bio: | ||
| 441 | bio_put(bio); | ||
| 442 | out: | ||
| 443 | return -ENOMEM; | ||
| 417 | } | 444 | } |
| 418 | EXPORT_SYMBOL(blkdev_issue_discard); | 445 | EXPORT_SYMBOL(blkdev_issue_discard); |
diff --git a/block/blk-core.c b/block/blk-core.c index 8135228e4b29..81f34311659a 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include "blk.h" | 34 | #include "blk.h" |
| 35 | 35 | ||
| 36 | EXPORT_TRACEPOINT_SYMBOL_GPL(block_remap); | 36 | EXPORT_TRACEPOINT_SYMBOL_GPL(block_remap); |
| 37 | EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap); | ||
| 37 | EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete); | 38 | EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete); |
| 38 | 39 | ||
| 39 | static int __make_request(struct request_queue *q, struct bio *bio); | 40 | static int __make_request(struct request_queue *q, struct bio *bio); |
| @@ -69,7 +70,7 @@ static void drive_stat_acct(struct request *rq, int new_io) | |||
| 69 | part_stat_inc(cpu, part, merges[rw]); | 70 | part_stat_inc(cpu, part, merges[rw]); |
| 70 | else { | 71 | else { |
| 71 | part_round_stats(cpu, part); | 72 | part_round_stats(cpu, part); |
| 72 | part_inc_in_flight(part, rw); | 73 | part_inc_in_flight(part); |
| 73 | } | 74 | } |
| 74 | 75 | ||
| 75 | part_stat_unlock(); | 76 | part_stat_unlock(); |
| @@ -1031,7 +1032,7 @@ static void part_round_stats_single(int cpu, struct hd_struct *part, | |||
| 1031 | 1032 | ||
| 1032 | if (part->in_flight) { | 1033 | if (part->in_flight) { |
| 1033 | __part_stat_add(cpu, part, time_in_queue, | 1034 | __part_stat_add(cpu, part, time_in_queue, |
| 1034 | part_in_flight(part) * (now - part->stamp)); | 1035 | part->in_flight * (now - part->stamp)); |
| 1035 | __part_stat_add(cpu, part, io_ticks, (now - part->stamp)); | 1036 | __part_stat_add(cpu, part, io_ticks, (now - part->stamp)); |
| 1036 | } | 1037 | } |
| 1037 | part->stamp = now; | 1038 | part->stamp = now; |
| @@ -1124,7 +1125,6 @@ void init_request_from_bio(struct request *req, struct bio *bio) | |||
| 1124 | req->cmd_flags |= REQ_DISCARD; | 1125 | req->cmd_flags |= REQ_DISCARD; |
| 1125 | if (bio_rw_flagged(bio, BIO_RW_BARRIER)) | 1126 | if (bio_rw_flagged(bio, BIO_RW_BARRIER)) |
| 1126 | req->cmd_flags |= REQ_SOFTBARRIER; | 1127 | req->cmd_flags |= REQ_SOFTBARRIER; |
| 1127 | req->q->prepare_discard_fn(req->q, req); | ||
| 1128 | } else if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) | 1128 | } else if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) |
| 1129 | req->cmd_flags |= REQ_HARDBARRIER; | 1129 | req->cmd_flags |= REQ_HARDBARRIER; |
| 1130 | 1130 | ||
| @@ -1437,7 +1437,8 @@ static inline void __generic_make_request(struct bio *bio) | |||
| 1437 | goto end_io; | 1437 | goto end_io; |
| 1438 | } | 1438 | } |
| 1439 | 1439 | ||
| 1440 | if (unlikely(nr_sectors > queue_max_hw_sectors(q))) { | 1440 | if (unlikely(!bio_rw_flagged(bio, BIO_RW_DISCARD) && |
| 1441 | nr_sectors > queue_max_hw_sectors(q))) { | ||
| 1441 | printk(KERN_ERR "bio too big device %s (%u > %u)\n", | 1442 | printk(KERN_ERR "bio too big device %s (%u > %u)\n", |
| 1442 | bdevname(bio->bi_bdev, b), | 1443 | bdevname(bio->bi_bdev, b), |
| 1443 | bio_sectors(bio), | 1444 | bio_sectors(bio), |
| @@ -1470,7 +1471,7 @@ static inline void __generic_make_request(struct bio *bio) | |||
| 1470 | goto end_io; | 1471 | goto end_io; |
| 1471 | 1472 | ||
| 1472 | if (bio_rw_flagged(bio, BIO_RW_DISCARD) && | 1473 | if (bio_rw_flagged(bio, BIO_RW_DISCARD) && |
| 1473 | !q->prepare_discard_fn) { | 1474 | !blk_queue_discard(q)) { |
| 1474 | err = -EOPNOTSUPP; | 1475 | err = -EOPNOTSUPP; |
| 1475 | goto end_io; | 1476 | goto end_io; |
| 1476 | } | 1477 | } |
| @@ -1738,7 +1739,7 @@ static void blk_account_io_done(struct request *req) | |||
| 1738 | part_stat_inc(cpu, part, ios[rw]); | 1739 | part_stat_inc(cpu, part, ios[rw]); |
| 1739 | part_stat_add(cpu, part, ticks[rw], duration); | 1740 | part_stat_add(cpu, part, ticks[rw], duration); |
| 1740 | part_round_stats(cpu, part); | 1741 | part_round_stats(cpu, part); |
| 1741 | part_dec_in_flight(part, rw); | 1742 | part_dec_in_flight(part); |
| 1742 | 1743 | ||
| 1743 | part_stat_unlock(); | 1744 | part_stat_unlock(); |
| 1744 | } | 1745 | } |
| @@ -2491,6 +2492,14 @@ int kblockd_schedule_work(struct request_queue *q, struct work_struct *work) | |||
| 2491 | } | 2492 | } |
| 2492 | EXPORT_SYMBOL(kblockd_schedule_work); | 2493 | EXPORT_SYMBOL(kblockd_schedule_work); |
| 2493 | 2494 | ||
| 2495 | int kblockd_schedule_delayed_work(struct request_queue *q, | ||
| 2496 | struct delayed_work *work, | ||
| 2497 | unsigned long delay) | ||
| 2498 | { | ||
| 2499 | return queue_delayed_work(kblockd_workqueue, work, delay); | ||
| 2500 | } | ||
| 2501 | EXPORT_SYMBOL(kblockd_schedule_delayed_work); | ||
| 2502 | |||
| 2494 | int __init blk_dev_init(void) | 2503 | int __init blk_dev_init(void) |
| 2495 | { | 2504 | { |
| 2496 | BUILD_BUG_ON(__REQ_NR_BITS > 8 * | 2505 | BUILD_BUG_ON(__REQ_NR_BITS > 8 * |
diff --git a/block/blk-merge.c b/block/blk-merge.c index 99cb5cf1f447..b0de8574fdc8 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
| @@ -351,7 +351,7 @@ static void blk_account_io_merge(struct request *req) | |||
| 351 | part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req)); | 351 | part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req)); |
| 352 | 352 | ||
| 353 | part_round_stats(cpu, part); | 353 | part_round_stats(cpu, part); |
| 354 | part_dec_in_flight(part, rq_data_dir(req)); | 354 | part_dec_in_flight(part); |
| 355 | 355 | ||
| 356 | part_stat_unlock(); | 356 | part_stat_unlock(); |
| 357 | } | 357 | } |
diff --git a/block/blk-settings.c b/block/blk-settings.c index 83413ff83739..e0695bca7027 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c | |||
| @@ -34,23 +34,6 @@ void blk_queue_prep_rq(struct request_queue *q, prep_rq_fn *pfn) | |||
| 34 | EXPORT_SYMBOL(blk_queue_prep_rq); | 34 | EXPORT_SYMBOL(blk_queue_prep_rq); |
| 35 | 35 | ||
| 36 | /** | 36 | /** |
| 37 | * blk_queue_set_discard - set a discard_sectors function for queue | ||
| 38 | * @q: queue | ||
| 39 | * @dfn: prepare_discard function | ||
| 40 | * | ||
| 41 | * It's possible for a queue to register a discard callback which is used | ||
| 42 | * to transform a discard request into the appropriate type for the | ||
| 43 | * hardware. If none is registered, then discard requests are failed | ||
| 44 | * with %EOPNOTSUPP. | ||
| 45 | * | ||
| 46 | */ | ||
| 47 | void blk_queue_set_discard(struct request_queue *q, prepare_discard_fn *dfn) | ||
| 48 | { | ||
| 49 | q->prepare_discard_fn = dfn; | ||
| 50 | } | ||
| 51 | EXPORT_SYMBOL(blk_queue_set_discard); | ||
| 52 | |||
| 53 | /** | ||
| 54 | * blk_queue_merge_bvec - set a merge_bvec function for queue | 37 | * blk_queue_merge_bvec - set a merge_bvec function for queue |
| 55 | * @q: queue | 38 | * @q: queue |
| 56 | * @mbfn: merge_bvec_fn | 39 | * @mbfn: merge_bvec_fn |
| @@ -111,7 +94,9 @@ void blk_set_default_limits(struct queue_limits *lim) | |||
| 111 | lim->max_hw_segments = MAX_HW_SEGMENTS; | 94 | lim->max_hw_segments = MAX_HW_SEGMENTS; |
| 112 | lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK; | 95 | lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK; |
| 113 | lim->max_segment_size = MAX_SEGMENT_SIZE; | 96 | lim->max_segment_size = MAX_SEGMENT_SIZE; |
| 114 | lim->max_sectors = lim->max_hw_sectors = SAFE_MAX_SECTORS; | 97 | lim->max_sectors = BLK_DEF_MAX_SECTORS; |
| 98 | lim->max_hw_sectors = INT_MAX; | ||
| 99 | lim->max_discard_sectors = SAFE_MAX_SECTORS; | ||
| 115 | lim->logical_block_size = lim->physical_block_size = lim->io_min = 512; | 100 | lim->logical_block_size = lim->physical_block_size = lim->io_min = 512; |
| 116 | lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT); | 101 | lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT); |
| 117 | lim->alignment_offset = 0; | 102 | lim->alignment_offset = 0; |
| @@ -164,6 +149,7 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn) | |||
| 164 | q->unplug_timer.data = (unsigned long)q; | 149 | q->unplug_timer.data = (unsigned long)q; |
| 165 | 150 | ||
| 166 | blk_set_default_limits(&q->limits); | 151 | blk_set_default_limits(&q->limits); |
| 152 | blk_queue_max_sectors(q, SAFE_MAX_SECTORS); | ||
| 167 | 153 | ||
| 168 | /* | 154 | /* |
| 169 | * If the caller didn't supply a lock, fall back to our embedded | 155 | * If the caller didn't supply a lock, fall back to our embedded |
| @@ -254,6 +240,18 @@ void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_sectors) | |||
| 254 | EXPORT_SYMBOL(blk_queue_max_hw_sectors); | 240 | EXPORT_SYMBOL(blk_queue_max_hw_sectors); |
| 255 | 241 | ||
| 256 | /** | 242 | /** |
| 243 | * blk_queue_max_discard_sectors - set max sectors for a single discard | ||
| 244 | * @q: the request queue for the device | ||
| 245 | * @max_discard: maximum number of sectors to discard | ||
| 246 | **/ | ||
| 247 | void blk_queue_max_discard_sectors(struct request_queue *q, | ||
| 248 | unsigned int max_discard_sectors) | ||
| 249 | { | ||
| 250 | q->limits.max_discard_sectors = max_discard_sectors; | ||
| 251 | } | ||
| 252 | EXPORT_SYMBOL(blk_queue_max_discard_sectors); | ||
| 253 | |||
| 254 | /** | ||
| 257 | * blk_queue_max_phys_segments - set max phys segments for a request for this queue | 255 | * blk_queue_max_phys_segments - set max phys segments for a request for this queue |
| 258 | * @q: the request queue for the device | 256 | * @q: the request queue for the device |
| 259 | * @max_segments: max number of segments | 257 | * @max_segments: max number of segments |
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index b78c9c3e2670..8a6d81afb284 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c | |||
| @@ -452,6 +452,7 @@ int blk_register_queue(struct gendisk *disk) | |||
| 452 | if (ret) { | 452 | if (ret) { |
| 453 | kobject_uevent(&q->kobj, KOBJ_REMOVE); | 453 | kobject_uevent(&q->kobj, KOBJ_REMOVE); |
| 454 | kobject_del(&q->kobj); | 454 | kobject_del(&q->kobj); |
| 455 | blk_trace_remove_sysfs(disk_to_dev(disk)); | ||
| 455 | return ret; | 456 | return ret; |
| 456 | } | 457 | } |
| 457 | 458 | ||
| @@ -465,11 +466,11 @@ void blk_unregister_queue(struct gendisk *disk) | |||
| 465 | if (WARN_ON(!q)) | 466 | if (WARN_ON(!q)) |
| 466 | return; | 467 | return; |
| 467 | 468 | ||
| 468 | if (q->request_fn) { | 469 | if (q->request_fn) |
| 469 | elv_unregister_queue(q); | 470 | elv_unregister_queue(q); |
| 470 | 471 | ||
| 471 | kobject_uevent(&q->kobj, KOBJ_REMOVE); | 472 | kobject_uevent(&q->kobj, KOBJ_REMOVE); |
| 472 | kobject_del(&q->kobj); | 473 | kobject_del(&q->kobj); |
| 473 | kobject_put(&disk_to_dev(disk)->kobj); | 474 | blk_trace_remove_sysfs(disk_to_dev(disk)); |
| 474 | } | 475 | kobject_put(&disk_to_dev(disk)->kobj); |
| 475 | } | 476 | } |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 1ca813b16e78..9c4b679908f4 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
| @@ -150,7 +150,7 @@ struct cfq_data { | |||
| 150 | * idle window management | 150 | * idle window management |
| 151 | */ | 151 | */ |
| 152 | struct timer_list idle_slice_timer; | 152 | struct timer_list idle_slice_timer; |
| 153 | struct work_struct unplug_work; | 153 | struct delayed_work unplug_work; |
| 154 | 154 | ||
| 155 | struct cfq_queue *active_queue; | 155 | struct cfq_queue *active_queue; |
| 156 | struct cfq_io_context *active_cic; | 156 | struct cfq_io_context *active_cic; |
| @@ -173,6 +173,7 @@ struct cfq_data { | |||
| 173 | unsigned int cfq_slice[2]; | 173 | unsigned int cfq_slice[2]; |
| 174 | unsigned int cfq_slice_async_rq; | 174 | unsigned int cfq_slice_async_rq; |
| 175 | unsigned int cfq_slice_idle; | 175 | unsigned int cfq_slice_idle; |
| 176 | unsigned int cfq_latency; | ||
| 176 | 177 | ||
| 177 | struct list_head cic_list; | 178 | struct list_head cic_list; |
| 178 | 179 | ||
| @@ -180,6 +181,8 @@ struct cfq_data { | |||
| 180 | * Fallback dummy cfqq for extreme OOM conditions | 181 | * Fallback dummy cfqq for extreme OOM conditions |
| 181 | */ | 182 | */ |
| 182 | struct cfq_queue oom_cfqq; | 183 | struct cfq_queue oom_cfqq; |
| 184 | |||
| 185 | unsigned long last_end_sync_rq; | ||
| 183 | }; | 186 | }; |
| 184 | 187 | ||
| 185 | enum cfqq_state_flags { | 188 | enum cfqq_state_flags { |
| @@ -265,11 +268,13 @@ static inline int cfq_bio_sync(struct bio *bio) | |||
| 265 | * scheduler run of queue, if there are requests pending and no one in the | 268 | * scheduler run of queue, if there are requests pending and no one in the |
| 266 | * driver that will restart queueing | 269 | * driver that will restart queueing |
| 267 | */ | 270 | */ |
| 268 | static inline void cfq_schedule_dispatch(struct cfq_data *cfqd) | 271 | static inline void cfq_schedule_dispatch(struct cfq_data *cfqd, |
| 272 | unsigned long delay) | ||
| 269 | { | 273 | { |
| 270 | if (cfqd->busy_queues) { | 274 | if (cfqd->busy_queues) { |
| 271 | cfq_log(cfqd, "schedule dispatch"); | 275 | cfq_log(cfqd, "schedule dispatch"); |
| 272 | kblockd_schedule_work(cfqd->queue, &cfqd->unplug_work); | 276 | kblockd_schedule_delayed_work(cfqd->queue, &cfqd->unplug_work, |
| 277 | delay); | ||
| 273 | } | 278 | } |
| 274 | } | 279 | } |
| 275 | 280 | ||
| @@ -1326,12 +1331,30 @@ static int cfq_dispatch_requests(struct request_queue *q, int force) | |||
| 1326 | return 0; | 1331 | return 0; |
| 1327 | 1332 | ||
| 1328 | /* | 1333 | /* |
| 1329 | * we are the only queue, allow up to 4 times of 'quantum' | 1334 | * Sole queue user, allow bigger slice |
| 1330 | */ | 1335 | */ |
| 1331 | if (cfqq->dispatched >= 4 * max_dispatch) | 1336 | max_dispatch *= 4; |
| 1332 | return 0; | 1337 | } |
| 1338 | |||
| 1339 | /* | ||
| 1340 | * Async queues must wait a bit before being allowed dispatch. | ||
| 1341 | * We also ramp up the dispatch depth gradually for async IO, | ||
| 1342 | * based on the last sync IO we serviced | ||
| 1343 | */ | ||
| 1344 | if (!cfq_cfqq_sync(cfqq) && cfqd->cfq_latency) { | ||
| 1345 | unsigned long last_sync = jiffies - cfqd->last_end_sync_rq; | ||
| 1346 | unsigned int depth; | ||
| 1347 | |||
| 1348 | depth = last_sync / cfqd->cfq_slice[1]; | ||
| 1349 | if (!depth && !cfqq->dispatched) | ||
| 1350 | depth = 1; | ||
| 1351 | if (depth < max_dispatch) | ||
| 1352 | max_dispatch = depth; | ||
| 1333 | } | 1353 | } |
| 1334 | 1354 | ||
| 1355 | if (cfqq->dispatched >= max_dispatch) | ||
| 1356 | return 0; | ||
| 1357 | |||
| 1335 | /* | 1358 | /* |
| 1336 | * Dispatch a request from this cfqq | 1359 | * Dispatch a request from this cfqq |
| 1337 | */ | 1360 | */ |
| @@ -1376,7 +1399,7 @@ static void cfq_put_queue(struct cfq_queue *cfqq) | |||
| 1376 | 1399 | ||
| 1377 | if (unlikely(cfqd->active_queue == cfqq)) { | 1400 | if (unlikely(cfqd->active_queue == cfqq)) { |
| 1378 | __cfq_slice_expired(cfqd, cfqq, 0); | 1401 | __cfq_slice_expired(cfqd, cfqq, 0); |
| 1379 | cfq_schedule_dispatch(cfqd); | 1402 | cfq_schedule_dispatch(cfqd, 0); |
| 1380 | } | 1403 | } |
| 1381 | 1404 | ||
| 1382 | kmem_cache_free(cfq_pool, cfqq); | 1405 | kmem_cache_free(cfq_pool, cfqq); |
| @@ -1471,7 +1494,7 @@ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) | |||
| 1471 | { | 1494 | { |
| 1472 | if (unlikely(cfqq == cfqd->active_queue)) { | 1495 | if (unlikely(cfqq == cfqd->active_queue)) { |
| 1473 | __cfq_slice_expired(cfqd, cfqq, 0); | 1496 | __cfq_slice_expired(cfqd, cfqq, 0); |
| 1474 | cfq_schedule_dispatch(cfqd); | 1497 | cfq_schedule_dispatch(cfqd, 0); |
| 1475 | } | 1498 | } |
| 1476 | 1499 | ||
| 1477 | cfq_put_queue(cfqq); | 1500 | cfq_put_queue(cfqq); |
| @@ -1951,7 +1974,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
| 1951 | enable_idle = old_idle = cfq_cfqq_idle_window(cfqq); | 1974 | enable_idle = old_idle = cfq_cfqq_idle_window(cfqq); |
| 1952 | 1975 | ||
| 1953 | if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle || | 1976 | if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle || |
| 1954 | (cfqd->hw_tag && CIC_SEEKY(cic))) | 1977 | (!cfqd->cfq_latency && cfqd->hw_tag && CIC_SEEKY(cic))) |
| 1955 | enable_idle = 0; | 1978 | enable_idle = 0; |
| 1956 | else if (sample_valid(cic->ttime_samples)) { | 1979 | else if (sample_valid(cic->ttime_samples)) { |
| 1957 | if (cic->ttime_mean > cfqd->cfq_slice_idle) | 1980 | if (cic->ttime_mean > cfqd->cfq_slice_idle) |
| @@ -2157,8 +2180,10 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) | |||
| 2157 | if (cfq_cfqq_sync(cfqq)) | 2180 | if (cfq_cfqq_sync(cfqq)) |
| 2158 | cfqd->sync_flight--; | 2181 | cfqd->sync_flight--; |
| 2159 | 2182 | ||
| 2160 | if (sync) | 2183 | if (sync) { |
| 2161 | RQ_CIC(rq)->last_end_request = now; | 2184 | RQ_CIC(rq)->last_end_request = now; |
| 2185 | cfqd->last_end_sync_rq = now; | ||
| 2186 | } | ||
| 2162 | 2187 | ||
| 2163 | /* | 2188 | /* |
| 2164 | * If this is the active queue, check if it needs to be expired, | 2189 | * If this is the active queue, check if it needs to be expired, |
| @@ -2186,7 +2211,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) | |||
| 2186 | } | 2211 | } |
| 2187 | 2212 | ||
| 2188 | if (!rq_in_driver(cfqd)) | 2213 | if (!rq_in_driver(cfqd)) |
| 2189 | cfq_schedule_dispatch(cfqd); | 2214 | cfq_schedule_dispatch(cfqd, 0); |
| 2190 | } | 2215 | } |
| 2191 | 2216 | ||
| 2192 | /* | 2217 | /* |
| @@ -2316,7 +2341,7 @@ queue_fail: | |||
| 2316 | if (cic) | 2341 | if (cic) |
| 2317 | put_io_context(cic->ioc); | 2342 | put_io_context(cic->ioc); |
| 2318 | 2343 | ||
| 2319 | cfq_schedule_dispatch(cfqd); | 2344 | cfq_schedule_dispatch(cfqd, 0); |
| 2320 | spin_unlock_irqrestore(q->queue_lock, flags); | 2345 | spin_unlock_irqrestore(q->queue_lock, flags); |
| 2321 | cfq_log(cfqd, "set_request fail"); | 2346 | cfq_log(cfqd, "set_request fail"); |
| 2322 | return 1; | 2347 | return 1; |
| @@ -2325,7 +2350,7 @@ queue_fail: | |||
| 2325 | static void cfq_kick_queue(struct work_struct *work) | 2350 | static void cfq_kick_queue(struct work_struct *work) |
| 2326 | { | 2351 | { |
| 2327 | struct cfq_data *cfqd = | 2352 | struct cfq_data *cfqd = |
| 2328 | container_of(work, struct cfq_data, unplug_work); | 2353 | container_of(work, struct cfq_data, unplug_work.work); |
| 2329 | struct request_queue *q = cfqd->queue; | 2354 | struct request_queue *q = cfqd->queue; |
| 2330 | 2355 | ||
| 2331 | spin_lock_irq(q->queue_lock); | 2356 | spin_lock_irq(q->queue_lock); |
| @@ -2379,7 +2404,7 @@ static void cfq_idle_slice_timer(unsigned long data) | |||
| 2379 | expire: | 2404 | expire: |
| 2380 | cfq_slice_expired(cfqd, timed_out); | 2405 | cfq_slice_expired(cfqd, timed_out); |
| 2381 | out_kick: | 2406 | out_kick: |
| 2382 | cfq_schedule_dispatch(cfqd); | 2407 | cfq_schedule_dispatch(cfqd, 0); |
| 2383 | out_cont: | 2408 | out_cont: |
| 2384 | spin_unlock_irqrestore(cfqd->queue->queue_lock, flags); | 2409 | spin_unlock_irqrestore(cfqd->queue->queue_lock, flags); |
| 2385 | } | 2410 | } |
| @@ -2387,7 +2412,7 @@ out_cont: | |||
| 2387 | static void cfq_shutdown_timer_wq(struct cfq_data *cfqd) | 2412 | static void cfq_shutdown_timer_wq(struct cfq_data *cfqd) |
| 2388 | { | 2413 | { |
| 2389 | del_timer_sync(&cfqd->idle_slice_timer); | 2414 | del_timer_sync(&cfqd->idle_slice_timer); |
| 2390 | cancel_work_sync(&cfqd->unplug_work); | 2415 | cancel_delayed_work_sync(&cfqd->unplug_work); |
| 2391 | } | 2416 | } |
| 2392 | 2417 | ||
| 2393 | static void cfq_put_async_queues(struct cfq_data *cfqd) | 2418 | static void cfq_put_async_queues(struct cfq_data *cfqd) |
| @@ -2469,7 +2494,7 @@ static void *cfq_init_queue(struct request_queue *q) | |||
| 2469 | cfqd->idle_slice_timer.function = cfq_idle_slice_timer; | 2494 | cfqd->idle_slice_timer.function = cfq_idle_slice_timer; |
| 2470 | cfqd->idle_slice_timer.data = (unsigned long) cfqd; | 2495 | cfqd->idle_slice_timer.data = (unsigned long) cfqd; |
| 2471 | 2496 | ||
| 2472 | INIT_WORK(&cfqd->unplug_work, cfq_kick_queue); | 2497 | INIT_DELAYED_WORK(&cfqd->unplug_work, cfq_kick_queue); |
| 2473 | 2498 | ||
| 2474 | cfqd->cfq_quantum = cfq_quantum; | 2499 | cfqd->cfq_quantum = cfq_quantum; |
| 2475 | cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0]; | 2500 | cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0]; |
| @@ -2480,8 +2505,9 @@ static void *cfq_init_queue(struct request_queue *q) | |||
| 2480 | cfqd->cfq_slice[1] = cfq_slice_sync; | 2505 | cfqd->cfq_slice[1] = cfq_slice_sync; |
| 2481 | cfqd->cfq_slice_async_rq = cfq_slice_async_rq; | 2506 | cfqd->cfq_slice_async_rq = cfq_slice_async_rq; |
| 2482 | cfqd->cfq_slice_idle = cfq_slice_idle; | 2507 | cfqd->cfq_slice_idle = cfq_slice_idle; |
| 2508 | cfqd->cfq_latency = 1; | ||
| 2483 | cfqd->hw_tag = 1; | 2509 | cfqd->hw_tag = 1; |
| 2484 | 2510 | cfqd->last_end_sync_rq = jiffies; | |
| 2485 | return cfqd; | 2511 | return cfqd; |
| 2486 | } | 2512 | } |
| 2487 | 2513 | ||
| @@ -2549,6 +2575,7 @@ SHOW_FUNCTION(cfq_slice_idle_show, cfqd->cfq_slice_idle, 1); | |||
| 2549 | SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1); | 2575 | SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1); |
| 2550 | SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1); | 2576 | SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1); |
| 2551 | SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0); | 2577 | SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0); |
| 2578 | SHOW_FUNCTION(cfq_low_latency_show, cfqd->cfq_latency, 0); | ||
| 2552 | #undef SHOW_FUNCTION | 2579 | #undef SHOW_FUNCTION |
| 2553 | 2580 | ||
| 2554 | #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ | 2581 | #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ |
| @@ -2580,6 +2607,7 @@ STORE_FUNCTION(cfq_slice_sync_store, &cfqd->cfq_slice[1], 1, UINT_MAX, 1); | |||
| 2580 | STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1); | 2607 | STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1); |
| 2581 | STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, | 2608 | STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, |
| 2582 | UINT_MAX, 0); | 2609 | UINT_MAX, 0); |
| 2610 | STORE_FUNCTION(cfq_low_latency_store, &cfqd->cfq_latency, 0, 1, 0); | ||
| 2583 | #undef STORE_FUNCTION | 2611 | #undef STORE_FUNCTION |
| 2584 | 2612 | ||
| 2585 | #define CFQ_ATTR(name) \ | 2613 | #define CFQ_ATTR(name) \ |
| @@ -2595,6 +2623,7 @@ static struct elv_fs_entry cfq_attrs[] = { | |||
| 2595 | CFQ_ATTR(slice_async), | 2623 | CFQ_ATTR(slice_async), |
| 2596 | CFQ_ATTR(slice_async_rq), | 2624 | CFQ_ATTR(slice_async_rq), |
| 2597 | CFQ_ATTR(slice_idle), | 2625 | CFQ_ATTR(slice_idle), |
| 2626 | CFQ_ATTR(low_latency), | ||
| 2598 | __ATTR_NULL | 2627 | __ATTR_NULL |
| 2599 | }; | 2628 | }; |
| 2600 | 2629 | ||
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c index 7865a34e0faa..9bd086c1a4d5 100644 --- a/block/compat_ioctl.c +++ b/block/compat_ioctl.c | |||
| @@ -21,6 +21,11 @@ static int compat_put_int(unsigned long arg, int val) | |||
| 21 | return put_user(val, (compat_int_t __user *)compat_ptr(arg)); | 21 | return put_user(val, (compat_int_t __user *)compat_ptr(arg)); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | static int compat_put_uint(unsigned long arg, unsigned int val) | ||
| 25 | { | ||
| 26 | return put_user(val, (compat_uint_t __user *)compat_ptr(arg)); | ||
| 27 | } | ||
| 28 | |||
| 24 | static int compat_put_long(unsigned long arg, long val) | 29 | static int compat_put_long(unsigned long arg, long val) |
| 25 | { | 30 | { |
| 26 | return put_user(val, (compat_long_t __user *)compat_ptr(arg)); | 31 | return put_user(val, (compat_long_t __user *)compat_ptr(arg)); |
| @@ -734,6 +739,14 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
| 734 | switch (cmd) { | 739 | switch (cmd) { |
| 735 | case HDIO_GETGEO: | 740 | case HDIO_GETGEO: |
| 736 | return compat_hdio_getgeo(disk, bdev, compat_ptr(arg)); | 741 | return compat_hdio_getgeo(disk, bdev, compat_ptr(arg)); |
| 742 | case BLKPBSZGET: | ||
| 743 | return compat_put_uint(arg, bdev_physical_block_size(bdev)); | ||
| 744 | case BLKIOMIN: | ||
| 745 | return compat_put_uint(arg, bdev_io_min(bdev)); | ||
| 746 | case BLKIOOPT: | ||
| 747 | return compat_put_uint(arg, bdev_io_opt(bdev)); | ||
| 748 | case BLKALIGNOFF: | ||
| 749 | return compat_put_int(arg, bdev_alignment_offset(bdev)); | ||
| 737 | case BLKFLSBUF: | 750 | case BLKFLSBUF: |
| 738 | case BLKROSET: | 751 | case BLKROSET: |
| 739 | case BLKDISCARD: | 752 | case BLKDISCARD: |
diff --git a/block/genhd.c b/block/genhd.c index 517e4332cb37..5a0861da324d 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
| @@ -869,7 +869,6 @@ static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); | |||
| 869 | static DEVICE_ATTR(alignment_offset, S_IRUGO, disk_alignment_offset_show, NULL); | 869 | static DEVICE_ATTR(alignment_offset, S_IRUGO, disk_alignment_offset_show, NULL); |
| 870 | static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL); | 870 | static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL); |
| 871 | static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); | 871 | static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); |
| 872 | static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL); | ||
| 873 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 872 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
| 874 | static struct device_attribute dev_attr_fail = | 873 | static struct device_attribute dev_attr_fail = |
| 875 | __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store); | 874 | __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store); |
| @@ -889,7 +888,6 @@ static struct attribute *disk_attrs[] = { | |||
| 889 | &dev_attr_alignment_offset.attr, | 888 | &dev_attr_alignment_offset.attr, |
| 890 | &dev_attr_capability.attr, | 889 | &dev_attr_capability.attr, |
| 891 | &dev_attr_stat.attr, | 890 | &dev_attr_stat.attr, |
| 892 | &dev_attr_inflight.attr, | ||
| 893 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 891 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
| 894 | &dev_attr_fail.attr, | 892 | &dev_attr_fail.attr, |
| 895 | #endif | 893 | #endif |
| @@ -1055,7 +1053,7 @@ static int diskstats_show(struct seq_file *seqf, void *v) | |||
| 1055 | part_stat_read(hd, merges[1]), | 1053 | part_stat_read(hd, merges[1]), |
| 1056 | (unsigned long long)part_stat_read(hd, sectors[1]), | 1054 | (unsigned long long)part_stat_read(hd, sectors[1]), |
| 1057 | jiffies_to_msecs(part_stat_read(hd, ticks[1])), | 1055 | jiffies_to_msecs(part_stat_read(hd, ticks[1])), |
| 1058 | part_in_flight(hd), | 1056 | hd->in_flight, |
| 1059 | jiffies_to_msecs(part_stat_read(hd, io_ticks)), | 1057 | jiffies_to_msecs(part_stat_read(hd, io_ticks)), |
| 1060 | jiffies_to_msecs(part_stat_read(hd, time_in_queue)) | 1058 | jiffies_to_msecs(part_stat_read(hd, time_in_queue)) |
| 1061 | ); | 1059 | ); |
diff --git a/block/ioctl.c b/block/ioctl.c index d3e6b5827a34..1f4d1de12b09 100644 --- a/block/ioctl.c +++ b/block/ioctl.c | |||
| @@ -138,6 +138,11 @@ static int put_int(unsigned long arg, int val) | |||
| 138 | return put_user(val, (int __user *)arg); | 138 | return put_user(val, (int __user *)arg); |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | static int put_uint(unsigned long arg, unsigned int val) | ||
| 142 | { | ||
| 143 | return put_user(val, (unsigned int __user *)arg); | ||
| 144 | } | ||
| 145 | |||
| 141 | static int put_long(unsigned long arg, long val) | 146 | static int put_long(unsigned long arg, long val) |
| 142 | { | 147 | { |
| 143 | return put_user(val, (long __user *)arg); | 148 | return put_user(val, (long __user *)arg); |
| @@ -263,10 +268,18 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, | |||
| 263 | return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512); | 268 | return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512); |
| 264 | case BLKROGET: | 269 | case BLKROGET: |
| 265 | return put_int(arg, bdev_read_only(bdev) != 0); | 270 | return put_int(arg, bdev_read_only(bdev) != 0); |
| 266 | case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */ | 271 | case BLKBSZGET: /* get block device soft block size (cf. BLKSSZGET) */ |
| 267 | return put_int(arg, block_size(bdev)); | 272 | return put_int(arg, block_size(bdev)); |
| 268 | case BLKSSZGET: /* get block device hardware sector size */ | 273 | case BLKSSZGET: /* get block device logical block size */ |
| 269 | return put_int(arg, bdev_logical_block_size(bdev)); | 274 | return put_int(arg, bdev_logical_block_size(bdev)); |
| 275 | case BLKPBSZGET: /* get block device physical block size */ | ||
| 276 | return put_uint(arg, bdev_physical_block_size(bdev)); | ||
| 277 | case BLKIOMIN: | ||
| 278 | return put_uint(arg, bdev_io_min(bdev)); | ||
| 279 | case BLKIOOPT: | ||
| 280 | return put_uint(arg, bdev_io_opt(bdev)); | ||
| 281 | case BLKALIGNOFF: | ||
| 282 | return put_int(arg, bdev_alignment_offset(bdev)); | ||
| 270 | case BLKSECTGET: | 283 | case BLKSECTGET: |
| 271 | return put_ushort(arg, queue_max_sectors(bdev_get_queue(bdev))); | 284 | return put_ushort(arg, queue_max_sectors(bdev_get_queue(bdev))); |
| 272 | case BLKRASET: | 285 | case BLKRASET: |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index dd8729d674e5..0ed42d8870c7 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
| @@ -211,6 +211,18 @@ config ACPI_HOTPLUG_CPU | |||
| 211 | select ACPI_CONTAINER | 211 | select ACPI_CONTAINER |
| 212 | default y | 212 | default y |
| 213 | 213 | ||
| 214 | config ACPI_PROCESSOR_AGGREGATOR | ||
| 215 | tristate "Processor Aggregator" | ||
| 216 | depends on ACPI_PROCESSOR | ||
| 217 | depends on EXPERIMENTAL | ||
| 218 | depends on X86 | ||
| 219 | help | ||
| 220 | ACPI 4.0 defines processor Aggregator, which enables OS to perform | ||
| 221 | specfic processor configuration and control that applies to all | ||
| 222 | processors in the platform. Currently only logical processor idling | ||
| 223 | is defined, which is to reduce power consumption. This driver | ||
| 224 | support the new device. | ||
| 225 | |||
| 214 | config ACPI_THERMAL | 226 | config ACPI_THERMAL |
| 215 | tristate "Thermal Zone" | 227 | tristate "Thermal Zone" |
| 216 | depends on ACPI_PROCESSOR | 228 | depends on ACPI_PROCESSOR |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 82cd49dc603b..7702118509a0 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
| @@ -62,3 +62,5 @@ obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o | |||
| 62 | processor-y := processor_core.o processor_throttling.o | 62 | processor-y := processor_core.o processor_throttling.o |
| 63 | processor-y += processor_idle.o processor_thermal.o | 63 | processor-y += processor_idle.o processor_thermal.o |
| 64 | processor-$(CONFIG_CPU_FREQ) += processor_perflib.o | 64 | processor-$(CONFIG_CPU_FREQ) += processor_perflib.o |
| 65 | |||
| 66 | obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o | ||
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c new file mode 100644 index 000000000000..0d2cdb86158b --- /dev/null +++ b/drivers/acpi/acpi_pad.c | |||
| @@ -0,0 +1,514 @@ | |||
| 1 | /* | ||
| 2 | * acpi_pad.c ACPI Processor Aggregator Driver | ||
| 3 | * | ||
| 4 | * Copyright (c) 2009, Intel Corporation. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms and conditions of the GNU General Public License, | ||
| 8 | * version 2, as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 13 | * more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License along with | ||
| 16 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 17 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 18 | * | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/kernel.h> | ||
| 22 | #include <linux/cpumask.h> | ||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/init.h> | ||
| 25 | #include <linux/types.h> | ||
| 26 | #include <linux/kthread.h> | ||
| 27 | #include <linux/freezer.h> | ||
| 28 | #include <linux/cpu.h> | ||
| 29 | #include <linux/clockchips.h> | ||
| 30 | #include <acpi/acpi_bus.h> | ||
| 31 | #include <acpi/acpi_drivers.h> | ||
| 32 | |||
| 33 | #define ACPI_PROCESSOR_AGGREGATOR_CLASS "processor_aggregator" | ||
| 34 | #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" | ||
| 35 | #define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80 | ||
| 36 | static DEFINE_MUTEX(isolated_cpus_lock); | ||
| 37 | |||
| 38 | #define MWAIT_SUBSTATE_MASK (0xf) | ||
| 39 | #define MWAIT_CSTATE_MASK (0xf) | ||
| 40 | #define MWAIT_SUBSTATE_SIZE (4) | ||
| 41 | #define CPUID_MWAIT_LEAF (5) | ||
| 42 | #define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1) | ||
| 43 | #define CPUID5_ECX_INTERRUPT_BREAK (0x2) | ||
| 44 | static unsigned long power_saving_mwait_eax; | ||
| 45 | static void power_saving_mwait_init(void) | ||
| 46 | { | ||
| 47 | unsigned int eax, ebx, ecx, edx; | ||
| 48 | unsigned int highest_cstate = 0; | ||
| 49 | unsigned int highest_subcstate = 0; | ||
| 50 | int i; | ||
| 51 | |||
| 52 | if (!boot_cpu_has(X86_FEATURE_MWAIT)) | ||
| 53 | return; | ||
| 54 | if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) | ||
| 55 | return; | ||
| 56 | |||
| 57 | cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx); | ||
| 58 | |||
| 59 | if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) || | ||
| 60 | !(ecx & CPUID5_ECX_INTERRUPT_BREAK)) | ||
| 61 | return; | ||
| 62 | |||
| 63 | edx >>= MWAIT_SUBSTATE_SIZE; | ||
| 64 | for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) { | ||
| 65 | if (edx & MWAIT_SUBSTATE_MASK) { | ||
| 66 | highest_cstate = i; | ||
| 67 | highest_subcstate = edx & MWAIT_SUBSTATE_MASK; | ||
| 68 | } | ||
| 69 | } | ||
| 70 | power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) | | ||
| 71 | (highest_subcstate - 1); | ||
| 72 | |||
| 73 | for_each_online_cpu(i) | ||
| 74 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &i); | ||
| 75 | |||
| 76 | #if defined(CONFIG_GENERIC_TIME) && defined(CONFIG_X86) | ||
| 77 | switch (boot_cpu_data.x86_vendor) { | ||
| 78 | case X86_VENDOR_AMD: | ||
| 79 | case X86_VENDOR_INTEL: | ||
| 80 | /* | ||
| 81 | * AMD Fam10h TSC will tick in all | ||
| 82 | * C/P/S0/S1 states when this bit is set. | ||
| 83 | */ | ||
| 84 | if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) | ||
| 85 | return; | ||
| 86 | |||
| 87 | /*FALL THROUGH*/ | ||
| 88 | default: | ||
| 89 | /* TSC could halt in idle, so notify users */ | ||
| 90 | mark_tsc_unstable("TSC halts in idle"); | ||
| 91 | } | ||
| 92 | #endif | ||
| 93 | } | ||
| 94 | |||
| 95 | static unsigned long cpu_weight[NR_CPUS]; | ||
| 96 | static int tsk_in_cpu[NR_CPUS] = {[0 ... NR_CPUS-1] = -1}; | ||
| 97 | static DECLARE_BITMAP(pad_busy_cpus_bits, NR_CPUS); | ||
| 98 | static void round_robin_cpu(unsigned int tsk_index) | ||
| 99 | { | ||
| 100 | struct cpumask *pad_busy_cpus = to_cpumask(pad_busy_cpus_bits); | ||
| 101 | cpumask_var_t tmp; | ||
| 102 | int cpu; | ||
| 103 | unsigned long min_weight = -1, preferred_cpu; | ||
| 104 | |||
| 105 | if (!alloc_cpumask_var(&tmp, GFP_KERNEL)) | ||
| 106 | return; | ||
| 107 | |||
| 108 | mutex_lock(&isolated_cpus_lock); | ||
| 109 | cpumask_clear(tmp); | ||
| 110 | for_each_cpu(cpu, pad_busy_cpus) | ||
| 111 | cpumask_or(tmp, tmp, topology_thread_cpumask(cpu)); | ||
| 112 | cpumask_andnot(tmp, cpu_online_mask, tmp); | ||
| 113 | /* avoid HT sibilings if possible */ | ||
| 114 | if (cpumask_empty(tmp)) | ||
| 115 | cpumask_andnot(tmp, cpu_online_mask, pad_busy_cpus); | ||
| 116 | if (cpumask_empty(tmp)) { | ||
| 117 | mutex_unlock(&isolated_cpus_lock); | ||
| 118 | return; | ||
| 119 | } | ||
| 120 | for_each_cpu(cpu, tmp) { | ||
| 121 | if (cpu_weight[cpu] < min_weight) { | ||
| 122 | min_weight = cpu_weight[cpu]; | ||
| 123 | preferred_cpu = cpu; | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | if (tsk_in_cpu[tsk_index] != -1) | ||
| 128 | cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus); | ||
| 129 | tsk_in_cpu[tsk_index] = preferred_cpu; | ||
| 130 | cpumask_set_cpu(preferred_cpu, pad_busy_cpus); | ||
| 131 | cpu_weight[preferred_cpu]++; | ||
| 132 | mutex_unlock(&isolated_cpus_lock); | ||
| 133 | |||
| 134 | set_cpus_allowed_ptr(current, cpumask_of(preferred_cpu)); | ||
| 135 | } | ||
| 136 | |||
| 137 | static void exit_round_robin(unsigned int tsk_index) | ||
| 138 | { | ||
| 139 | struct cpumask *pad_busy_cpus = to_cpumask(pad_busy_cpus_bits); | ||
| 140 | cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus); | ||
| 141 | tsk_in_cpu[tsk_index] = -1; | ||
| 142 | } | ||
| 143 | |||
| 144 | static unsigned int idle_pct = 5; /* percentage */ | ||
| 145 | static unsigned int round_robin_time = 10; /* second */ | ||
| 146 | static int power_saving_thread(void *data) | ||
| 147 | { | ||
| 148 | struct sched_param param = {.sched_priority = 1}; | ||
| 149 | int do_sleep; | ||
| 150 | unsigned int tsk_index = (unsigned long)data; | ||
| 151 | u64 last_jiffies = 0; | ||
| 152 | |||
| 153 | sched_setscheduler(current, SCHED_RR, ¶m); | ||
| 154 | |||
| 155 | while (!kthread_should_stop()) { | ||
| 156 | int cpu; | ||
| 157 | u64 expire_time; | ||
| 158 | |||
| 159 | try_to_freeze(); | ||
| 160 | |||
| 161 | /* round robin to cpus */ | ||
| 162 | if (last_jiffies + round_robin_time * HZ < jiffies) { | ||
| 163 | last_jiffies = jiffies; | ||
| 164 | round_robin_cpu(tsk_index); | ||
| 165 | } | ||
| 166 | |||
| 167 | do_sleep = 0; | ||
| 168 | |||
| 169 | current_thread_info()->status &= ~TS_POLLING; | ||
| 170 | /* | ||
| 171 | * TS_POLLING-cleared state must be visible before we test | ||
| 172 | * NEED_RESCHED: | ||
| 173 | */ | ||
| 174 | smp_mb(); | ||
| 175 | |||
| 176 | expire_time = jiffies + HZ * (100 - idle_pct) / 100; | ||
| 177 | |||
| 178 | while (!need_resched()) { | ||
| 179 | local_irq_disable(); | ||
| 180 | cpu = smp_processor_id(); | ||
| 181 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, | ||
| 182 | &cpu); | ||
| 183 | stop_critical_timings(); | ||
| 184 | |||
| 185 | __monitor((void *)¤t_thread_info()->flags, 0, 0); | ||
| 186 | smp_mb(); | ||
| 187 | if (!need_resched()) | ||
| 188 | __mwait(power_saving_mwait_eax, 1); | ||
| 189 | |||
| 190 | start_critical_timings(); | ||
| 191 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, | ||
| 192 | &cpu); | ||
| 193 | local_irq_enable(); | ||
| 194 | |||
| 195 | if (jiffies > expire_time) { | ||
| 196 | do_sleep = 1; | ||
| 197 | break; | ||
| 198 | } | ||
| 199 | } | ||
| 200 | |||
| 201 | current_thread_info()->status |= TS_POLLING; | ||
| 202 | |||
| 203 | /* | ||
| 204 | * current sched_rt has threshold for rt task running time. | ||
| 205 | * When a rt task uses 95% CPU time, the rt thread will be | ||
| 206 | * scheduled out for 5% CPU time to not starve other tasks. But | ||
| 207 | * the mechanism only works when all CPUs have RT task running, | ||
| 208 | * as if one CPU hasn't RT task, RT task from other CPUs will | ||
| 209 | * borrow CPU time from this CPU and cause RT task use > 95% | ||
| 210 | * CPU time. To make 'avoid staration' work, takes a nap here. | ||
| 211 | */ | ||
| 212 | if (do_sleep) | ||
| 213 | schedule_timeout_killable(HZ * idle_pct / 100); | ||
| 214 | } | ||
| 215 | |||
| 216 | exit_round_robin(tsk_index); | ||
| 217 | return 0; | ||
| 218 | } | ||
| 219 | |||
| 220 | static struct task_struct *ps_tsks[NR_CPUS]; | ||
| 221 | static unsigned int ps_tsk_num; | ||
| 222 | static int create_power_saving_task(void) | ||
| 223 | { | ||
| 224 | ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread, | ||
| 225 | (void *)(unsigned long)ps_tsk_num, | ||
| 226 | "power_saving/%d", ps_tsk_num); | ||
| 227 | if (ps_tsks[ps_tsk_num]) { | ||
| 228 | ps_tsk_num++; | ||
| 229 | return 0; | ||
| 230 | } | ||
| 231 | return -EINVAL; | ||
| 232 | } | ||
| 233 | |||
| 234 | static void destroy_power_saving_task(void) | ||
| 235 | { | ||
| 236 | if (ps_tsk_num > 0) { | ||
| 237 | ps_tsk_num--; | ||
| 238 | kthread_stop(ps_tsks[ps_tsk_num]); | ||
| 239 | } | ||
| 240 | } | ||
| 241 | |||
| 242 | static void set_power_saving_task_num(unsigned int num) | ||
| 243 | { | ||
| 244 | if (num > ps_tsk_num) { | ||
| 245 | while (ps_tsk_num < num) { | ||
| 246 | if (create_power_saving_task()) | ||
| 247 | return; | ||
| 248 | } | ||
| 249 | } else if (num < ps_tsk_num) { | ||
| 250 | while (ps_tsk_num > num) | ||
| 251 | destroy_power_saving_task(); | ||
| 252 | } | ||
| 253 | } | ||
| 254 | |||
| 255 | static int acpi_pad_idle_cpus(unsigned int num_cpus) | ||
| 256 | { | ||
| 257 | get_online_cpus(); | ||
| 258 | |||
| 259 | num_cpus = min_t(unsigned int, num_cpus, num_online_cpus()); | ||
| 260 | set_power_saving_task_num(num_cpus); | ||
| 261 | |||
| 262 | put_online_cpus(); | ||
| 263 | return 0; | ||
| 264 | } | ||
| 265 | |||
| 266 | static uint32_t acpi_pad_idle_cpus_num(void) | ||
| 267 | { | ||
| 268 | return ps_tsk_num; | ||
| 269 | } | ||
| 270 | |||
| 271 | static ssize_t acpi_pad_rrtime_store(struct device *dev, | ||
| 272 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 273 | { | ||
| 274 | unsigned long num; | ||
| 275 | if (strict_strtoul(buf, 0, &num)) | ||
| 276 | return -EINVAL; | ||
| 277 | if (num < 1 || num >= 100) | ||
| 278 | return -EINVAL; | ||
| 279 | mutex_lock(&isolated_cpus_lock); | ||
| 280 | round_robin_time = num; | ||
| 281 | mutex_unlock(&isolated_cpus_lock); | ||
| 282 | return count; | ||
| 283 | } | ||
| 284 | |||
| 285 | static ssize_t acpi_pad_rrtime_show(struct device *dev, | ||
| 286 | struct device_attribute *attr, char *buf) | ||
| 287 | { | ||
| 288 | return scnprintf(buf, PAGE_SIZE, "%d", round_robin_time); | ||
| 289 | } | ||
| 290 | static DEVICE_ATTR(rrtime, S_IRUGO|S_IWUSR, | ||
| 291 | acpi_pad_rrtime_show, | ||
| 292 | acpi_pad_rrtime_store); | ||
| 293 | |||
| 294 | static ssize_t acpi_pad_idlepct_store(struct device *dev, | ||
| 295 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 296 | { | ||
| 297 | unsigned long num; | ||
| 298 | if (strict_strtoul(buf, 0, &num)) | ||
| 299 | return -EINVAL; | ||
| 300 | if (num < 1 || num >= 100) | ||
| 301 | return -EINVAL; | ||
| 302 | mutex_lock(&isolated_cpus_lock); | ||
| 303 | idle_pct = num; | ||
| 304 | mutex_unlock(&isolated_cpus_lock); | ||
| 305 | return count; | ||
| 306 | } | ||
| 307 | |||
| 308 | static ssize_t acpi_pad_idlepct_show(struct device *dev, | ||
| 309 | struct device_attribute *attr, char *buf) | ||
| 310 | { | ||
| 311 | return scnprintf(buf, PAGE_SIZE, "%d", idle_pct); | ||
| 312 | } | ||
| 313 | static DEVICE_ATTR(idlepct, S_IRUGO|S_IWUSR, | ||
| 314 | acpi_pad_idlepct_show, | ||
| 315 | acpi_pad_idlepct_store); | ||
| 316 | |||
| 317 | static ssize_t acpi_pad_idlecpus_store(struct device *dev, | ||
| 318 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 319 | { | ||
| 320 | unsigned long num; | ||
| 321 | if (strict_strtoul(buf, 0, &num)) | ||
| 322 | return -EINVAL; | ||
| 323 | mutex_lock(&isolated_cpus_lock); | ||
| 324 | acpi_pad_idle_cpus(num); | ||
| 325 | mutex_unlock(&isolated_cpus_lock); | ||
| 326 | return count; | ||
| 327 | } | ||
| 328 | |||
| 329 | static ssize_t acpi_pad_idlecpus_show(struct device *dev, | ||
| 330 | struct device_attribute *attr, char *buf) | ||
| 331 | { | ||
| 332 | return cpumask_scnprintf(buf, PAGE_SIZE, | ||
| 333 | to_cpumask(pad_busy_cpus_bits)); | ||
| 334 | } | ||
| 335 | static DEVICE_ATTR(idlecpus, S_IRUGO|S_IWUSR, | ||
| 336 | acpi_pad_idlecpus_show, | ||
| 337 | acpi_pad_idlecpus_store); | ||
| 338 | |||
| 339 | static int acpi_pad_add_sysfs(struct acpi_device *device) | ||
| 340 | { | ||
| 341 | int result; | ||
| 342 | |||
| 343 | result = device_create_file(&device->dev, &dev_attr_idlecpus); | ||
| 344 | if (result) | ||
| 345 | return -ENODEV; | ||
| 346 | result = device_create_file(&device->dev, &dev_attr_idlepct); | ||
| 347 | if (result) { | ||
| 348 | device_remove_file(&device->dev, &dev_attr_idlecpus); | ||
| 349 | return -ENODEV; | ||
| 350 | } | ||
| 351 | result = device_create_file(&device->dev, &dev_attr_rrtime); | ||
| 352 | if (result) { | ||
| 353 | device_remove_file(&device->dev, &dev_attr_idlecpus); | ||
| 354 | device_remove_file(&device->dev, &dev_attr_idlepct); | ||
| 355 | return -ENODEV; | ||
| 356 | } | ||
| 357 | return 0; | ||
| 358 | } | ||
| 359 | |||
| 360 | static void acpi_pad_remove_sysfs(struct acpi_device *device) | ||
| 361 | { | ||
| 362 | device_remove_file(&device->dev, &dev_attr_idlecpus); | ||
| 363 | device_remove_file(&device->dev, &dev_attr_idlepct); | ||
| 364 | device_remove_file(&device->dev, &dev_attr_rrtime); | ||
| 365 | } | ||
| 366 | |||
| 367 | /* Query firmware how many CPUs should be idle */ | ||
| 368 | static int acpi_pad_pur(acpi_handle handle, int *num_cpus) | ||
| 369 | { | ||
| 370 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
| 371 | acpi_status status; | ||
| 372 | union acpi_object *package; | ||
| 373 | int rev, num, ret = -EINVAL; | ||
| 374 | |||
| 375 | status = acpi_evaluate_object(handle, "_PUR", NULL, &buffer); | ||
| 376 | if (ACPI_FAILURE(status)) | ||
| 377 | return -EINVAL; | ||
| 378 | package = buffer.pointer; | ||
| 379 | if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2) | ||
| 380 | goto out; | ||
| 381 | rev = package->package.elements[0].integer.value; | ||
| 382 | num = package->package.elements[1].integer.value; | ||
| 383 | if (rev != 1) | ||
| 384 | goto out; | ||
| 385 | *num_cpus = num; | ||
| 386 | ret = 0; | ||
| 387 | out: | ||
| 388 | kfree(buffer.pointer); | ||
| 389 | return ret; | ||
| 390 | } | ||
| 391 | |||
| 392 | /* Notify firmware how many CPUs are idle */ | ||
| 393 | static void acpi_pad_ost(acpi_handle handle, int stat, | ||
| 394 | uint32_t idle_cpus) | ||
| 395 | { | ||
| 396 | union acpi_object params[3] = { | ||
| 397 | {.type = ACPI_TYPE_INTEGER,}, | ||
| 398 | {.type = ACPI_TYPE_INTEGER,}, | ||
| 399 | {.type = ACPI_TYPE_BUFFER,}, | ||
| 400 | }; | ||
| 401 | struct acpi_object_list arg_list = {3, params}; | ||
| 402 | |||
| 403 | params[0].integer.value = ACPI_PROCESSOR_AGGREGATOR_NOTIFY; | ||
| 404 | params[1].integer.value = stat; | ||
| 405 | params[2].buffer.length = 4; | ||
| 406 | params[2].buffer.pointer = (void *)&idle_cpus; | ||
| 407 | acpi_evaluate_object(handle, "_OST", &arg_list, NULL); | ||
| 408 | } | ||
| 409 | |||
| 410 | static void acpi_pad_handle_notify(acpi_handle handle) | ||
| 411 | { | ||
| 412 | int num_cpus, ret; | ||
| 413 | uint32_t idle_cpus; | ||
| 414 | |||
| 415 | mutex_lock(&isolated_cpus_lock); | ||
| 416 | if (acpi_pad_pur(handle, &num_cpus)) { | ||
| 417 | mutex_unlock(&isolated_cpus_lock); | ||
| 418 | return; | ||
| 419 | } | ||
| 420 | ret = acpi_pad_idle_cpus(num_cpus); | ||
| 421 | idle_cpus = acpi_pad_idle_cpus_num(); | ||
| 422 | if (!ret) | ||
| 423 | acpi_pad_ost(handle, 0, idle_cpus); | ||
| 424 | else | ||
| 425 | acpi_pad_ost(handle, 1, 0); | ||
| 426 | mutex_unlock(&isolated_cpus_lock); | ||
| 427 | } | ||
| 428 | |||
| 429 | static void acpi_pad_notify(acpi_handle handle, u32 event, | ||
| 430 | void *data) | ||
| 431 | { | ||
| 432 | struct acpi_device *device = data; | ||
| 433 | |||
| 434 | switch (event) { | ||
| 435 | case ACPI_PROCESSOR_AGGREGATOR_NOTIFY: | ||
| 436 | acpi_pad_handle_notify(handle); | ||
| 437 | acpi_bus_generate_proc_event(device, event, 0); | ||
| 438 | acpi_bus_generate_netlink_event(device->pnp.device_class, | ||
| 439 | dev_name(&device->dev), event, 0); | ||
| 440 | break; | ||
| 441 | default: | ||
| 442 | printk(KERN_WARNING"Unsupported event [0x%x]\n", event); | ||
| 443 | break; | ||
| 444 | } | ||
| 445 | } | ||
| 446 | |||
| 447 | static int acpi_pad_add(struct acpi_device *device) | ||
| 448 | { | ||
| 449 | acpi_status status; | ||
| 450 | |||
| 451 | strcpy(acpi_device_name(device), ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME); | ||
| 452 | strcpy(acpi_device_class(device), ACPI_PROCESSOR_AGGREGATOR_CLASS); | ||
| 453 | |||
| 454 | if (acpi_pad_add_sysfs(device)) | ||
| 455 | return -ENODEV; | ||
| 456 | |||
| 457 | status = acpi_install_notify_handler(device->handle, | ||
| 458 | ACPI_DEVICE_NOTIFY, acpi_pad_notify, device); | ||
| 459 | if (ACPI_FAILURE(status)) { | ||
| 460 | acpi_pad_remove_sysfs(device); | ||
| 461 | return -ENODEV; | ||
| 462 | } | ||
| 463 | |||
| 464 | return 0; | ||
| 465 | } | ||
| 466 | |||
| 467 | static int acpi_pad_remove(struct acpi_device *device, | ||
| 468 | int type) | ||
| 469 | { | ||
| 470 | mutex_lock(&isolated_cpus_lock); | ||
| 471 | acpi_pad_idle_cpus(0); | ||
| 472 | mutex_unlock(&isolated_cpus_lock); | ||
| 473 | |||
| 474 | acpi_remove_notify_handler(device->handle, | ||
| 475 | ACPI_DEVICE_NOTIFY, acpi_pad_notify); | ||
| 476 | acpi_pad_remove_sysfs(device); | ||
| 477 | return 0; | ||
| 478 | } | ||
| 479 | |||
| 480 | static const struct acpi_device_id pad_device_ids[] = { | ||
| 481 | {"ACPI000C", 0}, | ||
| 482 | {"", 0}, | ||
| 483 | }; | ||
| 484 | MODULE_DEVICE_TABLE(acpi, pad_device_ids); | ||
| 485 | |||
| 486 | static struct acpi_driver acpi_pad_driver = { | ||
| 487 | .name = "processor_aggregator", | ||
| 488 | .class = ACPI_PROCESSOR_AGGREGATOR_CLASS, | ||
| 489 | .ids = pad_device_ids, | ||
| 490 | .ops = { | ||
| 491 | .add = acpi_pad_add, | ||
| 492 | .remove = acpi_pad_remove, | ||
| 493 | }, | ||
| 494 | }; | ||
| 495 | |||
| 496 | static int __init acpi_pad_init(void) | ||
| 497 | { | ||
| 498 | power_saving_mwait_init(); | ||
| 499 | if (power_saving_mwait_eax == 0) | ||
| 500 | return -EINVAL; | ||
| 501 | |||
| 502 | return acpi_bus_register_driver(&acpi_pad_driver); | ||
| 503 | } | ||
| 504 | |||
| 505 | static void __exit acpi_pad_exit(void) | ||
| 506 | { | ||
| 507 | acpi_bus_unregister_driver(&acpi_pad_driver); | ||
| 508 | } | ||
| 509 | |||
| 510 | module_init(acpi_pad_init); | ||
| 511 | module_exit(acpi_pad_exit); | ||
| 512 | MODULE_AUTHOR("Shaohua Li<shaohua.li@intel.com>"); | ||
| 513 | MODULE_DESCRIPTION("ACPI Processor Aggregator Driver"); | ||
| 514 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 3a2cfefc71ab..7338b6a3e049 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
| @@ -67,7 +67,7 @@ struct dock_station { | |||
| 67 | struct list_head dependent_devices; | 67 | struct list_head dependent_devices; |
| 68 | struct list_head hotplug_devices; | 68 | struct list_head hotplug_devices; |
| 69 | 69 | ||
| 70 | struct list_head sibiling; | 70 | struct list_head sibling; |
| 71 | struct platform_device *dock_device; | 71 | struct platform_device *dock_device; |
| 72 | }; | 72 | }; |
| 73 | static LIST_HEAD(dock_stations); | 73 | static LIST_HEAD(dock_stations); |
| @@ -275,7 +275,7 @@ int is_dock_device(acpi_handle handle) | |||
| 275 | 275 | ||
| 276 | if (is_dock(handle)) | 276 | if (is_dock(handle)) |
| 277 | return 1; | 277 | return 1; |
| 278 | list_for_each_entry(dock_station, &dock_stations, sibiling) { | 278 | list_for_each_entry(dock_station, &dock_stations, sibling) { |
| 279 | if (find_dock_dependent_device(dock_station, handle)) | 279 | if (find_dock_dependent_device(dock_station, handle)) |
| 280 | return 1; | 280 | return 1; |
| 281 | } | 281 | } |
| @@ -619,7 +619,7 @@ register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops, | |||
| 619 | * make sure this handle is for a device dependent on the dock, | 619 | * make sure this handle is for a device dependent on the dock, |
| 620 | * this would include the dock station itself | 620 | * this would include the dock station itself |
| 621 | */ | 621 | */ |
| 622 | list_for_each_entry(dock_station, &dock_stations, sibiling) { | 622 | list_for_each_entry(dock_station, &dock_stations, sibling) { |
| 623 | /* | 623 | /* |
| 624 | * An ATA bay can be in a dock and itself can be ejected | 624 | * An ATA bay can be in a dock and itself can be ejected |
| 625 | * seperately, so there are two 'dock stations' which need the | 625 | * seperately, so there are two 'dock stations' which need the |
| @@ -651,7 +651,7 @@ void unregister_hotplug_dock_device(acpi_handle handle) | |||
| 651 | if (!dock_station_count) | 651 | if (!dock_station_count) |
| 652 | return; | 652 | return; |
| 653 | 653 | ||
| 654 | list_for_each_entry(dock_station, &dock_stations, sibiling) { | 654 | list_for_each_entry(dock_station, &dock_stations, sibling) { |
| 655 | dd = find_dock_dependent_device(dock_station, handle); | 655 | dd = find_dock_dependent_device(dock_station, handle); |
| 656 | if (dd) | 656 | if (dd) |
| 657 | dock_del_hotplug_device(dock_station, dd); | 657 | dock_del_hotplug_device(dock_station, dd); |
| @@ -787,7 +787,7 @@ static int acpi_dock_notifier_call(struct notifier_block *this, | |||
| 787 | if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK | 787 | if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK |
| 788 | && event != ACPI_NOTIFY_EJECT_REQUEST) | 788 | && event != ACPI_NOTIFY_EJECT_REQUEST) |
| 789 | return 0; | 789 | return 0; |
| 790 | list_for_each_entry(dock_station, &dock_stations, sibiling) { | 790 | list_for_each_entry(dock_station, &dock_stations, sibling) { |
| 791 | if (dock_station->handle == handle) { | 791 | if (dock_station->handle == handle) { |
| 792 | struct dock_data *dock_data; | 792 | struct dock_data *dock_data; |
| 793 | 793 | ||
| @@ -958,7 +958,7 @@ static int dock_add(acpi_handle handle) | |||
| 958 | dock_station->last_dock_time = jiffies - HZ; | 958 | dock_station->last_dock_time = jiffies - HZ; |
| 959 | INIT_LIST_HEAD(&dock_station->dependent_devices); | 959 | INIT_LIST_HEAD(&dock_station->dependent_devices); |
| 960 | INIT_LIST_HEAD(&dock_station->hotplug_devices); | 960 | INIT_LIST_HEAD(&dock_station->hotplug_devices); |
| 961 | INIT_LIST_HEAD(&dock_station->sibiling); | 961 | INIT_LIST_HEAD(&dock_station->sibling); |
| 962 | spin_lock_init(&dock_station->dd_lock); | 962 | spin_lock_init(&dock_station->dd_lock); |
| 963 | mutex_init(&dock_station->hp_lock); | 963 | mutex_init(&dock_station->hp_lock); |
| 964 | ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); | 964 | ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); |
| @@ -1044,7 +1044,7 @@ static int dock_add(acpi_handle handle) | |||
| 1044 | add_dock_dependent_device(dock_station, dd); | 1044 | add_dock_dependent_device(dock_station, dd); |
| 1045 | 1045 | ||
| 1046 | dock_station_count++; | 1046 | dock_station_count++; |
| 1047 | list_add(&dock_station->sibiling, &dock_stations); | 1047 | list_add(&dock_station->sibling, &dock_stations); |
| 1048 | return 0; | 1048 | return 0; |
| 1049 | 1049 | ||
| 1050 | dock_add_err_unregister: | 1050 | dock_add_err_unregister: |
| @@ -1149,7 +1149,7 @@ static void __exit dock_exit(void) | |||
| 1149 | struct dock_station *tmp; | 1149 | struct dock_station *tmp; |
| 1150 | 1150 | ||
| 1151 | unregister_acpi_bus_notifier(&dock_acpi_notifier); | 1151 | unregister_acpi_bus_notifier(&dock_acpi_notifier); |
| 1152 | list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibiling) | 1152 | list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibling) |
| 1153 | dock_remove(dock_station); | 1153 | dock_remove(dock_station); |
| 1154 | } | 1154 | } |
| 1155 | 1155 | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index f70796081c4c..baef28c1e630 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -119,6 +119,8 @@ static struct acpi_ec { | |||
| 119 | } *boot_ec, *first_ec; | 119 | } *boot_ec, *first_ec; |
| 120 | 120 | ||
| 121 | static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ | 121 | static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ |
| 122 | static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ | ||
| 123 | static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */ | ||
| 122 | 124 | ||
| 123 | /* -------------------------------------------------------------------------- | 125 | /* -------------------------------------------------------------------------- |
| 124 | Transaction Management | 126 | Transaction Management |
| @@ -232,10 +234,8 @@ static int ec_poll(struct acpi_ec *ec) | |||
| 232 | } | 234 | } |
| 233 | advance_transaction(ec, acpi_ec_read_status(ec)); | 235 | advance_transaction(ec, acpi_ec_read_status(ec)); |
| 234 | } while (time_before(jiffies, delay)); | 236 | } while (time_before(jiffies, delay)); |
| 235 | if (!ec->curr->irq_count || | 237 | if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) |
| 236 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)) | ||
| 237 | break; | 238 | break; |
| 238 | /* try restart command if we get any false interrupts */ | ||
| 239 | pr_debug(PREFIX "controller reset, restart transaction\n"); | 239 | pr_debug(PREFIX "controller reset, restart transaction\n"); |
| 240 | spin_lock_irqsave(&ec->curr_lock, flags); | 240 | spin_lock_irqsave(&ec->curr_lock, flags); |
| 241 | start_transaction(ec); | 241 | start_transaction(ec); |
| @@ -899,6 +899,44 @@ static const struct acpi_device_id ec_device_ids[] = { | |||
| 899 | {"", 0}, | 899 | {"", 0}, |
| 900 | }; | 900 | }; |
| 901 | 901 | ||
| 902 | /* Some BIOS do not survive early DSDT scan, skip it */ | ||
| 903 | static int ec_skip_dsdt_scan(const struct dmi_system_id *id) | ||
| 904 | { | ||
| 905 | EC_FLAGS_SKIP_DSDT_SCAN = 1; | ||
| 906 | return 0; | ||
| 907 | } | ||
| 908 | |||
| 909 | /* ASUStek often supplies us with broken ECDT, validate it */ | ||
| 910 | static int ec_validate_ecdt(const struct dmi_system_id *id) | ||
| 911 | { | ||
| 912 | EC_FLAGS_VALIDATE_ECDT = 1; | ||
| 913 | return 0; | ||
| 914 | } | ||
| 915 | |||
| 916 | /* MSI EC needs special treatment, enable it */ | ||
| 917 | static int ec_flag_msi(const struct dmi_system_id *id) | ||
| 918 | { | ||
| 919 | EC_FLAGS_MSI = 1; | ||
| 920 | EC_FLAGS_VALIDATE_ECDT = 1; | ||
| 921 | return 0; | ||
| 922 | } | ||
| 923 | |||
| 924 | static struct dmi_system_id __initdata ec_dmi_table[] = { | ||
| 925 | { | ||
| 926 | ec_skip_dsdt_scan, "Compal JFL92", { | ||
| 927 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), | ||
| 928 | DMI_MATCH(DMI_BOARD_NAME, "JFL92") }, NULL}, | ||
| 929 | { | ||
| 930 | ec_flag_msi, "MSI hardware", { | ||
| 931 | DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star"), | ||
| 932 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star") }, NULL}, | ||
| 933 | { | ||
| 934 | ec_validate_ecdt, "ASUS hardware", { | ||
| 935 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, | ||
| 936 | {}, | ||
| 937 | }; | ||
| 938 | |||
| 939 | |||
| 902 | int __init acpi_ec_ecdt_probe(void) | 940 | int __init acpi_ec_ecdt_probe(void) |
| 903 | { | 941 | { |
| 904 | acpi_status status; | 942 | acpi_status status; |
| @@ -911,11 +949,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
| 911 | /* | 949 | /* |
| 912 | * Generate a boot ec context | 950 | * Generate a boot ec context |
| 913 | */ | 951 | */ |
| 914 | if (dmi_name_in_vendors("Micro-Star") || | 952 | dmi_check_system(ec_dmi_table); |
| 915 | dmi_name_in_vendors("Notebook")) { | ||
| 916 | pr_info(PREFIX "Enabling special treatment for EC from MSI.\n"); | ||
| 917 | EC_FLAGS_MSI = 1; | ||
| 918 | } | ||
| 919 | status = acpi_get_table(ACPI_SIG_ECDT, 1, | 953 | status = acpi_get_table(ACPI_SIG_ECDT, 1, |
| 920 | (struct acpi_table_header **)&ecdt_ptr); | 954 | (struct acpi_table_header **)&ecdt_ptr); |
| 921 | if (ACPI_SUCCESS(status)) { | 955 | if (ACPI_SUCCESS(status)) { |
| @@ -926,7 +960,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
| 926 | boot_ec->handle = ACPI_ROOT_OBJECT; | 960 | boot_ec->handle = ACPI_ROOT_OBJECT; |
| 927 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); | 961 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); |
| 928 | /* Don't trust ECDT, which comes from ASUSTek */ | 962 | /* Don't trust ECDT, which comes from ASUSTek */ |
| 929 | if (!dmi_name_in_vendors("ASUS") && EC_FLAGS_MSI == 0) | 963 | if (!EC_FLAGS_VALIDATE_ECDT) |
| 930 | goto install; | 964 | goto install; |
| 931 | saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); | 965 | saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); |
| 932 | if (!saved_ec) | 966 | if (!saved_ec) |
| @@ -934,6 +968,10 @@ int __init acpi_ec_ecdt_probe(void) | |||
| 934 | memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec)); | 968 | memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec)); |
| 935 | /* fall through */ | 969 | /* fall through */ |
| 936 | } | 970 | } |
| 971 | |||
| 972 | if (EC_FLAGS_SKIP_DSDT_SCAN) | ||
| 973 | return -ENODEV; | ||
| 974 | |||
| 937 | /* This workaround is needed only on some broken machines, | 975 | /* This workaround is needed only on some broken machines, |
| 938 | * which require early EC, but fail to provide ECDT */ | 976 | * which require early EC, but fail to provide ECDT */ |
| 939 | printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); | 977 | printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); |
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index d0d550d22a6d..f8b6f555ba52 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
| @@ -398,6 +398,8 @@ acpi_system_write_wakeup_device(struct file *file, | |||
| 398 | 398 | ||
| 399 | if (len > 4) | 399 | if (len > 4) |
| 400 | len = 4; | 400 | len = 4; |
| 401 | if (len < 0) | ||
| 402 | return -EFAULT; | ||
| 401 | 403 | ||
| 402 | if (copy_from_user(strbuf, buffer, len)) | 404 | if (copy_from_user(strbuf, buffer, len)) |
| 403 | return -EFAULT; | 405 | return -EFAULT; |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index c2d4d6e09364..c567b46dfa0f 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
| @@ -863,13 +863,6 @@ static int acpi_processor_add(struct acpi_device *device) | |||
| 863 | goto err_remove_sysfs; | 863 | goto err_remove_sysfs; |
| 864 | } | 864 | } |
| 865 | 865 | ||
| 866 | if (pr->flags.throttling) { | ||
| 867 | printk(KERN_INFO PREFIX "%s [%s] (supports", | ||
| 868 | acpi_device_name(device), acpi_device_bid(device)); | ||
| 869 | printk(" %d throttling states", pr->throttling.state_count); | ||
| 870 | printk(")\n"); | ||
| 871 | } | ||
| 872 | |||
| 873 | return 0; | 866 | return 0; |
| 874 | 867 | ||
| 875 | err_remove_sysfs: | 868 | err_remove_sysfs: |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 468921bed22f..14a7481c97d7 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
| @@ -1052,6 +1052,8 @@ static void acpi_device_set_id(struct acpi_device *device) | |||
| 1052 | device->flags.bus_address = 1; | 1052 | device->flags.bus_address = 1; |
| 1053 | } | 1053 | } |
| 1054 | 1054 | ||
| 1055 | kfree(info); | ||
| 1056 | |||
| 1055 | /* | 1057 | /* |
| 1056 | * Some devices don't reliably have _HIDs & _CIDs, so add | 1058 | * Some devices don't reliably have _HIDs & _CIDs, so add |
| 1057 | * synthetic HIDs to make sure drivers can find them. | 1059 | * synthetic HIDs to make sure drivers can find them. |
| @@ -1325,13 +1327,8 @@ static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops, | |||
| 1325 | struct acpi_device **child) | 1327 | struct acpi_device **child) |
| 1326 | { | 1328 | { |
| 1327 | acpi_status status; | 1329 | acpi_status status; |
| 1328 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
| 1329 | void *device = NULL; | 1330 | void *device = NULL; |
| 1330 | 1331 | ||
| 1331 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | ||
| 1332 | printk(KERN_INFO PREFIX "Enumerating devices from [%s]\n", | ||
| 1333 | (char *) buffer.pointer); | ||
| 1334 | |||
| 1335 | status = acpi_bus_check_add(handle, 0, ops, &device); | 1332 | status = acpi_bus_check_add(handle, 0, ops, &device); |
| 1336 | if (ACPI_SUCCESS(status)) | 1333 | if (ACPI_SUCCESS(status)) |
| 1337 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | 1334 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 6fa7b0fdbdfd..eb4fa1943944 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
| 39 | #include <linux/smp_lock.h> | 39 | #include <linux/smp_lock.h> |
| 40 | #include <linux/proc_fs.h> | 40 | #include <linux/proc_fs.h> |
| 41 | #include <linux/seq_file.h> | ||
| 41 | #include <linux/reboot.h> | 42 | #include <linux/reboot.h> |
| 42 | #include <linux/spinlock.h> | 43 | #include <linux/spinlock.h> |
| 43 | #include <linux/timer.h> | 44 | #include <linux/timer.h> |
| @@ -6422,16 +6423,10 @@ static bool DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller, | |||
| 6422 | return true; | 6423 | return true; |
| 6423 | } | 6424 | } |
| 6424 | 6425 | ||
| 6425 | 6426 | static int dac960_proc_show(struct seq_file *m, void *v) | |
| 6426 | /* | ||
| 6427 | DAC960_ProcReadStatus implements reading /proc/rd/status. | ||
| 6428 | */ | ||
| 6429 | |||
| 6430 | static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset, | ||
| 6431 | int Count, int *EOF, void *Data) | ||
| 6432 | { | 6427 | { |
| 6433 | unsigned char *StatusMessage = "OK\n"; | 6428 | unsigned char *StatusMessage = "OK\n"; |
| 6434 | int ControllerNumber, BytesAvailable; | 6429 | int ControllerNumber; |
| 6435 | for (ControllerNumber = 0; | 6430 | for (ControllerNumber = 0; |
| 6436 | ControllerNumber < DAC960_ControllerCount; | 6431 | ControllerNumber < DAC960_ControllerCount; |
| 6437 | ControllerNumber++) | 6432 | ControllerNumber++) |
| @@ -6444,52 +6439,49 @@ static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset, | |||
| 6444 | break; | 6439 | break; |
| 6445 | } | 6440 | } |
| 6446 | } | 6441 | } |
| 6447 | BytesAvailable = strlen(StatusMessage) - Offset; | 6442 | seq_puts(m, StatusMessage); |
| 6448 | if (Count >= BytesAvailable) | 6443 | return 0; |
| 6449 | { | ||
| 6450 | Count = BytesAvailable; | ||
| 6451 | *EOF = true; | ||
| 6452 | } | ||
| 6453 | if (Count <= 0) return 0; | ||
| 6454 | *Start = Page; | ||
| 6455 | memcpy(Page, &StatusMessage[Offset], Count); | ||
| 6456 | return Count; | ||
| 6457 | } | 6444 | } |
| 6458 | 6445 | ||
| 6446 | static int dac960_proc_open(struct inode *inode, struct file *file) | ||
| 6447 | { | ||
| 6448 | return single_open(file, dac960_proc_show, NULL); | ||
| 6449 | } | ||
| 6459 | 6450 | ||
| 6460 | /* | 6451 | static const struct file_operations dac960_proc_fops = { |
| 6461 | DAC960_ProcReadInitialStatus implements reading /proc/rd/cN/initial_status. | 6452 | .owner = THIS_MODULE, |
| 6462 | */ | 6453 | .open = dac960_proc_open, |
| 6454 | .read = seq_read, | ||
| 6455 | .llseek = seq_lseek, | ||
| 6456 | .release = single_release, | ||
| 6457 | }; | ||
| 6463 | 6458 | ||
| 6464 | static int DAC960_ProcReadInitialStatus(char *Page, char **Start, off_t Offset, | 6459 | static int dac960_initial_status_proc_show(struct seq_file *m, void *v) |
| 6465 | int Count, int *EOF, void *Data) | ||
| 6466 | { | 6460 | { |
| 6467 | DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data; | 6461 | DAC960_Controller_T *Controller = (DAC960_Controller_T *)m->private; |
| 6468 | int BytesAvailable = Controller->InitialStatusLength - Offset; | 6462 | seq_printf(m, "%.*s", Controller->InitialStatusLength, Controller->CombinedStatusBuffer); |
| 6469 | if (Count >= BytesAvailable) | 6463 | return 0; |
| 6470 | { | ||
| 6471 | Count = BytesAvailable; | ||
| 6472 | *EOF = true; | ||
| 6473 | } | ||
| 6474 | if (Count <= 0) return 0; | ||
| 6475 | *Start = Page; | ||
| 6476 | memcpy(Page, &Controller->CombinedStatusBuffer[Offset], Count); | ||
| 6477 | return Count; | ||
| 6478 | } | 6464 | } |
| 6479 | 6465 | ||
| 6466 | static int dac960_initial_status_proc_open(struct inode *inode, struct file *file) | ||
| 6467 | { | ||
| 6468 | return single_open(file, dac960_initial_status_proc_show, PDE(inode)->data); | ||
| 6469 | } | ||
| 6480 | 6470 | ||
| 6481 | /* | 6471 | static const struct file_operations dac960_initial_status_proc_fops = { |
| 6482 | DAC960_ProcReadCurrentStatus implements reading /proc/rd/cN/current_status. | 6472 | .owner = THIS_MODULE, |
| 6483 | */ | 6473 | .open = dac960_initial_status_proc_open, |
| 6474 | .read = seq_read, | ||
| 6475 | .llseek = seq_lseek, | ||
| 6476 | .release = single_release, | ||
| 6477 | }; | ||
| 6484 | 6478 | ||
| 6485 | static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset, | 6479 | static int dac960_current_status_proc_show(struct seq_file *m, void *v) |
| 6486 | int Count, int *EOF, void *Data) | ||
| 6487 | { | 6480 | { |
| 6488 | DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data; | 6481 | DAC960_Controller_T *Controller = (DAC960_Controller_T *) m->private; |
| 6489 | unsigned char *StatusMessage = | 6482 | unsigned char *StatusMessage = |
| 6490 | "No Rebuild or Consistency Check in Progress\n"; | 6483 | "No Rebuild or Consistency Check in Progress\n"; |
| 6491 | int ProgressMessageLength = strlen(StatusMessage); | 6484 | int ProgressMessageLength = strlen(StatusMessage); |
| 6492 | int BytesAvailable; | ||
| 6493 | if (jiffies != Controller->LastCurrentStatusTime) | 6485 | if (jiffies != Controller->LastCurrentStatusTime) |
| 6494 | { | 6486 | { |
| 6495 | Controller->CurrentStatusLength = 0; | 6487 | Controller->CurrentStatusLength = 0; |
| @@ -6513,49 +6505,41 @@ static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset, | |||
| 6513 | } | 6505 | } |
| 6514 | Controller->LastCurrentStatusTime = jiffies; | 6506 | Controller->LastCurrentStatusTime = jiffies; |
| 6515 | } | 6507 | } |
| 6516 | BytesAvailable = Controller->CurrentStatusLength - Offset; | 6508 | seq_printf(m, "%.*s", Controller->CurrentStatusLength, Controller->CurrentStatusBuffer); |
| 6517 | if (Count >= BytesAvailable) | 6509 | return 0; |
| 6518 | { | ||
| 6519 | Count = BytesAvailable; | ||
| 6520 | *EOF = true; | ||
| 6521 | } | ||
| 6522 | if (Count <= 0) return 0; | ||
| 6523 | *Start = Page; | ||
| 6524 | memcpy(Page, &Controller->CurrentStatusBuffer[Offset], Count); | ||
| 6525 | return Count; | ||
| 6526 | } | 6510 | } |
| 6527 | 6511 | ||
| 6512 | static int dac960_current_status_proc_open(struct inode *inode, struct file *file) | ||
| 6513 | { | ||
| 6514 | return single_open(file, dac960_current_status_proc_show, PDE(inode)->data); | ||
| 6515 | } | ||
| 6528 | 6516 | ||
| 6529 | /* | 6517 | static const struct file_operations dac960_current_status_proc_fops = { |
| 6530 | DAC960_ProcReadUserCommand implements reading /proc/rd/cN/user_command. | 6518 | .owner = THIS_MODULE, |
| 6531 | */ | 6519 | .open = dac960_current_status_proc_open, |
| 6520 | .read = seq_read, | ||
| 6521 | .llseek = seq_lseek, | ||
| 6522 | .release = single_release, | ||
| 6523 | }; | ||
| 6532 | 6524 | ||
| 6533 | static int DAC960_ProcReadUserCommand(char *Page, char **Start, off_t Offset, | 6525 | static int dac960_user_command_proc_show(struct seq_file *m, void *v) |
| 6534 | int Count, int *EOF, void *Data) | ||
| 6535 | { | 6526 | { |
| 6536 | DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data; | 6527 | DAC960_Controller_T *Controller = (DAC960_Controller_T *)m->private; |
| 6537 | int BytesAvailable = Controller->UserStatusLength - Offset; | ||
| 6538 | if (Count >= BytesAvailable) | ||
| 6539 | { | ||
| 6540 | Count = BytesAvailable; | ||
| 6541 | *EOF = true; | ||
| 6542 | } | ||
| 6543 | if (Count <= 0) return 0; | ||
| 6544 | *Start = Page; | ||
| 6545 | memcpy(Page, &Controller->UserStatusBuffer[Offset], Count); | ||
| 6546 | return Count; | ||
| 6547 | } | ||
| 6548 | 6528 | ||
| 6529 | seq_printf(m, "%.*s", Controller->UserStatusLength, Controller->UserStatusBuffer); | ||
| 6530 | return 0; | ||
| 6531 | } | ||
| 6549 | 6532 | ||
| 6550 | /* | 6533 | static int dac960_user_command_proc_open(struct inode *inode, struct file *file) |
| 6551 | DAC960_ProcWriteUserCommand implements writing /proc/rd/cN/user_command. | 6534 | { |
| 6552 | */ | 6535 | return single_open(file, dac960_user_command_proc_show, PDE(inode)->data); |
| 6536 | } | ||
| 6553 | 6537 | ||
| 6554 | static int DAC960_ProcWriteUserCommand(struct file *file, | 6538 | static ssize_t dac960_user_command_proc_write(struct file *file, |
| 6555 | const char __user *Buffer, | 6539 | const char __user *Buffer, |
| 6556 | unsigned long Count, void *Data) | 6540 | size_t Count, loff_t *pos) |
| 6557 | { | 6541 | { |
| 6558 | DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data; | 6542 | DAC960_Controller_T *Controller = (DAC960_Controller_T *) PDE(file->f_path.dentry->d_inode)->data; |
| 6559 | unsigned char CommandBuffer[80]; | 6543 | unsigned char CommandBuffer[80]; |
| 6560 | int Length; | 6544 | int Length; |
| 6561 | if (Count > sizeof(CommandBuffer)-1) return -EINVAL; | 6545 | if (Count > sizeof(CommandBuffer)-1) return -EINVAL; |
| @@ -6572,6 +6556,14 @@ static int DAC960_ProcWriteUserCommand(struct file *file, | |||
| 6572 | ? Count : -EBUSY); | 6556 | ? Count : -EBUSY); |
| 6573 | } | 6557 | } |
| 6574 | 6558 | ||
| 6559 | static const struct file_operations dac960_user_command_proc_fops = { | ||
| 6560 | .owner = THIS_MODULE, | ||
| 6561 | .open = dac960_user_command_proc_open, | ||
| 6562 | .read = seq_read, | ||
| 6563 | .llseek = seq_lseek, | ||
| 6564 | .release = single_release, | ||
| 6565 | .write = dac960_user_command_proc_write, | ||
| 6566 | }; | ||
| 6575 | 6567 | ||
| 6576 | /* | 6568 | /* |
| 6577 | DAC960_CreateProcEntries creates the /proc/rd/... entries for the | 6569 | DAC960_CreateProcEntries creates the /proc/rd/... entries for the |
| @@ -6586,23 +6578,17 @@ static void DAC960_CreateProcEntries(DAC960_Controller_T *Controller) | |||
| 6586 | 6578 | ||
| 6587 | if (DAC960_ProcDirectoryEntry == NULL) { | 6579 | if (DAC960_ProcDirectoryEntry == NULL) { |
| 6588 | DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL); | 6580 | DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL); |
| 6589 | StatusProcEntry = create_proc_read_entry("status", 0, | 6581 | StatusProcEntry = proc_create("status", 0, |
| 6590 | DAC960_ProcDirectoryEntry, | 6582 | DAC960_ProcDirectoryEntry, |
| 6591 | DAC960_ProcReadStatus, NULL); | 6583 | &dac960_proc_fops); |
| 6592 | } | 6584 | } |
| 6593 | 6585 | ||
| 6594 | sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber); | 6586 | sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber); |
| 6595 | ControllerProcEntry = proc_mkdir(Controller->ControllerName, | 6587 | ControllerProcEntry = proc_mkdir(Controller->ControllerName, |
| 6596 | DAC960_ProcDirectoryEntry); | 6588 | DAC960_ProcDirectoryEntry); |
| 6597 | create_proc_read_entry("initial_status", 0, ControllerProcEntry, | 6589 | proc_create_data("initial_status", 0, ControllerProcEntry, &dac960_initial_status_proc_fops, Controller); |
| 6598 | DAC960_ProcReadInitialStatus, Controller); | 6590 | proc_create_data("current_status", 0, ControllerProcEntry, &dac960_current_status_proc_fops, Controller); |
| 6599 | create_proc_read_entry("current_status", 0, ControllerProcEntry, | 6591 | UserCommandProcEntry = proc_create_data("user_command", S_IWUSR | S_IRUSR, ControllerProcEntry, &dac960_user_command_proc_fops, Controller); |
| 6600 | DAC960_ProcReadCurrentStatus, Controller); | ||
| 6601 | UserCommandProcEntry = | ||
| 6602 | create_proc_read_entry("user_command", S_IWUSR | S_IRUSR, | ||
| 6603 | ControllerProcEntry, DAC960_ProcReadUserCommand, | ||
| 6604 | Controller); | ||
| 6605 | UserCommandProcEntry->write_proc = DAC960_ProcWriteUserCommand; | ||
| 6606 | Controller->ControllerProcEntry = ControllerProcEntry; | 6592 | Controller->ControllerProcEntry = ControllerProcEntry; |
| 6607 | } | 6593 | } |
| 6608 | 6594 | ||
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 1ece0b47b581..fb5be2d95d52 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
| @@ -36,9 +36,11 @@ | |||
| 36 | #include <linux/proc_fs.h> | 36 | #include <linux/proc_fs.h> |
| 37 | #include <linux/seq_file.h> | 37 | #include <linux/seq_file.h> |
| 38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
| 39 | #include <linux/jiffies.h> | ||
| 39 | #include <linux/hdreg.h> | 40 | #include <linux/hdreg.h> |
| 40 | #include <linux/spinlock.h> | 41 | #include <linux/spinlock.h> |
| 41 | #include <linux/compat.h> | 42 | #include <linux/compat.h> |
| 43 | #include <linux/mutex.h> | ||
| 42 | #include <asm/uaccess.h> | 44 | #include <asm/uaccess.h> |
| 43 | #include <asm/io.h> | 45 | #include <asm/io.h> |
| 44 | 46 | ||
| @@ -155,6 +157,10 @@ static struct board_type products[] = { | |||
| 155 | 157 | ||
| 156 | static ctlr_info_t *hba[MAX_CTLR]; | 158 | static ctlr_info_t *hba[MAX_CTLR]; |
| 157 | 159 | ||
| 160 | static struct task_struct *cciss_scan_thread; | ||
| 161 | static DEFINE_MUTEX(scan_mutex); | ||
| 162 | static LIST_HEAD(scan_q); | ||
| 163 | |||
| 158 | static void do_cciss_request(struct request_queue *q); | 164 | static void do_cciss_request(struct request_queue *q); |
| 159 | static irqreturn_t do_cciss_intr(int irq, void *dev_id); | 165 | static irqreturn_t do_cciss_intr(int irq, void *dev_id); |
| 160 | static int cciss_open(struct block_device *bdev, fmode_t mode); | 166 | static int cciss_open(struct block_device *bdev, fmode_t mode); |
| @@ -164,9 +170,9 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
| 164 | static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); | 170 | static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); |
| 165 | 171 | ||
| 166 | static int cciss_revalidate(struct gendisk *disk); | 172 | static int cciss_revalidate(struct gendisk *disk); |
| 167 | static int rebuild_lun_table(ctlr_info_t *h, int first_time); | 173 | static int rebuild_lun_table(ctlr_info_t *h, int first_time, int via_ioctl); |
| 168 | static int deregister_disk(ctlr_info_t *h, int drv_index, | 174 | static int deregister_disk(ctlr_info_t *h, int drv_index, |
| 169 | int clear_all); | 175 | int clear_all, int via_ioctl); |
| 170 | 176 | ||
| 171 | static void cciss_read_capacity(int ctlr, int logvol, int withirq, | 177 | static void cciss_read_capacity(int ctlr, int logvol, int withirq, |
| 172 | sector_t *total_size, unsigned int *block_size); | 178 | sector_t *total_size, unsigned int *block_size); |
| @@ -189,8 +195,13 @@ static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c, | |||
| 189 | static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c); | 195 | static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c); |
| 190 | 196 | ||
| 191 | static void fail_all_cmds(unsigned long ctlr); | 197 | static void fail_all_cmds(unsigned long ctlr); |
| 198 | static int add_to_scan_list(struct ctlr_info *h); | ||
| 192 | static int scan_thread(void *data); | 199 | static int scan_thread(void *data); |
| 193 | static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c); | 200 | static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c); |
| 201 | static void cciss_hba_release(struct device *dev); | ||
| 202 | static void cciss_device_release(struct device *dev); | ||
| 203 | static void cciss_free_gendisk(ctlr_info_t *h, int drv_index); | ||
| 204 | static void cciss_free_drive_info(ctlr_info_t *h, int drv_index); | ||
| 194 | 205 | ||
| 195 | #ifdef CONFIG_PROC_FS | 206 | #ifdef CONFIG_PROC_FS |
| 196 | static void cciss_procinit(int i); | 207 | static void cciss_procinit(int i); |
| @@ -245,7 +256,10 @@ static inline void removeQ(CommandList_struct *c) | |||
| 245 | 256 | ||
| 246 | #include "cciss_scsi.c" /* For SCSI tape support */ | 257 | #include "cciss_scsi.c" /* For SCSI tape support */ |
| 247 | 258 | ||
| 248 | #define RAID_UNKNOWN 6 | 259 | static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", |
| 260 | "UNKNOWN" | ||
| 261 | }; | ||
| 262 | #define RAID_UNKNOWN (sizeof(raid_label) / sizeof(raid_label[0])-1) | ||
| 249 | 263 | ||
| 250 | #ifdef CONFIG_PROC_FS | 264 | #ifdef CONFIG_PROC_FS |
| 251 | 265 | ||
| @@ -255,9 +269,6 @@ static inline void removeQ(CommandList_struct *c) | |||
| 255 | #define ENG_GIG 1000000000 | 269 | #define ENG_GIG 1000000000 |
| 256 | #define ENG_GIG_FACTOR (ENG_GIG/512) | 270 | #define ENG_GIG_FACTOR (ENG_GIG/512) |
| 257 | #define ENGAGE_SCSI "engage scsi" | 271 | #define ENGAGE_SCSI "engage scsi" |
| 258 | static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", | ||
| 259 | "UNKNOWN" | ||
| 260 | }; | ||
| 261 | 272 | ||
| 262 | static struct proc_dir_entry *proc_cciss; | 273 | static struct proc_dir_entry *proc_cciss; |
| 263 | 274 | ||
| @@ -318,7 +329,7 @@ static int cciss_seq_show(struct seq_file *seq, void *v) | |||
| 318 | ctlr_info_t *h = seq->private; | 329 | ctlr_info_t *h = seq->private; |
| 319 | unsigned ctlr = h->ctlr; | 330 | unsigned ctlr = h->ctlr; |
| 320 | loff_t *pos = v; | 331 | loff_t *pos = v; |
| 321 | drive_info_struct *drv = &h->drv[*pos]; | 332 | drive_info_struct *drv = h->drv[*pos]; |
| 322 | 333 | ||
| 323 | if (*pos > h->highest_lun) | 334 | if (*pos > h->highest_lun) |
| 324 | return 0; | 335 | return 0; |
| @@ -331,7 +342,7 @@ static int cciss_seq_show(struct seq_file *seq, void *v) | |||
| 331 | vol_sz_frac *= 100; | 342 | vol_sz_frac *= 100; |
| 332 | sector_div(vol_sz_frac, ENG_GIG_FACTOR); | 343 | sector_div(vol_sz_frac, ENG_GIG_FACTOR); |
| 333 | 344 | ||
| 334 | if (drv->raid_level > 5) | 345 | if (drv->raid_level < 0 || drv->raid_level > RAID_UNKNOWN) |
| 335 | drv->raid_level = RAID_UNKNOWN; | 346 | drv->raid_level = RAID_UNKNOWN; |
| 336 | seq_printf(seq, "cciss/c%dd%d:" | 347 | seq_printf(seq, "cciss/c%dd%d:" |
| 337 | "\t%4u.%02uGB\tRAID %s\n", | 348 | "\t%4u.%02uGB\tRAID %s\n", |
| @@ -454,9 +465,19 @@ static void __devinit cciss_procinit(int i) | |||
| 454 | #define to_hba(n) container_of(n, struct ctlr_info, dev) | 465 | #define to_hba(n) container_of(n, struct ctlr_info, dev) |
| 455 | #define to_drv(n) container_of(n, drive_info_struct, dev) | 466 | #define to_drv(n) container_of(n, drive_info_struct, dev) |
| 456 | 467 | ||
| 457 | static struct device_type cciss_host_type = { | 468 | static ssize_t host_store_rescan(struct device *dev, |
| 458 | .name = "cciss_host", | 469 | struct device_attribute *attr, |
| 459 | }; | 470 | const char *buf, size_t count) |
| 471 | { | ||
| 472 | struct ctlr_info *h = to_hba(dev); | ||
| 473 | |||
| 474 | add_to_scan_list(h); | ||
| 475 | wake_up_process(cciss_scan_thread); | ||
| 476 | wait_for_completion_interruptible(&h->scan_wait); | ||
| 477 | |||
| 478 | return count; | ||
| 479 | } | ||
| 480 | DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan); | ||
| 460 | 481 | ||
| 461 | static ssize_t dev_show_unique_id(struct device *dev, | 482 | static ssize_t dev_show_unique_id(struct device *dev, |
| 462 | struct device_attribute *attr, | 483 | struct device_attribute *attr, |
| @@ -560,11 +581,101 @@ static ssize_t dev_show_rev(struct device *dev, | |||
| 560 | } | 581 | } |
| 561 | DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL); | 582 | DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL); |
| 562 | 583 | ||
| 584 | static ssize_t cciss_show_lunid(struct device *dev, | ||
| 585 | struct device_attribute *attr, char *buf) | ||
| 586 | { | ||
| 587 | drive_info_struct *drv = to_drv(dev); | ||
| 588 | struct ctlr_info *h = to_hba(drv->dev.parent); | ||
| 589 | unsigned long flags; | ||
| 590 | unsigned char lunid[8]; | ||
| 591 | |||
| 592 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | ||
| 593 | if (h->busy_configuring) { | ||
| 594 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
| 595 | return -EBUSY; | ||
| 596 | } | ||
| 597 | if (!drv->heads) { | ||
| 598 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
| 599 | return -ENOTTY; | ||
| 600 | } | ||
| 601 | memcpy(lunid, drv->LunID, sizeof(lunid)); | ||
| 602 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
| 603 | return snprintf(buf, 20, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", | ||
| 604 | lunid[0], lunid[1], lunid[2], lunid[3], | ||
| 605 | lunid[4], lunid[5], lunid[6], lunid[7]); | ||
| 606 | } | ||
| 607 | DEVICE_ATTR(lunid, S_IRUGO, cciss_show_lunid, NULL); | ||
| 608 | |||
| 609 | static ssize_t cciss_show_raid_level(struct device *dev, | ||
| 610 | struct device_attribute *attr, char *buf) | ||
| 611 | { | ||
| 612 | drive_info_struct *drv = to_drv(dev); | ||
| 613 | struct ctlr_info *h = to_hba(drv->dev.parent); | ||
| 614 | int raid; | ||
| 615 | unsigned long flags; | ||
| 616 | |||
| 617 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | ||
| 618 | if (h->busy_configuring) { | ||
| 619 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
| 620 | return -EBUSY; | ||
| 621 | } | ||
| 622 | raid = drv->raid_level; | ||
| 623 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
| 624 | if (raid < 0 || raid > RAID_UNKNOWN) | ||
| 625 | raid = RAID_UNKNOWN; | ||
| 626 | |||
| 627 | return snprintf(buf, strlen(raid_label[raid]) + 7, "RAID %s\n", | ||
| 628 | raid_label[raid]); | ||
| 629 | } | ||
| 630 | DEVICE_ATTR(raid_level, S_IRUGO, cciss_show_raid_level, NULL); | ||
| 631 | |||
| 632 | static ssize_t cciss_show_usage_count(struct device *dev, | ||
| 633 | struct device_attribute *attr, char *buf) | ||
| 634 | { | ||
| 635 | drive_info_struct *drv = to_drv(dev); | ||
| 636 | struct ctlr_info *h = to_hba(drv->dev.parent); | ||
| 637 | unsigned long flags; | ||
| 638 | int count; | ||
| 639 | |||
| 640 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | ||
| 641 | if (h->busy_configuring) { | ||
| 642 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
| 643 | return -EBUSY; | ||
| 644 | } | ||
| 645 | count = drv->usage_count; | ||
| 646 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
| 647 | return snprintf(buf, 20, "%d\n", count); | ||
| 648 | } | ||
| 649 | DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL); | ||
| 650 | |||
| 651 | static struct attribute *cciss_host_attrs[] = { | ||
| 652 | &dev_attr_rescan.attr, | ||
| 653 | NULL | ||
| 654 | }; | ||
| 655 | |||
| 656 | static struct attribute_group cciss_host_attr_group = { | ||
| 657 | .attrs = cciss_host_attrs, | ||
| 658 | }; | ||
| 659 | |||
| 660 | static const struct attribute_group *cciss_host_attr_groups[] = { | ||
| 661 | &cciss_host_attr_group, | ||
| 662 | NULL | ||
| 663 | }; | ||
| 664 | |||
| 665 | static struct device_type cciss_host_type = { | ||
| 666 | .name = "cciss_host", | ||
| 667 | .groups = cciss_host_attr_groups, | ||
| 668 | .release = cciss_hba_release, | ||
| 669 | }; | ||
| 670 | |||
| 563 | static struct attribute *cciss_dev_attrs[] = { | 671 | static struct attribute *cciss_dev_attrs[] = { |
| 564 | &dev_attr_unique_id.attr, | 672 | &dev_attr_unique_id.attr, |
| 565 | &dev_attr_model.attr, | 673 | &dev_attr_model.attr, |
| 566 | &dev_attr_vendor.attr, | 674 | &dev_attr_vendor.attr, |
| 567 | &dev_attr_rev.attr, | 675 | &dev_attr_rev.attr, |
| 676 | &dev_attr_lunid.attr, | ||
| 677 | &dev_attr_raid_level.attr, | ||
| 678 | &dev_attr_usage_count.attr, | ||
| 568 | NULL | 679 | NULL |
| 569 | }; | 680 | }; |
| 570 | 681 | ||
| @@ -580,12 +691,24 @@ static const struct attribute_group *cciss_dev_attr_groups[] = { | |||
| 580 | static struct device_type cciss_dev_type = { | 691 | static struct device_type cciss_dev_type = { |
| 581 | .name = "cciss_device", | 692 | .name = "cciss_device", |
| 582 | .groups = cciss_dev_attr_groups, | 693 | .groups = cciss_dev_attr_groups, |
| 694 | .release = cciss_device_release, | ||
| 583 | }; | 695 | }; |
| 584 | 696 | ||
| 585 | static struct bus_type cciss_bus_type = { | 697 | static struct bus_type cciss_bus_type = { |
| 586 | .name = "cciss", | 698 | .name = "cciss", |
| 587 | }; | 699 | }; |
| 588 | 700 | ||
| 701 | /* | ||
| 702 | * cciss_hba_release is called when the reference count | ||
| 703 | * of h->dev goes to zero. | ||
| 704 | */ | ||
| 705 | static void cciss_hba_release(struct device *dev) | ||
| 706 | { | ||
| 707 | /* | ||
| 708 | * nothing to do, but need this to avoid a warning | ||
| 709 | * about not having a release handler from lib/kref.c. | ||
| 710 | */ | ||
| 711 | } | ||
| 589 | 712 | ||
| 590 | /* | 713 | /* |
| 591 | * Initialize sysfs entry for each controller. This sets up and registers | 714 | * Initialize sysfs entry for each controller. This sets up and registers |
| @@ -609,6 +732,16 @@ static int cciss_create_hba_sysfs_entry(struct ctlr_info *h) | |||
| 609 | static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h) | 732 | static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h) |
| 610 | { | 733 | { |
| 611 | device_del(&h->dev); | 734 | device_del(&h->dev); |
| 735 | put_device(&h->dev); /* final put. */ | ||
| 736 | } | ||
| 737 | |||
| 738 | /* cciss_device_release is called when the reference count | ||
| 739 | * of h->drv[x]dev goes to zero. | ||
| 740 | */ | ||
| 741 | static void cciss_device_release(struct device *dev) | ||
| 742 | { | ||
| 743 | drive_info_struct *drv = to_drv(dev); | ||
| 744 | kfree(drv); | ||
| 612 | } | 745 | } |
| 613 | 746 | ||
| 614 | /* | 747 | /* |
| @@ -617,24 +750,39 @@ static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h) | |||
| 617 | * /sys/bus/pci/devices/<dev/ccis#/. We also create a link from | 750 | * /sys/bus/pci/devices/<dev/ccis#/. We also create a link from |
| 618 | * /sys/block/cciss!c#d# to this entry. | 751 | * /sys/block/cciss!c#d# to this entry. |
| 619 | */ | 752 | */ |
| 620 | static int cciss_create_ld_sysfs_entry(struct ctlr_info *h, | 753 | static long cciss_create_ld_sysfs_entry(struct ctlr_info *h, |
| 621 | drive_info_struct *drv, | ||
| 622 | int drv_index) | 754 | int drv_index) |
| 623 | { | 755 | { |
| 624 | device_initialize(&drv->dev); | 756 | struct device *dev; |
| 625 | drv->dev.type = &cciss_dev_type; | 757 | |
| 626 | drv->dev.bus = &cciss_bus_type; | 758 | if (h->drv[drv_index]->device_initialized) |
| 627 | dev_set_name(&drv->dev, "c%dd%d", h->ctlr, drv_index); | 759 | return 0; |
| 628 | drv->dev.parent = &h->dev; | 760 | |
| 629 | return device_add(&drv->dev); | 761 | dev = &h->drv[drv_index]->dev; |
| 762 | device_initialize(dev); | ||
| 763 | dev->type = &cciss_dev_type; | ||
| 764 | dev->bus = &cciss_bus_type; | ||
| 765 | dev_set_name(dev, "c%dd%d", h->ctlr, drv_index); | ||
| 766 | dev->parent = &h->dev; | ||
| 767 | h->drv[drv_index]->device_initialized = 1; | ||
| 768 | return device_add(dev); | ||
| 630 | } | 769 | } |
| 631 | 770 | ||
| 632 | /* | 771 | /* |
| 633 | * Remove sysfs entries for a logical drive. | 772 | * Remove sysfs entries for a logical drive. |
| 634 | */ | 773 | */ |
| 635 | static void cciss_destroy_ld_sysfs_entry(drive_info_struct *drv) | 774 | static void cciss_destroy_ld_sysfs_entry(struct ctlr_info *h, int drv_index, |
| 775 | int ctlr_exiting) | ||
| 636 | { | 776 | { |
| 637 | device_del(&drv->dev); | 777 | struct device *dev = &h->drv[drv_index]->dev; |
| 778 | |||
| 779 | /* special case for c*d0, we only destroy it on controller exit */ | ||
| 780 | if (drv_index == 0 && !ctlr_exiting) | ||
| 781 | return; | ||
| 782 | |||
| 783 | device_del(dev); | ||
| 784 | put_device(dev); /* the "final" put. */ | ||
| 785 | h->drv[drv_index] = NULL; | ||
| 638 | } | 786 | } |
| 639 | 787 | ||
| 640 | /* | 788 | /* |
| @@ -751,7 +899,7 @@ static int cciss_open(struct block_device *bdev, fmode_t mode) | |||
| 751 | printk(KERN_DEBUG "cciss_open %s\n", bdev->bd_disk->disk_name); | 899 | printk(KERN_DEBUG "cciss_open %s\n", bdev->bd_disk->disk_name); |
| 752 | #endif /* CCISS_DEBUG */ | 900 | #endif /* CCISS_DEBUG */ |
| 753 | 901 | ||
| 754 | if (host->busy_initializing || drv->busy_configuring) | 902 | if (drv->busy_configuring) |
| 755 | return -EBUSY; | 903 | return -EBUSY; |
| 756 | /* | 904 | /* |
| 757 | * Root is allowed to open raw volume zero even if it's not configured | 905 | * Root is allowed to open raw volume zero even if it's not configured |
| @@ -767,7 +915,8 @@ static int cciss_open(struct block_device *bdev, fmode_t mode) | |||
| 767 | if (MINOR(bdev->bd_dev) & 0x0f) { | 915 | if (MINOR(bdev->bd_dev) & 0x0f) { |
| 768 | return -ENXIO; | 916 | return -ENXIO; |
| 769 | /* if it is, make sure we have a LUN ID */ | 917 | /* if it is, make sure we have a LUN ID */ |
| 770 | } else if (drv->LunID == 0) { | 918 | } else if (memcmp(drv->LunID, CTLR_LUNID, |
| 919 | sizeof(drv->LunID))) { | ||
| 771 | return -ENXIO; | 920 | return -ENXIO; |
| 772 | } | 921 | } |
| 773 | } | 922 | } |
| @@ -1132,12 +1281,13 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
| 1132 | case CCISS_DEREGDISK: | 1281 | case CCISS_DEREGDISK: |
| 1133 | case CCISS_REGNEWD: | 1282 | case CCISS_REGNEWD: |
| 1134 | case CCISS_REVALIDVOLS: | 1283 | case CCISS_REVALIDVOLS: |
| 1135 | return rebuild_lun_table(host, 0); | 1284 | return rebuild_lun_table(host, 0, 1); |
| 1136 | 1285 | ||
| 1137 | case CCISS_GETLUNINFO:{ | 1286 | case CCISS_GETLUNINFO:{ |
| 1138 | LogvolInfo_struct luninfo; | 1287 | LogvolInfo_struct luninfo; |
| 1139 | 1288 | ||
| 1140 | luninfo.LunID = drv->LunID; | 1289 | memcpy(&luninfo.LunID, drv->LunID, |
| 1290 | sizeof(luninfo.LunID)); | ||
| 1141 | luninfo.num_opens = drv->usage_count; | 1291 | luninfo.num_opens = drv->usage_count; |
| 1142 | luninfo.num_parts = 0; | 1292 | luninfo.num_parts = 0; |
| 1143 | if (copy_to_user(argp, &luninfo, | 1293 | if (copy_to_user(argp, &luninfo, |
| @@ -1475,7 +1625,10 @@ static void cciss_check_queues(ctlr_info_t *h) | |||
| 1475 | /* make sure the disk has been added and the drive is real | 1625 | /* make sure the disk has been added and the drive is real |
| 1476 | * because this can be called from the middle of init_one. | 1626 | * because this can be called from the middle of init_one. |
| 1477 | */ | 1627 | */ |
| 1478 | if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads)) | 1628 | if (!h->drv[curr_queue]) |
| 1629 | continue; | ||
| 1630 | if (!(h->drv[curr_queue]->queue) || | ||
| 1631 | !(h->drv[curr_queue]->heads)) | ||
| 1479 | continue; | 1632 | continue; |
| 1480 | blk_start_queue(h->gendisk[curr_queue]->queue); | 1633 | blk_start_queue(h->gendisk[curr_queue]->queue); |
| 1481 | 1634 | ||
| @@ -1532,13 +1685,11 @@ static void cciss_softirq_done(struct request *rq) | |||
| 1532 | spin_unlock_irqrestore(&h->lock, flags); | 1685 | spin_unlock_irqrestore(&h->lock, flags); |
| 1533 | } | 1686 | } |
| 1534 | 1687 | ||
| 1535 | static void log_unit_to_scsi3addr(ctlr_info_t *h, unsigned char scsi3addr[], | 1688 | static inline void log_unit_to_scsi3addr(ctlr_info_t *h, |
| 1536 | uint32_t log_unit) | 1689 | unsigned char scsi3addr[], uint32_t log_unit) |
| 1537 | { | 1690 | { |
| 1538 | log_unit = h->drv[log_unit].LunID & 0x03fff; | 1691 | memcpy(scsi3addr, h->drv[log_unit]->LunID, |
| 1539 | memset(&scsi3addr[4], 0, 4); | 1692 | sizeof(h->drv[log_unit]->LunID)); |
| 1540 | memcpy(&scsi3addr[0], &log_unit, 4); | ||
| 1541 | scsi3addr[3] |= 0x40; | ||
| 1542 | } | 1693 | } |
| 1543 | 1694 | ||
| 1544 | /* This function gets the SCSI vendor, model, and revision of a logical drive | 1695 | /* This function gets the SCSI vendor, model, and revision of a logical drive |
| @@ -1615,16 +1766,23 @@ static void cciss_get_serial_no(int ctlr, int logvol, int withirq, | |||
| 1615 | return; | 1766 | return; |
| 1616 | } | 1767 | } |
| 1617 | 1768 | ||
| 1618 | static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, | 1769 | /* |
| 1770 | * cciss_add_disk sets up the block device queue for a logical drive | ||
| 1771 | */ | ||
| 1772 | static int cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, | ||
| 1619 | int drv_index) | 1773 | int drv_index) |
| 1620 | { | 1774 | { |
| 1621 | disk->queue = blk_init_queue(do_cciss_request, &h->lock); | 1775 | disk->queue = blk_init_queue(do_cciss_request, &h->lock); |
| 1776 | if (!disk->queue) | ||
| 1777 | goto init_queue_failure; | ||
| 1622 | sprintf(disk->disk_name, "cciss/c%dd%d", h->ctlr, drv_index); | 1778 | sprintf(disk->disk_name, "cciss/c%dd%d", h->ctlr, drv_index); |
| 1623 | disk->major = h->major; | 1779 | disk->major = h->major; |
| 1624 | disk->first_minor = drv_index << NWD_SHIFT; | 1780 | disk->first_minor = drv_index << NWD_SHIFT; |
| 1625 | disk->fops = &cciss_fops; | 1781 | disk->fops = &cciss_fops; |
| 1626 | disk->private_data = &h->drv[drv_index]; | 1782 | if (cciss_create_ld_sysfs_entry(h, drv_index)) |
| 1627 | disk->driverfs_dev = &h->drv[drv_index].dev; | 1783 | goto cleanup_queue; |
| 1784 | disk->private_data = h->drv[drv_index]; | ||
| 1785 | disk->driverfs_dev = &h->drv[drv_index]->dev; | ||
| 1628 | 1786 | ||
| 1629 | /* Set up queue information */ | 1787 | /* Set up queue information */ |
| 1630 | blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); | 1788 | blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); |
| @@ -1642,14 +1800,21 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, | |||
| 1642 | disk->queue->queuedata = h; | 1800 | disk->queue->queuedata = h; |
| 1643 | 1801 | ||
| 1644 | blk_queue_logical_block_size(disk->queue, | 1802 | blk_queue_logical_block_size(disk->queue, |
| 1645 | h->drv[drv_index].block_size); | 1803 | h->drv[drv_index]->block_size); |
| 1646 | 1804 | ||
| 1647 | /* Make sure all queue data is written out before */ | 1805 | /* Make sure all queue data is written out before */ |
| 1648 | /* setting h->drv[drv_index].queue, as setting this */ | 1806 | /* setting h->drv[drv_index]->queue, as setting this */ |
| 1649 | /* allows the interrupt handler to start the queue */ | 1807 | /* allows the interrupt handler to start the queue */ |
| 1650 | wmb(); | 1808 | wmb(); |
| 1651 | h->drv[drv_index].queue = disk->queue; | 1809 | h->drv[drv_index]->queue = disk->queue; |
| 1652 | add_disk(disk); | 1810 | add_disk(disk); |
| 1811 | return 0; | ||
| 1812 | |||
| 1813 | cleanup_queue: | ||
| 1814 | blk_cleanup_queue(disk->queue); | ||
| 1815 | disk->queue = NULL; | ||
| 1816 | init_queue_failure: | ||
| 1817 | return -1; | ||
| 1653 | } | 1818 | } |
| 1654 | 1819 | ||
| 1655 | /* This function will check the usage_count of the drive to be updated/added. | 1820 | /* This function will check the usage_count of the drive to be updated/added. |
| @@ -1662,7 +1827,8 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, | |||
| 1662 | * is also the controller node. Any changes to disk 0 will show up on | 1827 | * is also the controller node. Any changes to disk 0 will show up on |
| 1663 | * the next reboot. | 1828 | * the next reboot. |
| 1664 | */ | 1829 | */ |
| 1665 | static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) | 1830 | static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, |
| 1831 | int via_ioctl) | ||
| 1666 | { | 1832 | { |
| 1667 | ctlr_info_t *h = hba[ctlr]; | 1833 | ctlr_info_t *h = hba[ctlr]; |
| 1668 | struct gendisk *disk; | 1834 | struct gendisk *disk; |
| @@ -1672,21 +1838,13 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) | |||
| 1672 | unsigned long flags = 0; | 1838 | unsigned long flags = 0; |
| 1673 | int ret = 0; | 1839 | int ret = 0; |
| 1674 | drive_info_struct *drvinfo; | 1840 | drive_info_struct *drvinfo; |
| 1675 | int was_only_controller_node; | ||
| 1676 | 1841 | ||
| 1677 | /* Get information about the disk and modify the driver structure */ | 1842 | /* Get information about the disk and modify the driver structure */ |
| 1678 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | 1843 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); |
| 1679 | drvinfo = kmalloc(sizeof(*drvinfo), GFP_KERNEL); | 1844 | drvinfo = kzalloc(sizeof(*drvinfo), GFP_KERNEL); |
| 1680 | if (inq_buff == NULL || drvinfo == NULL) | 1845 | if (inq_buff == NULL || drvinfo == NULL) |
| 1681 | goto mem_msg; | 1846 | goto mem_msg; |
| 1682 | 1847 | ||
| 1683 | /* See if we're trying to update the "controller node" | ||
| 1684 | * this will happen the when the first logical drive gets | ||
| 1685 | * created by ACU. | ||
| 1686 | */ | ||
| 1687 | was_only_controller_node = (drv_index == 0 && | ||
| 1688 | h->drv[0].raid_level == -1); | ||
| 1689 | |||
| 1690 | /* testing to see if 16-byte CDBs are already being used */ | 1848 | /* testing to see if 16-byte CDBs are already being used */ |
| 1691 | if (h->cciss_read == CCISS_READ_16) { | 1849 | if (h->cciss_read == CCISS_READ_16) { |
| 1692 | cciss_read_capacity_16(h->ctlr, drv_index, 1, | 1850 | cciss_read_capacity_16(h->ctlr, drv_index, 1, |
| @@ -1719,16 +1877,19 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) | |||
| 1719 | drvinfo->model, drvinfo->rev); | 1877 | drvinfo->model, drvinfo->rev); |
| 1720 | cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no, | 1878 | cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no, |
| 1721 | sizeof(drvinfo->serial_no)); | 1879 | sizeof(drvinfo->serial_no)); |
| 1880 | /* Save the lunid in case we deregister the disk, below. */ | ||
| 1881 | memcpy(drvinfo->LunID, h->drv[drv_index]->LunID, | ||
| 1882 | sizeof(drvinfo->LunID)); | ||
| 1722 | 1883 | ||
| 1723 | /* Is it the same disk we already know, and nothing's changed? */ | 1884 | /* Is it the same disk we already know, and nothing's changed? */ |
| 1724 | if (h->drv[drv_index].raid_level != -1 && | 1885 | if (h->drv[drv_index]->raid_level != -1 && |
| 1725 | ((memcmp(drvinfo->serial_no, | 1886 | ((memcmp(drvinfo->serial_no, |
| 1726 | h->drv[drv_index].serial_no, 16) == 0) && | 1887 | h->drv[drv_index]->serial_no, 16) == 0) && |
| 1727 | drvinfo->block_size == h->drv[drv_index].block_size && | 1888 | drvinfo->block_size == h->drv[drv_index]->block_size && |
| 1728 | drvinfo->nr_blocks == h->drv[drv_index].nr_blocks && | 1889 | drvinfo->nr_blocks == h->drv[drv_index]->nr_blocks && |
| 1729 | drvinfo->heads == h->drv[drv_index].heads && | 1890 | drvinfo->heads == h->drv[drv_index]->heads && |
| 1730 | drvinfo->sectors == h->drv[drv_index].sectors && | 1891 | drvinfo->sectors == h->drv[drv_index]->sectors && |
| 1731 | drvinfo->cylinders == h->drv[drv_index].cylinders)) | 1892 | drvinfo->cylinders == h->drv[drv_index]->cylinders)) |
| 1732 | /* The disk is unchanged, nothing to update */ | 1893 | /* The disk is unchanged, nothing to update */ |
| 1733 | goto freeret; | 1894 | goto freeret; |
| 1734 | 1895 | ||
| @@ -1738,18 +1899,17 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) | |||
| 1738 | * If the disk already exists then deregister it before proceeding | 1899 | * If the disk already exists then deregister it before proceeding |
| 1739 | * (unless it's the first disk (for the controller node). | 1900 | * (unless it's the first disk (for the controller node). |
| 1740 | */ | 1901 | */ |
| 1741 | if (h->drv[drv_index].raid_level != -1 && drv_index != 0) { | 1902 | if (h->drv[drv_index]->raid_level != -1 && drv_index != 0) { |
| 1742 | printk(KERN_WARNING "disk %d has changed.\n", drv_index); | 1903 | printk(KERN_WARNING "disk %d has changed.\n", drv_index); |
| 1743 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 1904 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); |
| 1744 | h->drv[drv_index].busy_configuring = 1; | 1905 | h->drv[drv_index]->busy_configuring = 1; |
| 1745 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 1906 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
| 1746 | 1907 | ||
| 1747 | /* deregister_disk sets h->drv[drv_index].queue = NULL | 1908 | /* deregister_disk sets h->drv[drv_index]->queue = NULL |
| 1748 | * which keeps the interrupt handler from starting | 1909 | * which keeps the interrupt handler from starting |
| 1749 | * the queue. | 1910 | * the queue. |
| 1750 | */ | 1911 | */ |
| 1751 | ret = deregister_disk(h, drv_index, 0); | 1912 | ret = deregister_disk(h, drv_index, 0, via_ioctl); |
| 1752 | h->drv[drv_index].busy_configuring = 0; | ||
| 1753 | } | 1913 | } |
| 1754 | 1914 | ||
| 1755 | /* If the disk is in use return */ | 1915 | /* If the disk is in use return */ |
| @@ -1757,22 +1917,31 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) | |||
| 1757 | goto freeret; | 1917 | goto freeret; |
| 1758 | 1918 | ||
| 1759 | /* Save the new information from cciss_geometry_inquiry | 1919 | /* Save the new information from cciss_geometry_inquiry |
| 1760 | * and serial number inquiry. | 1920 | * and serial number inquiry. If the disk was deregistered |
| 1921 | * above, then h->drv[drv_index] will be NULL. | ||
| 1761 | */ | 1922 | */ |
| 1762 | h->drv[drv_index].block_size = drvinfo->block_size; | 1923 | if (h->drv[drv_index] == NULL) { |
| 1763 | h->drv[drv_index].nr_blocks = drvinfo->nr_blocks; | 1924 | drvinfo->device_initialized = 0; |
| 1764 | h->drv[drv_index].heads = drvinfo->heads; | 1925 | h->drv[drv_index] = drvinfo; |
| 1765 | h->drv[drv_index].sectors = drvinfo->sectors; | 1926 | drvinfo = NULL; /* so it won't be freed below. */ |
| 1766 | h->drv[drv_index].cylinders = drvinfo->cylinders; | 1927 | } else { |
| 1767 | h->drv[drv_index].raid_level = drvinfo->raid_level; | 1928 | /* special case for cxd0 */ |
| 1768 | memcpy(h->drv[drv_index].serial_no, drvinfo->serial_no, 16); | 1929 | h->drv[drv_index]->block_size = drvinfo->block_size; |
| 1769 | memcpy(h->drv[drv_index].vendor, drvinfo->vendor, VENDOR_LEN + 1); | 1930 | h->drv[drv_index]->nr_blocks = drvinfo->nr_blocks; |
| 1770 | memcpy(h->drv[drv_index].model, drvinfo->model, MODEL_LEN + 1); | 1931 | h->drv[drv_index]->heads = drvinfo->heads; |
| 1771 | memcpy(h->drv[drv_index].rev, drvinfo->rev, REV_LEN + 1); | 1932 | h->drv[drv_index]->sectors = drvinfo->sectors; |
| 1933 | h->drv[drv_index]->cylinders = drvinfo->cylinders; | ||
| 1934 | h->drv[drv_index]->raid_level = drvinfo->raid_level; | ||
| 1935 | memcpy(h->drv[drv_index]->serial_no, drvinfo->serial_no, 16); | ||
| 1936 | memcpy(h->drv[drv_index]->vendor, drvinfo->vendor, | ||
| 1937 | VENDOR_LEN + 1); | ||
| 1938 | memcpy(h->drv[drv_index]->model, drvinfo->model, MODEL_LEN + 1); | ||
| 1939 | memcpy(h->drv[drv_index]->rev, drvinfo->rev, REV_LEN + 1); | ||
| 1940 | } | ||
| 1772 | 1941 | ||
| 1773 | ++h->num_luns; | 1942 | ++h->num_luns; |
| 1774 | disk = h->gendisk[drv_index]; | 1943 | disk = h->gendisk[drv_index]; |
| 1775 | set_capacity(disk, h->drv[drv_index].nr_blocks); | 1944 | set_capacity(disk, h->drv[drv_index]->nr_blocks); |
| 1776 | 1945 | ||
| 1777 | /* If it's not disk 0 (drv_index != 0) | 1946 | /* If it's not disk 0 (drv_index != 0) |
| 1778 | * or if it was disk 0, but there was previously | 1947 | * or if it was disk 0, but there was previously |
| @@ -1780,8 +1949,15 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) | |||
| 1780 | * (raid_leve == -1) then we want to update the | 1949 | * (raid_leve == -1) then we want to update the |
| 1781 | * logical drive's information. | 1950 | * logical drive's information. |
| 1782 | */ | 1951 | */ |
| 1783 | if (drv_index || first_time) | 1952 | if (drv_index || first_time) { |
| 1784 | cciss_add_disk(h, disk, drv_index); | 1953 | if (cciss_add_disk(h, disk, drv_index) != 0) { |
| 1954 | cciss_free_gendisk(h, drv_index); | ||
| 1955 | cciss_free_drive_info(h, drv_index); | ||
| 1956 | printk(KERN_WARNING "cciss:%d could not update " | ||
| 1957 | "disk %d\n", h->ctlr, drv_index); | ||
| 1958 | --h->num_luns; | ||
| 1959 | } | ||
| 1960 | } | ||
| 1785 | 1961 | ||
| 1786 | freeret: | 1962 | freeret: |
| 1787 | kfree(inq_buff); | 1963 | kfree(inq_buff); |
| @@ -1793,28 +1969,70 @@ mem_msg: | |||
| 1793 | } | 1969 | } |
| 1794 | 1970 | ||
| 1795 | /* This function will find the first index of the controllers drive array | 1971 | /* This function will find the first index of the controllers drive array |
| 1796 | * that has a -1 for the raid_level and will return that index. This is | 1972 | * that has a null drv pointer and allocate the drive info struct and |
| 1797 | * where new drives will be added. If the index to be returned is greater | 1973 | * will return that index This is where new drives will be added. |
| 1798 | * than the highest_lun index for the controller then highest_lun is set | 1974 | * If the index to be returned is greater than the highest_lun index for |
| 1799 | * to this new index. If there are no available indexes then -1 is returned. | 1975 | * the controller then highest_lun is set * to this new index. |
| 1800 | * "controller_node" is used to know if this is a real logical drive, or just | 1976 | * If there are no available indexes or if tha allocation fails, then -1 |
| 1801 | * the controller node, which determines if this counts towards highest_lun. | 1977 | * is returned. * "controller_node" is used to know if this is a real |
| 1978 | * logical drive, or just the controller node, which determines if this | ||
| 1979 | * counts towards highest_lun. | ||
| 1802 | */ | 1980 | */ |
| 1803 | static int cciss_find_free_drive_index(int ctlr, int controller_node) | 1981 | static int cciss_alloc_drive_info(ctlr_info_t *h, int controller_node) |
| 1804 | { | 1982 | { |
| 1805 | int i; | 1983 | int i; |
| 1984 | drive_info_struct *drv; | ||
| 1806 | 1985 | ||
| 1986 | /* Search for an empty slot for our drive info */ | ||
| 1807 | for (i = 0; i < CISS_MAX_LUN; i++) { | 1987 | for (i = 0; i < CISS_MAX_LUN; i++) { |
| 1808 | if (hba[ctlr]->drv[i].raid_level == -1) { | 1988 | |
| 1809 | if (i > hba[ctlr]->highest_lun) | 1989 | /* if not cxd0 case, and it's occupied, skip it. */ |
| 1810 | if (!controller_node) | 1990 | if (h->drv[i] && i != 0) |
| 1811 | hba[ctlr]->highest_lun = i; | 1991 | continue; |
| 1992 | /* | ||
| 1993 | * If it's cxd0 case, and drv is alloc'ed already, and a | ||
| 1994 | * disk is configured there, skip it. | ||
| 1995 | */ | ||
| 1996 | if (i == 0 && h->drv[i] && h->drv[i]->raid_level != -1) | ||
| 1997 | continue; | ||
| 1998 | |||
| 1999 | /* | ||
| 2000 | * We've found an empty slot. Update highest_lun | ||
| 2001 | * provided this isn't just the fake cxd0 controller node. | ||
| 2002 | */ | ||
| 2003 | if (i > h->highest_lun && !controller_node) | ||
| 2004 | h->highest_lun = i; | ||
| 2005 | |||
| 2006 | /* If adding a real disk at cxd0, and it's already alloc'ed */ | ||
| 2007 | if (i == 0 && h->drv[i] != NULL) | ||
| 1812 | return i; | 2008 | return i; |
| 1813 | } | 2009 | |
| 2010 | /* | ||
| 2011 | * Found an empty slot, not already alloc'ed. Allocate it. | ||
| 2012 | * Mark it with raid_level == -1, so we know it's new later on. | ||
| 2013 | */ | ||
| 2014 | drv = kzalloc(sizeof(*drv), GFP_KERNEL); | ||
| 2015 | if (!drv) | ||
| 2016 | return -1; | ||
| 2017 | drv->raid_level = -1; /* so we know it's new */ | ||
| 2018 | h->drv[i] = drv; | ||
| 2019 | return i; | ||
| 1814 | } | 2020 | } |
| 1815 | return -1; | 2021 | return -1; |
| 1816 | } | 2022 | } |
| 1817 | 2023 | ||
| 2024 | static void cciss_free_drive_info(ctlr_info_t *h, int drv_index) | ||
| 2025 | { | ||
| 2026 | kfree(h->drv[drv_index]); | ||
| 2027 | h->drv[drv_index] = NULL; | ||
| 2028 | } | ||
| 2029 | |||
| 2030 | static void cciss_free_gendisk(ctlr_info_t *h, int drv_index) | ||
| 2031 | { | ||
| 2032 | put_disk(h->gendisk[drv_index]); | ||
| 2033 | h->gendisk[drv_index] = NULL; | ||
| 2034 | } | ||
| 2035 | |||
| 1818 | /* cciss_add_gendisk finds a free hba[]->drv structure | 2036 | /* cciss_add_gendisk finds a free hba[]->drv structure |
| 1819 | * and allocates a gendisk if needed, and sets the lunid | 2037 | * and allocates a gendisk if needed, and sets the lunid |
| 1820 | * in the drvinfo structure. It returns the index into | 2038 | * in the drvinfo structure. It returns the index into |
| @@ -1824,13 +2042,15 @@ static int cciss_find_free_drive_index(int ctlr, int controller_node) | |||
| 1824 | * a means to talk to the controller in case no logical | 2042 | * a means to talk to the controller in case no logical |
| 1825 | * drives have yet been configured. | 2043 | * drives have yet been configured. |
| 1826 | */ | 2044 | */ |
| 1827 | static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) | 2045 | static int cciss_add_gendisk(ctlr_info_t *h, unsigned char lunid[], |
| 2046 | int controller_node) | ||
| 1828 | { | 2047 | { |
| 1829 | int drv_index; | 2048 | int drv_index; |
| 1830 | 2049 | ||
| 1831 | drv_index = cciss_find_free_drive_index(h->ctlr, controller_node); | 2050 | drv_index = cciss_alloc_drive_info(h, controller_node); |
| 1832 | if (drv_index == -1) | 2051 | if (drv_index == -1) |
| 1833 | return -1; | 2052 | return -1; |
| 2053 | |||
| 1834 | /*Check if the gendisk needs to be allocated */ | 2054 | /*Check if the gendisk needs to be allocated */ |
| 1835 | if (!h->gendisk[drv_index]) { | 2055 | if (!h->gendisk[drv_index]) { |
| 1836 | h->gendisk[drv_index] = | 2056 | h->gendisk[drv_index] = |
| @@ -1839,23 +2059,24 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) | |||
| 1839 | printk(KERN_ERR "cciss%d: could not " | 2059 | printk(KERN_ERR "cciss%d: could not " |
| 1840 | "allocate a new disk %d\n", | 2060 | "allocate a new disk %d\n", |
| 1841 | h->ctlr, drv_index); | 2061 | h->ctlr, drv_index); |
| 1842 | return -1; | 2062 | goto err_free_drive_info; |
| 1843 | } | 2063 | } |
| 1844 | } | 2064 | } |
| 1845 | h->drv[drv_index].LunID = lunid; | 2065 | memcpy(h->drv[drv_index]->LunID, lunid, |
| 1846 | if (cciss_create_ld_sysfs_entry(h, &h->drv[drv_index], drv_index)) | 2066 | sizeof(h->drv[drv_index]->LunID)); |
| 2067 | if (cciss_create_ld_sysfs_entry(h, drv_index)) | ||
| 1847 | goto err_free_disk; | 2068 | goto err_free_disk; |
| 1848 | |||
| 1849 | /* Don't need to mark this busy because nobody */ | 2069 | /* Don't need to mark this busy because nobody */ |
| 1850 | /* else knows about this disk yet to contend */ | 2070 | /* else knows about this disk yet to contend */ |
| 1851 | /* for access to it. */ | 2071 | /* for access to it. */ |
| 1852 | h->drv[drv_index].busy_configuring = 0; | 2072 | h->drv[drv_index]->busy_configuring = 0; |
| 1853 | wmb(); | 2073 | wmb(); |
| 1854 | return drv_index; | 2074 | return drv_index; |
| 1855 | 2075 | ||
| 1856 | err_free_disk: | 2076 | err_free_disk: |
| 1857 | put_disk(h->gendisk[drv_index]); | 2077 | cciss_free_gendisk(h, drv_index); |
| 1858 | h->gendisk[drv_index] = NULL; | 2078 | err_free_drive_info: |
| 2079 | cciss_free_drive_info(h, drv_index); | ||
| 1859 | return -1; | 2080 | return -1; |
| 1860 | } | 2081 | } |
| 1861 | 2082 | ||
| @@ -1872,21 +2093,25 @@ static void cciss_add_controller_node(ctlr_info_t *h) | |||
| 1872 | if (h->gendisk[0] != NULL) /* already did this? Then bail. */ | 2093 | if (h->gendisk[0] != NULL) /* already did this? Then bail. */ |
| 1873 | return; | 2094 | return; |
| 1874 | 2095 | ||
| 1875 | drv_index = cciss_add_gendisk(h, 0, 1); | 2096 | drv_index = cciss_add_gendisk(h, CTLR_LUNID, 1); |
| 1876 | if (drv_index == -1) { | 2097 | if (drv_index == -1) |
| 1877 | printk(KERN_WARNING "cciss%d: could not " | 2098 | goto error; |
| 1878 | "add disk 0.\n", h->ctlr); | 2099 | h->drv[drv_index]->block_size = 512; |
| 1879 | return; | 2100 | h->drv[drv_index]->nr_blocks = 0; |
| 1880 | } | 2101 | h->drv[drv_index]->heads = 0; |
| 1881 | h->drv[drv_index].block_size = 512; | 2102 | h->drv[drv_index]->sectors = 0; |
| 1882 | h->drv[drv_index].nr_blocks = 0; | 2103 | h->drv[drv_index]->cylinders = 0; |
| 1883 | h->drv[drv_index].heads = 0; | 2104 | h->drv[drv_index]->raid_level = -1; |
| 1884 | h->drv[drv_index].sectors = 0; | 2105 | memset(h->drv[drv_index]->serial_no, 0, 16); |
| 1885 | h->drv[drv_index].cylinders = 0; | ||
| 1886 | h->drv[drv_index].raid_level = -1; | ||
| 1887 | memset(h->drv[drv_index].serial_no, 0, 16); | ||
| 1888 | disk = h->gendisk[drv_index]; | 2106 | disk = h->gendisk[drv_index]; |
| 1889 | cciss_add_disk(h, disk, drv_index); | 2107 | if (cciss_add_disk(h, disk, drv_index) == 0) |
| 2108 | return; | ||
| 2109 | cciss_free_gendisk(h, drv_index); | ||
| 2110 | cciss_free_drive_info(h, drv_index); | ||
| 2111 | error: | ||
| 2112 | printk(KERN_WARNING "cciss%d: could not " | ||
| 2113 | "add disk 0.\n", h->ctlr); | ||
| 2114 | return; | ||
| 1890 | } | 2115 | } |
| 1891 | 2116 | ||
| 1892 | /* This function will add and remove logical drives from the Logical | 2117 | /* This function will add and remove logical drives from the Logical |
| @@ -1897,7 +2122,8 @@ static void cciss_add_controller_node(ctlr_info_t *h) | |||
| 1897 | * INPUT | 2122 | * INPUT |
| 1898 | * h = The controller to perform the operations on | 2123 | * h = The controller to perform the operations on |
| 1899 | */ | 2124 | */ |
| 1900 | static int rebuild_lun_table(ctlr_info_t *h, int first_time) | 2125 | static int rebuild_lun_table(ctlr_info_t *h, int first_time, |
| 2126 | int via_ioctl) | ||
| 1901 | { | 2127 | { |
| 1902 | int ctlr = h->ctlr; | 2128 | int ctlr = h->ctlr; |
| 1903 | int num_luns; | 2129 | int num_luns; |
| @@ -1907,7 +2133,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) | |||
| 1907 | int i; | 2133 | int i; |
| 1908 | int drv_found; | 2134 | int drv_found; |
| 1909 | int drv_index = 0; | 2135 | int drv_index = 0; |
| 1910 | __u32 lunid = 0; | 2136 | unsigned char lunid[8] = CTLR_LUNID; |
| 1911 | unsigned long flags; | 2137 | unsigned long flags; |
| 1912 | 2138 | ||
| 1913 | if (!capable(CAP_SYS_RAWIO)) | 2139 | if (!capable(CAP_SYS_RAWIO)) |
| @@ -1960,13 +2186,13 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) | |||
| 1960 | drv_found = 0; | 2186 | drv_found = 0; |
| 1961 | 2187 | ||
| 1962 | /* skip holes in the array from already deleted drives */ | 2188 | /* skip holes in the array from already deleted drives */ |
| 1963 | if (h->drv[i].raid_level == -1) | 2189 | if (h->drv[i] == NULL) |
| 1964 | continue; | 2190 | continue; |
| 1965 | 2191 | ||
| 1966 | for (j = 0; j < num_luns; j++) { | 2192 | for (j = 0; j < num_luns; j++) { |
| 1967 | memcpy(&lunid, &ld_buff->LUN[j][0], 4); | 2193 | memcpy(lunid, &ld_buff->LUN[j][0], sizeof(lunid)); |
| 1968 | lunid = le32_to_cpu(lunid); | 2194 | if (memcmp(h->drv[i]->LunID, lunid, |
| 1969 | if (h->drv[i].LunID == lunid) { | 2195 | sizeof(lunid)) == 0) { |
| 1970 | drv_found = 1; | 2196 | drv_found = 1; |
| 1971 | break; | 2197 | break; |
| 1972 | } | 2198 | } |
| @@ -1974,11 +2200,11 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) | |||
| 1974 | if (!drv_found) { | 2200 | if (!drv_found) { |
| 1975 | /* Deregister it from the OS, it's gone. */ | 2201 | /* Deregister it from the OS, it's gone. */ |
| 1976 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 2202 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); |
| 1977 | h->drv[i].busy_configuring = 1; | 2203 | h->drv[i]->busy_configuring = 1; |
| 1978 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 2204 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
| 1979 | return_code = deregister_disk(h, i, 1); | 2205 | return_code = deregister_disk(h, i, 1, via_ioctl); |
| 1980 | cciss_destroy_ld_sysfs_entry(&h->drv[i]); | 2206 | if (h->drv[i] != NULL) |
| 1981 | h->drv[i].busy_configuring = 0; | 2207 | h->drv[i]->busy_configuring = 0; |
| 1982 | } | 2208 | } |
| 1983 | } | 2209 | } |
| 1984 | 2210 | ||
| @@ -1992,17 +2218,16 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) | |||
| 1992 | 2218 | ||
| 1993 | drv_found = 0; | 2219 | drv_found = 0; |
| 1994 | 2220 | ||
| 1995 | memcpy(&lunid, &ld_buff->LUN[i][0], 4); | 2221 | memcpy(lunid, &ld_buff->LUN[i][0], sizeof(lunid)); |
| 1996 | lunid = le32_to_cpu(lunid); | ||
| 1997 | |||
| 1998 | /* Find if the LUN is already in the drive array | 2222 | /* Find if the LUN is already in the drive array |
| 1999 | * of the driver. If so then update its info | 2223 | * of the driver. If so then update its info |
| 2000 | * if not in use. If it does not exist then find | 2224 | * if not in use. If it does not exist then find |
| 2001 | * the first free index and add it. | 2225 | * the first free index and add it. |
| 2002 | */ | 2226 | */ |
| 2003 | for (j = 0; j <= h->highest_lun; j++) { | 2227 | for (j = 0; j <= h->highest_lun; j++) { |
| 2004 | if (h->drv[j].raid_level != -1 && | 2228 | if (h->drv[j] != NULL && |
| 2005 | h->drv[j].LunID == lunid) { | 2229 | memcmp(h->drv[j]->LunID, lunid, |
| 2230 | sizeof(h->drv[j]->LunID)) == 0) { | ||
| 2006 | drv_index = j; | 2231 | drv_index = j; |
| 2007 | drv_found = 1; | 2232 | drv_found = 1; |
| 2008 | break; | 2233 | break; |
| @@ -2015,7 +2240,8 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) | |||
| 2015 | if (drv_index == -1) | 2240 | if (drv_index == -1) |
| 2016 | goto freeret; | 2241 | goto freeret; |
| 2017 | } | 2242 | } |
| 2018 | cciss_update_drive_info(ctlr, drv_index, first_time); | 2243 | cciss_update_drive_info(ctlr, drv_index, first_time, |
| 2244 | via_ioctl); | ||
| 2019 | } /* end for */ | 2245 | } /* end for */ |
| 2020 | 2246 | ||
| 2021 | freeret: | 2247 | freeret: |
| @@ -2032,6 +2258,25 @@ mem_msg: | |||
| 2032 | goto freeret; | 2258 | goto freeret; |
| 2033 | } | 2259 | } |
| 2034 | 2260 | ||
| 2261 | static void cciss_clear_drive_info(drive_info_struct *drive_info) | ||
| 2262 | { | ||
| 2263 | /* zero out the disk size info */ | ||
| 2264 | drive_info->nr_blocks = 0; | ||
| 2265 | drive_info->block_size = 0; | ||
| 2266 | drive_info->heads = 0; | ||
| 2267 | drive_info->sectors = 0; | ||
| 2268 | drive_info->cylinders = 0; | ||
| 2269 | drive_info->raid_level = -1; | ||
| 2270 | memset(drive_info->serial_no, 0, sizeof(drive_info->serial_no)); | ||
| 2271 | memset(drive_info->model, 0, sizeof(drive_info->model)); | ||
| 2272 | memset(drive_info->rev, 0, sizeof(drive_info->rev)); | ||
| 2273 | memset(drive_info->vendor, 0, sizeof(drive_info->vendor)); | ||
| 2274 | /* | ||
| 2275 | * don't clear the LUNID though, we need to remember which | ||
| 2276 | * one this one is. | ||
| 2277 | */ | ||
| 2278 | } | ||
| 2279 | |||
| 2035 | /* This function will deregister the disk and it's queue from the | 2280 | /* This function will deregister the disk and it's queue from the |
| 2036 | * kernel. It must be called with the controller lock held and the | 2281 | * kernel. It must be called with the controller lock held and the |
| 2037 | * drv structures busy_configuring flag set. It's parameters are: | 2282 | * drv structures busy_configuring flag set. It's parameters are: |
| @@ -2046,43 +2291,48 @@ mem_msg: | |||
| 2046 | * the disk in preparation for re-adding it. In this case | 2291 | * the disk in preparation for re-adding it. In this case |
| 2047 | * the highest_lun should be left unchanged and the LunID | 2292 | * the highest_lun should be left unchanged and the LunID |
| 2048 | * should not be cleared. | 2293 | * should not be cleared. |
| 2294 | * via_ioctl | ||
| 2295 | * This indicates whether we've reached this path via ioctl. | ||
| 2296 | * This affects the maximum usage count allowed for c0d0 to be messed with. | ||
| 2297 | * If this path is reached via ioctl(), then the max_usage_count will | ||
| 2298 | * be 1, as the process calling ioctl() has got to have the device open. | ||
| 2299 | * If we get here via sysfs, then the max usage count will be zero. | ||
| 2049 | */ | 2300 | */ |
| 2050 | static int deregister_disk(ctlr_info_t *h, int drv_index, | 2301 | static int deregister_disk(ctlr_info_t *h, int drv_index, |
| 2051 | int clear_all) | 2302 | int clear_all, int via_ioctl) |
| 2052 | { | 2303 | { |
| 2053 | int i; | 2304 | int i; |
| 2054 | struct gendisk *disk; | 2305 | struct gendisk *disk; |
| 2055 | drive_info_struct *drv; | 2306 | drive_info_struct *drv; |
| 2307 | int recalculate_highest_lun; | ||
| 2056 | 2308 | ||
| 2057 | if (!capable(CAP_SYS_RAWIO)) | 2309 | if (!capable(CAP_SYS_RAWIO)) |
| 2058 | return -EPERM; | 2310 | return -EPERM; |
| 2059 | 2311 | ||
| 2060 | drv = &h->drv[drv_index]; | 2312 | drv = h->drv[drv_index]; |
| 2061 | disk = h->gendisk[drv_index]; | 2313 | disk = h->gendisk[drv_index]; |
| 2062 | 2314 | ||
| 2063 | /* make sure logical volume is NOT is use */ | 2315 | /* make sure logical volume is NOT is use */ |
| 2064 | if (clear_all || (h->gendisk[0] == disk)) { | 2316 | if (clear_all || (h->gendisk[0] == disk)) { |
| 2065 | if (drv->usage_count > 1) | 2317 | if (drv->usage_count > via_ioctl) |
| 2066 | return -EBUSY; | 2318 | return -EBUSY; |
| 2067 | } else if (drv->usage_count > 0) | 2319 | } else if (drv->usage_count > 0) |
| 2068 | return -EBUSY; | 2320 | return -EBUSY; |
| 2069 | 2321 | ||
| 2322 | recalculate_highest_lun = (drv == h->drv[h->highest_lun]); | ||
| 2323 | |||
| 2070 | /* invalidate the devices and deregister the disk. If it is disk | 2324 | /* invalidate the devices and deregister the disk. If it is disk |
| 2071 | * zero do not deregister it but just zero out it's values. This | 2325 | * zero do not deregister it but just zero out it's values. This |
| 2072 | * allows us to delete disk zero but keep the controller registered. | 2326 | * allows us to delete disk zero but keep the controller registered. |
| 2073 | */ | 2327 | */ |
| 2074 | if (h->gendisk[0] != disk) { | 2328 | if (h->gendisk[0] != disk) { |
| 2075 | struct request_queue *q = disk->queue; | 2329 | struct request_queue *q = disk->queue; |
| 2076 | if (disk->flags & GENHD_FL_UP) | 2330 | if (disk->flags & GENHD_FL_UP) { |
| 2331 | cciss_destroy_ld_sysfs_entry(h, drv_index, 0); | ||
| 2077 | del_gendisk(disk); | 2332 | del_gendisk(disk); |
| 2078 | if (q) { | ||
| 2079 | blk_cleanup_queue(q); | ||
| 2080 | /* Set drv->queue to NULL so that we do not try | ||
| 2081 | * to call blk_start_queue on this queue in the | ||
| 2082 | * interrupt handler | ||
| 2083 | */ | ||
| 2084 | drv->queue = NULL; | ||
| 2085 | } | 2333 | } |
| 2334 | if (q) | ||
| 2335 | blk_cleanup_queue(q); | ||
| 2086 | /* If clear_all is set then we are deleting the logical | 2336 | /* If clear_all is set then we are deleting the logical |
| 2087 | * drive, not just refreshing its info. For drives | 2337 | * drive, not just refreshing its info. For drives |
| 2088 | * other than disk 0 we will call put_disk. We do not | 2338 | * other than disk 0 we will call put_disk. We do not |
| @@ -2105,34 +2355,20 @@ static int deregister_disk(ctlr_info_t *h, int drv_index, | |||
| 2105 | } | 2355 | } |
| 2106 | } else { | 2356 | } else { |
| 2107 | set_capacity(disk, 0); | 2357 | set_capacity(disk, 0); |
| 2358 | cciss_clear_drive_info(drv); | ||
| 2108 | } | 2359 | } |
| 2109 | 2360 | ||
| 2110 | --h->num_luns; | 2361 | --h->num_luns; |
| 2111 | /* zero out the disk size info */ | ||
| 2112 | drv->nr_blocks = 0; | ||
| 2113 | drv->block_size = 0; | ||
| 2114 | drv->heads = 0; | ||
| 2115 | drv->sectors = 0; | ||
| 2116 | drv->cylinders = 0; | ||
| 2117 | drv->raid_level = -1; /* This can be used as a flag variable to | ||
| 2118 | * indicate that this element of the drive | ||
| 2119 | * array is free. | ||
| 2120 | */ | ||
| 2121 | |||
| 2122 | if (clear_all) { | ||
| 2123 | /* check to see if it was the last disk */ | ||
| 2124 | if (drv == h->drv + h->highest_lun) { | ||
| 2125 | /* if so, find the new hightest lun */ | ||
| 2126 | int i, newhighest = -1; | ||
| 2127 | for (i = 0; i <= h->highest_lun; i++) { | ||
| 2128 | /* if the disk has size > 0, it is available */ | ||
| 2129 | if (h->drv[i].heads) | ||
| 2130 | newhighest = i; | ||
| 2131 | } | ||
| 2132 | h->highest_lun = newhighest; | ||
| 2133 | } | ||
| 2134 | 2362 | ||
| 2135 | drv->LunID = 0; | 2363 | /* if it was the last disk, find the new hightest lun */ |
| 2364 | if (clear_all && recalculate_highest_lun) { | ||
| 2365 | int i, newhighest = -1; | ||
| 2366 | for (i = 0; i <= h->highest_lun; i++) { | ||
| 2367 | /* if the disk has size > 0, it is available */ | ||
| 2368 | if (h->drv[i] && h->drv[i]->heads) | ||
| 2369 | newhighest = i; | ||
| 2370 | } | ||
| 2371 | h->highest_lun = newhighest; | ||
| 2136 | } | 2372 | } |
| 2137 | return 0; | 2373 | return 0; |
| 2138 | } | 2374 | } |
| @@ -2479,8 +2715,6 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, | |||
| 2479 | } else { /* Get geometry failed */ | 2715 | } else { /* Get geometry failed */ |
| 2480 | printk(KERN_WARNING "cciss: reading geometry failed\n"); | 2716 | printk(KERN_WARNING "cciss: reading geometry failed\n"); |
| 2481 | } | 2717 | } |
| 2482 | printk(KERN_INFO " heads=%d, sectors=%d, cylinders=%d\n\n", | ||
| 2483 | drv->heads, drv->sectors, drv->cylinders); | ||
| 2484 | } | 2718 | } |
| 2485 | 2719 | ||
| 2486 | static void | 2720 | static void |
| @@ -2514,9 +2748,6 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, | |||
| 2514 | *total_size = 0; | 2748 | *total_size = 0; |
| 2515 | *block_size = BLOCK_SIZE; | 2749 | *block_size = BLOCK_SIZE; |
| 2516 | } | 2750 | } |
| 2517 | if (*total_size != 0) | ||
| 2518 | printk(KERN_INFO " blocks= %llu block_size= %d\n", | ||
| 2519 | (unsigned long long)*total_size+1, *block_size); | ||
| 2520 | kfree(buf); | 2751 | kfree(buf); |
| 2521 | } | 2752 | } |
| 2522 | 2753 | ||
| @@ -2568,7 +2799,8 @@ static int cciss_revalidate(struct gendisk *disk) | |||
| 2568 | InquiryData_struct *inq_buff = NULL; | 2799 | InquiryData_struct *inq_buff = NULL; |
| 2569 | 2800 | ||
| 2570 | for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { | 2801 | for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { |
| 2571 | if (h->drv[logvol].LunID == drv->LunID) { | 2802 | if (memcmp(h->drv[logvol]->LunID, drv->LunID, |
| 2803 | sizeof(drv->LunID)) == 0) { | ||
| 2572 | FOUND = 1; | 2804 | FOUND = 1; |
| 2573 | break; | 2805 | break; |
| 2574 | } | 2806 | } |
| @@ -3053,8 +3285,7 @@ static void do_cciss_request(struct request_queue *q) | |||
| 3053 | /* The first 2 bits are reserved for controller error reporting. */ | 3285 | /* The first 2 bits are reserved for controller error reporting. */ |
| 3054 | c->Header.Tag.lower = (c->cmdindex << 3); | 3286 | c->Header.Tag.lower = (c->cmdindex << 3); |
| 3055 | c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */ | 3287 | c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */ |
| 3056 | c->Header.LUN.LogDev.VolId = drv->LunID; | 3288 | memcpy(&c->Header.LUN, drv->LunID, sizeof(drv->LunID)); |
| 3057 | c->Header.LUN.LogDev.Mode = 1; | ||
| 3058 | c->Request.CDBLen = 10; // 12 byte commands not in FW yet; | 3289 | c->Request.CDBLen = 10; // 12 byte commands not in FW yet; |
| 3059 | c->Request.Type.Type = TYPE_CMD; // It is a command. | 3290 | c->Request.Type.Type = TYPE_CMD; // It is a command. |
| 3060 | c->Request.Type.Attribute = ATTR_SIMPLE; | 3291 | c->Request.Type.Attribute = ATTR_SIMPLE; |
| @@ -3232,20 +3463,121 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id) | |||
| 3232 | return IRQ_HANDLED; | 3463 | return IRQ_HANDLED; |
| 3233 | } | 3464 | } |
| 3234 | 3465 | ||
| 3466 | /** | ||
| 3467 | * add_to_scan_list() - add controller to rescan queue | ||
| 3468 | * @h: Pointer to the controller. | ||
| 3469 | * | ||
| 3470 | * Adds the controller to the rescan queue if not already on the queue. | ||
| 3471 | * | ||
| 3472 | * returns 1 if added to the queue, 0 if skipped (could be on the | ||
| 3473 | * queue already, or the controller could be initializing or shutting | ||
| 3474 | * down). | ||
| 3475 | **/ | ||
| 3476 | static int add_to_scan_list(struct ctlr_info *h) | ||
| 3477 | { | ||
| 3478 | struct ctlr_info *test_h; | ||
| 3479 | int found = 0; | ||
| 3480 | int ret = 0; | ||
| 3481 | |||
| 3482 | if (h->busy_initializing) | ||
| 3483 | return 0; | ||
| 3484 | |||
| 3485 | if (!mutex_trylock(&h->busy_shutting_down)) | ||
| 3486 | return 0; | ||
| 3487 | |||
| 3488 | mutex_lock(&scan_mutex); | ||
| 3489 | list_for_each_entry(test_h, &scan_q, scan_list) { | ||
| 3490 | if (test_h == h) { | ||
| 3491 | found = 1; | ||
| 3492 | break; | ||
| 3493 | } | ||
| 3494 | } | ||
| 3495 | if (!found && !h->busy_scanning) { | ||
| 3496 | INIT_COMPLETION(h->scan_wait); | ||
| 3497 | list_add_tail(&h->scan_list, &scan_q); | ||
| 3498 | ret = 1; | ||
| 3499 | } | ||
| 3500 | mutex_unlock(&scan_mutex); | ||
| 3501 | mutex_unlock(&h->busy_shutting_down); | ||
| 3502 | |||
| 3503 | return ret; | ||
| 3504 | } | ||
| 3505 | |||
| 3506 | /** | ||
| 3507 | * remove_from_scan_list() - remove controller from rescan queue | ||
| 3508 | * @h: Pointer to the controller. | ||
| 3509 | * | ||
| 3510 | * Removes the controller from the rescan queue if present. Blocks if | ||
| 3511 | * the controller is currently conducting a rescan. | ||
| 3512 | **/ | ||
| 3513 | static void remove_from_scan_list(struct ctlr_info *h) | ||
| 3514 | { | ||
| 3515 | struct ctlr_info *test_h, *tmp_h; | ||
| 3516 | int scanning = 0; | ||
| 3517 | |||
| 3518 | mutex_lock(&scan_mutex); | ||
| 3519 | list_for_each_entry_safe(test_h, tmp_h, &scan_q, scan_list) { | ||
| 3520 | if (test_h == h) { | ||
| 3521 | list_del(&h->scan_list); | ||
| 3522 | complete_all(&h->scan_wait); | ||
| 3523 | mutex_unlock(&scan_mutex); | ||
| 3524 | return; | ||
| 3525 | } | ||
| 3526 | } | ||
| 3527 | if (&h->busy_scanning) | ||
| 3528 | scanning = 0; | ||
| 3529 | mutex_unlock(&scan_mutex); | ||
| 3530 | |||
| 3531 | if (scanning) | ||
| 3532 | wait_for_completion(&h->scan_wait); | ||
| 3533 | } | ||
| 3534 | |||
| 3535 | /** | ||
| 3536 | * scan_thread() - kernel thread used to rescan controllers | ||
| 3537 | * @data: Ignored. | ||
| 3538 | * | ||
| 3539 | * A kernel thread used scan for drive topology changes on | ||
| 3540 | * controllers. The thread processes only one controller at a time | ||
| 3541 | * using a queue. Controllers are added to the queue using | ||
| 3542 | * add_to_scan_list() and removed from the queue either after done | ||
| 3543 | * processing or using remove_from_scan_list(). | ||
| 3544 | * | ||
| 3545 | * returns 0. | ||
| 3546 | **/ | ||
| 3235 | static int scan_thread(void *data) | 3547 | static int scan_thread(void *data) |
| 3236 | { | 3548 | { |
| 3237 | ctlr_info_t *h = data; | 3549 | struct ctlr_info *h; |
| 3238 | int rc; | ||
| 3239 | DECLARE_COMPLETION_ONSTACK(wait); | ||
| 3240 | h->rescan_wait = &wait; | ||
| 3241 | 3550 | ||
| 3242 | for (;;) { | 3551 | while (1) { |
| 3243 | rc = wait_for_completion_interruptible(&wait); | 3552 | set_current_state(TASK_INTERRUPTIBLE); |
| 3553 | schedule(); | ||
| 3244 | if (kthread_should_stop()) | 3554 | if (kthread_should_stop()) |
| 3245 | break; | 3555 | break; |
| 3246 | if (!rc) | 3556 | |
| 3247 | rebuild_lun_table(h, 0); | 3557 | while (1) { |
| 3558 | mutex_lock(&scan_mutex); | ||
| 3559 | if (list_empty(&scan_q)) { | ||
| 3560 | mutex_unlock(&scan_mutex); | ||
| 3561 | break; | ||
| 3562 | } | ||
| 3563 | |||
| 3564 | h = list_entry(scan_q.next, | ||
| 3565 | struct ctlr_info, | ||
| 3566 | scan_list); | ||
| 3567 | list_del(&h->scan_list); | ||
| 3568 | h->busy_scanning = 1; | ||
| 3569 | mutex_unlock(&scan_mutex); | ||
| 3570 | |||
| 3571 | if (h) { | ||
| 3572 | rebuild_lun_table(h, 0, 0); | ||
| 3573 | complete_all(&h->scan_wait); | ||
| 3574 | mutex_lock(&scan_mutex); | ||
| 3575 | h->busy_scanning = 0; | ||
| 3576 | mutex_unlock(&scan_mutex); | ||
| 3577 | } | ||
| 3578 | } | ||
| 3248 | } | 3579 | } |
| 3580 | |||
| 3249 | return 0; | 3581 | return 0; |
| 3250 | } | 3582 | } |
| 3251 | 3583 | ||
| @@ -3268,8 +3600,8 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c) | |||
| 3268 | case REPORT_LUNS_CHANGED: | 3600 | case REPORT_LUNS_CHANGED: |
| 3269 | printk(KERN_WARNING "cciss%d: report LUN data " | 3601 | printk(KERN_WARNING "cciss%d: report LUN data " |
| 3270 | "changed\n", h->ctlr); | 3602 | "changed\n", h->ctlr); |
| 3271 | if (h->rescan_wait) | 3603 | add_to_scan_list(h); |
| 3272 | complete(h->rescan_wait); | 3604 | wake_up_process(cciss_scan_thread); |
| 3273 | return 1; | 3605 | return 1; |
| 3274 | break; | 3606 | break; |
| 3275 | case POWER_OR_RESET: | 3607 | case POWER_OR_RESET: |
| @@ -3489,7 +3821,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
| 3489 | if (scratchpad == CCISS_FIRMWARE_READY) | 3821 | if (scratchpad == CCISS_FIRMWARE_READY) |
| 3490 | break; | 3822 | break; |
| 3491 | set_current_state(TASK_INTERRUPTIBLE); | 3823 | set_current_state(TASK_INTERRUPTIBLE); |
| 3492 | schedule_timeout(HZ / 10); /* wait 100ms */ | 3824 | schedule_timeout(msecs_to_jiffies(100)); /* wait 100ms */ |
| 3493 | } | 3825 | } |
| 3494 | if (scratchpad != CCISS_FIRMWARE_READY) { | 3826 | if (scratchpad != CCISS_FIRMWARE_READY) { |
| 3495 | printk(KERN_WARNING "cciss: Board not ready. Timed out.\n"); | 3827 | printk(KERN_WARNING "cciss: Board not ready. Timed out.\n"); |
| @@ -3615,7 +3947,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
| 3615 | break; | 3947 | break; |
| 3616 | /* delay and try again */ | 3948 | /* delay and try again */ |
| 3617 | set_current_state(TASK_INTERRUPTIBLE); | 3949 | set_current_state(TASK_INTERRUPTIBLE); |
| 3618 | schedule_timeout(10); | 3950 | schedule_timeout(msecs_to_jiffies(1)); |
| 3619 | } | 3951 | } |
| 3620 | 3952 | ||
| 3621 | #ifdef CCISS_DEBUG | 3953 | #ifdef CCISS_DEBUG |
| @@ -3669,15 +4001,16 @@ Enomem: | |||
| 3669 | return -1; | 4001 | return -1; |
| 3670 | } | 4002 | } |
| 3671 | 4003 | ||
| 3672 | static void free_hba(int i) | 4004 | static void free_hba(int n) |
| 3673 | { | 4005 | { |
| 3674 | ctlr_info_t *p = hba[i]; | 4006 | ctlr_info_t *h = hba[n]; |
| 3675 | int n; | 4007 | int i; |
| 3676 | 4008 | ||
| 3677 | hba[i] = NULL; | 4009 | hba[n] = NULL; |
| 3678 | for (n = 0; n < CISS_MAX_LUN; n++) | 4010 | for (i = 0; i < h->highest_lun + 1; i++) |
| 3679 | put_disk(p->gendisk[n]); | 4011 | if (h->gendisk[i] != NULL) |
| 3680 | kfree(p); | 4012 | put_disk(h->gendisk[i]); |
| 4013 | kfree(h); | ||
| 3681 | } | 4014 | } |
| 3682 | 4015 | ||
| 3683 | /* Send a message CDB to the firmware. */ | 4016 | /* Send a message CDB to the firmware. */ |
| @@ -3918,6 +4251,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
| 3918 | hba[i]->busy_initializing = 1; | 4251 | hba[i]->busy_initializing = 1; |
| 3919 | INIT_HLIST_HEAD(&hba[i]->cmpQ); | 4252 | INIT_HLIST_HEAD(&hba[i]->cmpQ); |
| 3920 | INIT_HLIST_HEAD(&hba[i]->reqQ); | 4253 | INIT_HLIST_HEAD(&hba[i]->reqQ); |
| 4254 | mutex_init(&hba[i]->busy_shutting_down); | ||
| 3921 | 4255 | ||
| 3922 | if (cciss_pci_init(hba[i], pdev) != 0) | 4256 | if (cciss_pci_init(hba[i], pdev) != 0) |
| 3923 | goto clean0; | 4257 | goto clean0; |
| @@ -3926,6 +4260,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
| 3926 | hba[i]->ctlr = i; | 4260 | hba[i]->ctlr = i; |
| 3927 | hba[i]->pdev = pdev; | 4261 | hba[i]->pdev = pdev; |
| 3928 | 4262 | ||
| 4263 | init_completion(&hba[i]->scan_wait); | ||
| 4264 | |||
| 3929 | if (cciss_create_hba_sysfs_entry(hba[i])) | 4265 | if (cciss_create_hba_sysfs_entry(hba[i])) |
| 3930 | goto clean0; | 4266 | goto clean0; |
| 3931 | 4267 | ||
| @@ -4001,8 +4337,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
| 4001 | hba[i]->num_luns = 0; | 4337 | hba[i]->num_luns = 0; |
| 4002 | hba[i]->highest_lun = -1; | 4338 | hba[i]->highest_lun = -1; |
| 4003 | for (j = 0; j < CISS_MAX_LUN; j++) { | 4339 | for (j = 0; j < CISS_MAX_LUN; j++) { |
| 4004 | hba[i]->drv[j].raid_level = -1; | 4340 | hba[i]->drv[j] = NULL; |
| 4005 | hba[i]->drv[j].queue = NULL; | ||
| 4006 | hba[i]->gendisk[j] = NULL; | 4341 | hba[i]->gendisk[j] = NULL; |
| 4007 | } | 4342 | } |
| 4008 | 4343 | ||
| @@ -4035,14 +4370,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
| 4035 | 4370 | ||
| 4036 | hba[i]->cciss_max_sectors = 2048; | 4371 | hba[i]->cciss_max_sectors = 2048; |
| 4037 | 4372 | ||
| 4373 | rebuild_lun_table(hba[i], 1, 0); | ||
| 4038 | hba[i]->busy_initializing = 0; | 4374 | hba[i]->busy_initializing = 0; |
| 4039 | |||
| 4040 | rebuild_lun_table(hba[i], 1); | ||
| 4041 | hba[i]->cciss_scan_thread = kthread_run(scan_thread, hba[i], | ||
| 4042 | "cciss_scan%02d", i); | ||
| 4043 | if (IS_ERR(hba[i]->cciss_scan_thread)) | ||
| 4044 | return PTR_ERR(hba[i]->cciss_scan_thread); | ||
| 4045 | |||
| 4046 | return 1; | 4375 | return 1; |
| 4047 | 4376 | ||
| 4048 | clean4: | 4377 | clean4: |
| @@ -4063,12 +4392,7 @@ clean1: | |||
| 4063 | cciss_destroy_hba_sysfs_entry(hba[i]); | 4392 | cciss_destroy_hba_sysfs_entry(hba[i]); |
| 4064 | clean0: | 4393 | clean0: |
| 4065 | hba[i]->busy_initializing = 0; | 4394 | hba[i]->busy_initializing = 0; |
| 4066 | /* cleanup any queues that may have been initialized */ | 4395 | |
| 4067 | for (j=0; j <= hba[i]->highest_lun; j++){ | ||
| 4068 | drive_info_struct *drv = &(hba[i]->drv[j]); | ||
| 4069 | if (drv->queue) | ||
| 4070 | blk_cleanup_queue(drv->queue); | ||
| 4071 | } | ||
| 4072 | /* | 4396 | /* |
| 4073 | * Deliberately omit pci_disable_device(): it does something nasty to | 4397 | * Deliberately omit pci_disable_device(): it does something nasty to |
| 4074 | * Smart Array controllers that pci_enable_device does not undo | 4398 | * Smart Array controllers that pci_enable_device does not undo |
| @@ -4125,8 +4449,9 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) | |||
| 4125 | return; | 4449 | return; |
| 4126 | } | 4450 | } |
| 4127 | 4451 | ||
| 4128 | kthread_stop(hba[i]->cciss_scan_thread); | 4452 | mutex_lock(&hba[i]->busy_shutting_down); |
| 4129 | 4453 | ||
| 4454 | remove_from_scan_list(hba[i]); | ||
| 4130 | remove_proc_entry(hba[i]->devname, proc_cciss); | 4455 | remove_proc_entry(hba[i]->devname, proc_cciss); |
| 4131 | unregister_blkdev(hba[i]->major, hba[i]->devname); | 4456 | unregister_blkdev(hba[i]->major, hba[i]->devname); |
| 4132 | 4457 | ||
| @@ -4136,8 +4461,10 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) | |||
| 4136 | if (disk) { | 4461 | if (disk) { |
| 4137 | struct request_queue *q = disk->queue; | 4462 | struct request_queue *q = disk->queue; |
| 4138 | 4463 | ||
| 4139 | if (disk->flags & GENHD_FL_UP) | 4464 | if (disk->flags & GENHD_FL_UP) { |
| 4465 | cciss_destroy_ld_sysfs_entry(hba[i], j, 1); | ||
| 4140 | del_gendisk(disk); | 4466 | del_gendisk(disk); |
| 4467 | } | ||
| 4141 | if (q) | 4468 | if (q) |
| 4142 | blk_cleanup_queue(q); | 4469 | blk_cleanup_queue(q); |
| 4143 | } | 4470 | } |
| @@ -4170,6 +4497,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) | |||
| 4170 | pci_release_regions(pdev); | 4497 | pci_release_regions(pdev); |
| 4171 | pci_set_drvdata(pdev, NULL); | 4498 | pci_set_drvdata(pdev, NULL); |
| 4172 | cciss_destroy_hba_sysfs_entry(hba[i]); | 4499 | cciss_destroy_hba_sysfs_entry(hba[i]); |
| 4500 | mutex_unlock(&hba[i]->busy_shutting_down); | ||
| 4173 | free_hba(i); | 4501 | free_hba(i); |
| 4174 | } | 4502 | } |
| 4175 | 4503 | ||
| @@ -4202,15 +4530,25 @@ static int __init cciss_init(void) | |||
| 4202 | if (err) | 4530 | if (err) |
| 4203 | return err; | 4531 | return err; |
| 4204 | 4532 | ||
| 4533 | /* Start the scan thread */ | ||
| 4534 | cciss_scan_thread = kthread_run(scan_thread, NULL, "cciss_scan"); | ||
| 4535 | if (IS_ERR(cciss_scan_thread)) { | ||
| 4536 | err = PTR_ERR(cciss_scan_thread); | ||
| 4537 | goto err_bus_unregister; | ||
| 4538 | } | ||
| 4539 | |||
| 4205 | /* Register for our PCI devices */ | 4540 | /* Register for our PCI devices */ |
| 4206 | err = pci_register_driver(&cciss_pci_driver); | 4541 | err = pci_register_driver(&cciss_pci_driver); |
| 4207 | if (err) | 4542 | if (err) |
| 4208 | goto err_bus_register; | 4543 | goto err_thread_stop; |
| 4209 | 4544 | ||
| 4210 | return 0; | 4545 | return err; |
| 4211 | 4546 | ||
| 4212 | err_bus_register: | 4547 | err_thread_stop: |
| 4548 | kthread_stop(cciss_scan_thread); | ||
| 4549 | err_bus_unregister: | ||
| 4213 | bus_unregister(&cciss_bus_type); | 4550 | bus_unregister(&cciss_bus_type); |
| 4551 | |||
| 4214 | return err; | 4552 | return err; |
| 4215 | } | 4553 | } |
| 4216 | 4554 | ||
| @@ -4227,6 +4565,7 @@ static void __exit cciss_cleanup(void) | |||
| 4227 | cciss_remove_one(hba[i]->pdev); | 4565 | cciss_remove_one(hba[i]->pdev); |
| 4228 | } | 4566 | } |
| 4229 | } | 4567 | } |
| 4568 | kthread_stop(cciss_scan_thread); | ||
| 4230 | remove_proc_entry("driver/cciss", NULL); | 4569 | remove_proc_entry("driver/cciss", NULL); |
| 4231 | bus_unregister(&cciss_bus_type); | 4570 | bus_unregister(&cciss_bus_type); |
| 4232 | } | 4571 | } |
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index 06a5db25b298..31524cf42c77 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #define CCISS_H | 2 | #define CCISS_H |
| 3 | 3 | ||
| 4 | #include <linux/genhd.h> | 4 | #include <linux/genhd.h> |
| 5 | #include <linux/mutex.h> | ||
| 5 | 6 | ||
| 6 | #include "cciss_cmd.h" | 7 | #include "cciss_cmd.h" |
| 7 | 8 | ||
| @@ -29,7 +30,7 @@ struct access_method { | |||
| 29 | }; | 30 | }; |
| 30 | typedef struct _drive_info_struct | 31 | typedef struct _drive_info_struct |
| 31 | { | 32 | { |
| 32 | __u32 LunID; | 33 | unsigned char LunID[8]; |
| 33 | int usage_count; | 34 | int usage_count; |
| 34 | struct request_queue *queue; | 35 | struct request_queue *queue; |
| 35 | sector_t nr_blocks; | 36 | sector_t nr_blocks; |
| @@ -51,6 +52,7 @@ typedef struct _drive_info_struct | |||
| 51 | char vendor[VENDOR_LEN + 1]; /* SCSI vendor string */ | 52 | char vendor[VENDOR_LEN + 1]; /* SCSI vendor string */ |
| 52 | char model[MODEL_LEN + 1]; /* SCSI model string */ | 53 | char model[MODEL_LEN + 1]; /* SCSI model string */ |
| 53 | char rev[REV_LEN + 1]; /* SCSI revision string */ | 54 | char rev[REV_LEN + 1]; /* SCSI revision string */ |
| 55 | char device_initialized; /* indicates whether dev is initialized */ | ||
| 54 | } drive_info_struct; | 56 | } drive_info_struct; |
| 55 | 57 | ||
| 56 | struct ctlr_info | 58 | struct ctlr_info |
| @@ -86,7 +88,7 @@ struct ctlr_info | |||
| 86 | BYTE cciss_read_capacity; | 88 | BYTE cciss_read_capacity; |
| 87 | 89 | ||
| 88 | // information about each logical volume | 90 | // information about each logical volume |
| 89 | drive_info_struct drv[CISS_MAX_LUN]; | 91 | drive_info_struct *drv[CISS_MAX_LUN]; |
| 90 | 92 | ||
| 91 | struct access_method access; | 93 | struct access_method access; |
| 92 | 94 | ||
| @@ -108,6 +110,8 @@ struct ctlr_info | |||
| 108 | int nr_frees; | 110 | int nr_frees; |
| 109 | int busy_configuring; | 111 | int busy_configuring; |
| 110 | int busy_initializing; | 112 | int busy_initializing; |
| 113 | int busy_scanning; | ||
| 114 | struct mutex busy_shutting_down; | ||
| 111 | 115 | ||
| 112 | /* This element holds the zero based queue number of the last | 116 | /* This element holds the zero based queue number of the last |
| 113 | * queue to be started. It is used for fairness. | 117 | * queue to be started. It is used for fairness. |
| @@ -122,8 +126,8 @@ struct ctlr_info | |||
| 122 | /* and saved for later processing */ | 126 | /* and saved for later processing */ |
| 123 | #endif | 127 | #endif |
| 124 | unsigned char alive; | 128 | unsigned char alive; |
| 125 | struct completion *rescan_wait; | 129 | struct list_head scan_list; |
| 126 | struct task_struct *cciss_scan_thread; | 130 | struct completion scan_wait; |
| 127 | struct device dev; | 131 | struct device dev; |
| 128 | }; | 132 | }; |
| 129 | 133 | ||
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index b82d438e2607..6422651ec364 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <linux/blkpg.h> | 32 | #include <linux/blkpg.h> |
| 33 | #include <linux/timer.h> | 33 | #include <linux/timer.h> |
| 34 | #include <linux/proc_fs.h> | 34 | #include <linux/proc_fs.h> |
| 35 | #include <linux/seq_file.h> | ||
| 35 | #include <linux/init.h> | 36 | #include <linux/init.h> |
| 36 | #include <linux/hdreg.h> | 37 | #include <linux/hdreg.h> |
| 37 | #include <linux/spinlock.h> | 38 | #include <linux/spinlock.h> |
| @@ -177,7 +178,6 @@ static int cpqarray_register_ctlr(int ctlr, struct pci_dev *pdev); | |||
| 177 | 178 | ||
| 178 | #ifdef CONFIG_PROC_FS | 179 | #ifdef CONFIG_PROC_FS |
| 179 | static void ida_procinit(int i); | 180 | static void ida_procinit(int i); |
| 180 | static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data); | ||
| 181 | #else | 181 | #else |
| 182 | static void ida_procinit(int i) {} | 182 | static void ida_procinit(int i) {} |
| 183 | #endif | 183 | #endif |
| @@ -206,6 +206,7 @@ static const struct block_device_operations ida_fops = { | |||
| 206 | #ifdef CONFIG_PROC_FS | 206 | #ifdef CONFIG_PROC_FS |
| 207 | 207 | ||
| 208 | static struct proc_dir_entry *proc_array; | 208 | static struct proc_dir_entry *proc_array; |
| 209 | static const struct file_operations ida_proc_fops; | ||
| 209 | 210 | ||
| 210 | /* | 211 | /* |
| 211 | * Get us a file in /proc/array that says something about each controller. | 212 | * Get us a file in /proc/array that says something about each controller. |
| @@ -218,19 +219,16 @@ static void __init ida_procinit(int i) | |||
| 218 | if (!proc_array) return; | 219 | if (!proc_array) return; |
| 219 | } | 220 | } |
| 220 | 221 | ||
| 221 | create_proc_read_entry(hba[i]->devname, 0, proc_array, | 222 | proc_create_data(hba[i]->devname, 0, proc_array, &ida_proc_fops, hba[i]); |
| 222 | ida_proc_get_info, hba[i]); | ||
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | /* | 225 | /* |
| 226 | * Report information about this controller. | 226 | * Report information about this controller. |
| 227 | */ | 227 | */ |
| 228 | static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data) | 228 | static int ida_proc_show(struct seq_file *m, void *v) |
| 229 | { | 229 | { |
| 230 | off_t pos = 0; | 230 | int i, ctlr; |
| 231 | off_t len = 0; | 231 | ctlr_info_t *h = (ctlr_info_t*)m->private; |
| 232 | int size, i, ctlr; | ||
| 233 | ctlr_info_t *h = (ctlr_info_t*)data; | ||
| 234 | drv_info_t *drv; | 232 | drv_info_t *drv; |
| 235 | #ifdef CPQ_PROC_PRINT_QUEUES | 233 | #ifdef CPQ_PROC_PRINT_QUEUES |
| 236 | cmdlist_t *c; | 234 | cmdlist_t *c; |
| @@ -238,7 +236,7 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset, int lengt | |||
| 238 | #endif | 236 | #endif |
| 239 | 237 | ||
| 240 | ctlr = h->ctlr; | 238 | ctlr = h->ctlr; |
| 241 | size = sprintf(buffer, "%s: Compaq %s Controller\n" | 239 | seq_printf(m, "%s: Compaq %s Controller\n" |
| 242 | " Board ID: 0x%08lx\n" | 240 | " Board ID: 0x%08lx\n" |
| 243 | " Firmware Revision: %c%c%c%c\n" | 241 | " Firmware Revision: %c%c%c%c\n" |
| 244 | " Controller Sig: 0x%08lx\n" | 242 | " Controller Sig: 0x%08lx\n" |
| @@ -258,55 +256,54 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset, int lengt | |||
| 258 | h->log_drives, h->phys_drives, | 256 | h->log_drives, h->phys_drives, |
| 259 | h->Qdepth, h->maxQsinceinit); | 257 | h->Qdepth, h->maxQsinceinit); |
| 260 | 258 | ||
| 261 | pos += size; len += size; | 259 | seq_puts(m, "Logical Drive Info:\n"); |
| 262 | |||
| 263 | size = sprintf(buffer+len, "Logical Drive Info:\n"); | ||
| 264 | pos += size; len += size; | ||
| 265 | 260 | ||
| 266 | for(i=0; i<h->log_drives; i++) { | 261 | for(i=0; i<h->log_drives; i++) { |
| 267 | drv = &h->drv[i]; | 262 | drv = &h->drv[i]; |
| 268 | size = sprintf(buffer+len, "ida/c%dd%d: blksz=%d nr_blks=%d\n", | 263 | seq_printf(m, "ida/c%dd%d: blksz=%d nr_blks=%d\n", |
| 269 | ctlr, i, drv->blk_size, drv->nr_blks); | 264 | ctlr, i, drv->blk_size, drv->nr_blks); |
| 270 | pos += size; len += size; | ||
| 271 | } | 265 | } |
| 272 | 266 | ||
| 273 | #ifdef CPQ_PROC_PRINT_QUEUES | 267 | #ifdef CPQ_PROC_PRINT_QUEUES |
| 274 | spin_lock_irqsave(IDA_LOCK(h->ctlr), flags); | 268 | spin_lock_irqsave(IDA_LOCK(h->ctlr), flags); |
| 275 | size = sprintf(buffer+len, "\nCurrent Queues:\n"); | 269 | seq_puts(m, "\nCurrent Queues:\n"); |
| 276 | pos += size; len += size; | ||
| 277 | 270 | ||
| 278 | c = h->reqQ; | 271 | c = h->reqQ; |
| 279 | size = sprintf(buffer+len, "reqQ = %p", c); pos += size; len += size; | 272 | seq_printf(m, "reqQ = %p", c); |
| 280 | if (c) c=c->next; | 273 | if (c) c=c->next; |
| 281 | while(c && c != h->reqQ) { | 274 | while(c && c != h->reqQ) { |
| 282 | size = sprintf(buffer+len, "->%p", c); | 275 | seq_printf(m, "->%p", c); |
| 283 | pos += size; len += size; | ||
| 284 | c=c->next; | 276 | c=c->next; |
| 285 | } | 277 | } |
| 286 | 278 | ||
| 287 | c = h->cmpQ; | 279 | c = h->cmpQ; |
| 288 | size = sprintf(buffer+len, "\ncmpQ = %p", c); pos += size; len += size; | 280 | seq_printf(m, "\ncmpQ = %p", c); |
| 289 | if (c) c=c->next; | 281 | if (c) c=c->next; |
| 290 | while(c && c != h->cmpQ) { | 282 | while(c && c != h->cmpQ) { |
| 291 | size = sprintf(buffer+len, "->%p", c); | 283 | seq_printf(m, "->%p", c); |
| 292 | pos += size; len += size; | ||
| 293 | c=c->next; | 284 | c=c->next; |
| 294 | } | 285 | } |
| 295 | 286 | ||
| 296 | size = sprintf(buffer+len, "\n"); pos += size; len += size; | 287 | seq_putc(m, '\n'); |
| 297 | spin_unlock_irqrestore(IDA_LOCK(h->ctlr), flags); | 288 | spin_unlock_irqrestore(IDA_LOCK(h->ctlr), flags); |
| 298 | #endif | 289 | #endif |
| 299 | size = sprintf(buffer+len, "nr_allocs = %d\nnr_frees = %d\n", | 290 | seq_printf(m, "nr_allocs = %d\nnr_frees = %d\n", |
| 300 | h->nr_allocs, h->nr_frees); | 291 | h->nr_allocs, h->nr_frees); |
| 301 | pos += size; len += size; | 292 | return 0; |
| 302 | 293 | } | |
| 303 | *eof = 1; | 294 | |
| 304 | *start = buffer+offset; | 295 | static int ida_proc_open(struct inode *inode, struct file *file) |
| 305 | len -= offset; | 296 | { |
| 306 | if (len>length) | 297 | return single_open(file, ida_proc_show, PDE(inode)->data); |
| 307 | len = length; | ||
| 308 | return len; | ||
| 309 | } | 298 | } |
| 299 | |||
| 300 | static const struct file_operations ida_proc_fops = { | ||
| 301 | .owner = THIS_MODULE, | ||
| 302 | .open = ida_proc_open, | ||
| 303 | .read = seq_read, | ||
| 304 | .llseek = seq_lseek, | ||
| 305 | .release = single_release, | ||
| 306 | }; | ||
| 310 | #endif /* CONFIG_PROC_FS */ | 307 | #endif /* CONFIG_PROC_FS */ |
| 311 | 308 | ||
| 312 | module_param_array(eisa, int, NULL, 0); | 309 | module_param_array(eisa, int, NULL, 0); |
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c index 52e06589821d..045c930e6320 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c | |||
| @@ -56,6 +56,7 @@ | |||
| 56 | #include <linux/errno.h> /* for -EBUSY */ | 56 | #include <linux/errno.h> /* for -EBUSY */ |
| 57 | #include <linux/ioport.h> /* for request_region */ | 57 | #include <linux/ioport.h> /* for request_region */ |
| 58 | #include <linux/delay.h> /* for loops_per_jiffy */ | 58 | #include <linux/delay.h> /* for loops_per_jiffy */ |
| 59 | #include <linux/sched.h> | ||
| 59 | #include <linux/smp_lock.h> /* cycle_kernel_lock() */ | 60 | #include <linux/smp_lock.h> /* cycle_kernel_lock() */ |
| 60 | #include <asm/io.h> /* for inb_p, outb_p, inb, outb, etc. */ | 61 | #include <asm/io.h> /* for inb_p, outb_p, inb, outb, etc. */ |
| 61 | #include <asm/uaccess.h> /* for get_user, etc. */ | 62 | #include <asm/uaccess.h> /* for get_user, etc. */ |
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 41fc11dc921c..65545de3dbf4 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include <linux/errno.h> | 36 | #include <linux/errno.h> |
| 37 | #include <asm/system.h> | 37 | #include <asm/system.h> |
| 38 | #include <linux/poll.h> | 38 | #include <linux/poll.h> |
| 39 | #include <linux/sched.h> | ||
| 39 | #include <linux/spinlock.h> | 40 | #include <linux/spinlock.h> |
| 40 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
| 41 | #include <linux/ipmi.h> | 42 | #include <linux/ipmi.h> |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 09050797c76a..ec5e3f8df648 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <linux/errno.h> | 35 | #include <linux/errno.h> |
| 36 | #include <asm/system.h> | 36 | #include <asm/system.h> |
| 37 | #include <linux/poll.h> | 37 | #include <linux/poll.h> |
| 38 | #include <linux/sched.h> | ||
| 38 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
| 39 | #include <linux/mutex.h> | 40 | #include <linux/mutex.h> |
| 40 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index ced186d7e9a9..5089331544ed 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
| 34 | #include <linux/poll.h> | 34 | #include <linux/poll.h> |
| 35 | #include <linux/preempt.h> | 35 | #include <linux/preempt.h> |
| 36 | #include <linux/sched.h> | ||
| 36 | #include <linux/spinlock.h> | 37 | #include <linux/spinlock.h> |
| 37 | #include <linux/time.h> | 38 | #include <linux/time.h> |
| 38 | #include <linux/uaccess.h> | 39 | #include <linux/uaccess.h> |
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c index 420a96e7f2db..051d1ebbd287 100644 --- a/drivers/firmware/iscsi_ibft.c +++ b/drivers/firmware/iscsi_ibft.c | |||
| @@ -939,7 +939,7 @@ static int __init ibft_init(void) | |||
| 939 | 939 | ||
| 940 | if (ibft_addr) { | 940 | if (ibft_addr) { |
| 941 | printk(KERN_INFO "iBFT detected at 0x%llx.\n", | 941 | printk(KERN_INFO "iBFT detected at 0x%llx.\n", |
| 942 | (u64)virt_to_phys((void *)ibft_addr)); | 942 | (u64)isa_virt_to_bus(ibft_addr)); |
| 943 | 943 | ||
| 944 | rc = ibft_check_device(); | 944 | rc = ibft_check_device(); |
| 945 | if (rc) | 945 | if (rc) |
diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c index d53fbbfefa3e..dfb15c06c88f 100644 --- a/drivers/firmware/iscsi_ibft_find.c +++ b/drivers/firmware/iscsi_ibft_find.c | |||
| @@ -65,10 +65,10 @@ void __init reserve_ibft_region(void) | |||
| 65 | * so skip that area */ | 65 | * so skip that area */ |
| 66 | if (pos == VGA_MEM) | 66 | if (pos == VGA_MEM) |
| 67 | pos += VGA_SIZE; | 67 | pos += VGA_SIZE; |
| 68 | virt = phys_to_virt(pos); | 68 | virt = isa_bus_to_virt(pos); |
| 69 | if (memcmp(virt, IBFT_SIGN, IBFT_SIGN_LEN) == 0) { | 69 | if (memcmp(virt, IBFT_SIGN, IBFT_SIGN_LEN) == 0) { |
| 70 | unsigned long *addr = | 70 | unsigned long *addr = |
| 71 | (unsigned long *)phys_to_virt(pos + 4); | 71 | (unsigned long *)isa_bus_to_virt(pos + 4); |
| 72 | len = *addr; | 72 | len = *addr; |
| 73 | /* if the length of the table extends past 1M, | 73 | /* if the length of the table extends past 1M, |
| 74 | * the table cannot be valid. */ | 74 | * the table cannot be valid. */ |
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 0c6639ea03dd..ba05275e5104 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/major.h> | 30 | #include <linux/major.h> |
| 31 | #include <linux/hid.h> | 31 | #include <linux/hid.h> |
| 32 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
| 33 | #include <linux/sched.h> | ||
| 33 | #include <linux/smp_lock.h> | 34 | #include <linux/smp_lock.h> |
| 34 | 35 | ||
| 35 | #include <linux/hidraw.h> | 36 | #include <linux/hidraw.h> |
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c index 6c9a04136e0a..00d975eb5b83 100644 --- a/drivers/hwmon/ltc4215.c +++ b/drivers/hwmon/ltc4215.c | |||
| @@ -20,11 +20,6 @@ | |||
| 20 | #include <linux/hwmon.h> | 20 | #include <linux/hwmon.h> |
| 21 | #include <linux/hwmon-sysfs.h> | 21 | #include <linux/hwmon-sysfs.h> |
| 22 | 22 | ||
| 23 | static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; | ||
| 24 | |||
| 25 | /* Insmod parameters */ | ||
| 26 | I2C_CLIENT_INSMOD_1(ltc4215); | ||
| 27 | |||
| 28 | /* Here are names of the chip's registers (a.k.a. commands) */ | 23 | /* Here are names of the chip's registers (a.k.a. commands) */ |
| 29 | enum ltc4215_cmd { | 24 | enum ltc4215_cmd { |
| 30 | LTC4215_CONTROL = 0x00, /* rw */ | 25 | LTC4215_CONTROL = 0x00, /* rw */ |
| @@ -246,9 +241,13 @@ static const struct attribute_group ltc4215_group = { | |||
| 246 | static int ltc4215_probe(struct i2c_client *client, | 241 | static int ltc4215_probe(struct i2c_client *client, |
| 247 | const struct i2c_device_id *id) | 242 | const struct i2c_device_id *id) |
| 248 | { | 243 | { |
| 244 | struct i2c_adapter *adapter = client->adapter; | ||
| 249 | struct ltc4215_data *data; | 245 | struct ltc4215_data *data; |
| 250 | int ret; | 246 | int ret; |
| 251 | 247 | ||
| 248 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
| 249 | return -ENODEV; | ||
| 250 | |||
| 252 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 251 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
| 253 | if (!data) { | 252 | if (!data) { |
| 254 | ret = -ENOMEM; | 253 | ret = -ENOMEM; |
| @@ -294,56 +293,20 @@ static int ltc4215_remove(struct i2c_client *client) | |||
| 294 | return 0; | 293 | return 0; |
| 295 | } | 294 | } |
| 296 | 295 | ||
| 297 | static int ltc4215_detect(struct i2c_client *client, | ||
| 298 | int kind, | ||
| 299 | struct i2c_board_info *info) | ||
| 300 | { | ||
| 301 | struct i2c_adapter *adapter = client->adapter; | ||
| 302 | |||
| 303 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
| 304 | return -ENODEV; | ||
| 305 | |||
| 306 | if (kind < 0) { /* probed detection - check the chip type */ | ||
| 307 | s32 v; /* 8 bits from the chip, or -ERRNO */ | ||
| 308 | |||
| 309 | /* | ||
| 310 | * Register 0x01 bit b7 is reserved, expect 0 | ||
| 311 | * Register 0x03 bit b6 and b7 are reserved, expect 0 | ||
| 312 | */ | ||
| 313 | v = i2c_smbus_read_byte_data(client, LTC4215_ALERT); | ||
| 314 | if (v < 0 || (v & (1 << 7)) != 0) | ||
| 315 | return -ENODEV; | ||
| 316 | |||
| 317 | v = i2c_smbus_read_byte_data(client, LTC4215_FAULT); | ||
| 318 | if (v < 0 || (v & ((1 << 6) | (1 << 7))) != 0) | ||
| 319 | return -ENODEV; | ||
| 320 | } | ||
| 321 | |||
| 322 | strlcpy(info->type, "ltc4215", I2C_NAME_SIZE); | ||
| 323 | dev_info(&adapter->dev, "ltc4215 %s at address 0x%02x\n", | ||
| 324 | kind < 0 ? "probed" : "forced", | ||
| 325 | client->addr); | ||
| 326 | |||
| 327 | return 0; | ||
| 328 | } | ||
| 329 | |||
| 330 | static const struct i2c_device_id ltc4215_id[] = { | 296 | static const struct i2c_device_id ltc4215_id[] = { |
| 331 | { "ltc4215", ltc4215 }, | 297 | { "ltc4215", 0 }, |
| 332 | { } | 298 | { } |
| 333 | }; | 299 | }; |
| 334 | MODULE_DEVICE_TABLE(i2c, ltc4215_id); | 300 | MODULE_DEVICE_TABLE(i2c, ltc4215_id); |
| 335 | 301 | ||
| 336 | /* This is the driver that will be inserted */ | 302 | /* This is the driver that will be inserted */ |
| 337 | static struct i2c_driver ltc4215_driver = { | 303 | static struct i2c_driver ltc4215_driver = { |
| 338 | .class = I2C_CLASS_HWMON, | ||
| 339 | .driver = { | 304 | .driver = { |
| 340 | .name = "ltc4215", | 305 | .name = "ltc4215", |
| 341 | }, | 306 | }, |
| 342 | .probe = ltc4215_probe, | 307 | .probe = ltc4215_probe, |
| 343 | .remove = ltc4215_remove, | 308 | .remove = ltc4215_remove, |
| 344 | .id_table = ltc4215_id, | 309 | .id_table = ltc4215_id, |
| 345 | .detect = ltc4215_detect, | ||
| 346 | .address_data = &addr_data, | ||
| 347 | }; | 310 | }; |
| 348 | 311 | ||
| 349 | static int __init ltc4215_init(void) | 312 | static int __init ltc4215_init(void) |
diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c index e38964333612..65c232a9d0c5 100644 --- a/drivers/hwmon/ltc4245.c +++ b/drivers/hwmon/ltc4245.c | |||
| @@ -22,15 +22,6 @@ | |||
| 22 | #include <linux/hwmon.h> | 22 | #include <linux/hwmon.h> |
| 23 | #include <linux/hwmon-sysfs.h> | 23 | #include <linux/hwmon-sysfs.h> |
| 24 | 24 | ||
| 25 | /* Valid addresses are 0x20 - 0x3f | ||
| 26 | * | ||
| 27 | * For now, we do not probe, since some of these addresses | ||
| 28 | * are known to be unfriendly to probing */ | ||
| 29 | static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; | ||
| 30 | |||
| 31 | /* Insmod parameters */ | ||
| 32 | I2C_CLIENT_INSMOD_1(ltc4245); | ||
| 33 | |||
| 34 | /* Here are names of the chip's registers (a.k.a. commands) */ | 25 | /* Here are names of the chip's registers (a.k.a. commands) */ |
| 35 | enum ltc4245_cmd { | 26 | enum ltc4245_cmd { |
| 36 | LTC4245_STATUS = 0x00, /* readonly */ | 27 | LTC4245_STATUS = 0x00, /* readonly */ |
| @@ -369,9 +360,13 @@ static const struct attribute_group ltc4245_group = { | |||
| 369 | static int ltc4245_probe(struct i2c_client *client, | 360 | static int ltc4245_probe(struct i2c_client *client, |
| 370 | const struct i2c_device_id *id) | 361 | const struct i2c_device_id *id) |
| 371 | { | 362 | { |
| 363 | struct i2c_adapter *adapter = client->adapter; | ||
| 372 | struct ltc4245_data *data; | 364 | struct ltc4245_data *data; |
| 373 | int ret; | 365 | int ret; |
| 374 | 366 | ||
| 367 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
| 368 | return -ENODEV; | ||
| 369 | |||
| 375 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 370 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
| 376 | if (!data) { | 371 | if (!data) { |
| 377 | ret = -ENOMEM; | 372 | ret = -ENOMEM; |
| @@ -418,136 +413,20 @@ static int ltc4245_remove(struct i2c_client *client) | |||
| 418 | return 0; | 413 | return 0; |
| 419 | } | 414 | } |
| 420 | 415 | ||
| 421 | /* Check that some bits in a control register appear at all possible | ||
| 422 | * locations without changing value | ||
| 423 | * | ||
| 424 | * @client: the i2c client to use | ||
| 425 | * @reg: the register to read | ||
| 426 | * @bits: the bits to check (0xff checks all bits, | ||
| 427 | * 0x03 checks only the last two bits) | ||
| 428 | * | ||
| 429 | * return -ERRNO if the register read failed | ||
| 430 | * return -ENODEV if the register value doesn't stay constant at all | ||
| 431 | * possible addresses | ||
| 432 | * | ||
| 433 | * return 0 for success | ||
| 434 | */ | ||
| 435 | static int ltc4245_check_control_reg(struct i2c_client *client, u8 reg, u8 bits) | ||
| 436 | { | ||
| 437 | int i; | ||
| 438 | s32 v, voff1, voff2; | ||
| 439 | |||
| 440 | /* Read register and check for error */ | ||
| 441 | v = i2c_smbus_read_byte_data(client, reg); | ||
| 442 | if (v < 0) | ||
| 443 | return v; | ||
| 444 | |||
| 445 | v &= bits; | ||
| 446 | |||
| 447 | for (i = 0x00; i < 0xff; i += 0x20) { | ||
| 448 | |||
| 449 | voff1 = i2c_smbus_read_byte_data(client, reg + i); | ||
| 450 | if (voff1 < 0) | ||
| 451 | return voff1; | ||
| 452 | |||
| 453 | voff2 = i2c_smbus_read_byte_data(client, reg + i + 0x08); | ||
| 454 | if (voff2 < 0) | ||
| 455 | return voff2; | ||
| 456 | |||
| 457 | voff1 &= bits; | ||
| 458 | voff2 &= bits; | ||
| 459 | |||
| 460 | if (v != voff1 || v != voff2) | ||
| 461 | return -ENODEV; | ||
| 462 | } | ||
| 463 | |||
| 464 | return 0; | ||
| 465 | } | ||
| 466 | |||
| 467 | static int ltc4245_detect(struct i2c_client *client, | ||
| 468 | int kind, | ||
| 469 | struct i2c_board_info *info) | ||
| 470 | { | ||
| 471 | struct i2c_adapter *adapter = client->adapter; | ||
| 472 | |||
| 473 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
| 474 | return -ENODEV; | ||
| 475 | |||
| 476 | if (kind < 0) { /* probed detection - check the chip type */ | ||
| 477 | s32 v; /* 8 bits from the chip, or -ERRNO */ | ||
| 478 | |||
| 479 | /* Chip registers 0x00-0x07 are control registers | ||
| 480 | * Chip registers 0x10-0x1f are data registers | ||
| 481 | * | ||
| 482 | * Address bits b7-b5 are ignored. This makes the chip "repeat" | ||
| 483 | * in steps of 0x20. Any control registers should appear with | ||
| 484 | * the same values across all duplicated addresses. | ||
| 485 | * | ||
| 486 | * Register 0x02 bit b2 is reserved, expect 0 | ||
| 487 | * Register 0x07 bits b7 to b4 are reserved, expect 0 | ||
| 488 | * | ||
| 489 | * Registers 0x01, 0x02 are control registers and should not | ||
| 490 | * change on their own. | ||
| 491 | * | ||
| 492 | * Register 0x06 bits b6 and b7 are control bits, and should | ||
| 493 | * not change on their own. | ||
| 494 | * | ||
| 495 | * Register 0x07 bits b3 to b0 are control bits, and should | ||
| 496 | * not change on their own. | ||
| 497 | */ | ||
| 498 | |||
| 499 | /* read register 0x02 reserved bit, expect 0 */ | ||
| 500 | v = i2c_smbus_read_byte_data(client, LTC4245_CONTROL); | ||
| 501 | if (v < 0 || (v & 0x04) != 0) | ||
| 502 | return -ENODEV; | ||
| 503 | |||
| 504 | /* read register 0x07 reserved bits, expect 0 */ | ||
| 505 | v = i2c_smbus_read_byte_data(client, LTC4245_ADCADR); | ||
| 506 | if (v < 0 || (v & 0xf0) != 0) | ||
| 507 | return -ENODEV; | ||
| 508 | |||
| 509 | /* check that the alert register appears at all locations */ | ||
| 510 | if (ltc4245_check_control_reg(client, LTC4245_ALERT, 0xff)) | ||
| 511 | return -ENODEV; | ||
| 512 | |||
| 513 | /* check that the control register appears at all locations */ | ||
| 514 | if (ltc4245_check_control_reg(client, LTC4245_CONTROL, 0xff)) | ||
| 515 | return -ENODEV; | ||
| 516 | |||
| 517 | /* check that register 0x06 bits b6 and b7 stay constant */ | ||
| 518 | if (ltc4245_check_control_reg(client, LTC4245_GPIO, 0xc0)) | ||
| 519 | return -ENODEV; | ||
| 520 | |||
| 521 | /* check that register 0x07 bits b3-b0 stay constant */ | ||
| 522 | if (ltc4245_check_control_reg(client, LTC4245_ADCADR, 0x0f)) | ||
| 523 | return -ENODEV; | ||
| 524 | } | ||
| 525 | |||
| 526 | strlcpy(info->type, "ltc4245", I2C_NAME_SIZE); | ||
| 527 | dev_info(&adapter->dev, "ltc4245 %s at address 0x%02x\n", | ||
| 528 | kind < 0 ? "probed" : "forced", | ||
| 529 | client->addr); | ||
| 530 | |||
| 531 | return 0; | ||
| 532 | } | ||
| 533 | |||
| 534 | static const struct i2c_device_id ltc4245_id[] = { | 416 | static const struct i2c_device_id ltc4245_id[] = { |
| 535 | { "ltc4245", ltc4245 }, | 417 | { "ltc4245", 0 }, |
| 536 | { } | 418 | { } |
| 537 | }; | 419 | }; |
| 538 | MODULE_DEVICE_TABLE(i2c, ltc4245_id); | 420 | MODULE_DEVICE_TABLE(i2c, ltc4245_id); |
| 539 | 421 | ||
| 540 | /* This is the driver that will be inserted */ | 422 | /* This is the driver that will be inserted */ |
| 541 | static struct i2c_driver ltc4245_driver = { | 423 | static struct i2c_driver ltc4245_driver = { |
| 542 | .class = I2C_CLASS_HWMON, | ||
| 543 | .driver = { | 424 | .driver = { |
| 544 | .name = "ltc4245", | 425 | .name = "ltc4245", |
| 545 | }, | 426 | }, |
| 546 | .probe = ltc4245_probe, | 427 | .probe = ltc4245_probe, |
| 547 | .remove = ltc4245_remove, | 428 | .remove = ltc4245_remove, |
| 548 | .id_table = ltc4245_id, | 429 | .id_table = ltc4245_id, |
| 549 | .detect = ltc4245_detect, | ||
| 550 | .address_data = &addr_data, | ||
| 551 | }; | 430 | }; |
| 552 | 431 | ||
| 553 | static int __init ltc4245_init(void) | 432 | static int __init ltc4245_init(void) |
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index f7d6fe9c49ba..8f0b90ef8c76 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c | |||
| @@ -364,7 +364,7 @@ static int __devinit amd756_probe(struct pci_dev *pdev, | |||
| 364 | error = acpi_check_region(amd756_ioport, SMB_IOSIZE, | 364 | error = acpi_check_region(amd756_ioport, SMB_IOSIZE, |
| 365 | amd756_driver.name); | 365 | amd756_driver.name); |
| 366 | if (error) | 366 | if (error) |
| 367 | return error; | 367 | return -ENODEV; |
| 368 | 368 | ||
| 369 | if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) { | 369 | if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) { |
| 370 | dev_err(&pdev->dev, "SMB region 0x%x already in use!\n", | 370 | dev_err(&pdev->dev, "SMB region 0x%x already in use!\n", |
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index a7c59908c457..5b4ad86ca166 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c | |||
| @@ -376,8 +376,10 @@ static int __devinit amd8111_probe(struct pci_dev *dev, | |||
| 376 | smbus->size = pci_resource_len(dev, 0); | 376 | smbus->size = pci_resource_len(dev, 0); |
| 377 | 377 | ||
| 378 | error = acpi_check_resource_conflict(&dev->resource[0]); | 378 | error = acpi_check_resource_conflict(&dev->resource[0]); |
| 379 | if (error) | 379 | if (error) { |
| 380 | error = -ENODEV; | ||
| 380 | goto out_kfree; | 381 | goto out_kfree; |
| 382 | } | ||
| 381 | 383 | ||
| 382 | if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) { | 384 | if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) { |
| 383 | error = -EBUSY; | 385 | error = -EBUSY; |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 9d2c5adf5d4f..55edcfe5b851 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
| @@ -732,8 +732,10 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id | |||
| 732 | } | 732 | } |
| 733 | 733 | ||
| 734 | err = acpi_check_resource_conflict(&dev->resource[SMBBAR]); | 734 | err = acpi_check_resource_conflict(&dev->resource[SMBBAR]); |
| 735 | if (err) | 735 | if (err) { |
| 736 | err = -ENODEV; | ||
| 736 | goto exit; | 737 | goto exit; |
| 738 | } | ||
| 737 | 739 | ||
| 738 | err = pci_request_region(dev, SMBBAR, i801_driver.name); | 740 | err = pci_request_region(dev, SMBBAR, i801_driver.name); |
| 739 | if (err) { | 741 | if (err) { |
diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c index 9f6b8e0f8632..dba6eb053e2f 100644 --- a/drivers/i2c/busses/i2c-isch.c +++ b/drivers/i2c/busses/i2c-isch.c | |||
| @@ -281,7 +281,7 @@ static int __devinit sch_probe(struct pci_dev *dev, | |||
| 281 | return -ENODEV; | 281 | return -ENODEV; |
| 282 | } | 282 | } |
| 283 | if (acpi_check_region(sch_smba, SMBIOSIZE, sch_driver.name)) | 283 | if (acpi_check_region(sch_smba, SMBIOSIZE, sch_driver.name)) |
| 284 | return -EBUSY; | 284 | return -ENODEV; |
| 285 | if (!request_region(sch_smba, SMBIOSIZE, sch_driver.name)) { | 285 | if (!request_region(sch_smba, SMBIOSIZE, sch_driver.name)) { |
| 286 | dev_err(&dev->dev, "SMBus region 0x%x already in use!\n", | 286 | dev_err(&dev->dev, "SMBus region 0x%x already in use!\n", |
| 287 | sch_smba); | 287 | sch_smba); |
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index a782c7a08f9e..d26a972aacaa 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c | |||
| @@ -169,7 +169,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, | |||
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) | 171 | if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) |
| 172 | return -EBUSY; | 172 | return -ENODEV; |
| 173 | 173 | ||
| 174 | if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { | 174 | if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { |
| 175 | dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n", | 175 | 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, | |||
| 260 | 260 | ||
| 261 | piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0; | 261 | piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0; |
| 262 | if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) | 262 | if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) |
| 263 | return -EBUSY; | 263 | return -ENODEV; |
| 264 | 264 | ||
| 265 | if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { | 265 | if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { |
| 266 | dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n", | 266 | dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n", |
diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c index 8295885b2fdb..1649963b00dc 100644 --- a/drivers/i2c/busses/i2c-sis96x.c +++ b/drivers/i2c/busses/i2c-sis96x.c | |||
| @@ -280,7 +280,7 @@ static int __devinit sis96x_probe(struct pci_dev *dev, | |||
| 280 | 280 | ||
| 281 | retval = acpi_check_resource_conflict(&dev->resource[SIS96x_BAR]); | 281 | retval = acpi_check_resource_conflict(&dev->resource[SIS96x_BAR]); |
| 282 | if (retval) | 282 | if (retval) |
| 283 | return retval; | 283 | return -ENODEV; |
| 284 | 284 | ||
| 285 | /* Everything is happy, let's grab the memory and set things up. */ | 285 | /* Everything is happy, let's grab the memory and set things up. */ |
| 286 | if (!request_region(sis96x_smbus_base, SMB_IOSIZE, | 286 | if (!request_region(sis96x_smbus_base, SMB_IOSIZE, |
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 54d810a4d00f..e4b1543015af 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c | |||
| @@ -365,7 +365,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev, | |||
| 365 | found: | 365 | found: |
| 366 | error = acpi_check_region(vt596_smba, 8, vt596_driver.name); | 366 | error = acpi_check_region(vt596_smba, 8, vt596_driver.name); |
| 367 | if (error) | 367 | if (error) |
| 368 | return error; | 368 | return -ENODEV; |
| 369 | 369 | ||
| 370 | if (!request_region(vt596_smba, 8, vt596_driver.name)) { | 370 | if (!request_region(vt596_smba, 8, vt596_driver.name)) { |
| 371 | dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n", | 371 | dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n", |
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index 51bd9669cb1f..f504c9b00c1b 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include <linux/device.h> | 38 | #include <linux/device.h> |
| 39 | #include <linux/err.h> | 39 | #include <linux/err.h> |
| 40 | #include <linux/poll.h> | 40 | #include <linux/poll.h> |
| 41 | #include <linux/sched.h> | ||
| 41 | #include <linux/file.h> | 42 | #include <linux/file.h> |
| 42 | #include <linux/mount.h> | 43 | #include <linux/mount.h> |
| 43 | #include <linux/cdev.h> | 44 | #include <linux/cdev.h> |
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 8c46f2257098..7de02969ed7d 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | #include <linux/mutex.h> | 44 | #include <linux/mutex.h> |
| 45 | #include <linux/kref.h> | 45 | #include <linux/kref.h> |
| 46 | #include <linux/compat.h> | 46 | #include <linux/compat.h> |
| 47 | #include <linux/sched.h> | ||
| 47 | #include <linux/semaphore.h> | 48 | #include <linux/semaphore.h> |
| 48 | 49 | ||
| 49 | #include <asm/uaccess.h> | 50 | #include <asm/uaccess.h> |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index d3fff9e008a3..aec0fbdfe7f0 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #include <linux/err.h> | 40 | #include <linux/err.h> |
| 41 | #include <linux/fs.h> | 41 | #include <linux/fs.h> |
| 42 | #include <linux/poll.h> | 42 | #include <linux/poll.h> |
| 43 | #include <linux/sched.h> | ||
| 43 | #include <linux/file.h> | 44 | #include <linux/file.h> |
| 44 | #include <linux/mount.h> | 45 | #include <linux/mount.h> |
| 45 | #include <linux/cdev.h> | 46 | #include <linux/cdev.h> |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 1148140d08a1..dee6706038aa 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #define EVDEV_BUFFER_SIZE 64 | 13 | #define EVDEV_BUFFER_SIZE 64 |
| 14 | 14 | ||
| 15 | #include <linux/poll.h> | 15 | #include <linux/poll.h> |
| 16 | #include <linux/sched.h> | ||
| 16 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
| 17 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 18 | #include <linux/init.h> | 19 | #include <linux/init.h> |
diff --git a/drivers/input/input.c b/drivers/input/input.c index 16ec33f27c5d..c6f88ebb40c7 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/random.h> | 17 | #include <linux/random.h> |
| 18 | #include <linux/major.h> | 18 | #include <linux/major.h> |
| 19 | #include <linux/proc_fs.h> | 19 | #include <linux/proc_fs.h> |
| 20 | #include <linux/sched.h> | ||
| 20 | #include <linux/seq_file.h> | 21 | #include <linux/seq_file.h> |
| 21 | #include <linux/poll.h> | 22 | #include <linux/poll.h> |
| 22 | #include <linux/device.h> | 23 | #include <linux/device.h> |
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 901b2525993e..b1bd6dd32286 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/input.h> | 18 | #include <linux/input.h> |
| 19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
| 20 | #include <linux/major.h> | 20 | #include <linux/major.h> |
| 21 | #include <linux/sched.h> | ||
| 21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 22 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
| 23 | #include <linux/miscdevice.h> | 24 | #include <linux/miscdevice.h> |
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index c5a49aba418f..d3f57245420a 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | * - first public version | 30 | * - first public version |
| 31 | */ | 31 | */ |
| 32 | #include <linux/poll.h> | 32 | #include <linux/poll.h> |
| 33 | #include <linux/sched.h> | ||
| 33 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
| 34 | #include <linux/module.h> | 35 | #include <linux/module.h> |
| 35 | #include <linux/init.h> | 36 | #include <linux/init.h> |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 966b8868f792..a13d80f7da17 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #define MOUSEDEV_MINORS 32 | 13 | #define MOUSEDEV_MINORS 32 |
| 14 | #define MOUSEDEV_MIX 31 | 14 | #define MOUSEDEV_MIX 31 |
| 15 | 15 | ||
| 16 | #include <linux/sched.h> | ||
| 16 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
| 17 | #include <linux/smp_lock.h> | 18 | #include <linux/smp_lock.h> |
| 18 | #include <linux/poll.h> | 19 | #include <linux/poll.h> |
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c index 8b256a617c8a..3697c409bec6 100644 --- a/drivers/isdn/divert/divert_procfs.c +++ b/drivers/isdn/divert/divert_procfs.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #else | 16 | #else |
| 17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
| 18 | #endif | 18 | #endif |
| 19 | #include <linux/sched.h> | ||
| 19 | #include <linux/isdnif.h> | 20 | #include <linux/isdnif.h> |
| 20 | #include <net/net_namespace.h> | 21 | #include <net/net_namespace.h> |
| 21 | #include "isdn_divert.h" | 22 | #include "isdn_divert.h" |
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c index 708a8017c21d..adc561eb59d2 100644 --- a/drivers/leds/leds-pca9532.c +++ b/drivers/leds/leds-pca9532.c | |||
| @@ -19,9 +19,6 @@ | |||
| 19 | #include <linux/workqueue.h> | 19 | #include <linux/workqueue.h> |
| 20 | #include <linux/leds-pca9532.h> | 20 | #include <linux/leds-pca9532.h> |
| 21 | 21 | ||
| 22 | static const unsigned short normal_i2c[] = { /*0x60,*/ I2C_CLIENT_END}; | ||
| 23 | I2C_CLIENT_INSMOD_1(pca9532); | ||
| 24 | |||
| 25 | #define PCA9532_REG_PSC(i) (0x2+(i)*2) | 22 | #define PCA9532_REG_PSC(i) (0x2+(i)*2) |
| 26 | #define PCA9532_REG_PWM(i) (0x3+(i)*2) | 23 | #define PCA9532_REG_PWM(i) (0x3+(i)*2) |
| 27 | #define PCA9532_REG_LS0 0x6 | 24 | #define PCA9532_REG_LS0 0x6 |
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index fde377c60cca..556f0feaa4df 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c | |||
| @@ -124,6 +124,8 @@ read_reg(struct thermostat* th, int reg) | |||
| 124 | return data; | 124 | return data; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | static struct i2c_driver thermostat_driver; | ||
| 128 | |||
| 127 | static int | 129 | static int |
| 128 | attach_thermostat(struct i2c_adapter *adapter) | 130 | attach_thermostat(struct i2c_adapter *adapter) |
| 129 | { | 131 | { |
| @@ -148,7 +150,7 @@ attach_thermostat(struct i2c_adapter *adapter) | |||
| 148 | * Let i2c-core delete that device on driver removal. | 150 | * Let i2c-core delete that device on driver removal. |
| 149 | * This is safe because i2c-core holds the core_lock mutex for us. | 151 | * This is safe because i2c-core holds the core_lock mutex for us. |
| 150 | */ | 152 | */ |
| 151 | list_add_tail(&client->detected, &client->driver->clients); | 153 | list_add_tail(&client->detected, &thermostat_driver.clients); |
| 152 | return 0; | 154 | return 0; |
| 153 | } | 155 | } |
| 154 | 156 | ||
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index a028598af2d3..ea32c7e5a9af 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c | |||
| @@ -286,6 +286,8 @@ struct fcu_fan_table fcu_fans[] = { | |||
| 286 | }, | 286 | }, |
| 287 | }; | 287 | }; |
| 288 | 288 | ||
| 289 | static struct i2c_driver therm_pm72_driver; | ||
| 290 | |||
| 289 | /* | 291 | /* |
| 290 | * Utility function to create an i2c_client structure and | 292 | * Utility function to create an i2c_client structure and |
| 291 | * attach it to one of u3 adapters | 293 | * attach it to one of u3 adapters |
| @@ -318,7 +320,7 @@ static struct i2c_client *attach_i2c_chip(int id, const char *name) | |||
| 318 | * Let i2c-core delete that device on driver removal. | 320 | * Let i2c-core delete that device on driver removal. |
| 319 | * This is safe because i2c-core holds the core_lock mutex for us. | 321 | * This is safe because i2c-core holds the core_lock mutex for us. |
| 320 | */ | 322 | */ |
| 321 | list_add_tail(&clt->detected, &clt->driver->clients); | 323 | list_add_tail(&clt->detected, &therm_pm72_driver.clients); |
| 322 | return clt; | 324 | return clt; |
| 323 | } | 325 | } |
| 324 | 326 | ||
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c index 529886c7a826..ed6426a10773 100644 --- a/drivers/macintosh/windfarm_lm75_sensor.c +++ b/drivers/macintosh/windfarm_lm75_sensor.c | |||
| @@ -115,6 +115,8 @@ static int wf_lm75_probe(struct i2c_client *client, | |||
| 115 | return rc; | 115 | return rc; |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | static struct i2c_driver wf_lm75_driver; | ||
| 119 | |||
| 118 | static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter, | 120 | static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter, |
| 119 | u8 addr, int ds1775, | 121 | u8 addr, int ds1775, |
| 120 | const char *loc) | 122 | const char *loc) |
| @@ -157,7 +159,7 @@ static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter, | |||
| 157 | * Let i2c-core delete that device on driver removal. | 159 | * Let i2c-core delete that device on driver removal. |
| 158 | * This is safe because i2c-core holds the core_lock mutex for us. | 160 | * This is safe because i2c-core holds the core_lock mutex for us. |
| 159 | */ | 161 | */ |
| 160 | list_add_tail(&client->detected, &client->driver->clients); | 162 | list_add_tail(&client->detected, &wf_lm75_driver.clients); |
| 161 | return client; | 163 | return client; |
| 162 | fail: | 164 | fail: |
| 163 | return NULL; | 165 | return NULL; |
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c index e2a55ecda2b2..a67b349319e9 100644 --- a/drivers/macintosh/windfarm_max6690_sensor.c +++ b/drivers/macintosh/windfarm_max6690_sensor.c | |||
| @@ -88,6 +88,8 @@ static int wf_max6690_probe(struct i2c_client *client, | |||
| 88 | return rc; | 88 | return rc; |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | static struct i2c_driver wf_max6690_driver; | ||
| 92 | |||
| 91 | static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter, | 93 | static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter, |
| 92 | u8 addr, const char *loc) | 94 | u8 addr, const char *loc) |
| 93 | { | 95 | { |
| @@ -119,7 +121,7 @@ static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter, | |||
| 119 | * Let i2c-core delete that device on driver removal. | 121 | * Let i2c-core delete that device on driver removal. |
| 120 | * This is safe because i2c-core holds the core_lock mutex for us. | 122 | * This is safe because i2c-core holds the core_lock mutex for us. |
| 121 | */ | 123 | */ |
| 122 | list_add_tail(&client->detected, &client->driver->clients); | 124 | list_add_tail(&client->detected, &wf_max6690_driver.clients); |
| 123 | return client; | 125 | return client; |
| 124 | 126 | ||
| 125 | fail: | 127 | fail: |
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c index 5da729e58f99..e20330a28959 100644 --- a/drivers/macintosh/windfarm_smu_sat.c +++ b/drivers/macintosh/windfarm_smu_sat.c | |||
| @@ -194,6 +194,8 @@ static struct wf_sensor_ops wf_sat_ops = { | |||
| 194 | .owner = THIS_MODULE, | 194 | .owner = THIS_MODULE, |
| 195 | }; | 195 | }; |
| 196 | 196 | ||
| 197 | static struct i2c_driver wf_sat_driver; | ||
| 198 | |||
| 197 | static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) | 199 | static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) |
| 198 | { | 200 | { |
| 199 | struct i2c_board_info info; | 201 | struct i2c_board_info info; |
| @@ -222,7 +224,7 @@ static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) | |||
| 222 | * Let i2c-core delete that device on driver removal. | 224 | * Let i2c-core delete that device on driver removal. |
| 223 | * This is safe because i2c-core holds the core_lock mutex for us. | 225 | * This is safe because i2c-core holds the core_lock mutex for us. |
| 224 | */ | 226 | */ |
| 225 | list_add_tail(&client->detected, &client->driver->clients); | 227 | list_add_tail(&client->detected, &wf_sat_driver.clients); |
| 226 | } | 228 | } |
| 227 | 229 | ||
| 228 | static int wf_sat_probe(struct i2c_client *client, | 230 | static int wf_sat_probe(struct i2c_client *client, |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 376f1ab48a24..23e76fe0d359 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
| @@ -130,7 +130,7 @@ struct mapped_device { | |||
| 130 | /* | 130 | /* |
| 131 | * A list of ios that arrived while we were suspended. | 131 | * A list of ios that arrived while we were suspended. |
| 132 | */ | 132 | */ |
| 133 | atomic_t pending[2]; | 133 | atomic_t pending; |
| 134 | wait_queue_head_t wait; | 134 | wait_queue_head_t wait; |
| 135 | struct work_struct work; | 135 | struct work_struct work; |
| 136 | struct bio_list deferred; | 136 | struct bio_list deferred; |
| @@ -453,14 +453,13 @@ static void start_io_acct(struct dm_io *io) | |||
| 453 | { | 453 | { |
| 454 | struct mapped_device *md = io->md; | 454 | struct mapped_device *md = io->md; |
| 455 | int cpu; | 455 | int cpu; |
| 456 | int rw = bio_data_dir(io->bio); | ||
| 457 | 456 | ||
| 458 | io->start_time = jiffies; | 457 | io->start_time = jiffies; |
| 459 | 458 | ||
| 460 | cpu = part_stat_lock(); | 459 | cpu = part_stat_lock(); |
| 461 | part_round_stats(cpu, &dm_disk(md)->part0); | 460 | part_round_stats(cpu, &dm_disk(md)->part0); |
| 462 | part_stat_unlock(); | 461 | part_stat_unlock(); |
| 463 | dm_disk(md)->part0.in_flight[rw] = atomic_inc_return(&md->pending[rw]); | 462 | dm_disk(md)->part0.in_flight = atomic_inc_return(&md->pending); |
| 464 | } | 463 | } |
| 465 | 464 | ||
| 466 | static void end_io_acct(struct dm_io *io) | 465 | static void end_io_acct(struct dm_io *io) |
| @@ -480,9 +479,8 @@ static void end_io_acct(struct dm_io *io) | |||
| 480 | * After this is decremented the bio must not be touched if it is | 479 | * After this is decremented the bio must not be touched if it is |
| 481 | * a barrier. | 480 | * a barrier. |
| 482 | */ | 481 | */ |
| 483 | dm_disk(md)->part0.in_flight[rw] = pending = | 482 | dm_disk(md)->part0.in_flight = pending = |
| 484 | atomic_dec_return(&md->pending[rw]); | 483 | atomic_dec_return(&md->pending); |
| 485 | pending += atomic_read(&md->pending[rw^0x1]); | ||
| 486 | 484 | ||
| 487 | /* nudge anyone waiting on suspend queue */ | 485 | /* nudge anyone waiting on suspend queue */ |
| 488 | if (!pending) | 486 | if (!pending) |
| @@ -1787,8 +1785,7 @@ static struct mapped_device *alloc_dev(int minor) | |||
| 1787 | if (!md->disk) | 1785 | if (!md->disk) |
| 1788 | goto bad_disk; | 1786 | goto bad_disk; |
| 1789 | 1787 | ||
| 1790 | atomic_set(&md->pending[0], 0); | 1788 | atomic_set(&md->pending, 0); |
| 1791 | atomic_set(&md->pending[1], 0); | ||
| 1792 | init_waitqueue_head(&md->wait); | 1789 | init_waitqueue_head(&md->wait); |
| 1793 | INIT_WORK(&md->work, dm_wq_work); | 1790 | INIT_WORK(&md->work, dm_wq_work); |
| 1794 | init_waitqueue_head(&md->eventq); | 1791 | init_waitqueue_head(&md->eventq); |
| @@ -2091,8 +2088,7 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible) | |||
| 2091 | break; | 2088 | break; |
| 2092 | } | 2089 | } |
| 2093 | spin_unlock_irqrestore(q->queue_lock, flags); | 2090 | spin_unlock_irqrestore(q->queue_lock, flags); |
| 2094 | } else if (!atomic_read(&md->pending[0]) && | 2091 | } else if (!atomic_read(&md->pending)) |
| 2095 | !atomic_read(&md->pending[1])) | ||
| 2096 | break; | 2092 | break; |
| 2097 | 2093 | ||
| 2098 | if (interruptible == TASK_INTERRUPTIBLE && | 2094 | if (interruptible == TASK_INTERRUPTIBLE && |
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index 516414983593..c37790ad92d0 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | * | 20 | * |
| 21 | */ | 21 | */ |
| 22 | 22 | ||
| 23 | #include <linux/sched.h> | ||
| 23 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
| 24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| 25 | #include <linux/vmalloc.h> | 26 | #include <linux/vmalloc.h> |
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index eef6d3616626..91c537bca8ad 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | * | 21 | * |
| 22 | */ | 22 | */ |
| 23 | 23 | ||
| 24 | #include <linux/sched.h> | ||
| 24 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
| 25 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 26 | #include <linux/vmalloc.h> | 27 | #include <linux/vmalloc.h> |
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index 8b1440136c45..482d0f3be5ff 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include <linux/videodev2.h> /* V4L2 API defs */ | 38 | #include <linux/videodev2.h> /* V4L2 API defs */ |
| 39 | #include <linux/param.h> | 39 | #include <linux/param.h> |
| 40 | #include <linux/pnp.h> | 40 | #include <linux/pnp.h> |
| 41 | #include <linux/sched.h> | ||
| 41 | #include <linux/io.h> /* outb, outb_p */ | 42 | #include <linux/io.h> /* outb, outb_p */ |
| 42 | #include <media/v4l2-device.h> | 43 | #include <media/v4l2-device.h> |
| 43 | #include <media/v4l2-ioctl.h> | 44 | #include <media/v4l2-ioctl.h> |
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index 43ab0adf3b61..2377313c041a 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
| 32 | #include <linux/fs.h> | 32 | #include <linux/fs.h> |
| 33 | #include <linux/vmalloc.h> | 33 | #include <linux/vmalloc.h> |
| 34 | #include <linux/sched.h> | ||
| 34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| 35 | #include <linux/proc_fs.h> | 36 | #include <linux/proc_fs.h> |
| 36 | #include <linux/ctype.h> | 37 | #include <linux/ctype.h> |
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index 5447da16a170..613481028272 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c | |||
| @@ -57,8 +57,6 @@ | |||
| 57 | * The AB3100 is usually assigned address 0x48 (7-bit) | 57 | * The AB3100 is usually assigned address 0x48 (7-bit) |
| 58 | * The chip is defined in the platform i2c_board_data section. | 58 | * The chip is defined in the platform i2c_board_data section. |
| 59 | */ | 59 | */ |
| 60 | static unsigned short normal_i2c[] = { 0x48, I2C_CLIENT_END }; | ||
| 61 | I2C_CLIENT_INSMOD_1(ab3100); | ||
| 62 | 60 | ||
| 63 | u8 ab3100_get_chip_type(struct ab3100 *ab3100) | 61 | u8 ab3100_get_chip_type(struct ab3100 *ab3100) |
| 64 | { | 62 | { |
| @@ -966,7 +964,7 @@ static int __exit ab3100_remove(struct i2c_client *client) | |||
| 966 | } | 964 | } |
| 967 | 965 | ||
| 968 | static const struct i2c_device_id ab3100_id[] = { | 966 | static const struct i2c_device_id ab3100_id[] = { |
| 969 | { "ab3100", ab3100 }, | 967 | { "ab3100", 0 }, |
| 970 | { } | 968 | { } |
| 971 | }; | 969 | }; |
| 972 | MODULE_DEVICE_TABLE(i2c, ab3100_id); | 970 | MODULE_DEVICE_TABLE(i2c, ab3100_id); |
diff --git a/drivers/mfd/ucb1400_core.c b/drivers/mfd/ucb1400_core.c index 2afc08006e6d..fa294b6d600a 100644 --- a/drivers/mfd/ucb1400_core.c +++ b/drivers/mfd/ucb1400_core.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | */ | 21 | */ |
| 22 | 22 | ||
| 23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
| 24 | #include <linux/sched.h> | ||
| 24 | #include <linux/ucb1400.h> | 25 | #include <linux/ucb1400.h> |
| 25 | 26 | ||
| 26 | unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel, | 27 | unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel, |
diff --git a/drivers/misc/eeprom/max6875.c b/drivers/misc/eeprom/max6875.c index 3c0c58eed347..5a6b2bce8ad5 100644 --- a/drivers/misc/eeprom/max6875.c +++ b/drivers/misc/eeprom/max6875.c | |||
| @@ -33,12 +33,6 @@ | |||
| 33 | #include <linux/i2c.h> | 33 | #include <linux/i2c.h> |
| 34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
| 35 | 35 | ||
| 36 | /* Do not scan - the MAX6875 access method will write to some EEPROM chips */ | ||
| 37 | static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; | ||
| 38 | |||
| 39 | /* Insmod parameters */ | ||
| 40 | I2C_CLIENT_INSMOD_1(max6875); | ||
| 41 | |||
| 42 | /* The MAX6875 can only read/write 16 bytes at a time */ | 36 | /* The MAX6875 can only read/write 16 bytes at a time */ |
| 43 | #define SLICE_SIZE 16 | 37 | #define SLICE_SIZE 16 |
| 44 | #define SLICE_BITS 4 | 38 | #define SLICE_BITS 4 |
| @@ -146,31 +140,21 @@ static struct bin_attribute user_eeprom_attr = { | |||
| 146 | .read = max6875_read, | 140 | .read = max6875_read, |
| 147 | }; | 141 | }; |
| 148 | 142 | ||
| 149 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 143 | static int max6875_probe(struct i2c_client *client, |
| 150 | static int max6875_detect(struct i2c_client *client, int kind, | 144 | const struct i2c_device_id *id) |
| 151 | struct i2c_board_info *info) | ||
| 152 | { | 145 | { |
| 153 | struct i2c_adapter *adapter = client->adapter; | 146 | struct i2c_adapter *adapter = client->adapter; |
| 147 | struct max6875_data *data; | ||
| 148 | int err; | ||
| 154 | 149 | ||
| 155 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA | 150 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
| 156 | | I2C_FUNC_SMBUS_READ_BYTE)) | 151 | | I2C_FUNC_SMBUS_READ_BYTE)) |
| 157 | return -ENODEV; | 152 | return -ENODEV; |
| 158 | 153 | ||
| 159 | /* Only check even addresses */ | 154 | /* Only bind to even addresses */ |
| 160 | if (client->addr & 1) | 155 | if (client->addr & 1) |
| 161 | return -ENODEV; | 156 | return -ENODEV; |
| 162 | 157 | ||
| 163 | strlcpy(info->type, "max6875", I2C_NAME_SIZE); | ||
| 164 | |||
| 165 | return 0; | ||
| 166 | } | ||
| 167 | |||
| 168 | static int max6875_probe(struct i2c_client *client, | ||
| 169 | const struct i2c_device_id *id) | ||
| 170 | { | ||
| 171 | struct max6875_data *data; | ||
| 172 | int err; | ||
| 173 | |||
| 174 | if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL))) | 158 | if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL))) |
| 175 | return -ENOMEM; | 159 | return -ENOMEM; |
| 176 | 160 | ||
| @@ -222,9 +206,6 @@ static struct i2c_driver max6875_driver = { | |||
| 222 | .probe = max6875_probe, | 206 | .probe = max6875_probe, |
| 223 | .remove = max6875_remove, | 207 | .remove = max6875_remove, |
| 224 | .id_table = max6875_id, | 208 | .id_table = max6875_id, |
| 225 | |||
| 226 | .detect = max6875_detect, | ||
| 227 | .address_data = &addr_data, | ||
| 228 | }; | 209 | }; |
| 229 | 210 | ||
| 230 | static int __init max6875_init(void) | 211 | static int __init max6875_init(void) |
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 0acbf4f5be50..8ca17a3e96ea 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c | |||
| @@ -32,14 +32,6 @@ struct mtd_blkcore_priv { | |||
| 32 | spinlock_t queue_lock; | 32 | spinlock_t queue_lock; |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | static int blktrans_discard_request(struct request_queue *q, | ||
| 36 | struct request *req) | ||
| 37 | { | ||
| 38 | req->cmd_type = REQ_TYPE_LINUX_BLOCK; | ||
| 39 | req->cmd[0] = REQ_LB_OP_DISCARD; | ||
| 40 | return 0; | ||
| 41 | } | ||
| 42 | |||
| 43 | static int do_blktrans_request(struct mtd_blktrans_ops *tr, | 35 | static int do_blktrans_request(struct mtd_blktrans_ops *tr, |
| 44 | struct mtd_blktrans_dev *dev, | 36 | struct mtd_blktrans_dev *dev, |
| 45 | struct request *req) | 37 | struct request *req) |
| @@ -52,10 +44,6 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr, | |||
| 52 | 44 | ||
| 53 | buf = req->buffer; | 45 | buf = req->buffer; |
| 54 | 46 | ||
| 55 | if (req->cmd_type == REQ_TYPE_LINUX_BLOCK && | ||
| 56 | req->cmd[0] == REQ_LB_OP_DISCARD) | ||
| 57 | return tr->discard(dev, block, nsect); | ||
| 58 | |||
| 59 | if (!blk_fs_request(req)) | 47 | if (!blk_fs_request(req)) |
| 60 | return -EIO; | 48 | return -EIO; |
| 61 | 49 | ||
| @@ -63,6 +51,9 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr, | |||
| 63 | get_capacity(req->rq_disk)) | 51 | get_capacity(req->rq_disk)) |
| 64 | return -EIO; | 52 | return -EIO; |
| 65 | 53 | ||
| 54 | if (blk_discard_rq(req)) | ||
| 55 | return tr->discard(dev, block, nsect); | ||
| 56 | |||
| 66 | switch(rq_data_dir(req)) { | 57 | switch(rq_data_dir(req)) { |
| 67 | case READ: | 58 | case READ: |
| 68 | for (; nsect > 0; nsect--, block++, buf += tr->blksize) | 59 | for (; nsect > 0; nsect--, block++, buf += tr->blksize) |
| @@ -380,8 +371,8 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) | |||
| 380 | tr->blkcore_priv->rq->queuedata = tr; | 371 | tr->blkcore_priv->rq->queuedata = tr; |
| 381 | blk_queue_logical_block_size(tr->blkcore_priv->rq, tr->blksize); | 372 | blk_queue_logical_block_size(tr->blkcore_priv->rq, tr->blksize); |
| 382 | if (tr->discard) | 373 | if (tr->discard) |
| 383 | blk_queue_set_discard(tr->blkcore_priv->rq, | 374 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, |
| 384 | blktrans_discard_request); | 375 | tr->blkcore_priv->rq); |
| 385 | 376 | ||
| 386 | tr->blkshift = ffs(tr->blksize) - 1; | 377 | tr->blkshift = ffs(tr->blksize) - 1; |
| 387 | 378 | ||
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index afdbdaaf80cb..a2a742c8ff7e 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
| @@ -1211,15 +1211,6 @@ static int sony_nc_add(struct acpi_device *device) | |||
| 1211 | } | 1211 | } |
| 1212 | } | 1212 | } |
| 1213 | 1213 | ||
| 1214 | /* try to _INI the device if such method exists (ACPI spec 3.0-6.5.1 | ||
| 1215 | * should be respected as we already checked for the device presence above */ | ||
| 1216 | if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, METHOD_NAME__INI, &handle))) { | ||
| 1217 | dprintk("Invoking _INI\n"); | ||
| 1218 | if (ACPI_FAILURE(acpi_evaluate_object(sony_nc_acpi_handle, METHOD_NAME__INI, | ||
| 1219 | NULL, NULL))) | ||
| 1220 | dprintk("_INI Method failed\n"); | ||
| 1221 | } | ||
| 1222 | |||
| 1223 | if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON", | 1214 | if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON", |
| 1224 | &handle))) { | 1215 | &handle))) { |
| 1225 | if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL)) | 1216 | if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL)) |
| @@ -1399,27 +1390,20 @@ struct sonypi_eventtypes { | |||
| 1399 | struct sonypi_event *events; | 1390 | struct sonypi_event *events; |
| 1400 | }; | 1391 | }; |
| 1401 | 1392 | ||
| 1402 | struct device_ctrl { | 1393 | struct sony_pic_dev { |
| 1394 | struct acpi_device *acpi_dev; | ||
| 1395 | struct sony_pic_irq *cur_irq; | ||
| 1396 | struct sony_pic_ioport *cur_ioport; | ||
| 1397 | struct list_head interrupts; | ||
| 1398 | struct list_head ioports; | ||
| 1399 | struct mutex lock; | ||
| 1400 | struct sonypi_eventtypes *event_types; | ||
| 1401 | int (*handle_irq)(const u8, const u8); | ||
| 1403 | int model; | 1402 | int model; |
| 1404 | int (*handle_irq)(const u8, const u8); | ||
| 1405 | u16 evport_offset; | 1403 | u16 evport_offset; |
| 1406 | u8 has_camera; | 1404 | u8 camera_power; |
| 1407 | u8 has_bluetooth; | 1405 | u8 bluetooth_power; |
| 1408 | u8 has_wwan; | 1406 | u8 wwan_power; |
| 1409 | struct sonypi_eventtypes *event_types; | ||
| 1410 | }; | ||
| 1411 | |||
| 1412 | struct sony_pic_dev { | ||
| 1413 | struct device_ctrl *control; | ||
| 1414 | struct acpi_device *acpi_dev; | ||
| 1415 | struct sony_pic_irq *cur_irq; | ||
| 1416 | struct sony_pic_ioport *cur_ioport; | ||
| 1417 | struct list_head interrupts; | ||
| 1418 | struct list_head ioports; | ||
| 1419 | struct mutex lock; | ||
| 1420 | u8 camera_power; | ||
| 1421 | u8 bluetooth_power; | ||
| 1422 | u8 wwan_power; | ||
| 1423 | }; | 1407 | }; |
| 1424 | 1408 | ||
| 1425 | static struct sony_pic_dev spic_dev = { | 1409 | static struct sony_pic_dev spic_dev = { |
| @@ -1427,6 +1411,8 @@ static struct sony_pic_dev spic_dev = { | |||
| 1427 | .ioports = LIST_HEAD_INIT(spic_dev.ioports), | 1411 | .ioports = LIST_HEAD_INIT(spic_dev.ioports), |
| 1428 | }; | 1412 | }; |
| 1429 | 1413 | ||
| 1414 | static int spic_drv_registered; | ||
| 1415 | |||
| 1430 | /* Event masks */ | 1416 | /* Event masks */ |
| 1431 | #define SONYPI_JOGGER_MASK 0x00000001 | 1417 | #define SONYPI_JOGGER_MASK 0x00000001 |
| 1432 | #define SONYPI_CAPTURE_MASK 0x00000002 | 1418 | #define SONYPI_CAPTURE_MASK 0x00000002 |
| @@ -1724,27 +1710,6 @@ static int type3_handle_irq(const u8 data_mask, const u8 ev) | |||
| 1724 | return 1; | 1710 | return 1; |
| 1725 | } | 1711 | } |
| 1726 | 1712 | ||
| 1727 | static struct device_ctrl spic_types[] = { | ||
| 1728 | { | ||
| 1729 | .model = SONYPI_DEVICE_TYPE1, | ||
| 1730 | .handle_irq = NULL, | ||
| 1731 | .evport_offset = SONYPI_TYPE1_OFFSET, | ||
| 1732 | .event_types = type1_events, | ||
| 1733 | }, | ||
| 1734 | { | ||
| 1735 | .model = SONYPI_DEVICE_TYPE2, | ||
| 1736 | .handle_irq = NULL, | ||
| 1737 | .evport_offset = SONYPI_TYPE2_OFFSET, | ||
| 1738 | .event_types = type2_events, | ||
| 1739 | }, | ||
| 1740 | { | ||
| 1741 | .model = SONYPI_DEVICE_TYPE3, | ||
| 1742 | .handle_irq = type3_handle_irq, | ||
| 1743 | .evport_offset = SONYPI_TYPE3_OFFSET, | ||
| 1744 | .event_types = type3_events, | ||
| 1745 | }, | ||
| 1746 | }; | ||
| 1747 | |||
| 1748 | static void sony_pic_detect_device_type(struct sony_pic_dev *dev) | 1713 | static void sony_pic_detect_device_type(struct sony_pic_dev *dev) |
| 1749 | { | 1714 | { |
| 1750 | struct pci_dev *pcidev; | 1715 | struct pci_dev *pcidev; |
| @@ -1752,48 +1717,63 @@ static void sony_pic_detect_device_type(struct sony_pic_dev *dev) | |||
| 1752 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1717 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, |
| 1753 | PCI_DEVICE_ID_INTEL_82371AB_3, NULL); | 1718 | PCI_DEVICE_ID_INTEL_82371AB_3, NULL); |
| 1754 | if (pcidev) { | 1719 | if (pcidev) { |
| 1755 | dev->control = &spic_types[0]; | 1720 | dev->model = SONYPI_DEVICE_TYPE1; |
| 1721 | dev->evport_offset = SONYPI_TYPE1_OFFSET; | ||
| 1722 | dev->event_types = type1_events; | ||
| 1756 | goto out; | 1723 | goto out; |
| 1757 | } | 1724 | } |
| 1758 | 1725 | ||
| 1759 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1726 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, |
| 1760 | PCI_DEVICE_ID_INTEL_ICH6_1, NULL); | 1727 | PCI_DEVICE_ID_INTEL_ICH6_1, NULL); |
| 1761 | if (pcidev) { | 1728 | if (pcidev) { |
| 1762 | dev->control = &spic_types[2]; | 1729 | dev->model = SONYPI_DEVICE_TYPE2; |
| 1730 | dev->evport_offset = SONYPI_TYPE2_OFFSET; | ||
| 1731 | dev->event_types = type2_events; | ||
| 1763 | goto out; | 1732 | goto out; |
| 1764 | } | 1733 | } |
| 1765 | 1734 | ||
| 1766 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1735 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, |
| 1767 | PCI_DEVICE_ID_INTEL_ICH7_1, NULL); | 1736 | PCI_DEVICE_ID_INTEL_ICH7_1, NULL); |
| 1768 | if (pcidev) { | 1737 | if (pcidev) { |
| 1769 | dev->control = &spic_types[2]; | 1738 | dev->model = SONYPI_DEVICE_TYPE3; |
| 1739 | dev->handle_irq = type3_handle_irq; | ||
| 1740 | dev->evport_offset = SONYPI_TYPE3_OFFSET; | ||
| 1741 | dev->event_types = type3_events; | ||
| 1770 | goto out; | 1742 | goto out; |
| 1771 | } | 1743 | } |
| 1772 | 1744 | ||
| 1773 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1745 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, |
| 1774 | PCI_DEVICE_ID_INTEL_ICH8_4, NULL); | 1746 | PCI_DEVICE_ID_INTEL_ICH8_4, NULL); |
| 1775 | if (pcidev) { | 1747 | if (pcidev) { |
| 1776 | dev->control = &spic_types[2]; | 1748 | dev->model = SONYPI_DEVICE_TYPE3; |
| 1749 | dev->handle_irq = type3_handle_irq; | ||
| 1750 | dev->evport_offset = SONYPI_TYPE3_OFFSET; | ||
| 1751 | dev->event_types = type3_events; | ||
| 1777 | goto out; | 1752 | goto out; |
| 1778 | } | 1753 | } |
| 1779 | 1754 | ||
| 1780 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1755 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, |
| 1781 | PCI_DEVICE_ID_INTEL_ICH9_1, NULL); | 1756 | PCI_DEVICE_ID_INTEL_ICH9_1, NULL); |
| 1782 | if (pcidev) { | 1757 | if (pcidev) { |
| 1783 | dev->control = &spic_types[2]; | 1758 | dev->model = SONYPI_DEVICE_TYPE3; |
| 1759 | dev->handle_irq = type3_handle_irq; | ||
| 1760 | dev->evport_offset = SONYPI_TYPE3_OFFSET; | ||
| 1761 | dev->event_types = type3_events; | ||
| 1784 | goto out; | 1762 | goto out; |
| 1785 | } | 1763 | } |
| 1786 | 1764 | ||
| 1787 | /* default */ | 1765 | /* default */ |
| 1788 | dev->control = &spic_types[1]; | 1766 | dev->model = SONYPI_DEVICE_TYPE2; |
| 1767 | dev->evport_offset = SONYPI_TYPE2_OFFSET; | ||
| 1768 | dev->event_types = type2_events; | ||
| 1789 | 1769 | ||
| 1790 | out: | 1770 | out: |
| 1791 | if (pcidev) | 1771 | if (pcidev) |
| 1792 | pci_dev_put(pcidev); | 1772 | pci_dev_put(pcidev); |
| 1793 | 1773 | ||
| 1794 | printk(KERN_INFO DRV_PFX "detected Type%d model\n", | 1774 | printk(KERN_INFO DRV_PFX "detected Type%d model\n", |
| 1795 | dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 : | 1775 | dev->model == SONYPI_DEVICE_TYPE1 ? 1 : |
| 1796 | dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 : 3); | 1776 | dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3); |
| 1797 | } | 1777 | } |
| 1798 | 1778 | ||
| 1799 | /* camera tests and poweron/poweroff */ | 1779 | /* camera tests and poweron/poweroff */ |
| @@ -2566,7 +2546,7 @@ static int sony_pic_enable(struct acpi_device *device, | |||
| 2566 | buffer.pointer = resource; | 2546 | buffer.pointer = resource; |
| 2567 | 2547 | ||
| 2568 | /* setup Type 1 resources */ | 2548 | /* setup Type 1 resources */ |
| 2569 | if (spic_dev.control->model == SONYPI_DEVICE_TYPE1) { | 2549 | if (spic_dev.model == SONYPI_DEVICE_TYPE1) { |
| 2570 | 2550 | ||
| 2571 | /* setup io resources */ | 2551 | /* setup io resources */ |
| 2572 | resource->res1.type = ACPI_RESOURCE_TYPE_IO; | 2552 | resource->res1.type = ACPI_RESOURCE_TYPE_IO; |
| @@ -2649,29 +2629,28 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id) | |||
| 2649 | data_mask = inb_p(dev->cur_ioport->io2.minimum); | 2629 | data_mask = inb_p(dev->cur_ioport->io2.minimum); |
| 2650 | else | 2630 | else |
| 2651 | data_mask = inb_p(dev->cur_ioport->io1.minimum + | 2631 | data_mask = inb_p(dev->cur_ioport->io1.minimum + |
| 2652 | dev->control->evport_offset); | 2632 | dev->evport_offset); |
| 2653 | 2633 | ||
| 2654 | dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", | 2634 | dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", |
| 2655 | ev, data_mask, dev->cur_ioport->io1.minimum, | 2635 | ev, data_mask, dev->cur_ioport->io1.minimum, |
| 2656 | dev->control->evport_offset); | 2636 | dev->evport_offset); |
| 2657 | 2637 | ||
| 2658 | if (ev == 0x00 || ev == 0xff) | 2638 | if (ev == 0x00 || ev == 0xff) |
| 2659 | return IRQ_HANDLED; | 2639 | return IRQ_HANDLED; |
| 2660 | 2640 | ||
| 2661 | for (i = 0; dev->control->event_types[i].mask; i++) { | 2641 | for (i = 0; dev->event_types[i].mask; i++) { |
| 2662 | 2642 | ||
| 2663 | if ((data_mask & dev->control->event_types[i].data) != | 2643 | if ((data_mask & dev->event_types[i].data) != |
| 2664 | dev->control->event_types[i].data) | 2644 | dev->event_types[i].data) |
| 2665 | continue; | 2645 | continue; |
| 2666 | 2646 | ||
| 2667 | if (!(mask & dev->control->event_types[i].mask)) | 2647 | if (!(mask & dev->event_types[i].mask)) |
| 2668 | continue; | 2648 | continue; |
| 2669 | 2649 | ||
| 2670 | for (j = 0; dev->control->event_types[i].events[j].event; j++) { | 2650 | for (j = 0; dev->event_types[i].events[j].event; j++) { |
| 2671 | if (ev == dev->control->event_types[i].events[j].data) { | 2651 | if (ev == dev->event_types[i].events[j].data) { |
| 2672 | device_event = | 2652 | device_event = |
| 2673 | dev->control-> | 2653 | dev->event_types[i].events[j].event; |
| 2674 | event_types[i].events[j].event; | ||
| 2675 | goto found; | 2654 | goto found; |
| 2676 | } | 2655 | } |
| 2677 | } | 2656 | } |
| @@ -2679,13 +2658,12 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id) | |||
| 2679 | /* Still not able to decode the event try to pass | 2658 | /* Still not able to decode the event try to pass |
| 2680 | * it over to the minidriver | 2659 | * it over to the minidriver |
| 2681 | */ | 2660 | */ |
| 2682 | if (dev->control->handle_irq && | 2661 | if (dev->handle_irq && dev->handle_irq(data_mask, ev) == 0) |
| 2683 | dev->control->handle_irq(data_mask, ev) == 0) | ||
| 2684 | return IRQ_HANDLED; | 2662 | return IRQ_HANDLED; |
| 2685 | 2663 | ||
| 2686 | dprintk("unknown event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", | 2664 | dprintk("unknown event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", |
| 2687 | ev, data_mask, dev->cur_ioport->io1.minimum, | 2665 | ev, data_mask, dev->cur_ioport->io1.minimum, |
| 2688 | dev->control->evport_offset); | 2666 | dev->evport_offset); |
| 2689 | return IRQ_HANDLED; | 2667 | return IRQ_HANDLED; |
| 2690 | 2668 | ||
| 2691 | found: | 2669 | found: |
| @@ -2816,7 +2794,7 @@ static int sony_pic_add(struct acpi_device *device) | |||
| 2816 | /* request IRQ */ | 2794 | /* request IRQ */ |
| 2817 | list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) { | 2795 | list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) { |
| 2818 | if (!request_irq(irq->irq.interrupts[0], sony_pic_irq, | 2796 | if (!request_irq(irq->irq.interrupts[0], sony_pic_irq, |
| 2819 | IRQF_SHARED, "sony-laptop", &spic_dev)) { | 2797 | IRQF_DISABLED, "sony-laptop", &spic_dev)) { |
| 2820 | dprintk("IRQ: %d - triggering: %d - " | 2798 | dprintk("IRQ: %d - triggering: %d - " |
| 2821 | "polarity: %d - shr: %d\n", | 2799 | "polarity: %d - shr: %d\n", |
| 2822 | irq->irq.interrupts[0], | 2800 | irq->irq.interrupts[0], |
| @@ -2949,6 +2927,7 @@ static int __init sony_laptop_init(void) | |||
| 2949 | "Unable to register SPIC driver."); | 2927 | "Unable to register SPIC driver."); |
| 2950 | goto out; | 2928 | goto out; |
| 2951 | } | 2929 | } |
| 2930 | spic_drv_registered = 1; | ||
| 2952 | } | 2931 | } |
| 2953 | 2932 | ||
| 2954 | result = acpi_bus_register_driver(&sony_nc_driver); | 2933 | result = acpi_bus_register_driver(&sony_nc_driver); |
| @@ -2960,7 +2939,7 @@ static int __init sony_laptop_init(void) | |||
| 2960 | return 0; | 2939 | return 0; |
| 2961 | 2940 | ||
| 2962 | out_unregister_pic: | 2941 | out_unregister_pic: |
| 2963 | if (!no_spic) | 2942 | if (spic_drv_registered) |
| 2964 | acpi_bus_unregister_driver(&sony_pic_driver); | 2943 | acpi_bus_unregister_driver(&sony_pic_driver); |
| 2965 | out: | 2944 | out: |
| 2966 | return result; | 2945 | return result; |
| @@ -2969,7 +2948,7 @@ out: | |||
| 2969 | static void __exit sony_laptop_exit(void) | 2948 | static void __exit sony_laptop_exit(void) |
| 2970 | { | 2949 | { |
| 2971 | acpi_bus_unregister_driver(&sony_nc_driver); | 2950 | acpi_bus_unregister_driver(&sony_nc_driver); |
| 2972 | if (!no_spic) | 2951 | if (spic_drv_registered) |
| 2973 | acpi_bus_unregister_driver(&sony_pic_driver); | 2952 | acpi_bus_unregister_driver(&sony_pic_driver); |
| 2974 | } | 2953 | } |
| 2975 | 2954 | ||
diff --git a/drivers/sfi/sfi_core.c b/drivers/sfi/sfi_core.c index d3b496800477..b204a0929139 100644 --- a/drivers/sfi/sfi_core.c +++ b/drivers/sfi/sfi_core.c | |||
| @@ -90,7 +90,11 @@ static struct sfi_table_simple *syst_va __read_mostly; | |||
| 90 | */ | 90 | */ |
| 91 | static u32 sfi_use_ioremap __read_mostly; | 91 | static u32 sfi_use_ioremap __read_mostly; |
| 92 | 92 | ||
| 93 | static void __iomem *sfi_map_memory(u64 phys, u32 size) | 93 | /* |
| 94 | * sfi_un/map_memory calls early_ioremap/iounmap which is a __init function | ||
| 95 | * and introduces section mismatch. So use __ref to make it calm. | ||
| 96 | */ | ||
| 97 | static void __iomem * __ref sfi_map_memory(u64 phys, u32 size) | ||
| 94 | { | 98 | { |
| 95 | if (!phys || !size) | 99 | if (!phys || !size) |
| 96 | return NULL; | 100 | return NULL; |
| @@ -101,7 +105,7 @@ static void __iomem *sfi_map_memory(u64 phys, u32 size) | |||
| 101 | return early_ioremap(phys, size); | 105 | return early_ioremap(phys, size); |
| 102 | } | 106 | } |
| 103 | 107 | ||
| 104 | static void sfi_unmap_memory(void __iomem *virt, u32 size) | 108 | static void __ref sfi_unmap_memory(void __iomem *virt, u32 size) |
| 105 | { | 109 | { |
| 106 | if (!virt || !size) | 110 | if (!virt || !size) |
| 107 | return; | 111 | return; |
| @@ -125,7 +129,7 @@ static void sfi_print_table_header(unsigned long long pa, | |||
| 125 | * sfi_verify_table() | 129 | * sfi_verify_table() |
| 126 | * Sanity check table lengh, calculate checksum | 130 | * Sanity check table lengh, calculate checksum |
| 127 | */ | 131 | */ |
| 128 | static __init int sfi_verify_table(struct sfi_table_header *table) | 132 | static int sfi_verify_table(struct sfi_table_header *table) |
| 129 | { | 133 | { |
| 130 | 134 | ||
| 131 | u8 checksum = 0; | 135 | u8 checksum = 0; |
| @@ -213,12 +217,17 @@ static int sfi_table_check_key(struct sfi_table_header *th, | |||
| 213 | * the mapped virt address will be returned, and the virt space | 217 | * the mapped virt address will be returned, and the virt space |
| 214 | * will be released by call sfi_put_table() later | 218 | * will be released by call sfi_put_table() later |
| 215 | * | 219 | * |
| 220 | * This two cases are from two different functions with two different | ||
| 221 | * sections and causes section mismatch warning. So use __ref to tell | ||
| 222 | * modpost not to make any noise. | ||
| 223 | * | ||
| 216 | * Return value: | 224 | * Return value: |
| 217 | * NULL: when can't find a table matching the key | 225 | * NULL: when can't find a table matching the key |
| 218 | * ERR_PTR(error): error value | 226 | * ERR_PTR(error): error value |
| 219 | * virt table address: when a matched table is found | 227 | * virt table address: when a matched table is found |
| 220 | */ | 228 | */ |
| 221 | struct sfi_table_header *sfi_check_table(u64 pa, struct sfi_table_key *key) | 229 | struct sfi_table_header * |
| 230 | __ref sfi_check_table(u64 pa, struct sfi_table_key *key) | ||
| 222 | { | 231 | { |
| 223 | struct sfi_table_header *th; | 232 | struct sfi_table_header *th; |
| 224 | void *ret = NULL; | 233 | void *ret = NULL; |
diff --git a/drivers/staging/dst/dcore.c b/drivers/staging/dst/dcore.c index ee1601026fb0..c24e4e0367a2 100644 --- a/drivers/staging/dst/dcore.c +++ b/drivers/staging/dst/dcore.c | |||
| @@ -102,7 +102,7 @@ static int dst_request(struct request_queue *q, struct bio *bio) | |||
| 102 | struct dst_node *n = q->queuedata; | 102 | struct dst_node *n = q->queuedata; |
| 103 | int err = -EIO; | 103 | int err = -EIO; |
| 104 | 104 | ||
| 105 | if (bio_empty_barrier(bio) && !q->prepare_discard_fn) { | 105 | if (bio_empty_barrier(bio) && !blk_queue_discard(q)) { |
| 106 | /* | 106 | /* |
| 107 | * This is a dirty^Wnice hack, but if we complete this | 107 | * This is a dirty^Wnice hack, but if we complete this |
| 108 | * operation with -EOPNOTSUPP like intended, XFS | 108 | * operation with -EOPNOTSUPP like intended, XFS |
diff --git a/drivers/staging/iio/light/tsl2561.c b/drivers/staging/iio/light/tsl2561.c index ea8a5efc19bc..fc2107f4c049 100644 --- a/drivers/staging/iio/light/tsl2561.c +++ b/drivers/staging/iio/light/tsl2561.c | |||
| @@ -239,10 +239,6 @@ static int __devexit tsl2561_remove(struct i2c_client *client) | |||
| 239 | return tsl2561_powerdown(client); | 239 | return tsl2561_powerdown(client); |
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | static unsigned short normal_i2c[] = { 0x29, 0x39, 0x49, I2C_CLIENT_END }; | ||
| 243 | |||
| 244 | I2C_CLIENT_INSMOD; | ||
| 245 | |||
| 246 | static const struct i2c_device_id tsl2561_id[] = { | 242 | static const struct i2c_device_id tsl2561_id[] = { |
| 247 | { "tsl2561", 0 }, | 243 | { "tsl2561", 0 }, |
| 248 | { } | 244 | { } |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index c44367fea185..bf0f6520c6df 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/wait.h> | 30 | #include <linux/wait.h> |
| 31 | #include <linux/compiler.h> | 31 | #include <linux/compiler.h> |
| 32 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
| 33 | #include <linux/sched.h> | ||
| 33 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
| 34 | #include <linux/poll.h> | 35 | #include <linux/poll.h> |
| 35 | #include <linux/smp_lock.h> | 36 | #include <linux/smp_lock.h> |
diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c index df52cb355f7d..406caa6a71cb 100644 --- a/drivers/w1/masters/ds2482.c +++ b/drivers/w1/masters/ds2482.c | |||
| @@ -24,19 +24,6 @@ | |||
| 24 | #include "../w1_int.h" | 24 | #include "../w1_int.h" |
| 25 | 25 | ||
| 26 | /** | 26 | /** |
| 27 | * Address is selected using 2 pins, resulting in 4 possible addresses. | ||
| 28 | * 0x18, 0x19, 0x1a, 0x1b | ||
| 29 | * However, the chip cannot be detected without doing an i2c write, | ||
| 30 | * so use the force module parameter. | ||
| 31 | */ | ||
| 32 | static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; | ||
| 33 | |||
| 34 | /** | ||
| 35 | * Insmod parameters | ||
| 36 | */ | ||
| 37 | I2C_CLIENT_INSMOD_1(ds2482); | ||
| 38 | |||
| 39 | /** | ||
| 40 | * The DS2482 registers - there are 3 registers that are addressed by a read | 27 | * The DS2482 registers - there are 3 registers that are addressed by a read |
| 41 | * pointer. The read pointer is set by the last command executed. | 28 | * pointer. The read pointer is set by the last command executed. |
| 42 | * | 29 | * |
| @@ -96,8 +83,6 @@ static const u8 ds2482_chan_rd[8] = | |||
| 96 | 83 | ||
| 97 | static int ds2482_probe(struct i2c_client *client, | 84 | static int ds2482_probe(struct i2c_client *client, |
| 98 | const struct i2c_device_id *id); | 85 | const struct i2c_device_id *id); |
| 99 | static int ds2482_detect(struct i2c_client *client, int kind, | ||
| 100 | struct i2c_board_info *info); | ||
| 101 | static int ds2482_remove(struct i2c_client *client); | 86 | static int ds2482_remove(struct i2c_client *client); |
| 102 | 87 | ||
| 103 | 88 | ||
| @@ -117,8 +102,6 @@ static struct i2c_driver ds2482_driver = { | |||
| 117 | .probe = ds2482_probe, | 102 | .probe = ds2482_probe, |
| 118 | .remove = ds2482_remove, | 103 | .remove = ds2482_remove, |
| 119 | .id_table = ds2482_id, | 104 | .id_table = ds2482_id, |
| 120 | .detect = ds2482_detect, | ||
| 121 | .address_data = &addr_data, | ||
| 122 | }; | 105 | }; |
| 123 | 106 | ||
| 124 | /* | 107 | /* |
| @@ -425,19 +408,6 @@ static u8 ds2482_w1_reset_bus(void *data) | |||
| 425 | } | 408 | } |
| 426 | 409 | ||
| 427 | 410 | ||
| 428 | static int ds2482_detect(struct i2c_client *client, int kind, | ||
| 429 | struct i2c_board_info *info) | ||
| 430 | { | ||
| 431 | if (!i2c_check_functionality(client->adapter, | ||
| 432 | I2C_FUNC_SMBUS_WRITE_BYTE_DATA | | ||
| 433 | I2C_FUNC_SMBUS_BYTE)) | ||
| 434 | return -ENODEV; | ||
| 435 | |||
| 436 | strlcpy(info->type, "ds2482", I2C_NAME_SIZE); | ||
| 437 | |||
| 438 | return 0; | ||
| 439 | } | ||
| 440 | |||
| 441 | static int ds2482_probe(struct i2c_client *client, | 411 | static int ds2482_probe(struct i2c_client *client, |
| 442 | const struct i2c_device_id *id) | 412 | const struct i2c_device_id *id) |
| 443 | { | 413 | { |
| @@ -446,6 +416,11 @@ static int ds2482_probe(struct i2c_client *client, | |||
| 446 | int temp1; | 416 | int temp1; |
| 447 | int idx; | 417 | int idx; |
| 448 | 418 | ||
| 419 | if (!i2c_check_functionality(client->adapter, | ||
| 420 | I2C_FUNC_SMBUS_WRITE_BYTE_DATA | | ||
| 421 | I2C_FUNC_SMBUS_BYTE)) | ||
| 422 | return -ENODEV; | ||
| 423 | |||
| 449 | if (!(data = kzalloc(sizeof(struct ds2482_data), GFP_KERNEL))) { | 424 | if (!(data = kzalloc(sizeof(struct ds2482_data), GFP_KERNEL))) { |
| 450 | err = -ENOMEM; | 425 | err = -ENOMEM; |
| 451 | goto exit; | 426 | goto exit; |
diff --git a/drivers/xen/xenfs/xenbus.c b/drivers/xen/xenfs/xenbus.c index a9592d981b10..6c4269b836b7 100644 --- a/drivers/xen/xenfs/xenbus.c +++ b/drivers/xen/xenfs/xenbus.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #include <linux/fs.h> | 43 | #include <linux/fs.h> |
| 44 | #include <linux/poll.h> | 44 | #include <linux/poll.h> |
| 45 | #include <linux/mutex.h> | 45 | #include <linux/mutex.h> |
| 46 | #include <linux/sched.h> | ||
| 46 | #include <linux/spinlock.h> | 47 | #include <linux/spinlock.h> |
| 47 | #include <linux/mount.h> | 48 | #include <linux/mount.h> |
| 48 | #include <linux/pagemap.h> | 49 | #include <linux/pagemap.h> |
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index d11c51fc2a3f..2ca7a7cafdbf 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c | |||
| @@ -8,8 +8,10 @@ | |||
| 8 | * | 8 | * |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/cred.h> | ||
| 11 | #include <linux/file.h> | 12 | #include <linux/file.h> |
| 12 | #include <linux/poll.h> | 13 | #include <linux/poll.h> |
| 14 | #include <linux/sched.h> | ||
| 13 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
| 14 | #include <linux/init.h> | 16 | #include <linux/init.h> |
| 15 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
| @@ -249,6 +249,7 @@ void bio_free(struct bio *bio, struct bio_set *bs) | |||
| 249 | 249 | ||
| 250 | mempool_free(p, bs->bio_pool); | 250 | mempool_free(p, bs->bio_pool); |
| 251 | } | 251 | } |
| 252 | EXPORT_SYMBOL(bio_free); | ||
| 252 | 253 | ||
| 253 | void bio_init(struct bio *bio) | 254 | void bio_init(struct bio *bio) |
| 254 | { | 255 | { |
| @@ -257,6 +258,7 @@ void bio_init(struct bio *bio) | |||
| 257 | bio->bi_comp_cpu = -1; | 258 | bio->bi_comp_cpu = -1; |
| 258 | atomic_set(&bio->bi_cnt, 1); | 259 | atomic_set(&bio->bi_cnt, 1); |
| 259 | } | 260 | } |
| 261 | EXPORT_SYMBOL(bio_init); | ||
| 260 | 262 | ||
| 261 | /** | 263 | /** |
| 262 | * bio_alloc_bioset - allocate a bio for I/O | 264 | * bio_alloc_bioset - allocate a bio for I/O |
| @@ -311,6 +313,7 @@ err_free: | |||
| 311 | mempool_free(p, bs->bio_pool); | 313 | mempool_free(p, bs->bio_pool); |
| 312 | return NULL; | 314 | return NULL; |
| 313 | } | 315 | } |
| 316 | EXPORT_SYMBOL(bio_alloc_bioset); | ||
| 314 | 317 | ||
| 315 | static void bio_fs_destructor(struct bio *bio) | 318 | static void bio_fs_destructor(struct bio *bio) |
| 316 | { | 319 | { |
| @@ -337,6 +340,7 @@ struct bio *bio_alloc(gfp_t gfp_mask, int nr_iovecs) | |||
| 337 | 340 | ||
| 338 | return bio; | 341 | return bio; |
| 339 | } | 342 | } |
| 343 | EXPORT_SYMBOL(bio_alloc); | ||
| 340 | 344 | ||
| 341 | static void bio_kmalloc_destructor(struct bio *bio) | 345 | static void bio_kmalloc_destructor(struct bio *bio) |
| 342 | { | 346 | { |
| @@ -380,6 +384,7 @@ struct bio *bio_kmalloc(gfp_t gfp_mask, int nr_iovecs) | |||
| 380 | 384 | ||
| 381 | return bio; | 385 | return bio; |
| 382 | } | 386 | } |
| 387 | EXPORT_SYMBOL(bio_kmalloc); | ||
| 383 | 388 | ||
| 384 | void zero_fill_bio(struct bio *bio) | 389 | void zero_fill_bio(struct bio *bio) |
| 385 | { | 390 | { |
| @@ -416,6 +421,7 @@ void bio_put(struct bio *bio) | |||
| 416 | bio->bi_destructor(bio); | 421 | bio->bi_destructor(bio); |
| 417 | } | 422 | } |
| 418 | } | 423 | } |
| 424 | EXPORT_SYMBOL(bio_put); | ||
| 419 | 425 | ||
| 420 | inline int bio_phys_segments(struct request_queue *q, struct bio *bio) | 426 | inline int bio_phys_segments(struct request_queue *q, struct bio *bio) |
| 421 | { | 427 | { |
| @@ -424,6 +430,7 @@ inline int bio_phys_segments(struct request_queue *q, struct bio *bio) | |||
| 424 | 430 | ||
| 425 | return bio->bi_phys_segments; | 431 | return bio->bi_phys_segments; |
| 426 | } | 432 | } |
| 433 | EXPORT_SYMBOL(bio_phys_segments); | ||
| 427 | 434 | ||
| 428 | /** | 435 | /** |
| 429 | * __bio_clone - clone a bio | 436 | * __bio_clone - clone a bio |
| @@ -451,6 +458,7 @@ void __bio_clone(struct bio *bio, struct bio *bio_src) | |||
| 451 | bio->bi_size = bio_src->bi_size; | 458 | bio->bi_size = bio_src->bi_size; |
| 452 | bio->bi_idx = bio_src->bi_idx; | 459 | bio->bi_idx = bio_src->bi_idx; |
| 453 | } | 460 | } |
| 461 | EXPORT_SYMBOL(__bio_clone); | ||
| 454 | 462 | ||
| 455 | /** | 463 | /** |
| 456 | * bio_clone - clone a bio | 464 | * bio_clone - clone a bio |
| @@ -482,6 +490,7 @@ struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask) | |||
| 482 | 490 | ||
| 483 | return b; | 491 | return b; |
| 484 | } | 492 | } |
| 493 | EXPORT_SYMBOL(bio_clone); | ||
| 485 | 494 | ||
| 486 | /** | 495 | /** |
| 487 | * bio_get_nr_vecs - return approx number of vecs | 496 | * bio_get_nr_vecs - return approx number of vecs |
| @@ -505,6 +514,7 @@ int bio_get_nr_vecs(struct block_device *bdev) | |||
| 505 | 514 | ||
| 506 | return nr_pages; | 515 | return nr_pages; |
| 507 | } | 516 | } |
| 517 | EXPORT_SYMBOL(bio_get_nr_vecs); | ||
| 508 | 518 | ||
| 509 | static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page | 519 | static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page |
| 510 | *page, unsigned int len, unsigned int offset, | 520 | *page, unsigned int len, unsigned int offset, |
| @@ -635,6 +645,7 @@ int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page *page, | |||
| 635 | return __bio_add_page(q, bio, page, len, offset, | 645 | return __bio_add_page(q, bio, page, len, offset, |
| 636 | queue_max_hw_sectors(q)); | 646 | queue_max_hw_sectors(q)); |
| 637 | } | 647 | } |
| 648 | EXPORT_SYMBOL(bio_add_pc_page); | ||
| 638 | 649 | ||
| 639 | /** | 650 | /** |
| 640 | * bio_add_page - attempt to add page to bio | 651 | * bio_add_page - attempt to add page to bio |
| @@ -655,6 +666,7 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len, | |||
| 655 | struct request_queue *q = bdev_get_queue(bio->bi_bdev); | 666 | struct request_queue *q = bdev_get_queue(bio->bi_bdev); |
| 656 | return __bio_add_page(q, bio, page, len, offset, queue_max_sectors(q)); | 667 | return __bio_add_page(q, bio, page, len, offset, queue_max_sectors(q)); |
| 657 | } | 668 | } |
| 669 | EXPORT_SYMBOL(bio_add_page); | ||
| 658 | 670 | ||
| 659 | struct bio_map_data { | 671 | struct bio_map_data { |
| 660 | struct bio_vec *iovecs; | 672 | struct bio_vec *iovecs; |
| @@ -776,6 +788,7 @@ int bio_uncopy_user(struct bio *bio) | |||
| 776 | bio_put(bio); | 788 | bio_put(bio); |
| 777 | return ret; | 789 | return ret; |
| 778 | } | 790 | } |
| 791 | EXPORT_SYMBOL(bio_uncopy_user); | ||
| 779 | 792 | ||
| 780 | /** | 793 | /** |
| 781 | * bio_copy_user_iov - copy user data to bio | 794 | * bio_copy_user_iov - copy user data to bio |
| @@ -920,6 +933,7 @@ struct bio *bio_copy_user(struct request_queue *q, struct rq_map_data *map_data, | |||
| 920 | 933 | ||
| 921 | return bio_copy_user_iov(q, map_data, &iov, 1, write_to_vm, gfp_mask); | 934 | return bio_copy_user_iov(q, map_data, &iov, 1, write_to_vm, gfp_mask); |
| 922 | } | 935 | } |
| 936 | EXPORT_SYMBOL(bio_copy_user); | ||
| 923 | 937 | ||
| 924 | static struct bio *__bio_map_user_iov(struct request_queue *q, | 938 | static struct bio *__bio_map_user_iov(struct request_queue *q, |
| 925 | struct block_device *bdev, | 939 | struct block_device *bdev, |
| @@ -1050,6 +1064,7 @@ struct bio *bio_map_user(struct request_queue *q, struct block_device *bdev, | |||
| 1050 | 1064 | ||
| 1051 | return bio_map_user_iov(q, bdev, &iov, 1, write_to_vm, gfp_mask); | 1065 | return bio_map_user_iov(q, bdev, &iov, 1, write_to_vm, gfp_mask); |
| 1052 | } | 1066 | } |
| 1067 | EXPORT_SYMBOL(bio_map_user); | ||
| 1053 | 1068 | ||
| 1054 | /** | 1069 | /** |
| 1055 | * bio_map_user_iov - map user sg_iovec table into bio | 1070 | * bio_map_user_iov - map user sg_iovec table into bio |
| @@ -1117,13 +1132,13 @@ void bio_unmap_user(struct bio *bio) | |||
| 1117 | __bio_unmap_user(bio); | 1132 | __bio_unmap_user(bio); |
| 1118 | bio_put(bio); | 1133 | bio_put(bio); |
| 1119 | } | 1134 | } |
| 1135 | EXPORT_SYMBOL(bio_unmap_user); | ||
| 1120 | 1136 | ||
| 1121 | static void bio_map_kern_endio(struct bio *bio, int err) | 1137 | static void bio_map_kern_endio(struct bio *bio, int err) |
| 1122 | { | 1138 | { |
| 1123 | bio_put(bio); | 1139 | bio_put(bio); |
| 1124 | } | 1140 | } |
| 1125 | 1141 | ||
| 1126 | |||
| 1127 | static struct bio *__bio_map_kern(struct request_queue *q, void *data, | 1142 | static struct bio *__bio_map_kern(struct request_queue *q, void *data, |
| 1128 | unsigned int len, gfp_t gfp_mask) | 1143 | unsigned int len, gfp_t gfp_mask) |
| 1129 | { | 1144 | { |
| @@ -1189,6 +1204,7 @@ struct bio *bio_map_kern(struct request_queue *q, void *data, unsigned int len, | |||
| 1189 | bio_put(bio); | 1204 | bio_put(bio); |
| 1190 | return ERR_PTR(-EINVAL); | 1205 | return ERR_PTR(-EINVAL); |
| 1191 | } | 1206 | } |
| 1207 | EXPORT_SYMBOL(bio_map_kern); | ||
| 1192 | 1208 | ||
| 1193 | static void bio_copy_kern_endio(struct bio *bio, int err) | 1209 | static void bio_copy_kern_endio(struct bio *bio, int err) |
| 1194 | { | 1210 | { |
| @@ -1250,6 +1266,7 @@ struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len, | |||
| 1250 | 1266 | ||
| 1251 | return bio; | 1267 | return bio; |
| 1252 | } | 1268 | } |
| 1269 | EXPORT_SYMBOL(bio_copy_kern); | ||
| 1253 | 1270 | ||
| 1254 | /* | 1271 | /* |
| 1255 | * bio_set_pages_dirty() and bio_check_pages_dirty() are support functions | 1272 | * bio_set_pages_dirty() and bio_check_pages_dirty() are support functions |
| @@ -1400,6 +1417,7 @@ void bio_endio(struct bio *bio, int error) | |||
| 1400 | if (bio->bi_end_io) | 1417 | if (bio->bi_end_io) |
| 1401 | bio->bi_end_io(bio, error); | 1418 | bio->bi_end_io(bio, error); |
| 1402 | } | 1419 | } |
| 1420 | EXPORT_SYMBOL(bio_endio); | ||
| 1403 | 1421 | ||
| 1404 | void bio_pair_release(struct bio_pair *bp) | 1422 | void bio_pair_release(struct bio_pair *bp) |
| 1405 | { | 1423 | { |
| @@ -1410,6 +1428,7 @@ void bio_pair_release(struct bio_pair *bp) | |||
| 1410 | mempool_free(bp, bp->bio2.bi_private); | 1428 | mempool_free(bp, bp->bio2.bi_private); |
| 1411 | } | 1429 | } |
| 1412 | } | 1430 | } |
| 1431 | EXPORT_SYMBOL(bio_pair_release); | ||
| 1413 | 1432 | ||
| 1414 | static void bio_pair_end_1(struct bio *bi, int err) | 1433 | static void bio_pair_end_1(struct bio *bi, int err) |
| 1415 | { | 1434 | { |
| @@ -1477,6 +1496,7 @@ struct bio_pair *bio_split(struct bio *bi, int first_sectors) | |||
| 1477 | 1496 | ||
| 1478 | return bp; | 1497 | return bp; |
| 1479 | } | 1498 | } |
| 1499 | EXPORT_SYMBOL(bio_split); | ||
| 1480 | 1500 | ||
| 1481 | /** | 1501 | /** |
| 1482 | * bio_sector_offset - Find hardware sector offset in bio | 1502 | * bio_sector_offset - Find hardware sector offset in bio |
| @@ -1547,6 +1567,7 @@ void bioset_free(struct bio_set *bs) | |||
| 1547 | 1567 | ||
| 1548 | kfree(bs); | 1568 | kfree(bs); |
| 1549 | } | 1569 | } |
| 1570 | EXPORT_SYMBOL(bioset_free); | ||
| 1550 | 1571 | ||
| 1551 | /** | 1572 | /** |
| 1552 | * bioset_create - Create a bio_set | 1573 | * bioset_create - Create a bio_set |
| @@ -1592,6 +1613,7 @@ bad: | |||
| 1592 | bioset_free(bs); | 1613 | bioset_free(bs); |
| 1593 | return NULL; | 1614 | return NULL; |
| 1594 | } | 1615 | } |
| 1616 | EXPORT_SYMBOL(bioset_create); | ||
| 1595 | 1617 | ||
| 1596 | static void __init biovec_init_slabs(void) | 1618 | static void __init biovec_init_slabs(void) |
| 1597 | { | 1619 | { |
| @@ -1636,29 +1658,4 @@ static int __init init_bio(void) | |||
| 1636 | 1658 | ||
| 1637 | return 0; | 1659 | return 0; |
| 1638 | } | 1660 | } |
| 1639 | |||
| 1640 | subsys_initcall(init_bio); | 1661 | subsys_initcall(init_bio); |
| 1641 | |||
| 1642 | EXPORT_SYMBOL(bio_alloc); | ||
| 1643 | EXPORT_SYMBOL(bio_kmalloc); | ||
| 1644 | EXPORT_SYMBOL(bio_put); | ||
| 1645 | EXPORT_SYMBOL(bio_free); | ||
| 1646 | EXPORT_SYMBOL(bio_endio); | ||
| 1647 | EXPORT_SYMBOL(bio_init); | ||
| 1648 | EXPORT_SYMBOL(__bio_clone); | ||
| 1649 | EXPORT_SYMBOL(bio_clone); | ||
| 1650 | EXPORT_SYMBOL(bio_phys_segments); | ||
| 1651 | EXPORT_SYMBOL(bio_add_page); | ||
| 1652 | EXPORT_SYMBOL(bio_add_pc_page); | ||
| 1653 | EXPORT_SYMBOL(bio_get_nr_vecs); | ||
| 1654 | EXPORT_SYMBOL(bio_map_user); | ||
| 1655 | EXPORT_SYMBOL(bio_unmap_user); | ||
| 1656 | EXPORT_SYMBOL(bio_map_kern); | ||
| 1657 | EXPORT_SYMBOL(bio_copy_kern); | ||
| 1658 | EXPORT_SYMBOL(bio_pair_release); | ||
| 1659 | EXPORT_SYMBOL(bio_split); | ||
| 1660 | EXPORT_SYMBOL(bio_copy_user); | ||
| 1661 | EXPORT_SYMBOL(bio_uncopy_user); | ||
| 1662 | EXPORT_SYMBOL(bioset_create); | ||
| 1663 | EXPORT_SYMBOL(bioset_free); | ||
| 1664 | EXPORT_SYMBOL(bio_alloc_bioset); | ||
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index 0376ac66c44a..be4392ca2098 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
| 23 | #include <linux/major.h> | 23 | #include <linux/major.h> |
| 24 | #include <linux/time.h> | 24 | #include <linux/time.h> |
| 25 | #include <linux/sched.h> | ||
| 25 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 26 | #include <linux/ioport.h> | 27 | #include <linux/ioport.h> |
| 27 | #include <linux/fcntl.h> | 28 | #include <linux/fcntl.h> |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 7b685e10cbad..f38fee0311a7 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
| @@ -248,19 +248,11 @@ ssize_t part_stat_show(struct device *dev, | |||
| 248 | part_stat_read(p, merges[WRITE]), | 248 | part_stat_read(p, merges[WRITE]), |
| 249 | (unsigned long long)part_stat_read(p, sectors[WRITE]), | 249 | (unsigned long long)part_stat_read(p, sectors[WRITE]), |
| 250 | jiffies_to_msecs(part_stat_read(p, ticks[WRITE])), | 250 | jiffies_to_msecs(part_stat_read(p, ticks[WRITE])), |
| 251 | part_in_flight(p), | 251 | p->in_flight, |
| 252 | jiffies_to_msecs(part_stat_read(p, io_ticks)), | 252 | jiffies_to_msecs(part_stat_read(p, io_ticks)), |
| 253 | jiffies_to_msecs(part_stat_read(p, time_in_queue))); | 253 | jiffies_to_msecs(part_stat_read(p, time_in_queue))); |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | ssize_t part_inflight_show(struct device *dev, | ||
| 257 | struct device_attribute *attr, char *buf) | ||
| 258 | { | ||
| 259 | struct hd_struct *p = dev_to_part(dev); | ||
| 260 | |||
| 261 | return sprintf(buf, "%8u %8u\n", p->in_flight[0], p->in_flight[1]); | ||
| 262 | } | ||
| 263 | |||
| 264 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 256 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
| 265 | ssize_t part_fail_show(struct device *dev, | 257 | ssize_t part_fail_show(struct device *dev, |
| 266 | struct device_attribute *attr, char *buf) | 258 | struct device_attribute *attr, char *buf) |
| @@ -289,7 +281,6 @@ static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL); | |||
| 289 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); | 281 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); |
| 290 | static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL); | 282 | static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL); |
| 291 | static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); | 283 | static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); |
| 292 | static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL); | ||
| 293 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 284 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
| 294 | static struct device_attribute dev_attr_fail = | 285 | static struct device_attribute dev_attr_fail = |
| 295 | __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store); | 286 | __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store); |
| @@ -301,7 +292,6 @@ static struct attribute *part_attrs[] = { | |||
| 301 | &dev_attr_size.attr, | 292 | &dev_attr_size.attr, |
| 302 | &dev_attr_alignment_offset.attr, | 293 | &dev_attr_alignment_offset.attr, |
| 303 | &dev_attr_stat.attr, | 294 | &dev_attr_stat.attr, |
| 304 | &dev_attr_inflight.attr, | ||
| 305 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 295 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
| 306 | &dev_attr_fail.attr, | 296 | &dev_attr_fail.attr, |
| 307 | #endif | 297 | #endif |
diff --git a/fs/select.c b/fs/select.c index a201fc370223..fd38ce2e32e3 100644 --- a/fs/select.c +++ b/fs/select.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
| 18 | #include <linux/sched.h> | ||
| 18 | #include <linux/syscalls.h> | 19 | #include <linux/syscalls.h> |
| 19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index e23a86cae5ac..25119041e034 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
| @@ -82,7 +82,6 @@ enum rq_cmd_type_bits { | |||
| 82 | enum { | 82 | enum { |
| 83 | REQ_LB_OP_EJECT = 0x40, /* eject request */ | 83 | REQ_LB_OP_EJECT = 0x40, /* eject request */ |
| 84 | REQ_LB_OP_FLUSH = 0x41, /* flush request */ | 84 | REQ_LB_OP_FLUSH = 0x41, /* flush request */ |
| 85 | REQ_LB_OP_DISCARD = 0x42, /* discard sectors */ | ||
| 86 | }; | 85 | }; |
| 87 | 86 | ||
| 88 | /* | 87 | /* |
| @@ -261,7 +260,6 @@ typedef void (request_fn_proc) (struct request_queue *q); | |||
| 261 | typedef int (make_request_fn) (struct request_queue *q, struct bio *bio); | 260 | typedef int (make_request_fn) (struct request_queue *q, struct bio *bio); |
| 262 | typedef int (prep_rq_fn) (struct request_queue *, struct request *); | 261 | typedef int (prep_rq_fn) (struct request_queue *, struct request *); |
| 263 | typedef void (unplug_fn) (struct request_queue *); | 262 | typedef void (unplug_fn) (struct request_queue *); |
| 264 | typedef int (prepare_discard_fn) (struct request_queue *, struct request *); | ||
| 265 | 263 | ||
| 266 | struct bio_vec; | 264 | struct bio_vec; |
| 267 | struct bvec_merge_data { | 265 | struct bvec_merge_data { |
| @@ -313,6 +311,7 @@ struct queue_limits { | |||
| 313 | unsigned int alignment_offset; | 311 | unsigned int alignment_offset; |
| 314 | unsigned int io_min; | 312 | unsigned int io_min; |
| 315 | unsigned int io_opt; | 313 | unsigned int io_opt; |
| 314 | unsigned int max_discard_sectors; | ||
| 316 | 315 | ||
| 317 | unsigned short logical_block_size; | 316 | unsigned short logical_block_size; |
| 318 | unsigned short max_hw_segments; | 317 | unsigned short max_hw_segments; |
| @@ -340,7 +339,6 @@ struct request_queue | |||
| 340 | make_request_fn *make_request_fn; | 339 | make_request_fn *make_request_fn; |
| 341 | prep_rq_fn *prep_rq_fn; | 340 | prep_rq_fn *prep_rq_fn; |
| 342 | unplug_fn *unplug_fn; | 341 | unplug_fn *unplug_fn; |
| 343 | prepare_discard_fn *prepare_discard_fn; | ||
| 344 | merge_bvec_fn *merge_bvec_fn; | 342 | merge_bvec_fn *merge_bvec_fn; |
| 345 | prepare_flush_fn *prepare_flush_fn; | 343 | prepare_flush_fn *prepare_flush_fn; |
| 346 | softirq_done_fn *softirq_done_fn; | 344 | softirq_done_fn *softirq_done_fn; |
| @@ -460,6 +458,7 @@ struct request_queue | |||
| 460 | #define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */ | 458 | #define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */ |
| 461 | #define QUEUE_FLAG_IO_STAT 15 /* do IO stats */ | 459 | #define QUEUE_FLAG_IO_STAT 15 /* do IO stats */ |
| 462 | #define QUEUE_FLAG_CQ 16 /* hardware does queuing */ | 460 | #define QUEUE_FLAG_CQ 16 /* hardware does queuing */ |
| 461 | #define QUEUE_FLAG_DISCARD 17 /* supports DISCARD */ | ||
| 463 | 462 | ||
| 464 | #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ | 463 | #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ |
| 465 | (1 << QUEUE_FLAG_CLUSTER) | \ | 464 | (1 << QUEUE_FLAG_CLUSTER) | \ |
| @@ -591,6 +590,7 @@ enum { | |||
| 591 | #define blk_queue_flushing(q) ((q)->ordseq) | 590 | #define blk_queue_flushing(q) ((q)->ordseq) |
| 592 | #define blk_queue_stackable(q) \ | 591 | #define blk_queue_stackable(q) \ |
| 593 | test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags) | 592 | test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags) |
| 593 | #define blk_queue_discard(q) test_bit(QUEUE_FLAG_DISCARD, &(q)->queue_flags) | ||
| 594 | 594 | ||
| 595 | #define blk_fs_request(rq) ((rq)->cmd_type == REQ_TYPE_FS) | 595 | #define blk_fs_request(rq) ((rq)->cmd_type == REQ_TYPE_FS) |
| 596 | #define blk_pc_request(rq) ((rq)->cmd_type == REQ_TYPE_BLOCK_PC) | 596 | #define blk_pc_request(rq) ((rq)->cmd_type == REQ_TYPE_BLOCK_PC) |
| @@ -929,6 +929,8 @@ extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int); | |||
| 929 | extern void blk_queue_max_phys_segments(struct request_queue *, unsigned short); | 929 | extern void blk_queue_max_phys_segments(struct request_queue *, unsigned short); |
| 930 | extern void blk_queue_max_hw_segments(struct request_queue *, unsigned short); | 930 | extern void blk_queue_max_hw_segments(struct request_queue *, unsigned short); |
| 931 | extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); | 931 | extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); |
| 932 | extern void blk_queue_max_discard_sectors(struct request_queue *q, | ||
| 933 | unsigned int max_discard_sectors); | ||
| 932 | extern void blk_queue_logical_block_size(struct request_queue *, unsigned short); | 934 | extern void blk_queue_logical_block_size(struct request_queue *, unsigned short); |
| 933 | extern void blk_queue_physical_block_size(struct request_queue *, unsigned short); | 935 | extern void blk_queue_physical_block_size(struct request_queue *, unsigned short); |
| 934 | extern void blk_queue_alignment_offset(struct request_queue *q, | 936 | extern void blk_queue_alignment_offset(struct request_queue *q, |
| @@ -955,7 +957,6 @@ extern void blk_queue_merge_bvec(struct request_queue *, merge_bvec_fn *); | |||
| 955 | extern void blk_queue_dma_alignment(struct request_queue *, int); | 957 | extern void blk_queue_dma_alignment(struct request_queue *, int); |
| 956 | extern void blk_queue_update_dma_alignment(struct request_queue *, int); | 958 | extern void blk_queue_update_dma_alignment(struct request_queue *, int); |
| 957 | extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *); | 959 | extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *); |
| 958 | extern void blk_queue_set_discard(struct request_queue *, prepare_discard_fn *); | ||
| 959 | extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *); | 960 | extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *); |
| 960 | extern void blk_queue_rq_timeout(struct request_queue *, unsigned int); | 961 | extern void blk_queue_rq_timeout(struct request_queue *, unsigned int); |
| 961 | extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); | 962 | extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); |
| @@ -1080,25 +1081,37 @@ static inline unsigned int queue_physical_block_size(struct request_queue *q) | |||
| 1080 | return q->limits.physical_block_size; | 1081 | return q->limits.physical_block_size; |
| 1081 | } | 1082 | } |
| 1082 | 1083 | ||
| 1084 | static inline int bdev_physical_block_size(struct block_device *bdev) | ||
| 1085 | { | ||
| 1086 | return queue_physical_block_size(bdev_get_queue(bdev)); | ||
| 1087 | } | ||
| 1088 | |||
| 1083 | static inline unsigned int queue_io_min(struct request_queue *q) | 1089 | static inline unsigned int queue_io_min(struct request_queue *q) |
| 1084 | { | 1090 | { |
| 1085 | return q->limits.io_min; | 1091 | return q->limits.io_min; |
| 1086 | } | 1092 | } |
| 1087 | 1093 | ||
| 1094 | static inline int bdev_io_min(struct block_device *bdev) | ||
| 1095 | { | ||
| 1096 | return queue_io_min(bdev_get_queue(bdev)); | ||
| 1097 | } | ||
| 1098 | |||
| 1088 | static inline unsigned int queue_io_opt(struct request_queue *q) | 1099 | static inline unsigned int queue_io_opt(struct request_queue *q) |
| 1089 | { | 1100 | { |
| 1090 | return q->limits.io_opt; | 1101 | return q->limits.io_opt; |
| 1091 | } | 1102 | } |
| 1092 | 1103 | ||
| 1104 | static inline int bdev_io_opt(struct block_device *bdev) | ||
| 1105 | { | ||
| 1106 | return queue_io_opt(bdev_get_queue(bdev)); | ||
| 1107 | } | ||
| 1108 | |||
| 1093 | static inline int queue_alignment_offset(struct request_queue *q) | 1109 | static inline int queue_alignment_offset(struct request_queue *q) |
| 1094 | { | 1110 | { |
| 1095 | if (q && q->limits.misaligned) | 1111 | if (q->limits.misaligned) |
| 1096 | return -1; | 1112 | return -1; |
| 1097 | 1113 | ||
| 1098 | if (q && q->limits.alignment_offset) | 1114 | return q->limits.alignment_offset; |
| 1099 | return q->limits.alignment_offset; | ||
| 1100 | |||
| 1101 | return 0; | ||
| 1102 | } | 1115 | } |
| 1103 | 1116 | ||
| 1104 | static inline int queue_sector_alignment_offset(struct request_queue *q, | 1117 | static inline int queue_sector_alignment_offset(struct request_queue *q, |
| @@ -1108,6 +1121,19 @@ static inline int queue_sector_alignment_offset(struct request_queue *q, | |||
| 1108 | & (q->limits.io_min - 1); | 1121 | & (q->limits.io_min - 1); |
| 1109 | } | 1122 | } |
| 1110 | 1123 | ||
| 1124 | static inline int bdev_alignment_offset(struct block_device *bdev) | ||
| 1125 | { | ||
| 1126 | struct request_queue *q = bdev_get_queue(bdev); | ||
| 1127 | |||
| 1128 | if (q->limits.misaligned) | ||
| 1129 | return -1; | ||
| 1130 | |||
| 1131 | if (bdev != bdev->bd_contains) | ||
| 1132 | return bdev->bd_part->alignment_offset; | ||
| 1133 | |||
| 1134 | return q->limits.alignment_offset; | ||
| 1135 | } | ||
| 1136 | |||
| 1111 | static inline int queue_dma_alignment(struct request_queue *q) | 1137 | static inline int queue_dma_alignment(struct request_queue *q) |
| 1112 | { | 1138 | { |
| 1113 | return q ? q->dma_alignment : 511; | 1139 | return q ? q->dma_alignment : 511; |
| @@ -1146,7 +1172,11 @@ static inline void put_dev_sector(Sector p) | |||
| 1146 | } | 1172 | } |
| 1147 | 1173 | ||
| 1148 | struct work_struct; | 1174 | struct work_struct; |
| 1175 | struct delayed_work; | ||
| 1149 | int kblockd_schedule_work(struct request_queue *q, struct work_struct *work); | 1176 | int kblockd_schedule_work(struct request_queue *q, struct work_struct *work); |
| 1177 | int kblockd_schedule_delayed_work(struct request_queue *q, | ||
| 1178 | struct delayed_work *work, | ||
| 1179 | unsigned long delay); | ||
| 1150 | 1180 | ||
| 1151 | #define MODULE_ALIAS_BLOCKDEV(major,minor) \ | 1181 | #define MODULE_ALIAS_BLOCKDEV(major,minor) \ |
| 1152 | MODULE_ALIAS("block-major-" __stringify(major) "-" __stringify(minor)) | 1182 | MODULE_ALIAS("block-major-" __stringify(major) "-" __stringify(minor)) |
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index 7e4350ece0f8..3b73b9992b26 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h | |||
| @@ -198,6 +198,7 @@ extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, | |||
| 198 | char __user *arg); | 198 | char __user *arg); |
| 199 | extern int blk_trace_startstop(struct request_queue *q, int start); | 199 | extern int blk_trace_startstop(struct request_queue *q, int start); |
| 200 | extern int blk_trace_remove(struct request_queue *q); | 200 | extern int blk_trace_remove(struct request_queue *q); |
| 201 | extern void blk_trace_remove_sysfs(struct device *dev); | ||
| 201 | extern int blk_trace_init_sysfs(struct device *dev); | 202 | extern int blk_trace_init_sysfs(struct device *dev); |
| 202 | 203 | ||
| 203 | extern struct attribute_group blk_trace_attr_group; | 204 | extern struct attribute_group blk_trace_attr_group; |
| @@ -211,6 +212,7 @@ extern struct attribute_group blk_trace_attr_group; | |||
| 211 | # define blk_trace_startstop(q, start) (-ENOTTY) | 212 | # define blk_trace_startstop(q, start) (-ENOTTY) |
| 212 | # define blk_trace_remove(q) (-ENOTTY) | 213 | # define blk_trace_remove(q) (-ENOTTY) |
| 213 | # define blk_add_trace_msg(q, fmt, ...) do { } while (0) | 214 | # define blk_add_trace_msg(q, fmt, ...) do { } while (0) |
| 215 | # define blk_trace_remove_sysfs(dev) do { } while (0) | ||
| 214 | static inline int blk_trace_init_sysfs(struct device *dev) | 216 | static inline int blk_trace_init_sysfs(struct device *dev) |
| 215 | { | 217 | { |
| 216 | return 0; | 218 | return 0; |
diff --git a/include/linux/fs.h b/include/linux/fs.h index a1e6899d4b6c..2620a8c63571 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -300,6 +300,10 @@ struct inodes_stat_t { | |||
| 300 | #define BLKTRACESTOP _IO(0x12,117) | 300 | #define BLKTRACESTOP _IO(0x12,117) |
| 301 | #define BLKTRACETEARDOWN _IO(0x12,118) | 301 | #define BLKTRACETEARDOWN _IO(0x12,118) |
| 302 | #define BLKDISCARD _IO(0x12,119) | 302 | #define BLKDISCARD _IO(0x12,119) |
| 303 | #define BLKIOMIN _IO(0x12,120) | ||
| 304 | #define BLKIOOPT _IO(0x12,121) | ||
| 305 | #define BLKALIGNOFF _IO(0x12,122) | ||
| 306 | #define BLKPBSZGET _IO(0x12,123) | ||
| 303 | 307 | ||
| 304 | #define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ | 308 | #define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ |
| 305 | #define FIBMAP _IO(0x00,1) /* bmap access */ | 309 | #define FIBMAP _IO(0x00,1) /* bmap access */ |
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 297df45ffd0a..7beaa21b3880 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
| @@ -98,7 +98,7 @@ struct hd_struct { | |||
| 98 | int make_it_fail; | 98 | int make_it_fail; |
| 99 | #endif | 99 | #endif |
| 100 | unsigned long stamp; | 100 | unsigned long stamp; |
| 101 | int in_flight[2]; | 101 | int in_flight; |
| 102 | #ifdef CONFIG_SMP | 102 | #ifdef CONFIG_SMP |
| 103 | struct disk_stats *dkstats; | 103 | struct disk_stats *dkstats; |
| 104 | #else | 104 | #else |
| @@ -322,23 +322,18 @@ static inline void free_part_stats(struct hd_struct *part) | |||
| 322 | #define part_stat_sub(cpu, gendiskp, field, subnd) \ | 322 | #define part_stat_sub(cpu, gendiskp, field, subnd) \ |
| 323 | part_stat_add(cpu, gendiskp, field, -subnd) | 323 | part_stat_add(cpu, gendiskp, field, -subnd) |
| 324 | 324 | ||
| 325 | static inline void part_inc_in_flight(struct hd_struct *part, int rw) | 325 | static inline void part_inc_in_flight(struct hd_struct *part) |
| 326 | { | 326 | { |
| 327 | part->in_flight[rw]++; | 327 | part->in_flight++; |
| 328 | if (part->partno) | 328 | if (part->partno) |
| 329 | part_to_disk(part)->part0.in_flight[rw]++; | 329 | part_to_disk(part)->part0.in_flight++; |
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | static inline void part_dec_in_flight(struct hd_struct *part, int rw) | 332 | static inline void part_dec_in_flight(struct hd_struct *part) |
| 333 | { | 333 | { |
| 334 | part->in_flight[rw]--; | 334 | part->in_flight--; |
| 335 | if (part->partno) | 335 | if (part->partno) |
| 336 | part_to_disk(part)->part0.in_flight[rw]--; | 336 | part_to_disk(part)->part0.in_flight--; |
| 337 | } | ||
| 338 | |||
| 339 | static inline int part_in_flight(struct hd_struct *part) | ||
| 340 | { | ||
| 341 | return part->in_flight[0] + part->in_flight[1]; | ||
| 342 | } | 337 | } |
| 343 | 338 | ||
| 344 | /* block/blk-core.c */ | 339 | /* block/blk-core.c */ |
| @@ -551,8 +546,6 @@ extern ssize_t part_size_show(struct device *dev, | |||
| 551 | struct device_attribute *attr, char *buf); | 546 | struct device_attribute *attr, char *buf); |
| 552 | extern ssize_t part_stat_show(struct device *dev, | 547 | extern ssize_t part_stat_show(struct device *dev, |
| 553 | struct device_attribute *attr, char *buf); | 548 | struct device_attribute *attr, char *buf); |
| 554 | extern ssize_t part_inflight_show(struct device *dev, | ||
| 555 | struct device_attribute *attr, char *buf); | ||
| 556 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 549 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
| 557 | extern ssize_t part_fail_show(struct device *dev, | 550 | extern ssize_t part_fail_show(struct device *dev, |
| 558 | struct device_attribute *attr, char *buf); | 551 | struct device_attribute *attr, char *buf); |
diff --git a/include/linux/poll.h b/include/linux/poll.h index fa287f25138d..6673743946f7 100644 --- a/include/linux/poll.h +++ b/include/linux/poll.h | |||
| @@ -6,10 +6,10 @@ | |||
| 6 | #ifdef __KERNEL__ | 6 | #ifdef __KERNEL__ |
| 7 | 7 | ||
| 8 | #include <linux/compiler.h> | 8 | #include <linux/compiler.h> |
| 9 | #include <linux/ktime.h> | ||
| 9 | #include <linux/wait.h> | 10 | #include <linux/wait.h> |
| 10 | #include <linux/string.h> | 11 | #include <linux/string.h> |
| 11 | #include <linux/fs.h> | 12 | #include <linux/fs.h> |
| 12 | #include <linux/sched.h> | ||
| 13 | #include <asm/uaccess.h> | 13 | #include <asm/uaccess.h> |
| 14 | 14 | ||
| 15 | /* ~832 bytes of stack space used max in sys_select/sys_poll before allocating | 15 | /* ~832 bytes of stack space used max in sys_select/sys_poll before allocating |
diff --git a/include/trace/events/block.h b/include/trace/events/block.h index d86af94691c2..00405b5f624a 100644 --- a/include/trace/events/block.h +++ b/include/trace/events/block.h | |||
| @@ -488,6 +488,39 @@ TRACE_EVENT(block_remap, | |||
| 488 | (unsigned long long)__entry->old_sector) | 488 | (unsigned long long)__entry->old_sector) |
| 489 | ); | 489 | ); |
| 490 | 490 | ||
| 491 | TRACE_EVENT(block_rq_remap, | ||
| 492 | |||
| 493 | TP_PROTO(struct request_queue *q, struct request *rq, dev_t dev, | ||
| 494 | sector_t from), | ||
| 495 | |||
| 496 | TP_ARGS(q, rq, dev, from), | ||
| 497 | |||
| 498 | TP_STRUCT__entry( | ||
| 499 | __field( dev_t, dev ) | ||
| 500 | __field( sector_t, sector ) | ||
| 501 | __field( unsigned int, nr_sector ) | ||
| 502 | __field( dev_t, old_dev ) | ||
| 503 | __field( sector_t, old_sector ) | ||
| 504 | __array( char, rwbs, 6 ) | ||
| 505 | ), | ||
| 506 | |||
| 507 | TP_fast_assign( | ||
| 508 | __entry->dev = disk_devt(rq->rq_disk); | ||
| 509 | __entry->sector = blk_rq_pos(rq); | ||
| 510 | __entry->nr_sector = blk_rq_sectors(rq); | ||
| 511 | __entry->old_dev = dev; | ||
| 512 | __entry->old_sector = from; | ||
| 513 | blk_fill_rwbs_rq(__entry->rwbs, rq); | ||
| 514 | ), | ||
| 515 | |||
| 516 | TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu", | ||
| 517 | MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs, | ||
| 518 | (unsigned long long)__entry->sector, | ||
| 519 | __entry->nr_sector, | ||
| 520 | MAJOR(__entry->old_dev), MINOR(__entry->old_dev), | ||
| 521 | (unsigned long long)__entry->old_sector) | ||
| 522 | ); | ||
| 523 | |||
| 491 | #endif /* _TRACE_BLOCK_H */ | 524 | #endif /* _TRACE_BLOCK_H */ |
| 492 | 525 | ||
| 493 | /* This part must be outside protection */ | 526 | /* This part must be outside protection */ |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 6d7020490f94..3e1c36e7998f 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
| @@ -726,8 +726,6 @@ static int hrtimer_switch_to_hres(void) | |||
| 726 | /* "Retrigger" the interrupt to get things going */ | 726 | /* "Retrigger" the interrupt to get things going */ |
| 727 | retrigger_next_event(NULL); | 727 | retrigger_next_event(NULL); |
| 728 | local_irq_restore(flags); | 728 | local_irq_restore(flags); |
| 729 | printk(KERN_DEBUG "Switched to high resolution mode on CPU %d\n", | ||
| 730 | smp_processor_id()); | ||
| 731 | return 1; | 729 | return 1; |
| 732 | } | 730 | } |
| 733 | 731 | ||
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 0f86feb6db0c..e491fb087939 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
| @@ -1030,14 +1030,10 @@ void __perf_event_sched_out(struct perf_event_context *ctx, | |||
| 1030 | update_context_time(ctx); | 1030 | update_context_time(ctx); |
| 1031 | 1031 | ||
| 1032 | perf_disable(); | 1032 | perf_disable(); |
| 1033 | if (ctx->nr_active) { | 1033 | if (ctx->nr_active) |
| 1034 | list_for_each_entry(event, &ctx->group_list, group_entry) { | 1034 | list_for_each_entry(event, &ctx->group_list, group_entry) |
| 1035 | if (event != event->group_leader) | 1035 | group_sched_out(event, cpuctx, ctx); |
| 1036 | event_sched_out(event, cpuctx, ctx); | 1036 | |
| 1037 | else | ||
| 1038 | group_sched_out(event, cpuctx, ctx); | ||
| 1039 | } | ||
| 1040 | } | ||
| 1041 | perf_enable(); | 1037 | perf_enable(); |
| 1042 | out: | 1038 | out: |
| 1043 | spin_unlock(&ctx->lock); | 1039 | spin_unlock(&ctx->lock); |
| @@ -1258,12 +1254,8 @@ __perf_event_sched_in(struct perf_event_context *ctx, | |||
| 1258 | if (event->cpu != -1 && event->cpu != cpu) | 1254 | if (event->cpu != -1 && event->cpu != cpu) |
| 1259 | continue; | 1255 | continue; |
| 1260 | 1256 | ||
| 1261 | if (event != event->group_leader) | 1257 | if (group_can_go_on(event, cpuctx, 1)) |
| 1262 | event_sched_in(event, cpuctx, ctx, cpu); | 1258 | group_sched_in(event, cpuctx, ctx, cpu); |
| 1263 | else { | ||
| 1264 | if (group_can_go_on(event, cpuctx, 1)) | ||
| 1265 | group_sched_in(event, cpuctx, ctx, cpu); | ||
| 1266 | } | ||
| 1267 | 1259 | ||
| 1268 | /* | 1260 | /* |
| 1269 | * If this pinned group hasn't been scheduled, | 1261 | * If this pinned group hasn't been scheduled, |
| @@ -1291,15 +1283,9 @@ __perf_event_sched_in(struct perf_event_context *ctx, | |||
| 1291 | if (event->cpu != -1 && event->cpu != cpu) | 1283 | if (event->cpu != -1 && event->cpu != cpu) |
| 1292 | continue; | 1284 | continue; |
| 1293 | 1285 | ||
| 1294 | if (event != event->group_leader) { | 1286 | if (group_can_go_on(event, cpuctx, can_add_hw)) |
| 1295 | if (event_sched_in(event, cpuctx, ctx, cpu)) | 1287 | if (group_sched_in(event, cpuctx, ctx, cpu)) |
| 1296 | can_add_hw = 0; | 1288 | can_add_hw = 0; |
| 1297 | } else { | ||
| 1298 | if (group_can_go_on(event, cpuctx, can_add_hw)) { | ||
| 1299 | if (group_sched_in(event, cpuctx, ctx, cpu)) | ||
| 1300 | can_add_hw = 0; | ||
| 1301 | } | ||
| 1302 | } | ||
| 1303 | } | 1289 | } |
| 1304 | perf_enable(); | 1290 | perf_enable(); |
| 1305 | out: | 1291 | out: |
| @@ -4781,9 +4767,7 @@ int perf_event_init_task(struct task_struct *child) | |||
| 4781 | * We dont have to disable NMIs - we are only looking at | 4767 | * We dont have to disable NMIs - we are only looking at |
| 4782 | * the list, not manipulating it: | 4768 | * the list, not manipulating it: |
| 4783 | */ | 4769 | */ |
| 4784 | list_for_each_entry_rcu(event, &parent_ctx->event_list, event_entry) { | 4770 | list_for_each_entry(event, &parent_ctx->group_list, group_entry) { |
| 4785 | if (event != event->group_leader) | ||
| 4786 | continue; | ||
| 4787 | 4771 | ||
| 4788 | if (!event->attr.inherit) { | 4772 | if (!event->attr.inherit) { |
| 4789 | inherited_all = 0; | 4773 | inherited_all = 0; |
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 3eb159c277c8..d9d6206e0b14 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c | |||
| @@ -856,6 +856,37 @@ static void blk_add_trace_remap(struct request_queue *q, struct bio *bio, | |||
| 856 | } | 856 | } |
| 857 | 857 | ||
| 858 | /** | 858 | /** |
| 859 | * blk_add_trace_rq_remap - Add a trace for a request-remap operation | ||
| 860 | * @q: queue the io is for | ||
| 861 | * @rq: the source request | ||
| 862 | * @dev: target device | ||
| 863 | * @from: source sector | ||
| 864 | * | ||
| 865 | * Description: | ||
| 866 | * Device mapper remaps request to other devices. | ||
| 867 | * Add a trace for that action. | ||
| 868 | * | ||
| 869 | **/ | ||
| 870 | static void blk_add_trace_rq_remap(struct request_queue *q, | ||
| 871 | struct request *rq, dev_t dev, | ||
| 872 | sector_t from) | ||
| 873 | { | ||
| 874 | struct blk_trace *bt = q->blk_trace; | ||
| 875 | struct blk_io_trace_remap r; | ||
| 876 | |||
| 877 | if (likely(!bt)) | ||
| 878 | return; | ||
| 879 | |||
| 880 | r.device_from = cpu_to_be32(dev); | ||
| 881 | r.device_to = cpu_to_be32(disk_devt(rq->rq_disk)); | ||
| 882 | r.sector_from = cpu_to_be64(from); | ||
| 883 | |||
| 884 | __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq), | ||
| 885 | rq_data_dir(rq), BLK_TA_REMAP, !!rq->errors, | ||
| 886 | sizeof(r), &r); | ||
| 887 | } | ||
| 888 | |||
| 889 | /** | ||
| 859 | * blk_add_driver_data - Add binary message with driver-specific data | 890 | * blk_add_driver_data - Add binary message with driver-specific data |
| 860 | * @q: queue the io is for | 891 | * @q: queue the io is for |
| 861 | * @rq: io request | 892 | * @rq: io request |
| @@ -922,10 +953,13 @@ static void blk_register_tracepoints(void) | |||
| 922 | WARN_ON(ret); | 953 | WARN_ON(ret); |
| 923 | ret = register_trace_block_remap(blk_add_trace_remap); | 954 | ret = register_trace_block_remap(blk_add_trace_remap); |
| 924 | WARN_ON(ret); | 955 | WARN_ON(ret); |
| 956 | ret = register_trace_block_rq_remap(blk_add_trace_rq_remap); | ||
| 957 | WARN_ON(ret); | ||
| 925 | } | 958 | } |
| 926 | 959 | ||
| 927 | static void blk_unregister_tracepoints(void) | 960 | static void blk_unregister_tracepoints(void) |
| 928 | { | 961 | { |
| 962 | unregister_trace_block_rq_remap(blk_add_trace_rq_remap); | ||
| 929 | unregister_trace_block_remap(blk_add_trace_remap); | 963 | unregister_trace_block_remap(blk_add_trace_remap); |
| 930 | unregister_trace_block_split(blk_add_trace_split); | 964 | unregister_trace_block_split(blk_add_trace_split); |
| 931 | unregister_trace_block_unplug_io(blk_add_trace_unplug_io); | 965 | unregister_trace_block_unplug_io(blk_add_trace_unplug_io); |
| @@ -1657,6 +1691,11 @@ int blk_trace_init_sysfs(struct device *dev) | |||
| 1657 | return sysfs_create_group(&dev->kobj, &blk_trace_attr_group); | 1691 | return sysfs_create_group(&dev->kobj, &blk_trace_attr_group); |
| 1658 | } | 1692 | } |
| 1659 | 1693 | ||
| 1694 | void blk_trace_remove_sysfs(struct device *dev) | ||
| 1695 | { | ||
| 1696 | sysfs_remove_group(&dev->kobj, &blk_trace_attr_group); | ||
| 1697 | } | ||
| 1698 | |||
| 1660 | #endif /* CONFIG_BLK_DEV_IO_TRACE */ | 1699 | #endif /* CONFIG_BLK_DEV_IO_TRACE */ |
| 1661 | 1700 | ||
| 1662 | #ifdef CONFIG_EVENT_TRACING | 1701 | #ifdef CONFIG_EVENT_TRACING |
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 46592feab5a6..3724756e41ca 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
| @@ -225,7 +225,11 @@ static void ftrace_update_pid_func(void) | |||
| 225 | if (ftrace_trace_function == ftrace_stub) | 225 | if (ftrace_trace_function == ftrace_stub) |
| 226 | return; | 226 | return; |
| 227 | 227 | ||
| 228 | #ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST | ||
| 228 | func = ftrace_trace_function; | 229 | func = ftrace_trace_function; |
| 230 | #else | ||
| 231 | func = __ftrace_trace_function; | ||
| 232 | #endif | ||
| 229 | 233 | ||
| 230 | if (ftrace_pid_trace) { | 234 | if (ftrace_pid_trace) { |
| 231 | set_ftrace_pid_function(func); | 235 | set_ftrace_pid_function(func); |
diff --git a/kernel/trace/kmemtrace.c b/kernel/trace/kmemtrace.c index 81b1645c8549..a91da69f153a 100644 --- a/kernel/trace/kmemtrace.c +++ b/kernel/trace/kmemtrace.c | |||
| @@ -501,7 +501,7 @@ static int __init init_kmem_tracer(void) | |||
| 501 | return 1; | 501 | return 1; |
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | if (!register_tracer(&kmem_tracer)) { | 504 | if (register_tracer(&kmem_tracer) != 0) { |
| 505 | pr_warning("Warning: could not register the kmem tracer\n"); | 505 | pr_warning("Warning: could not register the kmem tracer\n"); |
| 506 | return 1; | 506 | return 1; |
| 507 | } | 507 | } |
diff --git a/mm/swapfile.c b/mm/swapfile.c index 4de7f02f820b..a1bc6b9af9a2 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
| @@ -1974,12 +1974,14 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) | |||
| 1974 | goto bad_swap; | 1974 | goto bad_swap; |
| 1975 | } | 1975 | } |
| 1976 | 1976 | ||
| 1977 | if (blk_queue_nonrot(bdev_get_queue(p->bdev))) { | 1977 | if (p->bdev) { |
| 1978 | p->flags |= SWP_SOLIDSTATE; | 1978 | if (blk_queue_nonrot(bdev_get_queue(p->bdev))) { |
| 1979 | p->cluster_next = 1 + (random32() % p->highest_bit); | 1979 | p->flags |= SWP_SOLIDSTATE; |
| 1980 | p->cluster_next = 1 + (random32() % p->highest_bit); | ||
| 1981 | } | ||
| 1982 | if (discard_swap(p) == 0) | ||
| 1983 | p->flags |= SWP_DISCARDABLE; | ||
| 1980 | } | 1984 | } |
| 1981 | if (discard_swap(p) == 0) | ||
| 1982 | p->flags |= SWP_DISCARDABLE; | ||
| 1983 | 1985 | ||
| 1984 | mutex_lock(&swapon_mutex); | 1986 | mutex_lock(&swapon_mutex); |
| 1985 | spin_lock(&swap_lock); | 1987 | spin_lock(&swap_lock); |
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index dbeaf2983822..ba2efb960c60 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/list.h> | 27 | #include <linux/list.h> |
| 28 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
| 29 | #include <linux/rfkill.h> | 29 | #include <linux/rfkill.h> |
| 30 | #include <linux/sched.h> | ||
| 30 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
| 31 | #include <linux/miscdevice.h> | 32 | #include <linux/miscdevice.h> |
| 32 | #include <linux/wait.h> | 33 | #include <linux/wait.h> |
diff --git a/tools/perf/Documentation/perf-timechart.txt b/tools/perf/Documentation/perf-timechart.txt index 1c2ed3090cce..a7910099d6fd 100644 --- a/tools/perf/Documentation/perf-timechart.txt +++ b/tools/perf/Documentation/perf-timechart.txt | |||
| @@ -31,6 +31,9 @@ OPTIONS | |||
| 31 | -w:: | 31 | -w:: |
| 32 | --width=:: | 32 | --width=:: |
| 33 | Select the width of the SVG file (default: 1000) | 33 | Select the width of the SVG file (default: 1000) |
| 34 | -p:: | ||
| 35 | --power-only:: | ||
| 36 | Only output the CPU power section of the diagram | ||
| 34 | 37 | ||
| 35 | 38 | ||
| 36 | SEE ALSO | 39 | SEE ALSO |
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index b5f1953b6144..5881943f0c34 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
| @@ -728,7 +728,7 @@ $(BUILT_INS): perf$X | |||
| 728 | common-cmds.h: util/generate-cmdlist.sh command-list.txt | 728 | common-cmds.h: util/generate-cmdlist.sh command-list.txt |
| 729 | 729 | ||
| 730 | common-cmds.h: $(wildcard Documentation/perf-*.txt) | 730 | common-cmds.h: $(wildcard Documentation/perf-*.txt) |
| 731 | $(QUIET_GEN)util/generate-cmdlist.sh > $@+ && mv $@+ $@ | 731 | $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@ |
| 732 | 732 | ||
| 733 | $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh | 733 | $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh |
| 734 | $(QUIET_GEN)$(RM) $@ $@+ && \ | 734 | $(QUIET_GEN)$(RM) $@ $@+ && \ |
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 4405681b3134..702d8fe58fbc 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c | |||
| @@ -46,6 +46,8 @@ static u64 turbo_frequency; | |||
| 46 | 46 | ||
| 47 | static u64 first_time, last_time; | 47 | static u64 first_time, last_time; |
| 48 | 48 | ||
| 49 | static int power_only; | ||
| 50 | |||
| 49 | 51 | ||
| 50 | static struct perf_header *header; | 52 | static struct perf_header *header; |
| 51 | 53 | ||
| @@ -547,7 +549,7 @@ static void end_sample_processing(void) | |||
| 547 | u64 cpu; | 549 | u64 cpu; |
| 548 | struct power_event *pwr; | 550 | struct power_event *pwr; |
| 549 | 551 | ||
| 550 | for (cpu = 0; cpu < numcpus; cpu++) { | 552 | for (cpu = 0; cpu <= numcpus; cpu++) { |
| 551 | pwr = malloc(sizeof(struct power_event)); | 553 | pwr = malloc(sizeof(struct power_event)); |
| 552 | if (!pwr) | 554 | if (!pwr) |
| 553 | return; | 555 | return; |
| @@ -871,7 +873,7 @@ static int determine_display_tasks(u64 threshold) | |||
| 871 | /* no exit marker, task kept running to the end */ | 873 | /* no exit marker, task kept running to the end */ |
| 872 | if (p->end_time == 0) | 874 | if (p->end_time == 0) |
| 873 | p->end_time = last_time; | 875 | p->end_time = last_time; |
| 874 | if (p->total_time >= threshold) | 876 | if (p->total_time >= threshold && !power_only) |
| 875 | p->display = 1; | 877 | p->display = 1; |
| 876 | 878 | ||
| 877 | c = p->all; | 879 | c = p->all; |
| @@ -882,7 +884,7 @@ static int determine_display_tasks(u64 threshold) | |||
| 882 | if (c->start_time == 1) | 884 | if (c->start_time == 1) |
| 883 | c->start_time = first_time; | 885 | c->start_time = first_time; |
| 884 | 886 | ||
| 885 | if (c->total_time >= threshold) { | 887 | if (c->total_time >= threshold && !power_only) { |
| 886 | c->display = 1; | 888 | c->display = 1; |
| 887 | count++; | 889 | count++; |
| 888 | } | 890 | } |
| @@ -1134,6 +1136,8 @@ static const struct option options[] = { | |||
| 1134 | "output file name"), | 1136 | "output file name"), |
| 1135 | OPT_INTEGER('w', "width", &svg_page_width, | 1137 | OPT_INTEGER('w', "width", &svg_page_width, |
| 1136 | "page width"), | 1138 | "page width"), |
| 1139 | OPT_BOOLEAN('p', "power-only", &power_only, | ||
| 1140 | "output power data only"), | ||
| 1137 | OPT_END() | 1141 | OPT_END() |
| 1138 | }; | 1142 | }; |
| 1139 | 1143 | ||
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 1ca88896eee4..37512e936235 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
| @@ -782,6 +782,7 @@ static const char *skip_symbols[] = { | |||
| 782 | "exit_idle", | 782 | "exit_idle", |
| 783 | "mwait_idle", | 783 | "mwait_idle", |
| 784 | "mwait_idle_with_hints", | 784 | "mwait_idle_with_hints", |
| 785 | "poll_idle", | ||
| 785 | "ppc64_runlatch_off", | 786 | "ppc64_runlatch_off", |
| 786 | "pseries_dedicated_idle_sleep", | 787 | "pseries_dedicated_idle_sleep", |
| 787 | NULL | 788 | NULL |
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index a778fd0f4ae4..856655d8b0b8 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c | |||
| @@ -28,7 +28,7 @@ static u64 turbo_frequency, max_freq; | |||
| 28 | 28 | ||
| 29 | int svg_page_width = 1000; | 29 | int svg_page_width = 1000; |
| 30 | 30 | ||
| 31 | #define MIN_TEXT_SIZE 0.001 | 31 | #define MIN_TEXT_SIZE 0.01 |
| 32 | 32 | ||
| 33 | static u64 total_height; | 33 | static u64 total_height; |
| 34 | static FILE *svgfile; | 34 | static FILE *svgfile; |
| @@ -217,6 +217,18 @@ static char *cpu_model(void) | |||
| 217 | } | 217 | } |
| 218 | fclose(file); | 218 | fclose(file); |
| 219 | } | 219 | } |
| 220 | |||
| 221 | /* CPU type */ | ||
| 222 | file = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies", "r"); | ||
| 223 | if (file) { | ||
| 224 | while (fgets(buf, 255, file)) { | ||
| 225 | unsigned int freq; | ||
| 226 | freq = strtoull(buf, NULL, 10); | ||
| 227 | if (freq > max_freq) | ||
| 228 | max_freq = freq; | ||
| 229 | } | ||
| 230 | fclose(file); | ||
| 231 | } | ||
| 220 | return cpu_m; | 232 | return cpu_m; |
| 221 | } | 233 | } |
| 222 | 234 | ||
