diff options
435 files changed, 8858 insertions, 4139 deletions
| @@ -369,10 +369,10 @@ P: 1024/8462A731 4C 55 86 34 44 59 A7 99 2B 97 88 4A 88 9A 0D 97 | |||
| 369 | D: sun4 port, Sparc hacker | 369 | D: sun4 port, Sparc hacker |
| 370 | 370 | ||
| 371 | N: Hugh Blemings | 371 | N: Hugh Blemings |
| 372 | E: hugh@misc.nu | 372 | E: hugh@blemings.org |
| 373 | W: http://misc.nu/hugh/ | 373 | W: http://blemings.org/hugh |
| 374 | D: Author and maintainer of the Keyspan USB to Serial drivers | 374 | D: Original author of the Keyspan USB to serial drivers, random PowerPC hacker |
| 375 | S: Po Box 234 | 375 | S: PO Box 234 |
| 376 | S: Belconnen ACT 2616 | 376 | S: Belconnen ACT 2616 |
| 377 | S: Australia | 377 | S: Australia |
| 378 | 378 | ||
diff --git a/Documentation/cputopology.txt b/Documentation/cputopology.txt index bd699da24666..45932ec21cee 100644 --- a/Documentation/cputopology.txt +++ b/Documentation/cputopology.txt | |||
| @@ -31,3 +31,51 @@ not defined by include/asm-XXX/topology.h: | |||
| 31 | 2) core_id: 0 | 31 | 2) core_id: 0 |
| 32 | 3) thread_siblings: just the given CPU | 32 | 3) thread_siblings: just the given CPU |
| 33 | 4) core_siblings: just the given CPU | 33 | 4) core_siblings: just the given CPU |
| 34 | |||
| 35 | Additionally, cpu topology information is provided under | ||
| 36 | /sys/devices/system/cpu and includes these files. The internal | ||
| 37 | source for the output is in brackets ("[]"). | ||
| 38 | |||
| 39 | kernel_max: the maximum cpu index allowed by the kernel configuration. | ||
| 40 | [NR_CPUS-1] | ||
| 41 | |||
| 42 | offline: cpus that are not online because they have been | ||
| 43 | HOTPLUGGED off (see cpu-hotplug.txt) or exceed the limit | ||
| 44 | of cpus allowed by the kernel configuration (kernel_max | ||
| 45 | above). [~cpu_online_mask + cpus >= NR_CPUS] | ||
| 46 | |||
| 47 | online: cpus that are online and being scheduled [cpu_online_mask] | ||
| 48 | |||
| 49 | possible: cpus that have been allocated resources and can be | ||
| 50 | brought online if they are present. [cpu_possible_mask] | ||
| 51 | |||
| 52 | present: cpus that have been identified as being present in the | ||
| 53 | system. [cpu_present_mask] | ||
| 54 | |||
| 55 | The format for the above output is compatible with cpulist_parse() | ||
| 56 | [see <linux/cpumask.h>]. Some examples follow. | ||
| 57 | |||
| 58 | In this example, there are 64 cpus in the system but cpus 32-63 exceed | ||
| 59 | the kernel max which is limited to 0..31 by the NR_CPUS config option | ||
| 60 | being 32. Note also that cpus 2 and 4-31 are not online but could be | ||
| 61 | brought online as they are both present and possible. | ||
| 62 | |||
| 63 | kernel_max: 31 | ||
| 64 | offline: 2,4-31,32-63 | ||
| 65 | online: 0-1,3 | ||
| 66 | possible: 0-31 | ||
| 67 | present: 0-31 | ||
| 68 | |||
| 69 | In this example, the NR_CPUS config option is 128, but the kernel was | ||
| 70 | started with possible_cpus=144. There are 4 cpus in the system and cpu2 | ||
| 71 | was manually taken offline (and is the only cpu that can be brought | ||
| 72 | online.) | ||
| 73 | |||
| 74 | kernel_max: 127 | ||
| 75 | offline: 2,4-127,128-143 | ||
| 76 | online: 0-1,3 | ||
| 77 | possible: 0-127 | ||
| 78 | present: 0-3 | ||
| 79 | |||
| 80 | See cpu-hotplug.txt for the possible_cpus=NUM kernel start parameter | ||
| 81 | as well as more information on the various cpumask's. | ||
diff --git a/Documentation/filesystems/ubifs.txt b/Documentation/filesystems/ubifs.txt index dd84ea3c10da..84da2a4ba25a 100644 --- a/Documentation/filesystems/ubifs.txt +++ b/Documentation/filesystems/ubifs.txt | |||
| @@ -95,6 +95,9 @@ no_chk_data_crc skip checking of CRCs on data nodes in order to | |||
| 95 | of this option is that corruption of the contents | 95 | of this option is that corruption of the contents |
| 96 | of a file can go unnoticed. | 96 | of a file can go unnoticed. |
| 97 | chk_data_crc (*) do not skip checking CRCs on data nodes | 97 | chk_data_crc (*) do not skip checking CRCs on data nodes |
| 98 | compr=none override default compressor and set it to "none" | ||
| 99 | compr=lzo override default compressor and set it to "lzo" | ||
| 100 | compr=zlib override default compressor and set it to "zlib" | ||
| 98 | 101 | ||
| 99 | 102 | ||
| 100 | Quick usage instructions | 103 | Quick usage instructions |
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt index b880ce5dbd33..824699174436 100644 --- a/Documentation/ioctl/ioctl-number.txt +++ b/Documentation/ioctl/ioctl-number.txt | |||
| @@ -97,6 +97,7 @@ Code Seq# Include File Comments | |||
| 97 | <http://linux01.gwdg.de/~alatham/ppdd.html> | 97 | <http://linux01.gwdg.de/~alatham/ppdd.html> |
| 98 | 'M' all linux/soundcard.h | 98 | 'M' all linux/soundcard.h |
| 99 | 'N' 00-1F drivers/usb/scanner.h | 99 | 'N' 00-1F drivers/usb/scanner.h |
| 100 | 'O' 00-02 include/mtd/ubi-user.h UBI | ||
| 100 | 'P' all linux/soundcard.h | 101 | 'P' all linux/soundcard.h |
| 101 | 'Q' all linux/soundcard.h | 102 | 'Q' all linux/soundcard.h |
| 102 | 'R' 00-1F linux/random.h | 103 | 'R' 00-1F linux/random.h |
| @@ -142,6 +143,9 @@ Code Seq# Include File Comments | |||
| 142 | 'n' 00-7F linux/ncp_fs.h | 143 | 'n' 00-7F linux/ncp_fs.h |
| 143 | 'n' E0-FF video/matrox.h matroxfb | 144 | 'n' E0-FF video/matrox.h matroxfb |
| 144 | 'o' 00-1F fs/ocfs2/ocfs2_fs.h OCFS2 | 145 | 'o' 00-1F fs/ocfs2/ocfs2_fs.h OCFS2 |
| 146 | 'o' 00-03 include/mtd/ubi-user.h conflict! (OCFS2 and UBI overlaps) | ||
| 147 | 'o' 40-41 include/mtd/ubi-user.h UBI | ||
| 148 | 'o' 01-A1 include/linux/dvb/*.h DVB | ||
| 145 | 'p' 00-0F linux/phantom.h conflict! (OpenHaptics needs this) | 149 | 'p' 00-0F linux/phantom.h conflict! (OpenHaptics needs this) |
| 146 | 'p' 00-3F linux/mc146818rtc.h conflict! | 150 | 'p' 00-3F linux/mc146818rtc.h conflict! |
| 147 | 'p' 40-7F linux/nvram.h | 151 | 'p' 40-7F linux/nvram.h |
diff --git a/Documentation/kbuild/00-INDEX b/Documentation/kbuild/00-INDEX index 114644285454..e8d2b6d83a3d 100644 --- a/Documentation/kbuild/00-INDEX +++ b/Documentation/kbuild/00-INDEX | |||
| @@ -1,5 +1,9 @@ | |||
| 1 | 00-INDEX | 1 | 00-INDEX |
| 2 | - this file: info on the kernel build process | 2 | - this file: info on the kernel build process |
| 3 | kbuild.txt | ||
| 4 | - developer information on kbuild | ||
| 5 | kconfig.txt | ||
| 6 | - usage help for make *config | ||
| 3 | kconfig-language.txt | 7 | kconfig-language.txt |
| 4 | - specification of Config Language, the language in Kconfig files | 8 | - specification of Config Language, the language in Kconfig files |
| 5 | makefiles.txt | 9 | makefiles.txt |
diff --git a/Documentation/kbuild/kbuild.txt b/Documentation/kbuild/kbuild.txt new file mode 100644 index 000000000000..51771847e816 --- /dev/null +++ b/Documentation/kbuild/kbuild.txt | |||
| @@ -0,0 +1,126 @@ | |||
| 1 | Environment variables | ||
| 2 | |||
| 3 | KCPPFLAGS | ||
| 4 | -------------------------------------------------- | ||
| 5 | Additional options to pass when preprocessing. The preprocessing options | ||
| 6 | will be used in all cases where kbuild do preprocessing including | ||
| 7 | building C files and assembler files. | ||
| 8 | |||
| 9 | KAFLAGS | ||
| 10 | -------------------------------------------------- | ||
| 11 | Additional options to the assembler. | ||
| 12 | |||
| 13 | KCFLAGS | ||
| 14 | -------------------------------------------------- | ||
| 15 | Additional options to the C compiler. | ||
| 16 | |||
| 17 | KBUILD_VERBOSE | ||
| 18 | -------------------------------------------------- | ||
| 19 | Set the kbuild verbosity. Can be assinged same values as "V=...". | ||
| 20 | See make help for the full list. | ||
| 21 | Setting "V=..." takes precedence over KBUILD_VERBOSE. | ||
| 22 | |||
| 23 | KBUILD_EXTMOD | ||
| 24 | -------------------------------------------------- | ||
| 25 | Set the directory to look for the kernel source when building external | ||
| 26 | modules. | ||
| 27 | The directory can be specified in several ways: | ||
| 28 | 1) Use "M=..." on the command line | ||
| 29 | 2) Environmnet variable KBUILD_EXTMOD | ||
| 30 | 3) Environmnet variable SUBDIRS | ||
| 31 | The possibilities are listed in the order they take precedence. | ||
| 32 | Using "M=..." will always override the others. | ||
| 33 | |||
| 34 | KBUILD_OUTPUT | ||
| 35 | -------------------------------------------------- | ||
| 36 | Specify the output directory when building the kernel. | ||
| 37 | The output directory can also be specificed using "O=...". | ||
| 38 | Setting "O=..." takes precedence over KBUILD_OUTPUT | ||
| 39 | |||
| 40 | ARCH | ||
| 41 | -------------------------------------------------- | ||
| 42 | Set ARCH to the architecture to be built. | ||
| 43 | In most cases the name of the architecture is the same as the | ||
| 44 | directory name found in the arch/ directory. | ||
| 45 | But some architectures suach as x86 and sparc has aliases. | ||
| 46 | x86: i386 for 32 bit, x86_64 for 64 bit | ||
| 47 | sparc: sparc for 32 bit, sparc64 for 64 bit | ||
| 48 | |||
| 49 | CROSS_COMPILE | ||
| 50 | -------------------------------------------------- | ||
| 51 | Specify an optional fixed part of the binutils filename. | ||
| 52 | CROSS_COMPILE can be a part of the filename or the full path. | ||
| 53 | |||
| 54 | CROSS_COMPILE is also used for ccache is some setups. | ||
| 55 | |||
| 56 | CF | ||
| 57 | -------------------------------------------------- | ||
| 58 | Additional options for sparse. | ||
| 59 | CF is often used on the command-line like this: | ||
| 60 | |||
| 61 | make CF=-Wbitwise C=2 | ||
| 62 | |||
| 63 | INSTALL_PATH | ||
| 64 | -------------------------------------------------- | ||
| 65 | INSTALL_PATH specifies where to place the updated kernel and system map | ||
| 66 | images. Default is /boot, but you can set it to other values | ||
| 67 | |||
| 68 | |||
| 69 | MODLIB | ||
| 70 | -------------------------------------------------- | ||
| 71 | Specify where to install modules. | ||
| 72 | The default value is: | ||
| 73 | |||
| 74 | $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE) | ||
| 75 | |||
| 76 | The value can be overridden in which case the default value is ignored. | ||
| 77 | |||
| 78 | INSTALL_MOD_PATH | ||
| 79 | -------------------------------------------------- | ||
| 80 | INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory | ||
| 81 | relocations required by build roots. This is not defined in the | ||
| 82 | makefile but the argument can be passed to make if needed. | ||
| 83 | |||
| 84 | INSTALL_MOD_STRIP | ||
| 85 | -------------------------------------------------- | ||
| 86 | INSTALL_MOD_STRIP, if defined, will cause modules to be | ||
| 87 | stripped after they are installed. If INSTALL_MOD_STRIP is '1', then | ||
| 88 | the default option --strip-debug will be used. Otherwise, | ||
| 89 | INSTALL_MOD_STRIP will used as the options to the strip command. | ||
| 90 | |||
| 91 | INSTALL_FW_PATH | ||
| 92 | -------------------------------------------------- | ||
| 93 | INSTALL_FW_PATH specify where to install the firmware blobs. | ||
| 94 | The default value is: | ||
| 95 | |||
| 96 | $(INSTALL_MOD_PATH)/lib/firmware | ||
| 97 | |||
| 98 | The value can be overridden in which case the default value is ignored. | ||
| 99 | |||
| 100 | INSTALL_HDR_PATH | ||
| 101 | -------------------------------------------------- | ||
| 102 | INSTALL_HDR_PATH specify where to install user space headers when | ||
| 103 | executing "make headers_*". | ||
| 104 | The default value is: | ||
| 105 | |||
| 106 | $(objtree)/usr | ||
| 107 | |||
| 108 | $(objtree) is the directory where output files are saved. | ||
| 109 | The output directory is often set using "O=..." on the commandline. | ||
| 110 | |||
| 111 | The value can be overridden in which case the default value is ignored. | ||
| 112 | |||
| 113 | KBUILD_MODPOST_WARN | ||
| 114 | -------------------------------------------------- | ||
| 115 | KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined | ||
| 116 | symbols in the final module linking stage. | ||
| 117 | |||
| 118 | KBUILD_MODPOST_FINAL | ||
| 119 | -------------------------------------------------- | ||
| 120 | KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules. | ||
| 121 | This is solely usefull to speed up test compiles. | ||
| 122 | |||
| 123 | KBUILD_EXTRA_SYMBOLS | ||
| 124 | -------------------------------------------------- | ||
| 125 | For modules use symbols from another modules. | ||
| 126 | See more details in modules.txt. | ||
diff --git a/Documentation/kbuild/kconfig.txt b/Documentation/kbuild/kconfig.txt new file mode 100644 index 000000000000..26a7c0a93193 --- /dev/null +++ b/Documentation/kbuild/kconfig.txt | |||
| @@ -0,0 +1,188 @@ | |||
| 1 | This file contains some assistance for using "make *config". | ||
| 2 | |||
| 3 | Use "make help" to list all of the possible configuration targets. | ||
| 4 | |||
| 5 | The xconfig ('qconf') and menuconfig ('mconf') programs also | ||
| 6 | have embedded help text. Be sure to check it for navigation, | ||
| 7 | search, and other general help text. | ||
| 8 | |||
| 9 | ====================================================================== | ||
| 10 | General | ||
| 11 | -------------------------------------------------- | ||
| 12 | |||
| 13 | New kernel releases often introduce new config symbols. Often more | ||
| 14 | important, new kernel releases may rename config symbols. When | ||
| 15 | this happens, using a previously working .config file and running | ||
| 16 | "make oldconfig" won't necessarily produce a working new kernel | ||
| 17 | for you, so you may find that you need to see what NEW kernel | ||
| 18 | symbols have been introduced. | ||
| 19 | |||
| 20 | To see a list of new config symbols when using "make oldconfig", use | ||
| 21 | |||
| 22 | cp user/some/old.config .config | ||
| 23 | yes "" | make oldconfig >conf.new | ||
| 24 | |||
| 25 | and the config program will list as (NEW) any new symbols that have | ||
| 26 | unknown values. Of course, the .config file is also updated with | ||
| 27 | new (default) values, so you can use: | ||
| 28 | |||
| 29 | grep "(NEW)" conf.new | ||
| 30 | |||
| 31 | to see the new config symbols or you can 'diff' the previous and | ||
| 32 | new .config files to see the differences: | ||
| 33 | |||
| 34 | diff .config.old .config | less | ||
| 35 | |||
| 36 | (Yes, we need something better here.) | ||
| 37 | |||
| 38 | |||
| 39 | ====================================================================== | ||
| 40 | menuconfig | ||
| 41 | -------------------------------------------------- | ||
| 42 | |||
| 43 | SEARCHING for CONFIG symbols | ||
| 44 | |||
| 45 | Searching in menuconfig: | ||
| 46 | |||
| 47 | The Search function searches for kernel configuration symbol | ||
| 48 | names, so you have to know something close to what you are | ||
| 49 | looking for. | ||
| 50 | |||
| 51 | Example: | ||
| 52 | /hotplug | ||
| 53 | This lists all config symbols that contain "hotplug", | ||
| 54 | e.g., HOTPLUG, HOTPLUG_CPU, MEMORY_HOTPLUG. | ||
| 55 | |||
| 56 | For search help, enter / followed TAB-TAB-TAB (to highlight | ||
| 57 | <Help>) and Enter. This will tell you that you can also use | ||
| 58 | regular expressions (regexes) in the search string, so if you | ||
| 59 | are not interested in MEMORY_HOTPLUG, you could try | ||
| 60 | |||
| 61 | /^hotplug | ||
| 62 | |||
| 63 | |||
| 64 | ______________________________________________________________________ | ||
| 65 | Color Themes for 'menuconfig' | ||
| 66 | |||
| 67 | It is possible to select different color themes using the variable | ||
| 68 | MENUCONFIG_COLOR. To select a theme use: | ||
| 69 | |||
| 70 | make MENUCONFIG_COLOR=<theme> menuconfig | ||
| 71 | |||
| 72 | Available themes are: | ||
| 73 | mono => selects colors suitable for monochrome displays | ||
| 74 | blackbg => selects a color scheme with black background | ||
| 75 | classic => theme with blue background. The classic look | ||
| 76 | bluetitle => a LCD friendly version of classic. (default) | ||
| 77 | |||
| 78 | ______________________________________________________________________ | ||
| 79 | Environment variables in 'menuconfig' | ||
| 80 | |||
| 81 | KCONFIG_ALLCONFIG | ||
| 82 | -------------------------------------------------- | ||
| 83 | (partially based on lkml email from/by Rob Landley, re: miniconfig) | ||
| 84 | -------------------------------------------------- | ||
| 85 | The allyesconfig/allmodconfig/allnoconfig/randconfig variants can | ||
| 86 | also use the environment variable KCONFIG_ALLCONFIG as a flag or a | ||
| 87 | filename that contains config symbols that the user requires to be | ||
| 88 | set to a specific value. If KCONFIG_ALLCONFIG is used without a | ||
| 89 | filename, "make *config" checks for a file named | ||
| 90 | "all{yes/mod/no/random}.config" (corresponding to the *config command | ||
| 91 | that was used) for symbol values that are to be forced. If this file | ||
| 92 | is not found, it checks for a file named "all.config" to contain forced | ||
| 93 | values. | ||
| 94 | |||
| 95 | This enables you to create "miniature" config (miniconfig) or custom | ||
| 96 | config files containing just the config symbols that you are interested | ||
| 97 | in. Then the kernel config system generates the full .config file, | ||
| 98 | including dependencies of your miniconfig file, based on the miniconfig | ||
| 99 | file. | ||
| 100 | |||
| 101 | This 'KCONFIG_ALLCONFIG' file is a config file which contains | ||
| 102 | (usually a subset of all) preset config symbols. These variable | ||
| 103 | settings are still subject to normal dependency checks. | ||
| 104 | |||
| 105 | Examples: | ||
| 106 | KCONFIG_ALLCONFIG=custom-notebook.config make allnoconfig | ||
| 107 | or | ||
| 108 | KCONFIG_ALLCONFIG=mini.config make allnoconfig | ||
| 109 | or | ||
| 110 | make KCONFIG_ALLCONFIG=mini.config allnoconfig | ||
| 111 | |||
| 112 | These examples will disable most options (allnoconfig) but enable or | ||
| 113 | disable the options that are explicitly listed in the specified | ||
| 114 | mini-config files. | ||
| 115 | |||
| 116 | KCONFIG_NOSILENTUPDATE | ||
| 117 | -------------------------------------------------- | ||
| 118 | If this variable has a non-blank value, it prevents silent kernel | ||
| 119 | config udpates (requires explicit updates). | ||
| 120 | |||
| 121 | KCONFIG_CONFIG | ||
| 122 | -------------------------------------------------- | ||
| 123 | This environment variable can be used to specify a default kernel config | ||
| 124 | file name to override the default name of ".config". | ||
| 125 | |||
| 126 | KCONFIG_OVERWRITECONFIG | ||
| 127 | -------------------------------------------------- | ||
| 128 | If you set KCONFIG_OVERWRITECONFIG in the environment, Kconfig will not | ||
| 129 | break symlinks when .config is a symlink to somewhere else. | ||
| 130 | |||
| 131 | KCONFIG_NOTIMESTAMP | ||
| 132 | -------------------------------------------------- | ||
| 133 | If this environment variable exists and is non-null, the timestamp line | ||
| 134 | in generated .config files is omitted. | ||
| 135 | |||
| 136 | KCONFIG_AUTOCONFIG | ||
| 137 | -------------------------------------------------- | ||
| 138 | This environment variable can be set to specify the path & name of the | ||
| 139 | "auto.conf" file. Its default value is "include/config/auto.conf". | ||
| 140 | |||
| 141 | KCONFIG_AUTOHEADER | ||
| 142 | -------------------------------------------------- | ||
| 143 | This environment variable can be set to specify the path & name of the | ||
| 144 | "autoconf.h" (header) file. Its default value is "include/linux/autoconf.h". | ||
| 145 | |||
| 146 | ______________________________________________________________________ | ||
| 147 | menuconfig User Interface Options | ||
| 148 | ---------------------------------------------------------------------- | ||
| 149 | MENUCONFIG_MODE | ||
| 150 | -------------------------------------------------- | ||
| 151 | This mode shows all sub-menus in one large tree. | ||
| 152 | |||
| 153 | Example: | ||
| 154 | MENUCONFIG_MODE=single_menu make menuconfig | ||
| 155 | |||
| 156 | ====================================================================== | ||
| 157 | xconfig | ||
| 158 | -------------------------------------------------- | ||
| 159 | |||
| 160 | Searching in xconfig: | ||
| 161 | |||
| 162 | The Search function searches for kernel configuration symbol | ||
| 163 | names, so you have to know something close to what you are | ||
| 164 | looking for. | ||
| 165 | |||
| 166 | Example: | ||
| 167 | Ctrl-F hotplug | ||
| 168 | or | ||
| 169 | Menu: File, Search, hotplug | ||
| 170 | |||
| 171 | lists all config symbol entries that contain "hotplug" in | ||
| 172 | the symbol name. In this Search dialog, you may change the | ||
| 173 | config setting for any of the entries that are not grayed out. | ||
| 174 | You can also enter a different search string without having | ||
| 175 | to return to the main menu. | ||
| 176 | |||
| 177 | |||
| 178 | ====================================================================== | ||
| 179 | gconfig | ||
| 180 | -------------------------------------------------- | ||
| 181 | |||
| 182 | Searching in gconfig: | ||
| 183 | |||
| 184 | None (gconfig isn't maintained as well as xconfig or menuconfig); | ||
| 185 | however, gconfig does have a few more viewing choices than | ||
| 186 | xconfig does. | ||
| 187 | |||
| 188 | ### | ||
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 335aef4dcaeb..b8d470596b0c 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 | |||
| @@ -152,3 +152,4 @@ | |||
| 152 | 151 -> ADS Tech Instant HDTV [1421:0380] | 152 | 151 -> ADS Tech Instant HDTV [1421:0380] |
| 153 | 152 -> Asus Tiger Rev:1.00 [1043:4857] | 153 | 152 -> Asus Tiger Rev:1.00 [1043:4857] |
| 154 | 153 -> Kworld Plus TV Analog Lite PCI [17de:7128] | 154 | 153 -> Kworld Plus TV Analog Lite PCI [17de:7128] |
| 155 | 154 -> Avermedia AVerTV GO 007 FM Plus [1461:f31d] | ||
diff --git a/Documentation/video4linux/si470x.txt b/Documentation/video4linux/si470x.txt index 11c5fd22a332..49679e6aaa76 100644 --- a/Documentation/video4linux/si470x.txt +++ b/Documentation/video4linux/si470x.txt | |||
| @@ -41,6 +41,7 @@ chips are known to work: | |||
| 41 | - 10c4:818a: Silicon Labs USB FM Radio Reference Design | 41 | - 10c4:818a: Silicon Labs USB FM Radio Reference Design |
| 42 | - 06e1:a155: ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF) | 42 | - 06e1:a155: ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF) |
| 43 | - 1b80:d700: KWorld USB FM Radio SnapMusic Mobile 700 (FM700) | 43 | - 1b80:d700: KWorld USB FM Radio SnapMusic Mobile 700 (FM700) |
| 44 | - 10c5:819a: DealExtreme USB Radio | ||
| 44 | 45 | ||
| 45 | 46 | ||
| 46 | Software | 47 | Software |
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index eeae76c22a93..ff124374e9ba 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt | |||
| @@ -184,7 +184,7 @@ may be NULL if the subdev driver does not support anything from that category. | |||
| 184 | It looks like this: | 184 | It looks like this: |
| 185 | 185 | ||
| 186 | struct v4l2_subdev_core_ops { | 186 | struct v4l2_subdev_core_ops { |
| 187 | int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip); | 187 | int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip); |
| 188 | int (*log_status)(struct v4l2_subdev *sd); | 188 | int (*log_status)(struct v4l2_subdev *sd); |
| 189 | int (*init)(struct v4l2_subdev *sd, u32 val); | 189 | int (*init)(struct v4l2_subdev *sd, u32 val); |
| 190 | ... | 190 | ... |
| @@ -390,16 +390,18 @@ allocated memory. | |||
| 390 | 390 | ||
| 391 | You should also set these fields: | 391 | You should also set these fields: |
| 392 | 392 | ||
| 393 | - parent: set to the parent device (same device as was used to register | 393 | - v4l2_dev: set to the v4l2_device parent device. |
| 394 | v4l2_device). | ||
| 395 | - name: set to something descriptive and unique. | 394 | - name: set to something descriptive and unique. |
| 396 | - fops: set to the file_operations struct. | 395 | - fops: set to the v4l2_file_operations struct. |
| 397 | - ioctl_ops: if you use the v4l2_ioctl_ops to simplify ioctl maintenance | 396 | - ioctl_ops: if you use the v4l2_ioctl_ops to simplify ioctl maintenance |
| 398 | (highly recommended to use this and it might become compulsory in the | 397 | (highly recommended to use this and it might become compulsory in the |
| 399 | future!), then set this to your v4l2_ioctl_ops struct. | 398 | future!), then set this to your v4l2_ioctl_ops struct. |
| 400 | 399 | ||
| 401 | If you use v4l2_ioctl_ops, then you should set .unlocked_ioctl to | 400 | If you use v4l2_ioctl_ops, then you should set either .unlocked_ioctl or |
| 402 | __video_ioctl2 or .ioctl to video_ioctl2 in your file_operations struct. | 401 | .ioctl to video_ioctl2 in your v4l2_file_operations struct. |
| 402 | |||
| 403 | The v4l2_file_operations struct is a subset of file_operations. The main | ||
| 404 | difference is that the inode argument is omitted since it is never used. | ||
| 403 | 405 | ||
| 404 | 406 | ||
| 405 | video_device registration | 407 | video_device registration |
| @@ -410,7 +412,7 @@ for you. | |||
| 410 | 412 | ||
| 411 | err = video_register_device(vdev, VFL_TYPE_GRABBER, -1); | 413 | err = video_register_device(vdev, VFL_TYPE_GRABBER, -1); |
| 412 | if (err) { | 414 | if (err) { |
| 413 | video_device_release(vdev); // or kfree(my_vdev); | 415 | video_device_release(vdev); /* or kfree(my_vdev); */ |
| 414 | return err; | 416 | return err; |
| 415 | } | 417 | } |
| 416 | 418 | ||
| @@ -516,5 +518,4 @@ void *video_drvdata(struct file *file); | |||
| 516 | 518 | ||
| 517 | You can go from a video_device struct to the v4l2_device struct using: | 519 | You can go from a video_device struct to the v4l2_device struct using: |
| 518 | 520 | ||
| 519 | struct v4l2_device *v4l2_dev = dev_get_drvdata(vdev->parent); | 521 | struct v4l2_device *v4l2_dev = vdev->v4l2_dev; |
| 520 | |||
| @@ -321,7 +321,8 @@ KALLSYMS = scripts/kallsyms | |||
| 321 | PERL = perl | 321 | PERL = perl |
| 322 | CHECK = sparse | 322 | CHECK = sparse |
| 323 | 323 | ||
| 324 | CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise $(CF) | 324 | CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \ |
| 325 | -Wbitwise -Wno-return-void $(CF) | ||
| 325 | MODFLAGS = -DMODULE | 326 | MODFLAGS = -DMODULE |
| 326 | CFLAGS_MODULE = $(MODFLAGS) | 327 | CFLAGS_MODULE = $(MODFLAGS) |
| 327 | AFLAGS_MODULE = $(MODFLAGS) | 328 | AFLAGS_MODULE = $(MODFLAGS) |
| @@ -52,11 +52,11 @@ DOCUMENTATION: | |||
| 52 | 52 | ||
| 53 | - The Documentation/DocBook/ subdirectory contains several guides for | 53 | - The Documentation/DocBook/ subdirectory contains several guides for |
| 54 | kernel developers and users. These guides can be rendered in a | 54 | kernel developers and users. These guides can be rendered in a |
| 55 | number of formats: PostScript (.ps), PDF, and HTML, among others. | 55 | number of formats: PostScript (.ps), PDF, HTML, & man-pages, among others. |
| 56 | After installation, "make psdocs", "make pdfdocs", or "make htmldocs" | 56 | After installation, "make psdocs", "make pdfdocs", "make htmldocs", |
| 57 | will render the documentation in the requested format. | 57 | or "make mandocs" will render the documentation in the requested format. |
| 58 | 58 | ||
| 59 | INSTALLING the kernel: | 59 | INSTALLING the kernel source: |
| 60 | 60 | ||
| 61 | - If you install the full sources, put the kernel tarball in a | 61 | - If you install the full sources, put the kernel tarball in a |
| 62 | directory where you have permissions (eg. your home directory) and | 62 | directory where you have permissions (eg. your home directory) and |
| @@ -187,14 +187,9 @@ CONFIGURING the kernel: | |||
| 187 | "make randconfig" Create a ./.config file by setting symbol | 187 | "make randconfig" Create a ./.config file by setting symbol |
| 188 | values to random values. | 188 | values to random values. |
| 189 | 189 | ||
| 190 | The allyesconfig/allmodconfig/allnoconfig/randconfig variants can | 190 | You can find more information on using the Linux kernel config tools |
| 191 | also use the environment variable KCONFIG_ALLCONFIG to specify a | 191 | in Documentation/kbuild/make-configs.txt. |
| 192 | filename that contains config options that the user requires to be | 192 | |
| 193 | set to a specific value. If KCONFIG_ALLCONFIG=filename is not used, | ||
| 194 | "make *config" checks for a file named "all{yes/mod/no/random}.config" | ||
| 195 | for symbol values that are to be forced. If this file is not found, | ||
| 196 | it checks for a file named "all.config" to contain forced values. | ||
| 197 | |||
| 198 | NOTES on "make config": | 193 | NOTES on "make config": |
| 199 | - having unnecessary drivers will make the kernel bigger, and can | 194 | - having unnecessary drivers will make the kernel bigger, and can |
| 200 | under some circumstances lead to problems: probing for a | 195 | under some circumstances lead to problems: probing for a |
| @@ -231,6 +226,19 @@ COMPILING the kernel: | |||
| 231 | - If you configured any of the parts of the kernel as `modules', you | 226 | - If you configured any of the parts of the kernel as `modules', you |
| 232 | will also have to do "make modules_install". | 227 | will also have to do "make modules_install". |
| 233 | 228 | ||
| 229 | - Verbose kernel compile/build output: | ||
| 230 | |||
| 231 | Normally the kernel build system runs in a fairly quiet mode (but not | ||
| 232 | totally silent). However, sometimes you or other kernel developers need | ||
| 233 | to see compile, link, or other commands exactly as they are executed. | ||
| 234 | For this, use "verbose" build mode. This is done by inserting | ||
| 235 | "V=1" in the "make" command. E.g.: | ||
| 236 | |||
| 237 | make V=1 all | ||
| 238 | |||
| 239 | To have the build system also tell the reason for the rebuild of each | ||
| 240 | target, use "V=2". The default is "V=0". | ||
| 241 | |||
| 234 | - Keep a backup kernel handy in case something goes wrong. This is | 242 | - Keep a backup kernel handy in case something goes wrong. This is |
| 235 | especially true for the development releases, since each new release | 243 | especially true for the development releases, since each new release |
| 236 | contains new code which has not been debugged. Make sure you keep a | 244 | contains new code which has not been debugged. Make sure you keep a |
diff --git a/arch/alpha/include/asm/topology.h b/arch/alpha/include/asm/topology.h index 149532e162c4..b4f284c72ff3 100644 --- a/arch/alpha/include/asm/topology.h +++ b/arch/alpha/include/asm/topology.h | |||
| @@ -39,7 +39,24 @@ static inline cpumask_t node_to_cpumask(int node) | |||
| 39 | return node_cpu_mask; | 39 | return node_cpu_mask; |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | extern struct cpumask node_to_cpumask_map[]; | ||
| 43 | /* FIXME: This is dumb, recalculating every time. But simple. */ | ||
| 44 | static const struct cpumask *cpumask_of_node(int node) | ||
| 45 | { | ||
| 46 | int cpu; | ||
| 47 | |||
| 48 | cpumask_clear(&node_to_cpumask_map[node]); | ||
| 49 | |||
| 50 | for_each_online_cpu(cpu) { | ||
| 51 | if (cpu_to_node(cpu) == node) | ||
| 52 | cpumask_set_cpu(cpu, node_to_cpumask_map[node]); | ||
| 53 | } | ||
| 54 | |||
| 55 | return &node_to_cpumask_map[node]; | ||
| 56 | } | ||
| 57 | |||
| 42 | #define pcibus_to_cpumask(bus) (cpu_online_map) | 58 | #define pcibus_to_cpumask(bus) (cpu_online_map) |
| 59 | #define cpumask_of_pcibus(bus) (cpu_online_mask) | ||
| 43 | 60 | ||
| 44 | #endif /* !CONFIG_NUMA */ | 61 | #endif /* !CONFIG_NUMA */ |
| 45 | # include <asm-generic/topology.h> | 62 | # include <asm-generic/topology.h> |
diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile index ac706c1d7ada..b4697759a123 100644 --- a/arch/alpha/kernel/Makefile +++ b/arch/alpha/kernel/Makefile | |||
| @@ -8,7 +8,7 @@ EXTRA_CFLAGS := -Werror -Wno-sign-compare | |||
| 8 | 8 | ||
| 9 | obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \ | 9 | obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \ |
| 10 | irq_alpha.o signal.o setup.o ptrace.o time.o \ | 10 | irq_alpha.o signal.o setup.o ptrace.o time.o \ |
| 11 | alpha_ksyms.o systbls.o err_common.o io.o | 11 | alpha_ksyms.o systbls.o err_common.o io.o binfmt_loader.o |
| 12 | 12 | ||
| 13 | obj-$(CONFIG_VGA_HOSE) += console.o | 13 | obj-$(CONFIG_VGA_HOSE) += console.o |
| 14 | obj-$(CONFIG_SMP) += smp.o | 14 | obj-$(CONFIG_SMP) += smp.o |
diff --git a/arch/alpha/kernel/binfmt_loader.c b/arch/alpha/kernel/binfmt_loader.c new file mode 100644 index 000000000000..4a0af906b00a --- /dev/null +++ b/arch/alpha/kernel/binfmt_loader.c | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | #include <linux/init.h> | ||
| 2 | #include <linux/fs.h> | ||
| 3 | #include <linux/file.h> | ||
| 4 | #include <linux/mm_types.h> | ||
| 5 | #include <linux/binfmts.h> | ||
| 6 | #include <linux/a.out.h> | ||
| 7 | |||
| 8 | static int load_binary(struct linux_binprm *bprm, struct pt_regs *regs) | ||
| 9 | { | ||
| 10 | struct exec *eh = (struct exec *)bprm->buf; | ||
| 11 | unsigned long loader; | ||
| 12 | struct file *file; | ||
| 13 | int retval; | ||
| 14 | |||
| 15 | if (eh->fh.f_magic != 0x183 || (eh->fh.f_flags & 0x3000) != 0x3000) | ||
| 16 | return -ENOEXEC; | ||
| 17 | |||
| 18 | if (bprm->loader) | ||
| 19 | return -ENOEXEC; | ||
| 20 | |||
| 21 | allow_write_access(bprm->file); | ||
| 22 | fput(bprm->file); | ||
| 23 | bprm->file = NULL; | ||
| 24 | |||
| 25 | loader = bprm->vma->vm_end - sizeof(void *); | ||
| 26 | |||
| 27 | file = open_exec("/sbin/loader"); | ||
| 28 | retval = PTR_ERR(file); | ||
| 29 | if (IS_ERR(file)) | ||
| 30 | return retval; | ||
| 31 | |||
| 32 | /* Remember if the application is TASO. */ | ||
| 33 | bprm->taso = eh->ah.entry < 0x100000000UL; | ||
| 34 | |||
| 35 | bprm->file = file; | ||
| 36 | bprm->loader = loader; | ||
| 37 | retval = prepare_binprm(bprm); | ||
| 38 | if (retval < 0) | ||
| 39 | return retval; | ||
| 40 | return search_binary_handler(bprm,regs); | ||
| 41 | } | ||
| 42 | |||
| 43 | static struct linux_binfmt loader_format = { | ||
| 44 | .load_binary = load_binary, | ||
| 45 | }; | ||
| 46 | |||
| 47 | static int __init init_loader_binfmt(void) | ||
| 48 | { | ||
| 49 | return register_binfmt(&loader_format); | ||
| 50 | } | ||
| 51 | arch_initcall(init_loader_binfmt); | ||
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index d0f1620007f7..703731accda6 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c | |||
| @@ -50,7 +50,8 @@ int irq_select_affinity(unsigned int irq) | |||
| 50 | if (!irq_desc[irq].chip->set_affinity || irq_user_affinity[irq]) | 50 | if (!irq_desc[irq].chip->set_affinity || irq_user_affinity[irq]) |
| 51 | return 1; | 51 | return 1; |
| 52 | 52 | ||
| 53 | while (!cpu_possible(cpu) || !cpu_isset(cpu, irq_default_affinity)) | 53 | while (!cpu_possible(cpu) || |
| 54 | !cpumask_test_cpu(cpu, irq_default_affinity)) | ||
| 54 | cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0); | 55 | cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0); |
| 55 | last_cpu = cpu; | 56 | last_cpu = cpu; |
| 56 | 57 | ||
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index a449e999027c..02bee6983ce2 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c | |||
| @@ -79,6 +79,11 @@ int alpha_l3_cacheshape; | |||
| 79 | unsigned long alpha_verbose_mcheck = CONFIG_VERBOSE_MCHECK_ON; | 79 | unsigned long alpha_verbose_mcheck = CONFIG_VERBOSE_MCHECK_ON; |
| 80 | #endif | 80 | #endif |
| 81 | 81 | ||
| 82 | #ifdef CONFIG_NUMA | ||
| 83 | struct cpumask node_to_cpumask_map[MAX_NUMNODES] __read_mostly; | ||
| 84 | EXPORT_SYMBOL(node_to_cpumask_map); | ||
| 85 | #endif | ||
| 86 | |||
| 82 | /* Which processor we booted from. */ | 87 | /* Which processor we booted from. */ |
| 83 | int boot_cpuid; | 88 | int boot_cpuid; |
| 84 | 89 | ||
diff --git a/arch/avr32/include/asm/bitops.h b/arch/avr32/include/asm/bitops.h index 1a50b69b1a19..f7dd5f71edf7 100644 --- a/arch/avr32/include/asm/bitops.h +++ b/arch/avr32/include/asm/bitops.h | |||
| @@ -263,6 +263,11 @@ static inline int fls(unsigned long word) | |||
| 263 | return 32 - result; | 263 | return 32 - result; |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | static inline int __fls(unsigned long word) | ||
| 267 | { | ||
| 268 | return fls(word) - 1; | ||
| 269 | } | ||
| 270 | |||
| 266 | unsigned long find_first_zero_bit(const unsigned long *addr, | 271 | unsigned long find_first_zero_bit(const unsigned long *addr, |
| 267 | unsigned long size); | 272 | unsigned long size); |
| 268 | unsigned long find_next_zero_bit(const unsigned long *addr, | 273 | unsigned long find_next_zero_bit(const unsigned long *addr, |
diff --git a/arch/blackfin/include/asm/bitops.h b/arch/blackfin/include/asm/bitops.h index b39a175c79c1..c428e4106f89 100644 --- a/arch/blackfin/include/asm/bitops.h +++ b/arch/blackfin/include/asm/bitops.h | |||
| @@ -213,6 +213,7 @@ static __inline__ int __test_bit(int nr, const void *addr) | |||
| 213 | #endif /* __KERNEL__ */ | 213 | #endif /* __KERNEL__ */ |
| 214 | 214 | ||
| 215 | #include <asm-generic/bitops/fls.h> | 215 | #include <asm-generic/bitops/fls.h> |
| 216 | #include <asm-generic/bitops/__fls.h> | ||
| 216 | #include <asm-generic/bitops/fls64.h> | 217 | #include <asm-generic/bitops/fls64.h> |
| 217 | 218 | ||
| 218 | #endif /* _BLACKFIN_BITOPS_H */ | 219 | #endif /* _BLACKFIN_BITOPS_H */ |
diff --git a/arch/cris/include/asm/bitops.h b/arch/cris/include/asm/bitops.h index c0e62f811e09..9e69cfb7f134 100644 --- a/arch/cris/include/asm/bitops.h +++ b/arch/cris/include/asm/bitops.h | |||
| @@ -148,6 +148,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) | |||
| 148 | #define ffs kernel_ffs | 148 | #define ffs kernel_ffs |
| 149 | 149 | ||
| 150 | #include <asm-generic/bitops/fls.h> | 150 | #include <asm-generic/bitops/fls.h> |
| 151 | #include <asm-generic/bitops/__fls.h> | ||
| 151 | #include <asm-generic/bitops/fls64.h> | 152 | #include <asm-generic/bitops/fls64.h> |
| 152 | #include <asm-generic/bitops/hweight.h> | 153 | #include <asm-generic/bitops/hweight.h> |
| 153 | #include <asm-generic/bitops/find.h> | 154 | #include <asm-generic/bitops/find.h> |
diff --git a/arch/h8300/include/asm/bitops.h b/arch/h8300/include/asm/bitops.h index cb18e3b0aa94..cb9ddf5fc54f 100644 --- a/arch/h8300/include/asm/bitops.h +++ b/arch/h8300/include/asm/bitops.h | |||
| @@ -207,6 +207,7 @@ static __inline__ unsigned long __ffs(unsigned long word) | |||
| 207 | #endif /* __KERNEL__ */ | 207 | #endif /* __KERNEL__ */ |
| 208 | 208 | ||
| 209 | #include <asm-generic/bitops/fls.h> | 209 | #include <asm-generic/bitops/fls.h> |
| 210 | #include <asm-generic/bitops/__fls.h> | ||
| 210 | #include <asm-generic/bitops/fls64.h> | 211 | #include <asm-generic/bitops/fls64.h> |
| 211 | 212 | ||
| 212 | #endif /* _H8300_BITOPS_H */ | 213 | #endif /* _H8300_BITOPS_H */ |
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 7fa8f615ba6e..3d31636cbafb 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
| @@ -687,3 +687,6 @@ config IRQ_PER_CPU | |||
| 687 | 687 | ||
| 688 | config IOMMU_HELPER | 688 | config IOMMU_HELPER |
| 689 | def_bool (IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_GENERIC || SWIOTLB) | 689 | def_bool (IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_GENERIC || SWIOTLB) |
| 690 | |||
| 691 | config IOMMU_API | ||
| 692 | def_bool (DMAR) | ||
diff --git a/arch/ia64/include/asm/irq.h b/arch/ia64/include/asm/irq.h index 3627116fb0e2..36429a532630 100644 --- a/arch/ia64/include/asm/irq.h +++ b/arch/ia64/include/asm/irq.h | |||
| @@ -27,7 +27,7 @@ irq_canonicalize (int irq) | |||
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | extern void set_irq_affinity_info (unsigned int irq, int dest, int redir); | 29 | extern void set_irq_affinity_info (unsigned int irq, int dest, int redir); |
| 30 | bool is_affinity_mask_valid(cpumask_t cpumask); | 30 | bool is_affinity_mask_valid(cpumask_var_t cpumask); |
| 31 | 31 | ||
| 32 | #define is_affinity_mask_valid is_affinity_mask_valid | 32 | #define is_affinity_mask_valid is_affinity_mask_valid |
| 33 | 33 | ||
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h index 0560f3fae538..348663661659 100644 --- a/arch/ia64/include/asm/kvm_host.h +++ b/arch/ia64/include/asm/kvm_host.h | |||
| @@ -467,7 +467,7 @@ struct kvm_arch { | |||
| 467 | struct kvm_sal_data rdv_sal_data; | 467 | struct kvm_sal_data rdv_sal_data; |
| 468 | 468 | ||
| 469 | struct list_head assigned_dev_head; | 469 | struct list_head assigned_dev_head; |
| 470 | struct dmar_domain *intel_iommu_domain; | 470 | struct iommu_domain *iommu_domain; |
| 471 | struct hlist_head irq_ack_notifier_list; | 471 | struct hlist_head irq_ack_notifier_list; |
| 472 | 472 | ||
| 473 | unsigned long irq_sources_bitmap; | 473 | unsigned long irq_sources_bitmap; |
diff --git a/arch/ia64/include/asm/topology.h b/arch/ia64/include/asm/topology.h index a3cc9f65f954..76a33a91ca69 100644 --- a/arch/ia64/include/asm/topology.h +++ b/arch/ia64/include/asm/topology.h | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | * Returns a bitmask of CPUs on Node 'node'. | 34 | * Returns a bitmask of CPUs on Node 'node'. |
| 35 | */ | 35 | */ |
| 36 | #define node_to_cpumask(node) (node_to_cpu_mask[node]) | 36 | #define node_to_cpumask(node) (node_to_cpu_mask[node]) |
| 37 | #define cpumask_of_node(node) (&node_to_cpu_mask[node]) | ||
| 37 | 38 | ||
| 38 | /* | 39 | /* |
| 39 | * Returns the number of the node containing Node 'nid'. | 40 | * Returns the number of the node containing Node 'nid'. |
| @@ -45,7 +46,7 @@ | |||
| 45 | /* | 46 | /* |
| 46 | * Returns the number of the first CPU on Node 'node'. | 47 | * Returns the number of the first CPU on Node 'node'. |
| 47 | */ | 48 | */ |
| 48 | #define node_to_first_cpu(node) (first_cpu(node_to_cpumask(node))) | 49 | #define node_to_first_cpu(node) (cpumask_first(cpumask_of_node(node))) |
| 49 | 50 | ||
| 50 | /* | 51 | /* |
| 51 | * Determines the node for a given pci bus | 52 | * Determines the node for a given pci bus |
| @@ -109,6 +110,8 @@ void build_cpu_to_node_map(void); | |||
| 109 | #define topology_core_id(cpu) (cpu_data(cpu)->core_id) | 110 | #define topology_core_id(cpu) (cpu_data(cpu)->core_id) |
| 110 | #define topology_core_siblings(cpu) (cpu_core_map[cpu]) | 111 | #define topology_core_siblings(cpu) (cpu_core_map[cpu]) |
| 111 | #define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu)) | 112 | #define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu)) |
| 113 | #define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) | ||
| 114 | #define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu)) | ||
| 112 | #define smt_capable() (smp_num_siblings > 1) | 115 | #define smt_capable() (smp_num_siblings > 1) |
| 113 | #endif | 116 | #endif |
| 114 | 117 | ||
| @@ -119,6 +122,10 @@ extern void arch_fix_phys_package_id(int num, u32 slot); | |||
| 119 | node_to_cpumask(pcibus_to_node(bus)) \ | 122 | node_to_cpumask(pcibus_to_node(bus)) \ |
| 120 | ) | 123 | ) |
| 121 | 124 | ||
| 125 | #define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \ | ||
| 126 | cpu_all_mask : \ | ||
| 127 | cpumask_from_node(pcibus_to_node(bus))) | ||
| 128 | |||
| 122 | #include <asm-generic/topology.h> | 129 | #include <asm-generic/topology.h> |
| 123 | 130 | ||
| 124 | #endif /* _ASM_IA64_TOPOLOGY_H */ | 131 | #endif /* _ASM_IA64_TOPOLOGY_H */ |
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index bd7acc71e8a9..0553648b7595 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
| @@ -202,7 +202,6 @@ char *__init __acpi_map_table(unsigned long phys_addr, unsigned long size) | |||
| 202 | Boot-time Table Parsing | 202 | Boot-time Table Parsing |
| 203 | -------------------------------------------------------------------------- */ | 203 | -------------------------------------------------------------------------- */ |
| 204 | 204 | ||
| 205 | static int total_cpus __initdata; | ||
| 206 | static int available_cpus __initdata; | 205 | static int available_cpus __initdata; |
| 207 | struct acpi_table_madt *acpi_madt __initdata; | 206 | struct acpi_table_madt *acpi_madt __initdata; |
| 208 | static u8 has_8259; | 207 | static u8 has_8259; |
| @@ -1001,7 +1000,7 @@ acpi_map_iosapic(acpi_handle handle, u32 depth, void *context, void **ret) | |||
| 1001 | node = pxm_to_node(pxm); | 1000 | node = pxm_to_node(pxm); |
| 1002 | 1001 | ||
| 1003 | if (node >= MAX_NUMNODES || !node_online(node) || | 1002 | if (node >= MAX_NUMNODES || !node_online(node) || |
| 1004 | cpus_empty(node_to_cpumask(node))) | 1003 | cpumask_empty(cpumask_of_node(node))) |
| 1005 | return AE_OK; | 1004 | return AE_OK; |
| 1006 | 1005 | ||
| 1007 | /* We know a gsi to node mapping! */ | 1006 | /* We know a gsi to node mapping! */ |
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index c8adecd5b416..5cfd3d91001a 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c | |||
| @@ -695,32 +695,31 @@ get_target_cpu (unsigned int gsi, int irq) | |||
| 695 | #ifdef CONFIG_NUMA | 695 | #ifdef CONFIG_NUMA |
| 696 | { | 696 | { |
| 697 | int num_cpus, cpu_index, iosapic_index, numa_cpu, i = 0; | 697 | int num_cpus, cpu_index, iosapic_index, numa_cpu, i = 0; |
| 698 | cpumask_t cpu_mask; | 698 | const struct cpumask *cpu_mask; |
| 699 | 699 | ||
| 700 | iosapic_index = find_iosapic(gsi); | 700 | iosapic_index = find_iosapic(gsi); |
| 701 | if (iosapic_index < 0 || | 701 | if (iosapic_index < 0 || |
| 702 | iosapic_lists[iosapic_index].node == MAX_NUMNODES) | 702 | iosapic_lists[iosapic_index].node == MAX_NUMNODES) |
| 703 | goto skip_numa_setup; | 703 | goto skip_numa_setup; |
| 704 | 704 | ||
| 705 | cpu_mask = node_to_cpumask(iosapic_lists[iosapic_index].node); | 705 | cpu_mask = cpumask_of_node(iosapic_lists[iosapic_index].node); |
| 706 | cpus_and(cpu_mask, cpu_mask, domain); | 706 | num_cpus = 0; |
| 707 | for_each_cpu_mask(numa_cpu, cpu_mask) { | 707 | for_each_cpu_and(numa_cpu, cpu_mask, &domain) { |
| 708 | if (!cpu_online(numa_cpu)) | 708 | if (cpu_online(numa_cpu)) |
| 709 | cpu_clear(numa_cpu, cpu_mask); | 709 | num_cpus++; |
| 710 | } | 710 | } |
| 711 | 711 | ||
| 712 | num_cpus = cpus_weight(cpu_mask); | ||
| 713 | |||
| 714 | if (!num_cpus) | 712 | if (!num_cpus) |
| 715 | goto skip_numa_setup; | 713 | goto skip_numa_setup; |
| 716 | 714 | ||
| 717 | /* Use irq assignment to distribute across cpus in node */ | 715 | /* Use irq assignment to distribute across cpus in node */ |
| 718 | cpu_index = irq % num_cpus; | 716 | cpu_index = irq % num_cpus; |
| 719 | 717 | ||
| 720 | for (numa_cpu = first_cpu(cpu_mask) ; i < cpu_index ; i++) | 718 | for_each_cpu_and(numa_cpu, cpu_mask, &domain) |
| 721 | numa_cpu = next_cpu(numa_cpu, cpu_mask); | 719 | if (cpu_online(numa_cpu) && i++ >= cpu_index) |
| 720 | break; | ||
| 722 | 721 | ||
| 723 | if (numa_cpu != NR_CPUS) | 722 | if (numa_cpu < nr_cpu_ids) |
| 724 | return cpu_physical_id(numa_cpu); | 723 | return cpu_physical_id(numa_cpu); |
| 725 | } | 724 | } |
| 726 | skip_numa_setup: | 725 | skip_numa_setup: |
| @@ -731,7 +730,7 @@ skip_numa_setup: | |||
| 731 | * case of NUMA.) | 730 | * case of NUMA.) |
| 732 | */ | 731 | */ |
| 733 | do { | 732 | do { |
| 734 | if (++cpu >= NR_CPUS) | 733 | if (++cpu >= nr_cpu_ids) |
| 735 | cpu = 0; | 734 | cpu = 0; |
| 736 | } while (!cpu_online(cpu) || !cpu_isset(cpu, domain)); | 735 | } while (!cpu_online(cpu) || !cpu_isset(cpu, domain)); |
| 737 | 736 | ||
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c index 0b6db53fedcf..95ff16cb05d8 100644 --- a/arch/ia64/kernel/irq.c +++ b/arch/ia64/kernel/irq.c | |||
| @@ -112,11 +112,11 @@ void set_irq_affinity_info (unsigned int irq, int hwid, int redir) | |||
| 112 | } | 112 | } |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | bool is_affinity_mask_valid(cpumask_t cpumask) | 115 | bool is_affinity_mask_valid(cpumask_var_t cpumask) |
| 116 | { | 116 | { |
| 117 | if (ia64_platform_is("sn2")) { | 117 | if (ia64_platform_is("sn2")) { |
| 118 | /* Only allow one CPU to be specified in the smp_affinity mask */ | 118 | /* Only allow one CPU to be specified in the smp_affinity mask */ |
| 119 | if (cpus_weight(cpumask) != 1) | 119 | if (cpumask_weight(cpumask) != 1) |
| 120 | return false; | 120 | return false; |
| 121 | } | 121 | } |
| 122 | return true; | 122 | return true; |
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 65c10a42c88f..f0ebb342409d 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c | |||
| @@ -93,13 +93,14 @@ void ia64_account_on_switch(struct task_struct *prev, struct task_struct *next) | |||
| 93 | now = ia64_get_itc(); | 93 | now = ia64_get_itc(); |
| 94 | 94 | ||
| 95 | delta_stime = cycle_to_cputime(pi->ac_stime + (now - pi->ac_stamp)); | 95 | delta_stime = cycle_to_cputime(pi->ac_stime + (now - pi->ac_stamp)); |
| 96 | account_system_time(prev, 0, delta_stime); | 96 | if (idle_task(smp_processor_id()) != prev) |
| 97 | account_system_time_scaled(prev, delta_stime); | 97 | account_system_time(prev, 0, delta_stime, delta_stime); |
| 98 | else | ||
| 99 | account_idle_time(delta_stime); | ||
| 98 | 100 | ||
| 99 | if (pi->ac_utime) { | 101 | if (pi->ac_utime) { |
| 100 | delta_utime = cycle_to_cputime(pi->ac_utime); | 102 | delta_utime = cycle_to_cputime(pi->ac_utime); |
| 101 | account_user_time(prev, delta_utime); | 103 | account_user_time(prev, delta_utime, delta_utime); |
| 102 | account_user_time_scaled(prev, delta_utime); | ||
| 103 | } | 104 | } |
| 104 | 105 | ||
| 105 | pi->ac_stamp = ni->ac_stamp = now; | 106 | pi->ac_stamp = ni->ac_stamp = now; |
| @@ -122,8 +123,10 @@ void account_system_vtime(struct task_struct *tsk) | |||
| 122 | now = ia64_get_itc(); | 123 | now = ia64_get_itc(); |
| 123 | 124 | ||
| 124 | delta_stime = cycle_to_cputime(ti->ac_stime + (now - ti->ac_stamp)); | 125 | delta_stime = cycle_to_cputime(ti->ac_stime + (now - ti->ac_stamp)); |
| 125 | account_system_time(tsk, 0, delta_stime); | 126 | if (irq_count() || idle_task(smp_processor_id()) != tsk) |
| 126 | account_system_time_scaled(tsk, delta_stime); | 127 | account_system_time(tsk, 0, delta_stime, delta_stime); |
| 128 | else | ||
| 129 | account_idle_time(delta_stime); | ||
| 127 | ti->ac_stime = 0; | 130 | ti->ac_stime = 0; |
| 128 | 131 | ||
| 129 | ti->ac_stamp = now; | 132 | ti->ac_stamp = now; |
| @@ -143,8 +146,7 @@ void account_process_tick(struct task_struct *p, int user_tick) | |||
| 143 | 146 | ||
| 144 | if (ti->ac_utime) { | 147 | if (ti->ac_utime) { |
| 145 | delta_utime = cycle_to_cputime(ti->ac_utime); | 148 | delta_utime = cycle_to_cputime(ti->ac_utime); |
| 146 | account_user_time(p, delta_utime); | 149 | account_user_time(p, delta_utime, delta_utime); |
| 147 | account_user_time_scaled(p, delta_utime); | ||
| 148 | ti->ac_utime = 0; | 150 | ti->ac_utime = 0; |
| 149 | } | 151 | } |
| 150 | } | 152 | } |
diff --git a/arch/ia64/kvm/Makefile b/arch/ia64/kvm/Makefile index 76464dc312e6..0bb99b732908 100644 --- a/arch/ia64/kvm/Makefile +++ b/arch/ia64/kvm/Makefile | |||
| @@ -51,8 +51,8 @@ EXTRA_AFLAGS += -Ivirt/kvm -Iarch/ia64/kvm/ | |||
| 51 | common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ | 51 | common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ |
| 52 | coalesced_mmio.o irq_comm.o) | 52 | coalesced_mmio.o irq_comm.o) |
| 53 | 53 | ||
| 54 | ifeq ($(CONFIG_DMAR),y) | 54 | ifeq ($(CONFIG_IOMMU_API),y) |
| 55 | common-objs += $(addprefix ../../../virt/kvm/, vtd.o) | 55 | common-objs += $(addprefix ../../../virt/kvm/, iommu.o) |
| 56 | endif | 56 | endif |
| 57 | 57 | ||
| 58 | kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o | 58 | kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o |
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 0f5ebd948437..4e586f6110aa 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/bitops.h> | 31 | #include <linux/bitops.h> |
| 32 | #include <linux/hrtimer.h> | 32 | #include <linux/hrtimer.h> |
| 33 | #include <linux/uaccess.h> | 33 | #include <linux/uaccess.h> |
| 34 | #include <linux/iommu.h> | ||
| 34 | #include <linux/intel-iommu.h> | 35 | #include <linux/intel-iommu.h> |
| 35 | 36 | ||
| 36 | #include <asm/pgtable.h> | 37 | #include <asm/pgtable.h> |
| @@ -188,7 +189,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
| 188 | r = KVM_COALESCED_MMIO_PAGE_OFFSET; | 189 | r = KVM_COALESCED_MMIO_PAGE_OFFSET; |
| 189 | break; | 190 | break; |
| 190 | case KVM_CAP_IOMMU: | 191 | case KVM_CAP_IOMMU: |
| 191 | r = intel_iommu_found(); | 192 | r = iommu_found(); |
| 192 | break; | 193 | break; |
| 193 | default: | 194 | default: |
| 194 | r = 0; | 195 | r = 0; |
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 636588e7e068..be339477f906 100644 --- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c | |||
| @@ -385,7 +385,6 @@ static int sn_topology_show(struct seq_file *s, void *d) | |||
| 385 | int j; | 385 | int j; |
| 386 | const char *slabname; | 386 | const char *slabname; |
| 387 | int ordinal; | 387 | int ordinal; |
| 388 | cpumask_t cpumask; | ||
| 389 | char slice; | 388 | char slice; |
| 390 | struct cpuinfo_ia64 *c; | 389 | struct cpuinfo_ia64 *c; |
| 391 | struct sn_hwperf_port_info *ptdata; | 390 | struct sn_hwperf_port_info *ptdata; |
| @@ -473,23 +472,21 @@ static int sn_topology_show(struct seq_file *s, void *d) | |||
| 473 | * CPUs on this node, if any | 472 | * CPUs on this node, if any |
| 474 | */ | 473 | */ |
| 475 | if (!SN_HWPERF_IS_IONODE(obj)) { | 474 | if (!SN_HWPERF_IS_IONODE(obj)) { |
| 476 | cpumask = node_to_cpumask(ordinal); | 475 | for_each_cpu_and(i, cpu_online_mask, |
| 477 | for_each_online_cpu(i) { | 476 | cpumask_of_node(ordinal)) { |
| 478 | if (cpu_isset(i, cpumask)) { | 477 | slice = 'a' + cpuid_to_slice(i); |
| 479 | slice = 'a' + cpuid_to_slice(i); | 478 | c = cpu_data(i); |
| 480 | c = cpu_data(i); | 479 | seq_printf(s, "cpu %d %s%c local" |
| 481 | seq_printf(s, "cpu %d %s%c local" | 480 | " freq %luMHz, arch ia64", |
| 482 | " freq %luMHz, arch ia64", | 481 | i, obj->location, slice, |
| 483 | i, obj->location, slice, | 482 | c->proc_freq / 1000000); |
| 484 | c->proc_freq / 1000000); | 483 | for_each_online_cpu(j) { |
| 485 | for_each_online_cpu(j) { | 484 | seq_printf(s, j ? ":%d" : ", dist %d", |
| 486 | seq_printf(s, j ? ":%d" : ", dist %d", | 485 | node_distance( |
| 487 | node_distance( | ||
| 488 | cpu_to_node(i), | 486 | cpu_to_node(i), |
| 489 | cpu_to_node(j))); | 487 | cpu_to_node(j))); |
| 490 | } | ||
| 491 | seq_putc(s, '\n'); | ||
| 492 | } | 488 | } |
| 489 | seq_putc(s, '\n'); | ||
| 493 | } | 490 | } |
| 494 | } | 491 | } |
| 495 | } | 492 | } |
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c index 0f06b3722e96..2547d6c4a827 100644 --- a/arch/m32r/kernel/smpboot.c +++ b/arch/m32r/kernel/smpboot.c | |||
| @@ -592,7 +592,7 @@ int setup_profiling_timer(unsigned int multiplier) | |||
| 592 | * accounting. At that time they also adjust their APIC timers | 592 | * accounting. At that time they also adjust their APIC timers |
| 593 | * accordingly. | 593 | * accordingly. |
| 594 | */ | 594 | */ |
| 595 | for (i = 0; i < NR_CPUS; ++i) | 595 | for_each_possible_cpu(i) |
| 596 | per_cpu(prof_multiplier, i) = multiplier; | 596 | per_cpu(prof_multiplier, i) = multiplier; |
| 597 | 597 | ||
| 598 | return 0; | 598 | return 0; |
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 836fb66f080d..c825bde17cb3 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig | |||
| @@ -280,7 +280,6 @@ config M68060 | |||
| 280 | 280 | ||
| 281 | config MMU_MOTOROLA | 281 | config MMU_MOTOROLA |
| 282 | bool | 282 | bool |
| 283 | depends on MMU && !MMU_SUN3 | ||
| 284 | 283 | ||
| 285 | config MMU_SUN3 | 284 | config MMU_SUN3 |
| 286 | bool | 285 | bool |
diff --git a/arch/m68knommu/include/asm/bitops.h b/arch/m68knommu/include/asm/bitops.h index 6f3685eab44c..9d3cbe5fad1e 100644 --- a/arch/m68knommu/include/asm/bitops.h +++ b/arch/m68knommu/include/asm/bitops.h | |||
| @@ -331,6 +331,7 @@ found_middle: | |||
| 331 | #endif /* __KERNEL__ */ | 331 | #endif /* __KERNEL__ */ |
| 332 | 332 | ||
| 333 | #include <asm-generic/bitops/fls.h> | 333 | #include <asm-generic/bitops/fls.h> |
| 334 | #include <asm-generic/bitops/__fls.h> | ||
| 334 | #include <asm-generic/bitops/fls64.h> | 335 | #include <asm-generic/bitops/fls64.h> |
| 335 | 336 | ||
| 336 | #endif /* _M68KNOMMU_BITOPS_H */ | 337 | #endif /* _M68KNOMMU_BITOPS_H */ |
diff --git a/arch/mips/include/asm/mach-ip27/topology.h b/arch/mips/include/asm/mach-ip27/topology.h index 1fb959f98982..55d481569a1f 100644 --- a/arch/mips/include/asm/mach-ip27/topology.h +++ b/arch/mips/include/asm/mach-ip27/topology.h | |||
| @@ -25,11 +25,13 @@ extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS]; | |||
| 25 | #define cpu_to_node(cpu) (sn_cpu_info[(cpu)].p_nodeid) | 25 | #define cpu_to_node(cpu) (sn_cpu_info[(cpu)].p_nodeid) |
| 26 | #define parent_node(node) (node) | 26 | #define parent_node(node) (node) |
| 27 | #define node_to_cpumask(node) (hub_data(node)->h_cpus) | 27 | #define node_to_cpumask(node) (hub_data(node)->h_cpus) |
| 28 | #define node_to_first_cpu(node) (first_cpu(node_to_cpumask(node))) | 28 | #define cpumask_of_node(node) (&hub_data(node)->h_cpus) |
| 29 | #define node_to_first_cpu(node) (cpumask_first(cpumask_of_node(node))) | ||
| 29 | struct pci_bus; | 30 | struct pci_bus; |
| 30 | extern int pcibus_to_node(struct pci_bus *); | 31 | extern int pcibus_to_node(struct pci_bus *); |
| 31 | 32 | ||
| 32 | #define pcibus_to_cpumask(bus) (cpu_online_map) | 33 | #define pcibus_to_cpumask(bus) (cpu_online_map) |
| 34 | #define cpumask_of_pcibus(bus) (cpu_online_mask) | ||
| 33 | 35 | ||
| 34 | extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES]; | 36 | extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES]; |
| 35 | 37 | ||
diff --git a/arch/parisc/include/asm/smp.h b/arch/parisc/include/asm/smp.h index 409e698f4361..6ef4b7867b1b 100644 --- a/arch/parisc/include/asm/smp.h +++ b/arch/parisc/include/asm/smp.h | |||
| @@ -16,8 +16,6 @@ | |||
| 16 | #include <linux/cpumask.h> | 16 | #include <linux/cpumask.h> |
| 17 | typedef unsigned long address_t; | 17 | typedef unsigned long address_t; |
| 18 | 18 | ||
| 19 | extern cpumask_t cpu_online_map; | ||
| 20 | |||
| 21 | 19 | ||
| 22 | /* | 20 | /* |
| 23 | * Private routines/data | 21 | * Private routines/data |
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index 373fca394a54..375258559ae6 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h | |||
| @@ -22,11 +22,11 @@ static inline cpumask_t node_to_cpumask(int node) | |||
| 22 | return numa_cpumask_lookup_table[node]; | 22 | return numa_cpumask_lookup_table[node]; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | #define cpumask_of_node(node) (&numa_cpumask_lookup_table[node]) | ||
| 26 | |||
| 25 | static inline int node_to_first_cpu(int node) | 27 | static inline int node_to_first_cpu(int node) |
| 26 | { | 28 | { |
| 27 | cpumask_t tmp; | 29 | return cpumask_first(cpumask_of_node(node)); |
| 28 | tmp = node_to_cpumask(node); | ||
| 29 | return first_cpu(tmp); | ||
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | int of_node_to_nid(struct device_node *device); | 32 | int of_node_to_nid(struct device_node *device); |
| @@ -46,6 +46,10 @@ static inline int pcibus_to_node(struct pci_bus *bus) | |||
| 46 | node_to_cpumask(pcibus_to_node(bus)) \ | 46 | node_to_cpumask(pcibus_to_node(bus)) \ |
| 47 | ) | 47 | ) |
| 48 | 48 | ||
| 49 | #define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \ | ||
| 50 | cpu_all_mask : \ | ||
| 51 | cpumask_of_node(pcibus_to_node(bus))) | ||
| 52 | |||
| 49 | /* sched_domains SD_NODE_INIT for PPC64 machines */ | 53 | /* sched_domains SD_NODE_INIT for PPC64 machines */ |
| 50 | #define SD_NODE_INIT (struct sched_domain) { \ | 54 | #define SD_NODE_INIT (struct sched_domain) { \ |
| 51 | .parent = NULL, \ | 55 | .parent = NULL, \ |
| @@ -108,6 +112,8 @@ static inline void sysfs_remove_device_from_node(struct sys_device *dev, | |||
| 108 | 112 | ||
| 109 | #define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu)) | 113 | #define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu)) |
| 110 | #define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu)) | 114 | #define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu)) |
| 115 | #define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu)) | ||
| 116 | #define topology_core_cpumask(cpu) (&per_cpu(cpu_core_map, cpu)) | ||
| 111 | #define topology_core_id(cpu) (cpu_to_core_id(cpu)) | 117 | #define topology_core_id(cpu) (cpu_to_core_id(cpu)) |
| 112 | #endif | 118 | #endif |
| 113 | #endif | 119 | #endif |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 51b201ddf9a1..fb7049c054c0 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/mqueue.h> | 33 | #include <linux/mqueue.h> |
| 34 | #include <linux/hardirq.h> | 34 | #include <linux/hardirq.h> |
| 35 | #include <linux/utsname.h> | 35 | #include <linux/utsname.h> |
| 36 | #include <linux/kernel_stat.h> | ||
| 36 | 37 | ||
| 37 | #include <asm/pgtable.h> | 38 | #include <asm/pgtable.h> |
| 38 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 99f1ddd68582..c9564031a2a9 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
| @@ -256,8 +256,10 @@ void account_system_vtime(struct task_struct *tsk) | |||
| 256 | delta += sys_time; | 256 | delta += sys_time; |
| 257 | get_paca()->system_time = 0; | 257 | get_paca()->system_time = 0; |
| 258 | } | 258 | } |
| 259 | account_system_time(tsk, 0, delta); | 259 | if (in_irq() || idle_task(smp_processor_id()) != tsk) |
| 260 | account_system_time_scaled(tsk, deltascaled); | 260 | account_system_time(tsk, 0, delta, deltascaled); |
| 261 | else | ||
| 262 | account_idle_time(delta); | ||
| 261 | per_cpu(cputime_last_delta, smp_processor_id()) = delta; | 263 | per_cpu(cputime_last_delta, smp_processor_id()) = delta; |
| 262 | per_cpu(cputime_scaled_last_delta, smp_processor_id()) = deltascaled; | 264 | per_cpu(cputime_scaled_last_delta, smp_processor_id()) = deltascaled; |
| 263 | local_irq_restore(flags); | 265 | local_irq_restore(flags); |
| @@ -275,10 +277,8 @@ void account_process_tick(struct task_struct *tsk, int user_tick) | |||
| 275 | 277 | ||
| 276 | utime = get_paca()->user_time; | 278 | utime = get_paca()->user_time; |
| 277 | get_paca()->user_time = 0; | 279 | get_paca()->user_time = 0; |
| 278 | account_user_time(tsk, utime); | ||
| 279 | |||
| 280 | utimescaled = cputime_to_scaled(utime); | 280 | utimescaled = cputime_to_scaled(utime); |
| 281 | account_user_time_scaled(tsk, utimescaled); | 281 | account_user_time(tsk, utime, utimescaled); |
| 282 | } | 282 | } |
| 283 | 283 | ||
| 284 | /* | 284 | /* |
| @@ -338,8 +338,12 @@ void calculate_steal_time(void) | |||
| 338 | tb = mftb(); | 338 | tb = mftb(); |
| 339 | purr = mfspr(SPRN_PURR); | 339 | purr = mfspr(SPRN_PURR); |
| 340 | stolen = (tb - pme->tb) - (purr - pme->purr); | 340 | stolen = (tb - pme->tb) - (purr - pme->purr); |
| 341 | if (stolen > 0) | 341 | if (stolen > 0) { |
| 342 | account_steal_time(current, stolen); | 342 | if (idle_task(smp_processor_id()) != current) |
| 343 | account_steal_time(stolen); | ||
| 344 | else | ||
| 345 | account_idle_time(stolen); | ||
| 346 | } | ||
| 343 | pme->tb = tb; | 347 | pme->tb = tb; |
| 344 | pme->purr = purr; | 348 | pme->purr = purr; |
| 345 | } | 349 | } |
diff --git a/arch/powerpc/platforms/cell/spu_priv1_mmio.c b/arch/powerpc/platforms/cell/spu_priv1_mmio.c index 906a0a2a9fe1..1410443731eb 100644 --- a/arch/powerpc/platforms/cell/spu_priv1_mmio.c +++ b/arch/powerpc/platforms/cell/spu_priv1_mmio.c | |||
| @@ -80,10 +80,10 @@ static void cpu_affinity_set(struct spu *spu, int cpu) | |||
| 80 | u64 route; | 80 | u64 route; |
| 81 | 81 | ||
| 82 | if (nr_cpus_node(spu->node)) { | 82 | if (nr_cpus_node(spu->node)) { |
| 83 | cpumask_t spumask = node_to_cpumask(spu->node); | 83 | const struct cpumask *spumask = cpumask_of_node(spu->node), |
| 84 | cpumask_t cpumask = node_to_cpumask(cpu_to_node(cpu)); | 84 | *cpumask = cpumask_of_node(cpu_to_node(cpu)); |
| 85 | 85 | ||
| 86 | if (!cpus_intersects(spumask, cpumask)) | 86 | if (!cpumask_intersects(spumask, cpumask)) |
| 87 | return; | 87 | return; |
| 88 | } | 88 | } |
| 89 | 89 | ||
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 2ad914c47493..6a0ad196aeb3 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c | |||
| @@ -166,9 +166,9 @@ void spu_update_sched_info(struct spu_context *ctx) | |||
| 166 | static int __node_allowed(struct spu_context *ctx, int node) | 166 | static int __node_allowed(struct spu_context *ctx, int node) |
| 167 | { | 167 | { |
| 168 | if (nr_cpus_node(node)) { | 168 | if (nr_cpus_node(node)) { |
| 169 | cpumask_t mask = node_to_cpumask(node); | 169 | const struct cpumask *mask = cpumask_of_node(node); |
| 170 | 170 | ||
| 171 | if (cpus_intersects(mask, ctx->cpus_allowed)) | 171 | if (cpumask_intersects(mask, &ctx->cpus_allowed)) |
| 172 | return 1; | 172 | return 1; |
| 173 | } | 173 | } |
| 174 | 174 | ||
diff --git a/arch/s390/include/asm/cpu.h b/arch/s390/include/asm/cpu.h index e5a6a9ba3adf..d60a2eefb17b 100644 --- a/arch/s390/include/asm/cpu.h +++ b/arch/s390/include/asm/cpu.h | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | 14 | ||
| 15 | struct s390_idle_data { | 15 | struct s390_idle_data { |
| 16 | spinlock_t lock; | 16 | spinlock_t lock; |
| 17 | unsigned int in_idle; | ||
| 18 | unsigned long long idle_count; | 17 | unsigned long long idle_count; |
| 19 | unsigned long long idle_enter; | 18 | unsigned long long idle_enter; |
| 20 | unsigned long long idle_time; | 19 | unsigned long long idle_time; |
| @@ -22,12 +21,12 @@ struct s390_idle_data { | |||
| 22 | 21 | ||
| 23 | DECLARE_PER_CPU(struct s390_idle_data, s390_idle); | 22 | DECLARE_PER_CPU(struct s390_idle_data, s390_idle); |
| 24 | 23 | ||
| 25 | void s390_idle_leave(void); | 24 | void vtime_start_cpu(void); |
| 26 | 25 | ||
| 27 | static inline void s390_idle_check(void) | 26 | static inline void s390_idle_check(void) |
| 28 | { | 27 | { |
| 29 | if ((&__get_cpu_var(s390_idle))->in_idle) | 28 | if ((&__get_cpu_var(s390_idle))->idle_enter != 0ULL) |
| 30 | s390_idle_leave(); | 29 | vtime_start_cpu(); |
| 31 | } | 30 | } |
| 32 | 31 | ||
| 33 | #endif /* _ASM_S390_CPU_H_ */ | 32 | #endif /* _ASM_S390_CPU_H_ */ |
diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h index 133ce054fc89..521726430afa 100644 --- a/arch/s390/include/asm/cputime.h +++ b/arch/s390/include/asm/cputime.h | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | #include <asm/div64.h> | 12 | #include <asm/div64.h> |
| 13 | 13 | ||
| 14 | /* We want to use micro-second resolution. */ | 14 | /* We want to use full resolution of the CPU timer: 2**-12 micro-seconds. */ |
| 15 | 15 | ||
| 16 | typedef unsigned long long cputime_t; | 16 | typedef unsigned long long cputime_t; |
| 17 | typedef unsigned long long cputime64_t; | 17 | typedef unsigned long long cputime64_t; |
| @@ -53,9 +53,9 @@ __div(unsigned long long n, unsigned int base) | |||
| 53 | #define cputime_ge(__a, __b) ((__a) >= (__b)) | 53 | #define cputime_ge(__a, __b) ((__a) >= (__b)) |
| 54 | #define cputime_lt(__a, __b) ((__a) < (__b)) | 54 | #define cputime_lt(__a, __b) ((__a) < (__b)) |
| 55 | #define cputime_le(__a, __b) ((__a) <= (__b)) | 55 | #define cputime_le(__a, __b) ((__a) <= (__b)) |
| 56 | #define cputime_to_jiffies(__ct) (__div((__ct), 1000000 / HZ)) | 56 | #define cputime_to_jiffies(__ct) (__div((__ct), 4096000000ULL / HZ)) |
| 57 | #define cputime_to_scaled(__ct) (__ct) | 57 | #define cputime_to_scaled(__ct) (__ct) |
| 58 | #define jiffies_to_cputime(__hz) ((cputime_t)(__hz) * (1000000 / HZ)) | 58 | #define jiffies_to_cputime(__hz) ((cputime_t)(__hz) * (4096000000ULL / HZ)) |
| 59 | 59 | ||
| 60 | #define cputime64_zero (0ULL) | 60 | #define cputime64_zero (0ULL) |
| 61 | #define cputime64_add(__a, __b) ((__a) + (__b)) | 61 | #define cputime64_add(__a, __b) ((__a) + (__b)) |
| @@ -64,7 +64,7 @@ __div(unsigned long long n, unsigned int base) | |||
| 64 | static inline u64 | 64 | static inline u64 |
| 65 | cputime64_to_jiffies64(cputime64_t cputime) | 65 | cputime64_to_jiffies64(cputime64_t cputime) |
| 66 | { | 66 | { |
| 67 | do_div(cputime, 1000000 / HZ); | 67 | do_div(cputime, 4096000000ULL / HZ); |
| 68 | return cputime; | 68 | return cputime; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| @@ -74,13 +74,13 @@ cputime64_to_jiffies64(cputime64_t cputime) | |||
| 74 | static inline unsigned int | 74 | static inline unsigned int |
| 75 | cputime_to_msecs(const cputime_t cputime) | 75 | cputime_to_msecs(const cputime_t cputime) |
| 76 | { | 76 | { |
| 77 | return __div(cputime, 1000); | 77 | return __div(cputime, 4096000); |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | static inline cputime_t | 80 | static inline cputime_t |
| 81 | msecs_to_cputime(const unsigned int m) | 81 | msecs_to_cputime(const unsigned int m) |
| 82 | { | 82 | { |
| 83 | return (cputime_t) m * 1000; | 83 | return (cputime_t) m * 4096000; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | /* | 86 | /* |
| @@ -89,13 +89,13 @@ msecs_to_cputime(const unsigned int m) | |||
| 89 | static inline unsigned int | 89 | static inline unsigned int |
| 90 | cputime_to_secs(const cputime_t cputime) | 90 | cputime_to_secs(const cputime_t cputime) |
| 91 | { | 91 | { |
| 92 | return __div(cputime, 1000000); | 92 | return __div(cputime, 2048000000) >> 1; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | static inline cputime_t | 95 | static inline cputime_t |
| 96 | secs_to_cputime(const unsigned int s) | 96 | secs_to_cputime(const unsigned int s) |
| 97 | { | 97 | { |
| 98 | return (cputime_t) s * 1000000; | 98 | return (cputime_t) s * 4096000000ULL; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | /* | 101 | /* |
| @@ -104,7 +104,7 @@ secs_to_cputime(const unsigned int s) | |||
| 104 | static inline cputime_t | 104 | static inline cputime_t |
| 105 | timespec_to_cputime(const struct timespec *value) | 105 | timespec_to_cputime(const struct timespec *value) |
| 106 | { | 106 | { |
| 107 | return value->tv_nsec / 1000 + (u64) value->tv_sec * 1000000; | 107 | return value->tv_nsec * 4096 / 1000 + (u64) value->tv_sec * 4096000000ULL; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | static inline void | 110 | static inline void |
| @@ -114,12 +114,12 @@ cputime_to_timespec(const cputime_t cputime, struct timespec *value) | |||
| 114 | register_pair rp; | 114 | register_pair rp; |
| 115 | 115 | ||
| 116 | rp.pair = cputime >> 1; | 116 | rp.pair = cputime >> 1; |
| 117 | asm ("dr %0,%1" : "+d" (rp) : "d" (1000000 >> 1)); | 117 | asm ("dr %0,%1" : "+d" (rp) : "d" (2048000000UL)); |
| 118 | value->tv_nsec = rp.subreg.even * 1000; | 118 | value->tv_nsec = rp.subreg.even * 1000 / 4096; |
| 119 | value->tv_sec = rp.subreg.odd; | 119 | value->tv_sec = rp.subreg.odd; |
| 120 | #else | 120 | #else |
| 121 | value->tv_nsec = (cputime % 1000000) * 1000; | 121 | value->tv_nsec = (cputime % 4096000000ULL) * 1000 / 4096; |
| 122 | value->tv_sec = cputime / 1000000; | 122 | value->tv_sec = cputime / 4096000000ULL; |
| 123 | #endif | 123 | #endif |
| 124 | } | 124 | } |
| 125 | 125 | ||
| @@ -131,7 +131,7 @@ cputime_to_timespec(const cputime_t cputime, struct timespec *value) | |||
| 131 | static inline cputime_t | 131 | static inline cputime_t |
| 132 | timeval_to_cputime(const struct timeval *value) | 132 | timeval_to_cputime(const struct timeval *value) |
| 133 | { | 133 | { |
| 134 | return value->tv_usec + (u64) value->tv_sec * 1000000; | 134 | return value->tv_usec * 4096 + (u64) value->tv_sec * 4096000000ULL; |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | static inline void | 137 | static inline void |
| @@ -141,12 +141,12 @@ cputime_to_timeval(const cputime_t cputime, struct timeval *value) | |||
| 141 | register_pair rp; | 141 | register_pair rp; |
| 142 | 142 | ||
| 143 | rp.pair = cputime >> 1; | 143 | rp.pair = cputime >> 1; |
| 144 | asm ("dr %0,%1" : "+d" (rp) : "d" (1000000 >> 1)); | 144 | asm ("dr %0,%1" : "+d" (rp) : "d" (2048000000UL)); |
| 145 | value->tv_usec = rp.subreg.even; | 145 | value->tv_usec = rp.subreg.even / 4096; |
| 146 | value->tv_sec = rp.subreg.odd; | 146 | value->tv_sec = rp.subreg.odd; |
| 147 | #else | 147 | #else |
| 148 | value->tv_usec = cputime % 1000000; | 148 | value->tv_usec = cputime % 4096000000ULL; |
| 149 | value->tv_sec = cputime / 1000000; | 149 | value->tv_sec = cputime / 4096000000ULL; |
| 150 | #endif | 150 | #endif |
| 151 | } | 151 | } |
| 152 | 152 | ||
| @@ -156,13 +156,13 @@ cputime_to_timeval(const cputime_t cputime, struct timeval *value) | |||
| 156 | static inline clock_t | 156 | static inline clock_t |
| 157 | cputime_to_clock_t(cputime_t cputime) | 157 | cputime_to_clock_t(cputime_t cputime) |
| 158 | { | 158 | { |
| 159 | return __div(cputime, 1000000 / USER_HZ); | 159 | return __div(cputime, 4096000000ULL / USER_HZ); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | static inline cputime_t | 162 | static inline cputime_t |
| 163 | clock_t_to_cputime(unsigned long x) | 163 | clock_t_to_cputime(unsigned long x) |
| 164 | { | 164 | { |
| 165 | return (cputime_t) x * (1000000 / USER_HZ); | 165 | return (cputime_t) x * (4096000000ULL / USER_HZ); |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | /* | 168 | /* |
| @@ -171,7 +171,7 @@ clock_t_to_cputime(unsigned long x) | |||
| 171 | static inline clock_t | 171 | static inline clock_t |
| 172 | cputime64_to_clock_t(cputime64_t cputime) | 172 | cputime64_to_clock_t(cputime64_t cputime) |
| 173 | { | 173 | { |
| 174 | return __div(cputime, 1000000 / USER_HZ); | 174 | return __div(cputime, 4096000000ULL / USER_HZ); |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | #endif /* _S390_CPUTIME_H */ | 177 | #endif /* _S390_CPUTIME_H */ |
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index 0bc51d52a899..ffdef5fe8587 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h | |||
| @@ -67,11 +67,11 @@ | |||
| 67 | #define __LC_SYNC_ENTER_TIMER 0x248 | 67 | #define __LC_SYNC_ENTER_TIMER 0x248 |
| 68 | #define __LC_ASYNC_ENTER_TIMER 0x250 | 68 | #define __LC_ASYNC_ENTER_TIMER 0x250 |
| 69 | #define __LC_EXIT_TIMER 0x258 | 69 | #define __LC_EXIT_TIMER 0x258 |
| 70 | #define __LC_LAST_UPDATE_TIMER 0x260 | 70 | #define __LC_USER_TIMER 0x260 |
| 71 | #define __LC_USER_TIMER 0x268 | 71 | #define __LC_SYSTEM_TIMER 0x268 |
| 72 | #define __LC_SYSTEM_TIMER 0x270 | 72 | #define __LC_STEAL_TIMER 0x270 |
| 73 | #define __LC_LAST_UPDATE_CLOCK 0x278 | 73 | #define __LC_LAST_UPDATE_TIMER 0x278 |
| 74 | #define __LC_STEAL_CLOCK 0x280 | 74 | #define __LC_LAST_UPDATE_CLOCK 0x280 |
| 75 | #define __LC_RETURN_MCCK_PSW 0x288 | 75 | #define __LC_RETURN_MCCK_PSW 0x288 |
| 76 | #define __LC_KERNEL_STACK 0xC40 | 76 | #define __LC_KERNEL_STACK 0xC40 |
| 77 | #define __LC_THREAD_INFO 0xC44 | 77 | #define __LC_THREAD_INFO 0xC44 |
| @@ -89,11 +89,11 @@ | |||
| 89 | #define __LC_SYNC_ENTER_TIMER 0x250 | 89 | #define __LC_SYNC_ENTER_TIMER 0x250 |
| 90 | #define __LC_ASYNC_ENTER_TIMER 0x258 | 90 | #define __LC_ASYNC_ENTER_TIMER 0x258 |
| 91 | #define __LC_EXIT_TIMER 0x260 | 91 | #define __LC_EXIT_TIMER 0x260 |
| 92 | #define __LC_LAST_UPDATE_TIMER 0x268 | 92 | #define __LC_USER_TIMER 0x268 |
| 93 | #define __LC_USER_TIMER 0x270 | 93 | #define __LC_SYSTEM_TIMER 0x270 |
| 94 | #define __LC_SYSTEM_TIMER 0x278 | 94 | #define __LC_STEAL_TIMER 0x278 |
| 95 | #define __LC_LAST_UPDATE_CLOCK 0x280 | 95 | #define __LC_LAST_UPDATE_TIMER 0x280 |
| 96 | #define __LC_STEAL_CLOCK 0x288 | 96 | #define __LC_LAST_UPDATE_CLOCK 0x288 |
| 97 | #define __LC_RETURN_MCCK_PSW 0x290 | 97 | #define __LC_RETURN_MCCK_PSW 0x290 |
| 98 | #define __LC_KERNEL_STACK 0xD40 | 98 | #define __LC_KERNEL_STACK 0xD40 |
| 99 | #define __LC_THREAD_INFO 0xD48 | 99 | #define __LC_THREAD_INFO 0xD48 |
| @@ -106,8 +106,10 @@ | |||
| 106 | #define __LC_IPLDEV 0xDB8 | 106 | #define __LC_IPLDEV 0xDB8 |
| 107 | #define __LC_CURRENT 0xDD8 | 107 | #define __LC_CURRENT 0xDD8 |
| 108 | #define __LC_INT_CLOCK 0xDE8 | 108 | #define __LC_INT_CLOCK 0xDE8 |
| 109 | #define __LC_VDSO_PER_CPU 0xE38 | ||
| 109 | #endif /* __s390x__ */ | 110 | #endif /* __s390x__ */ |
| 110 | 111 | ||
| 112 | #define __LC_PASTE 0xE40 | ||
| 111 | 113 | ||
| 112 | #define __LC_PANIC_MAGIC 0xE00 | 114 | #define __LC_PANIC_MAGIC 0xE00 |
| 113 | #ifndef __s390x__ | 115 | #ifndef __s390x__ |
| @@ -252,11 +254,11 @@ struct _lowcore | |||
| 252 | __u64 sync_enter_timer; /* 0x248 */ | 254 | __u64 sync_enter_timer; /* 0x248 */ |
| 253 | __u64 async_enter_timer; /* 0x250 */ | 255 | __u64 async_enter_timer; /* 0x250 */ |
| 254 | __u64 exit_timer; /* 0x258 */ | 256 | __u64 exit_timer; /* 0x258 */ |
| 255 | __u64 last_update_timer; /* 0x260 */ | 257 | __u64 user_timer; /* 0x260 */ |
| 256 | __u64 user_timer; /* 0x268 */ | 258 | __u64 system_timer; /* 0x268 */ |
| 257 | __u64 system_timer; /* 0x270 */ | 259 | __u64 steal_timer; /* 0x270 */ |
| 258 | __u64 last_update_clock; /* 0x278 */ | 260 | __u64 last_update_timer; /* 0x278 */ |
| 259 | __u64 steal_clock; /* 0x280 */ | 261 | __u64 last_update_clock; /* 0x280 */ |
| 260 | psw_t return_mcck_psw; /* 0x288 */ | 262 | psw_t return_mcck_psw; /* 0x288 */ |
| 261 | __u8 pad8[0xc00-0x290]; /* 0x290 */ | 263 | __u8 pad8[0xc00-0x290]; /* 0x290 */ |
| 262 | 264 | ||
| @@ -343,11 +345,11 @@ struct _lowcore | |||
| 343 | __u64 sync_enter_timer; /* 0x250 */ | 345 | __u64 sync_enter_timer; /* 0x250 */ |
| 344 | __u64 async_enter_timer; /* 0x258 */ | 346 | __u64 async_enter_timer; /* 0x258 */ |
| 345 | __u64 exit_timer; /* 0x260 */ | 347 | __u64 exit_timer; /* 0x260 */ |
| 346 | __u64 last_update_timer; /* 0x268 */ | 348 | __u64 user_timer; /* 0x268 */ |
| 347 | __u64 user_timer; /* 0x270 */ | 349 | __u64 system_timer; /* 0x270 */ |
| 348 | __u64 system_timer; /* 0x278 */ | 350 | __u64 steal_timer; /* 0x278 */ |
| 349 | __u64 last_update_clock; /* 0x280 */ | 351 | __u64 last_update_timer; /* 0x280 */ |
| 350 | __u64 steal_clock; /* 0x288 */ | 352 | __u64 last_update_clock; /* 0x288 */ |
| 351 | psw_t return_mcck_psw; /* 0x290 */ | 353 | psw_t return_mcck_psw; /* 0x290 */ |
| 352 | __u8 pad8[0xc00-0x2a0]; /* 0x2a0 */ | 354 | __u8 pad8[0xc00-0x2a0]; /* 0x2a0 */ |
| 353 | /* System info area */ | 355 | /* System info area */ |
| @@ -381,7 +383,12 @@ struct _lowcore | |||
| 381 | /* whether the kernel died with panic() or not */ | 383 | /* whether the kernel died with panic() or not */ |
| 382 | __u32 panic_magic; /* 0xe00 */ | 384 | __u32 panic_magic; /* 0xe00 */ |
| 383 | 385 | ||
| 384 | __u8 pad13[0x11b8-0xe04]; /* 0xe04 */ | 386 | /* Per cpu primary space access list */ |
| 387 | __u8 pad_0xe04[0xe3c-0xe04]; /* 0xe04 */ | ||
| 388 | __u32 vdso_per_cpu_data; /* 0xe3c */ | ||
| 389 | __u32 paste[16]; /* 0xe40 */ | ||
| 390 | |||
| 391 | __u8 pad13[0x11b8-0xe80]; /* 0xe80 */ | ||
| 385 | 392 | ||
| 386 | /* 64 bit extparam used for pfault, diag 250 etc */ | 393 | /* 64 bit extparam used for pfault, diag 250 etc */ |
| 387 | __u64 ext_params2; /* 0x11B8 */ | 394 | __u64 ext_params2; /* 0x11B8 */ |
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h index 024ef42ed6d7..3a8b26eb1f2e 100644 --- a/arch/s390/include/asm/system.h +++ b/arch/s390/include/asm/system.h | |||
| @@ -99,7 +99,7 @@ static inline void restore_access_regs(unsigned int *acrs) | |||
| 99 | prev = __switch_to(prev,next); \ | 99 | prev = __switch_to(prev,next); \ |
| 100 | } while (0) | 100 | } while (0) |
| 101 | 101 | ||
| 102 | extern void account_vtime(struct task_struct *); | 102 | extern void account_vtime(struct task_struct *, struct task_struct *); |
| 103 | extern void account_tick_vtime(struct task_struct *); | 103 | extern void account_tick_vtime(struct task_struct *); |
| 104 | extern void account_system_vtime(struct task_struct *); | 104 | extern void account_system_vtime(struct task_struct *); |
| 105 | 105 | ||
| @@ -121,7 +121,7 @@ static inline void cmma_init(void) { } | |||
| 121 | 121 | ||
| 122 | #define finish_arch_switch(prev) do { \ | 122 | #define finish_arch_switch(prev) do { \ |
| 123 | set_fs(current->thread.mm_segment); \ | 123 | set_fs(current->thread.mm_segment); \ |
| 124 | account_vtime(prev); \ | 124 | account_vtime(prev, current); \ |
| 125 | } while (0) | 125 | } while (0) |
| 126 | 126 | ||
| 127 | #define nop() asm volatile("nop") | 127 | #define nop() asm volatile("nop") |
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index c1eaf9604da7..c544aa524535 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h | |||
| @@ -47,6 +47,8 @@ struct thread_info { | |||
| 47 | unsigned int cpu; /* current CPU */ | 47 | unsigned int cpu; /* current CPU */ |
| 48 | int preempt_count; /* 0 => preemptable, <0 => BUG */ | 48 | int preempt_count; /* 0 => preemptable, <0 => BUG */ |
| 49 | struct restart_block restart_block; | 49 | struct restart_block restart_block; |
| 50 | __u64 user_timer; | ||
| 51 | __u64 system_timer; | ||
| 50 | }; | 52 | }; |
| 51 | 53 | ||
| 52 | /* | 54 | /* |
diff --git a/arch/s390/include/asm/timer.h b/arch/s390/include/asm/timer.h index 61705d60f995..e4bcab739c19 100644 --- a/arch/s390/include/asm/timer.h +++ b/arch/s390/include/asm/timer.h | |||
| @@ -23,20 +23,18 @@ struct vtimer_list { | |||
| 23 | __u64 expires; | 23 | __u64 expires; |
| 24 | __u64 interval; | 24 | __u64 interval; |
| 25 | 25 | ||
| 26 | spinlock_t lock; | ||
| 27 | unsigned long magic; | ||
| 28 | |||
| 29 | void (*function)(unsigned long); | 26 | void (*function)(unsigned long); |
| 30 | unsigned long data; | 27 | unsigned long data; |
| 31 | }; | 28 | }; |
| 32 | 29 | ||
| 33 | /* the offset value will wrap after ca. 71 years */ | 30 | /* the vtimer value will wrap after ca. 71 years */ |
| 34 | struct vtimer_queue { | 31 | struct vtimer_queue { |
| 35 | struct list_head list; | 32 | struct list_head list; |
| 36 | spinlock_t lock; | 33 | spinlock_t lock; |
| 37 | __u64 to_expire; /* current event expire time */ | 34 | __u64 timer; /* last programmed timer */ |
| 38 | __u64 offset; /* list offset to zero */ | 35 | __u64 elapsed; /* elapsed time of timer expire values */ |
| 39 | __u64 idle; /* temp var for idle */ | 36 | __u64 idle; /* temp var for idle */ |
| 37 | int do_spt; /* =1: reprogram cpu timer in idle */ | ||
| 40 | }; | 38 | }; |
| 41 | 39 | ||
| 42 | extern void init_virt_timer(struct vtimer_list *timer); | 40 | extern void init_virt_timer(struct vtimer_list *timer); |
| @@ -48,8 +46,8 @@ extern int del_virt_timer(struct vtimer_list *timer); | |||
| 48 | extern void init_cpu_vtimer(void); | 46 | extern void init_cpu_vtimer(void); |
| 49 | extern void vtime_init(void); | 47 | extern void vtime_init(void); |
| 50 | 48 | ||
| 51 | extern void vtime_start_cpu_timer(void); | 49 | extern void vtime_stop_cpu(void); |
| 52 | extern void vtime_stop_cpu_timer(void); | 50 | extern void vtime_start_leave(void); |
| 53 | 51 | ||
| 54 | #endif /* __KERNEL__ */ | 52 | #endif /* __KERNEL__ */ |
| 55 | 53 | ||
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h index d96c91643458..c93eb50e1d09 100644 --- a/arch/s390/include/asm/topology.h +++ b/arch/s390/include/asm/topology.h | |||
| @@ -6,10 +6,12 @@ | |||
| 6 | #define mc_capable() (1) | 6 | #define mc_capable() (1) |
| 7 | 7 | ||
| 8 | cpumask_t cpu_coregroup_map(unsigned int cpu); | 8 | cpumask_t cpu_coregroup_map(unsigned int cpu); |
| 9 | const struct cpumask *cpu_coregroup_mask(unsigned int cpu); | ||
| 9 | 10 | ||
| 10 | extern cpumask_t cpu_core_map[NR_CPUS]; | 11 | extern cpumask_t cpu_core_map[NR_CPUS]; |
| 11 | 12 | ||
| 12 | #define topology_core_siblings(cpu) (cpu_core_map[cpu]) | 13 | #define topology_core_siblings(cpu) (cpu_core_map[cpu]) |
| 14 | #define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) | ||
| 13 | 15 | ||
| 14 | int topology_set_cpu_management(int fc); | 16 | int topology_set_cpu_management(int fc); |
| 15 | void topology_schedule_update(void); | 17 | void topology_schedule_update(void); |
diff --git a/arch/s390/include/asm/vdso.h b/arch/s390/include/asm/vdso.h index a44f4fe16a35..7bdd7c8ebc91 100644 --- a/arch/s390/include/asm/vdso.h +++ b/arch/s390/include/asm/vdso.h | |||
| @@ -12,9 +12,9 @@ | |||
| 12 | #ifndef __ASSEMBLY__ | 12 | #ifndef __ASSEMBLY__ |
| 13 | 13 | ||
| 14 | /* | 14 | /* |
| 15 | * Note about this structure: | 15 | * Note about the vdso_data and vdso_per_cpu_data structures: |
| 16 | * | 16 | * |
| 17 | * NEVER USE THIS IN USERSPACE CODE DIRECTLY. The layout of this | 17 | * NEVER USE THEM IN USERSPACE CODE DIRECTLY. The layout of the |
| 18 | * structure is supposed to be known only to the function in the vdso | 18 | * structure is supposed to be known only to the function in the vdso |
| 19 | * itself and may change without notice. | 19 | * itself and may change without notice. |
| 20 | */ | 20 | */ |
| @@ -28,10 +28,21 @@ struct vdso_data { | |||
| 28 | __u64 wtom_clock_nsec; /* 0x28 */ | 28 | __u64 wtom_clock_nsec; /* 0x28 */ |
| 29 | __u32 tz_minuteswest; /* Minutes west of Greenwich 0x30 */ | 29 | __u32 tz_minuteswest; /* Minutes west of Greenwich 0x30 */ |
| 30 | __u32 tz_dsttime; /* Type of dst correction 0x34 */ | 30 | __u32 tz_dsttime; /* Type of dst correction 0x34 */ |
| 31 | __u32 ectg_available; | ||
| 32 | }; | ||
| 33 | |||
| 34 | struct vdso_per_cpu_data { | ||
| 35 | __u64 ectg_timer_base; | ||
| 36 | __u64 ectg_user_time; | ||
| 31 | }; | 37 | }; |
| 32 | 38 | ||
| 33 | extern struct vdso_data *vdso_data; | 39 | extern struct vdso_data *vdso_data; |
| 34 | 40 | ||
| 41 | #ifdef CONFIG_64BIT | ||
| 42 | int vdso_alloc_per_cpu(int cpu, struct _lowcore *lowcore); | ||
| 43 | void vdso_free_per_cpu(int cpu, struct _lowcore *lowcore); | ||
| 44 | #endif | ||
| 45 | |||
| 35 | #endif /* __ASSEMBLY__ */ | 46 | #endif /* __ASSEMBLY__ */ |
| 36 | 47 | ||
| 37 | #endif /* __KERNEL__ */ | 48 | #endif /* __KERNEL__ */ |
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index e641f60bac99..67a60016babb 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c | |||
| @@ -48,6 +48,11 @@ int main(void) | |||
| 48 | DEFINE(__VDSO_WTOM_SEC, offsetof(struct vdso_data, wtom_clock_sec)); | 48 | DEFINE(__VDSO_WTOM_SEC, offsetof(struct vdso_data, wtom_clock_sec)); |
| 49 | DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec)); | 49 | DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec)); |
| 50 | DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest)); | 50 | DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest)); |
| 51 | DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available)); | ||
| 52 | DEFINE(__VDSO_ECTG_BASE, | ||
| 53 | offsetof(struct vdso_per_cpu_data, ectg_timer_base)); | ||
| 54 | DEFINE(__VDSO_ECTG_USER, | ||
| 55 | offsetof(struct vdso_per_cpu_data, ectg_user_time)); | ||
| 51 | /* constants used by the vdso */ | 56 | /* constants used by the vdso */ |
| 52 | DEFINE(CLOCK_REALTIME, CLOCK_REALTIME); | 57 | DEFINE(CLOCK_REALTIME, CLOCK_REALTIME); |
| 53 | DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC); | 58 | DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC); |
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 55de521aef77..1268aa2991bf 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
| @@ -583,8 +583,8 @@ kernel_per: | |||
| 583 | 583 | ||
| 584 | .globl io_int_handler | 584 | .globl io_int_handler |
| 585 | io_int_handler: | 585 | io_int_handler: |
| 586 | stpt __LC_ASYNC_ENTER_TIMER | ||
| 587 | stck __LC_INT_CLOCK | 586 | stck __LC_INT_CLOCK |
| 587 | stpt __LC_ASYNC_ENTER_TIMER | ||
| 588 | SAVE_ALL_BASE __LC_SAVE_AREA+16 | 588 | SAVE_ALL_BASE __LC_SAVE_AREA+16 |
| 589 | SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 | 589 | SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 |
| 590 | CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 | 590 | CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 |
| @@ -723,8 +723,8 @@ io_notify_resume: | |||
| 723 | 723 | ||
| 724 | .globl ext_int_handler | 724 | .globl ext_int_handler |
| 725 | ext_int_handler: | 725 | ext_int_handler: |
| 726 | stpt __LC_ASYNC_ENTER_TIMER | ||
| 727 | stck __LC_INT_CLOCK | 726 | stck __LC_INT_CLOCK |
| 727 | stpt __LC_ASYNC_ENTER_TIMER | ||
| 728 | SAVE_ALL_BASE __LC_SAVE_AREA+16 | 728 | SAVE_ALL_BASE __LC_SAVE_AREA+16 |
| 729 | SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 | 729 | SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 |
| 730 | CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 | 730 | CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 |
| @@ -750,6 +750,7 @@ __critical_end: | |||
| 750 | 750 | ||
| 751 | .globl mcck_int_handler | 751 | .globl mcck_int_handler |
| 752 | mcck_int_handler: | 752 | mcck_int_handler: |
| 753 | stck __LC_INT_CLOCK | ||
| 753 | spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer | 754 | spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer |
| 754 | lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs | 755 | lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs |
| 755 | SAVE_ALL_BASE __LC_SAVE_AREA+32 | 756 | SAVE_ALL_BASE __LC_SAVE_AREA+32 |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 16bb4fd1a403..c6fbde13971a 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
| @@ -177,8 +177,11 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | |||
| 177 | .if !\sync | 177 | .if !\sync |
| 178 | ni \psworg+1,0xfd # clear wait state bit | 178 | ni \psworg+1,0xfd # clear wait state bit |
| 179 | .endif | 179 | .endif |
| 180 | lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15 of user | 180 | lg %r14,__LC_VDSO_PER_CPU |
| 181 | lmg %r0,%r13,SP_R0(%r15) # load gprs 0-13 of user | ||
| 181 | stpt __LC_EXIT_TIMER | 182 | stpt __LC_EXIT_TIMER |
| 183 | mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER | ||
| 184 | lmg %r14,%r15,SP_R14(%r15) # load grps 14-15 of user | ||
| 182 | lpswe \psworg # back to caller | 185 | lpswe \psworg # back to caller |
| 183 | .endm | 186 | .endm |
| 184 | 187 | ||
| @@ -559,8 +562,8 @@ kernel_per: | |||
| 559 | */ | 562 | */ |
| 560 | .globl io_int_handler | 563 | .globl io_int_handler |
| 561 | io_int_handler: | 564 | io_int_handler: |
| 562 | stpt __LC_ASYNC_ENTER_TIMER | ||
| 563 | stck __LC_INT_CLOCK | 565 | stck __LC_INT_CLOCK |
| 566 | stpt __LC_ASYNC_ENTER_TIMER | ||
| 564 | SAVE_ALL_BASE __LC_SAVE_AREA+32 | 567 | SAVE_ALL_BASE __LC_SAVE_AREA+32 |
| 565 | SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 | 568 | SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 |
| 566 | CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 | 569 | CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 |
| @@ -721,8 +724,8 @@ io_notify_resume: | |||
| 721 | */ | 724 | */ |
| 722 | .globl ext_int_handler | 725 | .globl ext_int_handler |
| 723 | ext_int_handler: | 726 | ext_int_handler: |
| 724 | stpt __LC_ASYNC_ENTER_TIMER | ||
| 725 | stck __LC_INT_CLOCK | 727 | stck __LC_INT_CLOCK |
| 728 | stpt __LC_ASYNC_ENTER_TIMER | ||
| 726 | SAVE_ALL_BASE __LC_SAVE_AREA+32 | 729 | SAVE_ALL_BASE __LC_SAVE_AREA+32 |
| 727 | SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 | 730 | SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 |
| 728 | CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 | 731 | CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 |
| @@ -746,6 +749,7 @@ __critical_end: | |||
| 746 | */ | 749 | */ |
| 747 | .globl mcck_int_handler | 750 | .globl mcck_int_handler |
| 748 | mcck_int_handler: | 751 | mcck_int_handler: |
| 752 | stck __LC_INT_CLOCK | ||
| 749 | la %r1,4095 # revalidate r1 | 753 | la %r1,4095 # revalidate r1 |
| 750 | spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer | 754 | spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer |
| 751 | lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs | 755 | lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs |
| @@ -979,23 +983,23 @@ cleanup_sysc_return: | |||
| 979 | 983 | ||
| 980 | cleanup_sysc_leave: | 984 | cleanup_sysc_leave: |
| 981 | clc 8(8,%r12),BASED(cleanup_sysc_leave_insn) | 985 | clc 8(8,%r12),BASED(cleanup_sysc_leave_insn) |
| 982 | je 2f | 986 | je 3f |
| 983 | mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER | ||
| 984 | clc 8(8,%r12),BASED(cleanup_sysc_leave_insn+8) | 987 | clc 8(8,%r12),BASED(cleanup_sysc_leave_insn+8) |
| 985 | je 2f | 988 | jhe 0f |
| 986 | mvc __LC_RETURN_PSW(16),SP_PSW(%r15) | 989 | mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER |
| 990 | 0: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) | ||
| 987 | cghi %r12,__LC_MCK_OLD_PSW | 991 | cghi %r12,__LC_MCK_OLD_PSW |
| 988 | jne 0f | 992 | jne 1f |
| 989 | mvc __LC_SAVE_AREA+64(32),SP_R12(%r15) | 993 | mvc __LC_SAVE_AREA+64(32),SP_R12(%r15) |
| 990 | j 1f | 994 | j 2f |
| 991 | 0: mvc __LC_SAVE_AREA+32(32),SP_R12(%r15) | 995 | 1: mvc __LC_SAVE_AREA+32(32),SP_R12(%r15) |
| 992 | 1: lmg %r0,%r11,SP_R0(%r15) | 996 | 2: lmg %r0,%r11,SP_R0(%r15) |
| 993 | lg %r15,SP_R15(%r15) | 997 | lg %r15,SP_R15(%r15) |
| 994 | 2: la %r12,__LC_RETURN_PSW | 998 | 3: la %r12,__LC_RETURN_PSW |
| 995 | br %r14 | 999 | br %r14 |
| 996 | cleanup_sysc_leave_insn: | 1000 | cleanup_sysc_leave_insn: |
| 997 | .quad sysc_done - 4 | 1001 | .quad sysc_done - 4 |
| 998 | .quad sysc_done - 8 | 1002 | .quad sysc_done - 16 |
| 999 | 1003 | ||
| 1000 | cleanup_io_return: | 1004 | cleanup_io_return: |
| 1001 | mvc __LC_RETURN_PSW(8),0(%r12) | 1005 | mvc __LC_RETURN_PSW(8),0(%r12) |
| @@ -1005,23 +1009,23 @@ cleanup_io_return: | |||
| 1005 | 1009 | ||
| 1006 | cleanup_io_leave: | 1010 | cleanup_io_leave: |
| 1007 | clc 8(8,%r12),BASED(cleanup_io_leave_insn) | 1011 | clc 8(8,%r12),BASED(cleanup_io_leave_insn) |
| 1008 | je 2f | 1012 | je 3f |
| 1009 | mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER | ||
| 1010 | clc 8(8,%r12),BASED(cleanup_io_leave_insn+8) | 1013 | clc 8(8,%r12),BASED(cleanup_io_leave_insn+8) |
| 1011 | je 2f | 1014 | jhe 0f |
| 1012 | mvc __LC_RETURN_PSW(16),SP_PSW(%r15) | 1015 | mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER |
| 1016 | 0: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) | ||
| 1013 | cghi %r12,__LC_MCK_OLD_PSW | 1017 | cghi %r12,__LC_MCK_OLD_PSW |
| 1014 | jne 0f | 1018 | jne 1f |
| 1015 | mvc __LC_SAVE_AREA+64(32),SP_R12(%r15) | 1019 | mvc __LC_SAVE_AREA+64(32),SP_R12(%r15) |
| 1016 | j 1f | 1020 | j 2f |
| 1017 | 0: mvc __LC_SAVE_AREA+32(32),SP_R12(%r15) | 1021 | 1: mvc __LC_SAVE_AREA+32(32),SP_R12(%r15) |
| 1018 | 1: lmg %r0,%r11,SP_R0(%r15) | 1022 | 2: lmg %r0,%r11,SP_R0(%r15) |
| 1019 | lg %r15,SP_R15(%r15) | 1023 | lg %r15,SP_R15(%r15) |
| 1020 | 2: la %r12,__LC_RETURN_PSW | 1024 | 3: la %r12,__LC_RETURN_PSW |
| 1021 | br %r14 | 1025 | br %r14 |
| 1022 | cleanup_io_leave_insn: | 1026 | cleanup_io_leave_insn: |
| 1023 | .quad io_done - 4 | 1027 | .quad io_done - 4 |
| 1024 | .quad io_done - 8 | 1028 | .quad io_done - 16 |
| 1025 | 1029 | ||
| 1026 | /* | 1030 | /* |
| 1027 | * Integer constants | 1031 | * Integer constants |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 3ccd36b24b8f..f9f70aa15244 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
| @@ -87,6 +87,8 @@ startup_continue: | |||
| 87 | lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area | 87 | lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area |
| 88 | # move IPL device to lowcore | 88 | # move IPL device to lowcore |
| 89 | mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12) | 89 | mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12) |
| 90 | lghi %r0,__LC_PASTE | ||
| 91 | stg %r0,__LC_VDSO_PER_CPU | ||
| 90 | # | 92 | # |
| 91 | # Setup stack | 93 | # Setup stack |
| 92 | # | 94 | # |
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 04f8c67a6101..b6110bdf8dc2 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include <linux/utsname.h> | 38 | #include <linux/utsname.h> |
| 39 | #include <linux/tick.h> | 39 | #include <linux/tick.h> |
| 40 | #include <linux/elfcore.h> | 40 | #include <linux/elfcore.h> |
| 41 | #include <linux/kernel_stat.h> | ||
| 41 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
| 42 | #include <asm/pgtable.h> | 43 | #include <asm/pgtable.h> |
| 43 | #include <asm/system.h> | 44 | #include <asm/system.h> |
| @@ -45,7 +46,6 @@ | |||
| 45 | #include <asm/processor.h> | 46 | #include <asm/processor.h> |
| 46 | #include <asm/irq.h> | 47 | #include <asm/irq.h> |
| 47 | #include <asm/timer.h> | 48 | #include <asm/timer.h> |
| 48 | #include <asm/cpu.h> | ||
| 49 | #include "entry.h" | 49 | #include "entry.h" |
| 50 | 50 | ||
| 51 | asmlinkage void ret_from_fork(void) asm ("ret_from_fork"); | 51 | asmlinkage void ret_from_fork(void) asm ("ret_from_fork"); |
| @@ -75,36 +75,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk) | |||
| 75 | return sf->gprs[8]; | 75 | return sf->gprs[8]; |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | DEFINE_PER_CPU(struct s390_idle_data, s390_idle) = { | ||
| 79 | .lock = __SPIN_LOCK_UNLOCKED(s390_idle.lock) | ||
| 80 | }; | ||
| 81 | |||
| 82 | static int s390_idle_enter(void) | ||
| 83 | { | ||
| 84 | struct s390_idle_data *idle; | ||
| 85 | |||
| 86 | idle = &__get_cpu_var(s390_idle); | ||
| 87 | spin_lock(&idle->lock); | ||
| 88 | idle->idle_count++; | ||
| 89 | idle->in_idle = 1; | ||
| 90 | idle->idle_enter = get_clock(); | ||
| 91 | spin_unlock(&idle->lock); | ||
| 92 | vtime_stop_cpu_timer(); | ||
| 93 | return NOTIFY_OK; | ||
| 94 | } | ||
| 95 | |||
| 96 | void s390_idle_leave(void) | ||
| 97 | { | ||
| 98 | struct s390_idle_data *idle; | ||
| 99 | |||
| 100 | vtime_start_cpu_timer(); | ||
| 101 | idle = &__get_cpu_var(s390_idle); | ||
| 102 | spin_lock(&idle->lock); | ||
| 103 | idle->idle_time += get_clock() - idle->idle_enter; | ||
| 104 | idle->in_idle = 0; | ||
| 105 | spin_unlock(&idle->lock); | ||
| 106 | } | ||
| 107 | |||
| 108 | extern void s390_handle_mcck(void); | 78 | extern void s390_handle_mcck(void); |
| 109 | /* | 79 | /* |
| 110 | * The idle loop on a S390... | 80 | * The idle loop on a S390... |
| @@ -117,10 +87,6 @@ static void default_idle(void) | |||
| 117 | local_irq_enable(); | 87 | local_irq_enable(); |
| 118 | return; | 88 | return; |
| 119 | } | 89 | } |
| 120 | if (s390_idle_enter() == NOTIFY_BAD) { | ||
| 121 | local_irq_enable(); | ||
| 122 | return; | ||
| 123 | } | ||
| 124 | #ifdef CONFIG_HOTPLUG_CPU | 90 | #ifdef CONFIG_HOTPLUG_CPU |
| 125 | if (cpu_is_offline(smp_processor_id())) { | 91 | if (cpu_is_offline(smp_processor_id())) { |
| 126 | preempt_enable_no_resched(); | 92 | preempt_enable_no_resched(); |
| @@ -130,7 +96,6 @@ static void default_idle(void) | |||
| 130 | local_mcck_disable(); | 96 | local_mcck_disable(); |
| 131 | if (test_thread_flag(TIF_MCCK_PENDING)) { | 97 | if (test_thread_flag(TIF_MCCK_PENDING)) { |
| 132 | local_mcck_enable(); | 98 | local_mcck_enable(); |
| 133 | s390_idle_leave(); | ||
| 134 | local_irq_enable(); | 99 | local_irq_enable(); |
| 135 | s390_handle_mcck(); | 100 | s390_handle_mcck(); |
| 136 | return; | 101 | return; |
| @@ -138,9 +103,9 @@ static void default_idle(void) | |||
| 138 | trace_hardirqs_on(); | 103 | trace_hardirqs_on(); |
| 139 | /* Don't trace preempt off for idle. */ | 104 | /* Don't trace preempt off for idle. */ |
| 140 | stop_critical_timings(); | 105 | stop_critical_timings(); |
| 141 | /* Wait for external, I/O or machine check interrupt. */ | 106 | /* Stop virtual timer and halt the cpu. */ |
| 142 | __load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT | | 107 | vtime_stop_cpu(); |
| 143 | PSW_MASK_IO | PSW_MASK_EXT); | 108 | /* Reenable preemption tracer. */ |
| 144 | start_critical_timings(); | 109 | start_critical_timings(); |
| 145 | } | 110 | } |
| 146 | 111 | ||
diff --git a/arch/s390/kernel/s390_ext.c b/arch/s390/kernel/s390_ext.c index e019b419efc6..a0d2d55d7fb3 100644 --- a/arch/s390/kernel/s390_ext.c +++ b/arch/s390/kernel/s390_ext.c | |||
| @@ -119,8 +119,8 @@ void do_extint(struct pt_regs *regs, unsigned short code) | |||
| 119 | struct pt_regs *old_regs; | 119 | struct pt_regs *old_regs; |
| 120 | 120 | ||
| 121 | old_regs = set_irq_regs(regs); | 121 | old_regs = set_irq_regs(regs); |
| 122 | irq_enter(); | ||
| 123 | s390_idle_check(); | 122 | s390_idle_check(); |
| 123 | irq_enter(); | ||
| 124 | if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) | 124 | if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) |
| 125 | /* Serve timer interrupts first. */ | 125 | /* Serve timer interrupts first. */ |
| 126 | clock_comparator_work(); | 126 | clock_comparator_work(); |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index b7a1efd5522c..d825f4950e4e 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
| @@ -427,6 +427,8 @@ setup_lowcore(void) | |||
| 427 | /* enable extended save area */ | 427 | /* enable extended save area */ |
| 428 | __ctl_set_bit(14, 29); | 428 | __ctl_set_bit(14, 29); |
| 429 | } | 429 | } |
| 430 | #else | ||
| 431 | lc->vdso_per_cpu_data = (unsigned long) &lc->paste[0]; | ||
| 430 | #endif | 432 | #endif |
| 431 | set_prefix((u32)(unsigned long) lc); | 433 | set_prefix((u32)(unsigned long) lc); |
| 432 | } | 434 | } |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 3ed5c7a83c6c..9c0ccb532a45 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | #include <asm/lowcore.h> | 47 | #include <asm/lowcore.h> |
| 48 | #include <asm/sclp.h> | 48 | #include <asm/sclp.h> |
| 49 | #include <asm/cpu.h> | 49 | #include <asm/cpu.h> |
| 50 | #include <asm/vdso.h> | ||
| 50 | #include "entry.h" | 51 | #include "entry.h" |
| 51 | 52 | ||
| 52 | /* | 53 | /* |
| @@ -500,6 +501,9 @@ static int __cpuinit smp_alloc_lowcore(int cpu) | |||
| 500 | goto out; | 501 | goto out; |
| 501 | lowcore->extended_save_area_addr = (u32) save_area; | 502 | lowcore->extended_save_area_addr = (u32) save_area; |
| 502 | } | 503 | } |
| 504 | #else | ||
| 505 | if (vdso_alloc_per_cpu(cpu, lowcore)) | ||
| 506 | goto out; | ||
| 503 | #endif | 507 | #endif |
| 504 | lowcore_ptr[cpu] = lowcore; | 508 | lowcore_ptr[cpu] = lowcore; |
| 505 | return 0; | 509 | return 0; |
| @@ -522,6 +526,8 @@ static void smp_free_lowcore(int cpu) | |||
| 522 | #ifndef CONFIG_64BIT | 526 | #ifndef CONFIG_64BIT |
| 523 | if (MACHINE_HAS_IEEE) | 527 | if (MACHINE_HAS_IEEE) |
| 524 | free_page((unsigned long) lowcore->extended_save_area_addr); | 528 | free_page((unsigned long) lowcore->extended_save_area_addr); |
| 529 | #else | ||
| 530 | vdso_free_per_cpu(cpu, lowcore); | ||
| 525 | #endif | 531 | #endif |
| 526 | free_page(lowcore->panic_stack - PAGE_SIZE); | 532 | free_page(lowcore->panic_stack - PAGE_SIZE); |
| 527 | free_pages(lowcore->async_stack - ASYNC_SIZE, ASYNC_ORDER); | 533 | free_pages(lowcore->async_stack - ASYNC_SIZE, ASYNC_ORDER); |
| @@ -664,6 +670,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
| 664 | lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, lc_order); | 670 | lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, lc_order); |
| 665 | panic_stack = __get_free_page(GFP_KERNEL); | 671 | panic_stack = __get_free_page(GFP_KERNEL); |
| 666 | async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); | 672 | async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); |
| 673 | BUG_ON(!lowcore || !panic_stack || !async_stack); | ||
| 667 | #ifndef CONFIG_64BIT | 674 | #ifndef CONFIG_64BIT |
| 668 | if (MACHINE_HAS_IEEE) | 675 | if (MACHINE_HAS_IEEE) |
| 669 | save_area = get_zeroed_page(GFP_KERNEL); | 676 | save_area = get_zeroed_page(GFP_KERNEL); |
| @@ -677,6 +684,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
| 677 | #ifndef CONFIG_64BIT | 684 | #ifndef CONFIG_64BIT |
| 678 | if (MACHINE_HAS_IEEE) | 685 | if (MACHINE_HAS_IEEE) |
| 679 | lowcore->extended_save_area_addr = (u32) save_area; | 686 | lowcore->extended_save_area_addr = (u32) save_area; |
| 687 | #else | ||
| 688 | BUG_ON(vdso_alloc_per_cpu(smp_processor_id(), lowcore)); | ||
| 680 | #endif | 689 | #endif |
| 681 | set_prefix((u32)(unsigned long) lowcore); | 690 | set_prefix((u32)(unsigned long) lowcore); |
| 682 | local_mcck_enable(); | 691 | local_mcck_enable(); |
| @@ -845,9 +854,11 @@ static ssize_t show_idle_count(struct sys_device *dev, | |||
| 845 | unsigned long long idle_count; | 854 | unsigned long long idle_count; |
| 846 | 855 | ||
| 847 | idle = &per_cpu(s390_idle, dev->id); | 856 | idle = &per_cpu(s390_idle, dev->id); |
| 848 | spin_lock_irq(&idle->lock); | 857 | spin_lock(&idle->lock); |
| 849 | idle_count = idle->idle_count; | 858 | idle_count = idle->idle_count; |
| 850 | spin_unlock_irq(&idle->lock); | 859 | if (idle->idle_enter) |
| 860 | idle_count++; | ||
| 861 | spin_unlock(&idle->lock); | ||
| 851 | return sprintf(buf, "%llu\n", idle_count); | 862 | return sprintf(buf, "%llu\n", idle_count); |
| 852 | } | 863 | } |
| 853 | static SYSDEV_ATTR(idle_count, 0444, show_idle_count, NULL); | 864 | static SYSDEV_ATTR(idle_count, 0444, show_idle_count, NULL); |
| @@ -856,18 +867,17 @@ static ssize_t show_idle_time(struct sys_device *dev, | |||
| 856 | struct sysdev_attribute *attr, char *buf) | 867 | struct sysdev_attribute *attr, char *buf) |
| 857 | { | 868 | { |
| 858 | struct s390_idle_data *idle; | 869 | struct s390_idle_data *idle; |
| 859 | unsigned long long new_time; | 870 | unsigned long long now, idle_time, idle_enter; |
| 860 | 871 | ||
| 861 | idle = &per_cpu(s390_idle, dev->id); | 872 | idle = &per_cpu(s390_idle, dev->id); |
| 862 | spin_lock_irq(&idle->lock); | 873 | spin_lock(&idle->lock); |
| 863 | if (idle->in_idle) { | 874 | now = get_clock(); |
| 864 | new_time = get_clock(); | 875 | idle_time = idle->idle_time; |
| 865 | idle->idle_time += new_time - idle->idle_enter; | 876 | idle_enter = idle->idle_enter; |
| 866 | idle->idle_enter = new_time; | 877 | if (idle_enter != 0ULL && idle_enter < now) |
| 867 | } | 878 | idle_time += now - idle_enter; |
| 868 | new_time = idle->idle_time; | 879 | spin_unlock(&idle->lock); |
| 869 | spin_unlock_irq(&idle->lock); | 880 | return sprintf(buf, "%llu\n", idle_time >> 12); |
| 870 | return sprintf(buf, "%llu\n", new_time >> 12); | ||
| 871 | } | 881 | } |
| 872 | static SYSDEV_ATTR(idle_time_us, 0444, show_idle_time, NULL); | 882 | static SYSDEV_ATTR(idle_time_us, 0444, show_idle_time, NULL); |
| 873 | 883 | ||
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 90e9ba11eba1..cc362c9ea8f1 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c | |||
| @@ -97,6 +97,11 @@ cpumask_t cpu_coregroup_map(unsigned int cpu) | |||
| 97 | return mask; | 97 | return mask; |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | const struct cpumask *cpu_coregroup_mask(unsigned int cpu) | ||
| 101 | { | ||
| 102 | return &cpu_core_map[cpu]; | ||
| 103 | } | ||
| 104 | |||
| 100 | static void add_cpus_to_core(struct tl_cpu *tl_cpu, struct core_info *core) | 105 | static void add_cpus_to_core(struct tl_cpu *tl_cpu, struct core_info *core) |
| 101 | { | 106 | { |
| 102 | unsigned int cpu; | 107 | unsigned int cpu; |
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index 10a6ccef4412..25a6a82f1c02 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c | |||
| @@ -31,9 +31,6 @@ | |||
| 31 | #include <asm/sections.h> | 31 | #include <asm/sections.h> |
| 32 | #include <asm/vdso.h> | 32 | #include <asm/vdso.h> |
| 33 | 33 | ||
| 34 | /* Max supported size for symbol names */ | ||
| 35 | #define MAX_SYMNAME 64 | ||
| 36 | |||
| 37 | #if defined(CONFIG_32BIT) || defined(CONFIG_COMPAT) | 34 | #if defined(CONFIG_32BIT) || defined(CONFIG_COMPAT) |
| 38 | extern char vdso32_start, vdso32_end; | 35 | extern char vdso32_start, vdso32_end; |
| 39 | static void *vdso32_kbase = &vdso32_start; | 36 | static void *vdso32_kbase = &vdso32_start; |
| @@ -71,6 +68,119 @@ static union { | |||
| 71 | struct vdso_data *vdso_data = &vdso_data_store.data; | 68 | struct vdso_data *vdso_data = &vdso_data_store.data; |
| 72 | 69 | ||
| 73 | /* | 70 | /* |
| 71 | * Setup vdso data page. | ||
| 72 | */ | ||
| 73 | static void vdso_init_data(struct vdso_data *vd) | ||
| 74 | { | ||
| 75 | unsigned int facility_list; | ||
| 76 | |||
| 77 | facility_list = stfl(); | ||
| 78 | vd->ectg_available = switch_amode && (facility_list & 1); | ||
| 79 | } | ||
| 80 | |||
| 81 | #ifdef CONFIG_64BIT | ||
| 82 | /* | ||
| 83 | * Setup per cpu vdso data page. | ||
| 84 | */ | ||
| 85 | static void vdso_init_per_cpu_data(int cpu, struct vdso_per_cpu_data *vpcd) | ||
| 86 | { | ||
| 87 | } | ||
| 88 | |||
| 89 | /* | ||
| 90 | * Allocate/free per cpu vdso data. | ||
| 91 | */ | ||
| 92 | #ifdef CONFIG_64BIT | ||
| 93 | #define SEGMENT_ORDER 2 | ||
| 94 | #else | ||
| 95 | #define SEGMENT_ORDER 1 | ||
| 96 | #endif | ||
| 97 | |||
| 98 | int vdso_alloc_per_cpu(int cpu, struct _lowcore *lowcore) | ||
| 99 | { | ||
| 100 | unsigned long segment_table, page_table, page_frame; | ||
| 101 | u32 *psal, *aste; | ||
| 102 | int i; | ||
| 103 | |||
| 104 | lowcore->vdso_per_cpu_data = __LC_PASTE; | ||
| 105 | |||
| 106 | if (!switch_amode || !vdso_enabled) | ||
| 107 | return 0; | ||
| 108 | |||
| 109 | segment_table = __get_free_pages(GFP_KERNEL, SEGMENT_ORDER); | ||
| 110 | page_table = get_zeroed_page(GFP_KERNEL | GFP_DMA); | ||
| 111 | page_frame = get_zeroed_page(GFP_KERNEL); | ||
| 112 | if (!segment_table || !page_table || !page_frame) | ||
| 113 | goto out; | ||
| 114 | |||
| 115 | clear_table((unsigned long *) segment_table, _SEGMENT_ENTRY_EMPTY, | ||
| 116 | PAGE_SIZE << SEGMENT_ORDER); | ||
| 117 | clear_table((unsigned long *) page_table, _PAGE_TYPE_EMPTY, | ||
| 118 | 256*sizeof(unsigned long)); | ||
| 119 | |||
| 120 | *(unsigned long *) segment_table = _SEGMENT_ENTRY + page_table; | ||
| 121 | *(unsigned long *) page_table = _PAGE_RO + page_frame; | ||
| 122 | |||
| 123 | psal = (u32 *) (page_table + 256*sizeof(unsigned long)); | ||
| 124 | aste = psal + 32; | ||
| 125 | |||
| 126 | for (i = 4; i < 32; i += 4) | ||
| 127 | psal[i] = 0x80000000; | ||
| 128 | |||
| 129 | lowcore->paste[4] = (u32)(addr_t) psal; | ||
| 130 | psal[0] = 0x20000000; | ||
| 131 | psal[2] = (u32)(addr_t) aste; | ||
| 132 | *(unsigned long *) (aste + 2) = segment_table + | ||
| 133 | _ASCE_TABLE_LENGTH + _ASCE_USER_BITS + _ASCE_TYPE_SEGMENT; | ||
| 134 | aste[4] = (u32)(addr_t) psal; | ||
| 135 | lowcore->vdso_per_cpu_data = page_frame; | ||
| 136 | |||
| 137 | vdso_init_per_cpu_data(cpu, (struct vdso_per_cpu_data *) page_frame); | ||
| 138 | return 0; | ||
| 139 | |||
| 140 | out: | ||
| 141 | free_page(page_frame); | ||
| 142 | free_page(page_table); | ||
| 143 | free_pages(segment_table, SEGMENT_ORDER); | ||
| 144 | return -ENOMEM; | ||
| 145 | } | ||
| 146 | |||
| 147 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 148 | void vdso_free_per_cpu(int cpu, struct _lowcore *lowcore) | ||
| 149 | { | ||
| 150 | unsigned long segment_table, page_table, page_frame; | ||
| 151 | u32 *psal, *aste; | ||
| 152 | |||
| 153 | if (!switch_amode || !vdso_enabled) | ||
| 154 | return; | ||
| 155 | |||
| 156 | psal = (u32 *)(addr_t) lowcore->paste[4]; | ||
| 157 | aste = (u32 *)(addr_t) psal[2]; | ||
| 158 | segment_table = *(unsigned long *)(aste + 2) & PAGE_MASK; | ||
| 159 | page_table = *(unsigned long *) segment_table; | ||
| 160 | page_frame = *(unsigned long *) page_table; | ||
| 161 | |||
| 162 | free_page(page_frame); | ||
| 163 | free_page(page_table); | ||
| 164 | free_pages(segment_table, SEGMENT_ORDER); | ||
| 165 | } | ||
| 166 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
| 167 | |||
| 168 | static void __vdso_init_cr5(void *dummy) | ||
| 169 | { | ||
| 170 | unsigned long cr5; | ||
| 171 | |||
| 172 | cr5 = offsetof(struct _lowcore, paste); | ||
| 173 | __ctl_load(cr5, 5, 5); | ||
| 174 | } | ||
| 175 | |||
| 176 | static void vdso_init_cr5(void) | ||
| 177 | { | ||
| 178 | if (switch_amode && vdso_enabled) | ||
| 179 | on_each_cpu(__vdso_init_cr5, NULL, 1); | ||
| 180 | } | ||
| 181 | #endif /* CONFIG_64BIT */ | ||
| 182 | |||
| 183 | /* | ||
| 74 | * This is called from binfmt_elf, we create the special vma for the | 184 | * This is called from binfmt_elf, we create the special vma for the |
| 75 | * vDSO and insert it into the mm struct tree | 185 | * vDSO and insert it into the mm struct tree |
| 76 | */ | 186 | */ |
| @@ -172,6 +282,9 @@ static int __init vdso_init(void) | |||
| 172 | { | 282 | { |
| 173 | int i; | 283 | int i; |
| 174 | 284 | ||
| 285 | if (!vdso_enabled) | ||
| 286 | return 0; | ||
| 287 | vdso_init_data(vdso_data); | ||
| 175 | #if defined(CONFIG_32BIT) || defined(CONFIG_COMPAT) | 288 | #if defined(CONFIG_32BIT) || defined(CONFIG_COMPAT) |
| 176 | /* Calculate the size of the 32 bit vDSO */ | 289 | /* Calculate the size of the 32 bit vDSO */ |
| 177 | vdso32_pages = ((&vdso32_end - &vdso32_start | 290 | vdso32_pages = ((&vdso32_end - &vdso32_start |
| @@ -208,6 +321,10 @@ static int __init vdso_init(void) | |||
| 208 | } | 321 | } |
| 209 | vdso64_pagelist[vdso64_pages - 1] = virt_to_page(vdso_data); | 322 | vdso64_pagelist[vdso64_pages - 1] = virt_to_page(vdso_data); |
| 210 | vdso64_pagelist[vdso64_pages] = NULL; | 323 | vdso64_pagelist[vdso64_pages] = NULL; |
| 324 | #ifndef CONFIG_SMP | ||
| 325 | BUG_ON(vdso_alloc_per_cpu(0, S390_lowcore)); | ||
| 326 | #endif | ||
| 327 | vdso_init_cr5(); | ||
| 211 | #endif /* CONFIG_64BIT */ | 328 | #endif /* CONFIG_64BIT */ |
| 212 | 329 | ||
| 213 | get_page(virt_to_page(vdso_data)); | 330 | get_page(virt_to_page(vdso_data)); |
diff --git a/arch/s390/kernel/vdso64/clock_getres.S b/arch/s390/kernel/vdso64/clock_getres.S index 488e31a3c0e7..9ce8caafdb4e 100644 --- a/arch/s390/kernel/vdso64/clock_getres.S +++ b/arch/s390/kernel/vdso64/clock_getres.S | |||
| @@ -22,7 +22,12 @@ __kernel_clock_getres: | |||
| 22 | cghi %r2,CLOCK_REALTIME | 22 | cghi %r2,CLOCK_REALTIME |
| 23 | je 0f | 23 | je 0f |
| 24 | cghi %r2,CLOCK_MONOTONIC | 24 | cghi %r2,CLOCK_MONOTONIC |
| 25 | je 0f | ||
| 26 | cghi %r2,-2 /* CLOCK_THREAD_CPUTIME_ID for this thread */ | ||
| 25 | jne 2f | 27 | jne 2f |
| 28 | larl %r5,_vdso_data | ||
| 29 | icm %r0,15,__LC_ECTG_OK(%r5) | ||
| 30 | jz 2f | ||
| 26 | 0: ltgr %r3,%r3 | 31 | 0: ltgr %r3,%r3 |
| 27 | jz 1f /* res == NULL */ | 32 | jz 1f /* res == NULL */ |
| 28 | larl %r1,3f | 33 | larl %r1,3f |
diff --git a/arch/s390/kernel/vdso64/clock_gettime.S b/arch/s390/kernel/vdso64/clock_gettime.S index 738a410b7eb2..79dbfee831ec 100644 --- a/arch/s390/kernel/vdso64/clock_gettime.S +++ b/arch/s390/kernel/vdso64/clock_gettime.S | |||
| @@ -22,8 +22,10 @@ __kernel_clock_gettime: | |||
| 22 | larl %r5,_vdso_data | 22 | larl %r5,_vdso_data |
| 23 | cghi %r2,CLOCK_REALTIME | 23 | cghi %r2,CLOCK_REALTIME |
| 24 | je 4f | 24 | je 4f |
| 25 | cghi %r2,-2 /* CLOCK_THREAD_CPUTIME_ID for this thread */ | ||
| 26 | je 9f | ||
| 25 | cghi %r2,CLOCK_MONOTONIC | 27 | cghi %r2,CLOCK_MONOTONIC |
| 26 | jne 9f | 28 | jne 12f |
| 27 | 29 | ||
| 28 | /* CLOCK_MONOTONIC */ | 30 | /* CLOCK_MONOTONIC */ |
| 29 | ltgr %r3,%r3 | 31 | ltgr %r3,%r3 |
| @@ -42,7 +44,7 @@ __kernel_clock_gettime: | |||
| 42 | alg %r0,__VDSO_WTOM_SEC(%r5) | 44 | alg %r0,__VDSO_WTOM_SEC(%r5) |
| 43 | clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ | 45 | clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ |
| 44 | jne 0b | 46 | jne 0b |
| 45 | larl %r5,10f | 47 | larl %r5,13f |
| 46 | 1: clg %r1,0(%r5) | 48 | 1: clg %r1,0(%r5) |
| 47 | jl 2f | 49 | jl 2f |
| 48 | slg %r1,0(%r5) | 50 | slg %r1,0(%r5) |
| @@ -68,7 +70,7 @@ __kernel_clock_gettime: | |||
| 68 | lg %r0,__VDSO_XTIME_SEC(%r5) | 70 | lg %r0,__VDSO_XTIME_SEC(%r5) |
| 69 | clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ | 71 | clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ |
| 70 | jne 5b | 72 | jne 5b |
| 71 | larl %r5,10f | 73 | larl %r5,13f |
| 72 | 6: clg %r1,0(%r5) | 74 | 6: clg %r1,0(%r5) |
| 73 | jl 7f | 75 | jl 7f |
| 74 | slg %r1,0(%r5) | 76 | slg %r1,0(%r5) |
| @@ -79,11 +81,38 @@ __kernel_clock_gettime: | |||
| 79 | 8: lghi %r2,0 | 81 | 8: lghi %r2,0 |
| 80 | br %r14 | 82 | br %r14 |
| 81 | 83 | ||
| 84 | /* CLOCK_THREAD_CPUTIME_ID for this thread */ | ||
| 85 | 9: icm %r0,15,__VDSO_ECTG_OK(%r5) | ||
| 86 | jz 12f | ||
| 87 | ear %r2,%a4 | ||
| 88 | llilh %r4,0x0100 | ||
| 89 | sar %a4,%r4 | ||
| 90 | lghi %r4,0 | ||
| 91 | sacf 512 /* Magic ectg instruction */ | ||
| 92 | .insn ssf,0xc80100000000,__VDSO_ECTG_BASE(4),__VDSO_ECTG_USER(4),4 | ||
| 93 | sacf 0 | ||
| 94 | sar %a4,%r2 | ||
| 95 | algr %r1,%r0 /* r1 = cputime as TOD value */ | ||
| 96 | mghi %r1,1000 /* convert to nanoseconds */ | ||
| 97 | srlg %r1,%r1,12 /* r1 = cputime in nanosec */ | ||
| 98 | lgr %r4,%r1 | ||
| 99 | larl %r5,13f | ||
| 100 | srlg %r1,%r1,9 /* divide by 1000000000 */ | ||
| 101 | mlg %r0,8(%r5) | ||
| 102 | srlg %r0,%r0,11 /* r0 = tv_sec */ | ||
| 103 | stg %r0,0(%r3) | ||
| 104 | msg %r0,0(%r5) /* calculate tv_nsec */ | ||
| 105 | slgr %r4,%r0 /* r4 = tv_nsec */ | ||
| 106 | stg %r4,8(%r3) | ||
| 107 | lghi %r2,0 | ||
| 108 | br %r14 | ||
| 109 | |||
| 82 | /* Fallback to system call */ | 110 | /* Fallback to system call */ |
| 83 | 9: lghi %r1,__NR_clock_gettime | 111 | 12: lghi %r1,__NR_clock_gettime |
| 84 | svc 0 | 112 | svc 0 |
| 85 | br %r14 | 113 | br %r14 |
| 86 | 114 | ||
| 87 | 10: .quad 1000000000 | 115 | 13: .quad 1000000000 |
| 116 | 14: .quad 19342813113834067 | ||
| 88 | .cfi_endproc | 117 | .cfi_endproc |
| 89 | .size __kernel_clock_gettime,.-__kernel_clock_gettime | 118 | .size __kernel_clock_gettime,.-__kernel_clock_gettime |
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 75a6e62ea973..2fb36e462194 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c | |||
| @@ -23,19 +23,43 @@ | |||
| 23 | #include <asm/s390_ext.h> | 23 | #include <asm/s390_ext.h> |
| 24 | #include <asm/timer.h> | 24 | #include <asm/timer.h> |
| 25 | #include <asm/irq_regs.h> | 25 | #include <asm/irq_regs.h> |
| 26 | #include <asm/cpu.h> | ||
| 26 | 27 | ||
| 27 | static ext_int_info_t ext_int_info_timer; | 28 | static ext_int_info_t ext_int_info_timer; |
| 29 | |||
| 28 | static DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer); | 30 | static DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer); |
| 29 | 31 | ||
| 32 | DEFINE_PER_CPU(struct s390_idle_data, s390_idle) = { | ||
| 33 | .lock = __SPIN_LOCK_UNLOCKED(s390_idle.lock) | ||
| 34 | }; | ||
| 35 | |||
| 36 | static inline __u64 get_vtimer(void) | ||
| 37 | { | ||
| 38 | __u64 timer; | ||
| 39 | |||
| 40 | asm volatile("STPT %0" : "=m" (timer)); | ||
| 41 | return timer; | ||
| 42 | } | ||
| 43 | |||
| 44 | static inline void set_vtimer(__u64 expires) | ||
| 45 | { | ||
| 46 | __u64 timer; | ||
| 47 | |||
| 48 | asm volatile (" STPT %0\n" /* Store current cpu timer value */ | ||
| 49 | " SPT %1" /* Set new value immediatly afterwards */ | ||
| 50 | : "=m" (timer) : "m" (expires) ); | ||
| 51 | S390_lowcore.system_timer += S390_lowcore.last_update_timer - timer; | ||
| 52 | S390_lowcore.last_update_timer = expires; | ||
| 53 | } | ||
| 54 | |||
| 30 | /* | 55 | /* |
| 31 | * Update process times based on virtual cpu times stored by entry.S | 56 | * Update process times based on virtual cpu times stored by entry.S |
| 32 | * to the lowcore fields user_timer, system_timer & steal_clock. | 57 | * to the lowcore fields user_timer, system_timer & steal_clock. |
| 33 | */ | 58 | */ |
| 34 | void account_process_tick(struct task_struct *tsk, int user_tick) | 59 | static void do_account_vtime(struct task_struct *tsk, int hardirq_offset) |
| 35 | { | 60 | { |
| 36 | cputime_t cputime; | 61 | struct thread_info *ti = task_thread_info(tsk); |
| 37 | __u64 timer, clock; | 62 | __u64 timer, clock, user, system, steal; |
| 38 | int rcu_user_flag; | ||
| 39 | 63 | ||
| 40 | timer = S390_lowcore.last_update_timer; | 64 | timer = S390_lowcore.last_update_timer; |
| 41 | clock = S390_lowcore.last_update_clock; | 65 | clock = S390_lowcore.last_update_clock; |
| @@ -44,50 +68,41 @@ void account_process_tick(struct task_struct *tsk, int user_tick) | |||
| 44 | : "=m" (S390_lowcore.last_update_timer), | 68 | : "=m" (S390_lowcore.last_update_timer), |
| 45 | "=m" (S390_lowcore.last_update_clock) ); | 69 | "=m" (S390_lowcore.last_update_clock) ); |
| 46 | S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; | 70 | S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; |
| 47 | S390_lowcore.steal_clock += S390_lowcore.last_update_clock - clock; | 71 | S390_lowcore.steal_timer += S390_lowcore.last_update_clock - clock; |
| 48 | 72 | ||
| 49 | cputime = S390_lowcore.user_timer >> 12; | 73 | user = S390_lowcore.user_timer - ti->user_timer; |
| 50 | rcu_user_flag = cputime != 0; | 74 | S390_lowcore.steal_timer -= user; |
| 51 | S390_lowcore.user_timer -= cputime << 12; | 75 | ti->user_timer = S390_lowcore.user_timer; |
| 52 | S390_lowcore.steal_clock -= cputime << 12; | 76 | account_user_time(tsk, user, user); |
| 53 | account_user_time(tsk, cputime); | 77 | |
| 54 | 78 | system = S390_lowcore.system_timer - ti->system_timer; | |
| 55 | cputime = S390_lowcore.system_timer >> 12; | 79 | S390_lowcore.steal_timer -= system; |
| 56 | S390_lowcore.system_timer -= cputime << 12; | 80 | ti->system_timer = S390_lowcore.system_timer; |
| 57 | S390_lowcore.steal_clock -= cputime << 12; | 81 | account_system_time(tsk, hardirq_offset, system, system); |
| 58 | account_system_time(tsk, HARDIRQ_OFFSET, cputime); | 82 | |
| 59 | 83 | steal = S390_lowcore.steal_timer; | |
| 60 | cputime = S390_lowcore.steal_clock; | 84 | if ((s64) steal > 0) { |
| 61 | if ((__s64) cputime > 0) { | 85 | S390_lowcore.steal_timer = 0; |
| 62 | cputime >>= 12; | 86 | account_steal_time(steal); |
| 63 | S390_lowcore.steal_clock -= cputime << 12; | ||
| 64 | account_steal_time(tsk, cputime); | ||
| 65 | } | 87 | } |
| 66 | } | 88 | } |
| 67 | 89 | ||
| 68 | /* | 90 | void account_vtime(struct task_struct *prev, struct task_struct *next) |
| 69 | * Update process times based on virtual cpu times stored by entry.S | ||
| 70 | * to the lowcore fields user_timer, system_timer & steal_clock. | ||
| 71 | */ | ||
| 72 | void account_vtime(struct task_struct *tsk) | ||
| 73 | { | 91 | { |
| 74 | cputime_t cputime; | 92 | struct thread_info *ti; |
| 75 | __u64 timer; | 93 | |
| 76 | 94 | do_account_vtime(prev, 0); | |
| 77 | timer = S390_lowcore.last_update_timer; | 95 | ti = task_thread_info(prev); |
| 78 | asm volatile (" STPT %0" /* Store current cpu timer value */ | 96 | ti->user_timer = S390_lowcore.user_timer; |
| 79 | : "=m" (S390_lowcore.last_update_timer) ); | 97 | ti->system_timer = S390_lowcore.system_timer; |
| 80 | S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; | 98 | ti = task_thread_info(next); |
| 81 | 99 | S390_lowcore.user_timer = ti->user_timer; | |
| 82 | cputime = S390_lowcore.user_timer >> 12; | 100 | S390_lowcore.system_timer = ti->system_timer; |
| 83 | S390_lowcore.user_timer -= cputime << 12; | 101 | } |
| 84 | S390_lowcore.steal_clock -= cputime << 12; | ||
| 85 | account_user_time(tsk, cputime); | ||
| 86 | 102 | ||
| 87 | cputime = S390_lowcore.system_timer >> 12; | 103 | void account_process_tick(struct task_struct *tsk, int user_tick) |
| 88 | S390_lowcore.system_timer -= cputime << 12; | 104 | { |
| 89 | S390_lowcore.steal_clock -= cputime << 12; | 105 | do_account_vtime(tsk, HARDIRQ_OFFSET); |
| 90 | account_system_time(tsk, 0, cputime); | ||
| 91 | } | 106 | } |
| 92 | 107 | ||
| 93 | /* | 108 | /* |
| @@ -96,80 +111,131 @@ void account_vtime(struct task_struct *tsk) | |||
| 96 | */ | 111 | */ |
| 97 | void account_system_vtime(struct task_struct *tsk) | 112 | void account_system_vtime(struct task_struct *tsk) |
| 98 | { | 113 | { |
| 99 | cputime_t cputime; | 114 | struct thread_info *ti = task_thread_info(tsk); |
| 100 | __u64 timer; | 115 | __u64 timer, system; |
| 101 | 116 | ||
| 102 | timer = S390_lowcore.last_update_timer; | 117 | timer = S390_lowcore.last_update_timer; |
| 103 | asm volatile (" STPT %0" /* Store current cpu timer value */ | 118 | S390_lowcore.last_update_timer = get_vtimer(); |
| 104 | : "=m" (S390_lowcore.last_update_timer) ); | ||
| 105 | S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; | 119 | S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; |
| 106 | 120 | ||
| 107 | cputime = S390_lowcore.system_timer >> 12; | 121 | system = S390_lowcore.system_timer - ti->system_timer; |
| 108 | S390_lowcore.system_timer -= cputime << 12; | 122 | S390_lowcore.steal_timer -= system; |
| 109 | S390_lowcore.steal_clock -= cputime << 12; | 123 | ti->system_timer = S390_lowcore.system_timer; |
| 110 | account_system_time(tsk, 0, cputime); | 124 | account_system_time(tsk, 0, system, system); |
| 111 | } | 125 | } |
| 112 | EXPORT_SYMBOL_GPL(account_system_vtime); | 126 | EXPORT_SYMBOL_GPL(account_system_vtime); |
| 113 | 127 | ||
| 114 | static inline void set_vtimer(__u64 expires) | 128 | void vtime_start_cpu(void) |
| 115 | { | ||
| 116 | __u64 timer; | ||
| 117 | |||
| 118 | asm volatile (" STPT %0\n" /* Store current cpu timer value */ | ||
| 119 | " SPT %1" /* Set new value immediatly afterwards */ | ||
| 120 | : "=m" (timer) : "m" (expires) ); | ||
| 121 | S390_lowcore.system_timer += S390_lowcore.last_update_timer - timer; | ||
| 122 | S390_lowcore.last_update_timer = expires; | ||
| 123 | |||
| 124 | /* store expire time for this CPU timer */ | ||
| 125 | __get_cpu_var(virt_cpu_timer).to_expire = expires; | ||
| 126 | } | ||
| 127 | |||
| 128 | void vtime_start_cpu_timer(void) | ||
| 129 | { | 129 | { |
| 130 | struct vtimer_queue *vt_list; | 130 | struct s390_idle_data *idle = &__get_cpu_var(s390_idle); |
| 131 | 131 | struct vtimer_queue *vq = &__get_cpu_var(virt_cpu_timer); | |
| 132 | vt_list = &__get_cpu_var(virt_cpu_timer); | 132 | __u64 idle_time, expires; |
| 133 | 133 | ||
| 134 | /* CPU timer interrupt is pending, don't reprogramm it */ | 134 | /* Account time spent with enabled wait psw loaded as idle time. */ |
| 135 | if (vt_list->idle & 1LL<<63) | 135 | idle_time = S390_lowcore.int_clock - idle->idle_enter; |
| 136 | return; | 136 | account_idle_time(idle_time); |
| 137 | S390_lowcore.last_update_clock = S390_lowcore.int_clock; | ||
| 138 | |||
| 139 | /* Account system time spent going idle. */ | ||
| 140 | S390_lowcore.system_timer += S390_lowcore.last_update_timer - vq->idle; | ||
| 141 | S390_lowcore.last_update_timer = S390_lowcore.async_enter_timer; | ||
| 142 | |||
| 143 | /* Restart vtime CPU timer */ | ||
| 144 | if (vq->do_spt) { | ||
| 145 | /* Program old expire value but first save progress. */ | ||
| 146 | expires = vq->idle - S390_lowcore.async_enter_timer; | ||
| 147 | expires += get_vtimer(); | ||
| 148 | set_vtimer(expires); | ||
| 149 | } else { | ||
| 150 | /* Don't account the CPU timer delta while the cpu was idle. */ | ||
| 151 | vq->elapsed -= vq->idle - S390_lowcore.async_enter_timer; | ||
| 152 | } | ||
| 137 | 153 | ||
| 138 | if (!list_empty(&vt_list->list)) | 154 | spin_lock(&idle->lock); |
| 139 | set_vtimer(vt_list->idle); | 155 | idle->idle_time += idle_time; |
| 156 | idle->idle_enter = 0ULL; | ||
| 157 | idle->idle_count++; | ||
| 158 | spin_unlock(&idle->lock); | ||
| 140 | } | 159 | } |
| 141 | 160 | ||
| 142 | void vtime_stop_cpu_timer(void) | 161 | void vtime_stop_cpu(void) |
| 143 | { | 162 | { |
| 144 | struct vtimer_queue *vt_list; | 163 | struct s390_idle_data *idle = &__get_cpu_var(s390_idle); |
| 145 | 164 | struct vtimer_queue *vq = &__get_cpu_var(virt_cpu_timer); | |
| 146 | vt_list = &__get_cpu_var(virt_cpu_timer); | 165 | psw_t psw; |
| 147 | 166 | ||
| 148 | /* nothing to do */ | 167 | /* Wait for external, I/O or machine check interrupt. */ |
| 149 | if (list_empty(&vt_list->list)) { | 168 | psw.mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_IO | PSW_MASK_EXT; |
| 150 | vt_list->idle = VTIMER_MAX_SLICE; | 169 | |
| 151 | goto fire; | 170 | /* Check if the CPU timer needs to be reprogrammed. */ |
| 171 | if (vq->do_spt) { | ||
| 172 | __u64 vmax = VTIMER_MAX_SLICE; | ||
| 173 | /* | ||
| 174 | * The inline assembly is equivalent to | ||
| 175 | * vq->idle = get_cpu_timer(); | ||
| 176 | * set_cpu_timer(VTIMER_MAX_SLICE); | ||
| 177 | * idle->idle_enter = get_clock(); | ||
| 178 | * __load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT | | ||
| 179 | * PSW_MASK_IO | PSW_MASK_EXT); | ||
| 180 | * The difference is that the inline assembly makes sure that | ||
| 181 | * the last three instruction are stpt, stck and lpsw in that | ||
| 182 | * order. This is done to increase the precision. | ||
| 183 | */ | ||
| 184 | asm volatile( | ||
| 185 | #ifndef CONFIG_64BIT | ||
| 186 | " basr 1,0\n" | ||
| 187 | "0: ahi 1,1f-0b\n" | ||
| 188 | " st 1,4(%2)\n" | ||
| 189 | #else /* CONFIG_64BIT */ | ||
| 190 | " larl 1,1f\n" | ||
| 191 | " stg 1,8(%2)\n" | ||
| 192 | #endif /* CONFIG_64BIT */ | ||
| 193 | " stpt 0(%4)\n" | ||
| 194 | " spt 0(%5)\n" | ||
| 195 | " stck 0(%3)\n" | ||
| 196 | #ifndef CONFIG_64BIT | ||
| 197 | " lpsw 0(%2)\n" | ||
| 198 | #else /* CONFIG_64BIT */ | ||
| 199 | " lpswe 0(%2)\n" | ||
| 200 | #endif /* CONFIG_64BIT */ | ||
| 201 | "1:" | ||
| 202 | : "=m" (idle->idle_enter), "=m" (vq->idle) | ||
| 203 | : "a" (&psw), "a" (&idle->idle_enter), | ||
| 204 | "a" (&vq->idle), "a" (&vmax), "m" (vmax), "m" (psw) | ||
| 205 | : "memory", "cc", "1"); | ||
| 206 | } else { | ||
| 207 | /* | ||
| 208 | * The inline assembly is equivalent to | ||
| 209 | * vq->idle = get_cpu_timer(); | ||
| 210 | * idle->idle_enter = get_clock(); | ||
| 211 | * __load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT | | ||
| 212 | * PSW_MASK_IO | PSW_MASK_EXT); | ||
| 213 | * The difference is that the inline assembly makes sure that | ||
| 214 | * the last three instruction are stpt, stck and lpsw in that | ||
| 215 | * order. This is done to increase the precision. | ||
| 216 | */ | ||
| 217 | asm volatile( | ||
| 218 | #ifndef CONFIG_64BIT | ||
| 219 | " basr 1,0\n" | ||
| 220 | "0: ahi 1,1f-0b\n" | ||
| 221 | " st 1,4(%2)\n" | ||
| 222 | #else /* CONFIG_64BIT */ | ||
| 223 | " larl 1,1f\n" | ||
| 224 | " stg 1,8(%2)\n" | ||
| 225 | #endif /* CONFIG_64BIT */ | ||
| 226 | " stpt 0(%4)\n" | ||
| 227 | " stck 0(%3)\n" | ||
| 228 | #ifndef CONFIG_64BIT | ||
| 229 | " lpsw 0(%2)\n" | ||
| 230 | #else /* CONFIG_64BIT */ | ||
| 231 | " lpswe 0(%2)\n" | ||
| 232 | #endif /* CONFIG_64BIT */ | ||
| 233 | "1:" | ||
| 234 | : "=m" (idle->idle_enter), "=m" (vq->idle) | ||
| 235 | : "a" (&psw), "a" (&idle->idle_enter), | ||
| 236 | "a" (&vq->idle), "m" (psw) | ||
| 237 | : "memory", "cc", "1"); | ||
| 152 | } | 238 | } |
| 153 | |||
| 154 | /* store the actual expire value */ | ||
| 155 | asm volatile ("STPT %0" : "=m" (vt_list->idle)); | ||
| 156 | |||
| 157 | /* | ||
| 158 | * If the CPU timer is negative we don't reprogramm | ||
| 159 | * it because we will get instantly an interrupt. | ||
| 160 | */ | ||
| 161 | if (vt_list->idle & 1LL<<63) | ||
| 162 | return; | ||
| 163 | |||
| 164 | vt_list->offset += vt_list->to_expire - vt_list->idle; | ||
| 165 | |||
| 166 | /* | ||
| 167 | * We cannot halt the CPU timer, we just write a value that | ||
| 168 | * nearly never expires (only after 71 years) and re-write | ||
| 169 | * the stored expire value if we continue the timer | ||
| 170 | */ | ||
| 171 | fire: | ||
| 172 | set_vtimer(VTIMER_MAX_SLICE); | ||
| 173 | } | 239 | } |
| 174 | 240 | ||
| 175 | /* | 241 | /* |
| @@ -195,30 +261,23 @@ static void list_add_sorted(struct vtimer_list *timer, struct list_head *head) | |||
| 195 | */ | 261 | */ |
| 196 | static void do_callbacks(struct list_head *cb_list) | 262 | static void do_callbacks(struct list_head *cb_list) |
| 197 | { | 263 | { |
| 198 | struct vtimer_queue *vt_list; | 264 | struct vtimer_queue *vq; |
| 199 | struct vtimer_list *event, *tmp; | 265 | struct vtimer_list *event, *tmp; |
| 200 | void (*fn)(unsigned long); | ||
| 201 | unsigned long data; | ||
| 202 | 266 | ||
| 203 | if (list_empty(cb_list)) | 267 | if (list_empty(cb_list)) |
| 204 | return; | 268 | return; |
| 205 | 269 | ||
| 206 | vt_list = &__get_cpu_var(virt_cpu_timer); | 270 | vq = &__get_cpu_var(virt_cpu_timer); |
| 207 | 271 | ||
| 208 | list_for_each_entry_safe(event, tmp, cb_list, entry) { | 272 | list_for_each_entry_safe(event, tmp, cb_list, entry) { |
| 209 | fn = event->function; | 273 | list_del_init(&event->entry); |
| 210 | data = event->data; | 274 | (event->function)(event->data); |
| 211 | fn(data); | 275 | if (event->interval) { |
| 212 | 276 | /* Recharge interval timer */ | |
| 213 | if (!event->interval) | 277 | event->expires = event->interval + vq->elapsed; |
| 214 | /* delete one shot timer */ | 278 | spin_lock(&vq->lock); |
| 215 | list_del_init(&event->entry); | 279 | list_add_sorted(event, &vq->list); |
| 216 | else { | 280 | spin_unlock(&vq->lock); |
| 217 | /* move interval timer back to list */ | ||
| 218 | spin_lock(&vt_list->lock); | ||
| 219 | list_del_init(&event->entry); | ||
| 220 | list_add_sorted(event, &vt_list->list); | ||
| 221 | spin_unlock(&vt_list->lock); | ||
| 222 | } | 281 | } |
| 223 | } | 282 | } |
| 224 | } | 283 | } |
| @@ -228,64 +287,57 @@ static void do_callbacks(struct list_head *cb_list) | |||
| 228 | */ | 287 | */ |
| 229 | static void do_cpu_timer_interrupt(__u16 error_code) | 288 | static void do_cpu_timer_interrupt(__u16 error_code) |
| 230 | { | 289 | { |
| 231 | __u64 next, delta; | 290 | struct vtimer_queue *vq; |
| 232 | struct vtimer_queue *vt_list; | ||
| 233 | struct vtimer_list *event, *tmp; | 291 | struct vtimer_list *event, *tmp; |
| 234 | struct list_head *ptr; | 292 | struct list_head cb_list; /* the callback queue */ |
| 235 | /* the callback queue */ | 293 | __u64 elapsed, next; |
| 236 | struct list_head cb_list; | ||
| 237 | 294 | ||
| 238 | INIT_LIST_HEAD(&cb_list); | 295 | INIT_LIST_HEAD(&cb_list); |
| 239 | vt_list = &__get_cpu_var(virt_cpu_timer); | 296 | vq = &__get_cpu_var(virt_cpu_timer); |
| 240 | 297 | ||
| 241 | /* walk timer list, fire all expired events */ | 298 | /* walk timer list, fire all expired events */ |
| 242 | spin_lock(&vt_list->lock); | 299 | spin_lock(&vq->lock); |
| 243 | 300 | ||
| 244 | if (vt_list->to_expire < VTIMER_MAX_SLICE) | 301 | elapsed = vq->elapsed + (vq->timer - S390_lowcore.async_enter_timer); |
| 245 | vt_list->offset += vt_list->to_expire; | 302 | BUG_ON((s64) elapsed < 0); |
| 246 | 303 | vq->elapsed = 0; | |
| 247 | list_for_each_entry_safe(event, tmp, &vt_list->list, entry) { | 304 | list_for_each_entry_safe(event, tmp, &vq->list, entry) { |
| 248 | if (event->expires > vt_list->offset) | 305 | if (event->expires < elapsed) |
| 249 | /* found first unexpired event, leave */ | 306 | /* move expired timer to the callback queue */ |
| 250 | break; | 307 | list_move_tail(&event->entry, &cb_list); |
| 251 | 308 | else | |
| 252 | /* re-charge interval timer, we have to add the offset */ | 309 | event->expires -= elapsed; |
| 253 | if (event->interval) | ||
| 254 | event->expires = event->interval + vt_list->offset; | ||
| 255 | |||
| 256 | /* move expired timer to the callback queue */ | ||
| 257 | list_move_tail(&event->entry, &cb_list); | ||
| 258 | } | 310 | } |
| 259 | spin_unlock(&vt_list->lock); | 311 | spin_unlock(&vq->lock); |
| 312 | |||
| 313 | vq->do_spt = list_empty(&cb_list); | ||
| 260 | do_callbacks(&cb_list); | 314 | do_callbacks(&cb_list); |
| 261 | 315 | ||
| 262 | /* next event is first in list */ | 316 | /* next event is first in list */ |
| 263 | spin_lock(&vt_list->lock); | 317 | next = VTIMER_MAX_SLICE; |
| 264 | if (!list_empty(&vt_list->list)) { | 318 | spin_lock(&vq->lock); |
| 265 | ptr = vt_list->list.next; | 319 | if (!list_empty(&vq->list)) { |
| 266 | event = list_entry(ptr, struct vtimer_list, entry); | 320 | event = list_first_entry(&vq->list, struct vtimer_list, entry); |
| 267 | next = event->expires - vt_list->offset; | 321 | next = event->expires; |
| 268 | 322 | } else | |
| 269 | /* add the expired time from this interrupt handler | 323 | vq->do_spt = 0; |
| 270 | * and the callback functions | 324 | spin_unlock(&vq->lock); |
| 271 | */ | 325 | /* |
| 272 | asm volatile ("STPT %0" : "=m" (delta)); | 326 | * To improve precision add the time spent by the |
| 273 | delta = 0xffffffffffffffffLL - delta + 1; | 327 | * interrupt handler to the elapsed time. |
| 274 | vt_list->offset += delta; | 328 | * Note: CPU timer counts down and we got an interrupt, |
| 275 | next -= delta; | 329 | * the current content is negative |
| 276 | } else { | 330 | */ |
| 277 | vt_list->offset = 0; | 331 | elapsed = S390_lowcore.async_enter_timer - get_vtimer(); |
| 278 | next = VTIMER_MAX_SLICE; | 332 | set_vtimer(next - elapsed); |
| 279 | } | 333 | vq->timer = next - elapsed; |
| 280 | spin_unlock(&vt_list->lock); | 334 | vq->elapsed = elapsed; |
| 281 | set_vtimer(next); | ||
| 282 | } | 335 | } |
| 283 | 336 | ||
| 284 | void init_virt_timer(struct vtimer_list *timer) | 337 | void init_virt_timer(struct vtimer_list *timer) |
| 285 | { | 338 | { |
| 286 | timer->function = NULL; | 339 | timer->function = NULL; |
| 287 | INIT_LIST_HEAD(&timer->entry); | 340 | INIT_LIST_HEAD(&timer->entry); |
| 288 | spin_lock_init(&timer->lock); | ||
| 289 | } | 341 | } |
| 290 | EXPORT_SYMBOL(init_virt_timer); | 342 | EXPORT_SYMBOL(init_virt_timer); |
| 291 | 343 | ||
| @@ -299,44 +351,40 @@ static inline int vtimer_pending(struct vtimer_list *timer) | |||
| 299 | */ | 351 | */ |
| 300 | static void internal_add_vtimer(struct vtimer_list *timer) | 352 | static void internal_add_vtimer(struct vtimer_list *timer) |
| 301 | { | 353 | { |
| 354 | struct vtimer_queue *vq; | ||
| 302 | unsigned long flags; | 355 | unsigned long flags; |
| 303 | __u64 done; | 356 | __u64 left, expires; |
| 304 | struct vtimer_list *event; | ||
| 305 | struct vtimer_queue *vt_list; | ||
| 306 | 357 | ||
| 307 | vt_list = &per_cpu(virt_cpu_timer, timer->cpu); | 358 | vq = &per_cpu(virt_cpu_timer, timer->cpu); |
| 308 | spin_lock_irqsave(&vt_list->lock, flags); | 359 | spin_lock_irqsave(&vq->lock, flags); |
| 309 | 360 | ||
| 310 | BUG_ON(timer->cpu != smp_processor_id()); | 361 | BUG_ON(timer->cpu != smp_processor_id()); |
| 311 | 362 | ||
| 312 | /* if list is empty we only have to set the timer */ | 363 | if (list_empty(&vq->list)) { |
| 313 | if (list_empty(&vt_list->list)) { | 364 | /* First timer on this cpu, just program it. */ |
| 314 | /* reset the offset, this may happen if the last timer was | 365 | list_add(&timer->entry, &vq->list); |
| 315 | * just deleted by mod_virt_timer and the interrupt | 366 | set_vtimer(timer->expires); |
| 316 | * didn't happen until here | 367 | vq->timer = timer->expires; |
| 317 | */ | 368 | vq->elapsed = 0; |
| 318 | vt_list->offset = 0; | 369 | } else { |
| 319 | goto fire; | 370 | /* Check progress of old timers. */ |
| 371 | expires = timer->expires; | ||
| 372 | left = get_vtimer(); | ||
| 373 | if (likely((s64) expires < (s64) left)) { | ||
| 374 | /* The new timer expires before the current timer. */ | ||
| 375 | set_vtimer(expires); | ||
| 376 | vq->elapsed += vq->timer - left; | ||
| 377 | vq->timer = expires; | ||
| 378 | } else { | ||
| 379 | vq->elapsed += vq->timer - left; | ||
| 380 | vq->timer = left; | ||
| 381 | } | ||
| 382 | /* Insert new timer into per cpu list. */ | ||
| 383 | timer->expires += vq->elapsed; | ||
| 384 | list_add_sorted(timer, &vq->list); | ||
| 320 | } | 385 | } |
| 321 | 386 | ||
| 322 | /* save progress */ | 387 | spin_unlock_irqrestore(&vq->lock, flags); |
| 323 | asm volatile ("STPT %0" : "=m" (done)); | ||
| 324 | |||
| 325 | /* calculate completed work */ | ||
| 326 | done = vt_list->to_expire - done + vt_list->offset; | ||
| 327 | vt_list->offset = 0; | ||
| 328 | |||
| 329 | list_for_each_entry(event, &vt_list->list, entry) | ||
| 330 | event->expires -= done; | ||
| 331 | |||
| 332 | fire: | ||
| 333 | list_add_sorted(timer, &vt_list->list); | ||
| 334 | |||
| 335 | /* get first element, which is the next vtimer slice */ | ||
| 336 | event = list_entry(vt_list->list.next, struct vtimer_list, entry); | ||
| 337 | |||
| 338 | set_vtimer(event->expires); | ||
| 339 | spin_unlock_irqrestore(&vt_list->lock, flags); | ||
| 340 | /* release CPU acquired in prepare_vtimer or mod_virt_timer() */ | 388 | /* release CPU acquired in prepare_vtimer or mod_virt_timer() */ |
| 341 | put_cpu(); | 389 | put_cpu(); |
| 342 | } | 390 | } |
| @@ -381,14 +429,15 @@ EXPORT_SYMBOL(add_virt_timer_periodic); | |||
| 381 | * If we change a pending timer the function must be called on the CPU | 429 | * If we change a pending timer the function must be called on the CPU |
| 382 | * where the timer is running on, e.g. by smp_call_function_single() | 430 | * where the timer is running on, e.g. by smp_call_function_single() |
| 383 | * | 431 | * |
| 384 | * The original mod_timer adds the timer if it is not pending. For compatibility | 432 | * The original mod_timer adds the timer if it is not pending. For |
| 385 | * we do the same. The timer will be added on the current CPU as a oneshot timer. | 433 | * compatibility we do the same. The timer will be added on the current |
| 434 | * CPU as a oneshot timer. | ||
| 386 | * | 435 | * |
| 387 | * returns whether it has modified a pending timer (1) or not (0) | 436 | * returns whether it has modified a pending timer (1) or not (0) |
| 388 | */ | 437 | */ |
| 389 | int mod_virt_timer(struct vtimer_list *timer, __u64 expires) | 438 | int mod_virt_timer(struct vtimer_list *timer, __u64 expires) |
| 390 | { | 439 | { |
| 391 | struct vtimer_queue *vt_list; | 440 | struct vtimer_queue *vq; |
| 392 | unsigned long flags; | 441 | unsigned long flags; |
| 393 | int cpu; | 442 | int cpu; |
| 394 | 443 | ||
| @@ -404,17 +453,17 @@ int mod_virt_timer(struct vtimer_list *timer, __u64 expires) | |||
| 404 | return 1; | 453 | return 1; |
| 405 | 454 | ||
| 406 | cpu = get_cpu(); | 455 | cpu = get_cpu(); |
| 407 | vt_list = &per_cpu(virt_cpu_timer, cpu); | 456 | vq = &per_cpu(virt_cpu_timer, cpu); |
| 408 | 457 | ||
| 409 | /* check if we run on the right CPU */ | 458 | /* check if we run on the right CPU */ |
| 410 | BUG_ON(timer->cpu != cpu); | 459 | BUG_ON(timer->cpu != cpu); |
| 411 | 460 | ||
| 412 | /* disable interrupts before test if timer is pending */ | 461 | /* disable interrupts before test if timer is pending */ |
| 413 | spin_lock_irqsave(&vt_list->lock, flags); | 462 | spin_lock_irqsave(&vq->lock, flags); |
| 414 | 463 | ||
| 415 | /* if timer isn't pending add it on the current CPU */ | 464 | /* if timer isn't pending add it on the current CPU */ |
| 416 | if (!vtimer_pending(timer)) { | 465 | if (!vtimer_pending(timer)) { |
| 417 | spin_unlock_irqrestore(&vt_list->lock, flags); | 466 | spin_unlock_irqrestore(&vq->lock, flags); |
| 418 | /* we do not activate an interval timer with mod_virt_timer */ | 467 | /* we do not activate an interval timer with mod_virt_timer */ |
| 419 | timer->interval = 0; | 468 | timer->interval = 0; |
| 420 | timer->expires = expires; | 469 | timer->expires = expires; |
| @@ -431,7 +480,7 @@ int mod_virt_timer(struct vtimer_list *timer, __u64 expires) | |||
| 431 | timer->interval = expires; | 480 | timer->interval = expires; |
| 432 | 481 | ||
| 433 | /* the timer can't expire anymore so we can release the lock */ | 482 | /* the timer can't expire anymore so we can release the lock */ |
| 434 | spin_unlock_irqrestore(&vt_list->lock, flags); | 483 | spin_unlock_irqrestore(&vq->lock, flags); |
| 435 | internal_add_vtimer(timer); | 484 | internal_add_vtimer(timer); |
| 436 | return 1; | 485 | return 1; |
| 437 | } | 486 | } |
| @@ -445,25 +494,19 @@ EXPORT_SYMBOL(mod_virt_timer); | |||
| 445 | int del_virt_timer(struct vtimer_list *timer) | 494 | int del_virt_timer(struct vtimer_list *timer) |
| 446 | { | 495 | { |
| 447 | unsigned long flags; | 496 | unsigned long flags; |
| 448 | struct vtimer_queue *vt_list; | 497 | struct vtimer_queue *vq; |
| 449 | 498 | ||
| 450 | /* check if timer is pending */ | 499 | /* check if timer is pending */ |
| 451 | if (!vtimer_pending(timer)) | 500 | if (!vtimer_pending(timer)) |
| 452 | return 0; | 501 | return 0; |
| 453 | 502 | ||
| 454 | vt_list = &per_cpu(virt_cpu_timer, timer->cpu); | 503 | vq = &per_cpu(virt_cpu_timer, timer->cpu); |
| 455 | spin_lock_irqsave(&vt_list->lock, flags); | 504 | spin_lock_irqsave(&vq->lock, flags); |
| 456 | 505 | ||
| 457 | /* we don't interrupt a running timer, just let it expire! */ | 506 | /* we don't interrupt a running timer, just let it expire! */ |
| 458 | list_del_init(&timer->entry); | 507 | list_del_init(&timer->entry); |
| 459 | 508 | ||
| 460 | /* last timer removed */ | 509 | spin_unlock_irqrestore(&vq->lock, flags); |
| 461 | if (list_empty(&vt_list->list)) { | ||
| 462 | vt_list->to_expire = 0; | ||
| 463 | vt_list->offset = 0; | ||
| 464 | } | ||
| 465 | |||
| 466 | spin_unlock_irqrestore(&vt_list->lock, flags); | ||
| 467 | return 1; | 510 | return 1; |
| 468 | } | 511 | } |
| 469 | EXPORT_SYMBOL(del_virt_timer); | 512 | EXPORT_SYMBOL(del_virt_timer); |
| @@ -473,24 +516,19 @@ EXPORT_SYMBOL(del_virt_timer); | |||
| 473 | */ | 516 | */ |
| 474 | void init_cpu_vtimer(void) | 517 | void init_cpu_vtimer(void) |
| 475 | { | 518 | { |
| 476 | struct vtimer_queue *vt_list; | 519 | struct vtimer_queue *vq; |
| 477 | 520 | ||
| 478 | /* kick the virtual timer */ | 521 | /* kick the virtual timer */ |
| 479 | S390_lowcore.exit_timer = VTIMER_MAX_SLICE; | ||
| 480 | S390_lowcore.last_update_timer = VTIMER_MAX_SLICE; | ||
| 481 | asm volatile ("SPT %0" : : "m" (S390_lowcore.last_update_timer)); | ||
| 482 | asm volatile ("STCK %0" : "=m" (S390_lowcore.last_update_clock)); | 522 | asm volatile ("STCK %0" : "=m" (S390_lowcore.last_update_clock)); |
| 523 | asm volatile ("STPT %0" : "=m" (S390_lowcore.last_update_timer)); | ||
| 524 | |||
| 525 | /* initialize per cpu vtimer structure */ | ||
| 526 | vq = &__get_cpu_var(virt_cpu_timer); | ||
| 527 | INIT_LIST_HEAD(&vq->list); | ||
| 528 | spin_lock_init(&vq->lock); | ||
| 483 | 529 | ||
| 484 | /* enable cpu timer interrupts */ | 530 | /* enable cpu timer interrupts */ |
| 485 | __ctl_set_bit(0,10); | 531 | __ctl_set_bit(0,10); |
| 486 | |||
| 487 | vt_list = &__get_cpu_var(virt_cpu_timer); | ||
| 488 | INIT_LIST_HEAD(&vt_list->list); | ||
| 489 | spin_lock_init(&vt_list->lock); | ||
| 490 | vt_list->to_expire = 0; | ||
| 491 | vt_list->offset = 0; | ||
| 492 | vt_list->idle = 0; | ||
| 493 | |||
| 494 | } | 532 | } |
| 495 | 533 | ||
| 496 | void __init vtime_init(void) | 534 | void __init vtime_init(void) |
diff --git a/arch/sh/include/asm/topology.h b/arch/sh/include/asm/topology.h index 279d9cc4a007..066f0fba590e 100644 --- a/arch/sh/include/asm/topology.h +++ b/arch/sh/include/asm/topology.h | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #define parent_node(node) ((void)(node),0) | 32 | #define parent_node(node) ((void)(node),0) |
| 33 | 33 | ||
| 34 | #define node_to_cpumask(node) ((void)node, cpu_online_map) | 34 | #define node_to_cpumask(node) ((void)node, cpu_online_map) |
| 35 | #define cpumask_of_node(node) ((void)node, cpu_online_mask) | ||
| 35 | #define node_to_first_cpu(node) ((void)(node),0) | 36 | #define node_to_first_cpu(node) ((void)(node),0) |
| 36 | 37 | ||
| 37 | #define pcibus_to_node(bus) ((void)(bus), -1) | 38 | #define pcibus_to_node(bus) ((void)(bus), -1) |
diff --git a/arch/sparc/include/asm/topology_64.h b/arch/sparc/include/asm/topology_64.h index 001c04027c82..b8a65b64e1df 100644 --- a/arch/sparc/include/asm/topology_64.h +++ b/arch/sparc/include/asm/topology_64.h | |||
| @@ -16,8 +16,12 @@ static inline cpumask_t node_to_cpumask(int node) | |||
| 16 | { | 16 | { |
| 17 | return numa_cpumask_lookup_table[node]; | 17 | return numa_cpumask_lookup_table[node]; |
| 18 | } | 18 | } |
| 19 | #define cpumask_of_node(node) (&numa_cpumask_lookup_table[node]) | ||
| 19 | 20 | ||
| 20 | /* Returns a pointer to the cpumask of CPUs on Node 'node'. */ | 21 | /* |
| 22 | * Returns a pointer to the cpumask of CPUs on Node 'node'. | ||
| 23 | * Deprecated: use "const struct cpumask *mask = cpumask_of_node(node)" | ||
| 24 | */ | ||
| 21 | #define node_to_cpumask_ptr(v, node) \ | 25 | #define node_to_cpumask_ptr(v, node) \ |
| 22 | cpumask_t *v = &(numa_cpumask_lookup_table[node]) | 26 | cpumask_t *v = &(numa_cpumask_lookup_table[node]) |
| 23 | 27 | ||
| @@ -26,9 +30,7 @@ static inline cpumask_t node_to_cpumask(int node) | |||
| 26 | 30 | ||
| 27 | static inline int node_to_first_cpu(int node) | 31 | static inline int node_to_first_cpu(int node) |
| 28 | { | 32 | { |
| 29 | cpumask_t tmp; | 33 | return cpumask_first(cpumask_of_node(node)); |
| 30 | tmp = node_to_cpumask(node); | ||
| 31 | return first_cpu(tmp); | ||
| 32 | } | 34 | } |
| 33 | 35 | ||
| 34 | struct pci_bus; | 36 | struct pci_bus; |
| @@ -77,10 +79,13 @@ static inline int pcibus_to_node(struct pci_bus *pbus) | |||
| 77 | #define topology_core_id(cpu) (cpu_data(cpu).core_id) | 79 | #define topology_core_id(cpu) (cpu_data(cpu).core_id) |
| 78 | #define topology_core_siblings(cpu) (cpu_core_map[cpu]) | 80 | #define topology_core_siblings(cpu) (cpu_core_map[cpu]) |
| 79 | #define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu)) | 81 | #define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu)) |
| 82 | #define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) | ||
| 83 | #define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu)) | ||
| 80 | #define mc_capable() (sparc64_multi_core) | 84 | #define mc_capable() (sparc64_multi_core) |
| 81 | #define smt_capable() (sparc64_multi_core) | 85 | #define smt_capable() (sparc64_multi_core) |
| 82 | #endif /* CONFIG_SMP */ | 86 | #endif /* CONFIG_SMP */ |
| 83 | 87 | ||
| 84 | #define cpu_coregroup_map(cpu) (cpu_core_map[cpu]) | 88 | #define cpu_coregroup_map(cpu) (cpu_core_map[cpu]) |
| 89 | #define cpu_coregroup_mask(cpu) (&cpu_core_map[cpu]) | ||
| 85 | 90 | ||
| 86 | #endif /* _ASM_SPARC64_TOPOLOGY_H */ | 91 | #endif /* _ASM_SPARC64_TOPOLOGY_H */ |
diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index 322046cdf85f..4873f28905b0 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c | |||
| @@ -778,7 +778,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op, | |||
| 778 | out: | 778 | out: |
| 779 | nid = of_node_to_nid(dp); | 779 | nid = of_node_to_nid(dp); |
| 780 | if (nid != -1) { | 780 | if (nid != -1) { |
| 781 | cpumask_t numa_mask = node_to_cpumask(nid); | 781 | cpumask_t numa_mask = *cpumask_of_node(nid); |
| 782 | 782 | ||
| 783 | irq_set_affinity(irq, &numa_mask); | 783 | irq_set_affinity(irq, &numa_mask); |
| 784 | } | 784 | } |
diff --git a/arch/sparc/kernel/pci_msi.c b/arch/sparc/kernel/pci_msi.c index 0d0cd815e83e..4ef282e81912 100644 --- a/arch/sparc/kernel/pci_msi.c +++ b/arch/sparc/kernel/pci_msi.c | |||
| @@ -286,7 +286,7 @@ static int bringup_one_msi_queue(struct pci_pbm_info *pbm, | |||
| 286 | 286 | ||
| 287 | nid = pbm->numa_node; | 287 | nid = pbm->numa_node; |
| 288 | if (nid != -1) { | 288 | if (nid != -1) { |
| 289 | cpumask_t numa_mask = node_to_cpumask(nid); | 289 | cpumask_t numa_mask = *cpumask_of_node(nid); |
| 290 | 290 | ||
| 291 | irq_set_affinity(irq, &numa_mask); | 291 | irq_set_affinity(irq, &numa_mask); |
| 292 | } | 292 | } |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 249d1e0824b5..862adb9bf0d4 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -586,6 +586,16 @@ config AMD_IOMMU | |||
| 586 | your BIOS for an option to enable it or if you have an IVRS ACPI | 586 | your BIOS for an option to enable it or if you have an IVRS ACPI |
| 587 | table. | 587 | table. |
| 588 | 588 | ||
| 589 | config AMD_IOMMU_STATS | ||
| 590 | bool "Export AMD IOMMU statistics to debugfs" | ||
| 591 | depends on AMD_IOMMU | ||
| 592 | select DEBUG_FS | ||
| 593 | help | ||
| 594 | This option enables code in the AMD IOMMU driver to collect various | ||
| 595 | statistics about whats happening in the driver and exports that | ||
| 596 | information to userspace via debugfs. | ||
| 597 | If unsure, say N. | ||
| 598 | |||
| 589 | # need this always selected by IOMMU for the VIA workaround | 599 | # need this always selected by IOMMU for the VIA workaround |
| 590 | config SWIOTLB | 600 | config SWIOTLB |
| 591 | def_bool y if X86_64 | 601 | def_bool y if X86_64 |
| @@ -599,6 +609,9 @@ config SWIOTLB | |||
| 599 | config IOMMU_HELPER | 609 | config IOMMU_HELPER |
| 600 | def_bool (CALGARY_IOMMU || GART_IOMMU || SWIOTLB || AMD_IOMMU) | 610 | def_bool (CALGARY_IOMMU || GART_IOMMU || SWIOTLB || AMD_IOMMU) |
| 601 | 611 | ||
| 612 | config IOMMU_API | ||
| 613 | def_bool (AMD_IOMMU || DMAR) | ||
| 614 | |||
| 602 | config MAXSMP | 615 | config MAXSMP |
| 603 | bool "Configure Maximum number of SMP Processors and NUMA Nodes" | 616 | bool "Configure Maximum number of SMP Processors and NUMA Nodes" |
| 604 | depends on X86_64 && SMP && DEBUG_KERNEL && EXPERIMENTAL | 617 | depends on X86_64 && SMP && DEBUG_KERNEL && EXPERIMENTAL |
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index b195f85526e3..9dabd00e9805 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c | |||
| @@ -24,15 +24,14 @@ | |||
| 24 | #include <asm/ucontext.h> | 24 | #include <asm/ucontext.h> |
| 25 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
| 26 | #include <asm/i387.h> | 26 | #include <asm/i387.h> |
| 27 | #include <asm/ia32.h> | ||
| 28 | #include <asm/ptrace.h> | 27 | #include <asm/ptrace.h> |
| 29 | #include <asm/ia32_unistd.h> | 28 | #include <asm/ia32_unistd.h> |
| 30 | #include <asm/user32.h> | 29 | #include <asm/user32.h> |
| 31 | #include <asm/sigcontext32.h> | 30 | #include <asm/sigcontext32.h> |
| 32 | #include <asm/proto.h> | 31 | #include <asm/proto.h> |
| 33 | #include <asm/vdso.h> | 32 | #include <asm/vdso.h> |
| 34 | |||
| 35 | #include <asm/sigframe.h> | 33 | #include <asm/sigframe.h> |
| 34 | #include <asm/sys_ia32.h> | ||
| 36 | 35 | ||
| 37 | #define DEBUG_SIG 0 | 36 | #define DEBUG_SIG 0 |
| 38 | 37 | ||
diff --git a/arch/x86/ia32/ipc32.c b/arch/x86/ia32/ipc32.c index d21991ce606c..29cdcd02ead3 100644 --- a/arch/x86/ia32/ipc32.c +++ b/arch/x86/ia32/ipc32.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <linux/shm.h> | 8 | #include <linux/shm.h> |
| 9 | #include <linux/ipc.h> | 9 | #include <linux/ipc.h> |
| 10 | #include <linux/compat.h> | 10 | #include <linux/compat.h> |
| 11 | #include <asm/sys_ia32.h> | ||
| 11 | 12 | ||
| 12 | asmlinkage long sys32_ipc(u32 call, int first, int second, int third, | 13 | asmlinkage long sys32_ipc(u32 call, int first, int second, int third, |
| 13 | compat_uptr_t ptr, u32 fifth) | 14 | compat_uptr_t ptr, u32 fifth) |
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index 2e09dcd3c0a6..6c0d7f6231af 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c | |||
| @@ -44,8 +44,8 @@ | |||
| 44 | #include <asm/types.h> | 44 | #include <asm/types.h> |
| 45 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
| 46 | #include <asm/atomic.h> | 46 | #include <asm/atomic.h> |
| 47 | #include <asm/ia32.h> | ||
| 48 | #include <asm/vgtod.h> | 47 | #include <asm/vgtod.h> |
| 48 | #include <asm/sys_ia32.h> | ||
| 49 | 49 | ||
| 50 | #define AA(__x) ((unsigned long)(__x)) | 50 | #define AA(__x) ((unsigned long)(__x)) |
| 51 | 51 | ||
diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h index ac302a2fa339..95c8cd9d22b5 100644 --- a/arch/x86/include/asm/amd_iommu_types.h +++ b/arch/x86/include/asm/amd_iommu_types.h | |||
| @@ -190,16 +190,23 @@ | |||
| 190 | /* FIXME: move this macro to <linux/pci.h> */ | 190 | /* FIXME: move this macro to <linux/pci.h> */ |
| 191 | #define PCI_BUS(x) (((x) >> 8) & 0xff) | 191 | #define PCI_BUS(x) (((x) >> 8) & 0xff) |
| 192 | 192 | ||
| 193 | /* Protection domain flags */ | ||
| 194 | #define PD_DMA_OPS_MASK (1UL << 0) /* domain used for dma_ops */ | ||
| 195 | #define PD_DEFAULT_MASK (1UL << 1) /* domain is a default dma_ops | ||
| 196 | domain for an IOMMU */ | ||
| 197 | |||
| 193 | /* | 198 | /* |
| 194 | * This structure contains generic data for IOMMU protection domains | 199 | * This structure contains generic data for IOMMU protection domains |
| 195 | * independent of their use. | 200 | * independent of their use. |
| 196 | */ | 201 | */ |
| 197 | struct protection_domain { | 202 | struct protection_domain { |
| 198 | spinlock_t lock; /* mostly used to lock the page table*/ | 203 | spinlock_t lock; /* mostly used to lock the page table*/ |
| 199 | u16 id; /* the domain id written to the device table */ | 204 | u16 id; /* the domain id written to the device table */ |
| 200 | int mode; /* paging mode (0-6 levels) */ | 205 | int mode; /* paging mode (0-6 levels) */ |
| 201 | u64 *pt_root; /* page table root pointer */ | 206 | u64 *pt_root; /* page table root pointer */ |
| 202 | void *priv; /* private data */ | 207 | unsigned long flags; /* flags to find out type of domain */ |
| 208 | unsigned dev_cnt; /* devices assigned to this domain */ | ||
| 209 | void *priv; /* private data */ | ||
| 203 | }; | 210 | }; |
| 204 | 211 | ||
| 205 | /* | 212 | /* |
| @@ -295,7 +302,7 @@ struct amd_iommu { | |||
| 295 | bool int_enabled; | 302 | bool int_enabled; |
| 296 | 303 | ||
| 297 | /* if one, we need to send a completion wait command */ | 304 | /* if one, we need to send a completion wait command */ |
| 298 | int need_sync; | 305 | bool need_sync; |
| 299 | 306 | ||
| 300 | /* default dma_ops domain for that IOMMU */ | 307 | /* default dma_ops domain for that IOMMU */ |
| 301 | struct dma_ops_domain *default_dom; | 308 | struct dma_ops_domain *default_dom; |
| @@ -374,7 +381,7 @@ extern struct protection_domain **amd_iommu_pd_table; | |||
| 374 | extern unsigned long *amd_iommu_pd_alloc_bitmap; | 381 | extern unsigned long *amd_iommu_pd_alloc_bitmap; |
| 375 | 382 | ||
| 376 | /* will be 1 if device isolation is enabled */ | 383 | /* will be 1 if device isolation is enabled */ |
| 377 | extern int amd_iommu_isolate; | 384 | extern bool amd_iommu_isolate; |
| 378 | 385 | ||
| 379 | /* | 386 | /* |
| 380 | * If true, the addresses will be flushed on unmap time, not when | 387 | * If true, the addresses will be flushed on unmap time, not when |
| @@ -382,18 +389,6 @@ extern int amd_iommu_isolate; | |||
| 382 | */ | 389 | */ |
| 383 | extern bool amd_iommu_unmap_flush; | 390 | extern bool amd_iommu_unmap_flush; |
| 384 | 391 | ||
| 385 | /* takes a PCI device id and prints it out in a readable form */ | ||
| 386 | static inline void print_devid(u16 devid, int nl) | ||
| 387 | { | ||
| 388 | int bus = devid >> 8; | ||
| 389 | int dev = devid >> 3 & 0x1f; | ||
| 390 | int fn = devid & 0x07; | ||
| 391 | |||
| 392 | printk("%02x:%02x.%x", bus, dev, fn); | ||
| 393 | if (nl) | ||
| 394 | printk("\n"); | ||
| 395 | } | ||
| 396 | |||
| 397 | /* takes bus and device/function and returns the device id | 392 | /* takes bus and device/function and returns the device id |
| 398 | * FIXME: should that be in generic PCI code? */ | 393 | * FIXME: should that be in generic PCI code? */ |
| 399 | static inline u16 calc_devid(u8 bus, u8 devfn) | 394 | static inline u16 calc_devid(u8 bus, u8 devfn) |
| @@ -401,4 +396,32 @@ static inline u16 calc_devid(u8 bus, u8 devfn) | |||
| 401 | return (((u16)bus) << 8) | devfn; | 396 | return (((u16)bus) << 8) | devfn; |
| 402 | } | 397 | } |
| 403 | 398 | ||
| 399 | #ifdef CONFIG_AMD_IOMMU_STATS | ||
| 400 | |||
| 401 | struct __iommu_counter { | ||
| 402 | char *name; | ||
| 403 | struct dentry *dent; | ||
| 404 | u64 value; | ||
| 405 | }; | ||
| 406 | |||
| 407 | #define DECLARE_STATS_COUNTER(nm) \ | ||
| 408 | static struct __iommu_counter nm = { \ | ||
| 409 | .name = #nm, \ | ||
| 410 | } | ||
| 411 | |||
| 412 | #define INC_STATS_COUNTER(name) name.value += 1 | ||
| 413 | #define ADD_STATS_COUNTER(name, x) name.value += (x) | ||
| 414 | #define SUB_STATS_COUNTER(name, x) name.value -= (x) | ||
| 415 | |||
| 416 | #else /* CONFIG_AMD_IOMMU_STATS */ | ||
| 417 | |||
| 418 | #define DECLARE_STATS_COUNTER(name) | ||
| 419 | #define INC_STATS_COUNTER(name) | ||
| 420 | #define ADD_STATS_COUNTER(name, x) | ||
| 421 | #define SUB_STATS_COUNTER(name, x) | ||
| 422 | |||
| 423 | static inline void amd_iommu_stats_init(void) { } | ||
| 424 | |||
| 425 | #endif /* CONFIG_AMD_IOMMU_STATS */ | ||
| 426 | |||
| 404 | #endif /* _ASM_X86_AMD_IOMMU_TYPES_H */ | 427 | #endif /* _ASM_X86_AMD_IOMMU_TYPES_H */ |
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 25caa0738af5..ab1d51a8855e 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h | |||
| @@ -54,7 +54,6 @@ extern int disable_apic; | |||
| 54 | extern int is_vsmp_box(void); | 54 | extern int is_vsmp_box(void); |
| 55 | extern void xapic_wait_icr_idle(void); | 55 | extern void xapic_wait_icr_idle(void); |
| 56 | extern u32 safe_xapic_wait_icr_idle(void); | 56 | extern u32 safe_xapic_wait_icr_idle(void); |
| 57 | extern u64 xapic_icr_read(void); | ||
| 58 | extern void xapic_icr_write(u32, u32); | 57 | extern void xapic_icr_write(u32, u32); |
| 59 | extern int setup_profiling_timer(unsigned int); | 58 | extern int setup_profiling_timer(unsigned int); |
| 60 | 59 | ||
| @@ -93,7 +92,7 @@ static inline u32 native_apic_msr_read(u32 reg) | |||
| 93 | } | 92 | } |
| 94 | 93 | ||
| 95 | #ifndef CONFIG_X86_32 | 94 | #ifndef CONFIG_X86_32 |
| 96 | extern int x2apic, x2apic_preenabled; | 95 | extern int x2apic; |
| 97 | extern void check_x2apic(void); | 96 | extern void check_x2apic(void); |
| 98 | extern void enable_x2apic(void); | 97 | extern void enable_x2apic(void); |
| 99 | extern void enable_IR_x2apic(void); | 98 | extern void enable_IR_x2apic(void); |
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index a2e545c91c35..ca5ffb2856b6 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h | |||
| @@ -90,6 +90,7 @@ extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size); | |||
| 90 | 90 | ||
| 91 | #endif /* CONFIG_X86_32 */ | 91 | #endif /* CONFIG_X86_32 */ |
| 92 | 92 | ||
| 93 | extern int add_efi_memmap; | ||
| 93 | extern void efi_reserve_early(void); | 94 | extern void efi_reserve_early(void); |
| 94 | extern void efi_call_phys_prelog(void); | 95 | extern void efi_call_phys_prelog(void); |
| 95 | extern void efi_call_phys_epilog(void); | 96 | extern void efi_call_phys_epilog(void); |
diff --git a/arch/x86/include/asm/es7000/apic.h b/arch/x86/include/asm/es7000/apic.h index 51ac1230294e..bc53d5ef1386 100644 --- a/arch/x86/include/asm/es7000/apic.h +++ b/arch/x86/include/asm/es7000/apic.h | |||
| @@ -157,7 +157,7 @@ cpu_mask_to_apicid_cluster(const struct cpumask *cpumask) | |||
| 157 | 157 | ||
| 158 | num_bits_set = cpumask_weight(cpumask); | 158 | num_bits_set = cpumask_weight(cpumask); |
| 159 | /* Return id to all */ | 159 | /* Return id to all */ |
| 160 | if (num_bits_set == NR_CPUS) | 160 | if (num_bits_set == nr_cpu_ids) |
| 161 | return 0xFF; | 161 | return 0xFF; |
| 162 | /* | 162 | /* |
| 163 | * The cpus in the mask must all be on the apic cluster. If are not | 163 | * The cpus in the mask must all be on the apic cluster. If are not |
| @@ -190,7 +190,7 @@ static inline unsigned int cpu_mask_to_apicid(const cpumask_t *cpumask) | |||
| 190 | 190 | ||
| 191 | num_bits_set = cpus_weight(*cpumask); | 191 | num_bits_set = cpus_weight(*cpumask); |
| 192 | /* Return id to all */ | 192 | /* Return id to all */ |
| 193 | if (num_bits_set == NR_CPUS) | 193 | if (num_bits_set == nr_cpu_ids) |
| 194 | return cpu_to_logical_apicid(0); | 194 | return cpu_to_logical_apicid(0); |
| 195 | /* | 195 | /* |
| 196 | * The cpus in the mask must all be on the apic cluster. If are not | 196 | * The cpus in the mask must all be on the apic cluster. If are not |
| @@ -218,9 +218,6 @@ static inline unsigned int cpu_mask_to_apicid(const cpumask_t *cpumask) | |||
| 218 | static inline unsigned int cpu_mask_to_apicid_and(const struct cpumask *inmask, | 218 | static inline unsigned int cpu_mask_to_apicid_and(const struct cpumask *inmask, |
| 219 | const struct cpumask *andmask) | 219 | const struct cpumask *andmask) |
| 220 | { | 220 | { |
| 221 | int num_bits_set; | ||
| 222 | int cpus_found = 0; | ||
| 223 | int cpu; | ||
| 224 | int apicid = cpu_to_logical_apicid(0); | 221 | int apicid = cpu_to_logical_apicid(0); |
| 225 | cpumask_var_t cpumask; | 222 | cpumask_var_t cpumask; |
| 226 | 223 | ||
| @@ -229,31 +226,8 @@ static inline unsigned int cpu_mask_to_apicid_and(const struct cpumask *inmask, | |||
| 229 | 226 | ||
| 230 | cpumask_and(cpumask, inmask, andmask); | 227 | cpumask_and(cpumask, inmask, andmask); |
| 231 | cpumask_and(cpumask, cpumask, cpu_online_mask); | 228 | cpumask_and(cpumask, cpumask, cpu_online_mask); |
| 229 | apicid = cpu_mask_to_apicid(cpumask); | ||
| 232 | 230 | ||
| 233 | num_bits_set = cpumask_weight(cpumask); | ||
| 234 | /* Return id to all */ | ||
| 235 | if (num_bits_set == NR_CPUS) | ||
| 236 | goto exit; | ||
| 237 | /* | ||
| 238 | * The cpus in the mask must all be on the apic cluster. If are not | ||
| 239 | * on the same apicid cluster return default value of TARGET_CPUS. | ||
| 240 | */ | ||
| 241 | cpu = cpumask_first(cpumask); | ||
| 242 | apicid = cpu_to_logical_apicid(cpu); | ||
| 243 | while (cpus_found < num_bits_set) { | ||
| 244 | if (cpumask_test_cpu(cpu, cpumask)) { | ||
| 245 | int new_apicid = cpu_to_logical_apicid(cpu); | ||
| 246 | if (apicid_cluster(apicid) != | ||
| 247 | apicid_cluster(new_apicid)){ | ||
| 248 | printk ("%s: Not a valid mask!\n", __func__); | ||
| 249 | return cpu_to_logical_apicid(0); | ||
| 250 | } | ||
| 251 | apicid = new_apicid; | ||
| 252 | cpus_found++; | ||
| 253 | } | ||
| 254 | cpu++; | ||
| 255 | } | ||
| 256 | exit: | ||
| 257 | free_cpumask_var(cpumask); | 231 | free_cpumask_var(cpumask); |
| 258 | return apicid; | 232 | return apicid; |
| 259 | } | 233 | } |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 97215a458e5f..730843d1d2fb 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
| @@ -360,7 +360,7 @@ struct kvm_arch{ | |||
| 360 | struct list_head active_mmu_pages; | 360 | struct list_head active_mmu_pages; |
| 361 | struct list_head assigned_dev_head; | 361 | struct list_head assigned_dev_head; |
| 362 | struct list_head oos_global_pages; | 362 | struct list_head oos_global_pages; |
| 363 | struct dmar_domain *intel_iommu_domain; | 363 | struct iommu_domain *iommu_domain; |
| 364 | struct kvm_pic *vpic; | 364 | struct kvm_pic *vpic; |
| 365 | struct kvm_ioapic *vioapic; | 365 | struct kvm_ioapic *vioapic; |
| 366 | struct kvm_pit *vpit; | 366 | struct kvm_pit *vpit; |
diff --git a/arch/x86/include/asm/lguest.h b/arch/x86/include/asm/lguest.h index d28a507cef39..1caf57628b9c 100644 --- a/arch/x86/include/asm/lguest.h +++ b/arch/x86/include/asm/lguest.h | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | #define SHARED_SWITCHER_PAGES \ | 15 | #define SHARED_SWITCHER_PAGES \ |
| 16 | DIV_ROUND_UP(end_switcher_text - start_switcher_text, PAGE_SIZE) | 16 | DIV_ROUND_UP(end_switcher_text - start_switcher_text, PAGE_SIZE) |
| 17 | /* Pages for switcher itself, then two pages per cpu */ | 17 | /* Pages for switcher itself, then two pages per cpu */ |
| 18 | #define TOTAL_SWITCHER_PAGES (SHARED_SWITCHER_PAGES + 2 * NR_CPUS) | 18 | #define TOTAL_SWITCHER_PAGES (SHARED_SWITCHER_PAGES + 2 * nr_cpu_ids) |
| 19 | 19 | ||
| 20 | /* We map at -4M for ease of mapping into the guest (one PTE page). */ | 20 | /* We map at -4M for ease of mapping into the guest (one PTE page). */ |
| 21 | #define SWITCHER_ADDR 0xFFC00000 | 21 | #define SWITCHER_ADDR 0xFFC00000 |
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h index 91885c28f66b..62d14ce3cd00 100644 --- a/arch/x86/include/asm/mpspec.h +++ b/arch/x86/include/asm/mpspec.h | |||
| @@ -6,13 +6,13 @@ | |||
| 6 | #include <asm/mpspec_def.h> | 6 | #include <asm/mpspec_def.h> |
| 7 | 7 | ||
| 8 | extern int apic_version[MAX_APICS]; | 8 | extern int apic_version[MAX_APICS]; |
| 9 | extern int pic_mode; | ||
| 9 | 10 | ||
| 10 | #ifdef CONFIG_X86_32 | 11 | #ifdef CONFIG_X86_32 |
| 11 | #include <mach_mpspec.h> | 12 | #include <mach_mpspec.h> |
| 12 | 13 | ||
| 13 | extern unsigned int def_to_bigsmp; | 14 | extern unsigned int def_to_bigsmp; |
| 14 | extern u8 apicid_2_node[]; | 15 | extern u8 apicid_2_node[]; |
| 15 | extern int pic_mode; | ||
| 16 | 16 | ||
| 17 | #ifdef CONFIG_X86_NUMAQ | 17 | #ifdef CONFIG_X86_NUMAQ |
| 18 | extern int mp_bus_id_to_node[MAX_MP_BUSSES]; | 18 | extern int mp_bus_id_to_node[MAX_MP_BUSSES]; |
diff --git a/arch/x86/include/asm/numaq/apic.h b/arch/x86/include/asm/numaq/apic.h index c80f00d29965..bf37bc49bd8e 100644 --- a/arch/x86/include/asm/numaq/apic.h +++ b/arch/x86/include/asm/numaq/apic.h | |||
| @@ -63,8 +63,8 @@ static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map) | |||
| 63 | extern u8 cpu_2_logical_apicid[]; | 63 | extern u8 cpu_2_logical_apicid[]; |
| 64 | static inline int cpu_to_logical_apicid(int cpu) | 64 | static inline int cpu_to_logical_apicid(int cpu) |
| 65 | { | 65 | { |
| 66 | if (cpu >= NR_CPUS) | 66 | if (cpu >= nr_cpu_ids) |
| 67 | return BAD_APICID; | 67 | return BAD_APICID; |
| 68 | return (int)cpu_2_logical_apicid[cpu]; | 68 | return (int)cpu_2_logical_apicid[cpu]; |
| 69 | } | 69 | } |
| 70 | 70 | ||
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index 66834c41c049..a977de23cb4d 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h | |||
| @@ -102,9 +102,9 @@ extern void pci_iommu_alloc(void); | |||
| 102 | 102 | ||
| 103 | #ifdef CONFIG_NUMA | 103 | #ifdef CONFIG_NUMA |
| 104 | /* Returns the node based on pci bus */ | 104 | /* Returns the node based on pci bus */ |
| 105 | static inline int __pcibus_to_node(struct pci_bus *bus) | 105 | static inline int __pcibus_to_node(const struct pci_bus *bus) |
| 106 | { | 106 | { |
| 107 | struct pci_sysdata *sd = bus->sysdata; | 107 | const struct pci_sysdata *sd = bus->sysdata; |
| 108 | 108 | ||
| 109 | return sd->node; | 109 | return sd->node; |
| 110 | } | 110 | } |
| @@ -113,6 +113,12 @@ static inline cpumask_t __pcibus_to_cpumask(struct pci_bus *bus) | |||
| 113 | { | 113 | { |
| 114 | return node_to_cpumask(__pcibus_to_node(bus)); | 114 | return node_to_cpumask(__pcibus_to_node(bus)); |
| 115 | } | 115 | } |
| 116 | |||
| 117 | static inline const struct cpumask * | ||
| 118 | cpumask_of_pcibus(const struct pci_bus *bus) | ||
| 119 | { | ||
| 120 | return cpumask_of_node(__pcibus_to_node(bus)); | ||
| 121 | } | ||
| 116 | #endif | 122 | #endif |
| 117 | 123 | ||
| 118 | #endif /* _ASM_X86_PCI_H */ | 124 | #endif /* _ASM_X86_PCI_H */ |
diff --git a/arch/x86/pci/pci.h b/arch/x86/include/asm/pci_x86.h index 1959018aac02..e60fd3e14bdf 100644 --- a/arch/x86/pci/pci.h +++ b/arch/x86/include/asm/pci_x86.h | |||
| @@ -57,7 +57,8 @@ extern struct pci_ops pci_root_ops; | |||
| 57 | struct irq_info { | 57 | struct irq_info { |
| 58 | u8 bus, devfn; /* Bus, device and function */ | 58 | u8 bus, devfn; /* Bus, device and function */ |
| 59 | struct { | 59 | struct { |
| 60 | u8 link; /* IRQ line ID, chipset dependent, 0=not routed */ | 60 | u8 link; /* IRQ line ID, chipset dependent, |
| 61 | 0 = not routed */ | ||
| 61 | u16 bitmap; /* Available IRQs */ | 62 | u16 bitmap; /* Available IRQs */ |
| 62 | } __attribute__((packed)) irq[4]; | 63 | } __attribute__((packed)) irq[4]; |
| 63 | u8 slot; /* Slot number, 0=onboard */ | 64 | u8 slot; /* Slot number, 0=onboard */ |
| @@ -69,11 +70,13 @@ struct irq_routing_table { | |||
| 69 | u16 version; /* PIRQ_VERSION */ | 70 | u16 version; /* PIRQ_VERSION */ |
| 70 | u16 size; /* Table size in bytes */ | 71 | u16 size; /* Table size in bytes */ |
| 71 | u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */ | 72 | u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */ |
| 72 | u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */ | 73 | u16 exclusive_irqs; /* IRQs devoted exclusively to |
| 73 | u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */ | 74 | PCI usage */ |
| 75 | u16 rtr_vendor, rtr_device; /* Vendor and device ID of | ||
| 76 | interrupt router */ | ||
| 74 | u32 miniport_data; /* Crap */ | 77 | u32 miniport_data; /* Crap */ |
| 75 | u8 rfu[11]; | 78 | u8 rfu[11]; |
| 76 | u8 checksum; /* Modulo 256 checksum must give zero */ | 79 | u8 checksum; /* Modulo 256 checksum must give 0 */ |
| 77 | struct irq_info slots[0]; | 80 | struct irq_info slots[0]; |
| 78 | } __attribute__((packed)); | 81 | } __attribute__((packed)); |
| 79 | 82 | ||
| @@ -148,15 +151,15 @@ static inline unsigned int mmio_config_readl(void __iomem *pos) | |||
| 148 | 151 | ||
| 149 | static inline void mmio_config_writeb(void __iomem *pos, u8 val) | 152 | static inline void mmio_config_writeb(void __iomem *pos, u8 val) |
| 150 | { | 153 | { |
| 151 | asm volatile("movb %%al,(%1)" :: "a" (val), "r" (pos) : "memory"); | 154 | asm volatile("movb %%al,(%1)" : : "a" (val), "r" (pos) : "memory"); |
| 152 | } | 155 | } |
| 153 | 156 | ||
| 154 | static inline void mmio_config_writew(void __iomem *pos, u16 val) | 157 | static inline void mmio_config_writew(void __iomem *pos, u16 val) |
| 155 | { | 158 | { |
| 156 | asm volatile("movw %%ax,(%1)" :: "a" (val), "r" (pos) : "memory"); | 159 | asm volatile("movw %%ax,(%1)" : : "a" (val), "r" (pos) : "memory"); |
| 157 | } | 160 | } |
| 158 | 161 | ||
| 159 | static inline void mmio_config_writel(void __iomem *pos, u32 val) | 162 | static inline void mmio_config_writel(void __iomem *pos, u32 val) |
| 160 | { | 163 | { |
| 161 | asm volatile("movl %%eax,(%1)" :: "a" (val), "r" (pos) : "memory"); | 164 | asm volatile("movl %%eax,(%1)" : : "a" (val), "r" (pos) : "memory"); |
| 162 | } | 165 | } |
diff --git a/arch/x86/include/asm/summit/apic.h b/arch/x86/include/asm/summit/apic.h index 99327d1be49f..4bb5fb34f030 100644 --- a/arch/x86/include/asm/summit/apic.h +++ b/arch/x86/include/asm/summit/apic.h | |||
| @@ -52,7 +52,7 @@ static inline void init_apic_ldr(void) | |||
| 52 | int i; | 52 | int i; |
| 53 | 53 | ||
| 54 | /* Create logical APIC IDs by counting CPUs already in cluster. */ | 54 | /* Create logical APIC IDs by counting CPUs already in cluster. */ |
| 55 | for (count = 0, i = NR_CPUS; --i >= 0; ) { | 55 | for (count = 0, i = nr_cpu_ids; --i >= 0; ) { |
| 56 | lid = cpu_2_logical_apicid[i]; | 56 | lid = cpu_2_logical_apicid[i]; |
| 57 | if (lid != BAD_APICID && apicid_cluster(lid) == my_cluster) | 57 | if (lid != BAD_APICID && apicid_cluster(lid) == my_cluster) |
| 58 | ++count; | 58 | ++count; |
| @@ -97,8 +97,8 @@ static inline int apicid_to_node(int logical_apicid) | |||
| 97 | static inline int cpu_to_logical_apicid(int cpu) | 97 | static inline int cpu_to_logical_apicid(int cpu) |
| 98 | { | 98 | { |
| 99 | #ifdef CONFIG_SMP | 99 | #ifdef CONFIG_SMP |
| 100 | if (cpu >= NR_CPUS) | 100 | if (cpu >= nr_cpu_ids) |
| 101 | return BAD_APICID; | 101 | return BAD_APICID; |
| 102 | return (int)cpu_2_logical_apicid[cpu]; | 102 | return (int)cpu_2_logical_apicid[cpu]; |
| 103 | #else | 103 | #else |
| 104 | return logical_smp_processor_id(); | 104 | return logical_smp_processor_id(); |
| @@ -107,7 +107,7 @@ static inline int cpu_to_logical_apicid(int cpu) | |||
| 107 | 107 | ||
| 108 | static inline int cpu_present_to_apicid(int mps_cpu) | 108 | static inline int cpu_present_to_apicid(int mps_cpu) |
| 109 | { | 109 | { |
| 110 | if (mps_cpu < NR_CPUS) | 110 | if (mps_cpu < nr_cpu_ids) |
| 111 | return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu); | 111 | return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu); |
| 112 | else | 112 | else |
| 113 | return BAD_APICID; | 113 | return BAD_APICID; |
| @@ -146,7 +146,7 @@ static inline unsigned int cpu_mask_to_apicid(const cpumask_t *cpumask) | |||
| 146 | 146 | ||
| 147 | num_bits_set = cpus_weight(*cpumask); | 147 | num_bits_set = cpus_weight(*cpumask); |
| 148 | /* Return id to all */ | 148 | /* Return id to all */ |
| 149 | if (num_bits_set == NR_CPUS) | 149 | if (num_bits_set >= nr_cpu_ids) |
| 150 | return (int) 0xFF; | 150 | return (int) 0xFF; |
| 151 | /* | 151 | /* |
| 152 | * The cpus in the mask must all be on the apic cluster. If are not | 152 | * The cpus in the mask must all be on the apic cluster. If are not |
| @@ -173,42 +173,16 @@ static inline unsigned int cpu_mask_to_apicid(const cpumask_t *cpumask) | |||
| 173 | static inline unsigned int cpu_mask_to_apicid_and(const struct cpumask *inmask, | 173 | static inline unsigned int cpu_mask_to_apicid_and(const struct cpumask *inmask, |
| 174 | const struct cpumask *andmask) | 174 | const struct cpumask *andmask) |
| 175 | { | 175 | { |
| 176 | int num_bits_set; | 176 | int apicid = cpu_to_logical_apicid(0); |
| 177 | int cpus_found = 0; | ||
| 178 | int cpu; | ||
| 179 | int apicid = 0xFF; | ||
| 180 | cpumask_var_t cpumask; | 177 | cpumask_var_t cpumask; |
| 181 | 178 | ||
| 182 | if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) | 179 | if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) |
| 183 | return (int) 0xFF; | 180 | return apicid; |
| 184 | 181 | ||
| 185 | cpumask_and(cpumask, inmask, andmask); | 182 | cpumask_and(cpumask, inmask, andmask); |
| 186 | cpumask_and(cpumask, cpumask, cpu_online_mask); | 183 | cpumask_and(cpumask, cpumask, cpu_online_mask); |
| 184 | apicid = cpu_mask_to_apicid(cpumask); | ||
| 187 | 185 | ||
| 188 | num_bits_set = cpumask_weight(cpumask); | ||
| 189 | /* Return id to all */ | ||
| 190 | if (num_bits_set == nr_cpu_ids) | ||
| 191 | goto exit; | ||
| 192 | /* | ||
| 193 | * The cpus in the mask must all be on the apic cluster. If are not | ||
| 194 | * on the same apicid cluster return default value of TARGET_CPUS. | ||
| 195 | */ | ||
| 196 | cpu = cpumask_first(cpumask); | ||
| 197 | apicid = cpu_to_logical_apicid(cpu); | ||
| 198 | while (cpus_found < num_bits_set) { | ||
| 199 | if (cpumask_test_cpu(cpu, cpumask)) { | ||
| 200 | int new_apicid = cpu_to_logical_apicid(cpu); | ||
| 201 | if (apicid_cluster(apicid) != | ||
| 202 | apicid_cluster(new_apicid)){ | ||
| 203 | printk ("%s: Not a valid mask!\n", __func__); | ||
| 204 | return 0xFF; | ||
| 205 | } | ||
| 206 | apicid = apicid | new_apicid; | ||
| 207 | cpus_found++; | ||
| 208 | } | ||
| 209 | cpu++; | ||
| 210 | } | ||
| 211 | exit: | ||
| 212 | free_cpumask_var(cpumask); | 186 | free_cpumask_var(cpumask); |
| 213 | return apicid; | 187 | return apicid; |
| 214 | } | 188 | } |
diff --git a/arch/x86/include/asm/sys_ia32.h b/arch/x86/include/asm/sys_ia32.h new file mode 100644 index 000000000000..ffb08be2a530 --- /dev/null +++ b/arch/x86/include/asm/sys_ia32.h | |||
| @@ -0,0 +1,101 @@ | |||
| 1 | /* | ||
| 2 | * sys_ia32.h - Linux ia32 syscall interfaces | ||
| 3 | * | ||
| 4 | * Copyright (c) 2008 Jaswinder Singh Rajput | ||
| 5 | * | ||
| 6 | * This file is released under the GPLv2. | ||
| 7 | * See the file COPYING for more details. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #ifndef _ASM_X86_SYS_IA32_H | ||
| 11 | #define _ASM_X86_SYS_IA32_H | ||
| 12 | |||
| 13 | #include <linux/compiler.h> | ||
| 14 | #include <linux/linkage.h> | ||
| 15 | #include <linux/types.h> | ||
| 16 | #include <linux/signal.h> | ||
| 17 | #include <asm/compat.h> | ||
| 18 | #include <asm/ia32.h> | ||
| 19 | |||
| 20 | /* ia32/sys_ia32.c */ | ||
| 21 | asmlinkage long sys32_truncate64(char __user *, unsigned long, unsigned long); | ||
| 22 | asmlinkage long sys32_ftruncate64(unsigned int, unsigned long, unsigned long); | ||
| 23 | |||
| 24 | asmlinkage long sys32_stat64(char __user *, struct stat64 __user *); | ||
| 25 | asmlinkage long sys32_lstat64(char __user *, struct stat64 __user *); | ||
| 26 | asmlinkage long sys32_fstat64(unsigned int, struct stat64 __user *); | ||
| 27 | asmlinkage long sys32_fstatat(unsigned int, char __user *, | ||
| 28 | struct stat64 __user *, int); | ||
| 29 | struct mmap_arg_struct; | ||
| 30 | asmlinkage long sys32_mmap(struct mmap_arg_struct __user *); | ||
| 31 | asmlinkage long sys32_mprotect(unsigned long, size_t, unsigned long); | ||
| 32 | |||
| 33 | asmlinkage long sys32_pipe(int __user *); | ||
| 34 | struct sigaction32; | ||
| 35 | struct old_sigaction32; | ||
| 36 | asmlinkage long sys32_rt_sigaction(int, struct sigaction32 __user *, | ||
| 37 | struct sigaction32 __user *, unsigned int); | ||
| 38 | asmlinkage long sys32_sigaction(int, struct old_sigaction32 __user *, | ||
| 39 | struct old_sigaction32 __user *); | ||
| 40 | asmlinkage long sys32_rt_sigprocmask(int, compat_sigset_t __user *, | ||
| 41 | compat_sigset_t __user *, unsigned int); | ||
| 42 | asmlinkage long sys32_alarm(unsigned int); | ||
| 43 | |||
| 44 | struct sel_arg_struct; | ||
| 45 | asmlinkage long sys32_old_select(struct sel_arg_struct __user *); | ||
| 46 | asmlinkage long sys32_waitpid(compat_pid_t, unsigned int *, int); | ||
| 47 | asmlinkage long sys32_sysfs(int, u32, u32); | ||
| 48 | |||
| 49 | asmlinkage long sys32_sched_rr_get_interval(compat_pid_t, | ||
| 50 | struct compat_timespec __user *); | ||
| 51 | asmlinkage long sys32_rt_sigpending(compat_sigset_t __user *, compat_size_t); | ||
| 52 | asmlinkage long sys32_rt_sigqueueinfo(int, int, compat_siginfo_t __user *); | ||
| 53 | |||
| 54 | #ifdef CONFIG_SYSCTL_SYSCALL | ||
| 55 | struct sysctl_ia32; | ||
| 56 | asmlinkage long sys32_sysctl(struct sysctl_ia32 __user *); | ||
| 57 | #endif | ||
| 58 | |||
| 59 | asmlinkage long sys32_pread(unsigned int, char __user *, u32, u32, u32); | ||
| 60 | asmlinkage long sys32_pwrite(unsigned int, char __user *, u32, u32, u32); | ||
| 61 | |||
| 62 | asmlinkage long sys32_personality(unsigned long); | ||
| 63 | asmlinkage long sys32_sendfile(int, int, compat_off_t __user *, s32); | ||
| 64 | |||
| 65 | asmlinkage long sys32_mmap2(unsigned long, unsigned long, unsigned long, | ||
| 66 | unsigned long, unsigned long, unsigned long); | ||
| 67 | |||
| 68 | struct oldold_utsname; | ||
| 69 | struct old_utsname; | ||
| 70 | asmlinkage long sys32_olduname(struct oldold_utsname __user *); | ||
| 71 | long sys32_uname(struct old_utsname __user *); | ||
| 72 | |||
| 73 | long sys32_ustat(unsigned, struct ustat32 __user *); | ||
| 74 | |||
| 75 | asmlinkage long sys32_execve(char __user *, compat_uptr_t __user *, | ||
| 76 | compat_uptr_t __user *, struct pt_regs *); | ||
| 77 | asmlinkage long sys32_clone(unsigned int, unsigned int, struct pt_regs *); | ||
| 78 | |||
| 79 | long sys32_lseek(unsigned int, int, unsigned int); | ||
| 80 | long sys32_kill(int, int); | ||
| 81 | long sys32_fadvise64_64(int, __u32, __u32, __u32, __u32, int); | ||
| 82 | long sys32_vm86_warning(void); | ||
| 83 | long sys32_lookup_dcookie(u32, u32, char __user *, size_t); | ||
| 84 | |||
| 85 | asmlinkage ssize_t sys32_readahead(int, unsigned, unsigned, size_t); | ||
| 86 | asmlinkage long sys32_sync_file_range(int, unsigned, unsigned, | ||
| 87 | unsigned, unsigned, int); | ||
| 88 | asmlinkage long sys32_fadvise64(int, unsigned, unsigned, size_t, int); | ||
| 89 | asmlinkage long sys32_fallocate(int, int, unsigned, | ||
| 90 | unsigned, unsigned, unsigned); | ||
| 91 | |||
| 92 | /* ia32/ia32_signal.c */ | ||
| 93 | asmlinkage long sys32_sigsuspend(int, int, old_sigset_t); | ||
| 94 | asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *, | ||
| 95 | stack_ia32_t __user *, struct pt_regs *); | ||
| 96 | asmlinkage long sys32_sigreturn(struct pt_regs *); | ||
| 97 | asmlinkage long sys32_rt_sigreturn(struct pt_regs *); | ||
| 98 | |||
| 99 | /* ia32/ipc32.c */ | ||
| 100 | asmlinkage long sys32_ipc(u32, int, int, int, compat_uptr_t, u32); | ||
| 101 | #endif /* _ASM_X86_SYS_IA32_H */ | ||
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 79e31e9dcdda..4e2f2e0aab27 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h | |||
| @@ -61,13 +61,19 @@ static inline int cpu_to_node(int cpu) | |||
| 61 | * | 61 | * |
| 62 | * Side note: this function creates the returned cpumask on the stack | 62 | * Side note: this function creates the returned cpumask on the stack |
| 63 | * so with a high NR_CPUS count, excessive stack space is used. The | 63 | * so with a high NR_CPUS count, excessive stack space is used. The |
| 64 | * node_to_cpumask_ptr function should be used whenever possible. | 64 | * cpumask_of_node function should be used whenever possible. |
| 65 | */ | 65 | */ |
| 66 | static inline cpumask_t node_to_cpumask(int node) | 66 | static inline cpumask_t node_to_cpumask(int node) |
| 67 | { | 67 | { |
| 68 | return node_to_cpumask_map[node]; | 68 | return node_to_cpumask_map[node]; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | /* Returns a bitmask of CPUs on Node 'node'. */ | ||
| 72 | static inline const struct cpumask *cpumask_of_node(int node) | ||
| 73 | { | ||
| 74 | return &node_to_cpumask_map[node]; | ||
| 75 | } | ||
| 76 | |||
| 71 | #else /* CONFIG_X86_64 */ | 77 | #else /* CONFIG_X86_64 */ |
| 72 | 78 | ||
| 73 | /* Mappings between node number and cpus on that node. */ | 79 | /* Mappings between node number and cpus on that node. */ |
| @@ -82,7 +88,7 @@ DECLARE_EARLY_PER_CPU(int, x86_cpu_to_node_map); | |||
| 82 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS | 88 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS |
| 83 | extern int cpu_to_node(int cpu); | 89 | extern int cpu_to_node(int cpu); |
| 84 | extern int early_cpu_to_node(int cpu); | 90 | extern int early_cpu_to_node(int cpu); |
| 85 | extern const cpumask_t *_node_to_cpumask_ptr(int node); | 91 | extern const cpumask_t *cpumask_of_node(int node); |
| 86 | extern cpumask_t node_to_cpumask(int node); | 92 | extern cpumask_t node_to_cpumask(int node); |
| 87 | 93 | ||
| 88 | #else /* !CONFIG_DEBUG_PER_CPU_MAPS */ | 94 | #else /* !CONFIG_DEBUG_PER_CPU_MAPS */ |
| @@ -103,7 +109,7 @@ static inline int early_cpu_to_node(int cpu) | |||
| 103 | } | 109 | } |
| 104 | 110 | ||
| 105 | /* Returns a pointer to the cpumask of CPUs on Node 'node'. */ | 111 | /* Returns a pointer to the cpumask of CPUs on Node 'node'. */ |
| 106 | static inline const cpumask_t *_node_to_cpumask_ptr(int node) | 112 | static inline const cpumask_t *cpumask_of_node(int node) |
| 107 | { | 113 | { |
| 108 | return &node_to_cpumask_map[node]; | 114 | return &node_to_cpumask_map[node]; |
| 109 | } | 115 | } |
| @@ -116,12 +122,15 @@ static inline cpumask_t node_to_cpumask(int node) | |||
| 116 | 122 | ||
| 117 | #endif /* !CONFIG_DEBUG_PER_CPU_MAPS */ | 123 | #endif /* !CONFIG_DEBUG_PER_CPU_MAPS */ |
| 118 | 124 | ||
| 119 | /* Replace default node_to_cpumask_ptr with optimized version */ | 125 | /* |
| 126 | * Replace default node_to_cpumask_ptr with optimized version | ||
| 127 | * Deprecated: use "const struct cpumask *mask = cpumask_of_node(node)" | ||
| 128 | */ | ||
| 120 | #define node_to_cpumask_ptr(v, node) \ | 129 | #define node_to_cpumask_ptr(v, node) \ |
| 121 | const cpumask_t *v = _node_to_cpumask_ptr(node) | 130 | const cpumask_t *v = cpumask_of_node(node) |
| 122 | 131 | ||
| 123 | #define node_to_cpumask_ptr_next(v, node) \ | 132 | #define node_to_cpumask_ptr_next(v, node) \ |
| 124 | v = _node_to_cpumask_ptr(node) | 133 | v = cpumask_of_node(node) |
| 125 | 134 | ||
| 126 | #endif /* CONFIG_X86_64 */ | 135 | #endif /* CONFIG_X86_64 */ |
| 127 | 136 | ||
| @@ -187,7 +196,7 @@ extern int __node_distance(int, int); | |||
| 187 | #define cpu_to_node(cpu) 0 | 196 | #define cpu_to_node(cpu) 0 |
| 188 | #define early_cpu_to_node(cpu) 0 | 197 | #define early_cpu_to_node(cpu) 0 |
| 189 | 198 | ||
| 190 | static inline const cpumask_t *_node_to_cpumask_ptr(int node) | 199 | static inline const cpumask_t *cpumask_of_node(int node) |
| 191 | { | 200 | { |
| 192 | return &cpu_online_map; | 201 | return &cpu_online_map; |
| 193 | } | 202 | } |
| @@ -200,12 +209,15 @@ static inline int node_to_first_cpu(int node) | |||
| 200 | return first_cpu(cpu_online_map); | 209 | return first_cpu(cpu_online_map); |
| 201 | } | 210 | } |
| 202 | 211 | ||
| 203 | /* Replace default node_to_cpumask_ptr with optimized version */ | 212 | /* |
| 213 | * Replace default node_to_cpumask_ptr with optimized version | ||
| 214 | * Deprecated: use "const struct cpumask *mask = cpumask_of_node(node)" | ||
| 215 | */ | ||
| 204 | #define node_to_cpumask_ptr(v, node) \ | 216 | #define node_to_cpumask_ptr(v, node) \ |
| 205 | const cpumask_t *v = _node_to_cpumask_ptr(node) | 217 | const cpumask_t *v = cpumask_of_node(node) |
| 206 | 218 | ||
| 207 | #define node_to_cpumask_ptr_next(v, node) \ | 219 | #define node_to_cpumask_ptr_next(v, node) \ |
| 208 | v = _node_to_cpumask_ptr(node) | 220 | v = cpumask_of_node(node) |
| 209 | #endif | 221 | #endif |
| 210 | 222 | ||
| 211 | #include <asm-generic/topology.h> | 223 | #include <asm-generic/topology.h> |
| @@ -214,12 +226,12 @@ static inline int node_to_first_cpu(int node) | |||
| 214 | /* Returns the number of the first CPU on Node 'node'. */ | 226 | /* Returns the number of the first CPU on Node 'node'. */ |
| 215 | static inline int node_to_first_cpu(int node) | 227 | static inline int node_to_first_cpu(int node) |
| 216 | { | 228 | { |
| 217 | node_to_cpumask_ptr(mask, node); | 229 | return cpumask_first(cpumask_of_node(node)); |
| 218 | return first_cpu(*mask); | ||
| 219 | } | 230 | } |
| 220 | #endif | 231 | #endif |
| 221 | 232 | ||
| 222 | extern cpumask_t cpu_coregroup_map(int cpu); | 233 | extern cpumask_t cpu_coregroup_map(int cpu); |
| 234 | extern const struct cpumask *cpu_coregroup_mask(int cpu); | ||
| 223 | 235 | ||
| 224 | #ifdef ENABLE_TOPO_DEFINES | 236 | #ifdef ENABLE_TOPO_DEFINES |
| 225 | #define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id) | 237 | #define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id) |
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index e2363253bbbf..50423c7b56b2 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h | |||
| @@ -133,61 +133,61 @@ struct bau_msg_payload { | |||
| 133 | * see table 4.2.3.0.1 in broacast_assist spec. | 133 | * see table 4.2.3.0.1 in broacast_assist spec. |
| 134 | */ | 134 | */ |
| 135 | struct bau_msg_header { | 135 | struct bau_msg_header { |
| 136 | int dest_subnodeid:6; /* must be zero */ | 136 | unsigned int dest_subnodeid:6; /* must be zero */ |
| 137 | /* bits 5:0 */ | 137 | /* bits 5:0 */ |
| 138 | int base_dest_nodeid:15; /* nasid>>1 (pnode) of first bit in node_map */ | 138 | unsigned int base_dest_nodeid:15; /* nasid>>1 (pnode) of */ |
| 139 | /* bits 20:6 */ | 139 | /* bits 20:6 */ /* first bit in node_map */ |
| 140 | int command:8; /* message type */ | 140 | unsigned int command:8; /* message type */ |
| 141 | /* bits 28:21 */ | 141 | /* bits 28:21 */ |
| 142 | /* 0x38: SN3net EndPoint Message */ | 142 | /* 0x38: SN3net EndPoint Message */ |
| 143 | int rsvd_1:3; /* must be zero */ | 143 | unsigned int rsvd_1:3; /* must be zero */ |
| 144 | /* bits 31:29 */ | 144 | /* bits 31:29 */ |
| 145 | /* int will align on 32 bits */ | 145 | /* int will align on 32 bits */ |
| 146 | int rsvd_2:9; /* must be zero */ | 146 | unsigned int rsvd_2:9; /* must be zero */ |
| 147 | /* bits 40:32 */ | 147 | /* bits 40:32 */ |
| 148 | /* Suppl_A is 56-41 */ | 148 | /* Suppl_A is 56-41 */ |
| 149 | int payload_2a:8; /* becomes byte 16 of msg */ | 149 | unsigned int payload_2a:8;/* becomes byte 16 of msg */ |
| 150 | /* bits 48:41 */ /* not currently using */ | 150 | /* bits 48:41 */ /* not currently using */ |
| 151 | int payload_2b:8; /* becomes byte 17 of msg */ | 151 | unsigned int payload_2b:8;/* becomes byte 17 of msg */ |
| 152 | /* bits 56:49 */ /* not currently using */ | 152 | /* bits 56:49 */ /* not currently using */ |
| 153 | /* Address field (96:57) is never used as an | 153 | /* Address field (96:57) is never used as an |
| 154 | address (these are address bits 42:3) */ | 154 | address (these are address bits 42:3) */ |
| 155 | int rsvd_3:1; /* must be zero */ | 155 | unsigned int rsvd_3:1; /* must be zero */ |
| 156 | /* bit 57 */ | 156 | /* bit 57 */ |
| 157 | /* address bits 27:4 are payload */ | 157 | /* address bits 27:4 are payload */ |
| 158 | /* these 24 bits become bytes 12-14 of msg */ | 158 | /* these 24 bits become bytes 12-14 of msg */ |
| 159 | int replied_to:1; /* sent as 0 by the source to byte 12 */ | 159 | unsigned int replied_to:1;/* sent as 0 by the source to byte 12 */ |
| 160 | /* bit 58 */ | 160 | /* bit 58 */ |
| 161 | 161 | ||
| 162 | int payload_1a:5; /* not currently used */ | 162 | unsigned int payload_1a:5;/* not currently used */ |
| 163 | /* bits 63:59 */ | 163 | /* bits 63:59 */ |
| 164 | int payload_1b:8; /* not currently used */ | 164 | unsigned int payload_1b:8;/* not currently used */ |
| 165 | /* bits 71:64 */ | 165 | /* bits 71:64 */ |
| 166 | int payload_1c:8; /* not currently used */ | 166 | unsigned int payload_1c:8;/* not currently used */ |
| 167 | /* bits 79:72 */ | 167 | /* bits 79:72 */ |
| 168 | int payload_1d:2; /* not currently used */ | 168 | unsigned int payload_1d:2;/* not currently used */ |
| 169 | /* bits 81:80 */ | 169 | /* bits 81:80 */ |
| 170 | 170 | ||
| 171 | int rsvd_4:7; /* must be zero */ | 171 | unsigned int rsvd_4:7; /* must be zero */ |
| 172 | /* bits 88:82 */ | 172 | /* bits 88:82 */ |
| 173 | int sw_ack_flag:1; /* software acknowledge flag */ | 173 | unsigned int sw_ack_flag:1;/* software acknowledge flag */ |
| 174 | /* bit 89 */ | 174 | /* bit 89 */ |
| 175 | /* INTD trasactions at destination are to | 175 | /* INTD trasactions at destination are to |
| 176 | wait for software acknowledge */ | 176 | wait for software acknowledge */ |
| 177 | int rsvd_5:6; /* must be zero */ | 177 | unsigned int rsvd_5:6; /* must be zero */ |
| 178 | /* bits 95:90 */ | 178 | /* bits 95:90 */ |
| 179 | int rsvd_6:5; /* must be zero */ | 179 | unsigned int rsvd_6:5; /* must be zero */ |
| 180 | /* bits 100:96 */ | 180 | /* bits 100:96 */ |
| 181 | int int_both:1; /* if 1, interrupt both sockets on the blade */ | 181 | unsigned int int_both:1;/* if 1, interrupt both sockets on the blade */ |
| 182 | /* bit 101*/ | 182 | /* bit 101*/ |
| 183 | int fairness:3; /* usually zero */ | 183 | unsigned int fairness:3;/* usually zero */ |
| 184 | /* bits 104:102 */ | 184 | /* bits 104:102 */ |
| 185 | int multilevel:1; /* multi-level multicast format */ | 185 | unsigned int multilevel:1; /* multi-level multicast format */ |
| 186 | /* bit 105 */ | 186 | /* bit 105 */ |
| 187 | /* 0 for TLB: endpoint multi-unicast messages */ | 187 | /* 0 for TLB: endpoint multi-unicast messages */ |
| 188 | int chaining:1; /* next descriptor is part of this activation*/ | 188 | unsigned int chaining:1;/* next descriptor is part of this activation*/ |
| 189 | /* bit 106 */ | 189 | /* bit 106 */ |
| 190 | int rsvd_7:21; /* must be zero */ | 190 | unsigned int rsvd_7:21; /* must be zero */ |
| 191 | /* bits 127:107 */ | 191 | /* bits 127:107 */ |
| 192 | }; | 192 | }; |
| 193 | 193 | ||
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 65d0b72777ea..29dc0c89d4af 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
| @@ -538,9 +538,10 @@ static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu) | |||
| 538 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 538 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
| 539 | union acpi_object *obj; | 539 | union acpi_object *obj; |
| 540 | struct acpi_madt_local_apic *lapic; | 540 | struct acpi_madt_local_apic *lapic; |
| 541 | cpumask_t tmp_map, new_map; | 541 | cpumask_var_t tmp_map, new_map; |
| 542 | u8 physid; | 542 | u8 physid; |
| 543 | int cpu; | 543 | int cpu; |
| 544 | int retval = -ENOMEM; | ||
| 544 | 545 | ||
| 545 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) | 546 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) |
| 546 | return -EINVAL; | 547 | return -EINVAL; |
| @@ -569,23 +570,37 @@ static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu) | |||
| 569 | buffer.length = ACPI_ALLOCATE_BUFFER; | 570 | buffer.length = ACPI_ALLOCATE_BUFFER; |
| 570 | buffer.pointer = NULL; | 571 | buffer.pointer = NULL; |
| 571 | 572 | ||
| 572 | tmp_map = cpu_present_map; | 573 | if (!alloc_cpumask_var(&tmp_map, GFP_KERNEL)) |
| 574 | goto out; | ||
| 575 | |||
| 576 | if (!alloc_cpumask_var(&new_map, GFP_KERNEL)) | ||
| 577 | goto free_tmp_map; | ||
| 578 | |||
| 579 | cpumask_copy(tmp_map, cpu_present_mask); | ||
| 573 | acpi_register_lapic(physid, lapic->lapic_flags & ACPI_MADT_ENABLED); | 580 | acpi_register_lapic(physid, lapic->lapic_flags & ACPI_MADT_ENABLED); |
| 574 | 581 | ||
| 575 | /* | 582 | /* |
| 576 | * If mp_register_lapic successfully generates a new logical cpu | 583 | * If mp_register_lapic successfully generates a new logical cpu |
| 577 | * number, then the following will get us exactly what was mapped | 584 | * number, then the following will get us exactly what was mapped |
| 578 | */ | 585 | */ |
| 579 | cpus_andnot(new_map, cpu_present_map, tmp_map); | 586 | cpumask_andnot(new_map, cpu_present_mask, tmp_map); |
| 580 | if (cpus_empty(new_map)) { | 587 | if (cpumask_empty(new_map)) { |
| 581 | printk ("Unable to map lapic to logical cpu number\n"); | 588 | printk ("Unable to map lapic to logical cpu number\n"); |
| 582 | return -EINVAL; | 589 | retval = -EINVAL; |
| 590 | goto free_new_map; | ||
| 583 | } | 591 | } |
| 584 | 592 | ||
| 585 | cpu = first_cpu(new_map); | 593 | cpu = cpumask_first(new_map); |
| 586 | 594 | ||
| 587 | *pcpu = cpu; | 595 | *pcpu = cpu; |
| 588 | return 0; | 596 | retval = 0; |
| 597 | |||
| 598 | free_new_map: | ||
| 599 | free_cpumask_var(new_map); | ||
| 600 | free_tmp_map: | ||
| 601 | free_cpumask_var(tmp_map); | ||
| 602 | out: | ||
| 603 | return retval; | ||
| 589 | } | 604 | } |
| 590 | 605 | ||
| 591 | /* wrapper to silence section mismatch warning */ | 606 | /* wrapper to silence section mismatch warning */ |
| @@ -598,7 +613,7 @@ EXPORT_SYMBOL(acpi_map_lsapic); | |||
| 598 | int acpi_unmap_lsapic(int cpu) | 613 | int acpi_unmap_lsapic(int cpu) |
| 599 | { | 614 | { |
| 600 | per_cpu(x86_cpu_to_apicid, cpu) = -1; | 615 | per_cpu(x86_cpu_to_apicid, cpu) = -1; |
| 601 | cpu_clear(cpu, cpu_present_map); | 616 | set_cpu_present(cpu, false); |
| 602 | num_processors--; | 617 | num_processors--; |
| 603 | 618 | ||
| 604 | return (0); | 619 | return (0); |
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 2e2da717b350..5113c080f0c4 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
| @@ -20,8 +20,12 @@ | |||
| 20 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
| 21 | #include <linux/gfp.h> | 21 | #include <linux/gfp.h> |
| 22 | #include <linux/bitops.h> | 22 | #include <linux/bitops.h> |
| 23 | #include <linux/debugfs.h> | ||
| 23 | #include <linux/scatterlist.h> | 24 | #include <linux/scatterlist.h> |
| 24 | #include <linux/iommu-helper.h> | 25 | #include <linux/iommu-helper.h> |
| 26 | #ifdef CONFIG_IOMMU_API | ||
| 27 | #include <linux/iommu.h> | ||
| 28 | #endif | ||
| 25 | #include <asm/proto.h> | 29 | #include <asm/proto.h> |
| 26 | #include <asm/iommu.h> | 30 | #include <asm/iommu.h> |
| 27 | #include <asm/gart.h> | 31 | #include <asm/gart.h> |
| @@ -38,6 +42,10 @@ static DEFINE_RWLOCK(amd_iommu_devtable_lock); | |||
| 38 | static LIST_HEAD(iommu_pd_list); | 42 | static LIST_HEAD(iommu_pd_list); |
| 39 | static DEFINE_SPINLOCK(iommu_pd_list_lock); | 43 | static DEFINE_SPINLOCK(iommu_pd_list_lock); |
| 40 | 44 | ||
| 45 | #ifdef CONFIG_IOMMU_API | ||
| 46 | static struct iommu_ops amd_iommu_ops; | ||
| 47 | #endif | ||
| 48 | |||
| 41 | /* | 49 | /* |
| 42 | * general struct to manage commands send to an IOMMU | 50 | * general struct to manage commands send to an IOMMU |
| 43 | */ | 51 | */ |
| @@ -47,6 +55,68 @@ struct iommu_cmd { | |||
| 47 | 55 | ||
| 48 | static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, | 56 | static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, |
| 49 | struct unity_map_entry *e); | 57 | struct unity_map_entry *e); |
| 58 | static struct dma_ops_domain *find_protection_domain(u16 devid); | ||
| 59 | |||
| 60 | |||
| 61 | #ifdef CONFIG_AMD_IOMMU_STATS | ||
| 62 | |||
| 63 | /* | ||
| 64 | * Initialization code for statistics collection | ||
| 65 | */ | ||
| 66 | |||
| 67 | DECLARE_STATS_COUNTER(compl_wait); | ||
| 68 | DECLARE_STATS_COUNTER(cnt_map_single); | ||
| 69 | DECLARE_STATS_COUNTER(cnt_unmap_single); | ||
| 70 | DECLARE_STATS_COUNTER(cnt_map_sg); | ||
| 71 | DECLARE_STATS_COUNTER(cnt_unmap_sg); | ||
| 72 | DECLARE_STATS_COUNTER(cnt_alloc_coherent); | ||
| 73 | DECLARE_STATS_COUNTER(cnt_free_coherent); | ||
| 74 | DECLARE_STATS_COUNTER(cross_page); | ||
| 75 | DECLARE_STATS_COUNTER(domain_flush_single); | ||
| 76 | DECLARE_STATS_COUNTER(domain_flush_all); | ||
| 77 | DECLARE_STATS_COUNTER(alloced_io_mem); | ||
| 78 | DECLARE_STATS_COUNTER(total_map_requests); | ||
| 79 | |||
| 80 | static struct dentry *stats_dir; | ||
| 81 | static struct dentry *de_isolate; | ||
| 82 | static struct dentry *de_fflush; | ||
| 83 | |||
| 84 | static void amd_iommu_stats_add(struct __iommu_counter *cnt) | ||
| 85 | { | ||
| 86 | if (stats_dir == NULL) | ||
| 87 | return; | ||
| 88 | |||
| 89 | cnt->dent = debugfs_create_u64(cnt->name, 0444, stats_dir, | ||
| 90 | &cnt->value); | ||
| 91 | } | ||
| 92 | |||
| 93 | static void amd_iommu_stats_init(void) | ||
| 94 | { | ||
| 95 | stats_dir = debugfs_create_dir("amd-iommu", NULL); | ||
| 96 | if (stats_dir == NULL) | ||
| 97 | return; | ||
| 98 | |||
| 99 | de_isolate = debugfs_create_bool("isolation", 0444, stats_dir, | ||
| 100 | (u32 *)&amd_iommu_isolate); | ||
| 101 | |||
| 102 | de_fflush = debugfs_create_bool("fullflush", 0444, stats_dir, | ||
| 103 | (u32 *)&amd_iommu_unmap_flush); | ||
| 104 | |||
| 105 | amd_iommu_stats_add(&compl_wait); | ||
| 106 | amd_iommu_stats_add(&cnt_map_single); | ||
| 107 | amd_iommu_stats_add(&cnt_unmap_single); | ||
| 108 | amd_iommu_stats_add(&cnt_map_sg); | ||
| 109 | amd_iommu_stats_add(&cnt_unmap_sg); | ||
| 110 | amd_iommu_stats_add(&cnt_alloc_coherent); | ||
| 111 | amd_iommu_stats_add(&cnt_free_coherent); | ||
| 112 | amd_iommu_stats_add(&cross_page); | ||
| 113 | amd_iommu_stats_add(&domain_flush_single); | ||
| 114 | amd_iommu_stats_add(&domain_flush_all); | ||
| 115 | amd_iommu_stats_add(&alloced_io_mem); | ||
| 116 | amd_iommu_stats_add(&total_map_requests); | ||
| 117 | } | ||
| 118 | |||
| 119 | #endif | ||
| 50 | 120 | ||
| 51 | /* returns !0 if the IOMMU is caching non-present entries in its TLB */ | 121 | /* returns !0 if the IOMMU is caching non-present entries in its TLB */ |
| 52 | static int iommu_has_npcache(struct amd_iommu *iommu) | 122 | static int iommu_has_npcache(struct amd_iommu *iommu) |
| @@ -189,13 +259,55 @@ static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd) | |||
| 189 | spin_lock_irqsave(&iommu->lock, flags); | 259 | spin_lock_irqsave(&iommu->lock, flags); |
| 190 | ret = __iommu_queue_command(iommu, cmd); | 260 | ret = __iommu_queue_command(iommu, cmd); |
| 191 | if (!ret) | 261 | if (!ret) |
| 192 | iommu->need_sync = 1; | 262 | iommu->need_sync = true; |
| 193 | spin_unlock_irqrestore(&iommu->lock, flags); | 263 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 194 | 264 | ||
| 195 | return ret; | 265 | return ret; |
| 196 | } | 266 | } |
| 197 | 267 | ||
| 198 | /* | 268 | /* |
| 269 | * This function waits until an IOMMU has completed a completion | ||
| 270 | * wait command | ||
| 271 | */ | ||
| 272 | static void __iommu_wait_for_completion(struct amd_iommu *iommu) | ||
| 273 | { | ||
| 274 | int ready = 0; | ||
| 275 | unsigned status = 0; | ||
| 276 | unsigned long i = 0; | ||
| 277 | |||
| 278 | INC_STATS_COUNTER(compl_wait); | ||
| 279 | |||
| 280 | while (!ready && (i < EXIT_LOOP_COUNT)) { | ||
| 281 | ++i; | ||
| 282 | /* wait for the bit to become one */ | ||
| 283 | status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET); | ||
| 284 | ready = status & MMIO_STATUS_COM_WAIT_INT_MASK; | ||
| 285 | } | ||
| 286 | |||
| 287 | /* set bit back to zero */ | ||
| 288 | status &= ~MMIO_STATUS_COM_WAIT_INT_MASK; | ||
| 289 | writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET); | ||
| 290 | |||
| 291 | if (unlikely(i == EXIT_LOOP_COUNT)) | ||
| 292 | panic("AMD IOMMU: Completion wait loop failed\n"); | ||
| 293 | } | ||
| 294 | |||
| 295 | /* | ||
| 296 | * This function queues a completion wait command into the command | ||
| 297 | * buffer of an IOMMU | ||
| 298 | */ | ||
| 299 | static int __iommu_completion_wait(struct amd_iommu *iommu) | ||
| 300 | { | ||
| 301 | struct iommu_cmd cmd; | ||
| 302 | |||
| 303 | memset(&cmd, 0, sizeof(cmd)); | ||
| 304 | cmd.data[0] = CMD_COMPL_WAIT_INT_MASK; | ||
| 305 | CMD_SET_TYPE(&cmd, CMD_COMPL_WAIT); | ||
| 306 | |||
| 307 | return __iommu_queue_command(iommu, &cmd); | ||
| 308 | } | ||
| 309 | |||
| 310 | /* | ||
| 199 | * This function is called whenever we need to ensure that the IOMMU has | 311 | * This function is called whenever we need to ensure that the IOMMU has |
| 200 | * completed execution of all commands we sent. It sends a | 312 | * completed execution of all commands we sent. It sends a |
| 201 | * COMPLETION_WAIT command and waits for it to finish. The IOMMU informs | 313 | * COMPLETION_WAIT command and waits for it to finish. The IOMMU informs |
| @@ -204,40 +316,22 @@ static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd) | |||
| 204 | */ | 316 | */ |
| 205 | static int iommu_completion_wait(struct amd_iommu *iommu) | 317 | static int iommu_completion_wait(struct amd_iommu *iommu) |
| 206 | { | 318 | { |
| 207 | int ret = 0, ready = 0; | 319 | int ret = 0; |
| 208 | unsigned status = 0; | 320 | unsigned long flags; |
| 209 | struct iommu_cmd cmd; | ||
| 210 | unsigned long flags, i = 0; | ||
| 211 | |||
| 212 | memset(&cmd, 0, sizeof(cmd)); | ||
| 213 | cmd.data[0] = CMD_COMPL_WAIT_INT_MASK; | ||
| 214 | CMD_SET_TYPE(&cmd, CMD_COMPL_WAIT); | ||
| 215 | 321 | ||
| 216 | spin_lock_irqsave(&iommu->lock, flags); | 322 | spin_lock_irqsave(&iommu->lock, flags); |
| 217 | 323 | ||
| 218 | if (!iommu->need_sync) | 324 | if (!iommu->need_sync) |
| 219 | goto out; | 325 | goto out; |
| 220 | 326 | ||
| 221 | iommu->need_sync = 0; | 327 | ret = __iommu_completion_wait(iommu); |
| 222 | 328 | ||
| 223 | ret = __iommu_queue_command(iommu, &cmd); | 329 | iommu->need_sync = false; |
| 224 | 330 | ||
| 225 | if (ret) | 331 | if (ret) |
| 226 | goto out; | 332 | goto out; |
| 227 | 333 | ||
| 228 | while (!ready && (i < EXIT_LOOP_COUNT)) { | 334 | __iommu_wait_for_completion(iommu); |
| 229 | ++i; | ||
| 230 | /* wait for the bit to become one */ | ||
| 231 | status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET); | ||
| 232 | ready = status & MMIO_STATUS_COM_WAIT_INT_MASK; | ||
| 233 | } | ||
| 234 | |||
| 235 | /* set bit back to zero */ | ||
| 236 | status &= ~MMIO_STATUS_COM_WAIT_INT_MASK; | ||
| 237 | writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET); | ||
| 238 | |||
| 239 | if (unlikely(i == EXIT_LOOP_COUNT)) | ||
| 240 | panic("AMD IOMMU: Completion wait loop failed\n"); | ||
| 241 | 335 | ||
| 242 | out: | 336 | out: |
| 243 | spin_unlock_irqrestore(&iommu->lock, flags); | 337 | spin_unlock_irqrestore(&iommu->lock, flags); |
| @@ -264,6 +358,21 @@ static int iommu_queue_inv_dev_entry(struct amd_iommu *iommu, u16 devid) | |||
| 264 | return ret; | 358 | return ret; |
| 265 | } | 359 | } |
| 266 | 360 | ||
| 361 | static void __iommu_build_inv_iommu_pages(struct iommu_cmd *cmd, u64 address, | ||
| 362 | u16 domid, int pde, int s) | ||
| 363 | { | ||
| 364 | memset(cmd, 0, sizeof(*cmd)); | ||
| 365 | address &= PAGE_MASK; | ||
| 366 | CMD_SET_TYPE(cmd, CMD_INV_IOMMU_PAGES); | ||
| 367 | cmd->data[1] |= domid; | ||
| 368 | cmd->data[2] = lower_32_bits(address); | ||
| 369 | cmd->data[3] = upper_32_bits(address); | ||
| 370 | if (s) /* size bit - we flush more than one 4kb page */ | ||
| 371 | cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK; | ||
| 372 | if (pde) /* PDE bit - we wan't flush everything not only the PTEs */ | ||
| 373 | cmd->data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK; | ||
| 374 | } | ||
| 375 | |||
| 267 | /* | 376 | /* |
| 268 | * Generic command send function for invalidaing TLB entries | 377 | * Generic command send function for invalidaing TLB entries |
| 269 | */ | 378 | */ |
| @@ -273,16 +382,7 @@ static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu, | |||
| 273 | struct iommu_cmd cmd; | 382 | struct iommu_cmd cmd; |
| 274 | int ret; | 383 | int ret; |
| 275 | 384 | ||
| 276 | memset(&cmd, 0, sizeof(cmd)); | 385 | __iommu_build_inv_iommu_pages(&cmd, address, domid, pde, s); |
| 277 | address &= PAGE_MASK; | ||
| 278 | CMD_SET_TYPE(&cmd, CMD_INV_IOMMU_PAGES); | ||
| 279 | cmd.data[1] |= domid; | ||
| 280 | cmd.data[2] = lower_32_bits(address); | ||
| 281 | cmd.data[3] = upper_32_bits(address); | ||
| 282 | if (s) /* size bit - we flush more than one 4kb page */ | ||
| 283 | cmd.data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK; | ||
| 284 | if (pde) /* PDE bit - we wan't flush everything not only the PTEs */ | ||
| 285 | cmd.data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK; | ||
| 286 | 386 | ||
| 287 | ret = iommu_queue_command(iommu, &cmd); | 387 | ret = iommu_queue_command(iommu, &cmd); |
| 288 | 388 | ||
| @@ -321,9 +421,35 @@ static void iommu_flush_tlb(struct amd_iommu *iommu, u16 domid) | |||
| 321 | { | 421 | { |
| 322 | u64 address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS; | 422 | u64 address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS; |
| 323 | 423 | ||
| 424 | INC_STATS_COUNTER(domain_flush_single); | ||
| 425 | |||
| 324 | iommu_queue_inv_iommu_pages(iommu, address, domid, 0, 1); | 426 | iommu_queue_inv_iommu_pages(iommu, address, domid, 0, 1); |
| 325 | } | 427 | } |
| 326 | 428 | ||
| 429 | /* | ||
| 430 | * This function is used to flush the IO/TLB for a given protection domain | ||
| 431 | * on every IOMMU in the system | ||
| 432 | */ | ||
| 433 | static void iommu_flush_domain(u16 domid) | ||
| 434 | { | ||
| 435 | unsigned long flags; | ||
| 436 | struct amd_iommu *iommu; | ||
| 437 | struct iommu_cmd cmd; | ||
| 438 | |||
| 439 | INC_STATS_COUNTER(domain_flush_all); | ||
| 440 | |||
| 441 | __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, | ||
| 442 | domid, 1, 1); | ||
| 443 | |||
| 444 | list_for_each_entry(iommu, &amd_iommu_list, list) { | ||
| 445 | spin_lock_irqsave(&iommu->lock, flags); | ||
| 446 | __iommu_queue_command(iommu, &cmd); | ||
| 447 | __iommu_completion_wait(iommu); | ||
| 448 | __iommu_wait_for_completion(iommu); | ||
| 449 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
| 450 | } | ||
| 451 | } | ||
| 452 | |||
| 327 | /**************************************************************************** | 453 | /**************************************************************************** |
| 328 | * | 454 | * |
| 329 | * The functions below are used the create the page table mappings for | 455 | * The functions below are used the create the page table mappings for |
| @@ -338,10 +464,10 @@ static void iommu_flush_tlb(struct amd_iommu *iommu, u16 domid) | |||
| 338 | * supporting all features of AMD IOMMU page tables like level skipping | 464 | * supporting all features of AMD IOMMU page tables like level skipping |
| 339 | * and full 64 bit address spaces. | 465 | * and full 64 bit address spaces. |
| 340 | */ | 466 | */ |
| 341 | static int iommu_map(struct protection_domain *dom, | 467 | static int iommu_map_page(struct protection_domain *dom, |
| 342 | unsigned long bus_addr, | 468 | unsigned long bus_addr, |
| 343 | unsigned long phys_addr, | 469 | unsigned long phys_addr, |
| 344 | int prot) | 470 | int prot) |
| 345 | { | 471 | { |
| 346 | u64 __pte, *pte, *page; | 472 | u64 __pte, *pte, *page; |
| 347 | 473 | ||
| @@ -388,6 +514,28 @@ static int iommu_map(struct protection_domain *dom, | |||
| 388 | return 0; | 514 | return 0; |
| 389 | } | 515 | } |
| 390 | 516 | ||
| 517 | static void iommu_unmap_page(struct protection_domain *dom, | ||
| 518 | unsigned long bus_addr) | ||
| 519 | { | ||
| 520 | u64 *pte; | ||
| 521 | |||
| 522 | pte = &dom->pt_root[IOMMU_PTE_L2_INDEX(bus_addr)]; | ||
| 523 | |||
| 524 | if (!IOMMU_PTE_PRESENT(*pte)) | ||
| 525 | return; | ||
| 526 | |||
| 527 | pte = IOMMU_PTE_PAGE(*pte); | ||
| 528 | pte = &pte[IOMMU_PTE_L1_INDEX(bus_addr)]; | ||
| 529 | |||
| 530 | if (!IOMMU_PTE_PRESENT(*pte)) | ||
| 531 | return; | ||
| 532 | |||
| 533 | pte = IOMMU_PTE_PAGE(*pte); | ||
| 534 | pte = &pte[IOMMU_PTE_L1_INDEX(bus_addr)]; | ||
| 535 | |||
| 536 | *pte = 0; | ||
| 537 | } | ||
| 538 | |||
| 391 | /* | 539 | /* |
| 392 | * This function checks if a specific unity mapping entry is needed for | 540 | * This function checks if a specific unity mapping entry is needed for |
| 393 | * this specific IOMMU. | 541 | * this specific IOMMU. |
| @@ -440,7 +588,7 @@ static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, | |||
| 440 | 588 | ||
| 441 | for (addr = e->address_start; addr < e->address_end; | 589 | for (addr = e->address_start; addr < e->address_end; |
| 442 | addr += PAGE_SIZE) { | 590 | addr += PAGE_SIZE) { |
| 443 | ret = iommu_map(&dma_dom->domain, addr, addr, e->prot); | 591 | ret = iommu_map_page(&dma_dom->domain, addr, addr, e->prot); |
| 444 | if (ret) | 592 | if (ret) |
| 445 | return ret; | 593 | return ret; |
| 446 | /* | 594 | /* |
| @@ -571,6 +719,16 @@ static u16 domain_id_alloc(void) | |||
| 571 | return id; | 719 | return id; |
| 572 | } | 720 | } |
| 573 | 721 | ||
| 722 | static void domain_id_free(int id) | ||
| 723 | { | ||
| 724 | unsigned long flags; | ||
| 725 | |||
| 726 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); | ||
| 727 | if (id > 0 && id < MAX_DOMAIN_ID) | ||
| 728 | __clear_bit(id, amd_iommu_pd_alloc_bitmap); | ||
| 729 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | ||
| 730 | } | ||
| 731 | |||
| 574 | /* | 732 | /* |
| 575 | * Used to reserve address ranges in the aperture (e.g. for exclusion | 733 | * Used to reserve address ranges in the aperture (e.g. for exclusion |
| 576 | * ranges. | 734 | * ranges. |
| @@ -587,12 +745,12 @@ static void dma_ops_reserve_addresses(struct dma_ops_domain *dom, | |||
| 587 | iommu_area_reserve(dom->bitmap, start_page, pages); | 745 | iommu_area_reserve(dom->bitmap, start_page, pages); |
| 588 | } | 746 | } |
| 589 | 747 | ||
| 590 | static void dma_ops_free_pagetable(struct dma_ops_domain *dma_dom) | 748 | static void free_pagetable(struct protection_domain *domain) |
| 591 | { | 749 | { |
| 592 | int i, j; | 750 | int i, j; |
| 593 | u64 *p1, *p2, *p3; | 751 | u64 *p1, *p2, *p3; |
| 594 | 752 | ||
| 595 | p1 = dma_dom->domain.pt_root; | 753 | p1 = domain->pt_root; |
| 596 | 754 | ||
| 597 | if (!p1) | 755 | if (!p1) |
| 598 | return; | 756 | return; |
| @@ -613,6 +771,8 @@ static void dma_ops_free_pagetable(struct dma_ops_domain *dma_dom) | |||
| 613 | } | 771 | } |
| 614 | 772 | ||
| 615 | free_page((unsigned long)p1); | 773 | free_page((unsigned long)p1); |
| 774 | |||
| 775 | domain->pt_root = NULL; | ||
| 616 | } | 776 | } |
| 617 | 777 | ||
| 618 | /* | 778 | /* |
| @@ -624,7 +784,7 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom) | |||
| 624 | if (!dom) | 784 | if (!dom) |
| 625 | return; | 785 | return; |
| 626 | 786 | ||
| 627 | dma_ops_free_pagetable(dom); | 787 | free_pagetable(&dom->domain); |
| 628 | 788 | ||
| 629 | kfree(dom->pte_pages); | 789 | kfree(dom->pte_pages); |
| 630 | 790 | ||
| @@ -663,6 +823,7 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu, | |||
| 663 | goto free_dma_dom; | 823 | goto free_dma_dom; |
| 664 | dma_dom->domain.mode = PAGE_MODE_3_LEVEL; | 824 | dma_dom->domain.mode = PAGE_MODE_3_LEVEL; |
| 665 | dma_dom->domain.pt_root = (void *)get_zeroed_page(GFP_KERNEL); | 825 | dma_dom->domain.pt_root = (void *)get_zeroed_page(GFP_KERNEL); |
| 826 | dma_dom->domain.flags = PD_DMA_OPS_MASK; | ||
| 666 | dma_dom->domain.priv = dma_dom; | 827 | dma_dom->domain.priv = dma_dom; |
| 667 | if (!dma_dom->domain.pt_root) | 828 | if (!dma_dom->domain.pt_root) |
| 668 | goto free_dma_dom; | 829 | goto free_dma_dom; |
| @@ -725,6 +886,15 @@ free_dma_dom: | |||
| 725 | } | 886 | } |
| 726 | 887 | ||
| 727 | /* | 888 | /* |
| 889 | * little helper function to check whether a given protection domain is a | ||
| 890 | * dma_ops domain | ||
| 891 | */ | ||
| 892 | static bool dma_ops_domain(struct protection_domain *domain) | ||
| 893 | { | ||
| 894 | return domain->flags & PD_DMA_OPS_MASK; | ||
| 895 | } | ||
| 896 | |||
| 897 | /* | ||
| 728 | * Find out the protection domain structure for a given PCI device. This | 898 | * Find out the protection domain structure for a given PCI device. This |
| 729 | * will give us the pointer to the page table root for example. | 899 | * will give us the pointer to the page table root for example. |
| 730 | */ | 900 | */ |
| @@ -744,14 +914,15 @@ static struct protection_domain *domain_for_device(u16 devid) | |||
| 744 | * If a device is not yet associated with a domain, this function does | 914 | * If a device is not yet associated with a domain, this function does |
| 745 | * assigns it visible for the hardware | 915 | * assigns it visible for the hardware |
| 746 | */ | 916 | */ |
| 747 | static void set_device_domain(struct amd_iommu *iommu, | 917 | static void attach_device(struct amd_iommu *iommu, |
| 748 | struct protection_domain *domain, | 918 | struct protection_domain *domain, |
| 749 | u16 devid) | 919 | u16 devid) |
| 750 | { | 920 | { |
| 751 | unsigned long flags; | 921 | unsigned long flags; |
| 752 | |||
| 753 | u64 pte_root = virt_to_phys(domain->pt_root); | 922 | u64 pte_root = virt_to_phys(domain->pt_root); |
| 754 | 923 | ||
| 924 | domain->dev_cnt += 1; | ||
| 925 | |||
| 755 | pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK) | 926 | pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK) |
| 756 | << DEV_ENTRY_MODE_SHIFT; | 927 | << DEV_ENTRY_MODE_SHIFT; |
| 757 | pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV; | 928 | pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV; |
| @@ -767,6 +938,116 @@ static void set_device_domain(struct amd_iommu *iommu, | |||
| 767 | iommu_queue_inv_dev_entry(iommu, devid); | 938 | iommu_queue_inv_dev_entry(iommu, devid); |
| 768 | } | 939 | } |
| 769 | 940 | ||
| 941 | /* | ||
| 942 | * Removes a device from a protection domain (unlocked) | ||
| 943 | */ | ||
| 944 | static void __detach_device(struct protection_domain *domain, u16 devid) | ||
| 945 | { | ||
| 946 | |||
| 947 | /* lock domain */ | ||
| 948 | spin_lock(&domain->lock); | ||
| 949 | |||
| 950 | /* remove domain from the lookup table */ | ||
| 951 | amd_iommu_pd_table[devid] = NULL; | ||
| 952 | |||
| 953 | /* remove entry from the device table seen by the hardware */ | ||
| 954 | amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV; | ||
| 955 | amd_iommu_dev_table[devid].data[1] = 0; | ||
| 956 | amd_iommu_dev_table[devid].data[2] = 0; | ||
| 957 | |||
| 958 | /* decrease reference counter */ | ||
| 959 | domain->dev_cnt -= 1; | ||
| 960 | |||
| 961 | /* ready */ | ||
| 962 | spin_unlock(&domain->lock); | ||
| 963 | } | ||
| 964 | |||
| 965 | /* | ||
| 966 | * Removes a device from a protection domain (with devtable_lock held) | ||
| 967 | */ | ||
| 968 | static void detach_device(struct protection_domain *domain, u16 devid) | ||
| 969 | { | ||
| 970 | unsigned long flags; | ||
| 971 | |||
| 972 | /* lock device table */ | ||
| 973 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); | ||
| 974 | __detach_device(domain, devid); | ||
| 975 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | ||
| 976 | } | ||
| 977 | |||
| 978 | static int device_change_notifier(struct notifier_block *nb, | ||
| 979 | unsigned long action, void *data) | ||
| 980 | { | ||
| 981 | struct device *dev = data; | ||
| 982 | struct pci_dev *pdev = to_pci_dev(dev); | ||
| 983 | u16 devid = calc_devid(pdev->bus->number, pdev->devfn); | ||
| 984 | struct protection_domain *domain; | ||
| 985 | struct dma_ops_domain *dma_domain; | ||
| 986 | struct amd_iommu *iommu; | ||
| 987 | int order = amd_iommu_aperture_order; | ||
| 988 | unsigned long flags; | ||
| 989 | |||
| 990 | if (devid > amd_iommu_last_bdf) | ||
| 991 | goto out; | ||
| 992 | |||
| 993 | devid = amd_iommu_alias_table[devid]; | ||
| 994 | |||
| 995 | iommu = amd_iommu_rlookup_table[devid]; | ||
| 996 | if (iommu == NULL) | ||
| 997 | goto out; | ||
| 998 | |||
| 999 | domain = domain_for_device(devid); | ||
| 1000 | |||
| 1001 | if (domain && !dma_ops_domain(domain)) | ||
| 1002 | WARN_ONCE(1, "AMD IOMMU WARNING: device %s already bound " | ||
| 1003 | "to a non-dma-ops domain\n", dev_name(dev)); | ||
| 1004 | |||
| 1005 | switch (action) { | ||
| 1006 | case BUS_NOTIFY_BOUND_DRIVER: | ||
| 1007 | if (domain) | ||
| 1008 | goto out; | ||
| 1009 | dma_domain = find_protection_domain(devid); | ||
| 1010 | if (!dma_domain) | ||
| 1011 | dma_domain = iommu->default_dom; | ||
| 1012 | attach_device(iommu, &dma_domain->domain, devid); | ||
| 1013 | printk(KERN_INFO "AMD IOMMU: Using protection domain %d for " | ||
| 1014 | "device %s\n", dma_domain->domain.id, dev_name(dev)); | ||
| 1015 | break; | ||
| 1016 | case BUS_NOTIFY_UNBIND_DRIVER: | ||
| 1017 | if (!domain) | ||
| 1018 | goto out; | ||
| 1019 | detach_device(domain, devid); | ||
| 1020 | break; | ||
| 1021 | case BUS_NOTIFY_ADD_DEVICE: | ||
| 1022 | /* allocate a protection domain if a device is added */ | ||
| 1023 | dma_domain = find_protection_domain(devid); | ||
| 1024 | if (dma_domain) | ||
| 1025 | goto out; | ||
| 1026 | dma_domain = dma_ops_domain_alloc(iommu, order); | ||
| 1027 | if (!dma_domain) | ||
| 1028 | goto out; | ||
| 1029 | dma_domain->target_dev = devid; | ||
| 1030 | |||
| 1031 | spin_lock_irqsave(&iommu_pd_list_lock, flags); | ||
| 1032 | list_add_tail(&dma_domain->list, &iommu_pd_list); | ||
| 1033 | spin_unlock_irqrestore(&iommu_pd_list_lock, flags); | ||
| 1034 | |||
| 1035 | break; | ||
| 1036 | default: | ||
| 1037 | goto out; | ||
| 1038 | } | ||
| 1039 | |||
| 1040 | iommu_queue_inv_dev_entry(iommu, devid); | ||
| 1041 | iommu_completion_wait(iommu); | ||
| 1042 | |||
| 1043 | out: | ||
| 1044 | return 0; | ||
| 1045 | } | ||
| 1046 | |||
| 1047 | struct notifier_block device_nb = { | ||
| 1048 | .notifier_call = device_change_notifier, | ||
| 1049 | }; | ||
| 1050 | |||
| 770 | /***************************************************************************** | 1051 | /***************************************************************************** |
| 771 | * | 1052 | * |
| 772 | * The next functions belong to the dma_ops mapping/unmapping code. | 1053 | * The next functions belong to the dma_ops mapping/unmapping code. |
| @@ -802,7 +1083,6 @@ static struct dma_ops_domain *find_protection_domain(u16 devid) | |||
| 802 | list_for_each_entry(entry, &iommu_pd_list, list) { | 1083 | list_for_each_entry(entry, &iommu_pd_list, list) { |
| 803 | if (entry->target_dev == devid) { | 1084 | if (entry->target_dev == devid) { |
| 804 | ret = entry; | 1085 | ret = entry; |
| 805 | list_del(&ret->list); | ||
| 806 | break; | 1086 | break; |
| 807 | } | 1087 | } |
| 808 | } | 1088 | } |
| @@ -853,14 +1133,13 @@ static int get_device_resources(struct device *dev, | |||
| 853 | if (!dma_dom) | 1133 | if (!dma_dom) |
| 854 | dma_dom = (*iommu)->default_dom; | 1134 | dma_dom = (*iommu)->default_dom; |
| 855 | *domain = &dma_dom->domain; | 1135 | *domain = &dma_dom->domain; |
| 856 | set_device_domain(*iommu, *domain, *bdf); | 1136 | attach_device(*iommu, *domain, *bdf); |
| 857 | printk(KERN_INFO "AMD IOMMU: Using protection domain %d for " | 1137 | printk(KERN_INFO "AMD IOMMU: Using protection domain %d for " |
| 858 | "device ", (*domain)->id); | 1138 | "device %s\n", (*domain)->id, dev_name(dev)); |
| 859 | print_devid(_bdf, 1); | ||
| 860 | } | 1139 | } |
| 861 | 1140 | ||
| 862 | if (domain_for_device(_bdf) == NULL) | 1141 | if (domain_for_device(_bdf) == NULL) |
| 863 | set_device_domain(*iommu, *domain, _bdf); | 1142 | attach_device(*iommu, *domain, _bdf); |
| 864 | 1143 | ||
| 865 | return 1; | 1144 | return 1; |
| 866 | } | 1145 | } |
| @@ -946,6 +1225,11 @@ static dma_addr_t __map_single(struct device *dev, | |||
| 946 | pages = iommu_num_pages(paddr, size, PAGE_SIZE); | 1225 | pages = iommu_num_pages(paddr, size, PAGE_SIZE); |
| 947 | paddr &= PAGE_MASK; | 1226 | paddr &= PAGE_MASK; |
| 948 | 1227 | ||
| 1228 | INC_STATS_COUNTER(total_map_requests); | ||
| 1229 | |||
| 1230 | if (pages > 1) | ||
| 1231 | INC_STATS_COUNTER(cross_page); | ||
| 1232 | |||
| 949 | if (align) | 1233 | if (align) |
| 950 | align_mask = (1UL << get_order(size)) - 1; | 1234 | align_mask = (1UL << get_order(size)) - 1; |
| 951 | 1235 | ||
| @@ -962,6 +1246,8 @@ static dma_addr_t __map_single(struct device *dev, | |||
| 962 | } | 1246 | } |
| 963 | address += offset; | 1247 | address += offset; |
| 964 | 1248 | ||
| 1249 | ADD_STATS_COUNTER(alloced_io_mem, size); | ||
| 1250 | |||
| 965 | if (unlikely(dma_dom->need_flush && !amd_iommu_unmap_flush)) { | 1251 | if (unlikely(dma_dom->need_flush && !amd_iommu_unmap_flush)) { |
| 966 | iommu_flush_tlb(iommu, dma_dom->domain.id); | 1252 | iommu_flush_tlb(iommu, dma_dom->domain.id); |
| 967 | dma_dom->need_flush = false; | 1253 | dma_dom->need_flush = false; |
| @@ -998,6 +1284,8 @@ static void __unmap_single(struct amd_iommu *iommu, | |||
| 998 | start += PAGE_SIZE; | 1284 | start += PAGE_SIZE; |
| 999 | } | 1285 | } |
| 1000 | 1286 | ||
| 1287 | SUB_STATS_COUNTER(alloced_io_mem, size); | ||
| 1288 | |||
| 1001 | dma_ops_free_addresses(dma_dom, dma_addr, pages); | 1289 | dma_ops_free_addresses(dma_dom, dma_addr, pages); |
| 1002 | 1290 | ||
| 1003 | if (amd_iommu_unmap_flush || dma_dom->need_flush) { | 1291 | if (amd_iommu_unmap_flush || dma_dom->need_flush) { |
| @@ -1019,6 +1307,8 @@ static dma_addr_t map_single(struct device *dev, phys_addr_t paddr, | |||
| 1019 | dma_addr_t addr; | 1307 | dma_addr_t addr; |
| 1020 | u64 dma_mask; | 1308 | u64 dma_mask; |
| 1021 | 1309 | ||
| 1310 | INC_STATS_COUNTER(cnt_map_single); | ||
| 1311 | |||
| 1022 | if (!check_device(dev)) | 1312 | if (!check_device(dev)) |
| 1023 | return bad_dma_address; | 1313 | return bad_dma_address; |
| 1024 | 1314 | ||
| @@ -1030,6 +1320,9 @@ static dma_addr_t map_single(struct device *dev, phys_addr_t paddr, | |||
| 1030 | /* device not handled by any AMD IOMMU */ | 1320 | /* device not handled by any AMD IOMMU */ |
| 1031 | return (dma_addr_t)paddr; | 1321 | return (dma_addr_t)paddr; |
| 1032 | 1322 | ||
| 1323 | if (!dma_ops_domain(domain)) | ||
| 1324 | return bad_dma_address; | ||
| 1325 | |||
| 1033 | spin_lock_irqsave(&domain->lock, flags); | 1326 | spin_lock_irqsave(&domain->lock, flags); |
| 1034 | addr = __map_single(dev, iommu, domain->priv, paddr, size, dir, false, | 1327 | addr = __map_single(dev, iommu, domain->priv, paddr, size, dir, false, |
| 1035 | dma_mask); | 1328 | dma_mask); |
| @@ -1055,11 +1348,16 @@ static void unmap_single(struct device *dev, dma_addr_t dma_addr, | |||
| 1055 | struct protection_domain *domain; | 1348 | struct protection_domain *domain; |
| 1056 | u16 devid; | 1349 | u16 devid; |
| 1057 | 1350 | ||
| 1351 | INC_STATS_COUNTER(cnt_unmap_single); | ||
| 1352 | |||
| 1058 | if (!check_device(dev) || | 1353 | if (!check_device(dev) || |
| 1059 | !get_device_resources(dev, &iommu, &domain, &devid)) | 1354 | !get_device_resources(dev, &iommu, &domain, &devid)) |
| 1060 | /* device not handled by any AMD IOMMU */ | 1355 | /* device not handled by any AMD IOMMU */ |
| 1061 | return; | 1356 | return; |
| 1062 | 1357 | ||
| 1358 | if (!dma_ops_domain(domain)) | ||
| 1359 | return; | ||
| 1360 | |||
| 1063 | spin_lock_irqsave(&domain->lock, flags); | 1361 | spin_lock_irqsave(&domain->lock, flags); |
| 1064 | 1362 | ||
| 1065 | __unmap_single(iommu, domain->priv, dma_addr, size, dir); | 1363 | __unmap_single(iommu, domain->priv, dma_addr, size, dir); |
| @@ -1104,6 +1402,8 @@ static int map_sg(struct device *dev, struct scatterlist *sglist, | |||
| 1104 | int mapped_elems = 0; | 1402 | int mapped_elems = 0; |
| 1105 | u64 dma_mask; | 1403 | u64 dma_mask; |
| 1106 | 1404 | ||
| 1405 | INC_STATS_COUNTER(cnt_map_sg); | ||
| 1406 | |||
| 1107 | if (!check_device(dev)) | 1407 | if (!check_device(dev)) |
| 1108 | return 0; | 1408 | return 0; |
| 1109 | 1409 | ||
| @@ -1114,6 +1414,9 @@ static int map_sg(struct device *dev, struct scatterlist *sglist, | |||
| 1114 | if (!iommu || !domain) | 1414 | if (!iommu || !domain) |
| 1115 | return map_sg_no_iommu(dev, sglist, nelems, dir); | 1415 | return map_sg_no_iommu(dev, sglist, nelems, dir); |
| 1116 | 1416 | ||
| 1417 | if (!dma_ops_domain(domain)) | ||
| 1418 | return 0; | ||
| 1419 | |||
| 1117 | spin_lock_irqsave(&domain->lock, flags); | 1420 | spin_lock_irqsave(&domain->lock, flags); |
| 1118 | 1421 | ||
| 1119 | for_each_sg(sglist, s, nelems, i) { | 1422 | for_each_sg(sglist, s, nelems, i) { |
| @@ -1163,10 +1466,15 @@ static void unmap_sg(struct device *dev, struct scatterlist *sglist, | |||
| 1163 | u16 devid; | 1466 | u16 devid; |
| 1164 | int i; | 1467 | int i; |
| 1165 | 1468 | ||
| 1469 | INC_STATS_COUNTER(cnt_unmap_sg); | ||
| 1470 | |||
| 1166 | if (!check_device(dev) || | 1471 | if (!check_device(dev) || |
| 1167 | !get_device_resources(dev, &iommu, &domain, &devid)) | 1472 | !get_device_resources(dev, &iommu, &domain, &devid)) |
| 1168 | return; | 1473 | return; |
| 1169 | 1474 | ||
| 1475 | if (!dma_ops_domain(domain)) | ||
| 1476 | return; | ||
| 1477 | |||
| 1170 | spin_lock_irqsave(&domain->lock, flags); | 1478 | spin_lock_irqsave(&domain->lock, flags); |
| 1171 | 1479 | ||
| 1172 | for_each_sg(sglist, s, nelems, i) { | 1480 | for_each_sg(sglist, s, nelems, i) { |
| @@ -1194,6 +1502,8 @@ static void *alloc_coherent(struct device *dev, size_t size, | |||
| 1194 | phys_addr_t paddr; | 1502 | phys_addr_t paddr; |
| 1195 | u64 dma_mask = dev->coherent_dma_mask; | 1503 | u64 dma_mask = dev->coherent_dma_mask; |
| 1196 | 1504 | ||
| 1505 | INC_STATS_COUNTER(cnt_alloc_coherent); | ||
| 1506 | |||
| 1197 | if (!check_device(dev)) | 1507 | if (!check_device(dev)) |
| 1198 | return NULL; | 1508 | return NULL; |
| 1199 | 1509 | ||
| @@ -1212,6 +1522,9 @@ static void *alloc_coherent(struct device *dev, size_t size, | |||
| 1212 | return virt_addr; | 1522 | return virt_addr; |
| 1213 | } | 1523 | } |
| 1214 | 1524 | ||
| 1525 | if (!dma_ops_domain(domain)) | ||
| 1526 | goto out_free; | ||
| 1527 | |||
| 1215 | if (!dma_mask) | 1528 | if (!dma_mask) |
| 1216 | dma_mask = *dev->dma_mask; | 1529 | dma_mask = *dev->dma_mask; |
| 1217 | 1530 | ||
| @@ -1220,18 +1533,20 @@ static void *alloc_coherent(struct device *dev, size_t size, | |||
| 1220 | *dma_addr = __map_single(dev, iommu, domain->priv, paddr, | 1533 | *dma_addr = __map_single(dev, iommu, domain->priv, paddr, |
| 1221 | size, DMA_BIDIRECTIONAL, true, dma_mask); | 1534 | size, DMA_BIDIRECTIONAL, true, dma_mask); |
| 1222 | 1535 | ||
| 1223 | if (*dma_addr == bad_dma_address) { | 1536 | if (*dma_addr == bad_dma_address) |
| 1224 | free_pages((unsigned long)virt_addr, get_order(size)); | 1537 | goto out_free; |
| 1225 | virt_addr = NULL; | ||
| 1226 | goto out; | ||
| 1227 | } | ||
| 1228 | 1538 | ||
| 1229 | iommu_completion_wait(iommu); | 1539 | iommu_completion_wait(iommu); |
| 1230 | 1540 | ||
| 1231 | out: | ||
| 1232 | spin_unlock_irqrestore(&domain->lock, flags); | 1541 | spin_unlock_irqrestore(&domain->lock, flags); |
| 1233 | 1542 | ||
| 1234 | return virt_addr; | 1543 | return virt_addr; |
| 1544 | |||
| 1545 | out_free: | ||
| 1546 | |||
| 1547 | free_pages((unsigned long)virt_addr, get_order(size)); | ||
| 1548 | |||
| 1549 | return NULL; | ||
| 1235 | } | 1550 | } |
| 1236 | 1551 | ||
| 1237 | /* | 1552 | /* |
| @@ -1245,6 +1560,8 @@ static void free_coherent(struct device *dev, size_t size, | |||
| 1245 | struct protection_domain *domain; | 1560 | struct protection_domain *domain; |
| 1246 | u16 devid; | 1561 | u16 devid; |
| 1247 | 1562 | ||
| 1563 | INC_STATS_COUNTER(cnt_free_coherent); | ||
| 1564 | |||
| 1248 | if (!check_device(dev)) | 1565 | if (!check_device(dev)) |
| 1249 | return; | 1566 | return; |
| 1250 | 1567 | ||
| @@ -1253,6 +1570,9 @@ static void free_coherent(struct device *dev, size_t size, | |||
| 1253 | if (!iommu || !domain) | 1570 | if (!iommu || !domain) |
| 1254 | goto free_mem; | 1571 | goto free_mem; |
| 1255 | 1572 | ||
| 1573 | if (!dma_ops_domain(domain)) | ||
| 1574 | goto free_mem; | ||
| 1575 | |||
| 1256 | spin_lock_irqsave(&domain->lock, flags); | 1576 | spin_lock_irqsave(&domain->lock, flags); |
| 1257 | 1577 | ||
| 1258 | __unmap_single(iommu, domain->priv, dma_addr, size, DMA_BIDIRECTIONAL); | 1578 | __unmap_single(iommu, domain->priv, dma_addr, size, DMA_BIDIRECTIONAL); |
| @@ -1296,7 +1616,7 @@ static int amd_iommu_dma_supported(struct device *dev, u64 mask) | |||
| 1296 | * we don't need to preallocate the protection domains anymore. | 1616 | * we don't need to preallocate the protection domains anymore. |
| 1297 | * For now we have to. | 1617 | * For now we have to. |
| 1298 | */ | 1618 | */ |
| 1299 | void prealloc_protection_domains(void) | 1619 | static void prealloc_protection_domains(void) |
| 1300 | { | 1620 | { |
| 1301 | struct pci_dev *dev = NULL; | 1621 | struct pci_dev *dev = NULL; |
| 1302 | struct dma_ops_domain *dma_dom; | 1622 | struct dma_ops_domain *dma_dom; |
| @@ -1305,7 +1625,7 @@ void prealloc_protection_domains(void) | |||
| 1305 | u16 devid; | 1625 | u16 devid; |
| 1306 | 1626 | ||
| 1307 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 1627 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { |
| 1308 | devid = (dev->bus->number << 8) | dev->devfn; | 1628 | devid = calc_devid(dev->bus->number, dev->devfn); |
| 1309 | if (devid > amd_iommu_last_bdf) | 1629 | if (devid > amd_iommu_last_bdf) |
| 1310 | continue; | 1630 | continue; |
| 1311 | devid = amd_iommu_alias_table[devid]; | 1631 | devid = amd_iommu_alias_table[devid]; |
| @@ -1352,6 +1672,7 @@ int __init amd_iommu_init_dma_ops(void) | |||
| 1352 | iommu->default_dom = dma_ops_domain_alloc(iommu, order); | 1672 | iommu->default_dom = dma_ops_domain_alloc(iommu, order); |
| 1353 | if (iommu->default_dom == NULL) | 1673 | if (iommu->default_dom == NULL) |
| 1354 | return -ENOMEM; | 1674 | return -ENOMEM; |
| 1675 | iommu->default_dom->domain.flags |= PD_DEFAULT_MASK; | ||
| 1355 | ret = iommu_init_unity_mappings(iommu); | 1676 | ret = iommu_init_unity_mappings(iommu); |
| 1356 | if (ret) | 1677 | if (ret) |
| 1357 | goto free_domains; | 1678 | goto free_domains; |
| @@ -1375,6 +1696,12 @@ int __init amd_iommu_init_dma_ops(void) | |||
| 1375 | /* Make the driver finally visible to the drivers */ | 1696 | /* Make the driver finally visible to the drivers */ |
| 1376 | dma_ops = &amd_iommu_dma_ops; | 1697 | dma_ops = &amd_iommu_dma_ops; |
| 1377 | 1698 | ||
| 1699 | register_iommu(&amd_iommu_ops); | ||
| 1700 | |||
| 1701 | bus_register_notifier(&pci_bus_type, &device_nb); | ||
| 1702 | |||
| 1703 | amd_iommu_stats_init(); | ||
| 1704 | |||
| 1378 | return 0; | 1705 | return 0; |
| 1379 | 1706 | ||
| 1380 | free_domains: | 1707 | free_domains: |
| @@ -1386,3 +1713,224 @@ free_domains: | |||
| 1386 | 1713 | ||
| 1387 | return ret; | 1714 | return ret; |
| 1388 | } | 1715 | } |
| 1716 | |||
| 1717 | /***************************************************************************** | ||
| 1718 | * | ||
| 1719 | * The following functions belong to the exported interface of AMD IOMMU | ||
| 1720 | * | ||
| 1721 | * This interface allows access to lower level functions of the IOMMU | ||
| 1722 | * like protection domain handling and assignement of devices to domains | ||
| 1723 | * which is not possible with the dma_ops interface. | ||
| 1724 | * | ||
| 1725 | *****************************************************************************/ | ||
| 1726 | |||
| 1727 | static void cleanup_domain(struct protection_domain *domain) | ||
| 1728 | { | ||
| 1729 | unsigned long flags; | ||
| 1730 | u16 devid; | ||
| 1731 | |||
| 1732 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); | ||
| 1733 | |||
| 1734 | for (devid = 0; devid <= amd_iommu_last_bdf; ++devid) | ||
| 1735 | if (amd_iommu_pd_table[devid] == domain) | ||
| 1736 | __detach_device(domain, devid); | ||
| 1737 | |||
| 1738 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | ||
| 1739 | } | ||
| 1740 | |||
| 1741 | static int amd_iommu_domain_init(struct iommu_domain *dom) | ||
| 1742 | { | ||
| 1743 | struct protection_domain *domain; | ||
| 1744 | |||
| 1745 | domain = kzalloc(sizeof(*domain), GFP_KERNEL); | ||
| 1746 | if (!domain) | ||
| 1747 | return -ENOMEM; | ||
| 1748 | |||
| 1749 | spin_lock_init(&domain->lock); | ||
| 1750 | domain->mode = PAGE_MODE_3_LEVEL; | ||
| 1751 | domain->id = domain_id_alloc(); | ||
| 1752 | if (!domain->id) | ||
| 1753 | goto out_free; | ||
| 1754 | domain->pt_root = (void *)get_zeroed_page(GFP_KERNEL); | ||
| 1755 | if (!domain->pt_root) | ||
| 1756 | goto out_free; | ||
| 1757 | |||
| 1758 | dom->priv = domain; | ||
| 1759 | |||
| 1760 | return 0; | ||
| 1761 | |||
| 1762 | out_free: | ||
| 1763 | kfree(domain); | ||
| 1764 | |||
| 1765 | return -ENOMEM; | ||
| 1766 | } | ||
| 1767 | |||
| 1768 | static void amd_iommu_domain_destroy(struct iommu_domain *dom) | ||
| 1769 | { | ||
| 1770 | struct protection_domain *domain = dom->priv; | ||
| 1771 | |||
| 1772 | if (!domain) | ||
| 1773 | return; | ||
| 1774 | |||
| 1775 | if (domain->dev_cnt > 0) | ||
| 1776 | cleanup_domain(domain); | ||
| 1777 | |||
| 1778 | BUG_ON(domain->dev_cnt != 0); | ||
| 1779 | |||
| 1780 | free_pagetable(domain); | ||
| 1781 | |||
| 1782 | domain_id_free(domain->id); | ||
| 1783 | |||
| 1784 | kfree(domain); | ||
| 1785 | |||
| 1786 | dom->priv = NULL; | ||
| 1787 | } | ||
| 1788 | |||
| 1789 | static void amd_iommu_detach_device(struct iommu_domain *dom, | ||
| 1790 | struct device *dev) | ||
| 1791 | { | ||
| 1792 | struct protection_domain *domain = dom->priv; | ||
| 1793 | struct amd_iommu *iommu; | ||
| 1794 | struct pci_dev *pdev; | ||
| 1795 | u16 devid; | ||
| 1796 | |||
| 1797 | if (dev->bus != &pci_bus_type) | ||
| 1798 | return; | ||
| 1799 | |||
| 1800 | pdev = to_pci_dev(dev); | ||
| 1801 | |||
| 1802 | devid = calc_devid(pdev->bus->number, pdev->devfn); | ||
| 1803 | |||
| 1804 | if (devid > 0) | ||
| 1805 | detach_device(domain, devid); | ||
| 1806 | |||
| 1807 | iommu = amd_iommu_rlookup_table[devid]; | ||
| 1808 | if (!iommu) | ||
| 1809 | return; | ||
| 1810 | |||
| 1811 | iommu_queue_inv_dev_entry(iommu, devid); | ||
| 1812 | iommu_completion_wait(iommu); | ||
| 1813 | } | ||
| 1814 | |||
| 1815 | static int amd_iommu_attach_device(struct iommu_domain *dom, | ||
| 1816 | struct device *dev) | ||
| 1817 | { | ||
| 1818 | struct protection_domain *domain = dom->priv; | ||
| 1819 | struct protection_domain *old_domain; | ||
| 1820 | struct amd_iommu *iommu; | ||
| 1821 | struct pci_dev *pdev; | ||
| 1822 | u16 devid; | ||
| 1823 | |||
| 1824 | if (dev->bus != &pci_bus_type) | ||
| 1825 | return -EINVAL; | ||
| 1826 | |||
| 1827 | pdev = to_pci_dev(dev); | ||
| 1828 | |||
| 1829 | devid = calc_devid(pdev->bus->number, pdev->devfn); | ||
| 1830 | |||
| 1831 | if (devid >= amd_iommu_last_bdf || | ||
| 1832 | devid != amd_iommu_alias_table[devid]) | ||
| 1833 | return -EINVAL; | ||
| 1834 | |||
| 1835 | iommu = amd_iommu_rlookup_table[devid]; | ||
| 1836 | if (!iommu) | ||
| 1837 | return -EINVAL; | ||
| 1838 | |||
| 1839 | old_domain = domain_for_device(devid); | ||
| 1840 | if (old_domain) | ||
| 1841 | return -EBUSY; | ||
| 1842 | |||
| 1843 | attach_device(iommu, domain, devid); | ||
| 1844 | |||
| 1845 | iommu_completion_wait(iommu); | ||
| 1846 | |||
| 1847 | return 0; | ||
| 1848 | } | ||
| 1849 | |||
| 1850 | static int amd_iommu_map_range(struct iommu_domain *dom, | ||
| 1851 | unsigned long iova, phys_addr_t paddr, | ||
| 1852 | size_t size, int iommu_prot) | ||
| 1853 | { | ||
| 1854 | struct protection_domain *domain = dom->priv; | ||
| 1855 | unsigned long i, npages = iommu_num_pages(paddr, size, PAGE_SIZE); | ||
| 1856 | int prot = 0; | ||
| 1857 | int ret; | ||
| 1858 | |||
| 1859 | if (iommu_prot & IOMMU_READ) | ||
| 1860 | prot |= IOMMU_PROT_IR; | ||
| 1861 | if (iommu_prot & IOMMU_WRITE) | ||
| 1862 | prot |= IOMMU_PROT_IW; | ||
| 1863 | |||
| 1864 | iova &= PAGE_MASK; | ||
| 1865 | paddr &= PAGE_MASK; | ||
| 1866 | |||
| 1867 | for (i = 0; i < npages; ++i) { | ||
| 1868 | ret = iommu_map_page(domain, iova, paddr, prot); | ||
| 1869 | if (ret) | ||
| 1870 | return ret; | ||
| 1871 | |||
| 1872 | iova += PAGE_SIZE; | ||
| 1873 | paddr += PAGE_SIZE; | ||
| 1874 | } | ||
| 1875 | |||
| 1876 | return 0; | ||
| 1877 | } | ||
| 1878 | |||
| 1879 | static void amd_iommu_unmap_range(struct iommu_domain *dom, | ||
| 1880 | unsigned long iova, size_t size) | ||
| 1881 | { | ||
| 1882 | |||
| 1883 | struct protection_domain *domain = dom->priv; | ||
| 1884 | unsigned long i, npages = iommu_num_pages(iova, size, PAGE_SIZE); | ||
| 1885 | |||
| 1886 | iova &= PAGE_MASK; | ||
| 1887 | |||
| 1888 | for (i = 0; i < npages; ++i) { | ||
| 1889 | iommu_unmap_page(domain, iova); | ||
| 1890 | iova += PAGE_SIZE; | ||
| 1891 | } | ||
| 1892 | |||
| 1893 | iommu_flush_domain(domain->id); | ||
| 1894 | } | ||
| 1895 | |||
| 1896 | static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, | ||
| 1897 | unsigned long iova) | ||
| 1898 | { | ||
| 1899 | struct protection_domain *domain = dom->priv; | ||
| 1900 | unsigned long offset = iova & ~PAGE_MASK; | ||
| 1901 | phys_addr_t paddr; | ||
| 1902 | u64 *pte; | ||
| 1903 | |||
| 1904 | pte = &domain->pt_root[IOMMU_PTE_L2_INDEX(iova)]; | ||
| 1905 | |||
| 1906 | if (!IOMMU_PTE_PRESENT(*pte)) | ||
| 1907 | return 0; | ||
| 1908 | |||
| 1909 | pte = IOMMU_PTE_PAGE(*pte); | ||
| 1910 | pte = &pte[IOMMU_PTE_L1_INDEX(iova)]; | ||
| 1911 | |||
| 1912 | if (!IOMMU_PTE_PRESENT(*pte)) | ||
| 1913 | return 0; | ||
| 1914 | |||
| 1915 | pte = IOMMU_PTE_PAGE(*pte); | ||
| 1916 | pte = &pte[IOMMU_PTE_L0_INDEX(iova)]; | ||
| 1917 | |||
| 1918 | if (!IOMMU_PTE_PRESENT(*pte)) | ||
| 1919 | return 0; | ||
| 1920 | |||
| 1921 | paddr = *pte & IOMMU_PAGE_MASK; | ||
| 1922 | paddr |= offset; | ||
| 1923 | |||
| 1924 | return paddr; | ||
| 1925 | } | ||
| 1926 | |||
| 1927 | static struct iommu_ops amd_iommu_ops = { | ||
| 1928 | .domain_init = amd_iommu_domain_init, | ||
| 1929 | .domain_destroy = amd_iommu_domain_destroy, | ||
| 1930 | .attach_dev = amd_iommu_attach_device, | ||
| 1931 | .detach_dev = amd_iommu_detach_device, | ||
| 1932 | .map = amd_iommu_map_range, | ||
| 1933 | .unmap = amd_iommu_unmap_range, | ||
| 1934 | .iova_to_phys = amd_iommu_iova_to_phys, | ||
| 1935 | }; | ||
| 1936 | |||
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index c625800c55ca..42c33cebf00f 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
| @@ -122,7 +122,8 @@ u16 amd_iommu_last_bdf; /* largest PCI device id we have | |||
| 122 | LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings | 122 | LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings |
| 123 | we find in ACPI */ | 123 | we find in ACPI */ |
| 124 | unsigned amd_iommu_aperture_order = 26; /* size of aperture in power of 2 */ | 124 | unsigned amd_iommu_aperture_order = 26; /* size of aperture in power of 2 */ |
| 125 | int amd_iommu_isolate = 1; /* if 1, device isolation is enabled */ | 125 | bool amd_iommu_isolate = true; /* if true, device isolation is |
| 126 | enabled */ | ||
| 126 | bool amd_iommu_unmap_flush; /* if true, flush on every unmap */ | 127 | bool amd_iommu_unmap_flush; /* if true, flush on every unmap */ |
| 127 | 128 | ||
| 128 | LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the | 129 | LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the |
| @@ -243,20 +244,16 @@ static void __init iommu_feature_disable(struct amd_iommu *iommu, u8 bit) | |||
| 243 | } | 244 | } |
| 244 | 245 | ||
| 245 | /* Function to enable the hardware */ | 246 | /* Function to enable the hardware */ |
| 246 | void __init iommu_enable(struct amd_iommu *iommu) | 247 | static void __init iommu_enable(struct amd_iommu *iommu) |
| 247 | { | 248 | { |
| 248 | printk(KERN_INFO "AMD IOMMU: Enabling IOMMU " | 249 | printk(KERN_INFO "AMD IOMMU: Enabling IOMMU at %s cap 0x%hx\n", |
| 249 | "at %02x:%02x.%x cap 0x%hx\n", | 250 | dev_name(&iommu->dev->dev), iommu->cap_ptr); |
| 250 | iommu->dev->bus->number, | ||
| 251 | PCI_SLOT(iommu->dev->devfn), | ||
| 252 | PCI_FUNC(iommu->dev->devfn), | ||
| 253 | iommu->cap_ptr); | ||
| 254 | 251 | ||
| 255 | iommu_feature_enable(iommu, CONTROL_IOMMU_EN); | 252 | iommu_feature_enable(iommu, CONTROL_IOMMU_EN); |
| 256 | } | 253 | } |
| 257 | 254 | ||
| 258 | /* Function to enable IOMMU event logging and event interrupts */ | 255 | /* Function to enable IOMMU event logging and event interrupts */ |
| 259 | void __init iommu_enable_event_logging(struct amd_iommu *iommu) | 256 | static void __init iommu_enable_event_logging(struct amd_iommu *iommu) |
| 260 | { | 257 | { |
| 261 | iommu_feature_enable(iommu, CONTROL_EVT_LOG_EN); | 258 | iommu_feature_enable(iommu, CONTROL_EVT_LOG_EN); |
| 262 | iommu_feature_enable(iommu, CONTROL_EVT_INT_EN); | 259 | iommu_feature_enable(iommu, CONTROL_EVT_INT_EN); |
| @@ -1218,9 +1215,9 @@ static int __init parse_amd_iommu_options(char *str) | |||
| 1218 | { | 1215 | { |
| 1219 | for (; *str; ++str) { | 1216 | for (; *str; ++str) { |
| 1220 | if (strncmp(str, "isolate", 7) == 0) | 1217 | if (strncmp(str, "isolate", 7) == 0) |
| 1221 | amd_iommu_isolate = 1; | 1218 | amd_iommu_isolate = true; |
| 1222 | if (strncmp(str, "share", 5) == 0) | 1219 | if (strncmp(str, "share", 5) == 0) |
| 1223 | amd_iommu_isolate = 0; | 1220 | amd_iommu_isolate = false; |
| 1224 | if (strncmp(str, "fullflush", 9) == 0) | 1221 | if (strncmp(str, "fullflush", 9) == 0) |
| 1225 | amd_iommu_unmap_flush = true; | 1222 | amd_iommu_unmap_flush = true; |
| 1226 | } | 1223 | } |
diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 6b7f824db160..b13d3c4dbd42 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c | |||
| @@ -98,8 +98,8 @@ __setup("apicpmtimer", setup_apicpmtimer); | |||
| 98 | #ifdef HAVE_X2APIC | 98 | #ifdef HAVE_X2APIC |
| 99 | int x2apic; | 99 | int x2apic; |
| 100 | /* x2apic enabled before OS handover */ | 100 | /* x2apic enabled before OS handover */ |
| 101 | int x2apic_preenabled; | 101 | static int x2apic_preenabled; |
| 102 | int disable_x2apic; | 102 | static int disable_x2apic; |
| 103 | static __init int setup_nox2apic(char *str) | 103 | static __init int setup_nox2apic(char *str) |
| 104 | { | 104 | { |
| 105 | disable_x2apic = 1; | 105 | disable_x2apic = 1; |
| @@ -140,7 +140,7 @@ static int lapic_next_event(unsigned long delta, | |||
| 140 | struct clock_event_device *evt); | 140 | struct clock_event_device *evt); |
| 141 | static void lapic_timer_setup(enum clock_event_mode mode, | 141 | static void lapic_timer_setup(enum clock_event_mode mode, |
| 142 | struct clock_event_device *evt); | 142 | struct clock_event_device *evt); |
| 143 | static void lapic_timer_broadcast(const cpumask_t *mask); | 143 | static void lapic_timer_broadcast(const struct cpumask *mask); |
| 144 | static void apic_pm_activate(void); | 144 | static void apic_pm_activate(void); |
| 145 | 145 | ||
| 146 | /* | 146 | /* |
| @@ -226,7 +226,7 @@ void xapic_icr_write(u32 low, u32 id) | |||
| 226 | apic_write(APIC_ICR, low); | 226 | apic_write(APIC_ICR, low); |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | u64 xapic_icr_read(void) | 229 | static u64 xapic_icr_read(void) |
| 230 | { | 230 | { |
| 231 | u32 icr1, icr2; | 231 | u32 icr1, icr2; |
| 232 | 232 | ||
| @@ -266,7 +266,7 @@ void x2apic_icr_write(u32 low, u32 id) | |||
| 266 | wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low); | 266 | wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low); |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | u64 x2apic_icr_read(void) | 269 | static u64 x2apic_icr_read(void) |
| 270 | { | 270 | { |
| 271 | unsigned long val; | 271 | unsigned long val; |
| 272 | 272 | ||
| @@ -453,7 +453,7 @@ static void lapic_timer_setup(enum clock_event_mode mode, | |||
| 453 | /* | 453 | /* |
| 454 | * Local APIC timer broadcast function | 454 | * Local APIC timer broadcast function |
| 455 | */ | 455 | */ |
| 456 | static void lapic_timer_broadcast(const cpumask_t *mask) | 456 | static void lapic_timer_broadcast(const struct cpumask *mask) |
| 457 | { | 457 | { |
| 458 | #ifdef CONFIG_SMP | 458 | #ifdef CONFIG_SMP |
| 459 | send_IPI_mask(mask, LOCAL_TIMER_VECTOR); | 459 | send_IPI_mask(mask, LOCAL_TIMER_VECTOR); |
diff --git a/arch/x86/kernel/bios_uv.c b/arch/x86/kernel/bios_uv.c index 2a0a2a3cac26..f63882728d91 100644 --- a/arch/x86/kernel/bios_uv.c +++ b/arch/x86/kernel/bios_uv.c | |||
| @@ -25,7 +25,7 @@ | |||
| 25 | #include <asm/uv/bios.h> | 25 | #include <asm/uv/bios.h> |
| 26 | #include <asm/uv/uv_hub.h> | 26 | #include <asm/uv/uv_hub.h> |
| 27 | 27 | ||
| 28 | struct uv_systab uv_systab; | 28 | static struct uv_systab uv_systab; |
| 29 | 29 | ||
| 30 | s64 uv_bios_call(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5) | 30 | s64 uv_bios_call(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5) |
| 31 | { | 31 | { |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 42e0853030cb..3f95a40f718a 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
| @@ -355,7 +355,7 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c) | |||
| 355 | printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); | 355 | printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); |
| 356 | } else if (smp_num_siblings > 1) { | 356 | } else if (smp_num_siblings > 1) { |
| 357 | 357 | ||
| 358 | if (smp_num_siblings > NR_CPUS) { | 358 | if (smp_num_siblings > nr_cpu_ids) { |
| 359 | printk(KERN_WARNING "CPU: Unsupported number of siblings %d", | 359 | printk(KERN_WARNING "CPU: Unsupported number of siblings %d", |
| 360 | smp_num_siblings); | 360 | smp_num_siblings); |
| 361 | smp_num_siblings = 1; | 361 | smp_num_siblings = 1; |
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 88ea02dcb622..28102ad1a363 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
| @@ -517,6 +517,17 @@ acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu) | |||
| 517 | } | 517 | } |
| 518 | } | 518 | } |
| 519 | 519 | ||
| 520 | static void free_acpi_perf_data(void) | ||
| 521 | { | ||
| 522 | unsigned int i; | ||
| 523 | |||
| 524 | /* Freeing a NULL pointer is OK, and alloc_percpu zeroes. */ | ||
| 525 | for_each_possible_cpu(i) | ||
| 526 | free_cpumask_var(per_cpu_ptr(acpi_perf_data, i) | ||
| 527 | ->shared_cpu_map); | ||
| 528 | free_percpu(acpi_perf_data); | ||
| 529 | } | ||
| 530 | |||
| 520 | /* | 531 | /* |
| 521 | * acpi_cpufreq_early_init - initialize ACPI P-States library | 532 | * acpi_cpufreq_early_init - initialize ACPI P-States library |
| 522 | * | 533 | * |
| @@ -527,6 +538,7 @@ acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu) | |||
| 527 | */ | 538 | */ |
| 528 | static int __init acpi_cpufreq_early_init(void) | 539 | static int __init acpi_cpufreq_early_init(void) |
| 529 | { | 540 | { |
| 541 | unsigned int i; | ||
| 530 | dprintk("acpi_cpufreq_early_init\n"); | 542 | dprintk("acpi_cpufreq_early_init\n"); |
| 531 | 543 | ||
| 532 | acpi_perf_data = alloc_percpu(struct acpi_processor_performance); | 544 | acpi_perf_data = alloc_percpu(struct acpi_processor_performance); |
| @@ -534,6 +546,16 @@ static int __init acpi_cpufreq_early_init(void) | |||
| 534 | dprintk("Memory allocation error for acpi_perf_data.\n"); | 546 | dprintk("Memory allocation error for acpi_perf_data.\n"); |
| 535 | return -ENOMEM; | 547 | return -ENOMEM; |
| 536 | } | 548 | } |
| 549 | for_each_possible_cpu(i) { | ||
| 550 | if (!alloc_cpumask_var_node( | ||
| 551 | &per_cpu_ptr(acpi_perf_data, i)->shared_cpu_map, | ||
| 552 | GFP_KERNEL, cpu_to_node(i))) { | ||
| 553 | |||
| 554 | /* Freeing a NULL pointer is OK: alloc_percpu zeroes. */ | ||
| 555 | free_acpi_perf_data(); | ||
| 556 | return -ENOMEM; | ||
| 557 | } | ||
| 558 | } | ||
| 537 | 559 | ||
| 538 | /* Do initialization in ACPI core */ | 560 | /* Do initialization in ACPI core */ |
| 539 | acpi_processor_preregister_performance(acpi_perf_data); | 561 | acpi_processor_preregister_performance(acpi_perf_data); |
| @@ -604,9 +626,9 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
| 604 | */ | 626 | */ |
| 605 | if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL || | 627 | if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL || |
| 606 | policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { | 628 | policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { |
| 607 | policy->cpus = perf->shared_cpu_map; | 629 | cpumask_copy(&policy->cpus, perf->shared_cpu_map); |
| 608 | } | 630 | } |
| 609 | policy->related_cpus = perf->shared_cpu_map; | 631 | cpumask_copy(&policy->related_cpus, perf->shared_cpu_map); |
| 610 | 632 | ||
| 611 | #ifdef CONFIG_SMP | 633 | #ifdef CONFIG_SMP |
| 612 | dmi_check_system(sw_any_bug_dmi_table); | 634 | dmi_check_system(sw_any_bug_dmi_table); |
| @@ -795,7 +817,7 @@ static int __init acpi_cpufreq_init(void) | |||
| 795 | 817 | ||
| 796 | ret = cpufreq_register_driver(&acpi_cpufreq_driver); | 818 | ret = cpufreq_register_driver(&acpi_cpufreq_driver); |
| 797 | if (ret) | 819 | if (ret) |
| 798 | free_percpu(acpi_perf_data); | 820 | free_acpi_perf_data(); |
| 799 | 821 | ||
| 800 | return ret; | 822 | return ret; |
| 801 | } | 823 | } |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c index 7c7d56b43136..1b446d79a8fd 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c | |||
| @@ -310,6 +310,12 @@ static int powernow_acpi_init(void) | |||
| 310 | goto err0; | 310 | goto err0; |
| 311 | } | 311 | } |
| 312 | 312 | ||
| 313 | if (!alloc_cpumask_var(&acpi_processor_perf->shared_cpu_map, | ||
| 314 | GFP_KERNEL)) { | ||
| 315 | retval = -ENOMEM; | ||
| 316 | goto err05; | ||
| 317 | } | ||
| 318 | |||
| 313 | if (acpi_processor_register_performance(acpi_processor_perf, 0)) { | 319 | if (acpi_processor_register_performance(acpi_processor_perf, 0)) { |
| 314 | retval = -EIO; | 320 | retval = -EIO; |
| 315 | goto err1; | 321 | goto err1; |
| @@ -412,6 +418,8 @@ static int powernow_acpi_init(void) | |||
| 412 | err2: | 418 | err2: |
| 413 | acpi_processor_unregister_performance(acpi_processor_perf, 0); | 419 | acpi_processor_unregister_performance(acpi_processor_perf, 0); |
| 414 | err1: | 420 | err1: |
| 421 | free_cpumask_var(acpi_processor_perf->shared_cpu_map); | ||
| 422 | err05: | ||
| 415 | kfree(acpi_processor_perf); | 423 | kfree(acpi_processor_perf); |
| 416 | err0: | 424 | err0: |
| 417 | printk(KERN_WARNING PFX "ACPI perflib can not be used in this platform\n"); | 425 | printk(KERN_WARNING PFX "ACPI perflib can not be used in this platform\n"); |
| @@ -652,6 +660,7 @@ static int powernow_cpu_exit (struct cpufreq_policy *policy) { | |||
| 652 | #ifdef CONFIG_X86_POWERNOW_K7_ACPI | 660 | #ifdef CONFIG_X86_POWERNOW_K7_ACPI |
| 653 | if (acpi_processor_perf) { | 661 | if (acpi_processor_perf) { |
| 654 | acpi_processor_unregister_performance(acpi_processor_perf, 0); | 662 | acpi_processor_unregister_performance(acpi_processor_perf, 0); |
| 663 | free_cpumask_var(acpi_processor_perf->shared_cpu_map); | ||
| 655 | kfree(acpi_processor_perf); | 664 | kfree(acpi_processor_perf); |
| 656 | } | 665 | } |
| 657 | #endif | 666 | #endif |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 7f05f44b97e9..c3c9adbaa26f 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
| @@ -766,7 +766,7 @@ static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned | |||
| 766 | static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | 766 | static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) |
| 767 | { | 767 | { |
| 768 | struct cpufreq_frequency_table *powernow_table; | 768 | struct cpufreq_frequency_table *powernow_table; |
| 769 | int ret_val; | 769 | int ret_val = -ENODEV; |
| 770 | 770 | ||
| 771 | if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { | 771 | if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { |
| 772 | dprintk("register performance failed: bad ACPI data\n"); | 772 | dprintk("register performance failed: bad ACPI data\n"); |
| @@ -815,6 +815,13 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
| 815 | /* notify BIOS that we exist */ | 815 | /* notify BIOS that we exist */ |
| 816 | acpi_processor_notify_smm(THIS_MODULE); | 816 | acpi_processor_notify_smm(THIS_MODULE); |
| 817 | 817 | ||
| 818 | if (!alloc_cpumask_var(&data->acpi_data.shared_cpu_map, GFP_KERNEL)) { | ||
| 819 | printk(KERN_ERR PFX | ||
| 820 | "unable to alloc powernow_k8_data cpumask\n"); | ||
| 821 | ret_val = -ENOMEM; | ||
| 822 | goto err_out_mem; | ||
| 823 | } | ||
| 824 | |||
| 818 | return 0; | 825 | return 0; |
| 819 | 826 | ||
| 820 | err_out_mem: | 827 | err_out_mem: |
| @@ -826,7 +833,7 @@ err_out: | |||
| 826 | /* data->acpi_data.state_count informs us at ->exit() whether ACPI was used */ | 833 | /* data->acpi_data.state_count informs us at ->exit() whether ACPI was used */ |
| 827 | data->acpi_data.state_count = 0; | 834 | data->acpi_data.state_count = 0; |
| 828 | 835 | ||
| 829 | return -ENODEV; | 836 | return ret_val; |
| 830 | } | 837 | } |
| 831 | 838 | ||
| 832 | static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table) | 839 | static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table) |
| @@ -929,6 +936,7 @@ static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) | |||
| 929 | { | 936 | { |
| 930 | if (data->acpi_data.state_count) | 937 | if (data->acpi_data.state_count) |
| 931 | acpi_processor_unregister_performance(&data->acpi_data, data->cpu); | 938 | acpi_processor_unregister_performance(&data->acpi_data, data->cpu); |
| 939 | free_cpumask_var(data->acpi_data.shared_cpu_map); | ||
| 932 | } | 940 | } |
| 933 | 941 | ||
| 934 | #else | 942 | #else |
| @@ -1134,7 +1142,8 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
| 1134 | data->cpu = pol->cpu; | 1142 | data->cpu = pol->cpu; |
| 1135 | data->currpstate = HW_PSTATE_INVALID; | 1143 | data->currpstate = HW_PSTATE_INVALID; |
| 1136 | 1144 | ||
| 1137 | if (powernow_k8_cpu_init_acpi(data)) { | 1145 | rc = powernow_k8_cpu_init_acpi(data); |
| 1146 | if (rc) { | ||
| 1138 | /* | 1147 | /* |
| 1139 | * Use the PSB BIOS structure. This is only availabe on | 1148 | * Use the PSB BIOS structure. This is only availabe on |
| 1140 | * an UP version, and is deprecated by AMD. | 1149 | * an UP version, and is deprecated by AMD. |
| @@ -1152,20 +1161,17 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
| 1152 | "ACPI maintainers and complain to your BIOS " | 1161 | "ACPI maintainers and complain to your BIOS " |
| 1153 | "vendor.\n"); | 1162 | "vendor.\n"); |
| 1154 | #endif | 1163 | #endif |
| 1155 | kfree(data); | 1164 | goto err_out; |
| 1156 | return -ENODEV; | ||
| 1157 | } | 1165 | } |
| 1158 | if (pol->cpu != 0) { | 1166 | if (pol->cpu != 0) { |
| 1159 | printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for " | 1167 | printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for " |
| 1160 | "CPU other than CPU0. Complain to your BIOS " | 1168 | "CPU other than CPU0. Complain to your BIOS " |
| 1161 | "vendor.\n"); | 1169 | "vendor.\n"); |
| 1162 | kfree(data); | 1170 | goto err_out; |
| 1163 | return -ENODEV; | ||
| 1164 | } | 1171 | } |
| 1165 | rc = find_psb_table(data); | 1172 | rc = find_psb_table(data); |
| 1166 | if (rc) { | 1173 | if (rc) { |
| 1167 | kfree(data); | 1174 | goto err_out; |
| 1168 | return -ENODEV; | ||
| 1169 | } | 1175 | } |
| 1170 | } | 1176 | } |
| 1171 | 1177 | ||
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index c6ecda64f5f1..48533d77be78 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | |||
| @@ -534,7 +534,7 @@ static void __cpuinit free_cache_attributes(unsigned int cpu) | |||
| 534 | per_cpu(cpuid4_info, cpu) = NULL; | 534 | per_cpu(cpuid4_info, cpu) = NULL; |
| 535 | } | 535 | } |
| 536 | 536 | ||
| 537 | static void get_cpu_leaves(void *_retval) | 537 | static void __cpuinit get_cpu_leaves(void *_retval) |
| 538 | { | 538 | { |
| 539 | int j, *retval = _retval, cpu = smp_processor_id(); | 539 | int j, *retval = _retval, cpu = smp_processor_id(); |
| 540 | 540 | ||
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index d6ec7ec30274..d259e5d2e054 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c | |||
| @@ -824,16 +824,14 @@ static int enable_mtrr_cleanup __initdata = | |||
| 824 | 824 | ||
| 825 | static int __init disable_mtrr_cleanup_setup(char *str) | 825 | static int __init disable_mtrr_cleanup_setup(char *str) |
| 826 | { | 826 | { |
| 827 | if (enable_mtrr_cleanup != -1) | 827 | enable_mtrr_cleanup = 0; |
| 828 | enable_mtrr_cleanup = 0; | ||
| 829 | return 0; | 828 | return 0; |
| 830 | } | 829 | } |
| 831 | early_param("disable_mtrr_cleanup", disable_mtrr_cleanup_setup); | 830 | early_param("disable_mtrr_cleanup", disable_mtrr_cleanup_setup); |
| 832 | 831 | ||
| 833 | static int __init enable_mtrr_cleanup_setup(char *str) | 832 | static int __init enable_mtrr_cleanup_setup(char *str) |
| 834 | { | 833 | { |
| 835 | if (enable_mtrr_cleanup != -1) | 834 | enable_mtrr_cleanup = 1; |
| 836 | enable_mtrr_cleanup = 1; | ||
| 837 | return 0; | 835 | return 0; |
| 838 | } | 836 | } |
| 839 | early_param("enable_mtrr_cleanup", enable_mtrr_cleanup_setup); | 837 | early_param("enable_mtrr_cleanup", enable_mtrr_cleanup_setup); |
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c index 72cefd1e649b..2ac1f0c2beb3 100644 --- a/arch/x86/kernel/cpuid.c +++ b/arch/x86/kernel/cpuid.c | |||
| @@ -39,10 +39,10 @@ | |||
| 39 | #include <linux/device.h> | 39 | #include <linux/device.h> |
| 40 | #include <linux/cpu.h> | 40 | #include <linux/cpu.h> |
| 41 | #include <linux/notifier.h> | 41 | #include <linux/notifier.h> |
| 42 | #include <linux/uaccess.h> | ||
| 42 | 43 | ||
| 43 | #include <asm/processor.h> | 44 | #include <asm/processor.h> |
| 44 | #include <asm/msr.h> | 45 | #include <asm/msr.h> |
| 45 | #include <asm/uaccess.h> | ||
| 46 | #include <asm/system.h> | 46 | #include <asm/system.h> |
| 47 | 47 | ||
| 48 | static struct class *cpuid_class; | 48 | static struct class *cpuid_class; |
| @@ -82,7 +82,7 @@ static loff_t cpuid_seek(struct file *file, loff_t offset, int orig) | |||
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | static ssize_t cpuid_read(struct file *file, char __user *buf, | 84 | static ssize_t cpuid_read(struct file *file, char __user *buf, |
| 85 | size_t count, loff_t * ppos) | 85 | size_t count, loff_t *ppos) |
| 86 | { | 86 | { |
| 87 | char __user *tmp = buf; | 87 | char __user *tmp = buf; |
| 88 | struct cpuid_regs cmd; | 88 | struct cpuid_regs cmd; |
| @@ -117,11 +117,11 @@ static int cpuid_open(struct inode *inode, struct file *file) | |||
| 117 | unsigned int cpu; | 117 | unsigned int cpu; |
| 118 | struct cpuinfo_x86 *c; | 118 | struct cpuinfo_x86 *c; |
| 119 | int ret = 0; | 119 | int ret = 0; |
| 120 | 120 | ||
| 121 | lock_kernel(); | 121 | lock_kernel(); |
| 122 | 122 | ||
| 123 | cpu = iminor(file->f_path.dentry->d_inode); | 123 | cpu = iminor(file->f_path.dentry->d_inode); |
| 124 | if (cpu >= NR_CPUS || !cpu_online(cpu)) { | 124 | if (cpu >= nr_cpu_ids || !cpu_online(cpu)) { |
| 125 | ret = -ENXIO; /* No such CPU */ | 125 | ret = -ENXIO; /* No such CPU */ |
| 126 | goto out; | 126 | goto out; |
| 127 | } | 127 | } |
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index 23b138e31e9c..504ad198e4ad 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c | |||
| @@ -886,7 +886,7 @@ asmlinkage void early_printk(const char *fmt, ...) | |||
| 886 | va_list ap; | 886 | va_list ap; |
| 887 | 887 | ||
| 888 | va_start(ap, fmt); | 888 | va_start(ap, fmt); |
| 889 | n = vscnprintf(buf, 512, fmt, ap); | 889 | n = vscnprintf(buf, sizeof(buf), fmt, ap); |
| 890 | early_console->write(early_console, buf, n); | 890 | early_console->write(early_console, buf, n); |
| 891 | va_end(ap); | 891 | va_end(ap); |
| 892 | } | 892 | } |
diff --git a/arch/x86/kernel/genx2apic_phys.c b/arch/x86/kernel/genx2apic_phys.c index 62895cf315ff..21bcc0e098ba 100644 --- a/arch/x86/kernel/genx2apic_phys.c +++ b/arch/x86/kernel/genx2apic_phys.c | |||
| @@ -161,12 +161,12 @@ static unsigned int phys_pkg_id(int index_msb) | |||
| 161 | return current_cpu_data.initial_apicid >> index_msb; | 161 | return current_cpu_data.initial_apicid >> index_msb; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | void x2apic_send_IPI_self(int vector) | 164 | static void x2apic_send_IPI_self(int vector) |
| 165 | { | 165 | { |
| 166 | apic_write(APIC_SELF_IPI, vector); | 166 | apic_write(APIC_SELF_IPI, vector); |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | void init_x2apic_ldr(void) | 169 | static void init_x2apic_ldr(void) |
| 170 | { | 170 | { |
| 171 | return; | 171 | return; |
| 172 | } | 172 | } |
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 388e05a5fc17..b9a4d8c4b935 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | #include <asm/trampoline.h> | 27 | #include <asm/trampoline.h> |
| 28 | 28 | ||
| 29 | /* boot cpu pda */ | 29 | /* boot cpu pda */ |
| 30 | static struct x8664_pda _boot_cpu_pda __read_mostly; | 30 | static struct x8664_pda _boot_cpu_pda; |
| 31 | 31 | ||
| 32 | #ifdef CONFIG_SMP | 32 | #ifdef CONFIG_SMP |
| 33 | /* | 33 | /* |
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c index 62ecfc991e1e..3639442aa7a4 100644 --- a/arch/x86/kernel/io_apic.c +++ b/arch/x86/kernel/io_apic.c | |||
| @@ -214,11 +214,11 @@ static struct irq_cfg *get_one_free_irq_cfg(int cpu) | |||
| 214 | 214 | ||
| 215 | cfg = kzalloc_node(sizeof(*cfg), GFP_ATOMIC, node); | 215 | cfg = kzalloc_node(sizeof(*cfg), GFP_ATOMIC, node); |
| 216 | if (cfg) { | 216 | if (cfg) { |
| 217 | /* FIXME: needs alloc_cpumask_var_node() */ | 217 | if (!alloc_cpumask_var_node(&cfg->domain, GFP_ATOMIC, node)) { |
| 218 | if (!alloc_cpumask_var(&cfg->domain, GFP_ATOMIC)) { | ||
| 219 | kfree(cfg); | 218 | kfree(cfg); |
| 220 | cfg = NULL; | 219 | cfg = NULL; |
| 221 | } else if (!alloc_cpumask_var(&cfg->old_domain, GFP_ATOMIC)) { | 220 | } else if (!alloc_cpumask_var_node(&cfg->old_domain, |
| 221 | GFP_ATOMIC, node)) { | ||
| 222 | free_cpumask_var(cfg->domain); | 222 | free_cpumask_var(cfg->domain); |
| 223 | kfree(cfg); | 223 | kfree(cfg); |
| 224 | cfg = NULL; | 224 | cfg = NULL; |
| @@ -706,7 +706,7 @@ static void __unmask_IO_APIC_irq(struct irq_cfg *cfg) | |||
| 706 | } | 706 | } |
| 707 | 707 | ||
| 708 | #ifdef CONFIG_X86_64 | 708 | #ifdef CONFIG_X86_64 |
| 709 | void io_apic_sync(struct irq_pin_list *entry) | 709 | static void io_apic_sync(struct irq_pin_list *entry) |
| 710 | { | 710 | { |
| 711 | /* | 711 | /* |
| 712 | * Synchronize the IO-APIC and the CPU by doing | 712 | * Synchronize the IO-APIC and the CPU by doing |
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index eee32b43fee3..71f1d99a635d 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c | |||
| @@ -12,8 +12,8 @@ | |||
| 12 | #include <linux/mm.h> | 12 | #include <linux/mm.h> |
| 13 | #include <linux/smp.h> | 13 | #include <linux/smp.h> |
| 14 | #include <linux/vmalloc.h> | 14 | #include <linux/vmalloc.h> |
| 15 | #include <linux/uaccess.h> | ||
| 15 | 16 | ||
| 16 | #include <asm/uaccess.h> | ||
| 17 | #include <asm/system.h> | 17 | #include <asm/system.h> |
| 18 | #include <asm/ldt.h> | 18 | #include <asm/ldt.h> |
| 19 | #include <asm/desc.h> | 19 | #include <asm/desc.h> |
| @@ -93,7 +93,7 @@ static inline int copy_ldt(mm_context_t *new, mm_context_t *old) | |||
| 93 | if (err < 0) | 93 | if (err < 0) |
| 94 | return err; | 94 | return err; |
| 95 | 95 | ||
| 96 | for(i = 0; i < old->size; i++) | 96 | for (i = 0; i < old->size; i++) |
| 97 | write_ldt_entry(new->ldt, i, old->ldt + i * LDT_ENTRY_SIZE); | 97 | write_ldt_entry(new->ldt, i, old->ldt + i * LDT_ENTRY_SIZE); |
| 98 | return 0; | 98 | return 0; |
| 99 | } | 99 | } |
diff --git a/arch/x86/kernel/mmconf-fam10h_64.c b/arch/x86/kernel/mmconf-fam10h_64.c index efc2f361fe85..666e43df51f9 100644 --- a/arch/x86/kernel/mmconf-fam10h_64.c +++ b/arch/x86/kernel/mmconf-fam10h_64.c | |||
| @@ -13,8 +13,7 @@ | |||
| 13 | #include <asm/msr.h> | 13 | #include <asm/msr.h> |
| 14 | #include <asm/acpi.h> | 14 | #include <asm/acpi.h> |
| 15 | #include <asm/mmconfig.h> | 15 | #include <asm/mmconfig.h> |
| 16 | 16 | #include <asm/pci_x86.h> | |
| 17 | #include "../pci/pci.h" | ||
| 18 | 17 | ||
| 19 | struct pci_hostbridge_probe { | 18 | struct pci_hostbridge_probe { |
| 20 | u32 bus; | 19 | u32 bus; |
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 45e3b69808ba..c5c5b8df1dbc 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c | |||
| @@ -16,14 +16,14 @@ | |||
| 16 | #include <linux/bitops.h> | 16 | #include <linux/bitops.h> |
| 17 | #include <linux/acpi.h> | 17 | #include <linux/acpi.h> |
| 18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 19 | #include <linux/smp.h> | ||
| 20 | #include <linux/acpi.h> | ||
| 19 | 21 | ||
| 20 | #include <asm/smp.h> | ||
| 21 | #include <asm/mtrr.h> | 22 | #include <asm/mtrr.h> |
| 22 | #include <asm/mpspec.h> | 23 | #include <asm/mpspec.h> |
| 23 | #include <asm/pgalloc.h> | 24 | #include <asm/pgalloc.h> |
| 24 | #include <asm/io_apic.h> | 25 | #include <asm/io_apic.h> |
| 25 | #include <asm/proto.h> | 26 | #include <asm/proto.h> |
| 26 | #include <asm/acpi.h> | ||
| 27 | #include <asm/bios_ebda.h> | 27 | #include <asm/bios_ebda.h> |
| 28 | #include <asm/e820.h> | 28 | #include <asm/e820.h> |
| 29 | #include <asm/trampoline.h> | 29 | #include <asm/trampoline.h> |
| @@ -95,8 +95,8 @@ static void __init MP_bus_info(struct mpc_config_bus *m) | |||
| 95 | #endif | 95 | #endif |
| 96 | 96 | ||
| 97 | if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA) - 1) == 0) { | 97 | if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA) - 1) == 0) { |
| 98 | set_bit(m->mpc_busid, mp_bus_not_pci); | 98 | set_bit(m->mpc_busid, mp_bus_not_pci); |
| 99 | #if defined(CONFIG_EISA) || defined (CONFIG_MCA) | 99 | #if defined(CONFIG_EISA) || defined(CONFIG_MCA) |
| 100 | mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; | 100 | mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; |
| 101 | #endif | 101 | #endif |
| 102 | } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI) - 1) == 0) { | 102 | } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI) - 1) == 0) { |
| @@ -104,7 +104,7 @@ static void __init MP_bus_info(struct mpc_config_bus *m) | |||
| 104 | x86_quirks->mpc_oem_pci_bus(m); | 104 | x86_quirks->mpc_oem_pci_bus(m); |
| 105 | 105 | ||
| 106 | clear_bit(m->mpc_busid, mp_bus_not_pci); | 106 | clear_bit(m->mpc_busid, mp_bus_not_pci); |
| 107 | #if defined(CONFIG_EISA) || defined (CONFIG_MCA) | 107 | #if defined(CONFIG_EISA) || defined(CONFIG_MCA) |
| 108 | mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI; | 108 | mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI; |
| 109 | } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA) - 1) == 0) { | 109 | } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA) - 1) == 0) { |
| 110 | mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA; | 110 | mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA; |
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 82a7c7ed6d45..726266695b2c 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c | |||
| @@ -136,7 +136,7 @@ static int msr_open(struct inode *inode, struct file *file) | |||
| 136 | lock_kernel(); | 136 | lock_kernel(); |
| 137 | cpu = iminor(file->f_path.dentry->d_inode); | 137 | cpu = iminor(file->f_path.dentry->d_inode); |
| 138 | 138 | ||
| 139 | if (cpu >= NR_CPUS || !cpu_online(cpu)) { | 139 | if (cpu >= nr_cpu_ids || !cpu_online(cpu)) { |
| 140 | ret = -ENXIO; /* No such CPU */ | 140 | ret = -ENXIO; /* No such CPU */ |
| 141 | goto out; | 141 | goto out; |
| 142 | } | 142 | } |
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index 8bd1bf9622a7..45a09ccdc214 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c | |||
| @@ -26,11 +26,10 @@ | |||
| 26 | #include <linux/kernel_stat.h> | 26 | #include <linux/kernel_stat.h> |
| 27 | #include <linux/kdebug.h> | 27 | #include <linux/kdebug.h> |
| 28 | #include <linux/smp.h> | 28 | #include <linux/smp.h> |
| 29 | #include <linux/nmi.h> | ||
| 29 | 30 | ||
| 30 | #include <asm/i8259.h> | 31 | #include <asm/i8259.h> |
| 31 | #include <asm/io_apic.h> | 32 | #include <asm/io_apic.h> |
| 32 | #include <asm/smp.h> | ||
| 33 | #include <asm/nmi.h> | ||
| 34 | #include <asm/proto.h> | 33 | #include <asm/proto.h> |
| 35 | #include <asm/timer.h> | 34 | #include <asm/timer.h> |
| 36 | 35 | ||
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index a35eaa379ff6..00c2bcd41463 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
| @@ -52,7 +52,7 @@ static u32 *iommu_gatt_base; /* Remapping table */ | |||
| 52 | * to trigger bugs with some popular PCI cards, in particular 3ware (but | 52 | * to trigger bugs with some popular PCI cards, in particular 3ware (but |
| 53 | * has been also also seen with Qlogic at least). | 53 | * has been also also seen with Qlogic at least). |
| 54 | */ | 54 | */ |
| 55 | int iommu_fullflush = 1; | 55 | static int iommu_fullflush = 1; |
| 56 | 56 | ||
| 57 | /* Allocation bitmap for the remapping area: */ | 57 | /* Allocation bitmap for the remapping area: */ |
| 58 | static DEFINE_SPINLOCK(iommu_bitmap_lock); | 58 | static DEFINE_SPINLOCK(iommu_bitmap_lock); |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 39643b1df061..2b46eb41643b 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <asm/proto.h> | 12 | #include <asm/proto.h> |
| 13 | #include <asm/reboot_fixups.h> | 13 | #include <asm/reboot_fixups.h> |
| 14 | #include <asm/reboot.h> | 14 | #include <asm/reboot.h> |
| 15 | #include <asm/pci_x86.h> | ||
| 15 | #include <asm/virtext.h> | 16 | #include <asm/virtext.h> |
| 16 | 17 | ||
| 17 | #ifdef CONFIG_X86_32 | 18 | #ifdef CONFIG_X86_32 |
| @@ -24,7 +25,6 @@ | |||
| 24 | 25 | ||
| 25 | #include <mach_ipi.h> | 26 | #include <mach_ipi.h> |
| 26 | 27 | ||
| 27 | |||
| 28 | /* | 28 | /* |
| 29 | * Power off function, if any | 29 | * Power off function, if any |
| 30 | */ | 30 | */ |
| @@ -501,7 +501,7 @@ void native_machine_shutdown(void) | |||
| 501 | 501 | ||
| 502 | #ifdef CONFIG_X86_32 | 502 | #ifdef CONFIG_X86_32 |
| 503 | /* See if there has been given a command line override */ | 503 | /* See if there has been given a command line override */ |
| 504 | if ((reboot_cpu != -1) && (reboot_cpu < NR_CPUS) && | 504 | if ((reboot_cpu != -1) && (reboot_cpu < nr_cpu_ids) && |
| 505 | cpu_online(reboot_cpu)) | 505 | cpu_online(reboot_cpu)) |
| 506 | reboot_cpu_id = reboot_cpu; | 506 | reboot_cpu_id = reboot_cpu; |
| 507 | #endif | 507 | #endif |
| @@ -511,7 +511,7 @@ void native_machine_shutdown(void) | |||
| 511 | reboot_cpu_id = smp_processor_id(); | 511 | reboot_cpu_id = smp_processor_id(); |
| 512 | 512 | ||
| 513 | /* Make certain I only run on the appropriate processor */ | 513 | /* Make certain I only run on the appropriate processor */ |
| 514 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(reboot_cpu_id)); | 514 | set_cpus_allowed_ptr(current, cpumask_of(reboot_cpu_id)); |
| 515 | 515 | ||
| 516 | /* O.K Now that I'm on the appropriate processor, | 516 | /* O.K Now that I'm on the appropriate processor, |
| 517 | * stop all of the others. | 517 | * stop all of the others. |
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 0b63b08e7530..a4b619c33106 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c | |||
| @@ -153,12 +153,10 @@ void __init setup_per_cpu_areas(void) | |||
| 153 | align = max_t(unsigned long, PAGE_SIZE, align); | 153 | align = max_t(unsigned long, PAGE_SIZE, align); |
| 154 | size = roundup(old_size, align); | 154 | size = roundup(old_size, align); |
| 155 | 155 | ||
| 156 | printk(KERN_INFO | 156 | pr_info("NR_CPUS:%d nr_cpumask_bits:%d nr_cpu_ids:%d nr_node_ids:%d\n", |
| 157 | "NR_CPUS:%d nr_cpumask_bits:%d nr_cpu_ids:%d nr_node_ids:%d\n", | ||
| 158 | NR_CPUS, nr_cpumask_bits, nr_cpu_ids, nr_node_ids); | 157 | NR_CPUS, nr_cpumask_bits, nr_cpu_ids, nr_node_ids); |
| 159 | 158 | ||
| 160 | printk(KERN_INFO "PERCPU: Allocating %zd bytes of per cpu data\n", | 159 | pr_info("PERCPU: Allocating %zd bytes of per cpu data\n", size); |
| 161 | size); | ||
| 162 | 160 | ||
| 163 | for_each_possible_cpu(cpu) { | 161 | for_each_possible_cpu(cpu) { |
| 164 | #ifndef CONFIG_NEED_MULTIPLE_NODES | 162 | #ifndef CONFIG_NEED_MULTIPLE_NODES |
| @@ -169,22 +167,15 @@ void __init setup_per_cpu_areas(void) | |||
| 169 | if (!node_online(node) || !NODE_DATA(node)) { | 167 | if (!node_online(node) || !NODE_DATA(node)) { |
| 170 | ptr = __alloc_bootmem(size, align, | 168 | ptr = __alloc_bootmem(size, align, |
| 171 | __pa(MAX_DMA_ADDRESS)); | 169 | __pa(MAX_DMA_ADDRESS)); |
| 172 | printk(KERN_INFO | 170 | pr_info("cpu %d has no node %d or node-local memory\n", |
| 173 | "cpu %d has no node %d or node-local memory\n", | ||
| 174 | cpu, node); | 171 | cpu, node); |
| 175 | if (ptr) | 172 | pr_debug("per cpu data for cpu%d at %016lx\n", |
| 176 | printk(KERN_DEBUG | 173 | cpu, __pa(ptr)); |
| 177 | "per cpu data for cpu%d at %016lx\n", | 174 | } else { |
| 178 | cpu, __pa(ptr)); | ||
| 179 | } | ||
| 180 | else { | ||
| 181 | ptr = __alloc_bootmem_node(NODE_DATA(node), size, align, | 175 | ptr = __alloc_bootmem_node(NODE_DATA(node), size, align, |
| 182 | __pa(MAX_DMA_ADDRESS)); | 176 | __pa(MAX_DMA_ADDRESS)); |
| 183 | if (ptr) | 177 | pr_debug("per cpu data for cpu%d on node%d at %016lx\n", |
| 184 | printk(KERN_DEBUG | 178 | cpu, node, __pa(ptr)); |
| 185 | "per cpu data for cpu%d on node%d " | ||
| 186 | "at %016lx\n", | ||
| 187 | cpu, node, __pa(ptr)); | ||
| 188 | } | 179 | } |
| 189 | #endif | 180 | #endif |
| 190 | per_cpu_offset(cpu) = ptr - __per_cpu_start; | 181 | per_cpu_offset(cpu) = ptr - __per_cpu_start; |
| @@ -339,25 +330,25 @@ static const cpumask_t cpu_mask_none; | |||
| 339 | /* | 330 | /* |
| 340 | * Returns a pointer to the bitmask of CPUs on Node 'node'. | 331 | * Returns a pointer to the bitmask of CPUs on Node 'node'. |
| 341 | */ | 332 | */ |
| 342 | const cpumask_t *_node_to_cpumask_ptr(int node) | 333 | const cpumask_t *cpumask_of_node(int node) |
| 343 | { | 334 | { |
| 344 | if (node_to_cpumask_map == NULL) { | 335 | if (node_to_cpumask_map == NULL) { |
| 345 | printk(KERN_WARNING | 336 | printk(KERN_WARNING |
| 346 | "_node_to_cpumask_ptr(%d): no node_to_cpumask_map!\n", | 337 | "cpumask_of_node(%d): no node_to_cpumask_map!\n", |
| 347 | node); | 338 | node); |
| 348 | dump_stack(); | 339 | dump_stack(); |
| 349 | return (const cpumask_t *)&cpu_online_map; | 340 | return (const cpumask_t *)&cpu_online_map; |
| 350 | } | 341 | } |
| 351 | if (node >= nr_node_ids) { | 342 | if (node >= nr_node_ids) { |
| 352 | printk(KERN_WARNING | 343 | printk(KERN_WARNING |
| 353 | "_node_to_cpumask_ptr(%d): node > nr_node_ids(%d)\n", | 344 | "cpumask_of_node(%d): node > nr_node_ids(%d)\n", |
| 354 | node, nr_node_ids); | 345 | node, nr_node_ids); |
| 355 | dump_stack(); | 346 | dump_stack(); |
| 356 | return &cpu_mask_none; | 347 | return &cpu_mask_none; |
| 357 | } | 348 | } |
| 358 | return &node_to_cpumask_map[node]; | 349 | return &node_to_cpumask_map[node]; |
| 359 | } | 350 | } |
| 360 | EXPORT_SYMBOL(_node_to_cpumask_ptr); | 351 | EXPORT_SYMBOL(cpumask_of_node); |
| 361 | 352 | ||
| 362 | /* | 353 | /* |
| 363 | * Returns a bitmask of CPUs on Node 'node'. | 354 | * Returns a bitmask of CPUs on Node 'node'. |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 31869bf5fabd..6bd4d9b73870 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
| @@ -496,7 +496,7 @@ void __cpuinit set_cpu_sibling_map(int cpu) | |||
| 496 | } | 496 | } |
| 497 | 497 | ||
| 498 | /* maps the cpu to the sched domain representing multi-core */ | 498 | /* maps the cpu to the sched domain representing multi-core */ |
| 499 | cpumask_t cpu_coregroup_map(int cpu) | 499 | const struct cpumask *cpu_coregroup_mask(int cpu) |
| 500 | { | 500 | { |
| 501 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 501 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
| 502 | /* | 502 | /* |
| @@ -504,9 +504,14 @@ cpumask_t cpu_coregroup_map(int cpu) | |||
| 504 | * And for power savings, we return cpu_core_map | 504 | * And for power savings, we return cpu_core_map |
| 505 | */ | 505 | */ |
| 506 | if (sched_mc_power_savings || sched_smt_power_savings) | 506 | if (sched_mc_power_savings || sched_smt_power_savings) |
| 507 | return per_cpu(cpu_core_map, cpu); | 507 | return &per_cpu(cpu_core_map, cpu); |
| 508 | else | 508 | else |
| 509 | return c->llc_shared_map; | 509 | return &c->llc_shared_map; |
| 510 | } | ||
| 511 | |||
| 512 | cpumask_t cpu_coregroup_map(int cpu) | ||
| 513 | { | ||
| 514 | return *cpu_coregroup_mask(cpu); | ||
| 510 | } | 515 | } |
| 511 | 516 | ||
| 512 | static void impress_friends(void) | 517 | static void impress_friends(void) |
| @@ -1149,7 +1154,7 @@ static void __init smp_cpu_index_default(void) | |||
| 1149 | for_each_possible_cpu(i) { | 1154 | for_each_possible_cpu(i) { |
| 1150 | c = &cpu_data(i); | 1155 | c = &cpu_data(i); |
| 1151 | /* mark all to hotplug */ | 1156 | /* mark all to hotplug */ |
| 1152 | c->cpu_index = NR_CPUS; | 1157 | c->cpu_index = nr_cpu_ids; |
| 1153 | } | 1158 | } |
| 1154 | } | 1159 | } |
| 1155 | 1160 | ||
| @@ -1293,6 +1298,8 @@ __init void prefill_possible_map(void) | |||
| 1293 | else | 1298 | else |
| 1294 | possible = setup_possible_cpus; | 1299 | possible = setup_possible_cpus; |
| 1295 | 1300 | ||
| 1301 | total_cpus = max_t(int, possible, num_processors + disabled_cpus); | ||
| 1302 | |||
| 1296 | if (possible > CONFIG_NR_CPUS) { | 1303 | if (possible > CONFIG_NR_CPUS) { |
| 1297 | printk(KERN_WARNING | 1304 | printk(KERN_WARNING |
| 1298 | "%d Processors exceeds NR_CPUS limit of %d\n", | 1305 | "%d Processors exceeds NR_CPUS limit of %d\n", |
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c index 6a00e5faaa74..f885023167e0 100644 --- a/arch/x86/kernel/tlb_uv.c +++ b/arch/x86/kernel/tlb_uv.c | |||
| @@ -582,7 +582,6 @@ static int __init uv_ptc_init(void) | |||
| 582 | static struct bau_control * __init uv_table_bases_init(int blade, int node) | 582 | static struct bau_control * __init uv_table_bases_init(int blade, int node) |
| 583 | { | 583 | { |
| 584 | int i; | 584 | int i; |
| 585 | int *ip; | ||
| 586 | struct bau_msg_status *msp; | 585 | struct bau_msg_status *msp; |
| 587 | struct bau_control *bau_tabp; | 586 | struct bau_control *bau_tabp; |
| 588 | 587 | ||
| @@ -599,13 +598,6 @@ static struct bau_control * __init uv_table_bases_init(int blade, int node) | |||
| 599 | bau_cpubits_clear(&msp->seen_by, (int) | 598 | bau_cpubits_clear(&msp->seen_by, (int) |
| 600 | uv_blade_nr_possible_cpus(blade)); | 599 | uv_blade_nr_possible_cpus(blade)); |
| 601 | 600 | ||
| 602 | bau_tabp->watching = | ||
| 603 | kmalloc_node(sizeof(int) * DEST_NUM_RESOURCES, GFP_KERNEL, node); | ||
| 604 | BUG_ON(!bau_tabp->watching); | ||
| 605 | |||
| 606 | for (i = 0, ip = bau_tabp->watching; i < DEST_Q_SIZE; i++, ip++) | ||
| 607 | *ip = 0; | ||
| 608 | |||
| 609 | uv_bau_table_bases[blade] = bau_tabp; | 601 | uv_bau_table_bases[blade] = bau_tabp; |
| 610 | 602 | ||
| 611 | return bau_tabp; | 603 | return bau_tabp; |
| @@ -628,7 +620,6 @@ uv_table_bases_finish(int blade, int node, int cur_cpu, | |||
| 628 | bcp->bau_msg_head = bau_tablesp->va_queue_first; | 620 | bcp->bau_msg_head = bau_tablesp->va_queue_first; |
| 629 | bcp->va_queue_first = bau_tablesp->va_queue_first; | 621 | bcp->va_queue_first = bau_tablesp->va_queue_first; |
| 630 | bcp->va_queue_last = bau_tablesp->va_queue_last; | 622 | bcp->va_queue_last = bau_tablesp->va_queue_last; |
| 631 | bcp->watching = bau_tablesp->watching; | ||
| 632 | bcp->msg_statuses = bau_tablesp->msg_statuses; | 623 | bcp->msg_statuses = bau_tablesp->msg_statuses; |
| 633 | bcp->descriptor_base = adp; | 624 | bcp->descriptor_base = adp; |
| 634 | } | 625 | } |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 2d1f4c7e4052..ce6650eb64e9 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
| @@ -292,8 +292,10 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) | |||
| 292 | tsk->thread.error_code = error_code; | 292 | tsk->thread.error_code = error_code; |
| 293 | tsk->thread.trap_no = 8; | 293 | tsk->thread.trap_no = 8; |
| 294 | 294 | ||
| 295 | /* This is always a kernel trap and never fixable (and thus must | 295 | /* |
| 296 | never return). */ | 296 | * This is always a kernel trap and never fixable (and thus must |
| 297 | * never return). | ||
| 298 | */ | ||
| 297 | for (;;) | 299 | for (;;) |
| 298 | die(str, regs, error_code); | 300 | die(str, regs, error_code); |
| 299 | } | 301 | } |
| @@ -520,9 +522,11 @@ dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) | |||
| 520 | } | 522 | } |
| 521 | 523 | ||
| 522 | #ifdef CONFIG_X86_64 | 524 | #ifdef CONFIG_X86_64 |
| 523 | /* Help handler running on IST stack to switch back to user stack | 525 | /* |
| 524 | for scheduling or signal handling. The actual stack switch is done in | 526 | * Help handler running on IST stack to switch back to user stack |
| 525 | entry.S */ | 527 | * for scheduling or signal handling. The actual stack switch is done in |
| 528 | * entry.S | ||
| 529 | */ | ||
| 526 | asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) | 530 | asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) |
| 527 | { | 531 | { |
| 528 | struct pt_regs *regs = eregs; | 532 | struct pt_regs *regs = eregs; |
| @@ -532,8 +536,10 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) | |||
| 532 | /* Exception from user space */ | 536 | /* Exception from user space */ |
| 533 | else if (user_mode(eregs)) | 537 | else if (user_mode(eregs)) |
| 534 | regs = task_pt_regs(current); | 538 | regs = task_pt_regs(current); |
| 535 | /* Exception from kernel and interrupts are enabled. Move to | 539 | /* |
| 536 | kernel process stack. */ | 540 | * Exception from kernel and interrupts are enabled. Move to |
| 541 | * kernel process stack. | ||
| 542 | */ | ||
| 537 | else if (eregs->flags & X86_EFLAGS_IF) | 543 | else if (eregs->flags & X86_EFLAGS_IF) |
| 538 | regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs)); | 544 | regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs)); |
| 539 | if (eregs != regs) | 545 | if (eregs != regs) |
| @@ -685,12 +691,7 @@ void math_error(void __user *ip) | |||
| 685 | cwd = get_fpu_cwd(task); | 691 | cwd = get_fpu_cwd(task); |
| 686 | swd = get_fpu_swd(task); | 692 | swd = get_fpu_swd(task); |
| 687 | 693 | ||
| 688 | err = swd & ~cwd & 0x3f; | 694 | err = swd & ~cwd; |
| 689 | |||
| 690 | #ifdef CONFIG_X86_32 | ||
| 691 | if (!err) | ||
| 692 | return; | ||
| 693 | #endif | ||
| 694 | 695 | ||
| 695 | if (err & 0x001) { /* Invalid op */ | 696 | if (err & 0x001) { /* Invalid op */ |
| 696 | /* | 697 | /* |
| @@ -708,7 +709,11 @@ void math_error(void __user *ip) | |||
| 708 | } else if (err & 0x020) { /* Precision */ | 709 | } else if (err & 0x020) { /* Precision */ |
| 709 | info.si_code = FPE_FLTRES; | 710 | info.si_code = FPE_FLTRES; |
| 710 | } else { | 711 | } else { |
| 711 | info.si_code = __SI_FAULT|SI_KERNEL; /* WTF? */ | 712 | /* |
| 713 | * If we're using IRQ 13, or supposedly even some trap 16 | ||
| 714 | * implementations, it's possible we get a spurious trap... | ||
| 715 | */ | ||
| 716 | return; /* Spurious trap, no error */ | ||
| 712 | } | 717 | } |
| 713 | force_sig_info(SIGFPE, &info, task); | 718 | force_sig_info(SIGFPE, &info, task); |
| 714 | } | 719 | } |
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c index 15c3e6999182..2b54fe002e94 100644 --- a/arch/x86/kernel/xsave.c +++ b/arch/x86/kernel/xsave.c | |||
| @@ -159,7 +159,7 @@ int save_i387_xstate(void __user *buf) | |||
| 159 | * Restore the extended state if present. Otherwise, restore the FP/SSE | 159 | * Restore the extended state if present. Otherwise, restore the FP/SSE |
| 160 | * state. | 160 | * state. |
| 161 | */ | 161 | */ |
| 162 | int restore_user_xstate(void __user *buf) | 162 | static int restore_user_xstate(void __user *buf) |
| 163 | { | 163 | { |
| 164 | struct _fpx_sw_bytes fx_sw_user; | 164 | struct _fpx_sw_bytes fx_sw_user; |
| 165 | u64 mask; | 165 | u64 mask; |
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index c02343594b4d..d3ec292f00f2 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile | |||
| @@ -7,8 +7,8 @@ common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ | |||
| 7 | ifeq ($(CONFIG_KVM_TRACE),y) | 7 | ifeq ($(CONFIG_KVM_TRACE),y) |
| 8 | common-objs += $(addprefix ../../../virt/kvm/, kvm_trace.o) | 8 | common-objs += $(addprefix ../../../virt/kvm/, kvm_trace.o) |
| 9 | endif | 9 | endif |
| 10 | ifeq ($(CONFIG_DMAR),y) | 10 | ifeq ($(CONFIG_IOMMU_API),y) |
| 11 | common-objs += $(addprefix ../../../virt/kvm/, vtd.o) | 11 | common-objs += $(addprefix ../../../virt/kvm/, iommu.o) |
| 12 | endif | 12 | endif |
| 13 | 13 | ||
| 14 | EXTRA_CFLAGS += -Ivirt/kvm -Iarch/x86/kvm | 14 | EXTRA_CFLAGS += -Ivirt/kvm -Iarch/x86/kvm |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0e6aa8141dcd..cc17546a2406 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
| 35 | #include <linux/mman.h> | 35 | #include <linux/mman.h> |
| 36 | #include <linux/highmem.h> | 36 | #include <linux/highmem.h> |
| 37 | #include <linux/iommu.h> | ||
| 37 | #include <linux/intel-iommu.h> | 38 | #include <linux/intel-iommu.h> |
| 38 | 39 | ||
| 39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
| @@ -989,7 +990,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
| 989 | r = !tdp_enabled; | 990 | r = !tdp_enabled; |
| 990 | break; | 991 | break; |
| 991 | case KVM_CAP_IOMMU: | 992 | case KVM_CAP_IOMMU: |
| 992 | r = intel_iommu_found(); | 993 | r = iommu_found(); |
| 993 | break; | 994 | break; |
| 994 | default: | 995 | default: |
| 995 | r = 0; | 996 | r = 0; |
diff --git a/arch/x86/mach-default/setup.c b/arch/x86/mach-default/setup.c index 37b9ae4d44c5..df167f265622 100644 --- a/arch/x86/mach-default/setup.c +++ b/arch/x86/mach-default/setup.c | |||
| @@ -133,29 +133,28 @@ void __init time_init_hook(void) | |||
| 133 | **/ | 133 | **/ |
| 134 | void mca_nmi_hook(void) | 134 | void mca_nmi_hook(void) |
| 135 | { | 135 | { |
| 136 | /* If I recall correctly, there's a whole bunch of other things that | 136 | /* |
| 137 | * If I recall correctly, there's a whole bunch of other things that | ||
| 137 | * we can do to check for NMI problems, but that's all I know about | 138 | * we can do to check for NMI problems, but that's all I know about |
| 138 | * at the moment. | 139 | * at the moment. |
| 139 | */ | 140 | */ |
| 140 | 141 | pr_warning("NMI generated from unknown source!\n"); | |
| 141 | printk("NMI generated from unknown source!\n"); | ||
| 142 | } | 142 | } |
| 143 | #endif | 143 | #endif |
| 144 | 144 | ||
| 145 | static __init int no_ipi_broadcast(char *str) | 145 | static __init int no_ipi_broadcast(char *str) |
| 146 | { | 146 | { |
| 147 | get_option(&str, &no_broadcast); | 147 | get_option(&str, &no_broadcast); |
| 148 | printk ("Using %s mode\n", no_broadcast ? "No IPI Broadcast" : | 148 | pr_info("Using %s mode\n", |
| 149 | "IPI Broadcast"); | 149 | no_broadcast ? "No IPI Broadcast" : "IPI Broadcast"); |
| 150 | return 1; | 150 | return 1; |
| 151 | } | 151 | } |
| 152 | |||
| 153 | __setup("no_ipi_broadcast=", no_ipi_broadcast); | 152 | __setup("no_ipi_broadcast=", no_ipi_broadcast); |
| 154 | 153 | ||
| 155 | static int __init print_ipi_mode(void) | 154 | static int __init print_ipi_mode(void) |
| 156 | { | 155 | { |
| 157 | printk ("Using IPI %s mode\n", no_broadcast ? "No-Shortcut" : | 156 | pr_info("Using IPI %s mode\n", |
| 158 | "Shortcut"); | 157 | no_broadcast ? "No-Shortcut" : "Shortcut"); |
| 159 | return 0; | 158 | return 0; |
| 160 | } | 159 | } |
| 161 | 160 | ||
diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c index a5bc05492b1e..9840b7ec749a 100644 --- a/arch/x86/mach-voyager/voyager_smp.c +++ b/arch/x86/mach-voyager/voyager_smp.c | |||
| @@ -357,9 +357,8 @@ void __init find_smp_config(void) | |||
| 357 | printk("VOYAGER SMP: Boot cpu is %d\n", boot_cpu_id); | 357 | printk("VOYAGER SMP: Boot cpu is %d\n", boot_cpu_id); |
| 358 | 358 | ||
| 359 | /* initialize the CPU structures (moved from smp_boot_cpus) */ | 359 | /* initialize the CPU structures (moved from smp_boot_cpus) */ |
| 360 | for (i = 0; i < NR_CPUS; i++) { | 360 | for (i = 0; i < nr_cpu_ids; i++) |
| 361 | cpu_irq_affinity[i] = ~0; | 361 | cpu_irq_affinity[i] = ~0; |
| 362 | } | ||
| 363 | cpu_online_map = cpumask_of_cpu(boot_cpu_id); | 362 | cpu_online_map = cpumask_of_cpu(boot_cpu_id); |
| 364 | 363 | ||
| 365 | /* The boot CPU must be extended */ | 364 | /* The boot CPU must be extended */ |
| @@ -1227,7 +1226,7 @@ int setup_profiling_timer(unsigned int multiplier) | |||
| 1227 | * new values until the next timer interrupt in which they do process | 1226 | * new values until the next timer interrupt in which they do process |
| 1228 | * accounting. | 1227 | * accounting. |
| 1229 | */ | 1228 | */ |
| 1230 | for (i = 0; i < NR_CPUS; ++i) | 1229 | for (i = 0; i < nr_cpu_ids; ++i) |
| 1231 | per_cpu(prof_multiplier, i) = multiplier; | 1230 | per_cpu(prof_multiplier, i) = multiplier; |
| 1232 | 1231 | ||
| 1233 | return 0; | 1232 | return 0; |
| @@ -1257,7 +1256,7 @@ void __init voyager_smp_intr_init(void) | |||
| 1257 | int i; | 1256 | int i; |
| 1258 | 1257 | ||
| 1259 | /* initialize the per cpu irq mask to all disabled */ | 1258 | /* initialize the per cpu irq mask to all disabled */ |
| 1260 | for (i = 0; i < NR_CPUS; i++) | 1259 | for (i = 0; i < nr_cpu_ids; i++) |
| 1261 | vic_irq_mask[i] = 0xFFFF; | 1260 | vic_irq_mask[i] = 0xFFFF; |
| 1262 | 1261 | ||
| 1263 | VIC_SET_GATE(VIC_CPI_LEVEL0, vic_cpi_interrupt); | 1262 | VIC_SET_GATE(VIC_CPI_LEVEL0, vic_cpi_interrupt); |
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 1d88d2b39771..9e5752fe4d15 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | #include <linux/irq.h> | 4 | #include <linux/irq.h> |
| 5 | #include <linux/dmi.h> | 5 | #include <linux/dmi.h> |
| 6 | #include <asm/numa.h> | 6 | #include <asm/numa.h> |
| 7 | #include "pci.h" | 7 | #include <asm/pci_x86.h> |
| 8 | 8 | ||
| 9 | struct pci_root_info { | 9 | struct pci_root_info { |
| 10 | char *name; | 10 | char *name; |
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index 22e057665e55..9bb09823b362 100644 --- a/arch/x86/pci/amd_bus.c +++ b/arch/x86/pci/amd_bus.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | #include <linux/pci.h> | 2 | #include <linux/pci.h> |
| 3 | #include <linux/topology.h> | 3 | #include <linux/topology.h> |
| 4 | #include <linux/cpu.h> | 4 | #include <linux/cpu.h> |
| 5 | #include "pci.h" | 5 | #include <asm/pci_x86.h> |
| 6 | 6 | ||
| 7 | #ifdef CONFIG_X86_64 | 7 | #ifdef CONFIG_X86_64 |
| 8 | #include <asm/pci-direct.h> | 8 | #include <asm/pci-direct.h> |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index bb1a01f089e2..62ddb73e09ed 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
| @@ -14,8 +14,7 @@ | |||
| 14 | #include <asm/segment.h> | 14 | #include <asm/segment.h> |
| 15 | #include <asm/io.h> | 15 | #include <asm/io.h> |
| 16 | #include <asm/smp.h> | 16 | #include <asm/smp.h> |
| 17 | 17 | #include <asm/pci_x86.h> | |
| 18 | #include "pci.h" | ||
| 19 | 18 | ||
| 20 | unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | | 19 | unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | |
| 21 | PCI_PROBE_MMCONF; | 20 | PCI_PROBE_MMCONF; |
diff --git a/arch/x86/pci/direct.c b/arch/x86/pci/direct.c index 9a5af6c8fbe9..bd13c3e4c6db 100644 --- a/arch/x86/pci/direct.c +++ b/arch/x86/pci/direct.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | #include <linux/pci.h> | 5 | #include <linux/pci.h> |
| 6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
| 7 | #include <linux/dmi.h> | 7 | #include <linux/dmi.h> |
| 8 | #include "pci.h" | 8 | #include <asm/pci_x86.h> |
| 9 | 9 | ||
| 10 | /* | 10 | /* |
| 11 | * Functions for accessing PCI base (first 256 bytes) and extended | 11 | * Functions for accessing PCI base (first 256 bytes) and extended |
diff --git a/arch/x86/pci/early.c b/arch/x86/pci/early.c index 86631ccbc25a..f6adf2c6d751 100644 --- a/arch/x86/pci/early.c +++ b/arch/x86/pci/early.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | #include <linux/pci.h> | 2 | #include <linux/pci.h> |
| 3 | #include <asm/pci-direct.h> | 3 | #include <asm/pci-direct.h> |
| 4 | #include <asm/io.h> | 4 | #include <asm/io.h> |
| 5 | #include "pci.h" | 5 | #include <asm/pci_x86.h> |
| 6 | 6 | ||
| 7 | /* Direct PCI access. This is used for PCI accesses in early boot before | 7 | /* Direct PCI access. This is used for PCI accesses in early boot before |
| 8 | the PCI subsystem works. */ | 8 | the PCI subsystem works. */ |
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 2051dc96b8e9..7d388d5cf548 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c | |||
| @@ -6,8 +6,7 @@ | |||
| 6 | #include <linux/dmi.h> | 6 | #include <linux/dmi.h> |
| 7 | #include <linux/pci.h> | 7 | #include <linux/pci.h> |
| 8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
| 9 | #include "pci.h" | 9 | #include <asm/pci_x86.h> |
| 10 | |||
| 11 | 10 | ||
| 12 | static void __devinit pci_fixup_i450nx(struct pci_dev *d) | 11 | static void __devinit pci_fixup_i450nx(struct pci_dev *d) |
| 13 | { | 12 | { |
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 844df0cbbd3e..e51bf2cda4b0 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c | |||
| @@ -34,8 +34,8 @@ | |||
| 34 | 34 | ||
| 35 | #include <asm/pat.h> | 35 | #include <asm/pat.h> |
| 36 | #include <asm/e820.h> | 36 | #include <asm/e820.h> |
| 37 | #include <asm/pci_x86.h> | ||
| 37 | 38 | ||
| 38 | #include "pci.h" | ||
| 39 | 39 | ||
| 40 | static int | 40 | static int |
| 41 | skip_isa_ioresource_align(struct pci_dev *dev) { | 41 | skip_isa_ioresource_align(struct pci_dev *dev) { |
diff --git a/arch/x86/pci/init.c b/arch/x86/pci/init.c index d6c950f81858..bec3b048e72b 100644 --- a/arch/x86/pci/init.c +++ b/arch/x86/pci/init.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | #include <linux/pci.h> | 1 | #include <linux/pci.h> |
| 2 | #include <linux/init.h> | 2 | #include <linux/init.h> |
| 3 | #include "pci.h" | 3 | #include <asm/pci_x86.h> |
| 4 | 4 | ||
| 5 | /* arch_initcall has too random ordering, so call the initializers | 5 | /* arch_initcall has too random ordering, so call the initializers |
| 6 | in the right sequence from here. */ | 6 | in the right sequence from here. */ |
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index bf69dbe08bff..373b9afe6d44 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c | |||
| @@ -16,8 +16,7 @@ | |||
| 16 | #include <asm/io_apic.h> | 16 | #include <asm/io_apic.h> |
| 17 | #include <linux/irq.h> | 17 | #include <linux/irq.h> |
| 18 | #include <linux/acpi.h> | 18 | #include <linux/acpi.h> |
| 19 | 19 | #include <asm/pci_x86.h> | |
| 20 | #include "pci.h" | ||
| 21 | 20 | ||
| 22 | #define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24)) | 21 | #define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24)) |
| 23 | #define PIRQ_VERSION 0x0100 | 22 | #define PIRQ_VERSION 0x0100 |
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c index b722dd481b39..f1065b129e9c 100644 --- a/arch/x86/pci/legacy.c +++ b/arch/x86/pci/legacy.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | */ | 3 | */ |
| 4 | #include <linux/init.h> | 4 | #include <linux/init.h> |
| 5 | #include <linux/pci.h> | 5 | #include <linux/pci.h> |
| 6 | #include "pci.h" | 6 | #include <asm/pci_x86.h> |
| 7 | 7 | ||
| 8 | /* | 8 | /* |
| 9 | * Discover remaining PCI buses in case there are peer host bridges. | 9 | * Discover remaining PCI buses in case there are peer host bridges. |
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 654a2234f8f3..89bf9242c80a 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
| @@ -15,8 +15,7 @@ | |||
| 15 | #include <linux/acpi.h> | 15 | #include <linux/acpi.h> |
| 16 | #include <linux/bitmap.h> | 16 | #include <linux/bitmap.h> |
| 17 | #include <asm/e820.h> | 17 | #include <asm/e820.h> |
| 18 | 18 | #include <asm/pci_x86.h> | |
| 19 | #include "pci.h" | ||
| 20 | 19 | ||
| 21 | /* aperture is up to 256MB but BIOS may reserve less */ | 20 | /* aperture is up to 256MB but BIOS may reserve less */ |
| 22 | #define MMCONFIG_APER_MIN (2 * 1024*1024) | 21 | #define MMCONFIG_APER_MIN (2 * 1024*1024) |
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c index f3c761dce695..8b2d561046a3 100644 --- a/arch/x86/pci/mmconfig_32.c +++ b/arch/x86/pci/mmconfig_32.c | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/acpi.h> | 14 | #include <linux/acpi.h> |
| 15 | #include <asm/e820.h> | 15 | #include <asm/e820.h> |
| 16 | #include "pci.h" | 16 | #include <asm/pci_x86.h> |
| 17 | 17 | ||
| 18 | /* Assume systems with more busses have correct MCFG */ | 18 | /* Assume systems with more busses have correct MCFG */ |
| 19 | #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) | 19 | #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) |
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c index a1994163c99d..30007ffc8e11 100644 --- a/arch/x86/pci/mmconfig_64.c +++ b/arch/x86/pci/mmconfig_64.c | |||
| @@ -10,8 +10,7 @@ | |||
| 10 | #include <linux/acpi.h> | 10 | #include <linux/acpi.h> |
| 11 | #include <linux/bitmap.h> | 11 | #include <linux/bitmap.h> |
| 12 | #include <asm/e820.h> | 12 | #include <asm/e820.h> |
| 13 | 13 | #include <asm/pci_x86.h> | |
| 14 | #include "pci.h" | ||
| 15 | 14 | ||
| 16 | /* Static virtual mapping of the MMCONFIG aperture */ | 15 | /* Static virtual mapping of the MMCONFIG aperture */ |
| 17 | struct mmcfg_virt { | 16 | struct mmcfg_virt { |
diff --git a/arch/x86/pci/numaq_32.c b/arch/x86/pci/numaq_32.c index 1177845d3186..2089354968a2 100644 --- a/arch/x86/pci/numaq_32.c +++ b/arch/x86/pci/numaq_32.c | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | #include <linux/nodemask.h> | 7 | #include <linux/nodemask.h> |
| 8 | #include <mach_apic.h> | 8 | #include <mach_apic.h> |
| 9 | #include <asm/mpspec.h> | 9 | #include <asm/mpspec.h> |
| 10 | #include "pci.h" | 10 | #include <asm/pci_x86.h> |
| 11 | 11 | ||
| 12 | #define XQUAD_PORTIO_BASE 0xfe400000 | 12 | #define XQUAD_PORTIO_BASE 0xfe400000 |
| 13 | #define XQUAD_PORTIO_QUAD 0x40000 /* 256k per quad. */ | 13 | #define XQUAD_PORTIO_QUAD 0x40000 /* 256k per quad. */ |
diff --git a/arch/x86/pci/olpc.c b/arch/x86/pci/olpc.c index e11e9e803d5f..b889d824f7c6 100644 --- a/arch/x86/pci/olpc.c +++ b/arch/x86/pci/olpc.c | |||
| @@ -29,7 +29,7 @@ | |||
| 29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
| 30 | #include <asm/olpc.h> | 30 | #include <asm/olpc.h> |
| 31 | #include <asm/geode.h> | 31 | #include <asm/geode.h> |
| 32 | #include "pci.h" | 32 | #include <asm/pci_x86.h> |
| 33 | 33 | ||
| 34 | /* | 34 | /* |
| 35 | * In the tables below, the first two line (8 longwords) are the | 35 | * In the tables below, the first two line (8 longwords) are the |
diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c index 37472fc6f729..b82cae970dfd 100644 --- a/arch/x86/pci/pcbios.c +++ b/arch/x86/pci/pcbios.c | |||
| @@ -6,9 +6,8 @@ | |||
| 6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
| 7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
| 8 | #include <linux/uaccess.h> | 8 | #include <linux/uaccess.h> |
| 9 | #include "pci.h" | 9 | #include <asm/pci_x86.h> |
| 10 | #include "pci-functions.h" | 10 | #include <asm/mach-default/pci-functions.h> |
| 11 | |||
| 12 | 11 | ||
| 13 | /* BIOS32 signature: "_32_" */ | 12 | /* BIOS32 signature: "_32_" */ |
| 14 | #define BIOS32_SIGNATURE (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24)) | 13 | #define BIOS32_SIGNATURE (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24)) |
diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c index 42f4cb19faca..16d0c0eb0d19 100644 --- a/arch/x86/pci/visws.c +++ b/arch/x86/pci/visws.c | |||
| @@ -9,11 +9,10 @@ | |||
| 9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
| 10 | 10 | ||
| 11 | #include <asm/setup.h> | 11 | #include <asm/setup.h> |
| 12 | #include <asm/pci_x86.h> | ||
| 12 | #include <asm/visws/cobalt.h> | 13 | #include <asm/visws/cobalt.h> |
| 13 | #include <asm/visws/lithium.h> | 14 | #include <asm/visws/lithium.h> |
| 14 | 15 | ||
| 15 | #include "pci.h" | ||
| 16 | |||
| 17 | static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; } | 16 | static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; } |
| 18 | static void pci_visws_disable_irq(struct pci_dev *dev) { } | 17 | static void pci_visws_disable_irq(struct pci_dev *dev) { } |
| 19 | 18 | ||
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 65d75a6be0ba..14f240623497 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c | |||
| @@ -132,8 +132,7 @@ static void do_stolen_accounting(void) | |||
| 132 | *snap = state; | 132 | *snap = state; |
| 133 | 133 | ||
| 134 | /* Add the appropriate number of ticks of stolen time, | 134 | /* Add the appropriate number of ticks of stolen time, |
| 135 | including any left-overs from last time. Passing NULL to | 135 | including any left-overs from last time. */ |
| 136 | account_steal_time accounts the time as stolen. */ | ||
| 137 | stolen = runnable + offline + __get_cpu_var(residual_stolen); | 136 | stolen = runnable + offline + __get_cpu_var(residual_stolen); |
| 138 | 137 | ||
| 139 | if (stolen < 0) | 138 | if (stolen < 0) |
| @@ -141,11 +140,10 @@ static void do_stolen_accounting(void) | |||
| 141 | 140 | ||
| 142 | ticks = iter_div_u64_rem(stolen, NS_PER_TICK, &stolen); | 141 | ticks = iter_div_u64_rem(stolen, NS_PER_TICK, &stolen); |
| 143 | __get_cpu_var(residual_stolen) = stolen; | 142 | __get_cpu_var(residual_stolen) = stolen; |
| 144 | account_steal_time(NULL, ticks); | 143 | account_steal_ticks(ticks); |
| 145 | 144 | ||
| 146 | /* Add the appropriate number of ticks of blocked time, | 145 | /* Add the appropriate number of ticks of blocked time, |
| 147 | including any left-overs from last time. Passing idle to | 146 | including any left-overs from last time. */ |
| 148 | account_steal_time accounts the time as idle/wait. */ | ||
| 149 | blocked += __get_cpu_var(residual_blocked); | 147 | blocked += __get_cpu_var(residual_blocked); |
| 150 | 148 | ||
| 151 | if (blocked < 0) | 149 | if (blocked < 0) |
| @@ -153,7 +151,7 @@ static void do_stolen_accounting(void) | |||
| 153 | 151 | ||
| 154 | ticks = iter_div_u64_rem(blocked, NS_PER_TICK, &blocked); | 152 | ticks = iter_div_u64_rem(blocked, NS_PER_TICK, &blocked); |
| 155 | __get_cpu_var(residual_blocked) = blocked; | 153 | __get_cpu_var(residual_blocked) = blocked; |
| 156 | account_steal_time(idle_task(smp_processor_id()), ticks); | 154 | account_idle_ticks(ticks); |
| 157 | } | 155 | } |
| 158 | 156 | ||
| 159 | /* | 157 | /* |
diff --git a/block/blk.h b/block/blk.h index d2e49af90db5..6e1ed40534e9 100644 --- a/block/blk.h +++ b/block/blk.h | |||
| @@ -99,8 +99,8 @@ static inline int queue_congestion_off_threshold(struct request_queue *q) | |||
| 99 | static inline int blk_cpu_to_group(int cpu) | 99 | static inline int blk_cpu_to_group(int cpu) |
| 100 | { | 100 | { |
| 101 | #ifdef CONFIG_SCHED_MC | 101 | #ifdef CONFIG_SCHED_MC |
| 102 | cpumask_t mask = cpu_coregroup_map(cpu); | 102 | const struct cpumask *mask = cpu_coregroup_mask(cpu); |
| 103 | return first_cpu(mask); | 103 | return cpumask_first(mask); |
| 104 | #elif defined(CONFIG_SCHED_SMT) | 104 | #elif defined(CONFIG_SCHED_SMT) |
| 105 | return first_cpu(per_cpu(cpu_sibling_map, cpu)); | 105 | return first_cpu(per_cpu(cpu_sibling_map, cpu)); |
| 106 | #else | 106 | #else |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 34948362f41d..0cc2fd31e376 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
| @@ -826,6 +826,11 @@ static int acpi_processor_add(struct acpi_device *device) | |||
| 826 | if (!pr) | 826 | if (!pr) |
| 827 | return -ENOMEM; | 827 | return -ENOMEM; |
| 828 | 828 | ||
| 829 | if (!alloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) { | ||
| 830 | kfree(pr); | ||
| 831 | return -ENOMEM; | ||
| 832 | } | ||
| 833 | |||
| 829 | pr->handle = device->handle; | 834 | pr->handle = device->handle; |
| 830 | strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME); | 835 | strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME); |
| 831 | strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); | 836 | strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); |
| @@ -845,10 +850,8 @@ static int acpi_processor_remove(struct acpi_device *device, int type) | |||
| 845 | 850 | ||
| 846 | pr = acpi_driver_data(device); | 851 | pr = acpi_driver_data(device); |
| 847 | 852 | ||
| 848 | if (pr->id >= nr_cpu_ids) { | 853 | if (pr->id >= nr_cpu_ids) |
| 849 | kfree(pr); | 854 | goto free; |
| 850 | return 0; | ||
| 851 | } | ||
| 852 | 855 | ||
| 853 | if (type == ACPI_BUS_REMOVAL_EJECT) { | 856 | if (type == ACPI_BUS_REMOVAL_EJECT) { |
| 854 | if (acpi_processor_handle_eject(pr)) | 857 | if (acpi_processor_handle_eject(pr)) |
| @@ -873,6 +876,9 @@ static int acpi_processor_remove(struct acpi_device *device, int type) | |||
| 873 | 876 | ||
| 874 | per_cpu(processors, pr->id) = NULL; | 877 | per_cpu(processors, pr->id) = NULL; |
| 875 | per_cpu(processor_device_array, pr->id) = NULL; | 878 | per_cpu(processor_device_array, pr->id) = NULL; |
| 879 | |||
| 880 | free: | ||
| 881 | free_cpumask_var(pr->throttling.shared_cpu_map); | ||
| 876 | kfree(pr); | 882 | kfree(pr); |
| 877 | 883 | ||
| 878 | return 0; | 884 | return 0; |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 0d7b772bef50..846e227592d4 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
| @@ -588,12 +588,15 @@ int acpi_processor_preregister_performance( | |||
| 588 | int count, count_target; | 588 | int count, count_target; |
| 589 | int retval = 0; | 589 | int retval = 0; |
| 590 | unsigned int i, j; | 590 | unsigned int i, j; |
| 591 | cpumask_t covered_cpus; | 591 | cpumask_var_t covered_cpus; |
| 592 | struct acpi_processor *pr; | 592 | struct acpi_processor *pr; |
| 593 | struct acpi_psd_package *pdomain; | 593 | struct acpi_psd_package *pdomain; |
| 594 | struct acpi_processor *match_pr; | 594 | struct acpi_processor *match_pr; |
| 595 | struct acpi_psd_package *match_pdomain; | 595 | struct acpi_psd_package *match_pdomain; |
| 596 | 596 | ||
| 597 | if (!alloc_cpumask_var(&covered_cpus, GFP_KERNEL)) | ||
| 598 | return -ENOMEM; | ||
| 599 | |||
| 597 | mutex_lock(&performance_mutex); | 600 | mutex_lock(&performance_mutex); |
| 598 | 601 | ||
| 599 | retval = 0; | 602 | retval = 0; |
| @@ -617,7 +620,7 @@ int acpi_processor_preregister_performance( | |||
| 617 | } | 620 | } |
| 618 | 621 | ||
| 619 | pr->performance = percpu_ptr(performance, i); | 622 | pr->performance = percpu_ptr(performance, i); |
| 620 | cpu_set(i, pr->performance->shared_cpu_map); | 623 | cpumask_set_cpu(i, pr->performance->shared_cpu_map); |
| 621 | if (acpi_processor_get_psd(pr)) { | 624 | if (acpi_processor_get_psd(pr)) { |
| 622 | retval = -EINVAL; | 625 | retval = -EINVAL; |
| 623 | continue; | 626 | continue; |
| @@ -650,18 +653,18 @@ int acpi_processor_preregister_performance( | |||
| 650 | } | 653 | } |
| 651 | } | 654 | } |
| 652 | 655 | ||
| 653 | cpus_clear(covered_cpus); | 656 | cpumask_clear(covered_cpus); |
| 654 | for_each_possible_cpu(i) { | 657 | for_each_possible_cpu(i) { |
| 655 | pr = per_cpu(processors, i); | 658 | pr = per_cpu(processors, i); |
| 656 | if (!pr) | 659 | if (!pr) |
| 657 | continue; | 660 | continue; |
| 658 | 661 | ||
| 659 | if (cpu_isset(i, covered_cpus)) | 662 | if (cpumask_test_cpu(i, covered_cpus)) |
| 660 | continue; | 663 | continue; |
| 661 | 664 | ||
| 662 | pdomain = &(pr->performance->domain_info); | 665 | pdomain = &(pr->performance->domain_info); |
| 663 | cpu_set(i, pr->performance->shared_cpu_map); | 666 | cpumask_set_cpu(i, pr->performance->shared_cpu_map); |
| 664 | cpu_set(i, covered_cpus); | 667 | cpumask_set_cpu(i, covered_cpus); |
| 665 | if (pdomain->num_processors <= 1) | 668 | if (pdomain->num_processors <= 1) |
| 666 | continue; | 669 | continue; |
| 667 | 670 | ||
| @@ -699,8 +702,8 @@ int acpi_processor_preregister_performance( | |||
| 699 | goto err_ret; | 702 | goto err_ret; |
| 700 | } | 703 | } |
| 701 | 704 | ||
| 702 | cpu_set(j, covered_cpus); | 705 | cpumask_set_cpu(j, covered_cpus); |
| 703 | cpu_set(j, pr->performance->shared_cpu_map); | 706 | cpumask_set_cpu(j, pr->performance->shared_cpu_map); |
| 704 | count++; | 707 | count++; |
| 705 | } | 708 | } |
| 706 | 709 | ||
| @@ -718,8 +721,8 @@ int acpi_processor_preregister_performance( | |||
| 718 | 721 | ||
| 719 | match_pr->performance->shared_type = | 722 | match_pr->performance->shared_type = |
| 720 | pr->performance->shared_type; | 723 | pr->performance->shared_type; |
| 721 | match_pr->performance->shared_cpu_map = | 724 | cpumask_copy(match_pr->performance->shared_cpu_map, |
| 722 | pr->performance->shared_cpu_map; | 725 | pr->performance->shared_cpu_map); |
| 723 | } | 726 | } |
| 724 | } | 727 | } |
| 725 | 728 | ||
| @@ -731,14 +734,15 @@ err_ret: | |||
| 731 | 734 | ||
| 732 | /* Assume no coordination on any error parsing domain info */ | 735 | /* Assume no coordination on any error parsing domain info */ |
| 733 | if (retval) { | 736 | if (retval) { |
| 734 | cpus_clear(pr->performance->shared_cpu_map); | 737 | cpumask_clear(pr->performance->shared_cpu_map); |
| 735 | cpu_set(i, pr->performance->shared_cpu_map); | 738 | cpumask_set_cpu(i, pr->performance->shared_cpu_map); |
| 736 | pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ALL; | 739 | pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ALL; |
| 737 | } | 740 | } |
| 738 | pr->performance = NULL; /* Will be set for real in register */ | 741 | pr->performance = NULL; /* Will be set for real in register */ |
| 739 | } | 742 | } |
| 740 | 743 | ||
| 741 | mutex_unlock(&performance_mutex); | 744 | mutex_unlock(&performance_mutex); |
| 745 | free_cpumask_var(covered_cpus); | ||
| 742 | return retval; | 746 | return retval; |
| 743 | } | 747 | } |
| 744 | EXPORT_SYMBOL(acpi_processor_preregister_performance); | 748 | EXPORT_SYMBOL(acpi_processor_preregister_performance); |
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index a0c38c94a8a0..d27838171f4a 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
| @@ -61,11 +61,14 @@ static int acpi_processor_update_tsd_coord(void) | |||
| 61 | int count, count_target; | 61 | int count, count_target; |
| 62 | int retval = 0; | 62 | int retval = 0; |
| 63 | unsigned int i, j; | 63 | unsigned int i, j; |
| 64 | cpumask_t covered_cpus; | 64 | cpumask_var_t covered_cpus; |
| 65 | struct acpi_processor *pr, *match_pr; | 65 | struct acpi_processor *pr, *match_pr; |
| 66 | struct acpi_tsd_package *pdomain, *match_pdomain; | 66 | struct acpi_tsd_package *pdomain, *match_pdomain; |
| 67 | struct acpi_processor_throttling *pthrottling, *match_pthrottling; | 67 | struct acpi_processor_throttling *pthrottling, *match_pthrottling; |
| 68 | 68 | ||
| 69 | if (!alloc_cpumask_var(&covered_cpus, GFP_KERNEL)) | ||
| 70 | return -ENOMEM; | ||
| 71 | |||
| 69 | /* | 72 | /* |
| 70 | * Now that we have _TSD data from all CPUs, lets setup T-state | 73 | * Now that we have _TSD data from all CPUs, lets setup T-state |
| 71 | * coordination between all CPUs. | 74 | * coordination between all CPUs. |
| @@ -91,19 +94,19 @@ static int acpi_processor_update_tsd_coord(void) | |||
| 91 | if (retval) | 94 | if (retval) |
| 92 | goto err_ret; | 95 | goto err_ret; |
| 93 | 96 | ||
| 94 | cpus_clear(covered_cpus); | 97 | cpumask_clear(covered_cpus); |
| 95 | for_each_possible_cpu(i) { | 98 | for_each_possible_cpu(i) { |
| 96 | pr = per_cpu(processors, i); | 99 | pr = per_cpu(processors, i); |
| 97 | if (!pr) | 100 | if (!pr) |
| 98 | continue; | 101 | continue; |
| 99 | 102 | ||
| 100 | if (cpu_isset(i, covered_cpus)) | 103 | if (cpumask_test_cpu(i, covered_cpus)) |
| 101 | continue; | 104 | continue; |
| 102 | pthrottling = &pr->throttling; | 105 | pthrottling = &pr->throttling; |
| 103 | 106 | ||
| 104 | pdomain = &(pthrottling->domain_info); | 107 | pdomain = &(pthrottling->domain_info); |
| 105 | cpu_set(i, pthrottling->shared_cpu_map); | 108 | cpumask_set_cpu(i, pthrottling->shared_cpu_map); |
| 106 | cpu_set(i, covered_cpus); | 109 | cpumask_set_cpu(i, covered_cpus); |
| 107 | /* | 110 | /* |
| 108 | * If the number of processor in the TSD domain is 1, it is | 111 | * If the number of processor in the TSD domain is 1, it is |
| 109 | * unnecessary to parse the coordination for this CPU. | 112 | * unnecessary to parse the coordination for this CPU. |
| @@ -144,8 +147,8 @@ static int acpi_processor_update_tsd_coord(void) | |||
| 144 | goto err_ret; | 147 | goto err_ret; |
| 145 | } | 148 | } |
| 146 | 149 | ||
| 147 | cpu_set(j, covered_cpus); | 150 | cpumask_set_cpu(j, covered_cpus); |
| 148 | cpu_set(j, pthrottling->shared_cpu_map); | 151 | cpumask_set_cpu(j, pthrottling->shared_cpu_map); |
| 149 | count++; | 152 | count++; |
| 150 | } | 153 | } |
| 151 | for_each_possible_cpu(j) { | 154 | for_each_possible_cpu(j) { |
| @@ -165,12 +168,14 @@ static int acpi_processor_update_tsd_coord(void) | |||
| 165 | * If some CPUS have the same domain, they | 168 | * If some CPUS have the same domain, they |
| 166 | * will have the same shared_cpu_map. | 169 | * will have the same shared_cpu_map. |
| 167 | */ | 170 | */ |
| 168 | match_pthrottling->shared_cpu_map = | 171 | cpumask_copy(match_pthrottling->shared_cpu_map, |
| 169 | pthrottling->shared_cpu_map; | 172 | pthrottling->shared_cpu_map); |
| 170 | } | 173 | } |
| 171 | } | 174 | } |
| 172 | 175 | ||
| 173 | err_ret: | 176 | err_ret: |
| 177 | free_cpumask_var(covered_cpus); | ||
| 178 | |||
| 174 | for_each_possible_cpu(i) { | 179 | for_each_possible_cpu(i) { |
| 175 | pr = per_cpu(processors, i); | 180 | pr = per_cpu(processors, i); |
| 176 | if (!pr) | 181 | if (!pr) |
| @@ -182,8 +187,8 @@ err_ret: | |||
| 182 | */ | 187 | */ |
| 183 | if (retval) { | 188 | if (retval) { |
| 184 | pthrottling = &(pr->throttling); | 189 | pthrottling = &(pr->throttling); |
| 185 | cpus_clear(pthrottling->shared_cpu_map); | 190 | cpumask_clear(pthrottling->shared_cpu_map); |
| 186 | cpu_set(i, pthrottling->shared_cpu_map); | 191 | cpumask_set_cpu(i, pthrottling->shared_cpu_map); |
| 187 | pthrottling->shared_type = DOMAIN_COORD_TYPE_SW_ALL; | 192 | pthrottling->shared_type = DOMAIN_COORD_TYPE_SW_ALL; |
| 188 | } | 193 | } |
| 189 | } | 194 | } |
| @@ -567,7 +572,7 @@ static int acpi_processor_get_tsd(struct acpi_processor *pr) | |||
| 567 | pthrottling = &pr->throttling; | 572 | pthrottling = &pr->throttling; |
| 568 | pthrottling->tsd_valid_flag = 1; | 573 | pthrottling->tsd_valid_flag = 1; |
| 569 | pthrottling->shared_type = pdomain->coord_type; | 574 | pthrottling->shared_type = pdomain->coord_type; |
| 570 | cpu_set(pr->id, pthrottling->shared_cpu_map); | 575 | cpumask_set_cpu(pr->id, pthrottling->shared_cpu_map); |
| 571 | /* | 576 | /* |
| 572 | * If the coordination type is not defined in ACPI spec, | 577 | * If the coordination type is not defined in ACPI spec, |
| 573 | * the tsd_valid_flag will be clear and coordination type | 578 | * the tsd_valid_flag will be clear and coordination type |
| @@ -826,7 +831,7 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr) | |||
| 826 | 831 | ||
| 827 | static int acpi_processor_get_throttling(struct acpi_processor *pr) | 832 | static int acpi_processor_get_throttling(struct acpi_processor *pr) |
| 828 | { | 833 | { |
| 829 | cpumask_t saved_mask; | 834 | cpumask_var_t saved_mask; |
| 830 | int ret; | 835 | int ret; |
| 831 | 836 | ||
| 832 | if (!pr) | 837 | if (!pr) |
| @@ -834,14 +839,20 @@ static int acpi_processor_get_throttling(struct acpi_processor *pr) | |||
| 834 | 839 | ||
| 835 | if (!pr->flags.throttling) | 840 | if (!pr->flags.throttling) |
| 836 | return -ENODEV; | 841 | return -ENODEV; |
| 842 | |||
| 843 | if (!alloc_cpumask_var(&saved_mask, GFP_KERNEL)) | ||
| 844 | return -ENOMEM; | ||
| 845 | |||
| 837 | /* | 846 | /* |
| 838 | * Migrate task to the cpu pointed by pr. | 847 | * Migrate task to the cpu pointed by pr. |
| 839 | */ | 848 | */ |
| 840 | saved_mask = current->cpus_allowed; | 849 | cpumask_copy(saved_mask, ¤t->cpus_allowed); |
| 841 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(pr->id)); | 850 | /* FIXME: use work_on_cpu() */ |
| 851 | set_cpus_allowed_ptr(current, cpumask_of(pr->id)); | ||
| 842 | ret = pr->throttling.acpi_processor_get_throttling(pr); | 852 | ret = pr->throttling.acpi_processor_get_throttling(pr); |
| 843 | /* restore the previous state */ | 853 | /* restore the previous state */ |
| 844 | set_cpus_allowed_ptr(current, &saved_mask); | 854 | set_cpus_allowed_ptr(current, saved_mask); |
| 855 | free_cpumask_var(saved_mask); | ||
| 845 | 856 | ||
| 846 | return ret; | 857 | return ret; |
| 847 | } | 858 | } |
| @@ -986,13 +997,13 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr, | |||
| 986 | 997 | ||
| 987 | int acpi_processor_set_throttling(struct acpi_processor *pr, int state) | 998 | int acpi_processor_set_throttling(struct acpi_processor *pr, int state) |
| 988 | { | 999 | { |
| 989 | cpumask_t saved_mask; | 1000 | cpumask_var_t saved_mask; |
| 990 | int ret = 0; | 1001 | int ret = 0; |
| 991 | unsigned int i; | 1002 | unsigned int i; |
| 992 | struct acpi_processor *match_pr; | 1003 | struct acpi_processor *match_pr; |
| 993 | struct acpi_processor_throttling *p_throttling; | 1004 | struct acpi_processor_throttling *p_throttling; |
| 994 | struct throttling_tstate t_state; | 1005 | struct throttling_tstate t_state; |
| 995 | cpumask_t online_throttling_cpus; | 1006 | cpumask_var_t online_throttling_cpus; |
| 996 | 1007 | ||
| 997 | if (!pr) | 1008 | if (!pr) |
| 998 | return -EINVAL; | 1009 | return -EINVAL; |
| @@ -1003,17 +1014,25 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state) | |||
| 1003 | if ((state < 0) || (state > (pr->throttling.state_count - 1))) | 1014 | if ((state < 0) || (state > (pr->throttling.state_count - 1))) |
| 1004 | return -EINVAL; | 1015 | return -EINVAL; |
| 1005 | 1016 | ||
| 1006 | saved_mask = current->cpus_allowed; | 1017 | if (!alloc_cpumask_var(&saved_mask, GFP_KERNEL)) |
| 1018 | return -ENOMEM; | ||
| 1019 | |||
| 1020 | if (!alloc_cpumask_var(&online_throttling_cpus, GFP_KERNEL)) { | ||
| 1021 | free_cpumask_var(saved_mask); | ||
| 1022 | return -ENOMEM; | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | cpumask_copy(saved_mask, ¤t->cpus_allowed); | ||
| 1007 | t_state.target_state = state; | 1026 | t_state.target_state = state; |
| 1008 | p_throttling = &(pr->throttling); | 1027 | p_throttling = &(pr->throttling); |
| 1009 | cpus_and(online_throttling_cpus, cpu_online_map, | 1028 | cpumask_and(online_throttling_cpus, cpu_online_mask, |
| 1010 | p_throttling->shared_cpu_map); | 1029 | p_throttling->shared_cpu_map); |
| 1011 | /* | 1030 | /* |
| 1012 | * The throttling notifier will be called for every | 1031 | * The throttling notifier will be called for every |
| 1013 | * affected cpu in order to get one proper T-state. | 1032 | * affected cpu in order to get one proper T-state. |
| 1014 | * The notifier event is THROTTLING_PRECHANGE. | 1033 | * The notifier event is THROTTLING_PRECHANGE. |
| 1015 | */ | 1034 | */ |
| 1016 | for_each_cpu_mask_nr(i, online_throttling_cpus) { | 1035 | for_each_cpu(i, online_throttling_cpus) { |
| 1017 | t_state.cpu = i; | 1036 | t_state.cpu = i; |
| 1018 | acpi_processor_throttling_notifier(THROTTLING_PRECHANGE, | 1037 | acpi_processor_throttling_notifier(THROTTLING_PRECHANGE, |
| 1019 | &t_state); | 1038 | &t_state); |
| @@ -1025,7 +1044,8 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state) | |||
| 1025 | * it can be called only for the cpu pointed by pr. | 1044 | * it can be called only for the cpu pointed by pr. |
| 1026 | */ | 1045 | */ |
| 1027 | if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) { | 1046 | if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) { |
| 1028 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(pr->id)); | 1047 | /* FIXME: use work_on_cpu() */ |
| 1048 | set_cpus_allowed_ptr(current, cpumask_of(pr->id)); | ||
| 1029 | ret = p_throttling->acpi_processor_set_throttling(pr, | 1049 | ret = p_throttling->acpi_processor_set_throttling(pr, |
| 1030 | t_state.target_state); | 1050 | t_state.target_state); |
| 1031 | } else { | 1051 | } else { |
| @@ -1034,7 +1054,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state) | |||
| 1034 | * it is necessary to set T-state for every affected | 1054 | * it is necessary to set T-state for every affected |
| 1035 | * cpus. | 1055 | * cpus. |
| 1036 | */ | 1056 | */ |
| 1037 | for_each_cpu_mask_nr(i, online_throttling_cpus) { | 1057 | for_each_cpu(i, online_throttling_cpus) { |
| 1038 | match_pr = per_cpu(processors, i); | 1058 | match_pr = per_cpu(processors, i); |
| 1039 | /* | 1059 | /* |
| 1040 | * If the pointer is invalid, we will report the | 1060 | * If the pointer is invalid, we will report the |
| @@ -1056,7 +1076,8 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state) | |||
| 1056 | continue; | 1076 | continue; |
| 1057 | } | 1077 | } |
| 1058 | t_state.cpu = i; | 1078 | t_state.cpu = i; |
| 1059 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(i)); | 1079 | /* FIXME: use work_on_cpu() */ |
| 1080 | set_cpus_allowed_ptr(current, cpumask_of(i)); | ||
| 1060 | ret = match_pr->throttling. | 1081 | ret = match_pr->throttling. |
| 1061 | acpi_processor_set_throttling( | 1082 | acpi_processor_set_throttling( |
| 1062 | match_pr, t_state.target_state); | 1083 | match_pr, t_state.target_state); |
| @@ -1068,13 +1089,16 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state) | |||
| 1068 | * affected cpu to update the T-states. | 1089 | * affected cpu to update the T-states. |
| 1069 | * The notifier event is THROTTLING_POSTCHANGE | 1090 | * The notifier event is THROTTLING_POSTCHANGE |
| 1070 | */ | 1091 | */ |
| 1071 | for_each_cpu_mask_nr(i, online_throttling_cpus) { | 1092 | for_each_cpu(i, online_throttling_cpus) { |
| 1072 | t_state.cpu = i; | 1093 | t_state.cpu = i; |
| 1073 | acpi_processor_throttling_notifier(THROTTLING_POSTCHANGE, | 1094 | acpi_processor_throttling_notifier(THROTTLING_POSTCHANGE, |
| 1074 | &t_state); | 1095 | &t_state); |
| 1075 | } | 1096 | } |
| 1076 | /* restore the previous state */ | 1097 | /* restore the previous state */ |
| 1077 | set_cpus_allowed_ptr(current, &saved_mask); | 1098 | /* FIXME: use work_on_cpu() */ |
| 1099 | set_cpus_allowed_ptr(current, saved_mask); | ||
| 1100 | free_cpumask_var(online_throttling_cpus); | ||
| 1101 | free_cpumask_var(saved_mask); | ||
| 1078 | return ret; | 1102 | return ret; |
| 1079 | } | 1103 | } |
| 1080 | 1104 | ||
| @@ -1120,7 +1144,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) | |||
| 1120 | if (acpi_processor_get_tsd(pr)) { | 1144 | if (acpi_processor_get_tsd(pr)) { |
| 1121 | pthrottling = &pr->throttling; | 1145 | pthrottling = &pr->throttling; |
| 1122 | pthrottling->tsd_valid_flag = 0; | 1146 | pthrottling->tsd_valid_flag = 0; |
| 1123 | cpu_set(pr->id, pthrottling->shared_cpu_map); | 1147 | cpumask_set_cpu(pr->id, pthrottling->shared_cpu_map); |
| 1124 | pthrottling->shared_type = DOMAIN_COORD_TYPE_SW_ALL; | 1148 | pthrottling->shared_type = DOMAIN_COORD_TYPE_SW_ALL; |
| 1125 | } | 1149 | } |
| 1126 | 1150 | ||
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index c66637392bbc..b5b8ba512b28 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile | |||
| @@ -11,6 +11,7 @@ obj-$(CONFIG_FW_LOADER) += firmware_class.o | |||
| 11 | obj-$(CONFIG_NUMA) += node.o | 11 | obj-$(CONFIG_NUMA) += node.o |
| 12 | obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o | 12 | obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o |
| 13 | obj-$(CONFIG_SMP) += topology.o | 13 | obj-$(CONFIG_SMP) += topology.o |
| 14 | obj-$(CONFIG_IOMMU_API) += iommu.o | ||
| 14 | ifeq ($(CONFIG_SYSFS),y) | 15 | ifeq ($(CONFIG_SYSFS),y) |
| 15 | obj-$(CONFIG_MODULES) += module.o | 16 | obj-$(CONFIG_MODULES) += module.o |
| 16 | endif | 17 | endif |
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 4259072f5bd0..719ee5c1c8d9 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
| @@ -128,10 +128,54 @@ print_cpus_func(online); | |||
| 128 | print_cpus_func(possible); | 128 | print_cpus_func(possible); |
| 129 | print_cpus_func(present); | 129 | print_cpus_func(present); |
| 130 | 130 | ||
| 131 | /* | ||
| 132 | * Print values for NR_CPUS and offlined cpus | ||
| 133 | */ | ||
| 134 | static ssize_t print_cpus_kernel_max(struct sysdev_class *class, char *buf) | ||
| 135 | { | ||
| 136 | int n = snprintf(buf, PAGE_SIZE-2, "%d\n", NR_CPUS - 1); | ||
| 137 | return n; | ||
| 138 | } | ||
| 139 | static SYSDEV_CLASS_ATTR(kernel_max, 0444, print_cpus_kernel_max, NULL); | ||
| 140 | |||
| 141 | /* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */ | ||
| 142 | unsigned int total_cpus; | ||
| 143 | |||
| 144 | static ssize_t print_cpus_offline(struct sysdev_class *class, char *buf) | ||
| 145 | { | ||
| 146 | int n = 0, len = PAGE_SIZE-2; | ||
| 147 | cpumask_var_t offline; | ||
| 148 | |||
| 149 | /* display offline cpus < nr_cpu_ids */ | ||
| 150 | if (!alloc_cpumask_var(&offline, GFP_KERNEL)) | ||
| 151 | return -ENOMEM; | ||
| 152 | cpumask_complement(offline, cpu_online_mask); | ||
| 153 | n = cpulist_scnprintf(buf, len, offline); | ||
| 154 | free_cpumask_var(offline); | ||
| 155 | |||
| 156 | /* display offline cpus >= nr_cpu_ids */ | ||
| 157 | if (total_cpus && nr_cpu_ids < total_cpus) { | ||
| 158 | if (n && n < len) | ||
| 159 | buf[n++] = ','; | ||
| 160 | |||
| 161 | if (nr_cpu_ids == total_cpus-1) | ||
| 162 | n += snprintf(&buf[n], len - n, "%d", nr_cpu_ids); | ||
| 163 | else | ||
| 164 | n += snprintf(&buf[n], len - n, "%d-%d", | ||
| 165 | nr_cpu_ids, total_cpus-1); | ||
| 166 | } | ||
| 167 | |||
| 168 | n += snprintf(&buf[n], len - n, "\n"); | ||
| 169 | return n; | ||
| 170 | } | ||
| 171 | static SYSDEV_CLASS_ATTR(offline, 0444, print_cpus_offline, NULL); | ||
| 172 | |||
| 131 | static struct sysdev_class_attribute *cpu_state_attr[] = { | 173 | static struct sysdev_class_attribute *cpu_state_attr[] = { |
| 132 | &attr_online_map, | 174 | &attr_online_map, |
| 133 | &attr_possible_map, | 175 | &attr_possible_map, |
| 134 | &attr_present_map, | 176 | &attr_present_map, |
| 177 | &attr_kernel_max, | ||
| 178 | &attr_offline, | ||
| 135 | }; | 179 | }; |
| 136 | 180 | ||
| 137 | static int cpu_states_init(void) | 181 | static int cpu_states_init(void) |
diff --git a/drivers/base/iommu.c b/drivers/base/iommu.c new file mode 100644 index 000000000000..5e039d4f877c --- /dev/null +++ b/drivers/base/iommu.c | |||
| @@ -0,0 +1,100 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2007-2008 Advanced Micro Devices, Inc. | ||
| 3 | * Author: Joerg Roedel <joerg.roedel@amd.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 as published | ||
| 7 | * by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/bug.h> | ||
| 20 | #include <linux/types.h> | ||
| 21 | #include <linux/errno.h> | ||
| 22 | #include <linux/iommu.h> | ||
| 23 | |||
| 24 | static struct iommu_ops *iommu_ops; | ||
| 25 | |||
| 26 | void register_iommu(struct iommu_ops *ops) | ||
| 27 | { | ||
| 28 | if (iommu_ops) | ||
| 29 | BUG(); | ||
| 30 | |||
| 31 | iommu_ops = ops; | ||
| 32 | } | ||
| 33 | |||
| 34 | bool iommu_found() | ||
| 35 | { | ||
| 36 | return iommu_ops != NULL; | ||
| 37 | } | ||
| 38 | EXPORT_SYMBOL_GPL(iommu_found); | ||
| 39 | |||
| 40 | struct iommu_domain *iommu_domain_alloc(void) | ||
| 41 | { | ||
| 42 | struct iommu_domain *domain; | ||
| 43 | int ret; | ||
| 44 | |||
| 45 | domain = kmalloc(sizeof(*domain), GFP_KERNEL); | ||
| 46 | if (!domain) | ||
| 47 | return NULL; | ||
| 48 | |||
| 49 | ret = iommu_ops->domain_init(domain); | ||
| 50 | if (ret) | ||
| 51 | goto out_free; | ||
| 52 | |||
| 53 | return domain; | ||
| 54 | |||
| 55 | out_free: | ||
| 56 | kfree(domain); | ||
| 57 | |||
| 58 | return NULL; | ||
| 59 | } | ||
| 60 | EXPORT_SYMBOL_GPL(iommu_domain_alloc); | ||
| 61 | |||
| 62 | void iommu_domain_free(struct iommu_domain *domain) | ||
| 63 | { | ||
| 64 | iommu_ops->domain_destroy(domain); | ||
| 65 | kfree(domain); | ||
| 66 | } | ||
| 67 | EXPORT_SYMBOL_GPL(iommu_domain_free); | ||
| 68 | |||
| 69 | int iommu_attach_device(struct iommu_domain *domain, struct device *dev) | ||
| 70 | { | ||
| 71 | return iommu_ops->attach_dev(domain, dev); | ||
| 72 | } | ||
| 73 | EXPORT_SYMBOL_GPL(iommu_attach_device); | ||
| 74 | |||
| 75 | void iommu_detach_device(struct iommu_domain *domain, struct device *dev) | ||
| 76 | { | ||
| 77 | iommu_ops->detach_dev(domain, dev); | ||
| 78 | } | ||
| 79 | EXPORT_SYMBOL_GPL(iommu_detach_device); | ||
| 80 | |||
| 81 | int iommu_map_range(struct iommu_domain *domain, unsigned long iova, | ||
| 82 | phys_addr_t paddr, size_t size, int prot) | ||
| 83 | { | ||
| 84 | return iommu_ops->map(domain, iova, paddr, size, prot); | ||
| 85 | } | ||
| 86 | EXPORT_SYMBOL_GPL(iommu_map_range); | ||
| 87 | |||
| 88 | void iommu_unmap_range(struct iommu_domain *domain, unsigned long iova, | ||
| 89 | size_t size) | ||
| 90 | { | ||
| 91 | iommu_ops->unmap(domain, iova, size); | ||
| 92 | } | ||
| 93 | EXPORT_SYMBOL_GPL(iommu_unmap_range); | ||
| 94 | |||
| 95 | phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, | ||
| 96 | unsigned long iova) | ||
| 97 | { | ||
| 98 | return iommu_ops->iova_to_phys(domain, iova); | ||
| 99 | } | ||
| 100 | EXPORT_SYMBOL_GPL(iommu_iova_to_phys); | ||
diff --git a/drivers/char/random.c b/drivers/char/random.c index d26891bfcd41..c7afc068c28d 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
| @@ -559,7 +559,40 @@ struct timer_rand_state { | |||
| 559 | }; | 559 | }; |
| 560 | 560 | ||
| 561 | #ifndef CONFIG_SPARSE_IRQ | 561 | #ifndef CONFIG_SPARSE_IRQ |
| 562 | struct timer_rand_state *irq_timer_state[NR_IRQS]; | 562 | |
| 563 | static struct timer_rand_state *irq_timer_state[NR_IRQS]; | ||
| 564 | |||
| 565 | static struct timer_rand_state *get_timer_rand_state(unsigned int irq) | ||
| 566 | { | ||
| 567 | return irq_timer_state[irq]; | ||
| 568 | } | ||
| 569 | |||
| 570 | static void set_timer_rand_state(unsigned int irq, | ||
| 571 | struct timer_rand_state *state) | ||
| 572 | { | ||
| 573 | irq_timer_state[irq] = state; | ||
| 574 | } | ||
| 575 | |||
| 576 | #else | ||
| 577 | |||
| 578 | static struct timer_rand_state *get_timer_rand_state(unsigned int irq) | ||
| 579 | { | ||
| 580 | struct irq_desc *desc; | ||
| 581 | |||
| 582 | desc = irq_to_desc(irq); | ||
| 583 | |||
| 584 | return desc->timer_rand_state; | ||
| 585 | } | ||
| 586 | |||
| 587 | static void set_timer_rand_state(unsigned int irq, | ||
| 588 | struct timer_rand_state *state) | ||
| 589 | { | ||
| 590 | struct irq_desc *desc; | ||
| 591 | |||
| 592 | desc = irq_to_desc(irq); | ||
| 593 | |||
| 594 | desc->timer_rand_state = state; | ||
| 595 | } | ||
| 563 | #endif | 596 | #endif |
| 564 | 597 | ||
| 565 | static struct timer_rand_state input_timer_state; | 598 | static struct timer_rand_state input_timer_state; |
| @@ -919,11 +952,6 @@ void rand_initialize_irq(int irq) | |||
| 919 | { | 952 | { |
| 920 | struct timer_rand_state *state; | 953 | struct timer_rand_state *state; |
| 921 | 954 | ||
| 922 | #ifndef CONFIG_SPARSE_IRQ | ||
| 923 | if (irq >= nr_irqs) | ||
| 924 | return; | ||
| 925 | #endif | ||
| 926 | |||
| 927 | state = get_timer_rand_state(irq); | 955 | state = get_timer_rand_state(irq); |
| 928 | 956 | ||
| 929 | if (state) | 957 | if (state) |
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index 757035ea246f..3128a5090dbd 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c | |||
| @@ -659,12 +659,12 @@ static inline int find_next_online_cpu(struct ehca_comp_pool *pool) | |||
| 659 | 659 | ||
| 660 | WARN_ON_ONCE(!in_interrupt()); | 660 | WARN_ON_ONCE(!in_interrupt()); |
| 661 | if (ehca_debug_level >= 3) | 661 | if (ehca_debug_level >= 3) |
| 662 | ehca_dmp(&cpu_online_map, sizeof(cpumask_t), ""); | 662 | ehca_dmp(cpu_online_mask, cpumask_size(), ""); |
| 663 | 663 | ||
| 664 | spin_lock_irqsave(&pool->last_cpu_lock, flags); | 664 | spin_lock_irqsave(&pool->last_cpu_lock, flags); |
| 665 | cpu = next_cpu_nr(pool->last_cpu, cpu_online_map); | 665 | cpu = cpumask_next(pool->last_cpu, cpu_online_mask); |
| 666 | if (cpu >= nr_cpu_ids) | 666 | if (cpu >= nr_cpu_ids) |
| 667 | cpu = first_cpu(cpu_online_map); | 667 | cpu = cpumask_first(cpu_online_mask); |
| 668 | pool->last_cpu = cpu; | 668 | pool->last_cpu = cpu; |
| 669 | spin_unlock_irqrestore(&pool->last_cpu_lock, flags); | 669 | spin_unlock_irqrestore(&pool->last_cpu_lock, flags); |
| 670 | 670 | ||
| @@ -855,7 +855,7 @@ static int __cpuinit comp_pool_callback(struct notifier_block *nfb, | |||
| 855 | case CPU_UP_CANCELED_FROZEN: | 855 | case CPU_UP_CANCELED_FROZEN: |
| 856 | ehca_gen_dbg("CPU: %x (CPU_CANCELED)", cpu); | 856 | ehca_gen_dbg("CPU: %x (CPU_CANCELED)", cpu); |
| 857 | cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); | 857 | cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); |
| 858 | kthread_bind(cct->task, any_online_cpu(cpu_online_map)); | 858 | kthread_bind(cct->task, cpumask_any(cpu_online_mask)); |
| 859 | destroy_comp_task(pool, cpu); | 859 | destroy_comp_task(pool, cpu); |
| 860 | break; | 860 | break; |
| 861 | case CPU_ONLINE: | 861 | case CPU_ONLINE: |
| @@ -902,7 +902,7 @@ int ehca_create_comp_pool(void) | |||
| 902 | return -ENOMEM; | 902 | return -ENOMEM; |
| 903 | 903 | ||
| 904 | spin_lock_init(&pool->last_cpu_lock); | 904 | spin_lock_init(&pool->last_cpu_lock); |
| 905 | pool->last_cpu = any_online_cpu(cpu_online_map); | 905 | pool->last_cpu = cpumask_any(cpu_online_mask); |
| 906 | 906 | ||
| 907 | pool->cpu_comp_tasks = alloc_percpu(struct ehca_cpu_comp_task); | 907 | pool->cpu_comp_tasks = alloc_percpu(struct ehca_cpu_comp_task); |
| 908 | if (pool->cpu_comp_tasks == NULL) { | 908 | if (pool->cpu_comp_tasks == NULL) { |
| @@ -934,10 +934,9 @@ void ehca_destroy_comp_pool(void) | |||
| 934 | 934 | ||
| 935 | unregister_hotcpu_notifier(&comp_pool_callback_nb); | 935 | unregister_hotcpu_notifier(&comp_pool_callback_nb); |
| 936 | 936 | ||
| 937 | for (i = 0; i < NR_CPUS; i++) { | 937 | for_each_online_cpu(i) |
| 938 | if (cpu_online(i)) | 938 | destroy_comp_task(pool, i); |
| 939 | destroy_comp_task(pool, i); | 939 | |
| 940 | } | ||
| 941 | free_percpu(pool->cpu_comp_tasks); | 940 | free_percpu(pool->cpu_comp_tasks); |
| 942 | kfree(pool); | 941 | kfree(pool); |
| 943 | } | 942 | } |
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c index 239d4e8068ac..23173982b32c 100644 --- a/drivers/infiniband/hw/ipath/ipath_file_ops.c +++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c | |||
| @@ -1679,7 +1679,7 @@ static int find_best_unit(struct file *fp, | |||
| 1679 | * InfiniPath chip to that processor (we assume reasonable connectivity, | 1679 | * InfiniPath chip to that processor (we assume reasonable connectivity, |
| 1680 | * for now). This code assumes that if affinity has been set | 1680 | * for now). This code assumes that if affinity has been set |
| 1681 | * before this point, that at most one cpu is set; for now this | 1681 | * before this point, that at most one cpu is set; for now this |
| 1682 | * is reasonable. I check for both cpus_empty() and cpus_full(), | 1682 | * is reasonable. I check for both cpumask_empty() and cpumask_full(), |
| 1683 | * in case some kernel variant sets none of the bits when no | 1683 | * in case some kernel variant sets none of the bits when no |
| 1684 | * affinity is set. 2.6.11 and 12 kernels have all present | 1684 | * affinity is set. 2.6.11 and 12 kernels have all present |
| 1685 | * cpus set. Some day we'll have to fix it up further to handle | 1685 | * cpus set. Some day we'll have to fix it up further to handle |
| @@ -1688,11 +1688,11 @@ static int find_best_unit(struct file *fp, | |||
| 1688 | * information. There may be some issues with dual core numbering | 1688 | * information. There may be some issues with dual core numbering |
| 1689 | * as well. This needs more work prior to release. | 1689 | * as well. This needs more work prior to release. |
| 1690 | */ | 1690 | */ |
| 1691 | if (!cpus_empty(current->cpus_allowed) && | 1691 | if (!cpumask_empty(¤t->cpus_allowed) && |
| 1692 | !cpus_full(current->cpus_allowed)) { | 1692 | !cpumask_full(¤t->cpus_allowed)) { |
| 1693 | int ncpus = num_online_cpus(), curcpu = -1, nset = 0; | 1693 | int ncpus = num_online_cpus(), curcpu = -1, nset = 0; |
| 1694 | for (i = 0; i < ncpus; i++) | 1694 | for (i = 0; i < ncpus; i++) |
| 1695 | if (cpu_isset(i, current->cpus_allowed)) { | 1695 | if (cpumask_test_cpu(i, ¤t->cpus_allowed)) { |
| 1696 | ipath_cdbg(PROC, "%s[%u] affinity set for " | 1696 | ipath_cdbg(PROC, "%s[%u] affinity set for " |
| 1697 | "cpu %d/%d\n", current->comm, | 1697 | "cpu %d/%d\n", current->comm, |
| 1698 | current->pid, i, ncpus); | 1698 | current->pid, i, ncpus); |
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 7d844af88384..cf06f4d10ad4 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c | |||
| @@ -192,9 +192,9 @@ void saa7146_buffer_timeout(unsigned long data) | |||
| 192 | /********************************************************************************/ | 192 | /********************************************************************************/ |
| 193 | /* file operations */ | 193 | /* file operations */ |
| 194 | 194 | ||
| 195 | static int fops_open(struct inode *inode, struct file *file) | 195 | static int fops_open(struct file *file) |
| 196 | { | 196 | { |
| 197 | unsigned int minor = iminor(inode); | 197 | unsigned int minor = video_devdata(file)->minor; |
| 198 | struct saa7146_dev *h = NULL, *dev = NULL; | 198 | struct saa7146_dev *h = NULL, *dev = NULL; |
| 199 | struct list_head *list; | 199 | struct list_head *list; |
| 200 | struct saa7146_fh *fh = NULL; | 200 | struct saa7146_fh *fh = NULL; |
| @@ -202,7 +202,7 @@ static int fops_open(struct inode *inode, struct file *file) | |||
| 202 | 202 | ||
| 203 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 203 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 204 | 204 | ||
| 205 | DEB_EE(("inode:%p, file:%p, minor:%d\n",inode,file,minor)); | 205 | DEB_EE(("file:%p, minor:%d\n", file, minor)); |
| 206 | 206 | ||
| 207 | if (mutex_lock_interruptible(&saa7146_devices_lock)) | 207 | if (mutex_lock_interruptible(&saa7146_devices_lock)) |
| 208 | return -ERESTARTSYS; | 208 | return -ERESTARTSYS; |
| @@ -255,7 +255,7 @@ static int fops_open(struct inode *inode, struct file *file) | |||
| 255 | if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) | 255 | if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) |
| 256 | result = saa7146_vbi_uops.open(dev,file); | 256 | result = saa7146_vbi_uops.open(dev,file); |
| 257 | if (dev->ext_vv_data->vbi_fops.open) | 257 | if (dev->ext_vv_data->vbi_fops.open) |
| 258 | dev->ext_vv_data->vbi_fops.open(inode, file); | 258 | dev->ext_vv_data->vbi_fops.open(file); |
| 259 | } else { | 259 | } else { |
| 260 | DEB_S(("initializing video...\n")); | 260 | DEB_S(("initializing video...\n")); |
| 261 | result = saa7146_video_uops.open(dev,file); | 261 | result = saa7146_video_uops.open(dev,file); |
| @@ -280,12 +280,12 @@ out: | |||
| 280 | return result; | 280 | return result; |
| 281 | } | 281 | } |
| 282 | 282 | ||
| 283 | static int fops_release(struct inode *inode, struct file *file) | 283 | static int fops_release(struct file *file) |
| 284 | { | 284 | { |
| 285 | struct saa7146_fh *fh = file->private_data; | 285 | struct saa7146_fh *fh = file->private_data; |
| 286 | struct saa7146_dev *dev = fh->dev; | 286 | struct saa7146_dev *dev = fh->dev; |
| 287 | 287 | ||
| 288 | DEB_EE(("inode:%p, file:%p\n",inode,file)); | 288 | DEB_EE(("file:%p\n", file)); |
| 289 | 289 | ||
| 290 | if (mutex_lock_interruptible(&saa7146_devices_lock)) | 290 | if (mutex_lock_interruptible(&saa7146_devices_lock)) |
| 291 | return -ERESTARTSYS; | 291 | return -ERESTARTSYS; |
| @@ -294,7 +294,7 @@ static int fops_release(struct inode *inode, struct file *file) | |||
| 294 | if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) | 294 | if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) |
| 295 | saa7146_vbi_uops.release(dev,file); | 295 | saa7146_vbi_uops.release(dev,file); |
| 296 | if (dev->ext_vv_data->vbi_fops.release) | 296 | if (dev->ext_vv_data->vbi_fops.release) |
| 297 | dev->ext_vv_data->vbi_fops.release(inode, file); | 297 | dev->ext_vv_data->vbi_fops.release(file); |
| 298 | } else { | 298 | } else { |
| 299 | saa7146_video_uops.release(dev,file); | 299 | saa7146_video_uops.release(dev,file); |
| 300 | } | 300 | } |
| @@ -308,10 +308,10 @@ static int fops_release(struct inode *inode, struct file *file) | |||
| 308 | return 0; | 308 | return 0; |
| 309 | } | 309 | } |
| 310 | 310 | ||
| 311 | static int fops_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 311 | static long fops_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 312 | { | 312 | { |
| 313 | /* | 313 | /* |
| 314 | DEB_EE(("inode:%p, file:%p, cmd:%d, arg:%li\n",inode, file, cmd, arg)); | 314 | DEB_EE(("file:%p, cmd:%d, arg:%li\n", file, cmd, arg)); |
| 315 | */ | 315 | */ |
| 316 | return video_usercopy(file, cmd, arg, saa7146_video_do_ioctl); | 316 | return video_usercopy(file, cmd, arg, saa7146_video_do_ioctl); |
| 317 | } | 317 | } |
| @@ -416,7 +416,7 @@ static ssize_t fops_write(struct file *file, const char __user *data, size_t cou | |||
| 416 | } | 416 | } |
| 417 | } | 417 | } |
| 418 | 418 | ||
| 419 | static const struct file_operations video_fops = | 419 | static const struct v4l2_file_operations video_fops = |
| 420 | { | 420 | { |
| 421 | .owner = THIS_MODULE, | 421 | .owner = THIS_MODULE, |
| 422 | .open = fops_open, | 422 | .open = fops_open, |
| @@ -426,7 +426,6 @@ static const struct file_operations video_fops = | |||
| 426 | .poll = fops_poll, | 426 | .poll = fops_poll, |
| 427 | .mmap = fops_mmap, | 427 | .mmap = fops_mmap, |
| 428 | .ioctl = fops_ioctl, | 428 | .ioctl = fops_ioctl, |
| 429 | .llseek = no_llseek, | ||
| 430 | }; | 429 | }; |
| 431 | 430 | ||
| 432 | static void vv_callback(struct saa7146_dev *dev, unsigned long status) | 431 | static void vv_callback(struct saa7146_dev *dev, unsigned long status) |
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index 101b01dbb8ea..6098b626811f 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c | |||
| @@ -834,13 +834,14 @@ static int video_end(struct saa7146_fh *fh, struct file *file) | |||
| 834 | * copying is done already, arg is a kernel pointer. | 834 | * copying is done already, arg is a kernel pointer. |
| 835 | */ | 835 | */ |
| 836 | 836 | ||
| 837 | int saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 837 | long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 838 | { | 838 | { |
| 839 | struct saa7146_fh *fh = file->private_data; | 839 | struct saa7146_fh *fh = file->private_data; |
| 840 | struct saa7146_dev *dev = fh->dev; | 840 | struct saa7146_dev *dev = fh->dev; |
| 841 | struct saa7146_vv *vv = dev->vv_data; | 841 | struct saa7146_vv *vv = dev->vv_data; |
| 842 | 842 | ||
| 843 | int err = 0, result = 0, ee = 0; | 843 | long err = 0; |
| 844 | int result = 0, ee = 0; | ||
| 844 | 845 | ||
| 845 | struct saa7146_use_ops *ops; | 846 | struct saa7146_use_ops *ops; |
| 846 | struct videobuf_queue *q; | 847 | struct videobuf_queue *q; |
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c index fb3f3b3adaba..de7adaf5fa5b 100644 --- a/drivers/media/common/tuners/tuner-simple.c +++ b/drivers/media/common/tuners/tuner-simple.c | |||
| @@ -820,6 +820,15 @@ static u32 simple_dvb_configure(struct dvb_frontend *fe, u8 *buf, | |||
| 820 | int ret; | 820 | int ret; |
| 821 | unsigned frequency = params->frequency / 62500; | 821 | unsigned frequency = params->frequency / 62500; |
| 822 | 822 | ||
| 823 | if (!tun->stepsize) { | ||
| 824 | /* tuner-core was loaded before the digital tuner was | ||
| 825 | * configured and somehow picked the wrong tuner type */ | ||
| 826 | tuner_err("attempt to treat tuner %d (%s) as digital tuner " | ||
| 827 | "without stepsize defined.\n", | ||
| 828 | priv->type, priv->tun->name); | ||
| 829 | return 0; /* failure */ | ||
| 830 | } | ||
| 831 | |||
| 823 | t_params = simple_tuner_params(fe, TUNER_PARAM_TYPE_DIGITAL); | 832 | t_params = simple_tuner_params(fe, TUNER_PARAM_TYPE_DIGITAL); |
| 824 | ret = simple_config_lookup(fe, t_params, &frequency, &config, &cb); | 833 | ret = simple_config_lookup(fe, t_params, &frequency, &config, &cb); |
| 825 | if (ret < 0) | 834 | if (ret < 0) |
| @@ -1059,7 +1068,12 @@ struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, | |||
| 1059 | memcpy(&fe->ops.tuner_ops, &simple_tuner_ops, | 1068 | memcpy(&fe->ops.tuner_ops, &simple_tuner_ops, |
| 1060 | sizeof(struct dvb_tuner_ops)); | 1069 | sizeof(struct dvb_tuner_ops)); |
| 1061 | 1070 | ||
| 1062 | tuner_info("type set to %d (%s)\n", type, priv->tun->name); | 1071 | if (type != priv->type) |
| 1072 | tuner_warn("couldn't set type to %d. Using %d (%s) instead\n", | ||
| 1073 | type, priv->type, priv->tun->name); | ||
| 1074 | else | ||
| 1075 | tuner_info("type set to %d (%s)\n", | ||
| 1076 | priv->type, priv->tun->name); | ||
| 1063 | 1077 | ||
| 1064 | if ((debug) || ((atv_input[priv->nr] > 0) || | 1078 | if ((debug) || ((atv_input[priv->nr] > 0) || |
| 1065 | (dtv_input[priv->nr] > 0))) { | 1079 | (dtv_input[priv->nr] > 0))) { |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 6c571d9f011c..65d69665f1fc 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c | |||
| @@ -436,8 +436,9 @@ static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
| 436 | { | 436 | { |
| 437 | struct dvb_device *dvbdev = dev_get_drvdata(dev); | 437 | struct dvb_device *dvbdev = dev_get_drvdata(dev); |
| 438 | 438 | ||
| 439 | add_uevent_var(env, "DVB_DEVICE_NUM=%d", dvbdev->id); | ||
| 440 | add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num); | 439 | add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num); |
| 440 | add_uevent_var(env, "DVB_DEVICE_TYPE=%s", dnames[dvbdev->type]); | ||
| 441 | add_uevent_var(env, "DVB_DEVICE_NUM=%d", dvbdev->id); | ||
| 441 | return 0; | 442 | return 0; |
| 442 | } | 443 | } |
| 443 | 444 | ||
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c index c1da962cc886..3dd6843864ed 100644 --- a/drivers/media/dvb/dvb-usb/gp8psk.c +++ b/drivers/media/dvb/dvb-usb/gp8psk.c | |||
| @@ -187,7 +187,7 @@ int gp8psk_bcm4500_reload(struct dvb_usb_device *d) | |||
| 187 | /* load BCM4500 firmware */ | 187 | /* load BCM4500 firmware */ |
| 188 | if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) | 188 | if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) |
| 189 | if (gp8psk_load_bcm4500fw(d)) | 189 | if (gp8psk_load_bcm4500fw(d)) |
| 190 | return EINVAL; | 190 | return -EINVAL; |
| 191 | return 0; | 191 | return 0; |
| 192 | } | 192 | } |
| 193 | 193 | ||
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c index 9b6c89e93f16..4f514d39b98f 100644 --- a/drivers/media/dvb/frontends/cx24116.c +++ b/drivers/media/dvb/frontends/cx24116.c | |||
| @@ -1463,6 +1463,7 @@ static struct dvb_frontend_ops cx24116_ops = { | |||
| 1463 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | 1463 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | |
| 1464 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | | 1464 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | |
| 1465 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | 1465 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | |
| 1466 | FE_CAN_2G_MODULATION | | ||
| 1466 | FE_CAN_QPSK | FE_CAN_RECOVER | 1467 | FE_CAN_QPSK | FE_CAN_RECOVER |
| 1467 | }, | 1468 | }, |
| 1468 | 1469 | ||
diff --git a/drivers/media/dvb/frontends/cx24116.h b/drivers/media/dvb/frontends/cx24116.h index 4cb3ddd6c626..b1b76b47a14c 100644 --- a/drivers/media/dvb/frontends/cx24116.h +++ b/drivers/media/dvb/frontends/cx24116.h | |||
| @@ -37,7 +37,8 @@ struct cx24116_config { | |||
| 37 | u8 mpg_clk_pos_pol:0x02; | 37 | u8 mpg_clk_pos_pol:0x02; |
| 38 | }; | 38 | }; |
| 39 | 39 | ||
| 40 | #if defined(CONFIG_DVB_CX24116) || defined(CONFIG_DVB_CX24116_MODULE) | 40 | #if defined(CONFIG_DVB_CX24116) || \ |
| 41 | (defined(CONFIG_DVB_CX24116_MODULE) && defined(MODULE)) | ||
| 41 | extern struct dvb_frontend *cx24116_attach( | 42 | extern struct dvb_frontend *cx24116_attach( |
| 42 | const struct cx24116_config *config, | 43 | const struct cx24116_config *config, |
| 43 | struct i2c_adapter *i2c); | 44 | struct i2c_adapter *i2c); |
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c index 528820170228..bee28f77b93f 100644 --- a/drivers/media/dvb/frontends/stb0899_drv.c +++ b/drivers/media/dvb/frontends/stb0899_drv.c | |||
| @@ -1618,6 +1618,7 @@ static struct dvb_frontend_ops stb0899_ops = { | |||
| 1618 | 1618 | ||
| 1619 | .caps = FE_CAN_INVERSION_AUTO | | 1619 | .caps = FE_CAN_INVERSION_AUTO | |
| 1620 | FE_CAN_FEC_AUTO | | 1620 | FE_CAN_FEC_AUTO | |
| 1621 | FE_CAN_2G_MODULATION | | ||
| 1621 | FE_CAN_QPSK | 1622 | FE_CAN_QPSK |
| 1622 | }, | 1623 | }, |
| 1623 | 1624 | ||
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c index 5506f80e180e..170720b02815 100644 --- a/drivers/media/dvb/frontends/zl10353.c +++ b/drivers/media/dvb/frontends/zl10353.c | |||
| @@ -587,8 +587,15 @@ static int zl10353_init(struct dvb_frontend *fe) | |||
| 587 | 587 | ||
| 588 | static int zl10353_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | 588 | static int zl10353_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) |
| 589 | { | 589 | { |
| 590 | struct zl10353_state *state = fe->demodulator_priv; | ||
| 590 | u8 val = 0x0a; | 591 | u8 val = 0x0a; |
| 591 | 592 | ||
| 593 | if (state->config.no_tuner) { | ||
| 594 | /* No tuner attached to the internal I2C bus */ | ||
| 595 | /* If set enable I2C bridge, the main I2C bus stopped hardly */ | ||
| 596 | return 0; | ||
| 597 | } | ||
| 598 | |||
| 592 | if (enable) | 599 | if (enable) |
| 593 | val |= 0x10; | 600 | val |= 0x10; |
| 594 | 601 | ||
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index fd62e0b85621..4307e4e8aa34 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c | |||
| @@ -120,7 +120,7 @@ static struct sms_board sms_boards[] = { | |||
| 120 | .name = "Hauppauge WinTV MiniCard", | 120 | .name = "Hauppauge WinTV MiniCard", |
| 121 | .type = SMS_NOVA_B0, | 121 | .type = SMS_NOVA_B0, |
| 122 | .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", | 122 | .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", |
| 123 | .lna_ctrl = 1, | 123 | .lna_ctrl = -1, |
| 124 | }, | 124 | }, |
| 125 | }; | 125 | }; |
| 126 | 126 | ||
| @@ -131,9 +131,10 @@ struct sms_board *sms_get_board(int id) | |||
| 131 | return &sms_boards[id]; | 131 | return &sms_boards[id]; |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | static int sms_set_gpio(struct smscore_device_t *coredev, u32 pin, int enable) | 134 | static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable) |
| 135 | { | 135 | { |
| 136 | int ret; | 136 | int lvl, ret; |
| 137 | u32 gpio; | ||
| 137 | struct smscore_gpio_config gpioconfig = { | 138 | struct smscore_gpio_config gpioconfig = { |
| 138 | .direction = SMS_GPIO_DIRECTION_OUTPUT, | 139 | .direction = SMS_GPIO_DIRECTION_OUTPUT, |
| 139 | .pullupdown = SMS_GPIO_PULLUPDOWN_NONE, | 140 | .pullupdown = SMS_GPIO_PULLUPDOWN_NONE, |
| @@ -145,12 +146,20 @@ static int sms_set_gpio(struct smscore_device_t *coredev, u32 pin, int enable) | |||
| 145 | if (pin == 0) | 146 | if (pin == 0) |
| 146 | return -EINVAL; | 147 | return -EINVAL; |
| 147 | 148 | ||
| 148 | ret = smscore_configure_gpio(coredev, pin, &gpioconfig); | 149 | if (pin < 0) { |
| 150 | /* inverted gpio */ | ||
| 151 | gpio = pin * -1; | ||
| 152 | lvl = enable ? 0 : 1; | ||
| 153 | } else { | ||
| 154 | gpio = pin; | ||
| 155 | lvl = enable ? 1 : 0; | ||
| 156 | } | ||
| 149 | 157 | ||
| 158 | ret = smscore_configure_gpio(coredev, gpio, &gpioconfig); | ||
| 150 | if (ret < 0) | 159 | if (ret < 0) |
| 151 | return ret; | 160 | return ret; |
| 152 | 161 | ||
| 153 | return smscore_set_gpio(coredev, pin, enable); | 162 | return smscore_set_gpio(coredev, gpio, lvl); |
| 154 | } | 163 | } |
| 155 | 164 | ||
| 156 | int sms_board_setup(struct smscore_device_t *coredev) | 165 | int sms_board_setup(struct smscore_device_t *coredev) |
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c index b4a0cc5dc935..c5b9c70563dc 100644 --- a/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/drivers/media/dvb/ttpci/av7110_v4l.c | |||
| @@ -316,7 +316,7 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh) | |||
| 316 | return 0; | 316 | return 0; |
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | 319 | static long av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) |
| 320 | { | 320 | { |
| 321 | struct saa7146_dev *dev = fh->dev; | 321 | struct saa7146_dev *dev = fh->dev; |
| 322 | struct av7110 *av7110 = (struct av7110*) dev->ext_priv; | 322 | struct av7110 *av7110 = (struct av7110*) dev->ext_priv; |
| @@ -567,7 +567,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
| 567 | return 0; | 567 | return 0; |
| 568 | } | 568 | } |
| 569 | 569 | ||
| 570 | static int av7110_vbi_reset(struct inode *inode, struct file *file) | 570 | static int av7110_vbi_reset(struct file *file) |
| 571 | { | 571 | { |
| 572 | struct saa7146_fh *fh = file->private_data; | 572 | struct saa7146_fh *fh = file->private_data; |
| 573 | struct saa7146_dev *dev = fh->dev; | 573 | struct saa7146_dev *dev = fh->dev; |
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index f996cef79ec1..4182121d7e5d 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c | |||
| @@ -1493,7 +1493,7 @@ static struct saa7146_extension_ioctls ioctls[] = { | |||
| 1493 | {0, 0} | 1493 | {0, 0} |
| 1494 | }; | 1494 | }; |
| 1495 | 1495 | ||
| 1496 | static int av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | 1496 | static long av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) |
| 1497 | { | 1497 | { |
| 1498 | struct saa7146_dev *dev = fh->dev; | 1498 | struct saa7146_dev *dev = fh->dev; |
| 1499 | struct budget_av *budget_av = (struct budget_av *) dev->ext_priv; | 1499 | struct budget_av *budget_av = (struct budget_av *) dev->ext_priv; |
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig index f546bccdb997..2663ae39b886 100644 --- a/drivers/media/dvb/ttusb-budget/Kconfig +++ b/drivers/media/dvb/ttusb-budget/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config DVB_TTUSB_BUDGET | 1 | config DVB_TTUSB_BUDGET |
| 2 | tristate "Technotrend/Hauppauge Nova-USB devices" | 2 | tristate "Technotrend/Hauppauge Nova-USB devices" |
| 3 | depends on DVB_CORE && USB && I2C | 3 | depends on DVB_CORE && USB && I2C && PCI |
| 4 | select DVB_CX22700 if !DVB_FE_CUSTOMISE | 4 | select DVB_CX22700 if !DVB_FE_CUSTOMISE |
| 5 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE | 5 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE |
| 6 | select DVB_VES1820 if !DVB_FE_CUSTOMISE | 6 | select DVB_VES1820 if !DVB_FE_CUSTOMISE |
diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig index d5f48a3102bd..290254ab06db 100644 --- a/drivers/media/dvb/ttusb-dec/Kconfig +++ b/drivers/media/dvb/ttusb-dec/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config DVB_TTUSB_DEC | 1 | config DVB_TTUSB_DEC |
| 2 | tristate "Technotrend/Hauppauge USB DEC devices" | 2 | tristate "Technotrend/Hauppauge USB DEC devices" |
| 3 | depends on DVB_CORE && USB && INPUT | 3 | depends on DVB_CORE && USB && INPUT && PCI |
| 4 | select CRC32 | 4 | select CRC32 |
| 5 | help | 5 | help |
| 6 | Support for external USB adapters designed by Technotrend and | 6 | Support for external USB adapters designed by Technotrend and |
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 5189c4eb439f..3315cac875e5 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig | |||
| @@ -387,4 +387,23 @@ config USB_MR800 | |||
| 387 | To compile this driver as a module, choose M here: the | 387 | To compile this driver as a module, choose M here: the |
| 388 | module will be called radio-mr800. | 388 | module will be called radio-mr800. |
| 389 | 389 | ||
| 390 | config RADIO_TEA5764 | ||
| 391 | tristate "TEA5764 I2C FM radio support" | ||
| 392 | depends on I2C && VIDEO_V4L2 | ||
| 393 | ---help--- | ||
| 394 | Say Y here if you want to use the TEA5764 FM chip found in | ||
| 395 | EZX phones. This FM chip is present in EZX phones from Motorola, | ||
| 396 | connected to internal pxa I2C bus. | ||
| 397 | |||
| 398 | To compile this driver as a module, choose M here: the | ||
| 399 | module will be called radio-tea5764. | ||
| 400 | |||
| 401 | config RADIO_TEA5764_XTAL | ||
| 402 | bool "TEA5764 crystal reference" | ||
| 403 | depends on RADIO_TEA5764=y | ||
| 404 | default y | ||
| 405 | help | ||
| 406 | Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N | ||
| 407 | here if TEA5764 reference frequency is connected in FREQIN. | ||
| 408 | |||
| 390 | endif # RADIO_ADAPTERS | 409 | endif # RADIO_ADAPTERS |
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile index 240ec63cdafc..0f2b35b3e560 100644 --- a/drivers/media/radio/Makefile +++ b/drivers/media/radio/Makefile | |||
| @@ -19,5 +19,6 @@ obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o | |||
| 19 | obj-$(CONFIG_USB_DSBR) += dsbr100.o | 19 | obj-$(CONFIG_USB_DSBR) += dsbr100.o |
| 20 | obj-$(CONFIG_USB_SI470X) += radio-si470x.o | 20 | obj-$(CONFIG_USB_SI470X) += radio-si470x.o |
| 21 | obj-$(CONFIG_USB_MR800) += radio-mr800.o | 21 | obj-$(CONFIG_USB_MR800) += radio-mr800.o |
| 22 | obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o | ||
| 22 | 23 | ||
| 23 | EXTRA_CFLAGS += -Isound | 24 | EXTRA_CFLAGS += -Isound |
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index 5474a22c1b22..2014ebc4e984 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c | |||
| @@ -154,8 +154,8 @@ devices, that would be 76 and 91. */ | |||
| 154 | static int usb_dsbr100_probe(struct usb_interface *intf, | 154 | static int usb_dsbr100_probe(struct usb_interface *intf, |
| 155 | const struct usb_device_id *id); | 155 | const struct usb_device_id *id); |
| 156 | static void usb_dsbr100_disconnect(struct usb_interface *intf); | 156 | static void usb_dsbr100_disconnect(struct usb_interface *intf); |
| 157 | static int usb_dsbr100_open(struct inode *inode, struct file *file); | 157 | static int usb_dsbr100_open(struct file *file); |
| 158 | static int usb_dsbr100_close(struct inode *inode, struct file *file); | 158 | static int usb_dsbr100_close(struct file *file); |
| 159 | static int usb_dsbr100_suspend(struct usb_interface *intf, | 159 | static int usb_dsbr100_suspend(struct usb_interface *intf, |
| 160 | pm_message_t message); | 160 | pm_message_t message); |
| 161 | static int usb_dsbr100_resume(struct usb_interface *intf); | 161 | static int usb_dsbr100_resume(struct usb_interface *intf); |
| @@ -566,7 +566,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 566 | return 0; | 566 | return 0; |
| 567 | } | 567 | } |
| 568 | 568 | ||
| 569 | static int usb_dsbr100_open(struct inode *inode, struct file *file) | 569 | static int usb_dsbr100_open(struct file *file) |
| 570 | { | 570 | { |
| 571 | struct dsbr100_device *radio = video_drvdata(file); | 571 | struct dsbr100_device *radio = video_drvdata(file); |
| 572 | int retval; | 572 | int retval; |
| @@ -593,7 +593,7 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file) | |||
| 593 | return 0; | 593 | return 0; |
| 594 | } | 594 | } |
| 595 | 595 | ||
| 596 | static int usb_dsbr100_close(struct inode *inode, struct file *file) | 596 | static int usb_dsbr100_close(struct file *file) |
| 597 | { | 597 | { |
| 598 | struct dsbr100_device *radio = video_drvdata(file); | 598 | struct dsbr100_device *radio = video_drvdata(file); |
| 599 | int retval; | 599 | int retval; |
| @@ -653,15 +653,11 @@ static void usb_dsbr100_video_device_release(struct video_device *videodev) | |||
| 653 | } | 653 | } |
| 654 | 654 | ||
| 655 | /* File system interface */ | 655 | /* File system interface */ |
| 656 | static const struct file_operations usb_dsbr100_fops = { | 656 | static const struct v4l2_file_operations usb_dsbr100_fops = { |
| 657 | .owner = THIS_MODULE, | 657 | .owner = THIS_MODULE, |
| 658 | .open = usb_dsbr100_open, | 658 | .open = usb_dsbr100_open, |
| 659 | .release = usb_dsbr100_close, | 659 | .release = usb_dsbr100_close, |
| 660 | .ioctl = video_ioctl2, | 660 | .ioctl = video_ioctl2, |
| 661 | #ifdef CONFIG_COMPAT | ||
| 662 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 663 | #endif | ||
| 664 | .llseek = no_llseek, | ||
| 665 | }; | 661 | }; |
| 666 | 662 | ||
| 667 | static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = { | 663 | static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = { |
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index dd6d3dfcd7d2..bfa13b8b3043 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c | |||
| @@ -374,26 +374,22 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 374 | 374 | ||
| 375 | static struct rt_device rtrack_unit; | 375 | static struct rt_device rtrack_unit; |
| 376 | 376 | ||
| 377 | static int rtrack_exclusive_open(struct inode *inode, struct file *file) | 377 | static int rtrack_exclusive_open(struct file *file) |
| 378 | { | 378 | { |
| 379 | return test_and_set_bit(0, &rtrack_unit.in_use) ? -EBUSY : 0; | 379 | return test_and_set_bit(0, &rtrack_unit.in_use) ? -EBUSY : 0; |
| 380 | } | 380 | } |
| 381 | 381 | ||
| 382 | static int rtrack_exclusive_release(struct inode *inode, struct file *file) | 382 | static int rtrack_exclusive_release(struct file *file) |
| 383 | { | 383 | { |
| 384 | clear_bit(0, &rtrack_unit.in_use); | 384 | clear_bit(0, &rtrack_unit.in_use); |
| 385 | return 0; | 385 | return 0; |
| 386 | } | 386 | } |
| 387 | 387 | ||
| 388 | static const struct file_operations rtrack_fops = { | 388 | static const struct v4l2_file_operations rtrack_fops = { |
| 389 | .owner = THIS_MODULE, | 389 | .owner = THIS_MODULE, |
| 390 | .open = rtrack_exclusive_open, | 390 | .open = rtrack_exclusive_open, |
| 391 | .release = rtrack_exclusive_release, | 391 | .release = rtrack_exclusive_release, |
| 392 | .ioctl = video_ioctl2, | 392 | .ioctl = video_ioctl2, |
| 393 | #ifdef CONFIG_COMPAT | ||
| 394 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 395 | #endif | ||
| 396 | .llseek = no_llseek, | ||
| 397 | }; | 393 | }; |
| 398 | 394 | ||
| 399 | static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { | 395 | static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { |
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index d78489573230..5604e881e96c 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c | |||
| @@ -338,26 +338,22 @@ static int vidioc_s_ctrl (struct file *file, void *priv, | |||
| 338 | 338 | ||
| 339 | static struct az_device aztech_unit; | 339 | static struct az_device aztech_unit; |
| 340 | 340 | ||
| 341 | static int aztech_exclusive_open(struct inode *inode, struct file *file) | 341 | static int aztech_exclusive_open(struct file *file) |
| 342 | { | 342 | { |
| 343 | return test_and_set_bit(0, &aztech_unit.in_use) ? -EBUSY : 0; | 343 | return test_and_set_bit(0, &aztech_unit.in_use) ? -EBUSY : 0; |
| 344 | } | 344 | } |
| 345 | 345 | ||
| 346 | static int aztech_exclusive_release(struct inode *inode, struct file *file) | 346 | static int aztech_exclusive_release(struct file *file) |
| 347 | { | 347 | { |
| 348 | clear_bit(0, &aztech_unit.in_use); | 348 | clear_bit(0, &aztech_unit.in_use); |
| 349 | return 0; | 349 | return 0; |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | static const struct file_operations aztech_fops = { | 352 | static const struct v4l2_file_operations aztech_fops = { |
| 353 | .owner = THIS_MODULE, | 353 | .owner = THIS_MODULE, |
| 354 | .open = aztech_exclusive_open, | 354 | .open = aztech_exclusive_open, |
| 355 | .release = aztech_exclusive_release, | 355 | .release = aztech_exclusive_release, |
| 356 | .ioctl = video_ioctl2, | 356 | .ioctl = video_ioctl2, |
| 357 | #ifdef CONFIG_COMPAT | ||
| 358 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 359 | #endif | ||
| 360 | .llseek = no_llseek, | ||
| 361 | }; | 357 | }; |
| 362 | 358 | ||
| 363 | static const struct v4l2_ioctl_ops aztech_ioctl_ops = { | 359 | static const struct v4l2_ioctl_ops aztech_ioctl_ops = { |
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index bfd37f38b9ab..cb3075ac104c 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c | |||
| @@ -529,7 +529,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 529 | } | 529 | } |
| 530 | 530 | ||
| 531 | static int | 531 | static int |
| 532 | cadet_open(struct inode *inode, struct file *file) | 532 | cadet_open(struct file *file) |
| 533 | { | 533 | { |
| 534 | users++; | 534 | users++; |
| 535 | if (1 == users) init_waitqueue_head(&read_queue); | 535 | if (1 == users) init_waitqueue_head(&read_queue); |
| @@ -537,7 +537,7 @@ cadet_open(struct inode *inode, struct file *file) | |||
| 537 | } | 537 | } |
| 538 | 538 | ||
| 539 | static int | 539 | static int |
| 540 | cadet_release(struct inode *inode, struct file *file) | 540 | cadet_release(struct file *file) |
| 541 | { | 541 | { |
| 542 | users--; | 542 | users--; |
| 543 | if (0 == users){ | 543 | if (0 == users){ |
| @@ -557,17 +557,13 @@ cadet_poll(struct file *file, struct poll_table_struct *wait) | |||
| 557 | } | 557 | } |
| 558 | 558 | ||
| 559 | 559 | ||
| 560 | static const struct file_operations cadet_fops = { | 560 | static const struct v4l2_file_operations cadet_fops = { |
| 561 | .owner = THIS_MODULE, | 561 | .owner = THIS_MODULE, |
| 562 | .open = cadet_open, | 562 | .open = cadet_open, |
| 563 | .release = cadet_release, | 563 | .release = cadet_release, |
| 564 | .read = cadet_read, | 564 | .read = cadet_read, |
| 565 | .ioctl = video_ioctl2, | 565 | .ioctl = video_ioctl2, |
| 566 | .poll = cadet_poll, | 566 | .poll = cadet_poll, |
| 567 | #ifdef CONFIG_COMPAT | ||
| 568 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 569 | #endif | ||
| 570 | .llseek = no_llseek, | ||
| 571 | }; | 567 | }; |
| 572 | 568 | ||
| 573 | static const struct v4l2_ioctl_ops cadet_ioctl_ops = { | 569 | static const struct v4l2_ioctl_ops cadet_ioctl_ops = { |
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index e15bee6d7cfc..0c96bf8525b0 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c | |||
| @@ -358,26 +358,22 @@ MODULE_DEVICE_TABLE( pci, gemtek_pci_id ); | |||
| 358 | 358 | ||
| 359 | static int mx = 1; | 359 | static int mx = 1; |
| 360 | 360 | ||
| 361 | static int gemtek_pci_exclusive_open(struct inode *inode, struct file *file) | 361 | static int gemtek_pci_exclusive_open(struct file *file) |
| 362 | { | 362 | { |
| 363 | return test_and_set_bit(0, &in_use) ? -EBUSY : 0; | 363 | return test_and_set_bit(0, &in_use) ? -EBUSY : 0; |
| 364 | } | 364 | } |
| 365 | 365 | ||
| 366 | static int gemtek_pci_exclusive_release(struct inode *inode, struct file *file) | 366 | static int gemtek_pci_exclusive_release(struct file *file) |
| 367 | { | 367 | { |
| 368 | clear_bit(0, &in_use); | 368 | clear_bit(0, &in_use); |
| 369 | return 0; | 369 | return 0; |
| 370 | } | 370 | } |
| 371 | 371 | ||
| 372 | static const struct file_operations gemtek_pci_fops = { | 372 | static const struct v4l2_file_operations gemtek_pci_fops = { |
| 373 | .owner = THIS_MODULE, | 373 | .owner = THIS_MODULE, |
| 374 | .open = gemtek_pci_exclusive_open, | 374 | .open = gemtek_pci_exclusive_open, |
| 375 | .release = gemtek_pci_exclusive_release, | 375 | .release = gemtek_pci_exclusive_release, |
| 376 | .ioctl = video_ioctl2, | 376 | .ioctl = video_ioctl2, |
| 377 | #ifdef CONFIG_COMPAT | ||
| 378 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 379 | #endif | ||
| 380 | .llseek = no_llseek, | ||
| 381 | }; | 377 | }; |
| 382 | 378 | ||
| 383 | static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { | 379 | static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { |
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index e13118da307b..2b68be773f13 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c | |||
| @@ -394,26 +394,22 @@ static struct v4l2_queryctrl radio_qctrl[] = { | |||
| 394 | } | 394 | } |
| 395 | }; | 395 | }; |
| 396 | 396 | ||
| 397 | static int gemtek_exclusive_open(struct inode *inode, struct file *file) | 397 | static int gemtek_exclusive_open(struct file *file) |
| 398 | { | 398 | { |
| 399 | return test_and_set_bit(0, &in_use) ? -EBUSY : 0; | 399 | return test_and_set_bit(0, &in_use) ? -EBUSY : 0; |
| 400 | } | 400 | } |
| 401 | 401 | ||
| 402 | static int gemtek_exclusive_release(struct inode *inode, struct file *file) | 402 | static int gemtek_exclusive_release(struct file *file) |
| 403 | { | 403 | { |
| 404 | clear_bit(0, &in_use); | 404 | clear_bit(0, &in_use); |
| 405 | return 0; | 405 | return 0; |
| 406 | } | 406 | } |
| 407 | 407 | ||
| 408 | static const struct file_operations gemtek_fops = { | 408 | static const struct v4l2_file_operations gemtek_fops = { |
| 409 | .owner = THIS_MODULE, | 409 | .owner = THIS_MODULE, |
| 410 | .open = gemtek_exclusive_open, | 410 | .open = gemtek_exclusive_open, |
| 411 | .release = gemtek_exclusive_release, | 411 | .release = gemtek_exclusive_release, |
| 412 | .ioctl = video_ioctl2, | 412 | .ioctl = video_ioctl2, |
| 413 | #ifdef CONFIG_COMPAT | ||
| 414 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 415 | #endif | ||
| 416 | .llseek = no_llseek | ||
| 417 | }; | 413 | }; |
| 418 | 414 | ||
| 419 | static int vidioc_querycap(struct file *file, void *priv, | 415 | static int vidioc_querycap(struct file *file, void *priv, |
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index 4bf4d007bcfa..ba3a13a90013 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c | |||
| @@ -79,12 +79,12 @@ static unsigned long in_use; | |||
| 79 | 79 | ||
| 80 | static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent); | 80 | static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent); |
| 81 | 81 | ||
| 82 | static int maestro_exclusive_open(struct inode *inode, struct file *file) | 82 | static int maestro_exclusive_open(struct file *file) |
| 83 | { | 83 | { |
| 84 | return test_and_set_bit(0, &in_use) ? -EBUSY : 0; | 84 | return test_and_set_bit(0, &in_use) ? -EBUSY : 0; |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | static int maestro_exclusive_release(struct inode *inode, struct file *file) | 87 | static int maestro_exclusive_release(struct file *file) |
| 88 | { | 88 | { |
| 89 | clear_bit(0, &in_use); | 89 | clear_bit(0, &in_use); |
| 90 | return 0; | 90 | return 0; |
| @@ -110,15 +110,11 @@ static struct pci_driver maestro_r_driver = { | |||
| 110 | .remove = __devexit_p(maestro_remove), | 110 | .remove = __devexit_p(maestro_remove), |
| 111 | }; | 111 | }; |
| 112 | 112 | ||
| 113 | static const struct file_operations maestro_fops = { | 113 | static const struct v4l2_file_operations maestro_fops = { |
| 114 | .owner = THIS_MODULE, | 114 | .owner = THIS_MODULE, |
| 115 | .open = maestro_exclusive_open, | 115 | .open = maestro_exclusive_open, |
| 116 | .release = maestro_exclusive_release, | 116 | .release = maestro_exclusive_release, |
| 117 | .ioctl = video_ioctl2, | 117 | .ioctl = video_ioctl2, |
| 118 | #ifdef CONFIG_COMPAT | ||
| 119 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 120 | #endif | ||
| 121 | .llseek = no_llseek, | ||
| 122 | }; | 118 | }; |
| 123 | 119 | ||
| 124 | struct radio_device { | 120 | struct radio_device { |
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index c777a17b00bc..c5dc00aa9c9f 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c | |||
| @@ -100,26 +100,22 @@ static unsigned long in_use; | |||
| 100 | #define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF) | 100 | #define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF) |
| 101 | 101 | ||
| 102 | 102 | ||
| 103 | static int maxiradio_exclusive_open(struct inode *inode, struct file *file) | 103 | static int maxiradio_exclusive_open(struct file *file) |
| 104 | { | 104 | { |
| 105 | return test_and_set_bit(0, &in_use) ? -EBUSY : 0; | 105 | return test_and_set_bit(0, &in_use) ? -EBUSY : 0; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | static int maxiradio_exclusive_release(struct inode *inode, struct file *file) | 108 | static int maxiradio_exclusive_release(struct file *file) |
| 109 | { | 109 | { |
| 110 | clear_bit(0, &in_use); | 110 | clear_bit(0, &in_use); |
| 111 | return 0; | 111 | return 0; |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | static const struct file_operations maxiradio_fops = { | 114 | static const struct v4l2_file_operations maxiradio_fops = { |
| 115 | .owner = THIS_MODULE, | 115 | .owner = THIS_MODULE, |
| 116 | .open = maxiradio_exclusive_open, | 116 | .open = maxiradio_exclusive_open, |
| 117 | .release = maxiradio_exclusive_release, | 117 | .release = maxiradio_exclusive_release, |
| 118 | .ioctl = video_ioctl2, | 118 | .ioctl = video_ioctl2, |
| 119 | #ifdef CONFIG_COMPAT | ||
| 120 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 121 | #endif | ||
| 122 | .llseek = no_llseek, | ||
| 123 | }; | 119 | }; |
| 124 | 120 | ||
| 125 | static struct radio_device | 121 | static struct radio_device |
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index e730eddb2bb5..0747dc8862b0 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c | |||
| @@ -127,8 +127,8 @@ static struct v4l2_queryctrl radio_qctrl[] = { | |||
| 127 | static int usb_amradio_probe(struct usb_interface *intf, | 127 | static int usb_amradio_probe(struct usb_interface *intf, |
| 128 | const struct usb_device_id *id); | 128 | const struct usb_device_id *id); |
| 129 | static void usb_amradio_disconnect(struct usb_interface *intf); | 129 | static void usb_amradio_disconnect(struct usb_interface *intf); |
| 130 | static int usb_amradio_open(struct inode *inode, struct file *file); | 130 | static int usb_amradio_open(struct file *file); |
| 131 | static int usb_amradio_close(struct inode *inode, struct file *file); | 131 | static int usb_amradio_close(struct file *file); |
| 132 | static int usb_amradio_suspend(struct usb_interface *intf, | 132 | static int usb_amradio_suspend(struct usb_interface *intf, |
| 133 | pm_message_t message); | 133 | pm_message_t message); |
| 134 | static int usb_amradio_resume(struct usb_interface *intf); | 134 | static int usb_amradio_resume(struct usb_interface *intf); |
| @@ -500,7 +500,7 @@ static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) | |||
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | /* open device - amradio_start() and amradio_setfreq() */ | 502 | /* open device - amradio_start() and amradio_setfreq() */ |
| 503 | static int usb_amradio_open(struct inode *inode, struct file *file) | 503 | static int usb_amradio_open(struct file *file) |
| 504 | { | 504 | { |
| 505 | struct amradio_device *radio = video_get_drvdata(video_devdata(file)); | 505 | struct amradio_device *radio = video_get_drvdata(video_devdata(file)); |
| 506 | 506 | ||
| @@ -525,7 +525,7 @@ static int usb_amradio_open(struct inode *inode, struct file *file) | |||
| 525 | } | 525 | } |
| 526 | 526 | ||
| 527 | /*close device */ | 527 | /*close device */ |
| 528 | static int usb_amradio_close(struct inode *inode, struct file *file) | 528 | static int usb_amradio_close(struct file *file) |
| 529 | { | 529 | { |
| 530 | struct amradio_device *radio = video_get_drvdata(video_devdata(file)); | 530 | struct amradio_device *radio = video_get_drvdata(video_devdata(file)); |
| 531 | int retval; | 531 | int retval; |
| @@ -572,15 +572,11 @@ static int usb_amradio_resume(struct usb_interface *intf) | |||
| 572 | } | 572 | } |
| 573 | 573 | ||
| 574 | /* File system interface */ | 574 | /* File system interface */ |
| 575 | static const struct file_operations usb_amradio_fops = { | 575 | static const struct v4l2_file_operations usb_amradio_fops = { |
| 576 | .owner = THIS_MODULE, | 576 | .owner = THIS_MODULE, |
| 577 | .open = usb_amradio_open, | 577 | .open = usb_amradio_open, |
| 578 | .release = usb_amradio_close, | 578 | .release = usb_amradio_close, |
| 579 | .ioctl = video_ioctl2, | 579 | .ioctl = video_ioctl2, |
| 580 | #ifdef CONFIG_COMPAT | ||
| 581 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 582 | #endif | ||
| 583 | .llseek = no_llseek, | ||
| 584 | }; | 580 | }; |
| 585 | 581 | ||
| 586 | static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = { | 582 | static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = { |
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index 7704f243b6f0..2587227214bf 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c | |||
| @@ -280,26 +280,22 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 280 | 280 | ||
| 281 | static struct rt_device rtrack2_unit; | 281 | static struct rt_device rtrack2_unit; |
| 282 | 282 | ||
| 283 | static int rtrack2_exclusive_open(struct inode *inode, struct file *file) | 283 | static int rtrack2_exclusive_open(struct file *file) |
| 284 | { | 284 | { |
| 285 | return test_and_set_bit(0, &rtrack2_unit.in_use) ? -EBUSY : 0; | 285 | return test_and_set_bit(0, &rtrack2_unit.in_use) ? -EBUSY : 0; |
| 286 | } | 286 | } |
| 287 | 287 | ||
| 288 | static int rtrack2_exclusive_release(struct inode *inode, struct file *file) | 288 | static int rtrack2_exclusive_release(struct file *file) |
| 289 | { | 289 | { |
| 290 | clear_bit(0, &rtrack2_unit.in_use); | 290 | clear_bit(0, &rtrack2_unit.in_use); |
| 291 | return 0; | 291 | return 0; |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | static const struct file_operations rtrack2_fops = { | 294 | static const struct v4l2_file_operations rtrack2_fops = { |
| 295 | .owner = THIS_MODULE, | 295 | .owner = THIS_MODULE, |
| 296 | .open = rtrack2_exclusive_open, | 296 | .open = rtrack2_exclusive_open, |
| 297 | .release = rtrack2_exclusive_release, | 297 | .release = rtrack2_exclusive_release, |
| 298 | .ioctl = video_ioctl2, | 298 | .ioctl = video_ioctl2, |
| 299 | #ifdef CONFIG_COMPAT | ||
| 300 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 301 | #endif | ||
| 302 | .llseek = no_llseek, | ||
| 303 | }; | 299 | }; |
| 304 | 300 | ||
| 305 | static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { | 301 | static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { |
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 834d43651c70..d358e48c2422 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c | |||
| @@ -280,26 +280,22 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 280 | 280 | ||
| 281 | static struct fmi_device fmi_unit; | 281 | static struct fmi_device fmi_unit; |
| 282 | 282 | ||
| 283 | static int fmi_exclusive_open(struct inode *inode, struct file *file) | 283 | static int fmi_exclusive_open(struct file *file) |
| 284 | { | 284 | { |
| 285 | return test_and_set_bit(0, &fmi_unit.in_use) ? -EBUSY : 0; | 285 | return test_and_set_bit(0, &fmi_unit.in_use) ? -EBUSY : 0; |
| 286 | } | 286 | } |
| 287 | 287 | ||
| 288 | static int fmi_exclusive_release(struct inode *inode, struct file *file) | 288 | static int fmi_exclusive_release(struct file *file) |
| 289 | { | 289 | { |
| 290 | clear_bit(0, &fmi_unit.in_use); | 290 | clear_bit(0, &fmi_unit.in_use); |
| 291 | return 0; | 291 | return 0; |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | static const struct file_operations fmi_fops = { | 294 | static const struct v4l2_file_operations fmi_fops = { |
| 295 | .owner = THIS_MODULE, | 295 | .owner = THIS_MODULE, |
| 296 | .open = fmi_exclusive_open, | 296 | .open = fmi_exclusive_open, |
| 297 | .release = fmi_exclusive_release, | 297 | .release = fmi_exclusive_release, |
| 298 | .ioctl = video_ioctl2, | 298 | .ioctl = video_ioctl2, |
| 299 | #ifdef CONFIG_COMPAT | ||
| 300 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 301 | #endif | ||
| 302 | .llseek = no_llseek, | ||
| 303 | }; | 299 | }; |
| 304 | 300 | ||
| 305 | static const struct v4l2_ioctl_ops fmi_ioctl_ops = { | 301 | static const struct v4l2_ioctl_ops fmi_ioctl_ops = { |
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index b1f47c322e02..92f17a347fa7 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c | |||
| @@ -396,26 +396,22 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 396 | 396 | ||
| 397 | static struct fmr2_device fmr2_unit; | 397 | static struct fmr2_device fmr2_unit; |
| 398 | 398 | ||
| 399 | static int fmr2_exclusive_open(struct inode *inode, struct file *file) | 399 | static int fmr2_exclusive_open(struct file *file) |
| 400 | { | 400 | { |
| 401 | return test_and_set_bit(0, &fmr2_unit.in_use) ? -EBUSY : 0; | 401 | return test_and_set_bit(0, &fmr2_unit.in_use) ? -EBUSY : 0; |
| 402 | } | 402 | } |
| 403 | 403 | ||
| 404 | static int fmr2_exclusive_release(struct inode *inode, struct file *file) | 404 | static int fmr2_exclusive_release(struct file *file) |
| 405 | { | 405 | { |
| 406 | clear_bit(0, &fmr2_unit.in_use); | 406 | clear_bit(0, &fmr2_unit.in_use); |
| 407 | return 0; | 407 | return 0; |
| 408 | } | 408 | } |
| 409 | 409 | ||
| 410 | static const struct file_operations fmr2_fops = { | 410 | static const struct v4l2_file_operations fmr2_fops = { |
| 411 | .owner = THIS_MODULE, | 411 | .owner = THIS_MODULE, |
| 412 | .open = fmr2_exclusive_open, | 412 | .open = fmr2_exclusive_open, |
| 413 | .release = fmr2_exclusive_release, | 413 | .release = fmr2_exclusive_release, |
| 414 | .ioctl = video_ioctl2, | 414 | .ioctl = video_ioctl2, |
| 415 | #ifdef CONFIG_COMPAT | ||
| 416 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 417 | #endif | ||
| 418 | .llseek = no_llseek, | ||
| 419 | }; | 415 | }; |
| 420 | 416 | ||
| 421 | static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { | 417 | static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { |
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 3e1830293de5..67cbce82cb91 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c | |||
| @@ -96,6 +96,8 @@ | |||
| 96 | * 2008-10-20 Alexey Klimov <klimov.linux@gmail.com> | 96 | * 2008-10-20 Alexey Klimov <klimov.linux@gmail.com> |
| 97 | * - add support for KWorld USB FM Radio FM700 | 97 | * - add support for KWorld USB FM Radio FM700 |
| 98 | * - blacklisted KWorld radio in hid-core.c and hid-ids.h | 98 | * - blacklisted KWorld radio in hid-core.c and hid-ids.h |
| 99 | * 2008-12-03 Mark Lord <mlord@pobox.com> | ||
| 100 | * - add support for DealExtreme USB Radio | ||
| 99 | * | 101 | * |
| 100 | * ToDo: | 102 | * ToDo: |
| 101 | * - add firmware download/update support | 103 | * - add firmware download/update support |
| @@ -138,6 +140,8 @@ static struct usb_device_id si470x_usb_driver_id_table[] = { | |||
| 138 | { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) }, | 140 | { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) }, |
| 139 | /* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */ | 141 | /* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */ |
| 140 | { USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) }, | 142 | { USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) }, |
| 143 | /* DealExtreme USB Radio */ | ||
| 144 | { USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) }, | ||
| 141 | /* Terminating entry */ | 145 | /* Terminating entry */ |
| 142 | { } | 146 | { } |
| 143 | }; | 147 | }; |
| @@ -1075,7 +1079,7 @@ static unsigned int si470x_fops_poll(struct file *file, | |||
| 1075 | /* | 1079 | /* |
| 1076 | * si470x_fops_open - file open | 1080 | * si470x_fops_open - file open |
| 1077 | */ | 1081 | */ |
| 1078 | static int si470x_fops_open(struct inode *inode, struct file *file) | 1082 | static int si470x_fops_open(struct file *file) |
| 1079 | { | 1083 | { |
| 1080 | struct si470x_device *radio = video_drvdata(file); | 1084 | struct si470x_device *radio = video_drvdata(file); |
| 1081 | int retval; | 1085 | int retval; |
| @@ -1105,7 +1109,7 @@ done: | |||
| 1105 | /* | 1109 | /* |
| 1106 | * si470x_fops_release - file release | 1110 | * si470x_fops_release - file release |
| 1107 | */ | 1111 | */ |
| 1108 | static int si470x_fops_release(struct inode *inode, struct file *file) | 1112 | static int si470x_fops_release(struct file *file) |
| 1109 | { | 1113 | { |
| 1110 | struct si470x_device *radio = video_drvdata(file); | 1114 | struct si470x_device *radio = video_drvdata(file); |
| 1111 | int retval = 0; | 1115 | int retval = 0; |
| @@ -1147,15 +1151,11 @@ done: | |||
| 1147 | /* | 1151 | /* |
| 1148 | * si470x_fops - file operations interface | 1152 | * si470x_fops - file operations interface |
| 1149 | */ | 1153 | */ |
| 1150 | static const struct file_operations si470x_fops = { | 1154 | static const struct v4l2_file_operations si470x_fops = { |
| 1151 | .owner = THIS_MODULE, | 1155 | .owner = THIS_MODULE, |
| 1152 | .llseek = no_llseek, | ||
| 1153 | .read = si470x_fops_read, | 1156 | .read = si470x_fops_read, |
| 1154 | .poll = si470x_fops_poll, | 1157 | .poll = si470x_fops_poll, |
| 1155 | .ioctl = video_ioctl2, | 1158 | .ioctl = video_ioctl2, |
| 1156 | #ifdef CONFIG_COMPAT | ||
| 1157 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1158 | #endif | ||
| 1159 | .open = si470x_fops_open, | 1159 | .open = si470x_fops_open, |
| 1160 | .release = si470x_fops_release, | 1160 | .release = si470x_fops_release, |
| 1161 | }; | 1161 | }; |
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c new file mode 100644 index 000000000000..4d35308fc1ff --- /dev/null +++ b/drivers/media/radio/radio-tea5764.c | |||
| @@ -0,0 +1,634 @@ | |||
| 1 | /* | ||
| 2 | * driver/media/radio/radio-tea5764.c | ||
| 3 | * | ||
| 4 | * Driver for TEA5764 radio chip for linux 2.6. | ||
| 5 | * This driver is for TEA5764 chip from NXP, used in EZX phones from Motorola. | ||
| 6 | * The I2C protocol is used for communicate with chip. | ||
| 7 | * | ||
| 8 | * Based in radio-tea5761.c Copyright (C) 2005 Nokia Corporation | ||
| 9 | * | ||
| 10 | * Copyright (c) 2008 Fabio Belavenuto <belavenuto@gmail.com> | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or modify | ||
| 13 | * it under the terms of the GNU General Public License as published by | ||
| 14 | * the Free Software Foundation; either version 2 of the License, or | ||
| 15 | * (at your option) any later version. | ||
| 16 | * | ||
| 17 | * This program is distributed in the hope that it will be useful, | ||
| 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 20 | * GNU General Public License for more details. | ||
| 21 | * | ||
| 22 | * You should have received a copy of the GNU General Public License | ||
| 23 | * along with this program; if not, write to the Free Software | ||
| 24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 25 | * | ||
| 26 | * History: | ||
| 27 | * 2008-12-06 Fabio Belavenuto <belavenuto@gmail.com> | ||
| 28 | * initial code | ||
| 29 | * | ||
| 30 | * TODO: | ||
| 31 | * add platform_data support for IRQs platform dependencies | ||
| 32 | * add RDS support | ||
| 33 | */ | ||
| 34 | #include <linux/kernel.h> | ||
| 35 | #include <linux/module.h> | ||
| 36 | #include <linux/init.h> /* Initdata */ | ||
| 37 | #include <linux/videodev2.h> /* kernel radio structs */ | ||
| 38 | #include <linux/i2c.h> /* I2C */ | ||
| 39 | #include <media/v4l2-common.h> | ||
| 40 | #include <media/v4l2-ioctl.h> | ||
| 41 | #include <linux/version.h> /* for KERNEL_VERSION MACRO */ | ||
| 42 | |||
| 43 | #define DRIVER_VERSION "v0.01" | ||
| 44 | #define RADIO_VERSION KERNEL_VERSION(0, 0, 1) | ||
| 45 | |||
| 46 | #define DRIVER_AUTHOR "Fabio Belavenuto <belavenuto@gmail.com>" | ||
| 47 | #define DRIVER_DESC "A driver for the TEA5764 radio chip for EZX Phones." | ||
| 48 | |||
| 49 | #define PINFO(format, ...)\ | ||
| 50 | printk(KERN_INFO KBUILD_MODNAME ": "\ | ||
| 51 | DRIVER_VERSION ": " format "\n", ## __VA_ARGS__) | ||
| 52 | #define PWARN(format, ...)\ | ||
| 53 | printk(KERN_WARNING KBUILD_MODNAME ": "\ | ||
| 54 | DRIVER_VERSION ": " format "\n", ## __VA_ARGS__) | ||
| 55 | # define PDEBUG(format, ...)\ | ||
| 56 | printk(KERN_DEBUG KBUILD_MODNAME ": "\ | ||
| 57 | DRIVER_VERSION ": " format "\n", ## __VA_ARGS__) | ||
| 58 | |||
| 59 | /* Frequency limits in MHz -- these are European values. For Japanese | ||
| 60 | devices, that would be 76000 and 91000. */ | ||
| 61 | #define FREQ_MIN 87500 | ||
| 62 | #define FREQ_MAX 108000 | ||
| 63 | #define FREQ_MUL 16 | ||
| 64 | |||
| 65 | /* TEA5764 registers */ | ||
| 66 | #define TEA5764_MANID 0x002b | ||
| 67 | #define TEA5764_CHIPID 0x5764 | ||
| 68 | |||
| 69 | #define TEA5764_INTREG_BLMSK 0x0001 | ||
| 70 | #define TEA5764_INTREG_FRRMSK 0x0002 | ||
| 71 | #define TEA5764_INTREG_LEVMSK 0x0008 | ||
| 72 | #define TEA5764_INTREG_IFMSK 0x0010 | ||
| 73 | #define TEA5764_INTREG_BLMFLAG 0x0100 | ||
| 74 | #define TEA5764_INTREG_FRRFLAG 0x0200 | ||
| 75 | #define TEA5764_INTREG_LEVFLAG 0x0800 | ||
| 76 | #define TEA5764_INTREG_IFFLAG 0x1000 | ||
| 77 | |||
| 78 | #define TEA5764_FRQSET_SUD 0x8000 | ||
| 79 | #define TEA5764_FRQSET_SM 0x4000 | ||
| 80 | |||
| 81 | #define TEA5764_TNCTRL_PUPD1 0x8000 | ||
| 82 | #define TEA5764_TNCTRL_PUPD0 0x4000 | ||
| 83 | #define TEA5764_TNCTRL_BLIM 0x2000 | ||
| 84 | #define TEA5764_TNCTRL_SWPM 0x1000 | ||
| 85 | #define TEA5764_TNCTRL_IFCTC 0x0800 | ||
| 86 | #define TEA5764_TNCTRL_AFM 0x0400 | ||
| 87 | #define TEA5764_TNCTRL_SMUTE 0x0200 | ||
| 88 | #define TEA5764_TNCTRL_SNC 0x0100 | ||
| 89 | #define TEA5764_TNCTRL_MU 0x0080 | ||
| 90 | #define TEA5764_TNCTRL_SSL1 0x0040 | ||
| 91 | #define TEA5764_TNCTRL_SSL0 0x0020 | ||
| 92 | #define TEA5764_TNCTRL_HLSI 0x0010 | ||
| 93 | #define TEA5764_TNCTRL_MST 0x0008 | ||
| 94 | #define TEA5764_TNCTRL_SWP 0x0004 | ||
| 95 | #define TEA5764_TNCTRL_DTC 0x0002 | ||
| 96 | #define TEA5764_TNCTRL_AHLSI 0x0001 | ||
| 97 | |||
| 98 | #define TEA5764_TUNCHK_LEVEL(x) (((x) & 0x00F0) >> 4) | ||
| 99 | #define TEA5764_TUNCHK_IFCNT(x) (((x) & 0xFE00) >> 9) | ||
| 100 | #define TEA5764_TUNCHK_TUNTO 0x0100 | ||
| 101 | #define TEA5764_TUNCHK_LD 0x0008 | ||
| 102 | #define TEA5764_TUNCHK_STEREO 0x0004 | ||
| 103 | |||
| 104 | #define TEA5764_TESTREG_TRIGFR 0x0800 | ||
| 105 | |||
| 106 | struct tea5764_regs { | ||
| 107 | u16 intreg; /* INTFLAG & INTMSK */ | ||
| 108 | u16 frqset; /* FRQSETMSB & FRQSETLSB */ | ||
| 109 | u16 tnctrl; /* TNCTRL1 & TNCTRL2 */ | ||
| 110 | u16 frqchk; /* FRQCHKMSB & FRQCHKLSB */ | ||
| 111 | u16 tunchk; /* IFCHK & LEVCHK */ | ||
| 112 | u16 testreg; /* TESTBITS & TESTMODE */ | ||
| 113 | u16 rdsstat; /* RDSSTAT1 & RDSSTAT2 */ | ||
| 114 | u16 rdslb; /* RDSLBMSB & RDSLBLSB */ | ||
| 115 | u16 rdspb; /* RDSPBMSB & RDSPBLSB */ | ||
| 116 | u16 rdsbc; /* RDSBBC & RDSGBC */ | ||
| 117 | u16 rdsctrl; /* RDSCTRL1 & RDSCTRL2 */ | ||
| 118 | u16 rdsbbl; /* PAUSEDET & RDSBBL */ | ||
| 119 | u16 manid; /* MANID1 & MANID2 */ | ||
| 120 | u16 chipid; /* CHIPID1 & CHIPID2 */ | ||
| 121 | } __attribute__ ((packed)); | ||
| 122 | |||
| 123 | struct tea5764_write_regs { | ||
| 124 | u8 intreg; /* INTMSK */ | ||
| 125 | u16 frqset; /* FRQSETMSB & FRQSETLSB */ | ||
| 126 | u16 tnctrl; /* TNCTRL1 & TNCTRL2 */ | ||
| 127 | u16 testreg; /* TESTBITS & TESTMODE */ | ||
| 128 | u16 rdsctrl; /* RDSCTRL1 & RDSCTRL2 */ | ||
| 129 | u16 rdsbbl; /* PAUSEDET & RDSBBL */ | ||
| 130 | } __attribute__ ((packed)); | ||
| 131 | |||
| 132 | #ifndef RADIO_TEA5764_XTAL | ||
| 133 | #define RADIO_TEA5764_XTAL 1 | ||
| 134 | #endif | ||
| 135 | |||
| 136 | static int radio_nr = -1; | ||
| 137 | static int use_xtal = RADIO_TEA5764_XTAL; | ||
| 138 | |||
| 139 | struct tea5764_device { | ||
| 140 | struct i2c_client *i2c_client; | ||
| 141 | struct video_device *videodev; | ||
| 142 | struct tea5764_regs regs; | ||
| 143 | struct mutex mutex; | ||
| 144 | int users; | ||
| 145 | }; | ||
| 146 | |||
| 147 | /* I2C code related */ | ||
| 148 | int tea5764_i2c_read(struct tea5764_device *radio) | ||
| 149 | { | ||
| 150 | int i; | ||
| 151 | u16 *p = (u16 *) &radio->regs; | ||
| 152 | |||
| 153 | struct i2c_msg msgs[1] = { | ||
| 154 | { radio->i2c_client->addr, I2C_M_RD, sizeof(radio->regs), | ||
| 155 | (void *)&radio->regs }, | ||
| 156 | }; | ||
| 157 | if (i2c_transfer(radio->i2c_client->adapter, msgs, 1) != 1) | ||
| 158 | return -EIO; | ||
| 159 | for (i = 0; i < sizeof(struct tea5764_regs) / sizeof(u16); i++) | ||
| 160 | p[i] = __be16_to_cpu(p[i]); | ||
| 161 | |||
| 162 | return 0; | ||
| 163 | } | ||
| 164 | |||
| 165 | int tea5764_i2c_write(struct tea5764_device *radio) | ||
| 166 | { | ||
| 167 | struct tea5764_write_regs wr; | ||
| 168 | struct tea5764_regs *r = &radio->regs; | ||
| 169 | struct i2c_msg msgs[1] = { | ||
| 170 | { radio->i2c_client->addr, 0, sizeof(wr), (void *) &wr }, | ||
| 171 | }; | ||
| 172 | wr.intreg = r->intreg & 0xff; | ||
| 173 | wr.frqset = __cpu_to_be16(r->frqset); | ||
| 174 | wr.tnctrl = __cpu_to_be16(r->tnctrl); | ||
| 175 | wr.testreg = __cpu_to_be16(r->testreg); | ||
| 176 | wr.rdsctrl = __cpu_to_be16(r->rdsctrl); | ||
| 177 | wr.rdsbbl = __cpu_to_be16(r->rdsbbl); | ||
| 178 | if (i2c_transfer(radio->i2c_client->adapter, msgs, 1) != 1) | ||
| 179 | return -EIO; | ||
| 180 | return 0; | ||
| 181 | } | ||
| 182 | |||
| 183 | /* V4L2 code related */ | ||
| 184 | static struct v4l2_queryctrl radio_qctrl[] = { | ||
| 185 | { | ||
| 186 | .id = V4L2_CID_AUDIO_MUTE, | ||
| 187 | .name = "Mute", | ||
| 188 | .minimum = 0, | ||
| 189 | .maximum = 1, | ||
| 190 | .default_value = 1, | ||
| 191 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
| 192 | } | ||
| 193 | }; | ||
| 194 | |||
| 195 | static void tea5764_power_up(struct tea5764_device *radio) | ||
| 196 | { | ||
| 197 | struct tea5764_regs *r = &radio->regs; | ||
| 198 | |||
| 199 | if (!(r->tnctrl & TEA5764_TNCTRL_PUPD0)) { | ||
| 200 | r->tnctrl &= ~(TEA5764_TNCTRL_AFM | TEA5764_TNCTRL_MU | | ||
| 201 | TEA5764_TNCTRL_HLSI); | ||
| 202 | if (!use_xtal) | ||
| 203 | r->testreg |= TEA5764_TESTREG_TRIGFR; | ||
| 204 | else | ||
| 205 | r->testreg &= ~TEA5764_TESTREG_TRIGFR; | ||
| 206 | |||
| 207 | r->tnctrl |= TEA5764_TNCTRL_PUPD0; | ||
| 208 | tea5764_i2c_write(radio); | ||
| 209 | } | ||
| 210 | } | ||
| 211 | |||
| 212 | static void tea5764_power_down(struct tea5764_device *radio) | ||
| 213 | { | ||
| 214 | struct tea5764_regs *r = &radio->regs; | ||
| 215 | |||
| 216 | if (r->tnctrl & TEA5764_TNCTRL_PUPD0) { | ||
| 217 | r->tnctrl &= ~TEA5764_TNCTRL_PUPD0; | ||
| 218 | tea5764_i2c_write(radio); | ||
| 219 | } | ||
| 220 | } | ||
| 221 | |||
| 222 | static void tea5764_set_freq(struct tea5764_device *radio, int freq) | ||
| 223 | { | ||
| 224 | struct tea5764_regs *r = &radio->regs; | ||
| 225 | |||
| 226 | /* formula: (freq [+ or -] 225000) / 8192 */ | ||
| 227 | if (r->tnctrl & TEA5764_TNCTRL_HLSI) | ||
| 228 | r->frqset = (freq + 225000) / 8192; | ||
| 229 | else | ||
| 230 | r->frqset = (freq - 225000) / 8192; | ||
| 231 | } | ||
| 232 | |||
| 233 | static int tea5764_get_freq(struct tea5764_device *radio) | ||
| 234 | { | ||
| 235 | struct tea5764_regs *r = &radio->regs; | ||
| 236 | |||
| 237 | if (r->tnctrl & TEA5764_TNCTRL_HLSI) | ||
| 238 | return (r->frqchk * 8192) - 225000; | ||
| 239 | else | ||
| 240 | return (r->frqchk * 8192) + 225000; | ||
| 241 | } | ||
| 242 | |||
| 243 | /* tune an frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */ | ||
| 244 | static void tea5764_tune(struct tea5764_device *radio, int freq) | ||
| 245 | { | ||
| 246 | tea5764_set_freq(radio, freq); | ||
| 247 | if (tea5764_i2c_write(radio)) | ||
| 248 | PWARN("Could not set frequency!"); | ||
| 249 | } | ||
| 250 | |||
| 251 | static void tea5764_set_audout_mode(struct tea5764_device *radio, int audmode) | ||
| 252 | { | ||
| 253 | struct tea5764_regs *r = &radio->regs; | ||
| 254 | int tnctrl = r->tnctrl; | ||
| 255 | |||
| 256 | if (audmode == V4L2_TUNER_MODE_MONO) | ||
| 257 | r->tnctrl |= TEA5764_TNCTRL_MST; | ||
| 258 | else | ||
| 259 | r->tnctrl &= ~TEA5764_TNCTRL_MST; | ||
| 260 | if (tnctrl != r->tnctrl) | ||
| 261 | tea5764_i2c_write(radio); | ||
| 262 | } | ||
| 263 | |||
| 264 | static int tea5764_get_audout_mode(struct tea5764_device *radio) | ||
| 265 | { | ||
| 266 | struct tea5764_regs *r = &radio->regs; | ||
| 267 | |||
| 268 | if (r->tnctrl & TEA5764_TNCTRL_MST) | ||
| 269 | return V4L2_TUNER_MODE_MONO; | ||
| 270 | else | ||
| 271 | return V4L2_TUNER_MODE_STEREO; | ||
| 272 | } | ||
| 273 | |||
| 274 | static void tea5764_mute(struct tea5764_device *radio, int on) | ||
| 275 | { | ||
| 276 | struct tea5764_regs *r = &radio->regs; | ||
| 277 | int tnctrl = r->tnctrl; | ||
| 278 | |||
| 279 | if (on) | ||
| 280 | r->tnctrl |= TEA5764_TNCTRL_MU; | ||
| 281 | else | ||
| 282 | r->tnctrl &= ~TEA5764_TNCTRL_MU; | ||
| 283 | if (tnctrl != r->tnctrl) | ||
| 284 | tea5764_i2c_write(radio); | ||
| 285 | } | ||
| 286 | |||
| 287 | static int tea5764_is_muted(struct tea5764_device *radio) | ||
| 288 | { | ||
| 289 | return radio->regs.tnctrl & TEA5764_TNCTRL_MU; | ||
| 290 | } | ||
| 291 | |||
| 292 | /* V4L2 vidioc */ | ||
| 293 | static int vidioc_querycap(struct file *file, void *priv, | ||
| 294 | struct v4l2_capability *v) | ||
| 295 | { | ||
| 296 | struct tea5764_device *radio = video_drvdata(file); | ||
| 297 | struct video_device *dev = radio->videodev; | ||
| 298 | |||
| 299 | strlcpy(v->driver, dev->dev.driver->name, sizeof(v->driver)); | ||
| 300 | strlcpy(v->card, dev->name, sizeof(v->card)); | ||
| 301 | snprintf(v->bus_info, sizeof(v->bus_info), "I2C:%s", dev->dev.bus_id); | ||
| 302 | v->version = RADIO_VERSION; | ||
| 303 | v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; | ||
| 304 | return 0; | ||
| 305 | } | ||
| 306 | |||
| 307 | static int vidioc_g_tuner(struct file *file, void *priv, | ||
| 308 | struct v4l2_tuner *v) | ||
| 309 | { | ||
| 310 | struct tea5764_device *radio = video_drvdata(file); | ||
| 311 | struct tea5764_regs *r = &radio->regs; | ||
| 312 | |||
| 313 | if (v->index > 0) | ||
| 314 | return -EINVAL; | ||
| 315 | |||
| 316 | memset(v, 0, sizeof(v)); | ||
| 317 | strcpy(v->name, "FM"); | ||
| 318 | v->type = V4L2_TUNER_RADIO; | ||
| 319 | tea5764_i2c_read(radio); | ||
| 320 | v->rangelow = FREQ_MIN * FREQ_MUL; | ||
| 321 | v->rangehigh = FREQ_MAX * FREQ_MUL; | ||
| 322 | v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; | ||
| 323 | if (r->tunchk & TEA5764_TUNCHK_STEREO) | ||
| 324 | v->rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
| 325 | v->audmode = tea5764_get_audout_mode(radio); | ||
| 326 | v->signal = TEA5764_TUNCHK_LEVEL(r->tunchk) * 0xffff / 0xf; | ||
| 327 | v->afc = TEA5764_TUNCHK_IFCNT(r->tunchk); | ||
| 328 | |||
| 329 | return 0; | ||
| 330 | } | ||
| 331 | |||
| 332 | static int vidioc_s_tuner(struct file *file, void *priv, | ||
| 333 | struct v4l2_tuner *v) | ||
| 334 | { | ||
| 335 | struct tea5764_device *radio = video_drvdata(file); | ||
| 336 | |||
| 337 | if (v->index > 0) | ||
| 338 | return -EINVAL; | ||
| 339 | |||
| 340 | tea5764_set_audout_mode(radio, v->audmode); | ||
| 341 | return 0; | ||
| 342 | } | ||
| 343 | |||
| 344 | static int vidioc_s_frequency(struct file *file, void *priv, | ||
| 345 | struct v4l2_frequency *f) | ||
| 346 | { | ||
| 347 | struct tea5764_device *radio = video_drvdata(file); | ||
| 348 | |||
| 349 | if (f->tuner != 0) | ||
| 350 | return -EINVAL; | ||
| 351 | if (f->frequency == 0) { | ||
| 352 | /* We special case this as a power down control. */ | ||
| 353 | tea5764_power_down(radio); | ||
| 354 | } | ||
| 355 | if (f->frequency < (FREQ_MIN * FREQ_MUL)) | ||
| 356 | return -EINVAL; | ||
| 357 | if (f->frequency > (FREQ_MAX * FREQ_MUL)) | ||
| 358 | return -EINVAL; | ||
| 359 | tea5764_power_up(radio); | ||
| 360 | tea5764_tune(radio, (f->frequency * 125) / 2); | ||
| 361 | return 0; | ||
| 362 | } | ||
| 363 | |||
| 364 | static int vidioc_g_frequency(struct file *file, void *priv, | ||
| 365 | struct v4l2_frequency *f) | ||
| 366 | { | ||
| 367 | struct tea5764_device *radio = video_drvdata(file); | ||
| 368 | struct tea5764_regs *r = &radio->regs; | ||
| 369 | |||
| 370 | tea5764_i2c_read(radio); | ||
| 371 | memset(f, 0, sizeof(f)); | ||
| 372 | f->type = V4L2_TUNER_RADIO; | ||
| 373 | if (r->tnctrl & TEA5764_TNCTRL_PUPD0) | ||
| 374 | f->frequency = (tea5764_get_freq(radio) * 2) / 125; | ||
| 375 | else | ||
| 376 | f->frequency = 0; | ||
| 377 | |||
| 378 | return 0; | ||
| 379 | } | ||
| 380 | |||
| 381 | static int vidioc_queryctrl(struct file *file, void *priv, | ||
| 382 | struct v4l2_queryctrl *qc) | ||
| 383 | { | ||
| 384 | int i; | ||
| 385 | |||
| 386 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { | ||
| 387 | if (qc->id && qc->id == radio_qctrl[i].id) { | ||
| 388 | memcpy(qc, &(radio_qctrl[i]), sizeof(*qc)); | ||
| 389 | return 0; | ||
| 390 | } | ||
| 391 | } | ||
| 392 | return -EINVAL; | ||
| 393 | } | ||
| 394 | |||
| 395 | static int vidioc_g_ctrl(struct file *file, void *priv, | ||
| 396 | struct v4l2_control *ctrl) | ||
| 397 | { | ||
| 398 | struct tea5764_device *radio = video_drvdata(file); | ||
| 399 | |||
| 400 | switch (ctrl->id) { | ||
| 401 | case V4L2_CID_AUDIO_MUTE: | ||
| 402 | tea5764_i2c_read(radio); | ||
| 403 | ctrl->value = tea5764_is_muted(radio) ? 1 : 0; | ||
| 404 | return 0; | ||
| 405 | } | ||
| 406 | return -EINVAL; | ||
| 407 | } | ||
| 408 | |||
| 409 | static int vidioc_s_ctrl(struct file *file, void *priv, | ||
| 410 | struct v4l2_control *ctrl) | ||
| 411 | { | ||
| 412 | struct tea5764_device *radio = video_drvdata(file); | ||
| 413 | |||
| 414 | switch (ctrl->id) { | ||
| 415 | case V4L2_CID_AUDIO_MUTE: | ||
| 416 | tea5764_mute(radio, ctrl->value); | ||
| 417 | return 0; | ||
| 418 | } | ||
| 419 | return -EINVAL; | ||
| 420 | } | ||
| 421 | |||
| 422 | static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) | ||
| 423 | { | ||
| 424 | *i = 0; | ||
| 425 | return 0; | ||
| 426 | } | ||
| 427 | |||
| 428 | static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) | ||
| 429 | { | ||
| 430 | if (i != 0) | ||
| 431 | return -EINVAL; | ||
| 432 | return 0; | ||
| 433 | } | ||
| 434 | |||
| 435 | static int vidioc_g_audio(struct file *file, void *priv, | ||
| 436 | struct v4l2_audio *a) | ||
| 437 | { | ||
| 438 | if (a->index > 1) | ||
| 439 | return -EINVAL; | ||
| 440 | |||
| 441 | strcpy(a->name, "Radio"); | ||
| 442 | a->capability = V4L2_AUDCAP_STEREO; | ||
| 443 | return 0; | ||
| 444 | } | ||
| 445 | |||
| 446 | static int vidioc_s_audio(struct file *file, void *priv, | ||
| 447 | struct v4l2_audio *a) | ||
| 448 | { | ||
| 449 | if (a->index != 0) | ||
| 450 | return -EINVAL; | ||
| 451 | |||
| 452 | return 0; | ||
| 453 | } | ||
| 454 | |||
| 455 | static int tea5764_open(struct file *file) | ||
| 456 | { | ||
| 457 | /* Currently we support only one device */ | ||
| 458 | int minor = video_devdata(file)->minor; | ||
| 459 | struct tea5764_device *radio = video_drvdata(file); | ||
| 460 | |||
| 461 | if (radio->videodev->minor != minor) | ||
| 462 | return -ENODEV; | ||
| 463 | |||
| 464 | mutex_lock(&radio->mutex); | ||
| 465 | /* Only exclusive access */ | ||
| 466 | if (radio->users) { | ||
| 467 | mutex_unlock(&radio->mutex); | ||
| 468 | return -EBUSY; | ||
| 469 | } | ||
| 470 | radio->users++; | ||
| 471 | mutex_unlock(&radio->mutex); | ||
| 472 | file->private_data = radio; | ||
| 473 | return 0; | ||
| 474 | } | ||
| 475 | |||
| 476 | static int tea5764_close(struct file *file) | ||
| 477 | { | ||
| 478 | struct tea5764_device *radio = video_drvdata(file); | ||
| 479 | |||
| 480 | if (!radio) | ||
| 481 | return -ENODEV; | ||
| 482 | mutex_lock(&radio->mutex); | ||
| 483 | radio->users--; | ||
| 484 | mutex_unlock(&radio->mutex); | ||
| 485 | return 0; | ||
| 486 | } | ||
| 487 | |||
| 488 | /* File system interface */ | ||
| 489 | static const struct v4l2_file_operations tea5764_fops = { | ||
| 490 | .owner = THIS_MODULE, | ||
| 491 | .open = tea5764_open, | ||
| 492 | .release = tea5764_close, | ||
| 493 | .ioctl = video_ioctl2, | ||
| 494 | }; | ||
| 495 | |||
| 496 | static const struct v4l2_ioctl_ops tea5764_ioctl_ops = { | ||
| 497 | .vidioc_querycap = vidioc_querycap, | ||
| 498 | .vidioc_g_tuner = vidioc_g_tuner, | ||
| 499 | .vidioc_s_tuner = vidioc_s_tuner, | ||
| 500 | .vidioc_g_audio = vidioc_g_audio, | ||
| 501 | .vidioc_s_audio = vidioc_s_audio, | ||
| 502 | .vidioc_g_input = vidioc_g_input, | ||
| 503 | .vidioc_s_input = vidioc_s_input, | ||
| 504 | .vidioc_g_frequency = vidioc_g_frequency, | ||
| 505 | .vidioc_s_frequency = vidioc_s_frequency, | ||
| 506 | .vidioc_queryctrl = vidioc_queryctrl, | ||
| 507 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
| 508 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
| 509 | }; | ||
| 510 | |||
| 511 | /* V4L2 interface */ | ||
| 512 | static struct video_device tea5764_radio_template = { | ||
| 513 | .name = "TEA5764 FM-Radio", | ||
| 514 | .fops = &tea5764_fops, | ||
| 515 | .ioctl_ops = &tea5764_ioctl_ops, | ||
| 516 | .release = video_device_release, | ||
| 517 | }; | ||
| 518 | |||
| 519 | /* I2C probe: check if the device exists and register with v4l if it is */ | ||
| 520 | static int __devinit tea5764_i2c_probe(struct i2c_client *client, | ||
| 521 | const struct i2c_device_id *id) | ||
| 522 | { | ||
| 523 | struct tea5764_device *radio; | ||
| 524 | struct tea5764_regs *r; | ||
| 525 | int ret; | ||
| 526 | |||
| 527 | PDEBUG("probe"); | ||
| 528 | radio = kmalloc(sizeof(struct tea5764_device), GFP_KERNEL); | ||
| 529 | if (!radio) | ||
| 530 | return -ENOMEM; | ||
| 531 | |||
| 532 | mutex_init(&radio->mutex); | ||
| 533 | radio->i2c_client = client; | ||
| 534 | ret = tea5764_i2c_read(radio); | ||
| 535 | if (ret) | ||
| 536 | goto errfr; | ||
| 537 | r = &radio->regs; | ||
| 538 | PDEBUG("chipid = %04X, manid = %04X", r->chipid, r->manid); | ||
| 539 | if (r->chipid != TEA5764_CHIPID || | ||
| 540 | (r->manid & 0x0fff) != TEA5764_MANID) { | ||
| 541 | PWARN("This chip is not a TEA5764!"); | ||
| 542 | ret = -EINVAL; | ||
| 543 | goto errfr; | ||
| 544 | } | ||
| 545 | |||
| 546 | radio->videodev = video_device_alloc(); | ||
| 547 | if (!(radio->videodev)) { | ||
| 548 | ret = -ENOMEM; | ||
| 549 | goto errfr; | ||
| 550 | } | ||
| 551 | memcpy(radio->videodev, &tea5764_radio_template, | ||
| 552 | sizeof(tea5764_radio_template)); | ||
| 553 | |||
| 554 | i2c_set_clientdata(client, radio); | ||
| 555 | video_set_drvdata(radio->videodev, radio); | ||
| 556 | |||
| 557 | ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); | ||
| 558 | if (ret < 0) { | ||
| 559 | PWARN("Could not register video device!"); | ||
| 560 | goto errrel; | ||
| 561 | } | ||
| 562 | |||
| 563 | /* initialize and power off the chip */ | ||
| 564 | tea5764_i2c_read(radio); | ||
| 565 | tea5764_set_audout_mode(radio, V4L2_TUNER_MODE_STEREO); | ||
| 566 | tea5764_mute(radio, 1); | ||
| 567 | tea5764_power_down(radio); | ||
| 568 | |||
| 569 | PINFO("registered."); | ||
| 570 | return 0; | ||
| 571 | errrel: | ||
| 572 | video_device_release(radio->videodev); | ||
| 573 | errfr: | ||
| 574 | kfree(radio); | ||
| 575 | return ret; | ||
| 576 | } | ||
| 577 | |||
| 578 | static int __devexit tea5764_i2c_remove(struct i2c_client *client) | ||
| 579 | { | ||
| 580 | struct tea5764_device *radio = i2c_get_clientdata(client); | ||
| 581 | |||
| 582 | PDEBUG("remove"); | ||
| 583 | if (radio) { | ||
| 584 | tea5764_power_down(radio); | ||
| 585 | video_unregister_device(radio->videodev); | ||
| 586 | kfree(radio); | ||
| 587 | } | ||
| 588 | return 0; | ||
| 589 | } | ||
| 590 | |||
| 591 | /* I2C subsystem interface */ | ||
| 592 | static const struct i2c_device_id tea5764_id[] = { | ||
| 593 | { "radio-tea5764", 0 }, | ||
| 594 | { } /* Terminating entry */ | ||
| 595 | }; | ||
| 596 | MODULE_DEVICE_TABLE(i2c, tea5764_id); | ||
| 597 | |||
| 598 | static struct i2c_driver tea5764_i2c_driver = { | ||
| 599 | .driver = { | ||
| 600 | .name = "radio-tea5764", | ||
| 601 | .owner = THIS_MODULE, | ||
| 602 | }, | ||
| 603 | .probe = tea5764_i2c_probe, | ||
| 604 | .remove = __devexit_p(tea5764_i2c_remove), | ||
| 605 | .id_table = tea5764_id, | ||
| 606 | }; | ||
| 607 | |||
| 608 | /* init the driver */ | ||
| 609 | static int __init tea5764_init(void) | ||
| 610 | { | ||
| 611 | int ret = i2c_add_driver(&tea5764_i2c_driver); | ||
| 612 | |||
| 613 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ": " | ||
| 614 | DRIVER_DESC "\n"); | ||
| 615 | return ret; | ||
| 616 | } | ||
| 617 | |||
| 618 | /* cleanup the driver */ | ||
| 619 | static void __exit tea5764_exit(void) | ||
| 620 | { | ||
| 621 | i2c_del_driver(&tea5764_i2c_driver); | ||
| 622 | } | ||
| 623 | |||
| 624 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
| 625 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
| 626 | MODULE_LICENSE("GPL"); | ||
| 627 | |||
| 628 | module_param(use_xtal, int, 1); | ||
| 629 | MODULE_PARM_DESC(use_xtal, "Chip have a xtal connected in board"); | ||
| 630 | module_param(radio_nr, int, 0); | ||
| 631 | MODULE_PARM_DESC(radio_nr, "video4linux device number to use"); | ||
| 632 | |||
| 633 | module_init(tea5764_init); | ||
| 634 | module_exit(tea5764_exit); | ||
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index 0abb186a9473..0798d71abd00 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c | |||
| @@ -352,26 +352,22 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 352 | 352 | ||
| 353 | static struct tt_device terratec_unit; | 353 | static struct tt_device terratec_unit; |
| 354 | 354 | ||
| 355 | static int terratec_exclusive_open(struct inode *inode, struct file *file) | 355 | static int terratec_exclusive_open(struct file *file) |
| 356 | { | 356 | { |
| 357 | return test_and_set_bit(0, &terratec_unit.in_use) ? -EBUSY : 0; | 357 | return test_and_set_bit(0, &terratec_unit.in_use) ? -EBUSY : 0; |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | static int terratec_exclusive_release(struct inode *inode, struct file *file) | 360 | static int terratec_exclusive_release(struct file *file) |
| 361 | { | 361 | { |
| 362 | clear_bit(0, &terratec_unit.in_use); | 362 | clear_bit(0, &terratec_unit.in_use); |
| 363 | return 0; | 363 | return 0; |
| 364 | } | 364 | } |
| 365 | 365 | ||
| 366 | static const struct file_operations terratec_fops = { | 366 | static const struct v4l2_file_operations terratec_fops = { |
| 367 | .owner = THIS_MODULE, | 367 | .owner = THIS_MODULE, |
| 368 | .open = terratec_exclusive_open, | 368 | .open = terratec_exclusive_open, |
| 369 | .release = terratec_exclusive_release, | 369 | .release = terratec_exclusive_release, |
| 370 | .ioctl = video_ioctl2, | 370 | .ioctl = video_ioctl2, |
| 371 | #ifdef CONFIG_COMPAT | ||
| 372 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 373 | #endif | ||
| 374 | .llseek = no_llseek, | ||
| 375 | }; | 371 | }; |
| 376 | 372 | ||
| 377 | static const struct v4l2_ioctl_ops terratec_ioctl_ops = { | 373 | static const struct v4l2_ioctl_ops terratec_ioctl_ops = { |
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index e7b111fcd105..bdf9cb6a75f4 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c | |||
| @@ -337,26 +337,22 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 337 | return 0; | 337 | return 0; |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | static int trust_exclusive_open(struct inode *inode, struct file *file) | 340 | static int trust_exclusive_open(struct file *file) |
| 341 | { | 341 | { |
| 342 | return test_and_set_bit(0, &in_use) ? -EBUSY : 0; | 342 | return test_and_set_bit(0, &in_use) ? -EBUSY : 0; |
| 343 | } | 343 | } |
| 344 | 344 | ||
| 345 | static int trust_exclusive_release(struct inode *inode, struct file *file) | 345 | static int trust_exclusive_release(struct file *file) |
| 346 | { | 346 | { |
| 347 | clear_bit(0, &in_use); | 347 | clear_bit(0, &in_use); |
| 348 | return 0; | 348 | return 0; |
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | static const struct file_operations trust_fops = { | 351 | static const struct v4l2_file_operations trust_fops = { |
| 352 | .owner = THIS_MODULE, | 352 | .owner = THIS_MODULE, |
| 353 | .open = trust_exclusive_open, | 353 | .open = trust_exclusive_open, |
| 354 | .release = trust_exclusive_release, | 354 | .release = trust_exclusive_release, |
| 355 | .ioctl = video_ioctl2, | 355 | .ioctl = video_ioctl2, |
| 356 | #ifdef CONFIG_COMPAT | ||
| 357 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 358 | #endif | ||
| 359 | .llseek = no_llseek, | ||
| 360 | }; | 356 | }; |
| 361 | 357 | ||
| 362 | static const struct v4l2_ioctl_ops trust_ioctl_ops = { | 358 | static const struct v4l2_ioctl_ops trust_ioctl_ops = { |
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index 952ec35a8415..5c3b319dab37 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c | |||
| @@ -330,26 +330,22 @@ static struct typhoon_device typhoon_unit = | |||
| 330 | .mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ, | 330 | .mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ, |
| 331 | }; | 331 | }; |
| 332 | 332 | ||
| 333 | static int typhoon_exclusive_open(struct inode *inode, struct file *file) | 333 | static int typhoon_exclusive_open(struct file *file) |
| 334 | { | 334 | { |
| 335 | return test_and_set_bit(0, &typhoon_unit.in_use) ? -EBUSY : 0; | 335 | return test_and_set_bit(0, &typhoon_unit.in_use) ? -EBUSY : 0; |
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | static int typhoon_exclusive_release(struct inode *inode, struct file *file) | 338 | static int typhoon_exclusive_release(struct file *file) |
| 339 | { | 339 | { |
| 340 | clear_bit(0, &typhoon_unit.in_use); | 340 | clear_bit(0, &typhoon_unit.in_use); |
| 341 | return 0; | 341 | return 0; |
| 342 | } | 342 | } |
| 343 | 343 | ||
| 344 | static const struct file_operations typhoon_fops = { | 344 | static const struct v4l2_file_operations typhoon_fops = { |
| 345 | .owner = THIS_MODULE, | 345 | .owner = THIS_MODULE, |
| 346 | .open = typhoon_exclusive_open, | 346 | .open = typhoon_exclusive_open, |
| 347 | .release = typhoon_exclusive_release, | 347 | .release = typhoon_exclusive_release, |
| 348 | .ioctl = video_ioctl2, | 348 | .ioctl = video_ioctl2, |
| 349 | #ifdef CONFIG_COMPAT | ||
| 350 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 351 | #endif | ||
| 352 | .llseek = no_llseek, | ||
| 353 | }; | 349 | }; |
| 354 | 350 | ||
| 355 | static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { | 351 | static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { |
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index 15b10bad6796..d2ac17eeec5f 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c | |||
| @@ -401,27 +401,23 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 401 | 401 | ||
| 402 | static struct zol_device zoltrix_unit; | 402 | static struct zol_device zoltrix_unit; |
| 403 | 403 | ||
| 404 | static int zoltrix_exclusive_open(struct inode *inode, struct file *file) | 404 | static int zoltrix_exclusive_open(struct file *file) |
| 405 | { | 405 | { |
| 406 | return test_and_set_bit(0, &zoltrix_unit.in_use) ? -EBUSY : 0; | 406 | return test_and_set_bit(0, &zoltrix_unit.in_use) ? -EBUSY : 0; |
| 407 | } | 407 | } |
| 408 | 408 | ||
| 409 | static int zoltrix_exclusive_release(struct inode *inode, struct file *file) | 409 | static int zoltrix_exclusive_release(struct file *file) |
| 410 | { | 410 | { |
| 411 | clear_bit(0, &zoltrix_unit.in_use); | 411 | clear_bit(0, &zoltrix_unit.in_use); |
| 412 | return 0; | 412 | return 0; |
| 413 | } | 413 | } |
| 414 | 414 | ||
| 415 | static const struct file_operations zoltrix_fops = | 415 | static const struct v4l2_file_operations zoltrix_fops = |
| 416 | { | 416 | { |
| 417 | .owner = THIS_MODULE, | 417 | .owner = THIS_MODULE, |
| 418 | .open = zoltrix_exclusive_open, | 418 | .open = zoltrix_exclusive_open, |
| 419 | .release = zoltrix_exclusive_release, | 419 | .release = zoltrix_exclusive_release, |
| 420 | .ioctl = video_ioctl2, | 420 | .ioctl = video_ioctl2, |
| 421 | #ifdef CONFIG_COMPAT | ||
| 422 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 423 | #endif | ||
| 424 | .llseek = no_llseek, | ||
| 425 | }; | 421 | }; |
| 426 | 422 | ||
| 427 | static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { | 423 | static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 1611c33b1aee..72f6d03d2d8f 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
| @@ -12,7 +12,10 @@ omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o | |||
| 12 | 12 | ||
| 13 | videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-subdev.o | 13 | videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-subdev.o |
| 14 | 14 | ||
| 15 | obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-compat-ioctl32.o v4l2-int-device.o | 15 | obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o |
| 16 | ifeq ($(CONFIG_COMPAT),y) | ||
| 17 | obj-$(CONFIG_VIDEO_DEV) += v4l2-compat-ioctl32.o | ||
| 18 | endif | ||
| 16 | 19 | ||
| 17 | obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o | 20 | obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o |
| 18 | 21 | ||
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index 2ba6abd92b6f..d137bac84511 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c | |||
| @@ -396,7 +396,7 @@ out_up: | |||
| 396 | return ret; | 396 | return ret; |
| 397 | } | 397 | } |
| 398 | 398 | ||
| 399 | static int ar_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 399 | static long ar_do_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 400 | { | 400 | { |
| 401 | struct video_device *dev = video_devdata(file); | 401 | struct video_device *dev = video_devdata(file); |
| 402 | struct ar_device *ar = video_get_drvdata(dev); | 402 | struct ar_device *ar = video_get_drvdata(dev); |
| @@ -539,7 +539,7 @@ static int ar_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 539 | return 0; | 539 | return 0; |
| 540 | } | 540 | } |
| 541 | 541 | ||
| 542 | static int ar_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 542 | static long ar_ioctl(struct file *file, unsigned int cmd, |
| 543 | unsigned long arg) | 543 | unsigned long arg) |
| 544 | { | 544 | { |
| 545 | return video_usercopy(file, cmd, arg, ar_do_ioctl); | 545 | return video_usercopy(file, cmd, arg, ar_do_ioctl); |
| @@ -744,27 +744,23 @@ void ar_release(struct video_device *vfd) | |||
| 744 | ****************************************************************************/ | 744 | ****************************************************************************/ |
| 745 | static struct ar_device ardev; | 745 | static struct ar_device ardev; |
| 746 | 746 | ||
| 747 | static int ar_exclusive_open(struct inode *inode, struct file *file) | 747 | static int ar_exclusive_open(struct file *file) |
| 748 | { | 748 | { |
| 749 | return test_and_set_bit(0, &ardev.in_use) ? -EBUSY : 0; | 749 | return test_and_set_bit(0, &ardev.in_use) ? -EBUSY : 0; |
| 750 | } | 750 | } |
| 751 | 751 | ||
| 752 | static int ar_exclusive_release(struct inode *inode, struct file *file) | 752 | static int ar_exclusive_release(struct file *file) |
| 753 | { | 753 | { |
| 754 | clear_bit(0, &ardev.in_use); | 754 | clear_bit(0, &ardev.in_use); |
| 755 | return 0; | 755 | return 0; |
| 756 | } | 756 | } |
| 757 | 757 | ||
| 758 | static const struct file_operations ar_fops = { | 758 | static const struct v4l2_file_operations ar_fops = { |
| 759 | .owner = THIS_MODULE, | 759 | .owner = THIS_MODULE, |
| 760 | .open = ar_exclusive_open, | 760 | .open = ar_exclusive_open, |
| 761 | .release = ar_exclusive_release, | 761 | .release = ar_exclusive_release, |
| 762 | .read = ar_read, | 762 | .read = ar_read, |
| 763 | .ioctl = ar_ioctl, | 763 | .ioctl = ar_ioctl, |
| 764 | #ifdef CONFIG_COMPAT | ||
| 765 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 766 | #endif | ||
| 767 | .llseek = no_llseek, | ||
| 768 | }; | 764 | }; |
| 769 | 765 | ||
| 770 | static struct video_device ar_template = { | 766 | static struct video_device ar_template = { |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 9ec4cec2e52d..c71f394fc0ea 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
| @@ -2039,7 +2039,7 @@ static int bttv_log_status(struct file *file, void *f) | |||
| 2039 | 2039 | ||
| 2040 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 2040 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 2041 | static int bttv_g_register(struct file *file, void *f, | 2041 | static int bttv_g_register(struct file *file, void *f, |
| 2042 | struct v4l2_register *reg) | 2042 | struct v4l2_dbg_register *reg) |
| 2043 | { | 2043 | { |
| 2044 | struct bttv_fh *fh = f; | 2044 | struct bttv_fh *fh = f; |
| 2045 | struct bttv *btv = fh->btv; | 2045 | struct bttv *btv = fh->btv; |
| @@ -2047,18 +2047,19 @@ static int bttv_g_register(struct file *file, void *f, | |||
| 2047 | if (!capable(CAP_SYS_ADMIN)) | 2047 | if (!capable(CAP_SYS_ADMIN)) |
| 2048 | return -EPERM; | 2048 | return -EPERM; |
| 2049 | 2049 | ||
| 2050 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 2050 | if (!v4l2_chip_match_host(®->match)) |
| 2051 | return -EINVAL; | 2051 | return -EINVAL; |
| 2052 | 2052 | ||
| 2053 | /* bt848 has a 12-bit register space */ | 2053 | /* bt848 has a 12-bit register space */ |
| 2054 | reg->reg &= 0xfff; | 2054 | reg->reg &= 0xfff; |
| 2055 | reg->val = btread(reg->reg); | 2055 | reg->val = btread(reg->reg); |
| 2056 | reg->size = 1; | ||
| 2056 | 2057 | ||
| 2057 | return 0; | 2058 | return 0; |
| 2058 | } | 2059 | } |
| 2059 | 2060 | ||
| 2060 | static int bttv_s_register(struct file *file, void *f, | 2061 | static int bttv_s_register(struct file *file, void *f, |
| 2061 | struct v4l2_register *reg) | 2062 | struct v4l2_dbg_register *reg) |
| 2062 | { | 2063 | { |
| 2063 | struct bttv_fh *fh = f; | 2064 | struct bttv_fh *fh = f; |
| 2064 | struct bttv *btv = fh->btv; | 2065 | struct bttv *btv = fh->btv; |
| @@ -2066,7 +2067,7 @@ static int bttv_s_register(struct file *file, void *f, | |||
| 2066 | if (!capable(CAP_SYS_ADMIN)) | 2067 | if (!capable(CAP_SYS_ADMIN)) |
| 2067 | return -EPERM; | 2068 | return -EPERM; |
| 2068 | 2069 | ||
| 2069 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 2070 | if (!v4l2_chip_match_host(®->match)) |
| 2070 | return -EINVAL; | 2071 | return -EINVAL; |
| 2071 | 2072 | ||
| 2072 | /* bt848 has a 12-bit register space */ | 2073 | /* bt848 has a 12-bit register space */ |
| @@ -3208,9 +3209,9 @@ err: | |||
| 3208 | return POLLERR; | 3209 | return POLLERR; |
| 3209 | } | 3210 | } |
| 3210 | 3211 | ||
| 3211 | static int bttv_open(struct inode *inode, struct file *file) | 3212 | static int bttv_open(struct file *file) |
| 3212 | { | 3213 | { |
| 3213 | int minor = iminor(inode); | 3214 | int minor = video_devdata(file)->minor; |
| 3214 | struct bttv *btv = NULL; | 3215 | struct bttv *btv = NULL; |
| 3215 | struct bttv_fh *fh; | 3216 | struct bttv_fh *fh; |
| 3216 | enum v4l2_buf_type type = 0; | 3217 | enum v4l2_buf_type type = 0; |
| @@ -3291,7 +3292,7 @@ static int bttv_open(struct inode *inode, struct file *file) | |||
| 3291 | return 0; | 3292 | return 0; |
| 3292 | } | 3293 | } |
| 3293 | 3294 | ||
| 3294 | static int bttv_release(struct inode *inode, struct file *file) | 3295 | static int bttv_release(struct file *file) |
| 3295 | { | 3296 | { |
| 3296 | struct bttv_fh *fh = file->private_data; | 3297 | struct bttv_fh *fh = file->private_data; |
| 3297 | struct bttv *btv = fh->btv; | 3298 | struct bttv *btv = fh->btv; |
| @@ -3346,14 +3347,12 @@ bttv_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 3346 | return videobuf_mmap_mapper(bttv_queue(fh),vma); | 3347 | return videobuf_mmap_mapper(bttv_queue(fh),vma); |
| 3347 | } | 3348 | } |
| 3348 | 3349 | ||
| 3349 | static const struct file_operations bttv_fops = | 3350 | static const struct v4l2_file_operations bttv_fops = |
| 3350 | { | 3351 | { |
| 3351 | .owner = THIS_MODULE, | 3352 | .owner = THIS_MODULE, |
| 3352 | .open = bttv_open, | 3353 | .open = bttv_open, |
| 3353 | .release = bttv_release, | 3354 | .release = bttv_release, |
| 3354 | .ioctl = video_ioctl2, | 3355 | .ioctl = video_ioctl2, |
| 3355 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 3356 | .llseek = no_llseek, | ||
| 3357 | .read = bttv_read, | 3356 | .read = bttv_read, |
| 3358 | .mmap = bttv_mmap, | 3357 | .mmap = bttv_mmap, |
| 3359 | .poll = bttv_poll, | 3358 | .poll = bttv_poll, |
| @@ -3422,9 +3421,9 @@ static struct video_device bttv_video_template = { | |||
| 3422 | /* ----------------------------------------------------------------------- */ | 3421 | /* ----------------------------------------------------------------------- */ |
| 3423 | /* radio interface */ | 3422 | /* radio interface */ |
| 3424 | 3423 | ||
| 3425 | static int radio_open(struct inode *inode, struct file *file) | 3424 | static int radio_open(struct file *file) |
| 3426 | { | 3425 | { |
| 3427 | int minor = iminor(inode); | 3426 | int minor = video_devdata(file)->minor; |
| 3428 | struct bttv *btv = NULL; | 3427 | struct bttv *btv = NULL; |
| 3429 | struct bttv_fh *fh; | 3428 | struct bttv_fh *fh; |
| 3430 | unsigned int i; | 3429 | unsigned int i; |
| @@ -3467,12 +3466,13 @@ static int radio_open(struct inode *inode, struct file *file) | |||
| 3467 | return 0; | 3466 | return 0; |
| 3468 | } | 3467 | } |
| 3469 | 3468 | ||
| 3470 | static int radio_release(struct inode *inode, struct file *file) | 3469 | static int radio_release(struct file *file) |
| 3471 | { | 3470 | { |
| 3472 | struct bttv_fh *fh = file->private_data; | 3471 | struct bttv_fh *fh = file->private_data; |
| 3473 | struct bttv *btv = fh->btv; | 3472 | struct bttv *btv = fh->btv; |
| 3474 | struct rds_command cmd; | 3473 | struct rds_command cmd; |
| 3475 | 3474 | ||
| 3475 | v4l2_prio_close(&btv->prio,&fh->prio); | ||
| 3476 | file->private_data = NULL; | 3476 | file->private_data = NULL; |
| 3477 | kfree(fh); | 3477 | kfree(fh); |
| 3478 | 3478 | ||
| @@ -3633,15 +3633,13 @@ static unsigned int radio_poll(struct file *file, poll_table *wait) | |||
| 3633 | return cmd.result; | 3633 | return cmd.result; |
| 3634 | } | 3634 | } |
| 3635 | 3635 | ||
| 3636 | static const struct file_operations radio_fops = | 3636 | static const struct v4l2_file_operations radio_fops = |
| 3637 | { | 3637 | { |
| 3638 | .owner = THIS_MODULE, | 3638 | .owner = THIS_MODULE, |
| 3639 | .open = radio_open, | 3639 | .open = radio_open, |
| 3640 | .read = radio_read, | 3640 | .read = radio_read, |
| 3641 | .release = radio_release, | 3641 | .release = radio_release, |
| 3642 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 3643 | .ioctl = video_ioctl2, | 3642 | .ioctl = video_ioctl2, |
| 3644 | .llseek = no_llseek, | ||
| 3645 | .poll = radio_poll, | 3643 | .poll = radio_poll, |
| 3646 | }; | 3644 | }; |
| 3647 | 3645 | ||
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index 17f80d03f38e..10dbd4a11b30 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c | |||
| @@ -706,7 +706,7 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l | |||
| 706 | * Video4linux interfacing | 706 | * Video4linux interfacing |
| 707 | */ | 707 | */ |
| 708 | 708 | ||
| 709 | static int qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 709 | static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 710 | { | 710 | { |
| 711 | struct video_device *dev = video_devdata(file); | 711 | struct video_device *dev = video_devdata(file); |
| 712 | struct qcam_device *qcam=(struct qcam_device *)dev; | 712 | struct qcam_device *qcam=(struct qcam_device *)dev; |
| @@ -863,7 +863,7 @@ static int qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 863 | return 0; | 863 | return 0; |
| 864 | } | 864 | } |
| 865 | 865 | ||
| 866 | static int qcam_ioctl(struct inode *inode, struct file *file, | 866 | static long qcam_ioctl(struct file *file, |
| 867 | unsigned int cmd, unsigned long arg) | 867 | unsigned int cmd, unsigned long arg) |
| 868 | { | 868 | { |
| 869 | return video_usercopy(file, cmd, arg, qcam_do_ioctl); | 869 | return video_usercopy(file, cmd, arg, qcam_do_ioctl); |
| @@ -893,7 +893,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf, | |||
| 893 | return len; | 893 | return len; |
| 894 | } | 894 | } |
| 895 | 895 | ||
| 896 | static int qcam_exclusive_open(struct inode *inode, struct file *file) | 896 | static int qcam_exclusive_open(struct file *file) |
| 897 | { | 897 | { |
| 898 | struct video_device *dev = video_devdata(file); | 898 | struct video_device *dev = video_devdata(file); |
| 899 | struct qcam_device *qcam = (struct qcam_device *)dev; | 899 | struct qcam_device *qcam = (struct qcam_device *)dev; |
| @@ -901,7 +901,7 @@ static int qcam_exclusive_open(struct inode *inode, struct file *file) | |||
| 901 | return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0; | 901 | return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0; |
| 902 | } | 902 | } |
| 903 | 903 | ||
| 904 | static int qcam_exclusive_release(struct inode *inode, struct file *file) | 904 | static int qcam_exclusive_release(struct file *file) |
| 905 | { | 905 | { |
| 906 | struct video_device *dev = video_devdata(file); | 906 | struct video_device *dev = video_devdata(file); |
| 907 | struct qcam_device *qcam = (struct qcam_device *)dev; | 907 | struct qcam_device *qcam = (struct qcam_device *)dev; |
| @@ -910,16 +910,12 @@ static int qcam_exclusive_release(struct inode *inode, struct file *file) | |||
| 910 | return 0; | 910 | return 0; |
| 911 | } | 911 | } |
| 912 | 912 | ||
| 913 | static const struct file_operations qcam_fops = { | 913 | static const struct v4l2_file_operations qcam_fops = { |
| 914 | .owner = THIS_MODULE, | 914 | .owner = THIS_MODULE, |
| 915 | .open = qcam_exclusive_open, | 915 | .open = qcam_exclusive_open, |
| 916 | .release = qcam_exclusive_release, | 916 | .release = qcam_exclusive_release, |
| 917 | .ioctl = qcam_ioctl, | 917 | .ioctl = qcam_ioctl, |
| 918 | #ifdef CONFIG_COMPAT | ||
| 919 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 920 | #endif | ||
| 921 | .read = qcam_read, | 918 | .read = qcam_read, |
| 922 | .llseek = no_llseek, | ||
| 923 | }; | 919 | }; |
| 924 | static struct video_device qcam_template= | 920 | static struct video_device qcam_template= |
| 925 | { | 921 | { |
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index 21c71eb085db..85cf1778827a 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c | |||
| @@ -500,7 +500,7 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le | |||
| 500 | * Video4linux interfacing | 500 | * Video4linux interfacing |
| 501 | */ | 501 | */ |
| 502 | 502 | ||
| 503 | static int qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 503 | static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 504 | { | 504 | { |
| 505 | struct video_device *dev = video_devdata(file); | 505 | struct video_device *dev = video_devdata(file); |
| 506 | struct qcam_device *qcam=(struct qcam_device *)dev; | 506 | struct qcam_device *qcam=(struct qcam_device *)dev; |
| @@ -665,7 +665,7 @@ static int qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 665 | return 0; | 665 | return 0; |
| 666 | } | 666 | } |
| 667 | 667 | ||
| 668 | static int qcam_ioctl(struct inode *inode, struct file *file, | 668 | static long qcam_ioctl(struct file *file, |
| 669 | unsigned int cmd, unsigned long arg) | 669 | unsigned int cmd, unsigned long arg) |
| 670 | { | 670 | { |
| 671 | return video_usercopy(file, cmd, arg, qcam_do_ioctl); | 671 | return video_usercopy(file, cmd, arg, qcam_do_ioctl); |
| @@ -687,7 +687,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf, | |||
| 687 | return len; | 687 | return len; |
| 688 | } | 688 | } |
| 689 | 689 | ||
| 690 | static int qcam_exclusive_open(struct inode *inode, struct file *file) | 690 | static int qcam_exclusive_open(struct file *file) |
| 691 | { | 691 | { |
| 692 | struct video_device *dev = video_devdata(file); | 692 | struct video_device *dev = video_devdata(file); |
| 693 | struct qcam_device *qcam = (struct qcam_device *)dev; | 693 | struct qcam_device *qcam = (struct qcam_device *)dev; |
| @@ -695,7 +695,7 @@ static int qcam_exclusive_open(struct inode *inode, struct file *file) | |||
| 695 | return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0; | 695 | return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0; |
| 696 | } | 696 | } |
| 697 | 697 | ||
| 698 | static int qcam_exclusive_release(struct inode *inode, struct file *file) | 698 | static int qcam_exclusive_release(struct file *file) |
| 699 | { | 699 | { |
| 700 | struct video_device *dev = video_devdata(file); | 700 | struct video_device *dev = video_devdata(file); |
| 701 | struct qcam_device *qcam = (struct qcam_device *)dev; | 701 | struct qcam_device *qcam = (struct qcam_device *)dev; |
| @@ -705,16 +705,12 @@ static int qcam_exclusive_release(struct inode *inode, struct file *file) | |||
| 705 | } | 705 | } |
| 706 | 706 | ||
| 707 | /* video device template */ | 707 | /* video device template */ |
| 708 | static const struct file_operations qcam_fops = { | 708 | static const struct v4l2_file_operations qcam_fops = { |
| 709 | .owner = THIS_MODULE, | 709 | .owner = THIS_MODULE, |
| 710 | .open = qcam_exclusive_open, | 710 | .open = qcam_exclusive_open, |
| 711 | .release = qcam_exclusive_release, | 711 | .release = qcam_exclusive_release, |
| 712 | .ioctl = qcam_ioctl, | 712 | .ioctl = qcam_ioctl, |
| 713 | #ifdef CONFIG_COMPAT | ||
| 714 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 715 | #endif | ||
| 716 | .read = qcam_read, | 713 | .read = qcam_read, |
| 717 | .llseek = no_llseek, | ||
| 718 | }; | 714 | }; |
| 719 | 715 | ||
| 720 | static struct video_device qcam_template= | 716 | static struct video_device qcam_template= |
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 1740b9ebdcef..34a39d2e4703 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c | |||
| @@ -859,7 +859,7 @@ static int __cafe_cam_reset(struct cafe_camera *cam) | |||
| 859 | */ | 859 | */ |
| 860 | static int cafe_cam_init(struct cafe_camera *cam) | 860 | static int cafe_cam_init(struct cafe_camera *cam) |
| 861 | { | 861 | { |
| 862 | struct v4l2_chip_ident chip = { V4L2_CHIP_MATCH_I2C_ADDR, 0, 0, 0 }; | 862 | struct v4l2_dbg_chip_ident chip; |
| 863 | int ret; | 863 | int ret; |
| 864 | 864 | ||
| 865 | mutex_lock(&cam->s_mutex); | 865 | mutex_lock(&cam->s_mutex); |
| @@ -869,8 +869,9 @@ static int cafe_cam_init(struct cafe_camera *cam) | |||
| 869 | ret = __cafe_cam_reset(cam); | 869 | ret = __cafe_cam_reset(cam); |
| 870 | if (ret) | 870 | if (ret) |
| 871 | goto out; | 871 | goto out; |
| 872 | chip.match_chip = cam->sensor->addr; | 872 | chip.match.type = V4L2_CHIP_MATCH_I2C_ADDR; |
| 873 | ret = __cafe_cam_cmd(cam, VIDIOC_G_CHIP_IDENT, &chip); | 873 | chip.match.addr = cam->sensor->addr; |
| 874 | ret = __cafe_cam_cmd(cam, VIDIOC_DBG_G_CHIP_IDENT, &chip); | ||
| 874 | if (ret) | 875 | if (ret) |
| 875 | goto out; | 876 | goto out; |
| 876 | cam->sensor_type = chip.ident; | 877 | cam->sensor_type = chip.ident; |
| @@ -1472,11 +1473,11 @@ static int cafe_v4l_mmap(struct file *filp, struct vm_area_struct *vma) | |||
| 1472 | 1473 | ||
| 1473 | 1474 | ||
| 1474 | 1475 | ||
| 1475 | static int cafe_v4l_open(struct inode *inode, struct file *filp) | 1476 | static int cafe_v4l_open(struct file *filp) |
| 1476 | { | 1477 | { |
| 1477 | struct cafe_camera *cam; | 1478 | struct cafe_camera *cam; |
| 1478 | 1479 | ||
| 1479 | cam = cafe_find_dev(iminor(inode)); | 1480 | cam = cafe_find_dev(video_devdata(filp)->minor); |
| 1480 | if (cam == NULL) | 1481 | if (cam == NULL) |
| 1481 | return -ENODEV; | 1482 | return -ENODEV; |
| 1482 | filp->private_data = cam; | 1483 | filp->private_data = cam; |
| @@ -1494,7 +1495,7 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp) | |||
| 1494 | } | 1495 | } |
| 1495 | 1496 | ||
| 1496 | 1497 | ||
| 1497 | static int cafe_v4l_release(struct inode *inode, struct file *filp) | 1498 | static int cafe_v4l_release(struct file *filp) |
| 1498 | { | 1499 | { |
| 1499 | struct cafe_camera *cam = filp->private_data; | 1500 | struct cafe_camera *cam = filp->private_data; |
| 1500 | 1501 | ||
| @@ -1759,7 +1760,7 @@ static void cafe_v4l_dev_release(struct video_device *vd) | |||
| 1759 | * clone it for specific real devices. | 1760 | * clone it for specific real devices. |
| 1760 | */ | 1761 | */ |
| 1761 | 1762 | ||
| 1762 | static const struct file_operations cafe_v4l_fops = { | 1763 | static const struct v4l2_file_operations cafe_v4l_fops = { |
| 1763 | .owner = THIS_MODULE, | 1764 | .owner = THIS_MODULE, |
| 1764 | .open = cafe_v4l_open, | 1765 | .open = cafe_v4l_open, |
| 1765 | .release = cafe_v4l_release, | 1766 | .release = cafe_v4l_release, |
| @@ -1767,7 +1768,6 @@ static const struct file_operations cafe_v4l_fops = { | |||
| 1767 | .poll = cafe_v4l_poll, | 1768 | .poll = cafe_v4l_poll, |
| 1768 | .mmap = cafe_v4l_mmap, | 1769 | .mmap = cafe_v4l_mmap, |
| 1769 | .ioctl = video_ioctl2, | 1770 | .ioctl = video_ioctl2, |
| 1770 | .llseek = no_llseek, | ||
| 1771 | }; | 1771 | }; |
| 1772 | 1772 | ||
| 1773 | static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { | 1773 | static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { |
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index 028a400d2453..c3b0c8c63c76 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c | |||
| @@ -3148,7 +3148,7 @@ static void put_cam(struct cpia_camera_ops* ops) | |||
| 3148 | } | 3148 | } |
| 3149 | 3149 | ||
| 3150 | /* ------------------------- V4L interface --------------------- */ | 3150 | /* ------------------------- V4L interface --------------------- */ |
| 3151 | static int cpia_open(struct inode *inode, struct file *file) | 3151 | static int cpia_open(struct file *file) |
| 3152 | { | 3152 | { |
| 3153 | struct video_device *dev = video_devdata(file); | 3153 | struct video_device *dev = video_devdata(file); |
| 3154 | struct cam_data *cam = video_get_drvdata(dev); | 3154 | struct cam_data *cam = video_get_drvdata(dev); |
| @@ -3225,7 +3225,7 @@ static int cpia_open(struct inode *inode, struct file *file) | |||
| 3225 | return err; | 3225 | return err; |
| 3226 | } | 3226 | } |
| 3227 | 3227 | ||
| 3228 | static int cpia_close(struct inode *inode, struct file *file) | 3228 | static int cpia_close(struct file *file) |
| 3229 | { | 3229 | { |
| 3230 | struct video_device *dev = file->private_data; | 3230 | struct video_device *dev = file->private_data; |
| 3231 | struct cam_data *cam = video_get_drvdata(dev); | 3231 | struct cam_data *cam = video_get_drvdata(dev); |
| @@ -3333,7 +3333,7 @@ static ssize_t cpia_read(struct file *file, char __user *buf, | |||
| 3333 | return cam->decompressed_frame.count; | 3333 | return cam->decompressed_frame.count; |
| 3334 | } | 3334 | } |
| 3335 | 3335 | ||
| 3336 | static int cpia_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 3336 | static long cpia_do_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 3337 | { | 3337 | { |
| 3338 | struct video_device *dev = file->private_data; | 3338 | struct video_device *dev = file->private_data; |
| 3339 | struct cam_data *cam = video_get_drvdata(dev); | 3339 | struct cam_data *cam = video_get_drvdata(dev); |
| @@ -3720,7 +3720,7 @@ static int cpia_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 3720 | return retval; | 3720 | return retval; |
| 3721 | } | 3721 | } |
| 3722 | 3722 | ||
| 3723 | static int cpia_ioctl(struct inode *inode, struct file *file, | 3723 | static long cpia_ioctl(struct file *file, |
| 3724 | unsigned int cmd, unsigned long arg) | 3724 | unsigned int cmd, unsigned long arg) |
| 3725 | { | 3725 | { |
| 3726 | return video_usercopy(file, cmd, arg, cpia_do_ioctl); | 3726 | return video_usercopy(file, cmd, arg, cpia_do_ioctl); |
| @@ -3780,17 +3780,13 @@ static int cpia_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 3780 | return 0; | 3780 | return 0; |
| 3781 | } | 3781 | } |
| 3782 | 3782 | ||
| 3783 | static const struct file_operations cpia_fops = { | 3783 | static const struct v4l2_file_operations cpia_fops = { |
| 3784 | .owner = THIS_MODULE, | 3784 | .owner = THIS_MODULE, |
| 3785 | .open = cpia_open, | 3785 | .open = cpia_open, |
| 3786 | .release = cpia_close, | 3786 | .release = cpia_close, |
| 3787 | .read = cpia_read, | 3787 | .read = cpia_read, |
| 3788 | .mmap = cpia_mmap, | 3788 | .mmap = cpia_mmap, |
| 3789 | .ioctl = cpia_ioctl, | 3789 | .ioctl = cpia_ioctl, |
| 3790 | #ifdef CONFIG_COMPAT | ||
| 3791 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 3792 | #endif | ||
| 3793 | .llseek = no_llseek, | ||
| 3794 | }; | 3790 | }; |
| 3795 | 3791 | ||
| 3796 | static struct video_device cpia_template = { | 3792 | static struct video_device cpia_template = { |
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index 3c2d7eac1197..9c25894fdd8e 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c | |||
| @@ -239,7 +239,7 @@ static struct v4l2_queryctrl controls[] = { | |||
| 239 | * cpia2_open | 239 | * cpia2_open |
| 240 | * | 240 | * |
| 241 | *****************************************************************************/ | 241 | *****************************************************************************/ |
| 242 | static int cpia2_open(struct inode *inode, struct file *file) | 242 | static int cpia2_open(struct file *file) |
| 243 | { | 243 | { |
| 244 | struct camera_data *cam = video_drvdata(file); | 244 | struct camera_data *cam = video_drvdata(file); |
| 245 | int retval = 0; | 245 | int retval = 0; |
| @@ -302,7 +302,7 @@ err_return: | |||
| 302 | * cpia2_close | 302 | * cpia2_close |
| 303 | * | 303 | * |
| 304 | *****************************************************************************/ | 304 | *****************************************************************************/ |
| 305 | static int cpia2_close(struct inode *inode, struct file *file) | 305 | static int cpia2_close(struct file *file) |
| 306 | { | 306 | { |
| 307 | struct video_device *dev = video_devdata(file); | 307 | struct video_device *dev = video_devdata(file); |
| 308 | struct camera_data *cam = video_get_drvdata(dev); | 308 | struct camera_data *cam = video_get_drvdata(dev); |
| @@ -1572,10 +1572,10 @@ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file) | |||
| 1572 | * cpia2_ioctl | 1572 | * cpia2_ioctl |
| 1573 | * | 1573 | * |
| 1574 | *****************************************************************************/ | 1574 | *****************************************************************************/ |
| 1575 | static int cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 1575 | static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 1576 | { | 1576 | { |
| 1577 | struct camera_data *cam = video_drvdata(file); | 1577 | struct camera_data *cam = video_drvdata(file); |
| 1578 | int retval = 0; | 1578 | long retval = 0; |
| 1579 | 1579 | ||
| 1580 | if (!cam) | 1580 | if (!cam) |
| 1581 | return -ENOTTY; | 1581 | return -ENOTTY; |
| @@ -1841,7 +1841,7 @@ static int cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 1841 | return retval; | 1841 | return retval; |
| 1842 | } | 1842 | } |
| 1843 | 1843 | ||
| 1844 | static int cpia2_ioctl(struct inode *inode, struct file *file, | 1844 | static long cpia2_ioctl(struct file *file, |
| 1845 | unsigned int cmd, unsigned long arg) | 1845 | unsigned int cmd, unsigned long arg) |
| 1846 | { | 1846 | { |
| 1847 | return video_usercopy(file, cmd, arg, cpia2_do_ioctl); | 1847 | return video_usercopy(file, cmd, arg, cpia2_do_ioctl); |
| @@ -1912,17 +1912,13 @@ static void reset_camera_struct_v4l(struct camera_data *cam) | |||
| 1912 | /*** | 1912 | /*** |
| 1913 | * The v4l video device structure initialized for this device | 1913 | * The v4l video device structure initialized for this device |
| 1914 | ***/ | 1914 | ***/ |
| 1915 | static const struct file_operations fops_template = { | 1915 | static const struct v4l2_file_operations fops_template = { |
| 1916 | .owner = THIS_MODULE, | 1916 | .owner = THIS_MODULE, |
| 1917 | .open = cpia2_open, | 1917 | .open = cpia2_open, |
| 1918 | .release = cpia2_close, | 1918 | .release = cpia2_close, |
| 1919 | .read = cpia2_v4l_read, | 1919 | .read = cpia2_v4l_read, |
| 1920 | .poll = cpia2_v4l_poll, | 1920 | .poll = cpia2_v4l_poll, |
| 1921 | .ioctl = cpia2_ioctl, | 1921 | .ioctl = cpia2_ioctl, |
| 1922 | .llseek = no_llseek, | ||
| 1923 | #ifdef CONFIG_COMPAT | ||
| 1924 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1925 | #endif | ||
| 1926 | .mmap = cpia2_mmap, | 1922 | .mmap = cpia2_mmap, |
| 1927 | }; | 1923 | }; |
| 1928 | 1924 | ||
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c index 70fcd0d5de13..14bebf8a116f 100644 --- a/drivers/media/video/cs5345.c +++ b/drivers/media/video/cs5345.c | |||
| @@ -95,25 +95,24 @@ static int cs5345_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 97 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 98 | static int cs5345_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 98 | static int cs5345_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 99 | { | 99 | { |
| 100 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 100 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 101 | 101 | ||
| 102 | if (!v4l2_chip_match_i2c_client(client, | 102 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 103 | reg->match_type, reg->match_chip)) | ||
| 104 | return -EINVAL; | 103 | return -EINVAL; |
| 105 | if (!capable(CAP_SYS_ADMIN)) | 104 | if (!capable(CAP_SYS_ADMIN)) |
| 106 | return -EPERM; | 105 | return -EPERM; |
| 106 | reg->size = 1; | ||
| 107 | reg->val = cs5345_read(sd, reg->reg & 0x1f); | 107 | reg->val = cs5345_read(sd, reg->reg & 0x1f); |
| 108 | return 0; | 108 | return 0; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | static int cs5345_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 111 | static int cs5345_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 112 | { | 112 | { |
| 113 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 113 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 114 | 114 | ||
| 115 | if (!v4l2_chip_match_i2c_client(client, | 115 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 116 | reg->match_type, reg->match_chip)) | ||
| 117 | return -EINVAL; | 116 | return -EINVAL; |
| 118 | if (!capable(CAP_SYS_ADMIN)) | 117 | if (!capable(CAP_SYS_ADMIN)) |
| 119 | return -EPERM; | 118 | return -EPERM; |
| @@ -122,7 +121,7 @@ static int cs5345_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | |||
| 122 | } | 121 | } |
| 123 | #endif | 122 | #endif |
| 124 | 123 | ||
| 125 | static int cs5345_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) | 124 | static int cs5345_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) |
| 126 | { | 125 | { |
| 127 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 126 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 128 | 127 | ||
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c index cb65d519cf78..7292a6316e63 100644 --- a/drivers/media/video/cs53l32a.c +++ b/drivers/media/video/cs53l32a.c | |||
| @@ -102,7 +102,7 @@ static int cs53l32a_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
| 102 | return 0; | 102 | return 0; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | static int cs53l32a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) | 105 | static int cs53l32a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) |
| 106 | { | 106 | { |
| 107 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 107 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 108 | 108 | ||
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c index 425271a29517..055f6e004b2d 100644 --- a/drivers/media/video/cx18/cx18-fileops.c +++ b/drivers/media/video/cx18/cx18-fileops.c | |||
| @@ -552,7 +552,7 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end) | |||
| 552 | } | 552 | } |
| 553 | } | 553 | } |
| 554 | 554 | ||
| 555 | int cx18_v4l2_close(struct inode *inode, struct file *filp) | 555 | int cx18_v4l2_close(struct file *filp) |
| 556 | { | 556 | { |
| 557 | struct cx18_open_id *id = filp->private_data; | 557 | struct cx18_open_id *id = filp->private_data; |
| 558 | struct cx18 *cx = id->cx; | 558 | struct cx18 *cx = id->cx; |
| @@ -650,12 +650,12 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp) | |||
| 650 | return 0; | 650 | return 0; |
| 651 | } | 651 | } |
| 652 | 652 | ||
| 653 | int cx18_v4l2_open(struct inode *inode, struct file *filp) | 653 | int cx18_v4l2_open(struct file *filp) |
| 654 | { | 654 | { |
| 655 | int res, x, y = 0; | 655 | int res, x, y = 0; |
| 656 | struct cx18 *cx = NULL; | 656 | struct cx18 *cx = NULL; |
| 657 | struct cx18_stream *s = NULL; | 657 | struct cx18_stream *s = NULL; |
| 658 | int minor = iminor(inode); | 658 | int minor = video_devdata(filp)->minor; |
| 659 | 659 | ||
| 660 | /* Find which card this open was on */ | 660 | /* Find which card this open was on */ |
| 661 | spin_lock(&cx18_cards_lock); | 661 | spin_lock(&cx18_cards_lock); |
diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/video/cx18/cx18-fileops.h index 46da0282fc7d..92e2d5dab936 100644 --- a/drivers/media/video/cx18/cx18-fileops.h +++ b/drivers/media/video/cx18/cx18-fileops.h | |||
| @@ -22,12 +22,12 @@ | |||
| 22 | */ | 22 | */ |
| 23 | 23 | ||
| 24 | /* Testing/Debugging */ | 24 | /* Testing/Debugging */ |
| 25 | int cx18_v4l2_open(struct inode *inode, struct file *filp); | 25 | int cx18_v4l2_open(struct file *filp); |
| 26 | ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count, | 26 | ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count, |
| 27 | loff_t *pos); | 27 | loff_t *pos); |
| 28 | ssize_t cx18_v4l2_write(struct file *filp, const char __user *buf, size_t count, | 28 | ssize_t cx18_v4l2_write(struct file *filp, const char __user *buf, size_t count, |
| 29 | loff_t *pos); | 29 | loff_t *pos); |
| 30 | int cx18_v4l2_close(struct inode *inode, struct file *filp); | 30 | int cx18_v4l2_close(struct file *filp); |
| 31 | unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait); | 31 | unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait); |
| 32 | int cx18_start_capture(struct cx18_open_id *id); | 32 | int cx18_start_capture(struct cx18_open_id *id); |
| 33 | void cx18_stop_capture(struct cx18_open_id *id, int gop_end); | 33 | void cx18_stop_capture(struct cx18_open_id *id, int gop_end); |
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index 8941f58bed7f..83e1c6333126 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c | |||
| @@ -242,7 +242,7 @@ int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg) | |||
| 242 | return retval; | 242 | return retval; |
| 243 | } | 243 | } |
| 244 | } | 244 | } |
| 245 | if (cmd != VIDIOC_G_CHIP_IDENT) | 245 | if (cmd != VIDIOC_DBG_G_CHIP_IDENT) |
| 246 | CX18_ERR("i2c addr 0x%02x not found for cmd 0x%x!\n", | 246 | CX18_ERR("i2c addr 0x%02x not found for cmd 0x%x!\n", |
| 247 | addr, cmd); | 247 | addr, cmd); |
| 248 | return -ENODEV; | 248 | return -ENODEV; |
| @@ -268,17 +268,6 @@ static int cx18_i2c_id_addr(struct cx18 *cx, u32 id) | |||
| 268 | return retval; | 268 | return retval; |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | /* Find the i2c device name matching the DRIVERID */ | ||
| 272 | static const char *cx18_i2c_id_name(u32 id) | ||
| 273 | { | ||
| 274 | int i; | ||
| 275 | |||
| 276 | for (i = 0; i < ARRAY_SIZE(hw_driverids); i++) | ||
| 277 | if (hw_driverids[i] == id) | ||
| 278 | return hw_devicenames[i]; | ||
| 279 | return "unknown device"; | ||
| 280 | } | ||
| 281 | |||
| 282 | /* Find the i2c device name matching the CX18_HW_ flag */ | 271 | /* Find the i2c device name matching the CX18_HW_ flag */ |
| 283 | static const char *cx18_i2c_hw_name(u32 hw) | 272 | static const char *cx18_i2c_hw_name(u32 hw) |
| 284 | { | 273 | { |
| @@ -326,21 +315,6 @@ int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg) | |||
| 326 | return cx18_call_i2c_client(cx, addr, cmd, arg); | 315 | return cx18_call_i2c_client(cx, addr, cmd, arg); |
| 327 | } | 316 | } |
| 328 | 317 | ||
| 329 | /* Calls i2c device based on I2C driver ID. */ | ||
| 330 | int cx18_i2c_id(struct cx18 *cx, u32 id, unsigned int cmd, void *arg) | ||
| 331 | { | ||
| 332 | int addr; | ||
| 333 | |||
| 334 | addr = cx18_i2c_id_addr(cx, id); | ||
| 335 | if (addr < 0) { | ||
| 336 | if (cmd != VIDIOC_G_CHIP_IDENT) | ||
| 337 | CX18_ERR("i2c ID 0x%08x (%s) not found for cmd 0x%x!\n", | ||
| 338 | id, cx18_i2c_id_name(id), cmd); | ||
| 339 | return addr; | ||
| 340 | } | ||
| 341 | return cx18_call_i2c_client(cx, addr, cmd, arg); | ||
| 342 | } | ||
| 343 | |||
| 344 | /* broadcast cmd for all I2C clients and for the gpio subsystem */ | 318 | /* broadcast cmd for all I2C clients and for the gpio subsystem */ |
| 345 | void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg) | 319 | void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg) |
| 346 | { | 320 | { |
diff --git a/drivers/media/video/cx18/cx18-i2c.h b/drivers/media/video/cx18/cx18-i2c.h index 113c3f9a2cc0..4869739013bd 100644 --- a/drivers/media/video/cx18/cx18-i2c.h +++ b/drivers/media/video/cx18/cx18-i2c.h | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | 23 | ||
| 24 | int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw); | 24 | int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw); |
| 25 | int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg); | 25 | int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg); |
| 26 | int cx18_i2c_id(struct cx18 *cx, u32 id, unsigned int cmd, void *arg); | ||
| 27 | int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg); | 26 | int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg); |
| 28 | void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg); | 27 | void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg); |
| 29 | int cx18_i2c_register(struct cx18 *cx, unsigned idx); | 28 | int cx18_i2c_register(struct cx18 *cx, unsigned idx); |
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index e6087486f889..7086aaba77d6 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c | |||
| @@ -254,30 +254,24 @@ static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh, | |||
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | static int cx18_g_chip_ident(struct file *file, void *fh, | 256 | static int cx18_g_chip_ident(struct file *file, void *fh, |
| 257 | struct v4l2_chip_ident *chip) | 257 | struct v4l2_dbg_chip_ident *chip) |
| 258 | { | 258 | { |
| 259 | struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; | 259 | struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; |
| 260 | 260 | ||
| 261 | chip->ident = V4L2_IDENT_NONE; | 261 | chip->ident = V4L2_IDENT_NONE; |
| 262 | chip->revision = 0; | 262 | chip->revision = 0; |
| 263 | if (chip->match_type == V4L2_CHIP_MATCH_HOST) { | 263 | if (v4l2_chip_match_host(&chip->match)) { |
| 264 | if (v4l2_chip_match_host(chip->match_type, chip->match_chip)) | 264 | chip->ident = V4L2_IDENT_CX23418; |
| 265 | chip->ident = V4L2_IDENT_CX23418; | ||
| 266 | return 0; | 265 | return 0; |
| 267 | } | 266 | } |
| 268 | if (chip->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) | 267 | cx18_call_i2c_clients(cx, VIDIOC_DBG_G_CHIP_IDENT, chip); |
| 269 | return cx18_i2c_id(cx, chip->match_chip, VIDIOC_G_CHIP_IDENT, | 268 | return 0; |
| 270 | chip); | ||
| 271 | if (chip->match_type == V4L2_CHIP_MATCH_I2C_ADDR) | ||
| 272 | return cx18_call_i2c_client(cx, chip->match_chip, | ||
| 273 | VIDIOC_G_CHIP_IDENT, chip); | ||
| 274 | return -EINVAL; | ||
| 275 | } | 269 | } |
| 276 | 270 | ||
| 277 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 271 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 278 | static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) | 272 | static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) |
| 279 | { | 273 | { |
| 280 | struct v4l2_register *regs = arg; | 274 | struct v4l2_dbg_register *regs = arg; |
| 281 | unsigned long flags; | 275 | unsigned long flags; |
| 282 | 276 | ||
| 283 | if (!capable(CAP_SYS_ADMIN)) | 277 | if (!capable(CAP_SYS_ADMIN)) |
| @@ -286,6 +280,7 @@ static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) | |||
| 286 | return -EINVAL; | 280 | return -EINVAL; |
| 287 | 281 | ||
| 288 | spin_lock_irqsave(&cx18_cards_lock, flags); | 282 | spin_lock_irqsave(&cx18_cards_lock, flags); |
| 283 | regs->size = 4; | ||
| 289 | if (cmd == VIDIOC_DBG_G_REGISTER) | 284 | if (cmd == VIDIOC_DBG_G_REGISTER) |
| 290 | regs->val = cx18_read_enc(cx, regs->reg); | 285 | regs->val = cx18_read_enc(cx, regs->reg); |
| 291 | else | 286 | else |
| @@ -295,31 +290,25 @@ static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) | |||
| 295 | } | 290 | } |
| 296 | 291 | ||
| 297 | static int cx18_g_register(struct file *file, void *fh, | 292 | static int cx18_g_register(struct file *file, void *fh, |
| 298 | struct v4l2_register *reg) | 293 | struct v4l2_dbg_register *reg) |
| 299 | { | 294 | { |
| 300 | struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; | 295 | struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; |
| 301 | 296 | ||
| 302 | if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 297 | if (v4l2_chip_match_host(®->match)) |
| 303 | return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg); | 298 | return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg); |
| 304 | if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) | 299 | cx18_call_i2c_clients(cx, VIDIOC_DBG_G_REGISTER, reg); |
| 305 | return cx18_i2c_id(cx, reg->match_chip, VIDIOC_DBG_G_REGISTER, | 300 | return 0; |
| 306 | reg); | ||
| 307 | return cx18_call_i2c_client(cx, reg->match_chip, VIDIOC_DBG_G_REGISTER, | ||
| 308 | reg); | ||
| 309 | } | 301 | } |
| 310 | 302 | ||
| 311 | static int cx18_s_register(struct file *file, void *fh, | 303 | static int cx18_s_register(struct file *file, void *fh, |
| 312 | struct v4l2_register *reg) | 304 | struct v4l2_dbg_register *reg) |
| 313 | { | 305 | { |
| 314 | struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; | 306 | struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; |
| 315 | 307 | ||
| 316 | if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 308 | if (v4l2_chip_match_host(®->match)) |
| 317 | return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg); | 309 | return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg); |
| 318 | if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) | 310 | cx18_call_i2c_clients(cx, VIDIOC_DBG_S_REGISTER, reg); |
| 319 | return cx18_i2c_id(cx, reg->match_chip, VIDIOC_DBG_S_REGISTER, | 311 | return 0; |
| 320 | reg); | ||
| 321 | return cx18_call_i2c_client(cx, reg->match_chip, VIDIOC_DBG_S_REGISTER, | ||
| 322 | reg); | ||
| 323 | } | 312 | } |
| 324 | #endif | 313 | #endif |
| 325 | 314 | ||
| @@ -755,7 +744,7 @@ static int cx18_log_status(struct file *file, void *fh) | |||
| 755 | return 0; | 744 | return 0; |
| 756 | } | 745 | } |
| 757 | 746 | ||
| 758 | static int cx18_default(struct file *file, void *fh, int cmd, void *arg) | 747 | static long cx18_default(struct file *file, void *fh, int cmd, void *arg) |
| 759 | { | 748 | { |
| 760 | struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; | 749 | struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; |
| 761 | 750 | ||
| @@ -783,19 +772,19 @@ static int cx18_default(struct file *file, void *fh, int cmd, void *arg) | |||
| 783 | return 0; | 772 | return 0; |
| 784 | } | 773 | } |
| 785 | 774 | ||
| 786 | int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | 775 | long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd, |
| 787 | unsigned long arg) | 776 | unsigned long arg) |
| 788 | { | 777 | { |
| 789 | struct video_device *vfd = video_devdata(filp); | 778 | struct video_device *vfd = video_devdata(filp); |
| 790 | struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data; | 779 | struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data; |
| 791 | struct cx18 *cx = id->cx; | 780 | struct cx18 *cx = id->cx; |
| 792 | int res; | 781 | long res; |
| 793 | 782 | ||
| 794 | mutex_lock(&cx->serialize_lock); | 783 | mutex_lock(&cx->serialize_lock); |
| 795 | 784 | ||
| 796 | if (cx18_debug & CX18_DBGFLG_IOCTL) | 785 | if (cx18_debug & CX18_DBGFLG_IOCTL) |
| 797 | vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; | 786 | vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; |
| 798 | res = video_ioctl2(inode, filp, cmd, arg); | 787 | res = video_ioctl2(filp, cmd, arg); |
| 799 | vfd->debug = 0; | 788 | vfd->debug = 0; |
| 800 | mutex_unlock(&cx->serialize_lock); | 789 | mutex_unlock(&cx->serialize_lock); |
| 801 | return res; | 790 | return res; |
diff --git a/drivers/media/video/cx18/cx18-ioctl.h b/drivers/media/video/cx18/cx18-ioctl.h index 08fe24e9510e..e2ca0d152116 100644 --- a/drivers/media/video/cx18/cx18-ioctl.h +++ b/drivers/media/video/cx18/cx18-ioctl.h | |||
| @@ -29,5 +29,5 @@ void cx18_set_funcs(struct video_device *vdev); | |||
| 29 | int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std); | 29 | int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std); |
| 30 | int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf); | 30 | int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf); |
| 31 | int cx18_s_input(struct file *file, void *fh, unsigned int inp); | 31 | int cx18_s_input(struct file *file, void *fh, unsigned int inp); |
| 32 | int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | 32 | long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd, |
| 33 | unsigned long arg); | 33 | unsigned long arg); |
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 63c336c95ff5..89c1ec94f335 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c | |||
| @@ -37,13 +37,12 @@ | |||
| 37 | 37 | ||
| 38 | #define CX18_DSP0_INTERRUPT_MASK 0xd0004C | 38 | #define CX18_DSP0_INTERRUPT_MASK 0xd0004C |
| 39 | 39 | ||
| 40 | static struct file_operations cx18_v4l2_enc_fops = { | 40 | static struct v4l2_file_operations cx18_v4l2_enc_fops = { |
| 41 | .owner = THIS_MODULE, | 41 | .owner = THIS_MODULE, |
| 42 | .read = cx18_v4l2_read, | 42 | .read = cx18_v4l2_read, |
| 43 | .open = cx18_v4l2_open, | 43 | .open = cx18_v4l2_open, |
| 44 | /* FIXME change to video_ioctl2 if serialization lock can be removed */ | 44 | /* FIXME change to video_ioctl2 if serialization lock can be removed */ |
| 45 | .ioctl = cx18_v4l2_ioctl, | 45 | .ioctl = cx18_v4l2_ioctl, |
| 46 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 47 | .release = cx18_v4l2_close, | 46 | .release = cx18_v4l2_close, |
| 48 | .poll = cx18_v4l2_enc_poll, | 47 | .poll = cx18_v4l2_enc_poll, |
| 49 | }; | 48 | }; |
| @@ -61,49 +60,41 @@ static struct { | |||
| 61 | int num_offset; | 60 | int num_offset; |
| 62 | int dma; | 61 | int dma; |
| 63 | enum v4l2_buf_type buf_type; | 62 | enum v4l2_buf_type buf_type; |
| 64 | struct file_operations *fops; | ||
| 65 | } cx18_stream_info[] = { | 63 | } cx18_stream_info[] = { |
| 66 | { /* CX18_ENC_STREAM_TYPE_MPG */ | 64 | { /* CX18_ENC_STREAM_TYPE_MPG */ |
| 67 | "encoder MPEG", | 65 | "encoder MPEG", |
| 68 | VFL_TYPE_GRABBER, 0, | 66 | VFL_TYPE_GRABBER, 0, |
| 69 | PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, | 67 | PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, |
| 70 | &cx18_v4l2_enc_fops | ||
| 71 | }, | 68 | }, |
| 72 | { /* CX18_ENC_STREAM_TYPE_TS */ | 69 | { /* CX18_ENC_STREAM_TYPE_TS */ |
| 73 | "TS", | 70 | "TS", |
| 74 | VFL_TYPE_GRABBER, -1, | 71 | VFL_TYPE_GRABBER, -1, |
| 75 | PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, | 72 | PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, |
| 76 | &cx18_v4l2_enc_fops | ||
| 77 | }, | 73 | }, |
| 78 | { /* CX18_ENC_STREAM_TYPE_YUV */ | 74 | { /* CX18_ENC_STREAM_TYPE_YUV */ |
| 79 | "encoder YUV", | 75 | "encoder YUV", |
| 80 | VFL_TYPE_GRABBER, CX18_V4L2_ENC_YUV_OFFSET, | 76 | VFL_TYPE_GRABBER, CX18_V4L2_ENC_YUV_OFFSET, |
| 81 | PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, | 77 | PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, |
| 82 | &cx18_v4l2_enc_fops | ||
| 83 | }, | 78 | }, |
| 84 | { /* CX18_ENC_STREAM_TYPE_VBI */ | 79 | { /* CX18_ENC_STREAM_TYPE_VBI */ |
| 85 | "encoder VBI", | 80 | "encoder VBI", |
| 86 | VFL_TYPE_VBI, 0, | 81 | VFL_TYPE_VBI, 0, |
| 87 | PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VBI_CAPTURE, | 82 | PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VBI_CAPTURE, |
| 88 | &cx18_v4l2_enc_fops | ||
| 89 | }, | 83 | }, |
| 90 | { /* CX18_ENC_STREAM_TYPE_PCM */ | 84 | { /* CX18_ENC_STREAM_TYPE_PCM */ |
| 91 | "encoder PCM audio", | 85 | "encoder PCM audio", |
| 92 | VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET, | 86 | VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET, |
| 93 | PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_PRIVATE, | 87 | PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_PRIVATE, |
| 94 | &cx18_v4l2_enc_fops | ||
| 95 | }, | 88 | }, |
| 96 | { /* CX18_ENC_STREAM_TYPE_IDX */ | 89 | { /* CX18_ENC_STREAM_TYPE_IDX */ |
| 97 | "encoder IDX", | 90 | "encoder IDX", |
| 98 | VFL_TYPE_GRABBER, -1, | 91 | VFL_TYPE_GRABBER, -1, |
| 99 | PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, | 92 | PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, |
| 100 | &cx18_v4l2_enc_fops | ||
| 101 | }, | 93 | }, |
| 102 | { /* CX18_ENC_STREAM_TYPE_RAD */ | 94 | { /* CX18_ENC_STREAM_TYPE_RAD */ |
| 103 | "encoder radio", | 95 | "encoder radio", |
| 104 | VFL_TYPE_RADIO, 0, | 96 | VFL_TYPE_RADIO, 0, |
| 105 | PCI_DMA_NONE, V4L2_BUF_TYPE_PRIVATE, | 97 | PCI_DMA_NONE, V4L2_BUF_TYPE_PRIVATE, |
| 106 | &cx18_v4l2_enc_fops | ||
| 107 | }, | 98 | }, |
| 108 | }; | 99 | }; |
| 109 | 100 | ||
| @@ -184,7 +175,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type) | |||
| 184 | 175 | ||
| 185 | s->v4l2dev->num = num; | 176 | s->v4l2dev->num = num; |
| 186 | s->v4l2dev->parent = &cx->dev->dev; | 177 | s->v4l2dev->parent = &cx->dev->dev; |
| 187 | s->v4l2dev->fops = cx18_stream_info[type].fops; | 178 | s->v4l2dev->fops = &cx18_v4l2_enc_fops; |
| 188 | s->v4l2dev->release = video_device_release; | 179 | s->v4l2dev->release = video_device_release; |
| 189 | s->v4l2dev->tvnorms = V4L2_STD_ALL; | 180 | s->v4l2dev->tvnorms = V4L2_STD_ALL; |
| 190 | cx18_set_funcs(s->v4l2dev); | 181 | cx18_set_funcs(s->v4l2dev); |
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 798d24024353..8f1db57bd1dd 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c | |||
| @@ -1027,12 +1027,13 @@ static int cx23885_initialize_codec(struct cx23885_dev *dev) | |||
| 1027 | printk(KERN_ERR "%s() f/w load failed\n", __func__); | 1027 | printk(KERN_ERR "%s() f/w load failed\n", __func__); |
| 1028 | return retval; | 1028 | return retval; |
| 1029 | } | 1029 | } |
| 1030 | dev->cx23417_mailbox = cx23885_find_mailbox(dev); | 1030 | retval = cx23885_find_mailbox(dev); |
| 1031 | if (dev->cx23417_mailbox < 0) { | 1031 | if (retval < 0) { |
| 1032 | printk(KERN_ERR "%s() mailbox < 0, error\n", | 1032 | printk(KERN_ERR "%s() mailbox < 0, error\n", |
| 1033 | __func__); | 1033 | __func__); |
| 1034 | return -1; | 1034 | return -1; |
| 1035 | } | 1035 | } |
| 1036 | dev->cx23417_mailbox = retval; | ||
| 1036 | retval = cx23885_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); | 1037 | retval = cx23885_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); |
| 1037 | if (retval < 0) { | 1038 | if (retval < 0) { |
| 1038 | printk(KERN_ERR | 1039 | printk(KERN_ERR |
| @@ -1573,9 +1574,9 @@ static int vidioc_queryctrl(struct file *file, void *priv, | |||
| 1573 | return cx23885_queryctrl(dev, c); | 1574 | return cx23885_queryctrl(dev, c); |
| 1574 | } | 1575 | } |
| 1575 | 1576 | ||
| 1576 | static int mpeg_open(struct inode *inode, struct file *file) | 1577 | static int mpeg_open(struct file *file) |
| 1577 | { | 1578 | { |
| 1578 | int minor = iminor(inode); | 1579 | int minor = video_devdata(file)->minor; |
| 1579 | struct cx23885_dev *h, *dev = NULL; | 1580 | struct cx23885_dev *h, *dev = NULL; |
| 1580 | struct list_head *list; | 1581 | struct list_head *list; |
| 1581 | struct cx23885_fh *fh; | 1582 | struct cx23885_fh *fh; |
| @@ -1617,7 +1618,7 @@ static int mpeg_open(struct inode *inode, struct file *file) | |||
| 1617 | return 0; | 1618 | return 0; |
| 1618 | } | 1619 | } |
| 1619 | 1620 | ||
| 1620 | static int mpeg_release(struct inode *inode, struct file *file) | 1621 | static int mpeg_release(struct file *file) |
| 1621 | { | 1622 | { |
| 1622 | struct cx23885_fh *fh = file->private_data; | 1623 | struct cx23885_fh *fh = file->private_data; |
| 1623 | struct cx23885_dev *dev = fh->dev; | 1624 | struct cx23885_dev *dev = fh->dev; |
| @@ -1694,15 +1695,13 @@ static int mpeg_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 1694 | return videobuf_mmap_mapper(&fh->mpegq, vma); | 1695 | return videobuf_mmap_mapper(&fh->mpegq, vma); |
| 1695 | } | 1696 | } |
| 1696 | 1697 | ||
| 1697 | static struct file_operations mpeg_fops = { | 1698 | static struct v4l2_file_operations mpeg_fops = { |
| 1698 | .owner = THIS_MODULE, | 1699 | .owner = THIS_MODULE, |
| 1699 | .open = mpeg_open, | 1700 | .open = mpeg_open, |
| 1700 | .release = mpeg_release, | 1701 | .release = mpeg_release, |
| 1701 | .read = mpeg_read, | 1702 | .read = mpeg_read, |
| 1702 | .poll = mpeg_poll, | 1703 | .poll = mpeg_poll, |
| 1703 | .mmap = mpeg_mmap, | 1704 | .mmap = mpeg_mmap, |
| 1704 | .ioctl = video_ioctl2, | ||
| 1705 | .llseek = no_llseek, | ||
| 1706 | }; | 1705 | }; |
| 1707 | 1706 | ||
| 1708 | static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { | 1707 | static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { |
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index c742a10be5cb..2d81c4d04340 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c | |||
| @@ -718,9 +718,9 @@ static int get_resource(struct cx23885_fh *fh) | |||
| 718 | } | 718 | } |
| 719 | } | 719 | } |
| 720 | 720 | ||
| 721 | static int video_open(struct inode *inode, struct file *file) | 721 | static int video_open(struct file *file) |
| 722 | { | 722 | { |
| 723 | int minor = iminor(inode); | 723 | int minor = video_devdata(file)->minor; |
| 724 | struct cx23885_dev *h, *dev = NULL; | 724 | struct cx23885_dev *h, *dev = NULL; |
| 725 | struct cx23885_fh *fh; | 725 | struct cx23885_fh *fh; |
| 726 | struct list_head *list; | 726 | struct list_head *list; |
| @@ -834,7 +834,7 @@ static unsigned int video_poll(struct file *file, | |||
| 834 | return 0; | 834 | return 0; |
| 835 | } | 835 | } |
| 836 | 836 | ||
| 837 | static int video_release(struct inode *inode, struct file *file) | 837 | static int video_release(struct file *file) |
| 838 | { | 838 | { |
| 839 | struct cx23885_fh *fh = file->private_data; | 839 | struct cx23885_fh *fh = file->private_data; |
| 840 | struct cx23885_dev *dev = fh->dev; | 840 | struct cx23885_dev *dev = fh->dev; |
| @@ -1326,11 +1326,11 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
| 1326 | 1326 | ||
| 1327 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1327 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 1328 | static int vidioc_g_register(struct file *file, void *fh, | 1328 | static int vidioc_g_register(struct file *file, void *fh, |
| 1329 | struct v4l2_register *reg) | 1329 | struct v4l2_dbg_register *reg) |
| 1330 | { | 1330 | { |
| 1331 | struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; | 1331 | struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; |
| 1332 | 1332 | ||
| 1333 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 1333 | if (!v4l2_chip_match_host(®->match)) |
| 1334 | return -EINVAL; | 1334 | return -EINVAL; |
| 1335 | 1335 | ||
| 1336 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_G_REGISTER, reg); | 1336 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_G_REGISTER, reg); |
| @@ -1339,11 +1339,11 @@ static int vidioc_g_register(struct file *file, void *fh, | |||
| 1339 | } | 1339 | } |
| 1340 | 1340 | ||
| 1341 | static int vidioc_s_register(struct file *file, void *fh, | 1341 | static int vidioc_s_register(struct file *file, void *fh, |
| 1342 | struct v4l2_register *reg) | 1342 | struct v4l2_dbg_register *reg) |
| 1343 | { | 1343 | { |
| 1344 | struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; | 1344 | struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; |
| 1345 | 1345 | ||
| 1346 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 1346 | if (!v4l2_chip_match_host(®->match)) |
| 1347 | return -EINVAL; | 1347 | return -EINVAL; |
| 1348 | 1348 | ||
| 1349 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_S_REGISTER, reg); | 1349 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_S_REGISTER, reg); |
| @@ -1422,7 +1422,7 @@ int cx23885_video_irq(struct cx23885_dev *dev, u32 status) | |||
| 1422 | /* ----------------------------------------------------------- */ | 1422 | /* ----------------------------------------------------------- */ |
| 1423 | /* exported stuff */ | 1423 | /* exported stuff */ |
| 1424 | 1424 | ||
| 1425 | static const struct file_operations video_fops = { | 1425 | static const struct v4l2_file_operations video_fops = { |
| 1426 | .owner = THIS_MODULE, | 1426 | .owner = THIS_MODULE, |
| 1427 | .open = video_open, | 1427 | .open = video_open, |
| 1428 | .release = video_release, | 1428 | .release = video_release, |
| @@ -1430,8 +1430,6 @@ static const struct file_operations video_fops = { | |||
| 1430 | .poll = video_poll, | 1430 | .poll = video_poll, |
| 1431 | .mmap = video_mmap, | 1431 | .mmap = video_mmap, |
| 1432 | .ioctl = video_ioctl2, | 1432 | .ioctl = video_ioctl2, |
| 1433 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1434 | .llseek = no_llseek, | ||
| 1435 | }; | 1433 | }; |
| 1436 | 1434 | ||
| 1437 | static const struct v4l2_ioctl_ops video_ioctl_ops = { | 1435 | static const struct v4l2_ioctl_ops video_ioctl_ops = { |
| @@ -1479,13 +1477,11 @@ static struct video_device cx23885_video_template = { | |||
| 1479 | .current_norm = V4L2_STD_NTSC_M, | 1477 | .current_norm = V4L2_STD_NTSC_M, |
| 1480 | }; | 1478 | }; |
| 1481 | 1479 | ||
| 1482 | static const struct file_operations radio_fops = { | 1480 | static const struct v4l2_file_operations radio_fops = { |
| 1483 | .owner = THIS_MODULE, | 1481 | .owner = THIS_MODULE, |
| 1484 | .open = video_open, | 1482 | .open = video_open, |
| 1485 | .release = video_release, | 1483 | .release = video_release, |
| 1486 | .ioctl = video_ioctl2, | 1484 | .ioctl = video_ioctl2, |
| 1487 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1488 | .llseek = no_llseek, | ||
| 1489 | }; | 1485 | }; |
| 1490 | 1486 | ||
| 1491 | 1487 | ||
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 2ad277189da8..88f2fd32bfe3 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
| @@ -1120,25 +1120,24 @@ static int cx25840_init(struct v4l2_subdev *sd, u32 val) | |||
| 1120 | } | 1120 | } |
| 1121 | 1121 | ||
| 1122 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1122 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 1123 | static int cx25840_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 1123 | static int cx25840_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 1124 | { | 1124 | { |
| 1125 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 1125 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 1126 | 1126 | ||
| 1127 | if (!v4l2_chip_match_i2c_client(client, | 1127 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 1128 | reg->match_type, reg->match_chip)) | ||
| 1129 | return -EINVAL; | 1128 | return -EINVAL; |
| 1130 | if (!capable(CAP_SYS_ADMIN)) | 1129 | if (!capable(CAP_SYS_ADMIN)) |
| 1131 | return -EPERM; | 1130 | return -EPERM; |
| 1131 | reg->size = 1; | ||
| 1132 | reg->val = cx25840_read(client, reg->reg & 0x0fff); | 1132 | reg->val = cx25840_read(client, reg->reg & 0x0fff); |
| 1133 | return 0; | 1133 | return 0; |
| 1134 | } | 1134 | } |
| 1135 | 1135 | ||
| 1136 | static int cx25840_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 1136 | static int cx25840_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 1137 | { | 1137 | { |
| 1138 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 1138 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 1139 | 1139 | ||
| 1140 | if (!v4l2_chip_match_i2c_client(client, | 1140 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 1141 | reg->match_type, reg->match_chip)) | ||
| 1142 | return -EINVAL; | 1141 | return -EINVAL; |
| 1143 | if (!capable(CAP_SYS_ADMIN)) | 1142 | if (!capable(CAP_SYS_ADMIN)) |
| 1144 | return -EPERM; | 1143 | return -EPERM; |
| @@ -1362,7 +1361,7 @@ static int cx25840_reset(struct v4l2_subdev *sd, u32 val) | |||
| 1362 | return 0; | 1361 | return 0; |
| 1363 | } | 1362 | } |
| 1364 | 1363 | ||
| 1365 | static int cx25840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) | 1364 | static int cx25840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) |
| 1366 | { | 1365 | { |
| 1367 | struct cx25840_state *state = to_state(sd); | 1366 | struct cx25840_state *state = to_state(sd); |
| 1368 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 1367 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index e162a70748c5..7f5b8bfd08ac 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
| @@ -1049,16 +1049,16 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id) | |||
| 1049 | 1049 | ||
| 1050 | /* FIXME: cx88_ioctl_hook not implemented */ | 1050 | /* FIXME: cx88_ioctl_hook not implemented */ |
| 1051 | 1051 | ||
| 1052 | static int mpeg_open(struct inode *inode, struct file *file) | 1052 | static int mpeg_open(struct file *file) |
| 1053 | { | 1053 | { |
| 1054 | int minor = iminor(inode); | 1054 | int minor = video_devdata(file)->minor; |
| 1055 | struct cx8802_dev *dev = NULL; | 1055 | struct cx8802_dev *dev = NULL; |
| 1056 | struct cx8802_fh *fh; | 1056 | struct cx8802_fh *fh; |
| 1057 | struct cx8802_driver *drv = NULL; | 1057 | struct cx8802_driver *drv = NULL; |
| 1058 | int err; | 1058 | int err; |
| 1059 | 1059 | ||
| 1060 | lock_kernel(); | 1060 | lock_kernel(); |
| 1061 | dev = cx8802_get_device(inode); | 1061 | dev = cx8802_get_device(minor); |
| 1062 | 1062 | ||
| 1063 | dprintk( 1, "%s\n", __func__); | 1063 | dprintk( 1, "%s\n", __func__); |
| 1064 | 1064 | ||
| @@ -1114,7 +1114,7 @@ static int mpeg_open(struct inode *inode, struct file *file) | |||
| 1114 | return 0; | 1114 | return 0; |
| 1115 | } | 1115 | } |
| 1116 | 1116 | ||
| 1117 | static int mpeg_release(struct inode *inode, struct file *file) | 1117 | static int mpeg_release(struct file *file) |
| 1118 | { | 1118 | { |
| 1119 | struct cx8802_fh *fh = file->private_data; | 1119 | struct cx8802_fh *fh = file->private_data; |
| 1120 | struct cx8802_dev *dev = fh->dev; | 1120 | struct cx8802_dev *dev = fh->dev; |
| @@ -1132,7 +1132,7 @@ static int mpeg_release(struct inode *inode, struct file *file) | |||
| 1132 | kfree(fh); | 1132 | kfree(fh); |
| 1133 | 1133 | ||
| 1134 | /* Make sure we release the hardware */ | 1134 | /* Make sure we release the hardware */ |
| 1135 | dev = cx8802_get_device(inode); | 1135 | dev = cx8802_get_device(video_devdata(file)->minor); |
| 1136 | if (dev == NULL) | 1136 | if (dev == NULL) |
| 1137 | return -ENODEV; | 1137 | return -ENODEV; |
| 1138 | 1138 | ||
| @@ -1178,7 +1178,7 @@ mpeg_mmap(struct file *file, struct vm_area_struct * vma) | |||
| 1178 | return videobuf_mmap_mapper(&fh->mpegq, vma); | 1178 | return videobuf_mmap_mapper(&fh->mpegq, vma); |
| 1179 | } | 1179 | } |
| 1180 | 1180 | ||
| 1181 | static const struct file_operations mpeg_fops = | 1181 | static const struct v4l2_file_operations mpeg_fops = |
| 1182 | { | 1182 | { |
| 1183 | .owner = THIS_MODULE, | 1183 | .owner = THIS_MODULE, |
| 1184 | .open = mpeg_open, | 1184 | .open = mpeg_open, |
| @@ -1187,7 +1187,6 @@ static const struct file_operations mpeg_fops = | |||
| 1187 | .poll = mpeg_poll, | 1187 | .poll = mpeg_poll, |
| 1188 | .mmap = mpeg_mmap, | 1188 | .mmap = mpeg_mmap, |
| 1189 | .ioctl = video_ioctl2, | 1189 | .ioctl = video_ioctl2, |
| 1190 | .llseek = no_llseek, | ||
| 1191 | }; | 1190 | }; |
| 1192 | 1191 | ||
| 1193 | static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { | 1192 | static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { |
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index a04fee235db6..59164fc94f5f 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
| @@ -578,9 +578,8 @@ static int cx8802_resume_common(struct pci_dev *pci_dev) | |||
| 578 | 578 | ||
| 579 | #if defined(CONFIG_VIDEO_CX88_BLACKBIRD) || \ | 579 | #if defined(CONFIG_VIDEO_CX88_BLACKBIRD) || \ |
| 580 | defined(CONFIG_VIDEO_CX88_BLACKBIRD_MODULE) | 580 | defined(CONFIG_VIDEO_CX88_BLACKBIRD_MODULE) |
| 581 | struct cx8802_dev * cx8802_get_device(struct inode *inode) | 581 | struct cx8802_dev *cx8802_get_device(int minor) |
| 582 | { | 582 | { |
| 583 | int minor = iminor(inode); | ||
| 584 | struct cx8802_dev *dev; | 583 | struct cx8802_dev *dev; |
| 585 | 584 | ||
| 586 | list_for_each_entry(dev, &cx8802_devlist, devlist) | 585 | list_for_each_entry(dev, &cx8802_devlist, devlist) |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index b96ce991d968..791e69d804f9 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
| @@ -757,9 +757,9 @@ static int get_ressource(struct cx8800_fh *fh) | |||
| 757 | } | 757 | } |
| 758 | } | 758 | } |
| 759 | 759 | ||
| 760 | static int video_open(struct inode *inode, struct file *file) | 760 | static int video_open(struct file *file) |
| 761 | { | 761 | { |
| 762 | int minor = iminor(inode); | 762 | int minor = video_devdata(file)->minor; |
| 763 | struct cx8800_dev *h,*dev = NULL; | 763 | struct cx8800_dev *h,*dev = NULL; |
| 764 | struct cx88_core *core; | 764 | struct cx88_core *core; |
| 765 | struct cx8800_fh *fh; | 765 | struct cx8800_fh *fh; |
| @@ -904,7 +904,7 @@ video_poll(struct file *file, struct poll_table_struct *wait) | |||
| 904 | return 0; | 904 | return 0; |
| 905 | } | 905 | } |
| 906 | 906 | ||
| 907 | static int video_release(struct inode *inode, struct file *file) | 907 | static int video_release(struct file *file) |
| 908 | { | 908 | { |
| 909 | struct cx8800_fh *fh = file->private_data; | 909 | struct cx8800_fh *fh = file->private_data; |
| 910 | struct cx8800_dev *dev = fh->dev; | 910 | struct cx8800_dev *dev = fh->dev; |
| @@ -1447,25 +1447,26 @@ static int vidioc_s_frequency (struct file *file, void *priv, | |||
| 1447 | 1447 | ||
| 1448 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1448 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 1449 | static int vidioc_g_register (struct file *file, void *fh, | 1449 | static int vidioc_g_register (struct file *file, void *fh, |
| 1450 | struct v4l2_register *reg) | 1450 | struct v4l2_dbg_register *reg) |
| 1451 | { | 1451 | { |
| 1452 | struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core; | 1452 | struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core; |
| 1453 | 1453 | ||
| 1454 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 1454 | if (!v4l2_chip_match_host(®->match)) |
| 1455 | return -EINVAL; | 1455 | return -EINVAL; |
| 1456 | /* cx2388x has a 24-bit register space */ | 1456 | /* cx2388x has a 24-bit register space */ |
| 1457 | reg->val = cx_read(reg->reg&0xffffff); | 1457 | reg->val = cx_read(reg->reg & 0xffffff); |
| 1458 | reg->size = 4; | ||
| 1458 | return 0; | 1459 | return 0; |
| 1459 | } | 1460 | } |
| 1460 | 1461 | ||
| 1461 | static int vidioc_s_register (struct file *file, void *fh, | 1462 | static int vidioc_s_register (struct file *file, void *fh, |
| 1462 | struct v4l2_register *reg) | 1463 | struct v4l2_dbg_register *reg) |
| 1463 | { | 1464 | { |
| 1464 | struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core; | 1465 | struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core; |
| 1465 | 1466 | ||
| 1466 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 1467 | if (!v4l2_chip_match_host(®->match)) |
| 1467 | return -EINVAL; | 1468 | return -EINVAL; |
| 1468 | cx_write(reg->reg&0xffffff, reg->val); | 1469 | cx_write(reg->reg & 0xffffff, reg->val); |
| 1469 | return 0; | 1470 | return 0; |
| 1470 | } | 1471 | } |
| 1471 | #endif | 1472 | #endif |
| @@ -1693,7 +1694,7 @@ static irqreturn_t cx8800_irq(int irq, void *dev_id) | |||
| 1693 | /* ----------------------------------------------------------- */ | 1694 | /* ----------------------------------------------------------- */ |
| 1694 | /* exported stuff */ | 1695 | /* exported stuff */ |
| 1695 | 1696 | ||
| 1696 | static const struct file_operations video_fops = | 1697 | static const struct v4l2_file_operations video_fops = |
| 1697 | { | 1698 | { |
| 1698 | .owner = THIS_MODULE, | 1699 | .owner = THIS_MODULE, |
| 1699 | .open = video_open, | 1700 | .open = video_open, |
| @@ -1702,8 +1703,6 @@ static const struct file_operations video_fops = | |||
| 1702 | .poll = video_poll, | 1703 | .poll = video_poll, |
| 1703 | .mmap = video_mmap, | 1704 | .mmap = video_mmap, |
| 1704 | .ioctl = video_ioctl2, | 1705 | .ioctl = video_ioctl2, |
| 1705 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1706 | .llseek = no_llseek, | ||
| 1707 | }; | 1706 | }; |
| 1708 | 1707 | ||
| 1709 | static const struct v4l2_ioctl_ops video_ioctl_ops = { | 1708 | static const struct v4l2_ioctl_ops video_ioctl_ops = { |
| @@ -1752,14 +1751,12 @@ static struct video_device cx8800_video_template = { | |||
| 1752 | .current_norm = V4L2_STD_NTSC_M, | 1751 | .current_norm = V4L2_STD_NTSC_M, |
| 1753 | }; | 1752 | }; |
| 1754 | 1753 | ||
| 1755 | static const struct file_operations radio_fops = | 1754 | static const struct v4l2_file_operations radio_fops = |
| 1756 | { | 1755 | { |
| 1757 | .owner = THIS_MODULE, | 1756 | .owner = THIS_MODULE, |
| 1758 | .open = video_open, | 1757 | .open = video_open, |
| 1759 | .release = video_release, | 1758 | .release = video_release, |
| 1760 | .ioctl = video_ioctl2, | 1759 | .ioctl = video_ioctl2, |
| 1761 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1762 | .llseek = no_llseek, | ||
| 1763 | }; | 1760 | }; |
| 1764 | 1761 | ||
| 1765 | static const struct v4l2_ioctl_ops radio_ioctl_ops = { | 1762 | static const struct v4l2_ioctl_ops radio_ioctl_ops = { |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 20649b25f7ba..eb9ce30dc5e6 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
| @@ -643,7 +643,7 @@ int cx88_audio_thread(void *data); | |||
| 643 | 643 | ||
| 644 | int cx8802_register_driver(struct cx8802_driver *drv); | 644 | int cx8802_register_driver(struct cx8802_driver *drv); |
| 645 | int cx8802_unregister_driver(struct cx8802_driver *drv); | 645 | int cx8802_unregister_driver(struct cx8802_driver *drv); |
| 646 | struct cx8802_dev * cx8802_get_device(struct inode *inode); | 646 | struct cx8802_dev *cx8802_get_device(int minor); |
| 647 | struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); | 647 | struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); |
| 648 | 648 | ||
| 649 | /* ----------------------------------------------------------- */ | 649 | /* ----------------------------------------------------------- */ |
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index 15c03f0e69ad..94378ccb7505 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c | |||
| @@ -62,9 +62,9 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev) | |||
| 62 | 62 | ||
| 63 | dprintk("Stopping isoc\n"); | 63 | dprintk("Stopping isoc\n"); |
| 64 | for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { | 64 | for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { |
| 65 | usb_unlink_urb(dev->adev->urb[i]); | 65 | usb_unlink_urb(dev->adev.urb[i]); |
| 66 | usb_free_urb(dev->adev->urb[i]); | 66 | usb_free_urb(dev->adev.urb[i]); |
| 67 | dev->adev->urb[i] = NULL; | 67 | dev->adev.urb[i] = NULL; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | return 0; | 70 | return 0; |
| @@ -81,8 +81,8 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
| 81 | unsigned int stride; | 81 | unsigned int stride; |
| 82 | struct snd_pcm_substream *substream; | 82 | struct snd_pcm_substream *substream; |
| 83 | struct snd_pcm_runtime *runtime; | 83 | struct snd_pcm_runtime *runtime; |
| 84 | if (dev->adev->capture_pcm_substream) { | 84 | if (dev->adev.capture_pcm_substream) { |
| 85 | substream = dev->adev->capture_pcm_substream; | 85 | substream = dev->adev.capture_pcm_substream; |
| 86 | runtime = substream->runtime; | 86 | runtime = substream->runtime; |
| 87 | stride = runtime->frame_bits >> 3; | 87 | stride = runtime->frame_bits >> 3; |
| 88 | 88 | ||
| @@ -95,7 +95,7 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
| 95 | if (!length) | 95 | if (!length) |
| 96 | continue; | 96 | continue; |
| 97 | 97 | ||
| 98 | oldptr = dev->adev->hwptr_done_capture; | 98 | oldptr = dev->adev.hwptr_done_capture; |
| 99 | if (oldptr + length >= runtime->buffer_size) { | 99 | if (oldptr + length >= runtime->buffer_size) { |
| 100 | unsigned int cnt = | 100 | unsigned int cnt = |
| 101 | runtime->buffer_size - oldptr; | 101 | runtime->buffer_size - oldptr; |
| @@ -110,16 +110,16 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
| 110 | 110 | ||
| 111 | snd_pcm_stream_lock(substream); | 111 | snd_pcm_stream_lock(substream); |
| 112 | 112 | ||
| 113 | dev->adev->hwptr_done_capture += length; | 113 | dev->adev.hwptr_done_capture += length; |
| 114 | if (dev->adev->hwptr_done_capture >= | 114 | if (dev->adev.hwptr_done_capture >= |
| 115 | runtime->buffer_size) | 115 | runtime->buffer_size) |
| 116 | dev->adev->hwptr_done_capture -= | 116 | dev->adev.hwptr_done_capture -= |
| 117 | runtime->buffer_size; | 117 | runtime->buffer_size; |
| 118 | 118 | ||
| 119 | dev->adev->capture_transfer_done += length; | 119 | dev->adev.capture_transfer_done += length; |
| 120 | if (dev->adev->capture_transfer_done >= | 120 | if (dev->adev.capture_transfer_done >= |
| 121 | runtime->period_size) { | 121 | runtime->period_size) { |
| 122 | dev->adev->capture_transfer_done -= | 122 | dev->adev.capture_transfer_done -= |
| 123 | runtime->period_size; | 123 | runtime->period_size; |
| 124 | period_elapsed = 1; | 124 | period_elapsed = 1; |
| 125 | } | 125 | } |
| @@ -131,7 +131,7 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
| 131 | } | 131 | } |
| 132 | urb->status = 0; | 132 | urb->status = 0; |
| 133 | 133 | ||
| 134 | if (dev->adev->shutdown) | 134 | if (dev->adev.shutdown) |
| 135 | return; | 135 | return; |
| 136 | 136 | ||
| 137 | status = usb_submit_urb(urb, GFP_ATOMIC); | 137 | status = usb_submit_urb(urb, GFP_ATOMIC); |
| @@ -154,17 +154,17 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) | |||
| 154 | struct urb *urb; | 154 | struct urb *urb; |
| 155 | int j, k; | 155 | int j, k; |
| 156 | 156 | ||
| 157 | dev->adev->transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC); | 157 | dev->adev.transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC); |
| 158 | if (!dev->adev->transfer_buffer[i]) | 158 | if (!dev->adev.transfer_buffer[i]) |
| 159 | return -ENOMEM; | 159 | return -ENOMEM; |
| 160 | 160 | ||
| 161 | memset(dev->adev->transfer_buffer[i], 0x80, sb_size); | 161 | memset(dev->adev.transfer_buffer[i], 0x80, sb_size); |
| 162 | urb = usb_alloc_urb(EM28XX_NUM_AUDIO_PACKETS, GFP_ATOMIC); | 162 | urb = usb_alloc_urb(EM28XX_NUM_AUDIO_PACKETS, GFP_ATOMIC); |
| 163 | if (!urb) { | 163 | if (!urb) { |
| 164 | em28xx_errdev("usb_alloc_urb failed!\n"); | 164 | em28xx_errdev("usb_alloc_urb failed!\n"); |
| 165 | for (j = 0; j < i; j++) { | 165 | for (j = 0; j < i; j++) { |
| 166 | usb_free_urb(dev->adev->urb[j]); | 166 | usb_free_urb(dev->adev.urb[j]); |
| 167 | kfree(dev->adev->transfer_buffer[j]); | 167 | kfree(dev->adev.transfer_buffer[j]); |
| 168 | } | 168 | } |
| 169 | return -ENOMEM; | 169 | return -ENOMEM; |
| 170 | } | 170 | } |
| @@ -173,7 +173,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) | |||
| 173 | urb->context = dev; | 173 | urb->context = dev; |
| 174 | urb->pipe = usb_rcvisocpipe(dev->udev, 0x83); | 174 | urb->pipe = usb_rcvisocpipe(dev->udev, 0x83); |
| 175 | urb->transfer_flags = URB_ISO_ASAP; | 175 | urb->transfer_flags = URB_ISO_ASAP; |
| 176 | urb->transfer_buffer = dev->adev->transfer_buffer[i]; | 176 | urb->transfer_buffer = dev->adev.transfer_buffer[i]; |
| 177 | urb->interval = 1; | 177 | urb->interval = 1; |
| 178 | urb->complete = em28xx_audio_isocirq; | 178 | urb->complete = em28xx_audio_isocirq; |
| 179 | urb->number_of_packets = EM28XX_NUM_AUDIO_PACKETS; | 179 | urb->number_of_packets = EM28XX_NUM_AUDIO_PACKETS; |
| @@ -185,11 +185,11 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) | |||
| 185 | urb->iso_frame_desc[j].length = | 185 | urb->iso_frame_desc[j].length = |
| 186 | EM28XX_AUDIO_MAX_PACKET_SIZE; | 186 | EM28XX_AUDIO_MAX_PACKET_SIZE; |
| 187 | } | 187 | } |
| 188 | dev->adev->urb[i] = urb; | 188 | dev->adev.urb[i] = urb; |
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { | 191 | for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { |
| 192 | errCode = usb_submit_urb(dev->adev->urb[i], GFP_ATOMIC); | 192 | errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC); |
| 193 | if (errCode) { | 193 | if (errCode) { |
| 194 | em28xx_isoc_audio_deinit(dev); | 194 | em28xx_isoc_audio_deinit(dev); |
| 195 | 195 | ||
| @@ -202,16 +202,16 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) | |||
| 202 | 202 | ||
| 203 | static int em28xx_cmd(struct em28xx *dev, int cmd, int arg) | 203 | static int em28xx_cmd(struct em28xx *dev, int cmd, int arg) |
| 204 | { | 204 | { |
| 205 | dprintk("%s transfer\n", (dev->adev->capture_stream == STREAM_ON)? | 205 | dprintk("%s transfer\n", (dev->adev.capture_stream == STREAM_ON) ? |
| 206 | "stop" : "start"); | 206 | "stop" : "start"); |
| 207 | 207 | ||
| 208 | switch (cmd) { | 208 | switch (cmd) { |
| 209 | case EM28XX_CAPTURE_STREAM_EN: | 209 | case EM28XX_CAPTURE_STREAM_EN: |
| 210 | if (dev->adev->capture_stream == STREAM_OFF && arg == 1) { | 210 | if (dev->adev.capture_stream == STREAM_OFF && arg == 1) { |
| 211 | dev->adev->capture_stream = STREAM_ON; | 211 | dev->adev.capture_stream = STREAM_ON; |
| 212 | em28xx_init_audio_isoc(dev); | 212 | em28xx_init_audio_isoc(dev); |
| 213 | } else if (dev->adev->capture_stream == STREAM_ON && arg == 0) { | 213 | } else if (dev->adev.capture_stream == STREAM_ON && arg == 0) { |
| 214 | dev->adev->capture_stream = STREAM_OFF; | 214 | dev->adev.capture_stream = STREAM_OFF; |
| 215 | em28xx_isoc_audio_deinit(dev); | 215 | em28xx_isoc_audio_deinit(dev); |
| 216 | } else { | 216 | } else { |
| 217 | printk(KERN_ERR "An underrun very likely occurred. " | 217 | printk(KERN_ERR "An underrun very likely occurred. " |
| @@ -289,17 +289,17 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) | |||
| 289 | goto err; | 289 | goto err; |
| 290 | 290 | ||
| 291 | runtime->hw = snd_em28xx_hw_capture; | 291 | runtime->hw = snd_em28xx_hw_capture; |
| 292 | if (dev->alt == 0 && dev->adev->users == 0) { | 292 | if (dev->alt == 0 && dev->adev.users == 0) { |
| 293 | int errCode; | 293 | int errCode; |
| 294 | dev->alt = 7; | 294 | dev->alt = 7; |
| 295 | errCode = usb_set_interface(dev->udev, 0, 7); | 295 | errCode = usb_set_interface(dev->udev, 0, 7); |
| 296 | dprintk("changing alternate number to 7\n"); | 296 | dprintk("changing alternate number to 7\n"); |
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | dev->adev->users++; | 299 | dev->adev.users++; |
| 300 | 300 | ||
| 301 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); | 301 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); |
| 302 | dev->adev->capture_pcm_substream = substream; | 302 | dev->adev.capture_pcm_substream = substream; |
| 303 | runtime->private_data = dev; | 303 | runtime->private_data = dev; |
| 304 | 304 | ||
| 305 | return 0; | 305 | return 0; |
| @@ -311,7 +311,7 @@ err: | |||
| 311 | static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) | 311 | static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) |
| 312 | { | 312 | { |
| 313 | struct em28xx *dev = snd_pcm_substream_chip(substream); | 313 | struct em28xx *dev = snd_pcm_substream_chip(substream); |
| 314 | dev->adev->users--; | 314 | dev->adev.users--; |
| 315 | 315 | ||
| 316 | dprintk("closing device\n"); | 316 | dprintk("closing device\n"); |
| 317 | 317 | ||
| @@ -320,10 +320,10 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) | |||
| 320 | em28xx_audio_analog_set(dev); | 320 | em28xx_audio_analog_set(dev); |
| 321 | mutex_unlock(&dev->lock); | 321 | mutex_unlock(&dev->lock); |
| 322 | 322 | ||
| 323 | if (dev->adev->users == 0 && dev->adev->shutdown == 1) { | 323 | if (dev->adev.users == 0 && dev->adev.shutdown == 1) { |
| 324 | dprintk("audio users: %d\n", dev->adev->users); | 324 | dprintk("audio users: %d\n", dev->adev.users); |
| 325 | dprintk("disabling audio stream!\n"); | 325 | dprintk("disabling audio stream!\n"); |
| 326 | dev->adev->shutdown = 0; | 326 | dev->adev.shutdown = 0; |
| 327 | dprintk("released lock\n"); | 327 | dprintk("released lock\n"); |
| 328 | em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0); | 328 | em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0); |
| 329 | } | 329 | } |
| @@ -356,7 +356,7 @@ static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream) | |||
| 356 | 356 | ||
| 357 | dprintk("Stop capture, if needed\n"); | 357 | dprintk("Stop capture, if needed\n"); |
| 358 | 358 | ||
| 359 | if (dev->adev->capture_stream == STREAM_ON) | 359 | if (dev->adev.capture_stream == STREAM_ON) |
| 360 | em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0); | 360 | em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0); |
| 361 | 361 | ||
| 362 | return 0; | 362 | return 0; |
| @@ -379,7 +379,7 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream, | |||
| 379 | em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 1); | 379 | em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 1); |
| 380 | return 0; | 380 | return 0; |
| 381 | case SNDRV_PCM_TRIGGER_STOP: | 381 | case SNDRV_PCM_TRIGGER_STOP: |
| 382 | dev->adev->shutdown = 1; | 382 | dev->adev.shutdown = 1; |
| 383 | return 0; | 383 | return 0; |
| 384 | default: | 384 | default: |
| 385 | return -EINVAL; | 385 | return -EINVAL; |
| @@ -393,7 +393,7 @@ static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream | |||
| 393 | 393 | ||
| 394 | snd_pcm_uframes_t hwptr_done; | 394 | snd_pcm_uframes_t hwptr_done; |
| 395 | dev = snd_pcm_substream_chip(substream); | 395 | dev = snd_pcm_substream_chip(substream); |
| 396 | hwptr_done = dev->adev->hwptr_done_capture; | 396 | hwptr_done = dev->adev.hwptr_done_capture; |
| 397 | 397 | ||
| 398 | return hwptr_done; | 398 | return hwptr_done; |
| 399 | } | 399 | } |
| @@ -420,7 +420,7 @@ static struct snd_pcm_ops snd_em28xx_pcm_capture = { | |||
| 420 | 420 | ||
| 421 | static int em28xx_audio_init(struct em28xx *dev) | 421 | static int em28xx_audio_init(struct em28xx *dev) |
| 422 | { | 422 | { |
| 423 | struct em28xx_audio *adev; | 423 | struct em28xx_audio *adev = &dev->adev; |
| 424 | struct snd_pcm *pcm; | 424 | struct snd_pcm *pcm; |
| 425 | struct snd_card *card; | 425 | struct snd_card *card; |
| 426 | static int devnr; | 426 | static int devnr; |
| @@ -438,16 +438,9 @@ static int em28xx_audio_init(struct em28xx *dev) | |||
| 438 | printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus " | 438 | printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus " |
| 439 | "Rechberger\n"); | 439 | "Rechberger\n"); |
| 440 | 440 | ||
| 441 | adev = kzalloc(sizeof(*adev), GFP_KERNEL); | ||
| 442 | if (!adev) { | ||
| 443 | printk(KERN_ERR "em28xx-audio.c: out of memory\n"); | ||
| 444 | return -1; | ||
| 445 | } | ||
| 446 | card = snd_card_new(index[devnr], "Em28xx Audio", THIS_MODULE, 0); | 441 | card = snd_card_new(index[devnr], "Em28xx Audio", THIS_MODULE, 0); |
| 447 | if (card == NULL) { | 442 | if (card == NULL) |
| 448 | kfree(adev); | ||
| 449 | return -ENOMEM; | 443 | return -ENOMEM; |
| 450 | } | ||
| 451 | 444 | ||
| 452 | spin_lock_init(&adev->slock); | 445 | spin_lock_init(&adev->slock); |
| 453 | err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm); | 446 | err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm); |
| @@ -471,7 +464,6 @@ static int em28xx_audio_init(struct em28xx *dev) | |||
| 471 | } | 464 | } |
| 472 | adev->sndcard = card; | 465 | adev->sndcard = card; |
| 473 | adev->udev = dev->udev; | 466 | adev->udev = dev->udev; |
| 474 | dev->adev = adev; | ||
| 475 | 467 | ||
| 476 | return 0; | 468 | return 0; |
| 477 | } | 469 | } |
| @@ -488,10 +480,9 @@ static int em28xx_audio_fini(struct em28xx *dev) | |||
| 488 | return 0; | 480 | return 0; |
| 489 | } | 481 | } |
| 490 | 482 | ||
| 491 | if (dev->adev) { | 483 | if (dev->adev.sndcard) { |
| 492 | snd_card_free(dev->adev->sndcard); | 484 | snd_card_free(dev->adev.sndcard); |
| 493 | kfree(dev->adev); | 485 | dev->adev.sndcard = NULL; |
| 494 | dev->adev = NULL; | ||
| 495 | } | 486 | } |
| 496 | 487 | ||
| 497 | return 0; | 488 | return 0; |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index f8504518586a..819cceaa6ef4 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
| @@ -1000,12 +1000,11 @@ void em28xx_wake_i2c(struct em28xx *dev) | |||
| 1000 | static LIST_HEAD(em28xx_devlist); | 1000 | static LIST_HEAD(em28xx_devlist); |
| 1001 | static DEFINE_MUTEX(em28xx_devlist_mutex); | 1001 | static DEFINE_MUTEX(em28xx_devlist_mutex); |
| 1002 | 1002 | ||
| 1003 | struct em28xx *em28xx_get_device(struct inode *inode, | 1003 | struct em28xx *em28xx_get_device(int minor, |
| 1004 | enum v4l2_buf_type *fh_type, | 1004 | enum v4l2_buf_type *fh_type, |
| 1005 | int *has_radio) | 1005 | int *has_radio) |
| 1006 | { | 1006 | { |
| 1007 | struct em28xx *h, *dev = NULL; | 1007 | struct em28xx *h, *dev = NULL; |
| 1008 | int minor = iminor(inode); | ||
| 1009 | 1008 | ||
| 1010 | *fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1009 | *fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 1011 | *has_radio = 0; | 1010 | *has_radio = 0; |
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h index 65dcb91bdcc2..24e39c56811e 100644 --- a/drivers/media/video/em28xx/em28xx-reg.h +++ b/drivers/media/video/em28xx/em28xx-reg.h | |||
| @@ -160,7 +160,7 @@ | |||
| 160 | 160 | ||
| 161 | /* FIXME: Need to be populated with the other chip ID's */ | 161 | /* FIXME: Need to be populated with the other chip ID's */ |
| 162 | enum em28xx_chip_id { | 162 | enum em28xx_chip_id { |
| 163 | CHIP_ID_EM2820 = 18, | 163 | CHIP_ID_EM2820 = 18, /* Also used by em2710 */ |
| 164 | CHIP_ID_EM2840 = 20, | 164 | CHIP_ID_EM2840 = 20, |
| 165 | CHIP_ID_EM2750 = 33, | 165 | CHIP_ID_EM2750 = 33, |
| 166 | CHIP_ID_EM2860 = 34, | 166 | CHIP_ID_EM2860 = 34, |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 53527536481e..416b691c33c1 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
| @@ -1154,7 +1154,7 @@ static int em28xx_reg_len(int reg) | |||
| 1154 | } | 1154 | } |
| 1155 | 1155 | ||
| 1156 | static int vidioc_g_chip_ident(struct file *file, void *priv, | 1156 | static int vidioc_g_chip_ident(struct file *file, void *priv, |
| 1157 | struct v4l2_chip_ident *chip) | 1157 | struct v4l2_dbg_chip_ident *chip) |
| 1158 | { | 1158 | { |
| 1159 | struct em28xx_fh *fh = priv; | 1159 | struct em28xx_fh *fh = priv; |
| 1160 | struct em28xx *dev = fh->dev; | 1160 | struct em28xx *dev = fh->dev; |
| @@ -1162,20 +1162,20 @@ static int vidioc_g_chip_ident(struct file *file, void *priv, | |||
| 1162 | chip->ident = V4L2_IDENT_NONE; | 1162 | chip->ident = V4L2_IDENT_NONE; |
| 1163 | chip->revision = 0; | 1163 | chip->revision = 0; |
| 1164 | 1164 | ||
| 1165 | em28xx_i2c_call_clients(dev, VIDIOC_G_CHIP_IDENT, chip); | 1165 | em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_CHIP_IDENT, chip); |
| 1166 | 1166 | ||
| 1167 | return 0; | 1167 | return 0; |
| 1168 | } | 1168 | } |
| 1169 | 1169 | ||
| 1170 | 1170 | ||
| 1171 | static int vidioc_g_register(struct file *file, void *priv, | 1171 | static int vidioc_g_register(struct file *file, void *priv, |
| 1172 | struct v4l2_register *reg) | 1172 | struct v4l2_dbg_register *reg) |
| 1173 | { | 1173 | { |
| 1174 | struct em28xx_fh *fh = priv; | 1174 | struct em28xx_fh *fh = priv; |
| 1175 | struct em28xx *dev = fh->dev; | 1175 | struct em28xx *dev = fh->dev; |
| 1176 | int ret; | 1176 | int ret; |
| 1177 | 1177 | ||
| 1178 | switch (reg->match_type) { | 1178 | switch (reg->match.type) { |
| 1179 | case V4L2_CHIP_MATCH_AC97: | 1179 | case V4L2_CHIP_MATCH_AC97: |
| 1180 | mutex_lock(&dev->lock); | 1180 | mutex_lock(&dev->lock); |
| 1181 | ret = em28xx_read_ac97(dev, reg->reg); | 1181 | ret = em28xx_read_ac97(dev, reg->reg); |
| @@ -1184,6 +1184,7 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
| 1184 | return ret; | 1184 | return ret; |
| 1185 | 1185 | ||
| 1186 | reg->val = ret; | 1186 | reg->val = ret; |
| 1187 | reg->size = 1; | ||
| 1187 | return 0; | 1188 | return 0; |
| 1188 | case V4L2_CHIP_MATCH_I2C_DRIVER: | 1189 | case V4L2_CHIP_MATCH_I2C_DRIVER: |
| 1189 | em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_REGISTER, reg); | 1190 | em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_REGISTER, reg); |
| @@ -1192,12 +1193,13 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
| 1192 | /* Not supported yet */ | 1193 | /* Not supported yet */ |
| 1193 | return -EINVAL; | 1194 | return -EINVAL; |
| 1194 | default: | 1195 | default: |
| 1195 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 1196 | if (!v4l2_chip_match_host(®->match)) |
| 1196 | return -EINVAL; | 1197 | return -EINVAL; |
| 1197 | } | 1198 | } |
| 1198 | 1199 | ||
| 1199 | /* Match host */ | 1200 | /* Match host */ |
| 1200 | if (em28xx_reg_len(reg->reg) == 1) { | 1201 | reg->size = em28xx_reg_len(reg->reg); |
| 1202 | if (reg->size == 1) { | ||
| 1201 | mutex_lock(&dev->lock); | 1203 | mutex_lock(&dev->lock); |
| 1202 | ret = em28xx_read_reg(dev, reg->reg); | 1204 | ret = em28xx_read_reg(dev, reg->reg); |
| 1203 | mutex_unlock(&dev->lock); | 1205 | mutex_unlock(&dev->lock); |
| @@ -1207,7 +1209,7 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
| 1207 | 1209 | ||
| 1208 | reg->val = ret; | 1210 | reg->val = ret; |
| 1209 | } else { | 1211 | } else { |
| 1210 | __le64 val = 0; | 1212 | __le16 val = 0; |
| 1211 | mutex_lock(&dev->lock); | 1213 | mutex_lock(&dev->lock); |
| 1212 | ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, | 1214 | ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, |
| 1213 | reg->reg, (char *)&val, 2); | 1215 | reg->reg, (char *)&val, 2); |
| @@ -1215,21 +1217,21 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
| 1215 | if (ret < 0) | 1217 | if (ret < 0) |
| 1216 | return ret; | 1218 | return ret; |
| 1217 | 1219 | ||
| 1218 | reg->val = le64_to_cpu(val); | 1220 | reg->val = le16_to_cpu(val); |
| 1219 | } | 1221 | } |
| 1220 | 1222 | ||
| 1221 | return 0; | 1223 | return 0; |
| 1222 | } | 1224 | } |
| 1223 | 1225 | ||
| 1224 | static int vidioc_s_register(struct file *file, void *priv, | 1226 | static int vidioc_s_register(struct file *file, void *priv, |
| 1225 | struct v4l2_register *reg) | 1227 | struct v4l2_dbg_register *reg) |
| 1226 | { | 1228 | { |
| 1227 | struct em28xx_fh *fh = priv; | 1229 | struct em28xx_fh *fh = priv; |
| 1228 | struct em28xx *dev = fh->dev; | 1230 | struct em28xx *dev = fh->dev; |
| 1229 | __le64 buf; | 1231 | __le16 buf; |
| 1230 | int rc; | 1232 | int rc; |
| 1231 | 1233 | ||
| 1232 | switch (reg->match_type) { | 1234 | switch (reg->match.type) { |
| 1233 | case V4L2_CHIP_MATCH_AC97: | 1235 | case V4L2_CHIP_MATCH_AC97: |
| 1234 | mutex_lock(&dev->lock); | 1236 | mutex_lock(&dev->lock); |
| 1235 | rc = em28xx_write_ac97(dev, reg->reg, reg->val); | 1237 | rc = em28xx_write_ac97(dev, reg->reg, reg->val); |
| @@ -1243,12 +1245,12 @@ static int vidioc_s_register(struct file *file, void *priv, | |||
| 1243 | /* Not supported yet */ | 1245 | /* Not supported yet */ |
| 1244 | return -EINVAL; | 1246 | return -EINVAL; |
| 1245 | default: | 1247 | default: |
| 1246 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 1248 | if (!v4l2_chip_match_host(®->match)) |
| 1247 | return -EINVAL; | 1249 | return -EINVAL; |
| 1248 | } | 1250 | } |
| 1249 | 1251 | ||
| 1250 | /* Match host */ | 1252 | /* Match host */ |
| 1251 | buf = cpu_to_le64(reg->val); | 1253 | buf = cpu_to_le16(reg->val); |
| 1252 | 1254 | ||
| 1253 | mutex_lock(&dev->lock); | 1255 | mutex_lock(&dev->lock); |
| 1254 | rc = em28xx_write_regs(dev, reg->reg, (char *)&buf, | 1256 | rc = em28xx_write_regs(dev, reg->reg, (char *)&buf, |
| @@ -1582,15 +1584,15 @@ static int radio_queryctrl(struct file *file, void *priv, | |||
| 1582 | * em28xx_v4l2_open() | 1584 | * em28xx_v4l2_open() |
| 1583 | * inits the device and starts isoc transfer | 1585 | * inits the device and starts isoc transfer |
| 1584 | */ | 1586 | */ |
| 1585 | static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | 1587 | static int em28xx_v4l2_open(struct file *filp) |
| 1586 | { | 1588 | { |
| 1587 | int minor = iminor(inode); | 1589 | int minor = video_devdata(filp)->minor; |
| 1588 | int errCode = 0, radio; | 1590 | int errCode = 0, radio; |
| 1589 | struct em28xx *dev; | 1591 | struct em28xx *dev; |
| 1590 | enum v4l2_buf_type fh_type; | 1592 | enum v4l2_buf_type fh_type; |
| 1591 | struct em28xx_fh *fh; | 1593 | struct em28xx_fh *fh; |
| 1592 | 1594 | ||
| 1593 | dev = em28xx_get_device(inode, &fh_type, &radio); | 1595 | dev = em28xx_get_device(minor, &fh_type, &radio); |
| 1594 | 1596 | ||
| 1595 | if (NULL == dev) | 1597 | if (NULL == dev) |
| 1596 | return -ENODEV; | 1598 | return -ENODEV; |
| @@ -1686,7 +1688,7 @@ void em28xx_release_analog_resources(struct em28xx *dev) | |||
| 1686 | * stops streaming and deallocates all resources allocated by the v4l2 | 1688 | * stops streaming and deallocates all resources allocated by the v4l2 |
| 1687 | * calls and ioctls | 1689 | * calls and ioctls |
| 1688 | */ | 1690 | */ |
| 1689 | static int em28xx_v4l2_close(struct inode *inode, struct file *filp) | 1691 | static int em28xx_v4l2_close(struct file *filp) |
| 1690 | { | 1692 | { |
| 1691 | struct em28xx_fh *fh = filp->private_data; | 1693 | struct em28xx_fh *fh = filp->private_data; |
| 1692 | struct em28xx *dev = fh->dev; | 1694 | struct em28xx *dev = fh->dev; |
| @@ -1826,7 +1828,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) | |||
| 1826 | return rc; | 1828 | return rc; |
| 1827 | } | 1829 | } |
| 1828 | 1830 | ||
| 1829 | static const struct file_operations em28xx_v4l_fops = { | 1831 | static const struct v4l2_file_operations em28xx_v4l_fops = { |
| 1830 | .owner = THIS_MODULE, | 1832 | .owner = THIS_MODULE, |
| 1831 | .open = em28xx_v4l2_open, | 1833 | .open = em28xx_v4l2_open, |
| 1832 | .release = em28xx_v4l2_close, | 1834 | .release = em28xx_v4l2_close, |
| @@ -1834,8 +1836,6 @@ static const struct file_operations em28xx_v4l_fops = { | |||
| 1834 | .poll = em28xx_v4l2_poll, | 1836 | .poll = em28xx_v4l2_poll, |
| 1835 | .mmap = em28xx_v4l2_mmap, | 1837 | .mmap = em28xx_v4l2_mmap, |
| 1836 | .ioctl = video_ioctl2, | 1838 | .ioctl = video_ioctl2, |
| 1837 | .llseek = no_llseek, | ||
| 1838 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1839 | }; | 1839 | }; |
| 1840 | 1840 | ||
| 1841 | static const struct v4l2_ioctl_ops video_ioctl_ops = { | 1841 | static const struct v4l2_ioctl_ops video_ioctl_ops = { |
| @@ -1890,13 +1890,11 @@ static const struct video_device em28xx_video_template = { | |||
| 1890 | .current_norm = V4L2_STD_PAL, | 1890 | .current_norm = V4L2_STD_PAL, |
| 1891 | }; | 1891 | }; |
| 1892 | 1892 | ||
| 1893 | static const struct file_operations radio_fops = { | 1893 | static const struct v4l2_file_operations radio_fops = { |
| 1894 | .owner = THIS_MODULE, | 1894 | .owner = THIS_MODULE, |
| 1895 | .open = em28xx_v4l2_open, | 1895 | .open = em28xx_v4l2_open, |
| 1896 | .release = em28xx_v4l2_close, | 1896 | .release = em28xx_v4l2_close, |
| 1897 | .ioctl = video_ioctl2, | 1897 | .ioctl = video_ioctl2, |
| 1898 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1899 | .llseek = no_llseek, | ||
| 1900 | }; | 1898 | }; |
| 1901 | 1899 | ||
| 1902 | static const struct v4l2_ioctl_ops radio_ioctl_ops = { | 1900 | static const struct v4l2_ioctl_ops radio_ioctl_ops = { |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index b5eddc26388e..6c6b94aa05b2 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
| @@ -473,7 +473,7 @@ struct em28xx { | |||
| 473 | unsigned long i2c_hash; /* i2c devicelist hash - | 473 | unsigned long i2c_hash; /* i2c devicelist hash - |
| 474 | for boards with generic ID */ | 474 | for boards with generic ID */ |
| 475 | 475 | ||
| 476 | struct em28xx_audio *adev; | 476 | struct em28xx_audio adev; |
| 477 | 477 | ||
| 478 | /* states */ | 478 | /* states */ |
| 479 | enum em28xx_dev_state state; | 479 | enum em28xx_dev_state state; |
| @@ -583,7 +583,7 @@ int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); | |||
| 583 | void em28xx_wake_i2c(struct em28xx *dev); | 583 | void em28xx_wake_i2c(struct em28xx *dev); |
| 584 | void em28xx_remove_from_devlist(struct em28xx *dev); | 584 | void em28xx_remove_from_devlist(struct em28xx *dev); |
| 585 | void em28xx_add_into_devlist(struct em28xx *dev); | 585 | void em28xx_add_into_devlist(struct em28xx *dev); |
| 586 | struct em28xx *em28xx_get_device(struct inode *inode, | 586 | struct em28xx *em28xx_get_device(int minor, |
| 587 | enum v4l2_buf_type *fh_type, | 587 | enum v4l2_buf_type *fh_type, |
| 588 | int *has_radio); | 588 | int *has_radio); |
| 589 | int em28xx_register_extension(struct em28xx_ops *dev); | 589 | int em28xx_register_extension(struct em28xx_ops *dev); |
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index 83c07112c59d..d1c1e457f0b9 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c | |||
| @@ -1206,7 +1206,7 @@ static void et61x251_release_resources(struct kref *kref) | |||
| 1206 | } | 1206 | } |
| 1207 | 1207 | ||
| 1208 | 1208 | ||
| 1209 | static int et61x251_open(struct inode* inode, struct file* filp) | 1209 | static int et61x251_open(struct file *filp) |
| 1210 | { | 1210 | { |
| 1211 | struct et61x251_device* cam; | 1211 | struct et61x251_device* cam; |
| 1212 | int err = 0; | 1212 | int err = 0; |
| @@ -1291,7 +1291,7 @@ out: | |||
| 1291 | } | 1291 | } |
| 1292 | 1292 | ||
| 1293 | 1293 | ||
| 1294 | static int et61x251_release(struct inode* inode, struct file* filp) | 1294 | static int et61x251_release(struct file *filp) |
| 1295 | { | 1295 | { |
| 1296 | struct et61x251_device* cam; | 1296 | struct et61x251_device* cam; |
| 1297 | 1297 | ||
| @@ -2392,8 +2392,8 @@ et61x251_vidioc_s_parm(struct et61x251_device* cam, void __user * arg) | |||
| 2392 | } | 2392 | } |
| 2393 | 2393 | ||
| 2394 | 2394 | ||
| 2395 | static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp, | 2395 | static long et61x251_ioctl_v4l2(struct file *filp, |
| 2396 | unsigned int cmd, void __user * arg) | 2396 | unsigned int cmd, void __user *arg) |
| 2397 | { | 2397 | { |
| 2398 | struct et61x251_device *cam = video_drvdata(filp); | 2398 | struct et61x251_device *cam = video_drvdata(filp); |
| 2399 | 2399 | ||
| @@ -2487,11 +2487,11 @@ static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
| 2487 | } | 2487 | } |
| 2488 | 2488 | ||
| 2489 | 2489 | ||
| 2490 | static int et61x251_ioctl(struct inode* inode, struct file* filp, | 2490 | static long et61x251_ioctl(struct file *filp, |
| 2491 | unsigned int cmd, unsigned long arg) | 2491 | unsigned int cmd, unsigned long arg) |
| 2492 | { | 2492 | { |
| 2493 | struct et61x251_device *cam = video_drvdata(filp); | 2493 | struct et61x251_device *cam = video_drvdata(filp); |
| 2494 | int err = 0; | 2494 | long err = 0; |
| 2495 | 2495 | ||
| 2496 | if (mutex_lock_interruptible(&cam->fileop_mutex)) | 2496 | if (mutex_lock_interruptible(&cam->fileop_mutex)) |
| 2497 | return -ERESTARTSYS; | 2497 | return -ERESTARTSYS; |
| @@ -2511,7 +2511,7 @@ static int et61x251_ioctl(struct inode* inode, struct file* filp, | |||
| 2511 | 2511 | ||
| 2512 | V4LDBG(3, "et61x251", cmd); | 2512 | V4LDBG(3, "et61x251", cmd); |
| 2513 | 2513 | ||
| 2514 | err = et61x251_ioctl_v4l2(inode, filp, cmd, (void __user *)arg); | 2514 | err = et61x251_ioctl_v4l2(filp, cmd, (void __user *)arg); |
| 2515 | 2515 | ||
| 2516 | mutex_unlock(&cam->fileop_mutex); | 2516 | mutex_unlock(&cam->fileop_mutex); |
| 2517 | 2517 | ||
| @@ -2519,18 +2519,14 @@ static int et61x251_ioctl(struct inode* inode, struct file* filp, | |||
| 2519 | } | 2519 | } |
| 2520 | 2520 | ||
| 2521 | 2521 | ||
| 2522 | static const struct file_operations et61x251_fops = { | 2522 | static const struct v4l2_file_operations et61x251_fops = { |
| 2523 | .owner = THIS_MODULE, | 2523 | .owner = THIS_MODULE, |
| 2524 | .open = et61x251_open, | 2524 | .open = et61x251_open, |
| 2525 | .release = et61x251_release, | 2525 | .release = et61x251_release, |
| 2526 | .ioctl = et61x251_ioctl, | 2526 | .ioctl = et61x251_ioctl, |
| 2527 | #ifdef CONFIG_COMPAT | ||
| 2528 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 2529 | #endif | ||
| 2530 | .read = et61x251_read, | 2527 | .read = et61x251_read, |
| 2531 | .poll = et61x251_poll, | 2528 | .poll = et61x251_poll, |
| 2532 | .mmap = et61x251_mmap, | 2529 | .mmap = et61x251_mmap, |
| 2533 | .llseek = no_llseek, | ||
| 2534 | }; | 2530 | }; |
| 2535 | 2531 | ||
| 2536 | /*****************************************************************************/ | 2532 | /*****************************************************************************/ |
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 8b9f3bde5740..5e36b9a4ae3e 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
| @@ -875,7 +875,7 @@ static void gspca_release(struct video_device *vfd) | |||
| 875 | kfree(gspca_dev); | 875 | kfree(gspca_dev); |
| 876 | } | 876 | } |
| 877 | 877 | ||
| 878 | static int dev_open(struct inode *inode, struct file *file) | 878 | static int dev_open(struct file *file) |
| 879 | { | 879 | { |
| 880 | struct gspca_dev *gspca_dev; | 880 | struct gspca_dev *gspca_dev; |
| 881 | int ret; | 881 | int ret; |
| @@ -922,7 +922,7 @@ out: | |||
| 922 | return ret; | 922 | return ret; |
| 923 | } | 923 | } |
| 924 | 924 | ||
| 925 | static int dev_close(struct inode *inode, struct file *file) | 925 | static int dev_close(struct file *file) |
| 926 | { | 926 | { |
| 927 | struct gspca_dev *gspca_dev = file->private_data; | 927 | struct gspca_dev *gspca_dev = file->private_data; |
| 928 | 928 | ||
| @@ -1802,17 +1802,13 @@ out: | |||
| 1802 | return ret; | 1802 | return ret; |
| 1803 | } | 1803 | } |
| 1804 | 1804 | ||
| 1805 | static struct file_operations dev_fops = { | 1805 | static struct v4l2_file_operations dev_fops = { |
| 1806 | .owner = THIS_MODULE, | 1806 | .owner = THIS_MODULE, |
| 1807 | .open = dev_open, | 1807 | .open = dev_open, |
| 1808 | .release = dev_close, | 1808 | .release = dev_close, |
| 1809 | .read = dev_read, | 1809 | .read = dev_read, |
| 1810 | .mmap = dev_mmap, | 1810 | .mmap = dev_mmap, |
| 1811 | .unlocked_ioctl = __video_ioctl2, | 1811 | .unlocked_ioctl = video_ioctl2, |
| 1812 | #ifdef CONFIG_COMPAT | ||
| 1813 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1814 | #endif | ||
| 1815 | .llseek = no_llseek, | ||
| 1816 | .poll = dev_poll, | 1812 | .poll = dev_poll, |
| 1817 | }; | 1813 | }; |
| 1818 | 1814 | ||
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c index 352f84d440fb..79393d1772e4 100644 --- a/drivers/media/video/hexium_gemini.c +++ b/drivers/media/video/hexium_gemini.c | |||
| @@ -306,7 +306,7 @@ static int hexium_detach(struct saa7146_dev *dev) | |||
| 306 | return 0; | 306 | return 0; |
| 307 | } | 307 | } |
| 308 | 308 | ||
| 309 | static int hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | 309 | static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) |
| 310 | { | 310 | { |
| 311 | struct saa7146_dev *dev = fh->dev; | 311 | struct saa7146_dev *dev = fh->dev; |
| 312 | struct hexium *hexium = (struct hexium *) dev->ext_priv; | 312 | struct hexium *hexium = (struct hexium *) dev->ext_priv; |
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c index 8d3c1482e7ea..074bec711fe0 100644 --- a/drivers/media/video/hexium_orion.c +++ b/drivers/media/video/hexium_orion.c | |||
| @@ -370,7 +370,7 @@ static int hexium_detach(struct saa7146_dev *dev) | |||
| 370 | return 0; | 370 | return 0; |
| 371 | } | 371 | } |
| 372 | 372 | ||
| 373 | static int hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | 373 | static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) |
| 374 | { | 374 | { |
| 375 | struct saa7146_dev *dev = fh->dev; | 375 | struct saa7146_dev *dev = fh->dev; |
| 376 | struct hexium *hexium = (struct hexium *) dev->ext_priv; | 376 | struct hexium *hexium = (struct hexium *) dev->ext_priv; |
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 08b762951759..e8e5921cdc34 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
| @@ -902,18 +902,19 @@ static void ivtv_load_and_init_modules(struct ivtv *itv) | |||
| 902 | } | 902 | } |
| 903 | 903 | ||
| 904 | if (hw & IVTV_HW_SAA711X) { | 904 | if (hw & IVTV_HW_SAA711X) { |
| 905 | struct v4l2_chip_ident v = { V4L2_CHIP_MATCH_I2C_DRIVER, I2C_DRIVERID_SAA711X }; | 905 | struct v4l2_dbg_chip_ident v; |
| 906 | 906 | ||
| 907 | /* determine the exact saa711x model */ | 907 | /* determine the exact saa711x model */ |
| 908 | itv->hw_flags &= ~IVTV_HW_SAA711X; | 908 | itv->hw_flags &= ~IVTV_HW_SAA711X; |
| 909 | 909 | ||
| 910 | v.match.type = V4L2_CHIP_MATCH_I2C_DRIVER; | ||
| 911 | strlcpy(v.match.name, "saa7115", sizeof(v.match.name)); | ||
| 910 | ivtv_call_hw(itv, IVTV_HW_SAA711X, core, g_chip_ident, &v); | 912 | ivtv_call_hw(itv, IVTV_HW_SAA711X, core, g_chip_ident, &v); |
| 911 | if (v.ident == V4L2_IDENT_SAA7114) { | 913 | if (v.ident == V4L2_IDENT_SAA7114) { |
| 912 | itv->hw_flags |= IVTV_HW_SAA7114; | 914 | itv->hw_flags |= IVTV_HW_SAA7114; |
| 913 | /* VBI is not yet supported by the saa7114 driver. */ | 915 | /* VBI is not yet supported by the saa7114 driver. */ |
| 914 | itv->v4l2_cap &= ~(V4L2_CAP_SLICED_VBI_CAPTURE|V4L2_CAP_VBI_CAPTURE); | 916 | itv->v4l2_cap &= ~(V4L2_CAP_SLICED_VBI_CAPTURE|V4L2_CAP_VBI_CAPTURE); |
| 915 | } | 917 | } else { |
| 916 | else { | ||
| 917 | itv->hw_flags |= IVTV_HW_SAA7115; | 918 | itv->hw_flags |= IVTV_HW_SAA7115; |
| 918 | } | 919 | } |
| 919 | itv->vbi.raw_decoder_line_size = 1443; | 920 | itv->vbi.raw_decoder_line_size = 1443; |
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 5eb587592e9d..d594bc29f07f 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
| @@ -831,7 +831,7 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts) | |||
| 831 | ivtv_release_stream(s); | 831 | ivtv_release_stream(s); |
| 832 | } | 832 | } |
| 833 | 833 | ||
| 834 | int ivtv_v4l2_close(struct inode *inode, struct file *filp) | 834 | int ivtv_v4l2_close(struct file *filp) |
| 835 | { | 835 | { |
| 836 | struct ivtv_open_id *id = filp->private_data; | 836 | struct ivtv_open_id *id = filp->private_data; |
| 837 | struct ivtv *itv = id->itv; | 837 | struct ivtv *itv = id->itv; |
| @@ -978,7 +978,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) | |||
| 978 | return 0; | 978 | return 0; |
| 979 | } | 979 | } |
| 980 | 980 | ||
| 981 | int ivtv_v4l2_open(struct inode *inode, struct file *filp) | 981 | int ivtv_v4l2_open(struct file *filp) |
| 982 | { | 982 | { |
| 983 | int res; | 983 | int res; |
| 984 | struct ivtv *itv = NULL; | 984 | struct ivtv *itv = NULL; |
diff --git a/drivers/media/video/ivtv/ivtv-fileops.h b/drivers/media/video/ivtv/ivtv-fileops.h index df81e790147f..049a2923965d 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.h +++ b/drivers/media/video/ivtv/ivtv-fileops.h | |||
| @@ -22,12 +22,12 @@ | |||
| 22 | #define IVTV_FILEOPS_H | 22 | #define IVTV_FILEOPS_H |
| 23 | 23 | ||
| 24 | /* Testing/Debugging */ | 24 | /* Testing/Debugging */ |
| 25 | int ivtv_v4l2_open(struct inode *inode, struct file *filp); | 25 | int ivtv_v4l2_open(struct file *filp); |
| 26 | ssize_t ivtv_v4l2_read(struct file *filp, char __user *buf, size_t count, | 26 | ssize_t ivtv_v4l2_read(struct file *filp, char __user *buf, size_t count, |
| 27 | loff_t * pos); | 27 | loff_t * pos); |
| 28 | ssize_t ivtv_v4l2_write(struct file *filp, const char __user *buf, size_t count, | 28 | ssize_t ivtv_v4l2_write(struct file *filp, const char __user *buf, size_t count, |
| 29 | loff_t * pos); | 29 | loff_t * pos); |
| 30 | int ivtv_v4l2_close(struct inode *inode, struct file *filp); | 30 | int ivtv_v4l2_close(struct file *filp); |
| 31 | unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait); | 31 | unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait); |
| 32 | unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table * wait); | 32 | unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table * wait); |
| 33 | int ivtv_start_capture(struct ivtv_open_id *id); | 33 | int ivtv_start_capture(struct ivtv_open_id *id); |
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index cd990a4b81a9..f6b3ef6e691b 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
| @@ -674,19 +674,19 @@ static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_f | |||
| 674 | return ret; | 674 | return ret; |
| 675 | } | 675 | } |
| 676 | 676 | ||
| 677 | static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_chip_ident *chip) | 677 | static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip) |
| 678 | { | 678 | { |
| 679 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | 679 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
| 680 | 680 | ||
| 681 | chip->ident = V4L2_IDENT_NONE; | 681 | chip->ident = V4L2_IDENT_NONE; |
| 682 | chip->revision = 0; | 682 | chip->revision = 0; |
| 683 | if (chip->match_type == V4L2_CHIP_MATCH_HOST) { | 683 | if (chip->match.type == V4L2_CHIP_MATCH_HOST) { |
| 684 | if (v4l2_chip_match_host(chip->match_type, chip->match_chip)) | 684 | if (v4l2_chip_match_host(&chip->match)) |
| 685 | chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416; | 685 | chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416; |
| 686 | return 0; | 686 | return 0; |
| 687 | } | 687 | } |
| 688 | if (chip->match_type != V4L2_CHIP_MATCH_I2C_DRIVER && | 688 | if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER && |
| 689 | chip->match_type != V4L2_CHIP_MATCH_I2C_ADDR) | 689 | chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) |
| 690 | return -EINVAL; | 690 | return -EINVAL; |
| 691 | /* TODO: is this correct? */ | 691 | /* TODO: is this correct? */ |
| 692 | return ivtv_call_all_err(itv, core, g_chip_ident, chip); | 692 | return ivtv_call_all_err(itv, core, g_chip_ident, chip); |
| @@ -695,7 +695,7 @@ static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_chip_ident | |||
| 695 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 695 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 696 | static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) | 696 | static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) |
| 697 | { | 697 | { |
| 698 | struct v4l2_register *regs = arg; | 698 | struct v4l2_dbg_register *regs = arg; |
| 699 | volatile u8 __iomem *reg_start; | 699 | volatile u8 __iomem *reg_start; |
| 700 | 700 | ||
| 701 | if (!capable(CAP_SYS_ADMIN)) | 701 | if (!capable(CAP_SYS_ADMIN)) |
| @@ -710,6 +710,7 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) | |||
| 710 | else | 710 | else |
| 711 | return -EINVAL; | 711 | return -EINVAL; |
| 712 | 712 | ||
| 713 | regs->size = 4; | ||
| 713 | if (cmd == VIDIOC_DBG_G_REGISTER) | 714 | if (cmd == VIDIOC_DBG_G_REGISTER) |
| 714 | regs->val = readl(regs->reg + reg_start); | 715 | regs->val = readl(regs->reg + reg_start); |
| 715 | else | 716 | else |
| @@ -717,11 +718,11 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) | |||
| 717 | return 0; | 718 | return 0; |
| 718 | } | 719 | } |
| 719 | 720 | ||
| 720 | static int ivtv_g_register(struct file *file, void *fh, struct v4l2_register *reg) | 721 | static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) |
| 721 | { | 722 | { |
| 722 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | 723 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
| 723 | 724 | ||
| 724 | if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 725 | if (v4l2_chip_match_host(®->match)) |
| 725 | return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg); | 726 | return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg); |
| 726 | /* TODO: subdev errors should not be ignored, this should become a | 727 | /* TODO: subdev errors should not be ignored, this should become a |
| 727 | subdev helper function. */ | 728 | subdev helper function. */ |
| @@ -729,11 +730,11 @@ static int ivtv_g_register(struct file *file, void *fh, struct v4l2_register *re | |||
| 729 | return 0; | 730 | return 0; |
| 730 | } | 731 | } |
| 731 | 732 | ||
| 732 | static int ivtv_s_register(struct file *file, void *fh, struct v4l2_register *reg) | 733 | static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) |
| 733 | { | 734 | { |
| 734 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | 735 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
| 735 | 736 | ||
| 736 | if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 737 | if (v4l2_chip_match_host(®->match)) |
| 737 | return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg); | 738 | return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg); |
| 738 | /* TODO: subdev errors should not be ignored, this should become a | 739 | /* TODO: subdev errors should not be ignored, this should become a |
| 739 | subdev helper function. */ | 740 | subdev helper function. */ |
| @@ -1725,7 +1726,7 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) | |||
| 1725 | return 0; | 1726 | return 0; |
| 1726 | } | 1727 | } |
| 1727 | 1728 | ||
| 1728 | static int ivtv_default(struct file *file, void *fh, int cmd, void *arg) | 1729 | static long ivtv_default(struct file *file, void *fh, int cmd, void *arg) |
| 1729 | { | 1730 | { |
| 1730 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | 1731 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
| 1731 | 1732 | ||
| @@ -1827,7 +1828,7 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp, | |||
| 1827 | 1828 | ||
| 1828 | if (ivtv_debug & IVTV_DBGFLG_IOCTL) | 1829 | if (ivtv_debug & IVTV_DBGFLG_IOCTL) |
| 1829 | vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; | 1830 | vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; |
| 1830 | ret = __video_ioctl2(filp, cmd, arg); | 1831 | ret = video_ioctl2(filp, cmd, arg); |
| 1831 | vfd->debug = 0; | 1832 | vfd->debug = 0; |
| 1832 | return ret; | 1833 | return ret; |
| 1833 | } | 1834 | } |
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index f77d764707b2..854a950af78c 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c | |||
| @@ -43,24 +43,22 @@ | |||
| 43 | #include "ivtv-cards.h" | 43 | #include "ivtv-cards.h" |
| 44 | #include "ivtv-streams.h" | 44 | #include "ivtv-streams.h" |
| 45 | 45 | ||
| 46 | static const struct file_operations ivtv_v4l2_enc_fops = { | 46 | static const struct v4l2_file_operations ivtv_v4l2_enc_fops = { |
| 47 | .owner = THIS_MODULE, | 47 | .owner = THIS_MODULE, |
| 48 | .read = ivtv_v4l2_read, | 48 | .read = ivtv_v4l2_read, |
| 49 | .write = ivtv_v4l2_write, | 49 | .write = ivtv_v4l2_write, |
| 50 | .open = ivtv_v4l2_open, | 50 | .open = ivtv_v4l2_open, |
| 51 | .unlocked_ioctl = ivtv_v4l2_ioctl, | 51 | .unlocked_ioctl = ivtv_v4l2_ioctl, |
| 52 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 53 | .release = ivtv_v4l2_close, | 52 | .release = ivtv_v4l2_close, |
| 54 | .poll = ivtv_v4l2_enc_poll, | 53 | .poll = ivtv_v4l2_enc_poll, |
| 55 | }; | 54 | }; |
| 56 | 55 | ||
| 57 | static const struct file_operations ivtv_v4l2_dec_fops = { | 56 | static const struct v4l2_file_operations ivtv_v4l2_dec_fops = { |
| 58 | .owner = THIS_MODULE, | 57 | .owner = THIS_MODULE, |
| 59 | .read = ivtv_v4l2_read, | 58 | .read = ivtv_v4l2_read, |
| 60 | .write = ivtv_v4l2_write, | 59 | .write = ivtv_v4l2_write, |
| 61 | .open = ivtv_v4l2_open, | 60 | .open = ivtv_v4l2_open, |
| 62 | .unlocked_ioctl = ivtv_v4l2_ioctl, | 61 | .unlocked_ioctl = ivtv_v4l2_ioctl, |
| 63 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 64 | .release = ivtv_v4l2_close, | 62 | .release = ivtv_v4l2_close, |
| 65 | .poll = ivtv_v4l2_dec_poll, | 63 | .poll = ivtv_v4l2_dec_poll, |
| 66 | }; | 64 | }; |
| @@ -78,7 +76,7 @@ static struct { | |||
| 78 | int num_offset; | 76 | int num_offset; |
| 79 | int dma, pio; | 77 | int dma, pio; |
| 80 | enum v4l2_buf_type buf_type; | 78 | enum v4l2_buf_type buf_type; |
| 81 | const struct file_operations *fops; | 79 | const struct v4l2_file_operations *fops; |
| 82 | } ivtv_stream_info[] = { | 80 | } ivtv_stream_info[] = { |
| 83 | { /* IVTV_ENC_STREAM_TYPE_MPG */ | 81 | { /* IVTV_ENC_STREAM_TYPE_MPG */ |
| 84 | "encoder MPG", | 82 | "encoder MPG", |
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c index 07be14a9fe7b..de397ef57b44 100644 --- a/drivers/media/video/m52790.c +++ b/drivers/media/video/m52790.c | |||
| @@ -80,29 +80,28 @@ static int m52790_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *r | |||
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 82 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 83 | static int m52790_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 83 | static int m52790_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 84 | { | 84 | { |
| 85 | struct m52790_state *state = to_state(sd); | 85 | struct m52790_state *state = to_state(sd); |
| 86 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 86 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 87 | 87 | ||
| 88 | if (!v4l2_chip_match_i2c_client(client, | 88 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 89 | reg->match_type, reg->match_chip)) | ||
| 90 | return -EINVAL; | 89 | return -EINVAL; |
| 91 | if (!capable(CAP_SYS_ADMIN)) | 90 | if (!capable(CAP_SYS_ADMIN)) |
| 92 | return -EPERM; | 91 | return -EPERM; |
| 93 | if (reg->reg != 0) | 92 | if (reg->reg != 0) |
| 94 | return -EINVAL; | 93 | return -EINVAL; |
| 94 | reg->size = 1; | ||
| 95 | reg->val = state->input | state->output; | 95 | reg->val = state->input | state->output; |
| 96 | return 0; | 96 | return 0; |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | static int m52790_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 99 | static int m52790_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 100 | { | 100 | { |
| 101 | struct m52790_state *state = to_state(sd); | 101 | struct m52790_state *state = to_state(sd); |
| 102 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 102 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 103 | 103 | ||
| 104 | if (!v4l2_chip_match_i2c_client(client, | 104 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 105 | reg->match_type, reg->match_chip)) | ||
| 106 | return -EINVAL; | 105 | return -EINVAL; |
| 107 | if (!capable(CAP_SYS_ADMIN)) | 106 | if (!capable(CAP_SYS_ADMIN)) |
| 108 | return -EPERM; | 107 | return -EPERM; |
| @@ -115,7 +114,7 @@ static int m52790_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | |||
| 115 | } | 114 | } |
| 116 | #endif | 115 | #endif |
| 117 | 116 | ||
| 118 | static int m52790_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) | 117 | static int m52790_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) |
| 119 | { | 118 | { |
| 120 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 119 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 121 | 120 | ||
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 6418f4a78f2a..b76e33d5c867 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c | |||
| @@ -841,7 +841,7 @@ again: | |||
| 841 | /* video4linux integration */ | 841 | /* video4linux integration */ |
| 842 | /****************************************************************************/ | 842 | /****************************************************************************/ |
| 843 | 843 | ||
| 844 | static int meye_open(struct inode *inode, struct file *file) | 844 | static int meye_open(struct file *file) |
| 845 | { | 845 | { |
| 846 | int i; | 846 | int i; |
| 847 | 847 | ||
| @@ -863,7 +863,7 @@ static int meye_open(struct inode *inode, struct file *file) | |||
| 863 | return 0; | 863 | return 0; |
| 864 | } | 864 | } |
| 865 | 865 | ||
| 866 | static int meye_release(struct inode *inode, struct file *file) | 866 | static int meye_release(struct file *file) |
| 867 | { | 867 | { |
| 868 | mchip_hic_stop(); | 868 | mchip_hic_stop(); |
| 869 | mchip_dma_free(); | 869 | mchip_dma_free(); |
| @@ -1577,7 +1577,7 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) | |||
| 1577 | return 0; | 1577 | return 0; |
| 1578 | } | 1578 | } |
| 1579 | 1579 | ||
| 1580 | static int vidioc_default(struct file *file, void *fh, int cmd, void *arg) | 1580 | static long vidioc_default(struct file *file, void *fh, int cmd, void *arg) |
| 1581 | { | 1581 | { |
| 1582 | switch (cmd) { | 1582 | switch (cmd) { |
| 1583 | case MEYEIOC_G_PARAMS: | 1583 | case MEYEIOC_G_PARAMS: |
| @@ -1684,17 +1684,13 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 1684 | return 0; | 1684 | return 0; |
| 1685 | } | 1685 | } |
| 1686 | 1686 | ||
| 1687 | static const struct file_operations meye_fops = { | 1687 | static const struct v4l2_file_operations meye_fops = { |
| 1688 | .owner = THIS_MODULE, | 1688 | .owner = THIS_MODULE, |
| 1689 | .open = meye_open, | 1689 | .open = meye_open, |
| 1690 | .release = meye_release, | 1690 | .release = meye_release, |
| 1691 | .mmap = meye_mmap, | 1691 | .mmap = meye_mmap, |
| 1692 | .ioctl = video_ioctl2, | 1692 | .ioctl = video_ioctl2, |
| 1693 | #ifdef CONFIG_COMPAT | ||
| 1694 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1695 | #endif | ||
| 1696 | .poll = meye_poll, | 1693 | .poll = meye_poll, |
| 1697 | .llseek = no_llseek, | ||
| 1698 | }; | 1694 | }; |
| 1699 | 1695 | ||
| 1700 | static const struct v4l2_ioctl_ops meye_ioctl_ops = { | 1696 | static const struct v4l2_ioctl_ops meye_ioctl_ops = { |
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index a622dbb72ed8..4d7a91852117 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c | |||
| @@ -483,7 +483,7 @@ static int msp_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
| 483 | } | 483 | } |
| 484 | 484 | ||
| 485 | #ifdef CONFIG_VIDEO_ALLOW_V4L1 | 485 | #ifdef CONFIG_VIDEO_ALLOW_V4L1 |
| 486 | static int msp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) | 486 | static long msp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) |
| 487 | { | 487 | { |
| 488 | struct msp_state *state = to_state(sd); | 488 | struct msp_state *state = to_state(sd); |
| 489 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 489 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| @@ -733,7 +733,7 @@ static int msp_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) | |||
| 733 | return 0; | 733 | return 0; |
| 734 | } | 734 | } |
| 735 | 735 | ||
| 736 | static int msp_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) | 736 | static int msp_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) |
| 737 | { | 737 | { |
| 738 | struct msp_state *state = to_state(sd); | 738 | struct msp_state *state = to_state(sd); |
| 739 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 739 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index 1a1a12453672..c1bf75ef2741 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c | |||
| @@ -343,14 +343,14 @@ static int mt9m001_try_fmt(struct soc_camera_device *icd, | |||
| 343 | } | 343 | } |
| 344 | 344 | ||
| 345 | static int mt9m001_get_chip_id(struct soc_camera_device *icd, | 345 | static int mt9m001_get_chip_id(struct soc_camera_device *icd, |
| 346 | struct v4l2_chip_ident *id) | 346 | struct v4l2_dbg_chip_ident *id) |
| 347 | { | 347 | { |
| 348 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 348 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); |
| 349 | 349 | ||
| 350 | if (id->match_type != V4L2_CHIP_MATCH_I2C_ADDR) | 350 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) |
| 351 | return -EINVAL; | 351 | return -EINVAL; |
| 352 | 352 | ||
| 353 | if (id->match_chip != mt9m001->client->addr) | 353 | if (id->match.addr != mt9m001->client->addr) |
| 354 | return -ENODEV; | 354 | return -ENODEV; |
| 355 | 355 | ||
| 356 | id->ident = mt9m001->model; | 356 | id->ident = mt9m001->model; |
| @@ -361,16 +361,17 @@ static int mt9m001_get_chip_id(struct soc_camera_device *icd, | |||
| 361 | 361 | ||
| 362 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 362 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 363 | static int mt9m001_get_register(struct soc_camera_device *icd, | 363 | static int mt9m001_get_register(struct soc_camera_device *icd, |
| 364 | struct v4l2_register *reg) | 364 | struct v4l2_dbg_register *reg) |
| 365 | { | 365 | { |
| 366 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 366 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); |
| 367 | 367 | ||
| 368 | if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 368 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
| 369 | return -EINVAL; | 369 | return -EINVAL; |
| 370 | 370 | ||
| 371 | if (reg->match_chip != mt9m001->client->addr) | 371 | if (reg->match.addr != mt9m001->client->addr) |
| 372 | return -ENODEV; | 372 | return -ENODEV; |
| 373 | 373 | ||
| 374 | reg->size = 2; | ||
| 374 | reg->val = reg_read(icd, reg->reg); | 375 | reg->val = reg_read(icd, reg->reg); |
| 375 | 376 | ||
| 376 | if (reg->val > 0xffff) | 377 | if (reg->val > 0xffff) |
| @@ -380,14 +381,14 @@ static int mt9m001_get_register(struct soc_camera_device *icd, | |||
| 380 | } | 381 | } |
| 381 | 382 | ||
| 382 | static int mt9m001_set_register(struct soc_camera_device *icd, | 383 | static int mt9m001_set_register(struct soc_camera_device *icd, |
| 383 | struct v4l2_register *reg) | 384 | struct v4l2_dbg_register *reg) |
| 384 | { | 385 | { |
| 385 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 386 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); |
| 386 | 387 | ||
| 387 | if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 388 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
| 388 | return -EINVAL; | 389 | return -EINVAL; |
| 389 | 390 | ||
| 390 | if (reg->match_chip != mt9m001->client->addr) | 391 | if (reg->match.addr != mt9m001->client->addr) |
| 391 | return -ENODEV; | 392 | return -ENODEV; |
| 392 | 393 | ||
| 393 | if (reg_write(icd, reg->reg, reg->val) < 0) | 394 | if (reg_write(icd, reg->reg, reg->val) < 0) |
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index c89ea41fe259..5b8e20979cce 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c | |||
| @@ -514,14 +514,14 @@ static int mt9m111_try_fmt(struct soc_camera_device *icd, | |||
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | static int mt9m111_get_chip_id(struct soc_camera_device *icd, | 516 | static int mt9m111_get_chip_id(struct soc_camera_device *icd, |
| 517 | struct v4l2_chip_ident *id) | 517 | struct v4l2_dbg_chip_ident *id) |
| 518 | { | 518 | { |
| 519 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 519 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
| 520 | 520 | ||
| 521 | if (id->match_type != V4L2_CHIP_MATCH_I2C_ADDR) | 521 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) |
| 522 | return -EINVAL; | 522 | return -EINVAL; |
| 523 | 523 | ||
| 524 | if (id->match_chip != mt9m111->client->addr) | 524 | if (id->match.addr != mt9m111->client->addr) |
| 525 | return -ENODEV; | 525 | return -ENODEV; |
| 526 | 526 | ||
| 527 | id->ident = mt9m111->model; | 527 | id->ident = mt9m111->model; |
| @@ -532,18 +532,19 @@ static int mt9m111_get_chip_id(struct soc_camera_device *icd, | |||
| 532 | 532 | ||
| 533 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 533 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 534 | static int mt9m111_get_register(struct soc_camera_device *icd, | 534 | static int mt9m111_get_register(struct soc_camera_device *icd, |
| 535 | struct v4l2_register *reg) | 535 | struct v4l2_dbg_register *reg) |
| 536 | { | 536 | { |
| 537 | int val; | 537 | int val; |
| 538 | 538 | ||
| 539 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 539 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
| 540 | 540 | ||
| 541 | if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) | 541 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) |
| 542 | return -EINVAL; | 542 | return -EINVAL; |
| 543 | if (reg->match_chip != mt9m111->client->addr) | 543 | if (reg->match.addr != mt9m111->client->addr) |
| 544 | return -ENODEV; | 544 | return -ENODEV; |
| 545 | 545 | ||
| 546 | val = mt9m111_reg_read(icd, reg->reg); | 546 | val = mt9m111_reg_read(icd, reg->reg); |
| 547 | reg->size = 2; | ||
| 547 | reg->val = (u64)val; | 548 | reg->val = (u64)val; |
| 548 | 549 | ||
| 549 | if (reg->val > 0xffff) | 550 | if (reg->val > 0xffff) |
| @@ -553,14 +554,14 @@ static int mt9m111_get_register(struct soc_camera_device *icd, | |||
| 553 | } | 554 | } |
| 554 | 555 | ||
| 555 | static int mt9m111_set_register(struct soc_camera_device *icd, | 556 | static int mt9m111_set_register(struct soc_camera_device *icd, |
| 556 | struct v4l2_register *reg) | 557 | struct v4l2_dbg_register *reg) |
| 557 | { | 558 | { |
| 558 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 559 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
| 559 | 560 | ||
| 560 | if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) | 561 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) |
| 561 | return -EINVAL; | 562 | return -EINVAL; |
| 562 | 563 | ||
| 563 | if (reg->match_chip != mt9m111->client->addr) | 564 | if (reg->match.addr != mt9m111->client->addr) |
| 564 | return -ENODEV; | 565 | return -ENODEV; |
| 565 | 566 | ||
| 566 | if (mt9m111_reg_write(icd, reg->reg, reg->val) < 0) | 567 | if (mt9m111_reg_write(icd, reg->reg, reg->val) < 0) |
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index 1a9d53966d06..349d8e365530 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c | |||
| @@ -326,14 +326,14 @@ static int mt9t031_try_fmt(struct soc_camera_device *icd, | |||
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | static int mt9t031_get_chip_id(struct soc_camera_device *icd, | 328 | static int mt9t031_get_chip_id(struct soc_camera_device *icd, |
| 329 | struct v4l2_chip_ident *id) | 329 | struct v4l2_dbg_chip_ident *id) |
| 330 | { | 330 | { |
| 331 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 331 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); |
| 332 | 332 | ||
| 333 | if (id->match_type != V4L2_CHIP_MATCH_I2C_ADDR) | 333 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) |
| 334 | return -EINVAL; | 334 | return -EINVAL; |
| 335 | 335 | ||
| 336 | if (id->match_chip != mt9t031->client->addr) | 336 | if (id->match.addr != mt9t031->client->addr) |
| 337 | return -ENODEV; | 337 | return -ENODEV; |
| 338 | 338 | ||
| 339 | id->ident = mt9t031->model; | 339 | id->ident = mt9t031->model; |
| @@ -344,14 +344,14 @@ static int mt9t031_get_chip_id(struct soc_camera_device *icd, | |||
| 344 | 344 | ||
| 345 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 345 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 346 | static int mt9t031_get_register(struct soc_camera_device *icd, | 346 | static int mt9t031_get_register(struct soc_camera_device *icd, |
| 347 | struct v4l2_register *reg) | 347 | struct v4l2_dbg_register *reg) |
| 348 | { | 348 | { |
| 349 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 349 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); |
| 350 | 350 | ||
| 351 | if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 351 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
| 352 | return -EINVAL; | 352 | return -EINVAL; |
| 353 | 353 | ||
| 354 | if (reg->match_chip != mt9t031->client->addr) | 354 | if (reg->match.addr != mt9t031->client->addr) |
| 355 | return -ENODEV; | 355 | return -ENODEV; |
| 356 | 356 | ||
| 357 | reg->val = reg_read(icd, reg->reg); | 357 | reg->val = reg_read(icd, reg->reg); |
| @@ -363,14 +363,14 @@ static int mt9t031_get_register(struct soc_camera_device *icd, | |||
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | static int mt9t031_set_register(struct soc_camera_device *icd, | 365 | static int mt9t031_set_register(struct soc_camera_device *icd, |
| 366 | struct v4l2_register *reg) | 366 | struct v4l2_dbg_register *reg) |
| 367 | { | 367 | { |
| 368 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 368 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); |
| 369 | 369 | ||
| 370 | if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 370 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
| 371 | return -EINVAL; | 371 | return -EINVAL; |
| 372 | 372 | ||
| 373 | if (reg->match_chip != mt9t031->client->addr) | 373 | if (reg->match.addr != mt9t031->client->addr) |
| 374 | return -ENODEV; | 374 | return -ENODEV; |
| 375 | 375 | ||
| 376 | if (reg_write(icd, reg->reg, reg->val) < 0) | 376 | if (reg_write(icd, reg->reg, reg->val) < 0) |
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index 14a5f9c21ffa..b04c8cb1644d 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c | |||
| @@ -422,14 +422,14 @@ static int mt9v022_try_fmt(struct soc_camera_device *icd, | |||
| 422 | } | 422 | } |
| 423 | 423 | ||
| 424 | static int mt9v022_get_chip_id(struct soc_camera_device *icd, | 424 | static int mt9v022_get_chip_id(struct soc_camera_device *icd, |
| 425 | struct v4l2_chip_ident *id) | 425 | struct v4l2_dbg_chip_ident *id) |
| 426 | { | 426 | { |
| 427 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 427 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
| 428 | 428 | ||
| 429 | if (id->match_type != V4L2_CHIP_MATCH_I2C_ADDR) | 429 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) |
| 430 | return -EINVAL; | 430 | return -EINVAL; |
| 431 | 431 | ||
| 432 | if (id->match_chip != mt9v022->client->addr) | 432 | if (id->match.addr != mt9v022->client->addr) |
| 433 | return -ENODEV; | 433 | return -ENODEV; |
| 434 | 434 | ||
| 435 | id->ident = mt9v022->model; | 435 | id->ident = mt9v022->model; |
| @@ -440,16 +440,17 @@ static int mt9v022_get_chip_id(struct soc_camera_device *icd, | |||
| 440 | 440 | ||
| 441 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 441 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 442 | static int mt9v022_get_register(struct soc_camera_device *icd, | 442 | static int mt9v022_get_register(struct soc_camera_device *icd, |
| 443 | struct v4l2_register *reg) | 443 | struct v4l2_dbg_register *reg) |
| 444 | { | 444 | { |
| 445 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 445 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
| 446 | 446 | ||
| 447 | if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 447 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
| 448 | return -EINVAL; | 448 | return -EINVAL; |
| 449 | 449 | ||
| 450 | if (reg->match_chip != mt9v022->client->addr) | 450 | if (reg->match.addr != mt9v022->client->addr) |
| 451 | return -ENODEV; | 451 | return -ENODEV; |
| 452 | 452 | ||
| 453 | reg->size = 2; | ||
| 453 | reg->val = reg_read(icd, reg->reg); | 454 | reg->val = reg_read(icd, reg->reg); |
| 454 | 455 | ||
| 455 | if (reg->val > 0xffff) | 456 | if (reg->val > 0xffff) |
| @@ -459,14 +460,14 @@ static int mt9v022_get_register(struct soc_camera_device *icd, | |||
| 459 | } | 460 | } |
| 460 | 461 | ||
| 461 | static int mt9v022_set_register(struct soc_camera_device *icd, | 462 | static int mt9v022_set_register(struct soc_camera_device *icd, |
| 462 | struct v4l2_register *reg) | 463 | struct v4l2_dbg_register *reg) |
| 463 | { | 464 | { |
| 464 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 465 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
| 465 | 466 | ||
| 466 | if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 467 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
| 467 | return -EINVAL; | 468 | return -EINVAL; |
| 468 | 469 | ||
| 469 | if (reg->match_chip != mt9v022->client->addr) | 470 | if (reg->match.addr != mt9v022->client->addr) |
| 470 | return -ENODEV; | 471 | return -ENODEV; |
| 471 | 472 | ||
| 472 | if (reg_write(icd, reg->reg, reg->val) < 0) | 473 | if (reg_write(icd, reg->reg, reg->val) < 0) |
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index 7f130284b5c7..e3cbe14c349a 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c | |||
| @@ -489,7 +489,7 @@ static int mxb_detach(struct saa7146_dev *dev) | |||
| 489 | return 0; | 489 | return 0; |
| 490 | } | 490 | } |
| 491 | 491 | ||
| 492 | static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | 492 | static long mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) |
| 493 | { | 493 | { |
| 494 | struct saa7146_dev *dev = fh->dev; | 494 | struct saa7146_dev *dev = fh->dev; |
| 495 | struct mxb *mxb = (struct mxb *)dev->ext_priv; | 495 | struct mxb *mxb = (struct mxb *)dev->ext_priv; |
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c index 85c3c7c92af1..73eb656acfe3 100644 --- a/drivers/media/video/omap24xxcam.c +++ b/drivers/media/video/omap24xxcam.c | |||
| @@ -1454,9 +1454,9 @@ static int omap24xxcam_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 1454 | return rval; | 1454 | return rval; |
| 1455 | } | 1455 | } |
| 1456 | 1456 | ||
| 1457 | static int omap24xxcam_open(struct inode *inode, struct file *file) | 1457 | static int omap24xxcam_open(struct file *file) |
| 1458 | { | 1458 | { |
| 1459 | int minor = iminor(inode); | 1459 | int minor = video_devdata(file)->minor; |
| 1460 | struct omap24xxcam_device *cam = omap24xxcam.priv; | 1460 | struct omap24xxcam_device *cam = omap24xxcam.priv; |
| 1461 | struct omap24xxcam_fh *fh; | 1461 | struct omap24xxcam_fh *fh; |
| 1462 | struct v4l2_format format; | 1462 | struct v4l2_format format; |
| @@ -1511,7 +1511,7 @@ out_try_module_get: | |||
| 1511 | return -ENODEV; | 1511 | return -ENODEV; |
| 1512 | } | 1512 | } |
| 1513 | 1513 | ||
| 1514 | static int omap24xxcam_release(struct inode *inode, struct file *file) | 1514 | static int omap24xxcam_release(struct file *file) |
| 1515 | { | 1515 | { |
| 1516 | struct omap24xxcam_fh *fh = file->private_data; | 1516 | struct omap24xxcam_fh *fh = file->private_data; |
| 1517 | struct omap24xxcam_device *cam = fh->cam; | 1517 | struct omap24xxcam_device *cam = fh->cam; |
| @@ -1559,8 +1559,7 @@ static int omap24xxcam_release(struct inode *inode, struct file *file) | |||
| 1559 | return 0; | 1559 | return 0; |
| 1560 | } | 1560 | } |
| 1561 | 1561 | ||
| 1562 | static struct file_operations omap24xxcam_fops = { | 1562 | static struct v4l2_file_operations omap24xxcam_fops = { |
| 1563 | .llseek = no_llseek, | ||
| 1564 | .ioctl = video_ioctl2, | 1563 | .ioctl = video_ioctl2, |
| 1565 | .poll = omap24xxcam_poll, | 1564 | .poll = omap24xxcam_poll, |
| 1566 | .mmap = omap24xxcam_mmap, | 1565 | .mmap = omap24xxcam_mmap, |
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index 6ee9b69cc4a9..9af5532db142 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c | |||
| @@ -3915,7 +3915,7 @@ ov51x_dealloc(struct usb_ov511 *ov) | |||
| 3915 | ***************************************************************************/ | 3915 | ***************************************************************************/ |
| 3916 | 3916 | ||
| 3917 | static int | 3917 | static int |
| 3918 | ov51x_v4l1_open(struct inode *inode, struct file *file) | 3918 | ov51x_v4l1_open(struct file *file) |
| 3919 | { | 3919 | { |
| 3920 | struct video_device *vdev = video_devdata(file); | 3920 | struct video_device *vdev = video_devdata(file); |
| 3921 | struct usb_ov511 *ov = video_get_drvdata(vdev); | 3921 | struct usb_ov511 *ov = video_get_drvdata(vdev); |
| @@ -3972,7 +3972,7 @@ out: | |||
| 3972 | } | 3972 | } |
| 3973 | 3973 | ||
| 3974 | static int | 3974 | static int |
| 3975 | ov51x_v4l1_close(struct inode *inode, struct file *file) | 3975 | ov51x_v4l1_close(struct file *file) |
| 3976 | { | 3976 | { |
| 3977 | struct video_device *vdev = file->private_data; | 3977 | struct video_device *vdev = file->private_data; |
| 3978 | struct usb_ov511 *ov = video_get_drvdata(vdev); | 3978 | struct usb_ov511 *ov = video_get_drvdata(vdev); |
| @@ -4010,7 +4010,7 @@ ov51x_v4l1_close(struct inode *inode, struct file *file) | |||
| 4010 | } | 4010 | } |
| 4011 | 4011 | ||
| 4012 | /* Do not call this function directly! */ | 4012 | /* Do not call this function directly! */ |
| 4013 | static int | 4013 | static long |
| 4014 | ov51x_v4l1_ioctl_internal(struct file *file, unsigned int cmd, void *arg) | 4014 | ov51x_v4l1_ioctl_internal(struct file *file, unsigned int cmd, void *arg) |
| 4015 | { | 4015 | { |
| 4016 | struct video_device *vdev = file->private_data; | 4016 | struct video_device *vdev = file->private_data; |
| @@ -4449,8 +4449,8 @@ redo: | |||
| 4449 | return 0; | 4449 | return 0; |
| 4450 | } | 4450 | } |
| 4451 | 4451 | ||
| 4452 | static int | 4452 | static long |
| 4453 | ov51x_v4l1_ioctl(struct inode *inode, struct file *file, | 4453 | ov51x_v4l1_ioctl(struct file *file, |
| 4454 | unsigned int cmd, unsigned long arg) | 4454 | unsigned int cmd, unsigned long arg) |
| 4455 | { | 4455 | { |
| 4456 | struct video_device *vdev = file->private_data; | 4456 | struct video_device *vdev = file->private_data; |
| @@ -4661,17 +4661,13 @@ ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 4661 | return 0; | 4661 | return 0; |
| 4662 | } | 4662 | } |
| 4663 | 4663 | ||
| 4664 | static const struct file_operations ov511_fops = { | 4664 | static const struct v4l2_file_operations ov511_fops = { |
| 4665 | .owner = THIS_MODULE, | 4665 | .owner = THIS_MODULE, |
| 4666 | .open = ov51x_v4l1_open, | 4666 | .open = ov51x_v4l1_open, |
| 4667 | .release = ov51x_v4l1_close, | 4667 | .release = ov51x_v4l1_close, |
| 4668 | .read = ov51x_v4l1_read, | 4668 | .read = ov51x_v4l1_read, |
| 4669 | .mmap = ov51x_v4l1_mmap, | 4669 | .mmap = ov51x_v4l1_mmap, |
| 4670 | .ioctl = ov51x_v4l1_ioctl, | 4670 | .ioctl = ov51x_v4l1_ioctl, |
| 4671 | #ifdef CONFIG_COMPAT | ||
| 4672 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 4673 | #endif | ||
| 4674 | .llseek = no_llseek, | ||
| 4675 | }; | 4671 | }; |
| 4676 | 4672 | ||
| 4677 | static struct video_device vdev_template = { | 4673 | static struct video_device vdev_template = { |
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index ea032f5f2f41..ca26b0c50cf2 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c | |||
| @@ -1310,7 +1310,7 @@ static int ov7670_command(struct i2c_client *client, unsigned int cmd, | |||
| 1310 | void *arg) | 1310 | void *arg) |
| 1311 | { | 1311 | { |
| 1312 | switch (cmd) { | 1312 | switch (cmd) { |
| 1313 | case VIDIOC_G_CHIP_IDENT: | 1313 | case VIDIOC_DBG_G_CHIP_IDENT: |
| 1314 | return v4l2_chip_ident_i2c_client(client, arg, V4L2_IDENT_OV7670, 0); | 1314 | return v4l2_chip_ident_i2c_client(client, arg, V4L2_IDENT_OV7670, 0); |
| 1315 | 1315 | ||
| 1316 | case VIDIOC_INT_RESET: | 1316 | case VIDIOC_INT_RESET: |
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c index 54b736fcc07a..3c9e0ba974e9 100644 --- a/drivers/media/video/ov772x.c +++ b/drivers/media/video/ov772x.c | |||
| @@ -724,7 +724,7 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd) | |||
| 724 | } | 724 | } |
| 725 | 725 | ||
| 726 | static int ov772x_get_chip_id(struct soc_camera_device *icd, | 726 | static int ov772x_get_chip_id(struct soc_camera_device *icd, |
| 727 | struct v4l2_chip_ident *id) | 727 | struct v4l2_dbg_chip_ident *id) |
| 728 | { | 728 | { |
| 729 | struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); | 729 | struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); |
| 730 | 730 | ||
| @@ -736,11 +736,12 @@ static int ov772x_get_chip_id(struct soc_camera_device *icd, | |||
| 736 | 736 | ||
| 737 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 737 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 738 | static int ov772x_get_register(struct soc_camera_device *icd, | 738 | static int ov772x_get_register(struct soc_camera_device *icd, |
| 739 | struct v4l2_register *reg) | 739 | struct v4l2_dbg_register *reg) |
| 740 | { | 740 | { |
| 741 | struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); | 741 | struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); |
| 742 | int ret; | 742 | int ret; |
| 743 | 743 | ||
| 744 | reg->size = 1; | ||
| 744 | if (reg->reg > 0xff) | 745 | if (reg->reg > 0xff) |
| 745 | return -EINVAL; | 746 | return -EINVAL; |
| 746 | 747 | ||
| @@ -754,7 +755,7 @@ static int ov772x_get_register(struct soc_camera_device *icd, | |||
| 754 | } | 755 | } |
| 755 | 756 | ||
| 756 | static int ov772x_set_register(struct soc_camera_device *icd, | 757 | static int ov772x_set_register(struct soc_camera_device *icd, |
| 757 | struct v4l2_register *reg) | 758 | struct v4l2_dbg_register *reg) |
| 758 | { | 759 | { |
| 759 | struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); | 760 | struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); |
| 760 | 761 | ||
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 45730fac1570..a1ad38fc49c1 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c | |||
| @@ -680,7 +680,7 @@ static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int | |||
| 680 | * Video4linux interfacing | 680 | * Video4linux interfacing |
| 681 | */ | 681 | */ |
| 682 | 682 | ||
| 683 | static int pms_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 683 | static long pms_do_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 684 | { | 684 | { |
| 685 | struct video_device *dev = video_devdata(file); | 685 | struct video_device *dev = video_devdata(file); |
| 686 | struct pms_device *pd=(struct pms_device *)dev; | 686 | struct pms_device *pd=(struct pms_device *)dev; |
| @@ -862,7 +862,7 @@ static int pms_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 862 | return 0; | 862 | return 0; |
| 863 | } | 863 | } |
| 864 | 864 | ||
| 865 | static int pms_ioctl(struct inode *inode, struct file *file, | 865 | static long pms_ioctl(struct file *file, |
| 866 | unsigned int cmd, unsigned long arg) | 866 | unsigned int cmd, unsigned long arg) |
| 867 | { | 867 | { |
| 868 | return video_usercopy(file, cmd, arg, pms_do_ioctl); | 868 | return video_usercopy(file, cmd, arg, pms_do_ioctl); |
| @@ -881,7 +881,7 @@ static ssize_t pms_read(struct file *file, char __user *buf, | |||
| 881 | return len; | 881 | return len; |
| 882 | } | 882 | } |
| 883 | 883 | ||
| 884 | static int pms_exclusive_open(struct inode *inode, struct file *file) | 884 | static int pms_exclusive_open(struct file *file) |
| 885 | { | 885 | { |
| 886 | struct video_device *v = video_devdata(file); | 886 | struct video_device *v = video_devdata(file); |
| 887 | struct pms_device *pd = (struct pms_device *)v; | 887 | struct pms_device *pd = (struct pms_device *)v; |
| @@ -889,7 +889,7 @@ static int pms_exclusive_open(struct inode *inode, struct file *file) | |||
| 889 | return test_and_set_bit(0, &pd->in_use) ? -EBUSY : 0; | 889 | return test_and_set_bit(0, &pd->in_use) ? -EBUSY : 0; |
| 890 | } | 890 | } |
| 891 | 891 | ||
| 892 | static int pms_exclusive_release(struct inode *inode, struct file *file) | 892 | static int pms_exclusive_release(struct file *file) |
| 893 | { | 893 | { |
| 894 | struct video_device *v = video_devdata(file); | 894 | struct video_device *v = video_devdata(file); |
| 895 | struct pms_device *pd = (struct pms_device *)v; | 895 | struct pms_device *pd = (struct pms_device *)v; |
| @@ -898,16 +898,12 @@ static int pms_exclusive_release(struct inode *inode, struct file *file) | |||
| 898 | return 0; | 898 | return 0; |
| 899 | } | 899 | } |
| 900 | 900 | ||
| 901 | static const struct file_operations pms_fops = { | 901 | static const struct v4l2_file_operations pms_fops = { |
| 902 | .owner = THIS_MODULE, | 902 | .owner = THIS_MODULE, |
| 903 | .open = pms_exclusive_open, | 903 | .open = pms_exclusive_open, |
| 904 | .release = pms_exclusive_release, | 904 | .release = pms_exclusive_release, |
| 905 | .ioctl = pms_ioctl, | 905 | .ioctl = pms_ioctl, |
| 906 | #ifdef CONFIG_COMPAT | ||
| 907 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 908 | #endif | ||
| 909 | .read = pms_read, | 906 | .read = pms_read, |
| 910 | .llseek = no_llseek, | ||
| 911 | }; | 907 | }; |
| 912 | 908 | ||
| 913 | static struct video_device pms_template= | 909 | static struct video_device pms_template= |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 4358079f1966..8fb92ac78c7b 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
| @@ -4732,26 +4732,25 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw) | |||
| 4732 | 4732 | ||
| 4733 | 4733 | ||
| 4734 | int pvr2_hdw_register_access(struct pvr2_hdw *hdw, | 4734 | int pvr2_hdw_register_access(struct pvr2_hdw *hdw, |
| 4735 | u32 match_type, u32 match_chip, u64 reg_id, | 4735 | struct v4l2_dbg_match *match, u64 reg_id, |
| 4736 | int setFl,u64 *val_ptr) | 4736 | int setFl, u64 *val_ptr) |
| 4737 | { | 4737 | { |
| 4738 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 4738 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 4739 | struct pvr2_i2c_client *cp; | 4739 | struct pvr2_i2c_client *cp; |
| 4740 | struct v4l2_register req; | 4740 | struct v4l2_dbg_register req; |
| 4741 | int stat = 0; | 4741 | int stat = 0; |
| 4742 | int okFl = 0; | 4742 | int okFl = 0; |
| 4743 | 4743 | ||
| 4744 | if (!capable(CAP_SYS_ADMIN)) return -EPERM; | 4744 | if (!capable(CAP_SYS_ADMIN)) return -EPERM; |
| 4745 | 4745 | ||
| 4746 | req.match_type = match_type; | 4746 | req.match = *match; |
| 4747 | req.match_chip = match_chip; | ||
| 4748 | req.reg = reg_id; | 4747 | req.reg = reg_id; |
| 4749 | if (setFl) req.val = *val_ptr; | 4748 | if (setFl) req.val = *val_ptr; |
| 4750 | mutex_lock(&hdw->i2c_list_lock); do { | 4749 | mutex_lock(&hdw->i2c_list_lock); do { |
| 4751 | list_for_each_entry(cp, &hdw->i2c_clients, list) { | 4750 | list_for_each_entry(cp, &hdw->i2c_clients, list) { |
| 4752 | if (!v4l2_chip_match_i2c_client( | 4751 | if (!v4l2_chip_match_i2c_client( |
| 4753 | cp->client, | 4752 | cp->client, |
| 4754 | req.match_type, req.match_chip)) { | 4753 | &req.match)) { |
| 4755 | continue; | 4754 | continue; |
| 4756 | } | 4755 | } |
| 4757 | stat = pvr2_i2c_client_cmd( | 4756 | stat = pvr2_i2c_client_cmd( |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h index 49482d1f2b28..1b4fec337c6b 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h | |||
| @@ -242,8 +242,8 @@ void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *, | |||
| 242 | setFl - true to set the register, false to read it | 242 | setFl - true to set the register, false to read it |
| 243 | val_ptr - storage location for source / result. */ | 243 | val_ptr - storage location for source / result. */ |
| 244 | int pvr2_hdw_register_access(struct pvr2_hdw *, | 244 | int pvr2_hdw_register_access(struct pvr2_hdw *, |
| 245 | u32 match_type, u32 match_chip,u64 reg_id, | 245 | struct v4l2_dbg_match *match, u64 reg_id, |
| 246 | int setFl,u64 *val_ptr); | 246 | int setFl, u64 *val_ptr); |
| 247 | 247 | ||
| 248 | /* The following entry points are all lower level things you normally don't | 248 | /* The following entry points are all lower level things you normally don't |
| 249 | want to worry about. */ | 249 | want to worry about. */ |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 52af1c435965..878fd52a73b3 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | |||
| @@ -168,13 +168,13 @@ static const char *get_v4l_name(int v4l_type) | |||
| 168 | * This is part of Video 4 Linux API. The procedure handles ioctl() calls. | 168 | * This is part of Video 4 Linux API. The procedure handles ioctl() calls. |
| 169 | * | 169 | * |
| 170 | */ | 170 | */ |
| 171 | static int pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 171 | static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 172 | { | 172 | { |
| 173 | struct pvr2_v4l2_fh *fh = file->private_data; | 173 | struct pvr2_v4l2_fh *fh = file->private_data; |
| 174 | struct pvr2_v4l2 *vp = fh->vhead; | 174 | struct pvr2_v4l2 *vp = fh->vhead; |
| 175 | struct pvr2_v4l2_dev *dev_info = fh->dev_info; | 175 | struct pvr2_v4l2_dev *dev_info = fh->dev_info; |
| 176 | struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; | 176 | struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; |
| 177 | int ret = -EINVAL; | 177 | long ret = -EINVAL; |
| 178 | 178 | ||
| 179 | if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { | 179 | if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { |
| 180 | v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),cmd); | 180 | v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),cmd); |
| @@ -851,11 +851,11 @@ static int pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 851 | case VIDIOC_DBG_G_REGISTER: | 851 | case VIDIOC_DBG_G_REGISTER: |
| 852 | { | 852 | { |
| 853 | u64 val; | 853 | u64 val; |
| 854 | struct v4l2_register *req = (struct v4l2_register *)arg; | 854 | struct v4l2_dbg_register *req = (struct v4l2_dbg_register *)arg; |
| 855 | if (cmd == VIDIOC_DBG_S_REGISTER) val = req->val; | 855 | if (cmd == VIDIOC_DBG_S_REGISTER) val = req->val; |
| 856 | ret = pvr2_hdw_register_access( | 856 | ret = pvr2_hdw_register_access( |
| 857 | hdw,req->match_type,req->match_chip,req->reg, | 857 | hdw, &req->match, req->reg, |
| 858 | cmd == VIDIOC_DBG_S_REGISTER,&val); | 858 | cmd == VIDIOC_DBG_S_REGISTER, &val); |
| 859 | if (cmd == VIDIOC_DBG_G_REGISTER) req->val = val; | 859 | if (cmd == VIDIOC_DBG_G_REGISTER) req->val = val; |
| 860 | break; | 860 | break; |
| 861 | } | 861 | } |
| @@ -871,20 +871,20 @@ static int pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 871 | if (ret < 0) { | 871 | if (ret < 0) { |
| 872 | if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { | 872 | if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { |
| 873 | pvr2_trace(PVR2_TRACE_V4LIOCTL, | 873 | pvr2_trace(PVR2_TRACE_V4LIOCTL, |
| 874 | "pvr2_v4l2_do_ioctl failure, ret=%d",ret); | 874 | "pvr2_v4l2_do_ioctl failure, ret=%ld", ret); |
| 875 | } else { | 875 | } else { |
| 876 | if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { | 876 | if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { |
| 877 | pvr2_trace(PVR2_TRACE_V4LIOCTL, | 877 | pvr2_trace(PVR2_TRACE_V4LIOCTL, |
| 878 | "pvr2_v4l2_do_ioctl failure, ret=%d" | 878 | "pvr2_v4l2_do_ioctl failure, ret=%ld" |
| 879 | " command was:",ret); | 879 | " command was:", ret); |
| 880 | v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw), | 880 | v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw), |
| 881 | cmd); | 881 | cmd); |
| 882 | } | 882 | } |
| 883 | } | 883 | } |
| 884 | } else { | 884 | } else { |
| 885 | pvr2_trace(PVR2_TRACE_V4LIOCTL, | 885 | pvr2_trace(PVR2_TRACE_V4LIOCTL, |
| 886 | "pvr2_v4l2_do_ioctl complete, ret=%d (0x%x)", | 886 | "pvr2_v4l2_do_ioctl complete, ret=%ld (0x%lx)", |
| 887 | ret,ret); | 887 | ret, ret); |
| 888 | } | 888 | } |
| 889 | return ret; | 889 | return ret; |
| 890 | } | 890 | } |
| @@ -948,7 +948,7 @@ static void pvr2_v4l2_internal_check(struct pvr2_channel *chp) | |||
| 948 | } | 948 | } |
| 949 | 949 | ||
| 950 | 950 | ||
| 951 | static int pvr2_v4l2_ioctl(struct inode *inode, struct file *file, | 951 | static long pvr2_v4l2_ioctl(struct file *file, |
| 952 | unsigned int cmd, unsigned long arg) | 952 | unsigned int cmd, unsigned long arg) |
| 953 | { | 953 | { |
| 954 | 954 | ||
| @@ -960,7 +960,7 @@ static int pvr2_v4l2_ioctl(struct inode *inode, struct file *file, | |||
| 960 | } | 960 | } |
| 961 | 961 | ||
| 962 | 962 | ||
| 963 | static int pvr2_v4l2_release(struct inode *inode, struct file *file) | 963 | static int pvr2_v4l2_release(struct file *file) |
| 964 | { | 964 | { |
| 965 | struct pvr2_v4l2_fh *fhp = file->private_data; | 965 | struct pvr2_v4l2_fh *fhp = file->private_data; |
| 966 | struct pvr2_v4l2 *vp = fhp->vhead; | 966 | struct pvr2_v4l2 *vp = fhp->vhead; |
| @@ -1008,7 +1008,7 @@ static int pvr2_v4l2_release(struct inode *inode, struct file *file) | |||
| 1008 | } | 1008 | } |
| 1009 | 1009 | ||
| 1010 | 1010 | ||
| 1011 | static int pvr2_v4l2_open(struct inode *inode, struct file *file) | 1011 | static int pvr2_v4l2_open(struct file *file) |
| 1012 | { | 1012 | { |
| 1013 | struct pvr2_v4l2_dev *dip; /* Our own context pointer */ | 1013 | struct pvr2_v4l2_dev *dip; /* Our own context pointer */ |
| 1014 | struct pvr2_v4l2_fh *fhp; | 1014 | struct pvr2_v4l2_fh *fhp; |
| @@ -1235,13 +1235,12 @@ static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait) | |||
| 1235 | } | 1235 | } |
| 1236 | 1236 | ||
| 1237 | 1237 | ||
| 1238 | static const struct file_operations vdev_fops = { | 1238 | static const struct v4l2_file_operations vdev_fops = { |
| 1239 | .owner = THIS_MODULE, | 1239 | .owner = THIS_MODULE, |
| 1240 | .open = pvr2_v4l2_open, | 1240 | .open = pvr2_v4l2_open, |
| 1241 | .release = pvr2_v4l2_release, | 1241 | .release = pvr2_v4l2_release, |
| 1242 | .read = pvr2_v4l2_read, | 1242 | .read = pvr2_v4l2_read, |
| 1243 | .ioctl = pvr2_v4l2_ioctl, | 1243 | .ioctl = pvr2_v4l2_ioctl, |
| 1244 | .llseek = no_llseek, | ||
| 1245 | .poll = pvr2_v4l2_poll, | 1244 | .poll = pvr2_v4l2_poll, |
| 1246 | }; | 1245 | }; |
| 1247 | 1246 | ||
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index c66530210192..f9fbe02e0f69 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c | |||
| @@ -1266,9 +1266,9 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) | |||
| 1266 | /* copy local variable to arg */ | 1266 | /* copy local variable to arg */ |
| 1267 | #define ARG_OUT(ARG_name) /* nothing */ | 1267 | #define ARG_OUT(ARG_name) /* nothing */ |
| 1268 | 1268 | ||
| 1269 | int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) | 1269 | long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) |
| 1270 | { | 1270 | { |
| 1271 | int ret = 0; | 1271 | long ret = 0; |
| 1272 | 1272 | ||
| 1273 | switch(cmd) { | 1273 | switch(cmd) { |
| 1274 | case VIDIOCPWCRUSER: | 1274 | case VIDIOCPWCRUSER: |
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 1ce9da167b7e..39fbc970f43d 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
| @@ -142,16 +142,16 @@ static struct { | |||
| 142 | 142 | ||
| 143 | /***/ | 143 | /***/ |
| 144 | 144 | ||
| 145 | static int pwc_video_open(struct inode *inode, struct file *file); | 145 | static int pwc_video_open(struct file *file); |
| 146 | static int pwc_video_close(struct inode *inode, struct file *file); | 146 | static int pwc_video_close(struct file *file); |
| 147 | static ssize_t pwc_video_read(struct file *file, char __user *buf, | 147 | static ssize_t pwc_video_read(struct file *file, char __user *buf, |
| 148 | size_t count, loff_t *ppos); | 148 | size_t count, loff_t *ppos); |
| 149 | static unsigned int pwc_video_poll(struct file *file, poll_table *wait); | 149 | static unsigned int pwc_video_poll(struct file *file, poll_table *wait); |
| 150 | static int pwc_video_ioctl(struct inode *inode, struct file *file, | 150 | static long pwc_video_ioctl(struct file *file, |
| 151 | unsigned int ioctlnr, unsigned long arg); | 151 | unsigned int ioctlnr, unsigned long arg); |
| 152 | static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); | 152 | static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); |
| 153 | 153 | ||
| 154 | static const struct file_operations pwc_fops = { | 154 | static const struct v4l2_file_operations pwc_fops = { |
| 155 | .owner = THIS_MODULE, | 155 | .owner = THIS_MODULE, |
| 156 | .open = pwc_video_open, | 156 | .open = pwc_video_open, |
| 157 | .release = pwc_video_close, | 157 | .release = pwc_video_close, |
| @@ -159,10 +159,6 @@ static const struct file_operations pwc_fops = { | |||
| 159 | .poll = pwc_video_poll, | 159 | .poll = pwc_video_poll, |
| 160 | .mmap = pwc_video_mmap, | 160 | .mmap = pwc_video_mmap, |
| 161 | .ioctl = pwc_video_ioctl, | 161 | .ioctl = pwc_video_ioctl, |
| 162 | #ifdef CONFIG_COMPAT | ||
| 163 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 164 | #endif | ||
| 165 | .llseek = no_llseek, | ||
| 166 | }; | 162 | }; |
| 167 | static struct video_device pwc_template = { | 163 | static struct video_device pwc_template = { |
| 168 | .name = "Philips Webcam", /* Filled in later */ | 164 | .name = "Philips Webcam", /* Filled in later */ |
| @@ -1104,7 +1100,7 @@ static const char *pwc_sensor_type_to_string(unsigned int sensor_type) | |||
| 1104 | /***************************************************************************/ | 1100 | /***************************************************************************/ |
| 1105 | /* Video4Linux functions */ | 1101 | /* Video4Linux functions */ |
| 1106 | 1102 | ||
| 1107 | static int pwc_video_open(struct inode *inode, struct file *file) | 1103 | static int pwc_video_open(struct file *file) |
| 1108 | { | 1104 | { |
| 1109 | int i, ret; | 1105 | int i, ret; |
| 1110 | struct video_device *vdev = video_devdata(file); | 1106 | struct video_device *vdev = video_devdata(file); |
| @@ -1224,7 +1220,7 @@ static void pwc_cleanup(struct pwc_device *pdev) | |||
| 1224 | } | 1220 | } |
| 1225 | 1221 | ||
| 1226 | /* Note that all cleanup is done in the reverse order as in _open */ | 1222 | /* Note that all cleanup is done in the reverse order as in _open */ |
| 1227 | static int pwc_video_close(struct inode *inode, struct file *file) | 1223 | static int pwc_video_close(struct file *file) |
| 1228 | { | 1224 | { |
| 1229 | struct video_device *vdev = file->private_data; | 1225 | struct video_device *vdev = file->private_data; |
| 1230 | struct pwc_device *pdev; | 1226 | struct pwc_device *pdev; |
| @@ -1399,12 +1395,12 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait) | |||
| 1399 | return 0; | 1395 | return 0; |
| 1400 | } | 1396 | } |
| 1401 | 1397 | ||
| 1402 | static int pwc_video_ioctl(struct inode *inode, struct file *file, | 1398 | static long pwc_video_ioctl(struct file *file, |
| 1403 | unsigned int cmd, unsigned long arg) | 1399 | unsigned int cmd, unsigned long arg) |
| 1404 | { | 1400 | { |
| 1405 | struct video_device *vdev = file->private_data; | 1401 | struct video_device *vdev = file->private_data; |
| 1406 | struct pwc_device *pdev; | 1402 | struct pwc_device *pdev; |
| 1407 | int r = -ENODEV; | 1403 | long r = -ENODEV; |
| 1408 | 1404 | ||
| 1409 | if (!vdev) | 1405 | if (!vdev) |
| 1410 | goto out; | 1406 | goto out; |
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index d7c147328e35..bc0a464295c5 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c | |||
| @@ -337,7 +337,7 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) | |||
| 337 | 337 | ||
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | int pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 340 | long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 341 | { | 341 | { |
| 342 | struct video_device *vdev = video_devdata(file); | 342 | struct video_device *vdev = video_devdata(file); |
| 343 | struct pwc_device *pdev; | 343 | struct pwc_device *pdev; |
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index c046a2535668..01411fb2337a 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h | |||
| @@ -337,10 +337,10 @@ extern int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise); | |||
| 337 | extern int pwc_camera_power(struct pwc_device *pdev, int power); | 337 | extern int pwc_camera_power(struct pwc_device *pdev, int power); |
| 338 | 338 | ||
| 339 | /* Private ioctl()s; see pwc-ioctl.h */ | 339 | /* Private ioctl()s; see pwc-ioctl.h */ |
| 340 | extern int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); | 340 | extern long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); |
| 341 | 341 | ||
| 342 | /** Functions in pwc-v4l.c */ | 342 | /** Functions in pwc-v4l.c */ |
| 343 | extern int pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg); | 343 | extern long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg); |
| 344 | 344 | ||
| 345 | /** pwc-uncompress.c */ | 345 | /** pwc-uncompress.c */ |
| 346 | /* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ | 346 | /* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ |
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 3c3f8cf73108..13f85ad363cd 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c | |||
| @@ -1502,9 +1502,9 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv, | |||
| 1502 | dprintk(2, "setting jpeg quality %d\n", jc->quality); | 1502 | dprintk(2, "setting jpeg quality %d\n", jc->quality); |
| 1503 | return 0; | 1503 | return 0; |
| 1504 | } | 1504 | } |
| 1505 | static int s2255_open(struct inode *inode, struct file *file) | 1505 | static int s2255_open(struct file *file) |
| 1506 | { | 1506 | { |
| 1507 | int minor = iminor(inode); | 1507 | int minor = video_devdata(file)->minor; |
| 1508 | struct s2255_dev *h, *dev = NULL; | 1508 | struct s2255_dev *h, *dev = NULL; |
| 1509 | struct s2255_fh *fh; | 1509 | struct s2255_fh *fh; |
| 1510 | struct list_head *list; | 1510 | struct list_head *list; |
| @@ -1711,11 +1711,11 @@ static void s2255_destroy(struct kref *kref) | |||
| 1711 | mutex_unlock(&dev->open_lock); | 1711 | mutex_unlock(&dev->open_lock); |
| 1712 | } | 1712 | } |
| 1713 | 1713 | ||
| 1714 | static int s2255_close(struct inode *inode, struct file *file) | 1714 | static int s2255_close(struct file *file) |
| 1715 | { | 1715 | { |
| 1716 | struct s2255_fh *fh = file->private_data; | 1716 | struct s2255_fh *fh = file->private_data; |
| 1717 | struct s2255_dev *dev = fh->dev; | 1717 | struct s2255_dev *dev = fh->dev; |
| 1718 | int minor = iminor(inode); | 1718 | int minor = video_devdata(file)->minor; |
| 1719 | if (!dev) | 1719 | if (!dev) |
| 1720 | return -ENODEV; | 1720 | return -ENODEV; |
| 1721 | 1721 | ||
| @@ -1759,15 +1759,13 @@ static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma) | |||
| 1759 | return ret; | 1759 | return ret; |
| 1760 | } | 1760 | } |
| 1761 | 1761 | ||
| 1762 | static const struct file_operations s2255_fops_v4l = { | 1762 | static const struct v4l2_file_operations s2255_fops_v4l = { |
| 1763 | .owner = THIS_MODULE, | 1763 | .owner = THIS_MODULE, |
| 1764 | .open = s2255_open, | 1764 | .open = s2255_open, |
| 1765 | .release = s2255_close, | 1765 | .release = s2255_close, |
| 1766 | .poll = s2255_poll, | 1766 | .poll = s2255_poll, |
| 1767 | .ioctl = video_ioctl2, /* V4L2 ioctl handler */ | 1767 | .ioctl = video_ioctl2, /* V4L2 ioctl handler */ |
| 1768 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1769 | .mmap = s2255_mmap_v4l, | 1768 | .mmap = s2255_mmap_v4l, |
| 1770 | .llseek = no_llseek, | ||
| 1771 | }; | 1769 | }; |
| 1772 | 1770 | ||
| 1773 | static const struct v4l2_ioctl_ops s2255_ioctl_ops = { | 1771 | static const struct v4l2_ioctl_ops s2255_ioctl_ops = { |
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index f159441e9375..e637e440b6d5 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c | |||
| @@ -804,7 +804,7 @@ static inline int saa5246a_stop_dau(struct saa5246a_device *t, | |||
| 804 | * | 804 | * |
| 805 | * Returns 0 if successful | 805 | * Returns 0 if successful |
| 806 | */ | 806 | */ |
| 807 | static int do_saa5246a_ioctl(struct file *file, unsigned int cmd, void *arg) | 807 | static long do_saa5246a_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 808 | { | 808 | { |
| 809 | struct saa5246a_device *t = video_drvdata(file); | 809 | struct saa5246a_device *t = video_drvdata(file); |
| 810 | 810 | ||
| @@ -944,11 +944,11 @@ static inline unsigned int vtx_fix_command(unsigned int cmd) | |||
| 944 | /* | 944 | /* |
| 945 | * Handle the locking | 945 | * Handle the locking |
| 946 | */ | 946 | */ |
| 947 | static int saa5246a_ioctl(struct inode *inode, struct file *file, | 947 | static long saa5246a_ioctl(struct file *file, |
| 948 | unsigned int cmd, unsigned long arg) | 948 | unsigned int cmd, unsigned long arg) |
| 949 | { | 949 | { |
| 950 | struct saa5246a_device *t = video_drvdata(file); | 950 | struct saa5246a_device *t = video_drvdata(file); |
| 951 | int err; | 951 | long err; |
| 952 | 952 | ||
| 953 | cmd = vtx_fix_command(cmd); | 953 | cmd = vtx_fix_command(cmd); |
| 954 | mutex_lock(&t->lock); | 954 | mutex_lock(&t->lock); |
| @@ -957,7 +957,7 @@ static int saa5246a_ioctl(struct inode *inode, struct file *file, | |||
| 957 | return err; | 957 | return err; |
| 958 | } | 958 | } |
| 959 | 959 | ||
| 960 | static int saa5246a_open(struct inode *inode, struct file *file) | 960 | static int saa5246a_open(struct file *file) |
| 961 | { | 961 | { |
| 962 | struct saa5246a_device *t = video_drvdata(file); | 962 | struct saa5246a_device *t = video_drvdata(file); |
| 963 | 963 | ||
| @@ -999,7 +999,7 @@ static int saa5246a_open(struct inode *inode, struct file *file) | |||
| 999 | return 0; | 999 | return 0; |
| 1000 | } | 1000 | } |
| 1001 | 1001 | ||
| 1002 | static int saa5246a_release(struct inode *inode, struct file *file) | 1002 | static int saa5246a_release(struct file *file) |
| 1003 | { | 1003 | { |
| 1004 | struct saa5246a_device *t = video_drvdata(file); | 1004 | struct saa5246a_device *t = video_drvdata(file); |
| 1005 | 1005 | ||
| @@ -1018,12 +1018,11 @@ static int saa5246a_release(struct inode *inode, struct file *file) | |||
| 1018 | return 0; | 1018 | return 0; |
| 1019 | } | 1019 | } |
| 1020 | 1020 | ||
| 1021 | static const struct file_operations saa_fops = { | 1021 | static const struct v4l2_file_operations saa_fops = { |
| 1022 | .owner = THIS_MODULE, | 1022 | .owner = THIS_MODULE, |
| 1023 | .open = saa5246a_open, | 1023 | .open = saa5246a_open, |
| 1024 | .release = saa5246a_release, | 1024 | .release = saa5246a_release, |
| 1025 | .ioctl = saa5246a_ioctl, | 1025 | .ioctl = saa5246a_ioctl, |
| 1026 | .llseek = no_llseek, | ||
| 1027 | }; | 1026 | }; |
| 1028 | 1027 | ||
| 1029 | static struct video_device saa_template = | 1028 | static struct video_device saa_template = |
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index 6ef3affb97f1..e29765192469 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c | |||
| @@ -190,7 +190,7 @@ static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf) | |||
| 190 | * Standard character-device-driver functions | 190 | * Standard character-device-driver functions |
| 191 | */ | 191 | */ |
| 192 | 192 | ||
| 193 | static int do_saa5249_ioctl(struct file *file, unsigned int cmd, void *arg) | 193 | static long do_saa5249_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 194 | { | 194 | { |
| 195 | static int virtual_mode = false; | 195 | static int virtual_mode = false; |
| 196 | struct saa5249_device *t = video_drvdata(file); | 196 | struct saa5249_device *t = video_drvdata(file); |
| @@ -479,11 +479,11 @@ static inline unsigned int vtx_fix_command(unsigned int cmd) | |||
| 479 | * Handle the locking | 479 | * Handle the locking |
| 480 | */ | 480 | */ |
| 481 | 481 | ||
| 482 | static int saa5249_ioctl(struct inode *inode, struct file *file, | 482 | static long saa5249_ioctl(struct file *file, |
| 483 | unsigned int cmd, unsigned long arg) | 483 | unsigned int cmd, unsigned long arg) |
| 484 | { | 484 | { |
| 485 | struct saa5249_device *t = video_drvdata(file); | 485 | struct saa5249_device *t = video_drvdata(file); |
| 486 | int err; | 486 | long err; |
| 487 | 487 | ||
| 488 | cmd = vtx_fix_command(cmd); | 488 | cmd = vtx_fix_command(cmd); |
| 489 | mutex_lock(&t->lock); | 489 | mutex_lock(&t->lock); |
| @@ -492,7 +492,7 @@ static int saa5249_ioctl(struct inode *inode, struct file *file, | |||
| 492 | return err; | 492 | return err; |
| 493 | } | 493 | } |
| 494 | 494 | ||
| 495 | static int saa5249_open(struct inode *inode, struct file *file) | 495 | static int saa5249_open(struct file *file) |
| 496 | { | 496 | { |
| 497 | struct saa5249_device *t = video_drvdata(file); | 497 | struct saa5249_device *t = video_drvdata(file); |
| 498 | int pgbuf; | 498 | int pgbuf; |
| @@ -529,7 +529,7 @@ static int saa5249_open(struct inode *inode, struct file *file) | |||
| 529 | 529 | ||
| 530 | 530 | ||
| 531 | 531 | ||
| 532 | static int saa5249_release(struct inode *inode, struct file *file) | 532 | static int saa5249_release(struct file *file) |
| 533 | { | 533 | { |
| 534 | struct saa5249_device *t = video_drvdata(file); | 534 | struct saa5249_device *t = video_drvdata(file); |
| 535 | 535 | ||
| @@ -539,15 +539,11 @@ static int saa5249_release(struct inode *inode, struct file *file) | |||
| 539 | return 0; | 539 | return 0; |
| 540 | } | 540 | } |
| 541 | 541 | ||
| 542 | static const struct file_operations saa_fops = { | 542 | static const struct v4l2_file_operations saa_fops = { |
| 543 | .owner = THIS_MODULE, | 543 | .owner = THIS_MODULE, |
| 544 | .open = saa5249_open, | 544 | .open = saa5249_open, |
| 545 | .release = saa5249_release, | 545 | .release = saa5249_release, |
| 546 | .ioctl = saa5249_ioctl, | 546 | .ioctl = saa5249_ioctl, |
| 547 | #ifdef CONFIG_COMPAT | ||
| 548 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 549 | #endif | ||
| 550 | .llseek = no_llseek, | ||
| 551 | }; | 547 | }; |
| 552 | 548 | ||
| 553 | static struct video_device saa_template = | 549 | static struct video_device saa_template = |
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index 22708ecdf1bb..46c796c3fec8 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c | |||
| @@ -1371,25 +1371,24 @@ static int saa711x_g_vbi_data(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_dat | |||
| 1371 | } | 1371 | } |
| 1372 | 1372 | ||
| 1373 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1373 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 1374 | static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 1374 | static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 1375 | { | 1375 | { |
| 1376 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 1376 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 1377 | 1377 | ||
| 1378 | if (!v4l2_chip_match_i2c_client(client, | 1378 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 1379 | reg->match_type, reg->match_chip)) | ||
| 1380 | return -EINVAL; | 1379 | return -EINVAL; |
| 1381 | if (!capable(CAP_SYS_ADMIN)) | 1380 | if (!capable(CAP_SYS_ADMIN)) |
| 1382 | return -EPERM; | 1381 | return -EPERM; |
| 1383 | reg->val = saa711x_read(sd, reg->reg & 0xff); | 1382 | reg->val = saa711x_read(sd, reg->reg & 0xff); |
| 1383 | reg->size = 1; | ||
| 1384 | return 0; | 1384 | return 0; |
| 1385 | } | 1385 | } |
| 1386 | 1386 | ||
| 1387 | static int saa711x_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 1387 | static int saa711x_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 1388 | { | 1388 | { |
| 1389 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 1389 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 1390 | 1390 | ||
| 1391 | if (!v4l2_chip_match_i2c_client(client, | 1391 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 1392 | reg->match_type, reg->match_chip)) | ||
| 1393 | return -EINVAL; | 1392 | return -EINVAL; |
| 1394 | if (!capable(CAP_SYS_ADMIN)) | 1393 | if (!capable(CAP_SYS_ADMIN)) |
| 1395 | return -EPERM; | 1394 | return -EPERM; |
| @@ -1398,7 +1397,7 @@ static int saa711x_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | |||
| 1398 | } | 1397 | } |
| 1399 | #endif | 1398 | #endif |
| 1400 | 1399 | ||
| 1401 | static int saa711x_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) | 1400 | static int saa711x_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) |
| 1402 | { | 1401 | { |
| 1403 | struct saa711x_state *state = to_state(sd); | 1402 | struct saa711x_state *state = to_state(sd); |
| 1404 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 1403 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c index bfc85654795e..d6848f7a503b 100644 --- a/drivers/media/video/saa7127.c +++ b/drivers/media/video/saa7127.c | |||
| @@ -623,25 +623,24 @@ static int saa7127_s_vbi_data(struct v4l2_subdev *sd, const struct v4l2_sliced_v | |||
| 623 | } | 623 | } |
| 624 | 624 | ||
| 625 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 625 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 626 | static int saa7127_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 626 | static int saa7127_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 627 | { | 627 | { |
| 628 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 628 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 629 | 629 | ||
| 630 | if (!v4l2_chip_match_i2c_client(client, | 630 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 631 | reg->match_type, reg->match_chip)) | ||
| 632 | return -EINVAL; | 631 | return -EINVAL; |
| 633 | if (!capable(CAP_SYS_ADMIN)) | 632 | if (!capable(CAP_SYS_ADMIN)) |
| 634 | return -EPERM; | 633 | return -EPERM; |
| 635 | reg->val = saa7127_read(sd, reg->reg & 0xff); | 634 | reg->val = saa7127_read(sd, reg->reg & 0xff); |
| 635 | reg->size = 1; | ||
| 636 | return 0; | 636 | return 0; |
| 637 | } | 637 | } |
| 638 | 638 | ||
| 639 | static int saa7127_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 639 | static int saa7127_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 640 | { | 640 | { |
| 641 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 641 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 642 | 642 | ||
| 643 | if (!v4l2_chip_match_i2c_client(client, | 643 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 644 | reg->match_type, reg->match_chip)) | ||
| 645 | return -EINVAL; | 644 | return -EINVAL; |
| 646 | if (!capable(CAP_SYS_ADMIN)) | 645 | if (!capable(CAP_SYS_ADMIN)) |
| 647 | return -EPERM; | 646 | return -EPERM; |
| @@ -650,7 +649,7 @@ static int saa7127_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | |||
| 650 | } | 649 | } |
| 651 | #endif | 650 | #endif |
| 652 | 651 | ||
| 653 | static int saa7127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) | 652 | static int saa7127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) |
| 654 | { | 653 | { |
| 655 | struct saa7127_state *state = to_state(sd); | 654 | struct saa7127_state *state = to_state(sd); |
| 656 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 655 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index 1fb6eccdade3..1fee6e84a512 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c | |||
| @@ -838,7 +838,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 838 | h->standard = *((v4l2_std_id *) arg); | 838 | h->standard = *((v4l2_std_id *) arg); |
| 839 | break; | 839 | break; |
| 840 | 840 | ||
| 841 | case VIDIOC_G_CHIP_IDENT: | 841 | case VIDIOC_DBG_G_CHIP_IDENT: |
| 842 | return v4l2_chip_ident_i2c_client(client, | 842 | return v4l2_chip_ident_i2c_client(client, |
| 843 | arg, h->chip, h->revision); | 843 | arg, h->chip, h->revision); |
| 844 | 844 | ||
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index a2e3f6729c5b..e2febcd6e529 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
| @@ -4462,6 +4462,7 @@ struct saa7134_board saa7134_boards[] = { | |||
| 4462 | .tuner_addr = ADDR_UNSET, | 4462 | .tuner_addr = ADDR_UNSET, |
| 4463 | .radio_addr = ADDR_UNSET, | 4463 | .radio_addr = ADDR_UNSET, |
| 4464 | .tda9887_conf = TDA9887_PRESENT, | 4464 | .tda9887_conf = TDA9887_PRESENT, |
| 4465 | .mpeg = SAA7134_MPEG_DVB, | ||
| 4465 | .inputs = {{ | 4466 | .inputs = {{ |
| 4466 | .name = name_tv, | 4467 | .name = name_tv, |
| 4467 | .vmux = 3, | 4468 | .vmux = 3, |
| @@ -4480,8 +4481,6 @@ struct saa7134_board saa7134_boards[] = { | |||
| 4480 | .name = name_radio, | 4481 | .name = name_radio, |
| 4481 | .amux = LINE2, | 4482 | .amux = LINE2, |
| 4482 | }, | 4483 | }, |
| 4483 | /* no DVB support for now */ | ||
| 4484 | /* .mpeg = SAA7134_MPEG_DVB, */ | ||
| 4485 | }, | 4484 | }, |
| 4486 | [SAA7134_BOARD_ASUSTeK_TIGER_3IN1] = { | 4485 | [SAA7134_BOARD_ASUSTeK_TIGER_3IN1] = { |
| 4487 | .name = "Asus Tiger 3in1", | 4486 | .name = "Asus Tiger 3in1", |
| @@ -4643,6 +4642,38 @@ struct saa7134_board saa7134_boards[] = { | |||
| 4643 | .amux = 2, | 4642 | .amux = 2, |
| 4644 | }, | 4643 | }, |
| 4645 | }, | 4644 | }, |
| 4645 | [SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS] = { | ||
| 4646 | .name = "Avermedia AVerTV GO 007 FM Plus", | ||
| 4647 | .audio_clock = 0x00187de7, | ||
| 4648 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
| 4649 | .radio_type = UNSET, | ||
| 4650 | .tuner_addr = ADDR_UNSET, | ||
| 4651 | .radio_addr = ADDR_UNSET, | ||
| 4652 | .gpiomask = 0x00300003, | ||
| 4653 | /* .gpiomask = 0x8c240003, */ | ||
| 4654 | .inputs = { { | ||
| 4655 | .name = name_tv, | ||
| 4656 | .vmux = 1, | ||
| 4657 | .amux = TV, | ||
| 4658 | .tv = 1, | ||
| 4659 | .gpio = 0x01, | ||
| 4660 | }, { | ||
| 4661 | .name = name_svideo, | ||
| 4662 | .vmux = 6, | ||
| 4663 | .amux = LINE1, | ||
| 4664 | .gpio = 0x02, | ||
| 4665 | } }, | ||
| 4666 | .radio = { | ||
| 4667 | .name = name_radio, | ||
| 4668 | .amux = TV, | ||
| 4669 | .gpio = 0x00300001, | ||
| 4670 | }, | ||
| 4671 | .mute = { | ||
| 4672 | .name = name_mute, | ||
| 4673 | .amux = TV, | ||
| 4674 | .gpio = 0x01, | ||
| 4675 | }, | ||
| 4676 | }, | ||
| 4646 | }; | 4677 | }; |
| 4647 | 4678 | ||
| 4648 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); | 4679 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); |
| @@ -5702,6 +5733,13 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
| 5702 | .subdevice = 0x7128, | 5733 | .subdevice = 0x7128, |
| 5703 | .driver_data = SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG, | 5734 | .driver_data = SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG, |
| 5704 | }, { | 5735 | }, { |
| 5736 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
| 5737 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
| 5738 | .subvendor = 0x1461, /* Avermedia Technologies Inc */ | ||
| 5739 | .subdevice = 0xf31d, | ||
| 5740 | .driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS, | ||
| 5741 | |||
| 5742 | }, { | ||
| 5705 | /* --- boards without eeprom + subsystem ID --- */ | 5743 | /* --- boards without eeprom + subsystem ID --- */ |
| 5706 | .vendor = PCI_VENDOR_ID_PHILIPS, | 5744 | .vendor = PCI_VENDOR_ID_PHILIPS, |
| 5707 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 5745 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
| @@ -5930,6 +5968,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
| 5930 | case SAA7134_BOARD_GENIUS_TVGO_A11MCE: | 5968 | case SAA7134_BOARD_GENIUS_TVGO_A11MCE: |
| 5931 | case SAA7134_BOARD_REAL_ANGEL_220: | 5969 | case SAA7134_BOARD_REAL_ANGEL_220: |
| 5932 | case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG: | 5970 | case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG: |
| 5971 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS: | ||
| 5933 | dev->has_remote = SAA7134_REMOTE_GPIO; | 5972 | dev->has_remote = SAA7134_REMOTE_GPIO; |
| 5934 | break; | 5973 | break; |
| 5935 | case SAA7134_BOARD_FLYDVBS_LR300: | 5974 | case SAA7134_BOARD_FLYDVBS_LR300: |
| @@ -6025,6 +6064,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
| 6025 | case SAA7134_BOARD_BEHOLD_M6: | 6064 | case SAA7134_BOARD_BEHOLD_M6: |
| 6026 | case SAA7134_BOARD_BEHOLD_M63: | 6065 | case SAA7134_BOARD_BEHOLD_M63: |
| 6027 | case SAA7134_BOARD_BEHOLD_M6_EXTRA: | 6066 | case SAA7134_BOARD_BEHOLD_M6_EXTRA: |
| 6067 | case SAA7134_BOARD_BEHOLD_H6: | ||
| 6028 | dev->has_remote = SAA7134_REMOTE_I2C; | 6068 | dev->has_remote = SAA7134_REMOTE_I2C; |
| 6029 | break; | 6069 | break; |
| 6030 | case SAA7134_BOARD_AVERMEDIA_A169_B: | 6070 | case SAA7134_BOARD_AVERMEDIA_A169_B: |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index d9a5652595b5..0776ecf56d27 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
| @@ -49,6 +49,8 @@ | |||
| 49 | #include "lnbp21.h" | 49 | #include "lnbp21.h" |
| 50 | #include "tuner-simple.h" | 50 | #include "tuner-simple.h" |
| 51 | 51 | ||
| 52 | #include "zl10353.h" | ||
| 53 | |||
| 52 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | 54 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
| 53 | MODULE_LICENSE("GPL"); | 55 | MODULE_LICENSE("GPL"); |
| 54 | 56 | ||
| @@ -854,6 +856,12 @@ static struct tda1004x_config ads_tech_duo_config = { | |||
| 854 | .request_firmware = philips_tda1004x_request_firmware | 856 | .request_firmware = philips_tda1004x_request_firmware |
| 855 | }; | 857 | }; |
| 856 | 858 | ||
| 859 | static struct zl10353_config behold_h6_config = { | ||
| 860 | .demod_address = 0x1e>>1, | ||
| 861 | .no_tuner = 1, | ||
| 862 | .parallel_ts = 1, | ||
| 863 | }; | ||
| 864 | |||
| 857 | /* ================================================================== | 865 | /* ================================================================== |
| 858 | * tda10086 based DVB-S cards, helper functions | 866 | * tda10086 based DVB-S cards, helper functions |
| 859 | */ | 867 | */ |
| @@ -1357,6 +1365,16 @@ static int dvb_init(struct saa7134_dev *dev) | |||
| 1357 | &tda827x_cfg_0) < 0) | 1365 | &tda827x_cfg_0) < 0) |
| 1358 | goto dettach_frontend; | 1366 | goto dettach_frontend; |
| 1359 | break; | 1367 | break; |
| 1368 | case SAA7134_BOARD_BEHOLD_H6: | ||
| 1369 | fe0->dvb.frontend = dvb_attach(zl10353_attach, | ||
| 1370 | &behold_h6_config, | ||
| 1371 | &dev->i2c_adap); | ||
| 1372 | if (fe0->dvb.frontend) { | ||
| 1373 | dvb_attach(simple_tuner_attach, fe0->dvb.frontend, | ||
| 1374 | &dev->i2c_adap, 0x61, | ||
| 1375 | TUNER_PHILIPS_FMD1216ME_MK3); | ||
| 1376 | } | ||
| 1377 | break; | ||
| 1360 | default: | 1378 | default: |
| 1361 | wprintk("Huh? unknown DVB card?\n"); | 1379 | wprintk("Huh? unknown DVB card?\n"); |
| 1362 | break; | 1380 | break; |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 7f40511bcc04..c9d8beb87a60 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
| @@ -83,9 +83,9 @@ static int ts_init_encoder(struct saa7134_dev* dev) | |||
| 83 | 83 | ||
| 84 | /* ------------------------------------------------------------------ */ | 84 | /* ------------------------------------------------------------------ */ |
| 85 | 85 | ||
| 86 | static int ts_open(struct inode *inode, struct file *file) | 86 | static int ts_open(struct file *file) |
| 87 | { | 87 | { |
| 88 | int minor = iminor(inode); | 88 | int minor = video_devdata(file)->minor; |
| 89 | struct saa7134_dev *dev; | 89 | struct saa7134_dev *dev; |
| 90 | int err; | 90 | int err; |
| 91 | 91 | ||
| @@ -119,7 +119,7 @@ done: | |||
| 119 | return err; | 119 | return err; |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | static int ts_release(struct inode *inode, struct file *file) | 122 | static int ts_release(struct file *file) |
| 123 | { | 123 | { |
| 124 | struct saa7134_dev *dev = file->private_data; | 124 | struct saa7134_dev *dev = file->private_data; |
| 125 | 125 | ||
| @@ -405,7 +405,7 @@ static int empress_querymenu(struct file *file, void *priv, | |||
| 405 | } | 405 | } |
| 406 | 406 | ||
| 407 | static int empress_g_chip_ident(struct file *file, void *fh, | 407 | static int empress_g_chip_ident(struct file *file, void *fh, |
| 408 | struct v4l2_chip_ident *chip) | 408 | struct v4l2_dbg_chip_ident *chip) |
| 409 | { | 409 | { |
| 410 | struct saa7134_dev *dev = file->private_data; | 410 | struct saa7134_dev *dev = file->private_data; |
| 411 | 411 | ||
| @@ -413,12 +413,12 @@ static int empress_g_chip_ident(struct file *file, void *fh, | |||
| 413 | chip->revision = 0; | 413 | chip->revision = 0; |
| 414 | if (dev->mpeg_i2c_client == NULL) | 414 | if (dev->mpeg_i2c_client == NULL) |
| 415 | return -EINVAL; | 415 | return -EINVAL; |
| 416 | if (chip->match_type == V4L2_CHIP_MATCH_I2C_DRIVER && | 416 | if (chip->match.type == V4L2_CHIP_MATCH_I2C_DRIVER && |
| 417 | chip->match_chip == I2C_DRIVERID_SAA6752HS) | 417 | !strcmp(chip->match.name, "saa6752hs")) |
| 418 | return saa7134_i2c_call_saa6752(dev, VIDIOC_G_CHIP_IDENT, chip); | 418 | return saa7134_i2c_call_saa6752(dev, VIDIOC_DBG_G_CHIP_IDENT, chip); |
| 419 | if (chip->match_type == V4L2_CHIP_MATCH_I2C_ADDR && | 419 | if (chip->match.type == V4L2_CHIP_MATCH_I2C_ADDR && |
| 420 | chip->match_chip == dev->mpeg_i2c_client->addr) | 420 | chip->match.addr == dev->mpeg_i2c_client->addr) |
| 421 | return saa7134_i2c_call_saa6752(dev, VIDIOC_G_CHIP_IDENT, chip); | 421 | return saa7134_i2c_call_saa6752(dev, VIDIOC_DBG_G_CHIP_IDENT, chip); |
| 422 | return -EINVAL; | 422 | return -EINVAL; |
| 423 | } | 423 | } |
| 424 | 424 | ||
| @@ -437,7 +437,7 @@ static int empress_g_std(struct file *file, void *priv, v4l2_std_id *id) | |||
| 437 | return 0; | 437 | return 0; |
| 438 | } | 438 | } |
| 439 | 439 | ||
| 440 | static const struct file_operations ts_fops = | 440 | static const struct v4l2_file_operations ts_fops = |
| 441 | { | 441 | { |
| 442 | .owner = THIS_MODULE, | 442 | .owner = THIS_MODULE, |
| 443 | .open = ts_open, | 443 | .open = ts_open, |
| @@ -446,7 +446,6 @@ static const struct file_operations ts_fops = | |||
| 446 | .poll = ts_poll, | 446 | .poll = ts_poll, |
| 447 | .mmap = ts_mmap, | 447 | .mmap = ts_mmap, |
| 448 | .ioctl = video_ioctl2, | 448 | .ioctl = video_ioctl2, |
| 449 | .llseek = no_llseek, | ||
| 450 | }; | 449 | }; |
| 451 | 450 | ||
| 452 | static const struct v4l2_ioctl_ops ts_ioctl_ops = { | 451 | static const struct v4l2_ioctl_ops ts_ioctl_ops = { |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index d2124f64e4e2..8a106d36e723 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
| @@ -449,6 +449,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
| 449 | case SAA7134_BOARD_AVERMEDIA_STUDIO_507: | 449 | case SAA7134_BOARD_AVERMEDIA_STUDIO_507: |
| 450 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM: | 450 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM: |
| 451 | case SAA7134_BOARD_AVERMEDIA_M102: | 451 | case SAA7134_BOARD_AVERMEDIA_M102: |
| 452 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS: | ||
| 452 | ir_codes = ir_codes_avermedia; | 453 | ir_codes = ir_codes_avermedia; |
| 453 | mask_keycode = 0x0007C8; | 454 | mask_keycode = 0x0007C8; |
| 454 | mask_keydown = 0x000010; | 455 | mask_keydown = 0x000010; |
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 02bb6747a39c..a1f7e351f572 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c | |||
| @@ -1326,9 +1326,9 @@ static int saa7134_resource(struct saa7134_fh *fh) | |||
| 1326 | return 0; | 1326 | return 0; |
| 1327 | } | 1327 | } |
| 1328 | 1328 | ||
| 1329 | static int video_open(struct inode *inode, struct file *file) | 1329 | static int video_open(struct file *file) |
| 1330 | { | 1330 | { |
| 1331 | int minor = iminor(inode); | 1331 | int minor = video_devdata(file)->minor; |
| 1332 | struct saa7134_dev *dev; | 1332 | struct saa7134_dev *dev; |
| 1333 | struct saa7134_fh *fh; | 1333 | struct saa7134_fh *fh; |
| 1334 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1334 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| @@ -1462,7 +1462,7 @@ err: | |||
| 1462 | return POLLERR; | 1462 | return POLLERR; |
| 1463 | } | 1463 | } |
| 1464 | 1464 | ||
| 1465 | static int video_release(struct inode *inode, struct file *file) | 1465 | static int video_release(struct file *file) |
| 1466 | { | 1466 | { |
| 1467 | struct saa7134_fh *fh = file->private_data; | 1467 | struct saa7134_fh *fh = file->private_data; |
| 1468 | struct saa7134_dev *dev = fh->dev; | 1468 | struct saa7134_dev *dev = fh->dev; |
| @@ -2247,24 +2247,25 @@ static int saa7134_g_parm(struct file *file, void *fh, | |||
| 2247 | 2247 | ||
| 2248 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 2248 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 2249 | static int vidioc_g_register (struct file *file, void *priv, | 2249 | static int vidioc_g_register (struct file *file, void *priv, |
| 2250 | struct v4l2_register *reg) | 2250 | struct v4l2_dbg_register *reg) |
| 2251 | { | 2251 | { |
| 2252 | struct saa7134_fh *fh = priv; | 2252 | struct saa7134_fh *fh = priv; |
| 2253 | struct saa7134_dev *dev = fh->dev; | 2253 | struct saa7134_dev *dev = fh->dev; |
| 2254 | 2254 | ||
| 2255 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 2255 | if (!v4l2_chip_match_host(®->match)) |
| 2256 | return -EINVAL; | 2256 | return -EINVAL; |
| 2257 | reg->val = saa_readb(reg->reg); | 2257 | reg->val = saa_readb(reg->reg); |
| 2258 | reg->size = 1; | ||
| 2258 | return 0; | 2259 | return 0; |
| 2259 | } | 2260 | } |
| 2260 | 2261 | ||
| 2261 | static int vidioc_s_register (struct file *file, void *priv, | 2262 | static int vidioc_s_register (struct file *file, void *priv, |
| 2262 | struct v4l2_register *reg) | 2263 | struct v4l2_dbg_register *reg) |
| 2263 | { | 2264 | { |
| 2264 | struct saa7134_fh *fh = priv; | 2265 | struct saa7134_fh *fh = priv; |
| 2265 | struct saa7134_dev *dev = fh->dev; | 2266 | struct saa7134_dev *dev = fh->dev; |
| 2266 | 2267 | ||
| 2267 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 2268 | if (!v4l2_chip_match_host(®->match)) |
| 2268 | return -EINVAL; | 2269 | return -EINVAL; |
| 2269 | saa_writeb(reg->reg&0xffffff, reg->val); | 2270 | saa_writeb(reg->reg&0xffffff, reg->val); |
| 2270 | return 0; | 2271 | return 0; |
| @@ -2377,7 +2378,7 @@ static int radio_queryctrl(struct file *file, void *priv, | |||
| 2377 | return 0; | 2378 | return 0; |
| 2378 | } | 2379 | } |
| 2379 | 2380 | ||
| 2380 | static const struct file_operations video_fops = | 2381 | static const struct v4l2_file_operations video_fops = |
| 2381 | { | 2382 | { |
| 2382 | .owner = THIS_MODULE, | 2383 | .owner = THIS_MODULE, |
| 2383 | .open = video_open, | 2384 | .open = video_open, |
| @@ -2386,8 +2387,6 @@ static const struct file_operations video_fops = | |||
| 2386 | .poll = video_poll, | 2387 | .poll = video_poll, |
| 2387 | .mmap = video_mmap, | 2388 | .mmap = video_mmap, |
| 2388 | .ioctl = video_ioctl2, | 2389 | .ioctl = video_ioctl2, |
| 2389 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 2390 | .llseek = no_llseek, | ||
| 2391 | }; | 2390 | }; |
| 2392 | 2391 | ||
| 2393 | static const struct v4l2_ioctl_ops video_ioctl_ops = { | 2392 | static const struct v4l2_ioctl_ops video_ioctl_ops = { |
| @@ -2441,13 +2440,11 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
| 2441 | #endif | 2440 | #endif |
| 2442 | }; | 2441 | }; |
| 2443 | 2442 | ||
| 2444 | static const struct file_operations radio_fops = { | 2443 | static const struct v4l2_file_operations radio_fops = { |
| 2445 | .owner = THIS_MODULE, | 2444 | .owner = THIS_MODULE, |
| 2446 | .open = video_open, | 2445 | .open = video_open, |
| 2447 | .release = video_release, | 2446 | .release = video_release, |
| 2448 | .ioctl = video_ioctl2, | 2447 | .ioctl = video_ioctl2, |
| 2449 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 2450 | .llseek = no_llseek, | ||
| 2451 | }; | 2448 | }; |
| 2452 | 2449 | ||
| 2453 | static const struct v4l2_ioctl_ops radio_ioctl_ops = { | 2450 | static const struct v4l2_ioctl_ops radio_ioctl_ops = { |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index f6c1fcc72070..14ee265f3374 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
| @@ -276,6 +276,7 @@ struct saa7134_format { | |||
| 276 | #define SAA7134_BOARD_ADS_INSTANT_HDTV_PCI 151 | 276 | #define SAA7134_BOARD_ADS_INSTANT_HDTV_PCI 151 |
| 277 | #define SAA7134_BOARD_ASUSTeK_TIGER 152 | 277 | #define SAA7134_BOARD_ASUSTeK_TIGER 152 |
| 278 | #define SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG 153 | 278 | #define SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG 153 |
| 279 | #define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154 | ||
| 279 | 280 | ||
| 280 | #define SAA7134_MAXBOARDS 32 | 281 | #define SAA7134_MAXBOARDS 32 |
| 281 | #define SAA7134_INPUT_MAX 8 | 282 | #define SAA7134_INPUT_MAX 8 |
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c index 9befca65905e..454ad1dd7507 100644 --- a/drivers/media/video/saa717x.c +++ b/drivers/media/video/saa717x.c | |||
| @@ -1171,25 +1171,26 @@ static int saa717x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) | |||
| 1171 | } | 1171 | } |
| 1172 | 1172 | ||
| 1173 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1173 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 1174 | static int saa717x_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 1174 | static int saa717x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 1175 | { | 1175 | { |
| 1176 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 1176 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 1177 | 1177 | ||
| 1178 | if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip)) | 1178 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 1179 | return -EINVAL; | 1179 | return -EINVAL; |
| 1180 | if (!capable(CAP_SYS_ADMIN)) | 1180 | if (!capable(CAP_SYS_ADMIN)) |
| 1181 | return -EPERM; | 1181 | return -EPERM; |
| 1182 | reg->val = saa717x_read(sd, reg->reg); | 1182 | reg->val = saa717x_read(sd, reg->reg); |
| 1183 | reg->size = 1; | ||
| 1183 | return 0; | 1184 | return 0; |
| 1184 | } | 1185 | } |
| 1185 | 1186 | ||
| 1186 | static int saa717x_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 1187 | static int saa717x_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 1187 | { | 1188 | { |
| 1188 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 1189 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 1189 | u16 addr = reg->reg & 0xffff; | 1190 | u16 addr = reg->reg & 0xffff; |
| 1190 | u8 val = reg->val & 0xff; | 1191 | u8 val = reg->val & 0xff; |
| 1191 | 1192 | ||
| 1192 | if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip)) | 1193 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 1193 | return -EINVAL; | 1194 | return -EINVAL; |
| 1194 | if (!capable(CAP_SYS_ADMIN)) | 1195 | if (!capable(CAP_SYS_ADMIN)) |
| 1195 | return -EPERM; | 1196 | return -EPERM; |
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c index d652f25eef0e..5990ab38a124 100644 --- a/drivers/media/video/se401.c +++ b/drivers/media/video/se401.c | |||
| @@ -932,7 +932,7 @@ static void usb_se401_remove_disconnected (struct usb_se401 *se401) | |||
| 932 | ***************************************************************************/ | 932 | ***************************************************************************/ |
| 933 | 933 | ||
| 934 | 934 | ||
| 935 | static int se401_open(struct inode *inode, struct file *file) | 935 | static int se401_open(struct file *file) |
| 936 | { | 936 | { |
| 937 | struct video_device *dev = video_devdata(file); | 937 | struct video_device *dev = video_devdata(file); |
| 938 | struct usb_se401 *se401 = (struct usb_se401 *)dev; | 938 | struct usb_se401 *se401 = (struct usb_se401 *)dev; |
| @@ -954,7 +954,7 @@ static int se401_open(struct inode *inode, struct file *file) | |||
| 954 | return err; | 954 | return err; |
| 955 | } | 955 | } |
| 956 | 956 | ||
| 957 | static int se401_close(struct inode *inode, struct file *file) | 957 | static int se401_close(struct file *file) |
| 958 | { | 958 | { |
| 959 | struct video_device *dev = file->private_data; | 959 | struct video_device *dev = file->private_data; |
| 960 | struct usb_se401 *se401 = (struct usb_se401 *)dev; | 960 | struct usb_se401 *se401 = (struct usb_se401 *)dev; |
| @@ -975,7 +975,7 @@ static int se401_close(struct inode *inode, struct file *file) | |||
| 975 | return 0; | 975 | return 0; |
| 976 | } | 976 | } |
| 977 | 977 | ||
| 978 | static int se401_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 978 | static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 979 | { | 979 | { |
| 980 | struct video_device *vdev = file->private_data; | 980 | struct video_device *vdev = file->private_data; |
| 981 | struct usb_se401 *se401 = (struct usb_se401 *)vdev; | 981 | struct usb_se401 *se401 = (struct usb_se401 *)vdev; |
| @@ -1138,7 +1138,7 @@ static int se401_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 1138 | return 0; | 1138 | return 0; |
| 1139 | } | 1139 | } |
| 1140 | 1140 | ||
| 1141 | static int se401_ioctl(struct inode *inode, struct file *file, | 1141 | static long se401_ioctl(struct file *file, |
| 1142 | unsigned int cmd, unsigned long arg) | 1142 | unsigned int cmd, unsigned long arg) |
| 1143 | { | 1143 | { |
| 1144 | return video_usercopy(file, cmd, arg, se401_do_ioctl); | 1144 | return video_usercopy(file, cmd, arg, se401_do_ioctl); |
| @@ -1222,17 +1222,13 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 1222 | return 0; | 1222 | return 0; |
| 1223 | } | 1223 | } |
| 1224 | 1224 | ||
| 1225 | static const struct file_operations se401_fops = { | 1225 | static const struct v4l2_file_operations se401_fops = { |
| 1226 | .owner = THIS_MODULE, | 1226 | .owner = THIS_MODULE, |
| 1227 | .open = se401_open, | 1227 | .open = se401_open, |
| 1228 | .release = se401_close, | 1228 | .release = se401_close, |
| 1229 | .read = se401_read, | 1229 | .read = se401_read, |
| 1230 | .mmap = se401_mmap, | 1230 | .mmap = se401_mmap, |
| 1231 | .ioctl = se401_ioctl, | 1231 | .ioctl = se401_ioctl, |
| 1232 | #ifdef CONFIG_COMPAT | ||
| 1233 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1234 | #endif | ||
| 1235 | .llseek = no_llseek, | ||
| 1236 | }; | 1232 | }; |
| 1237 | static struct video_device se401_template = { | 1233 | static struct video_device se401_template = { |
| 1238 | .name = "se401 USB camera", | 1234 | .name = "se401 USB camera", |
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index 01a8efb8deb1..23edfdc4d4bc 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c | |||
| @@ -1746,7 +1746,7 @@ static void sn9c102_release_resources(struct kref *kref) | |||
| 1746 | } | 1746 | } |
| 1747 | 1747 | ||
| 1748 | 1748 | ||
| 1749 | static int sn9c102_open(struct inode* inode, struct file* filp) | 1749 | static int sn9c102_open(struct file *filp) |
| 1750 | { | 1750 | { |
| 1751 | struct sn9c102_device* cam; | 1751 | struct sn9c102_device* cam; |
| 1752 | int err = 0; | 1752 | int err = 0; |
| @@ -1857,7 +1857,7 @@ out: | |||
| 1857 | } | 1857 | } |
| 1858 | 1858 | ||
| 1859 | 1859 | ||
| 1860 | static int sn9c102_release(struct inode* inode, struct file* filp) | 1860 | static int sn9c102_release(struct file *filp) |
| 1861 | { | 1861 | { |
| 1862 | struct sn9c102_device* cam; | 1862 | struct sn9c102_device* cam; |
| 1863 | 1863 | ||
| @@ -3092,8 +3092,8 @@ sn9c102_vidioc_s_audio(struct sn9c102_device* cam, void __user * arg) | |||
| 3092 | } | 3092 | } |
| 3093 | 3093 | ||
| 3094 | 3094 | ||
| 3095 | static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, | 3095 | static long sn9c102_ioctl_v4l2(struct file *filp, |
| 3096 | unsigned int cmd, void __user * arg) | 3096 | unsigned int cmd, void __user *arg) |
| 3097 | { | 3097 | { |
| 3098 | struct sn9c102_device *cam = video_drvdata(filp); | 3098 | struct sn9c102_device *cam = video_drvdata(filp); |
| 3099 | 3099 | ||
| @@ -3196,7 +3196,7 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
| 3196 | } | 3196 | } |
| 3197 | 3197 | ||
| 3198 | 3198 | ||
| 3199 | static int sn9c102_ioctl(struct inode* inode, struct file* filp, | 3199 | static long sn9c102_ioctl(struct file *filp, |
| 3200 | unsigned int cmd, unsigned long arg) | 3200 | unsigned int cmd, unsigned long arg) |
| 3201 | { | 3201 | { |
| 3202 | struct sn9c102_device *cam = video_drvdata(filp); | 3202 | struct sn9c102_device *cam = video_drvdata(filp); |
| @@ -3220,7 +3220,7 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp, | |||
| 3220 | 3220 | ||
| 3221 | V4LDBG(3, "sn9c102", cmd); | 3221 | V4LDBG(3, "sn9c102", cmd); |
| 3222 | 3222 | ||
| 3223 | err = sn9c102_ioctl_v4l2(inode, filp, cmd, (void __user *)arg); | 3223 | err = sn9c102_ioctl_v4l2(filp, cmd, (void __user *)arg); |
| 3224 | 3224 | ||
| 3225 | mutex_unlock(&cam->fileop_mutex); | 3225 | mutex_unlock(&cam->fileop_mutex); |
| 3226 | 3226 | ||
| @@ -3229,18 +3229,14 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp, | |||
| 3229 | 3229 | ||
| 3230 | /*****************************************************************************/ | 3230 | /*****************************************************************************/ |
| 3231 | 3231 | ||
| 3232 | static const struct file_operations sn9c102_fops = { | 3232 | static const struct v4l2_file_operations sn9c102_fops = { |
| 3233 | .owner = THIS_MODULE, | 3233 | .owner = THIS_MODULE, |
| 3234 | .open = sn9c102_open, | 3234 | .open = sn9c102_open, |
| 3235 | .release = sn9c102_release, | 3235 | .release = sn9c102_release, |
| 3236 | .ioctl = sn9c102_ioctl, | 3236 | .ioctl = sn9c102_ioctl, |
| 3237 | #ifdef CONFIG_COMPAT | ||
| 3238 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 3239 | #endif | ||
| 3240 | .read = sn9c102_read, | 3237 | .read = sn9c102_read, |
| 3241 | .poll = sn9c102_poll, | 3238 | .poll = sn9c102_poll, |
| 3242 | .mmap = sn9c102_mmap, | 3239 | .mmap = sn9c102_mmap, |
| 3243 | .llseek = no_llseek, | ||
| 3244 | }; | 3240 | }; |
| 3245 | 3241 | ||
| 3246 | /*****************************************************************************/ | 3242 | /*****************************************************************************/ |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 90077cb4fe66..fcb05f06de8f 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
| @@ -256,7 +256,7 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd) | |||
| 256 | vfree(icd->user_formats); | 256 | vfree(icd->user_formats); |
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | static int soc_camera_open(struct inode *inode, struct file *file) | 259 | static int soc_camera_open(struct file *file) |
| 260 | { | 260 | { |
| 261 | struct video_device *vdev; | 261 | struct video_device *vdev; |
| 262 | struct soc_camera_device *icd; | 262 | struct soc_camera_device *icd; |
| @@ -330,7 +330,7 @@ emgd: | |||
| 330 | return ret; | 330 | return ret; |
| 331 | } | 331 | } |
| 332 | 332 | ||
| 333 | static int soc_camera_close(struct inode *inode, struct file *file) | 333 | static int soc_camera_close(struct file *file) |
| 334 | { | 334 | { |
| 335 | struct soc_camera_file *icf = file->private_data; | 335 | struct soc_camera_file *icf = file->private_data; |
| 336 | struct soc_camera_device *icd = icf->icd; | 336 | struct soc_camera_device *icd = icf->icd; |
| @@ -400,7 +400,7 @@ static unsigned int soc_camera_poll(struct file *file, poll_table *pt) | |||
| 400 | return ici->ops->poll(file, pt); | 400 | return ici->ops->poll(file, pt); |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | static struct file_operations soc_camera_fops = { | 403 | static struct v4l2_file_operations soc_camera_fops = { |
| 404 | .owner = THIS_MODULE, | 404 | .owner = THIS_MODULE, |
| 405 | .open = soc_camera_open, | 405 | .open = soc_camera_open, |
| 406 | .release = soc_camera_close, | 406 | .release = soc_camera_close, |
| @@ -408,7 +408,6 @@ static struct file_operations soc_camera_fops = { | |||
| 408 | .read = soc_camera_read, | 408 | .read = soc_camera_read, |
| 409 | .mmap = soc_camera_mmap, | 409 | .mmap = soc_camera_mmap, |
| 410 | .poll = soc_camera_poll, | 410 | .poll = soc_camera_poll, |
| 411 | .llseek = no_llseek, | ||
| 412 | }; | 411 | }; |
| 413 | 412 | ||
| 414 | static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, | 413 | static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, |
| @@ -700,7 +699,7 @@ static int soc_camera_s_crop(struct file *file, void *fh, | |||
| 700 | } | 699 | } |
| 701 | 700 | ||
| 702 | static int soc_camera_g_chip_ident(struct file *file, void *fh, | 701 | static int soc_camera_g_chip_ident(struct file *file, void *fh, |
| 703 | struct v4l2_chip_ident *id) | 702 | struct v4l2_dbg_chip_ident *id) |
| 704 | { | 703 | { |
| 705 | struct soc_camera_file *icf = file->private_data; | 704 | struct soc_camera_file *icf = file->private_data; |
| 706 | struct soc_camera_device *icd = icf->icd; | 705 | struct soc_camera_device *icd = icf->icd; |
| @@ -713,7 +712,7 @@ static int soc_camera_g_chip_ident(struct file *file, void *fh, | |||
| 713 | 712 | ||
| 714 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 713 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 715 | static int soc_camera_g_register(struct file *file, void *fh, | 714 | static int soc_camera_g_register(struct file *file, void *fh, |
| 716 | struct v4l2_register *reg) | 715 | struct v4l2_dbg_register *reg) |
| 717 | { | 716 | { |
| 718 | struct soc_camera_file *icf = file->private_data; | 717 | struct soc_camera_file *icf = file->private_data; |
| 719 | struct soc_camera_device *icd = icf->icd; | 718 | struct soc_camera_device *icd = icf->icd; |
| @@ -725,7 +724,7 @@ static int soc_camera_g_register(struct file *file, void *fh, | |||
| 725 | } | 724 | } |
| 726 | 725 | ||
| 727 | static int soc_camera_s_register(struct file *file, void *fh, | 726 | static int soc_camera_s_register(struct file *file, void *fh, |
| 728 | struct v4l2_register *reg) | 727 | struct v4l2_dbg_register *reg) |
| 729 | { | 728 | { |
| 730 | struct soc_camera_file *icf = file->private_data; | 729 | struct soc_camera_file *icf = file->private_data; |
| 731 | struct soc_camera_device *icd = icf->icd; | 730 | struct soc_camera_device *icd = icf->icd; |
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index f9516d0f3c11..26378cf390fc 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c | |||
| @@ -664,7 +664,7 @@ static void stk_free_buffers(struct stk_camera *dev) | |||
| 664 | 664 | ||
| 665 | /* v4l file operations */ | 665 | /* v4l file operations */ |
| 666 | 666 | ||
| 667 | static int v4l_stk_open(struct inode *inode, struct file *fp) | 667 | static int v4l_stk_open(struct file *fp) |
| 668 | { | 668 | { |
| 669 | struct stk_camera *dev; | 669 | struct stk_camera *dev; |
| 670 | struct video_device *vdev; | 670 | struct video_device *vdev; |
| @@ -684,7 +684,7 @@ static int v4l_stk_open(struct inode *inode, struct file *fp) | |||
| 684 | return 0; | 684 | return 0; |
| 685 | } | 685 | } |
| 686 | 686 | ||
| 687 | static int v4l_stk_release(struct inode *inode, struct file *fp) | 687 | static int v4l_stk_release(struct file *fp) |
| 688 | { | 688 | { |
| 689 | struct stk_camera *dev = fp->private_data; | 689 | struct stk_camera *dev = fp->private_data; |
| 690 | 690 | ||
| @@ -1281,7 +1281,7 @@ static int stk_vidioc_enum_framesizes(struct file *filp, | |||
| 1281 | } | 1281 | } |
| 1282 | } | 1282 | } |
| 1283 | 1283 | ||
| 1284 | static struct file_operations v4l_stk_fops = { | 1284 | static struct v4l2_file_operations v4l_stk_fops = { |
| 1285 | .owner = THIS_MODULE, | 1285 | .owner = THIS_MODULE, |
| 1286 | .open = v4l_stk_open, | 1286 | .open = v4l_stk_open, |
| 1287 | .release = v4l_stk_release, | 1287 | .release = v4l_stk_release, |
| @@ -1289,10 +1289,6 @@ static struct file_operations v4l_stk_fops = { | |||
| 1289 | .poll = v4l_stk_poll, | 1289 | .poll = v4l_stk_poll, |
| 1290 | .mmap = v4l_stk_mmap, | 1290 | .mmap = v4l_stk_mmap, |
| 1291 | .ioctl = video_ioctl2, | 1291 | .ioctl = video_ioctl2, |
| 1292 | #ifdef CONFIG_COMPAT | ||
| 1293 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1294 | #endif | ||
| 1295 | .llseek = no_llseek | ||
| 1296 | }; | 1292 | }; |
| 1297 | 1293 | ||
| 1298 | static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = { | 1294 | static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = { |
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index bbad54f85c83..0eb313082c97 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c | |||
| @@ -1275,7 +1275,7 @@ static void make_clip_tab(struct saa7146 *saa, struct video_clip *cr, int ncr) | |||
| 1275 | clip_draw_rectangle(clipmap, 0, 0, 1024, -saa->win.y); | 1275 | clip_draw_rectangle(clipmap, 0, 0, 1024, -saa->win.y); |
| 1276 | } | 1276 | } |
| 1277 | 1277 | ||
| 1278 | static int saa_ioctl(struct inode *inode, struct file *file, | 1278 | static long saa_ioctl(struct file *file, |
| 1279 | unsigned int cmd, unsigned long argl) | 1279 | unsigned int cmd, unsigned long argl) |
| 1280 | { | 1280 | { |
| 1281 | struct saa7146 *saa = file->private_data; | 1281 | struct saa7146 *saa = file->private_data; |
| @@ -1877,7 +1877,7 @@ static ssize_t saa_write(struct file *file, const char __user * buf, | |||
| 1877 | return count; | 1877 | return count; |
| 1878 | } | 1878 | } |
| 1879 | 1879 | ||
| 1880 | static int saa_open(struct inode *inode, struct file *file) | 1880 | static int saa_open(struct file *file) |
| 1881 | { | 1881 | { |
| 1882 | struct video_device *vdev = video_devdata(file); | 1882 | struct video_device *vdev = video_devdata(file); |
| 1883 | struct saa7146 *saa = container_of(vdev, struct saa7146, video_dev); | 1883 | struct saa7146 *saa = container_of(vdev, struct saa7146, video_dev); |
| @@ -1895,7 +1895,7 @@ static int saa_open(struct inode *inode, struct file *file) | |||
| 1895 | return 0; | 1895 | return 0; |
| 1896 | } | 1896 | } |
| 1897 | 1897 | ||
| 1898 | static int saa_release(struct inode *inode, struct file *file) | 1898 | static int saa_release(struct file *file) |
| 1899 | { | 1899 | { |
| 1900 | struct saa7146 *saa = file->private_data; | 1900 | struct saa7146 *saa = file->private_data; |
| 1901 | saa->user--; | 1901 | saa->user--; |
| @@ -1906,16 +1906,12 @@ static int saa_release(struct inode *inode, struct file *file) | |||
| 1906 | return 0; | 1906 | return 0; |
| 1907 | } | 1907 | } |
| 1908 | 1908 | ||
| 1909 | static const struct file_operations saa_fops = { | 1909 | static const struct v4l2_file_operations saa_fops = { |
| 1910 | .owner = THIS_MODULE, | 1910 | .owner = THIS_MODULE, |
| 1911 | .open = saa_open, | 1911 | .open = saa_open, |
| 1912 | .release = saa_release, | 1912 | .release = saa_release, |
| 1913 | .ioctl = saa_ioctl, | 1913 | .ioctl = saa_ioctl, |
| 1914 | #ifdef CONFIG_COMPAT | ||
| 1915 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1916 | #endif | ||
| 1917 | .read = saa_read, | 1914 | .read = saa_read, |
| 1918 | .llseek = no_llseek, | ||
| 1919 | .write = saa_write, | 1915 | .write = saa_write, |
| 1920 | .mmap = saa_mmap, | 1916 | .mmap = saa_mmap, |
| 1921 | }; | 1917 | }; |
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c index 42acc92c182d..75f286f7a2e9 100644 --- a/drivers/media/video/stv680.c +++ b/drivers/media/video/stv680.c | |||
| @@ -1080,7 +1080,7 @@ static int stv680_newframe (struct usb_stv *stv680, int framenr) | |||
| 1080 | * Video4Linux | 1080 | * Video4Linux |
| 1081 | *********************************************************************/ | 1081 | *********************************************************************/ |
| 1082 | 1082 | ||
| 1083 | static int stv_open (struct inode *inode, struct file *file) | 1083 | static int stv_open(struct file *file) |
| 1084 | { | 1084 | { |
| 1085 | struct video_device *dev = video_devdata(file); | 1085 | struct video_device *dev = video_devdata(file); |
| 1086 | struct usb_stv *stv680 = video_get_drvdata(dev); | 1086 | struct usb_stv *stv680 = video_get_drvdata(dev); |
| @@ -1106,7 +1106,7 @@ static int stv_open (struct inode *inode, struct file *file) | |||
| 1106 | return err; | 1106 | return err; |
| 1107 | } | 1107 | } |
| 1108 | 1108 | ||
| 1109 | static int stv_close (struct inode *inode, struct file *file) | 1109 | static int stv_close(struct file *file) |
| 1110 | { | 1110 | { |
| 1111 | struct video_device *dev = file->private_data; | 1111 | struct video_device *dev = file->private_data; |
| 1112 | struct usb_stv *stv680 = video_get_drvdata(dev); | 1112 | struct usb_stv *stv680 = video_get_drvdata(dev); |
| @@ -1132,7 +1132,7 @@ static int stv_close (struct inode *inode, struct file *file) | |||
| 1132 | return 0; | 1132 | return 0; |
| 1133 | } | 1133 | } |
| 1134 | 1134 | ||
| 1135 | static int stv680_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 1135 | static long stv680_do_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 1136 | { | 1136 | { |
| 1137 | struct video_device *vdev = file->private_data; | 1137 | struct video_device *vdev = file->private_data; |
| 1138 | struct usb_stv *stv680 = video_get_drvdata(vdev); | 1138 | struct usb_stv *stv680 = video_get_drvdata(vdev); |
| @@ -1299,7 +1299,7 @@ static int stv680_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 1299 | return 0; | 1299 | return 0; |
| 1300 | } | 1300 | } |
| 1301 | 1301 | ||
| 1302 | static int stv680_ioctl(struct inode *inode, struct file *file, | 1302 | static long stv680_ioctl(struct file *file, |
| 1303 | unsigned int cmd, unsigned long arg) | 1303 | unsigned int cmd, unsigned long arg) |
| 1304 | { | 1304 | { |
| 1305 | return video_usercopy(file, cmd, arg, stv680_do_ioctl); | 1305 | return video_usercopy(file, cmd, arg, stv680_do_ioctl); |
| @@ -1391,17 +1391,13 @@ static ssize_t stv680_read (struct file *file, char __user *buf, | |||
| 1391 | return realcount; | 1391 | return realcount; |
| 1392 | } /* stv680_read */ | 1392 | } /* stv680_read */ |
| 1393 | 1393 | ||
| 1394 | static const struct file_operations stv680_fops = { | 1394 | static const struct v4l2_file_operations stv680_fops = { |
| 1395 | .owner = THIS_MODULE, | 1395 | .owner = THIS_MODULE, |
| 1396 | .open = stv_open, | 1396 | .open = stv_open, |
| 1397 | .release = stv_close, | 1397 | .release = stv_close, |
| 1398 | .read = stv680_read, | 1398 | .read = stv680_read, |
| 1399 | .mmap = stv680_mmap, | 1399 | .mmap = stv680_mmap, |
| 1400 | .ioctl = stv680_ioctl, | 1400 | .ioctl = stv680_ioctl, |
| 1401 | #ifdef CONFIG_COMPAT | ||
| 1402 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1403 | #endif | ||
| 1404 | .llseek = no_llseek, | ||
| 1405 | }; | 1401 | }; |
| 1406 | static struct video_device stv680_template = { | 1402 | static struct video_device stv680_template = { |
| 1407 | .name = "STV0680 USB camera", | 1403 | .name = "STV0680 USB camera", |
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c index 2644e0dc9251..6afb7059502d 100644 --- a/drivers/media/video/tda9840.c +++ b/drivers/media/video/tda9840.c | |||
| @@ -137,7 +137,7 @@ static int tda9840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t) | |||
| 137 | return 0; | 137 | return 0; |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | static int tda9840_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) | 140 | static long tda9840_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) |
| 141 | { | 141 | { |
| 142 | int byte; | 142 | int byte; |
| 143 | 143 | ||
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index 31dde86f2df4..7519fd1f57ef 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c | |||
| @@ -122,7 +122,7 @@ static int switch_matrix(struct i2c_client *client, int i, int o) | |||
| 122 | return ret; | 122 | return ret; |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | static int tea6415c_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) | 125 | static long tea6415c_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) |
| 126 | { | 126 | { |
| 127 | if (cmd == TEA6415C_SWITCH) { | 127 | if (cmd == TEA6415C_SWITCH) { |
| 128 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 128 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index 38e519f04bde..081e74fa3b2e 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c | |||
| @@ -90,7 +90,7 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g) | |||
| 90 | return 0; | 90 | return 0; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | static int tea6420_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) | 93 | static long tea6420_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) |
| 94 | { | 94 | { |
| 95 | if (cmd == TEA6420_SWITCH) { | 95 | if (cmd == TEA6420_SWITCH) { |
| 96 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 96 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 97d7509d212f..30640fbfd0f9 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
| @@ -800,7 +800,7 @@ static int tuner_s_standby(struct v4l2_subdev *sd, u32 standby) | |||
| 800 | } | 800 | } |
| 801 | 801 | ||
| 802 | #ifdef CONFIG_VIDEO_ALLOW_V4L1 | 802 | #ifdef CONFIG_VIDEO_ALLOW_V4L1 |
| 803 | static int tuner_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) | 803 | static long tuner_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) |
| 804 | { | 804 | { |
| 805 | struct tuner *t = to_tuner(sd); | 805 | struct tuner *t = to_tuner(sd); |
| 806 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 806 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index d0c794da735b..5aeccb301cea 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c | |||
| @@ -1762,7 +1762,7 @@ static int tvaudio_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *fr | |||
| 1762 | return 0; | 1762 | return 0; |
| 1763 | } | 1763 | } |
| 1764 | 1764 | ||
| 1765 | static int tvaudio_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) | 1765 | static int tvaudio_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) |
| 1766 | { | 1766 | { |
| 1767 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 1767 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 1768 | 1768 | ||
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index a388a9f0cb18..2cd64ef27b95 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c | |||
| @@ -963,7 +963,7 @@ static int tvp5150_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |||
| 963 | 963 | ||
| 964 | 964 | ||
| 965 | static int tvp5150_g_chip_ident(struct v4l2_subdev *sd, | 965 | static int tvp5150_g_chip_ident(struct v4l2_subdev *sd, |
| 966 | struct v4l2_chip_ident *chip) | 966 | struct v4l2_dbg_chip_ident *chip) |
| 967 | { | 967 | { |
| 968 | int rev; | 968 | int rev; |
| 969 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 969 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| @@ -977,25 +977,24 @@ static int tvp5150_g_chip_ident(struct v4l2_subdev *sd, | |||
| 977 | 977 | ||
| 978 | 978 | ||
| 979 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 979 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 980 | static int tvp5150_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 980 | static int tvp5150_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 981 | { | 981 | { |
| 982 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 982 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 983 | 983 | ||
| 984 | if (!v4l2_chip_match_i2c_client(client, | 984 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 985 | reg->match_type, reg->match_chip)) | ||
| 986 | return -EINVAL; | 985 | return -EINVAL; |
| 987 | if (!capable(CAP_SYS_ADMIN)) | 986 | if (!capable(CAP_SYS_ADMIN)) |
| 988 | return -EPERM; | 987 | return -EPERM; |
| 989 | reg->val = tvp5150_read(sd, reg->reg & 0xff); | 988 | reg->val = tvp5150_read(sd, reg->reg & 0xff); |
| 989 | reg->size = 1; | ||
| 990 | return 0; | 990 | return 0; |
| 991 | } | 991 | } |
| 992 | 992 | ||
| 993 | static int tvp5150_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 993 | static int tvp5150_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 994 | { | 994 | { |
| 995 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 995 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 996 | 996 | ||
| 997 | if (!v4l2_chip_match_i2c_client(client, | 997 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 998 | reg->match_type, reg->match_chip)) | ||
| 999 | return -EINVAL; | 998 | return -EINVAL; |
| 1000 | if (!capable(CAP_SYS_ADMIN)) | 999 | if (!capable(CAP_SYS_ADMIN)) |
| 1001 | return -EPERM; | 1000 | return -EPERM; |
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index d5cdc4be1a35..52c0357faa5d 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c | |||
| @@ -575,7 +575,7 @@ static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd) | |||
| 575 | } | 575 | } |
| 576 | 576 | ||
| 577 | static int tw9910_get_chip_id(struct soc_camera_device *icd, | 577 | static int tw9910_get_chip_id(struct soc_camera_device *icd, |
| 578 | struct v4l2_chip_ident *id) | 578 | struct v4l2_dbg_chip_ident *id) |
| 579 | { | 579 | { |
| 580 | id->ident = V4L2_IDENT_TW9910; | 580 | id->ident = V4L2_IDENT_TW9910; |
| 581 | id->revision = 0; | 581 | id->revision = 0; |
| @@ -606,7 +606,7 @@ static int tw9910_enum_input(struct soc_camera_device *icd, | |||
| 606 | 606 | ||
| 607 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 607 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 608 | static int tw9910_get_register(struct soc_camera_device *icd, | 608 | static int tw9910_get_register(struct soc_camera_device *icd, |
| 609 | struct v4l2_register *reg) | 609 | struct v4l2_dbg_register *reg) |
| 610 | { | 610 | { |
| 611 | struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); | 611 | struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); |
| 612 | int ret; | 612 | int ret; |
| @@ -627,7 +627,7 @@ static int tw9910_get_register(struct soc_camera_device *icd, | |||
| 627 | } | 627 | } |
| 628 | 628 | ||
| 629 | static int tw9910_set_register(struct soc_camera_device *icd, | 629 | static int tw9910_set_register(struct soc_camera_device *icd, |
| 630 | struct v4l2_register *reg) | 630 | struct v4l2_dbg_register *reg) |
| 631 | { | 631 | { |
| 632 | struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); | 632 | struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); |
| 633 | 633 | ||
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c index 7a609a3a6dbe..4f16effb530f 100644 --- a/drivers/media/video/upd64031a.c +++ b/drivers/media/video/upd64031a.c | |||
| @@ -147,7 +147,7 @@ static int upd64031a_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing | |||
| 147 | return upd64031a_s_frequency(sd, NULL); | 147 | return upd64031a_s_frequency(sd, NULL); |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | static int upd64031a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) | 150 | static int upd64031a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) |
| 151 | { | 151 | { |
| 152 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 152 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 153 | 153 | ||
| @@ -162,25 +162,24 @@ static int upd64031a_log_status(struct v4l2_subdev *sd) | |||
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 164 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 165 | static int upd64031a_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 165 | static int upd64031a_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 166 | { | 166 | { |
| 167 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 167 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 168 | 168 | ||
| 169 | if (!v4l2_chip_match_i2c_client(client, | 169 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 170 | reg->match_type, reg->match_chip)) | ||
| 171 | return -EINVAL; | 170 | return -EINVAL; |
| 172 | if (!capable(CAP_SYS_ADMIN)) | 171 | if (!capable(CAP_SYS_ADMIN)) |
| 173 | return -EPERM; | 172 | return -EPERM; |
| 174 | reg->val = upd64031a_read(sd, reg->reg & 0xff); | 173 | reg->val = upd64031a_read(sd, reg->reg & 0xff); |
| 174 | reg->size = 1; | ||
| 175 | return 0; | 175 | return 0; |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | static int upd64031a_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 178 | static int upd64031a_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 179 | { | 179 | { |
| 180 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 180 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 181 | 181 | ||
| 182 | if (!v4l2_chip_match_i2c_client(client, | 182 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 183 | reg->match_type, reg->match_chip)) | ||
| 184 | return -EINVAL; | 183 | return -EINVAL; |
| 185 | if (!capable(CAP_SYS_ADMIN)) | 184 | if (!capable(CAP_SYS_ADMIN)) |
| 186 | return -EPERM; | 185 | return -EPERM; |
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c index 58412cb9c01a..4b712f69d1b7 100644 --- a/drivers/media/video/upd64083.c +++ b/drivers/media/video/upd64083.c | |||
| @@ -120,25 +120,24 @@ static int upd64083_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing | |||
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 122 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 123 | static int upd64083_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 123 | static int upd64083_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 124 | { | 124 | { |
| 125 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 125 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 126 | 126 | ||
| 127 | if (!v4l2_chip_match_i2c_client(client, | 127 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 128 | reg->match_type, reg->match_chip)) | ||
| 129 | return -EINVAL; | 128 | return -EINVAL; |
| 130 | if (!capable(CAP_SYS_ADMIN)) | 129 | if (!capable(CAP_SYS_ADMIN)) |
| 131 | return -EPERM; | 130 | return -EPERM; |
| 132 | reg->val = upd64083_read(sd, reg->reg & 0xff); | 131 | reg->val = upd64083_read(sd, reg->reg & 0xff); |
| 132 | reg->size = 1; | ||
| 133 | return 0; | 133 | return 0; |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | static int upd64083_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) | 136 | static int upd64083_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
| 137 | { | 137 | { |
| 138 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 138 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 139 | 139 | ||
| 140 | if (!v4l2_chip_match_i2c_client(client, | 140 | if (!v4l2_chip_match_i2c_client(client, ®->match)) |
| 141 | reg->match_type, reg->match_chip)) | ||
| 142 | return -EINVAL; | 141 | return -EINVAL; |
| 143 | if (!capable(CAP_SYS_ADMIN)) | 142 | if (!capable(CAP_SYS_ADMIN)) |
| 144 | return -EPERM; | 143 | return -EPERM; |
| @@ -147,7 +146,7 @@ static int upd64083_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg | |||
| 147 | } | 146 | } |
| 148 | #endif | 147 | #endif |
| 149 | 148 | ||
| 150 | static int upd64083_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) | 149 | static int upd64083_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) |
| 151 | { | 150 | { |
| 152 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 151 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 153 | 152 | ||
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c index 148a1f98c70f..dea8b321fb4a 100644 --- a/drivers/media/video/usbvideo/usbvideo.c +++ b/drivers/media/video/usbvideo/usbvideo.c | |||
| @@ -41,13 +41,13 @@ module_param(video_nr, int, 0); | |||
| 41 | static void usbvideo_Disconnect(struct usb_interface *intf); | 41 | static void usbvideo_Disconnect(struct usb_interface *intf); |
| 42 | static void usbvideo_CameraRelease(struct uvd *uvd); | 42 | static void usbvideo_CameraRelease(struct uvd *uvd); |
| 43 | 43 | ||
| 44 | static int usbvideo_v4l_ioctl(struct inode *inode, struct file *file, | 44 | static long usbvideo_v4l_ioctl(struct file *file, |
| 45 | unsigned int cmd, unsigned long arg); | 45 | unsigned int cmd, unsigned long arg); |
| 46 | static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma); | 46 | static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma); |
| 47 | static int usbvideo_v4l_open(struct inode *inode, struct file *file); | 47 | static int usbvideo_v4l_open(struct file *file); |
| 48 | static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, | 48 | static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, |
| 49 | size_t count, loff_t *ppos); | 49 | size_t count, loff_t *ppos); |
| 50 | static int usbvideo_v4l_close(struct inode *inode, struct file *file); | 50 | static int usbvideo_v4l_close(struct file *file); |
| 51 | 51 | ||
| 52 | static int usbvideo_StartDataPump(struct uvd *uvd); | 52 | static int usbvideo_StartDataPump(struct uvd *uvd); |
| 53 | static void usbvideo_StopDataPump(struct uvd *uvd); | 53 | static void usbvideo_StopDataPump(struct uvd *uvd); |
| @@ -942,17 +942,13 @@ static int usbvideo_find_struct(struct usbvideo *cams) | |||
| 942 | return rv; | 942 | return rv; |
| 943 | } | 943 | } |
| 944 | 944 | ||
| 945 | static const struct file_operations usbvideo_fops = { | 945 | static const struct v4l2_file_operations usbvideo_fops = { |
| 946 | .owner = THIS_MODULE, | 946 | .owner = THIS_MODULE, |
| 947 | .open = usbvideo_v4l_open, | 947 | .open = usbvideo_v4l_open, |
| 948 | .release =usbvideo_v4l_close, | 948 | .release =usbvideo_v4l_close, |
| 949 | .read = usbvideo_v4l_read, | 949 | .read = usbvideo_v4l_read, |
| 950 | .mmap = usbvideo_v4l_mmap, | 950 | .mmap = usbvideo_v4l_mmap, |
| 951 | .ioctl = usbvideo_v4l_ioctl, | 951 | .ioctl = usbvideo_v4l_ioctl, |
| 952 | #ifdef CONFIG_COMPAT | ||
| 953 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 954 | #endif | ||
| 955 | .llseek = no_llseek, | ||
| 956 | }; | 952 | }; |
| 957 | static const struct video_device usbvideo_template = { | 953 | static const struct video_device usbvideo_template = { |
| 958 | .fops = &usbvideo_fops, | 954 | .fops = &usbvideo_fops, |
| @@ -1113,7 +1109,7 @@ static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 1113 | * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers. | 1109 | * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers. |
| 1114 | * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT). | 1110 | * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT). |
| 1115 | */ | 1111 | */ |
| 1116 | static int usbvideo_v4l_open(struct inode *inode, struct file *file) | 1112 | static int usbvideo_v4l_open(struct file *file) |
| 1117 | { | 1113 | { |
| 1118 | struct video_device *dev = video_devdata(file); | 1114 | struct video_device *dev = video_devdata(file); |
| 1119 | struct uvd *uvd = (struct uvd *) dev; | 1115 | struct uvd *uvd = (struct uvd *) dev; |
| @@ -1233,7 +1229,7 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) | |||
| 1233 | * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers. | 1229 | * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers. |
| 1234 | * 24-May-2000 Moved MOD_DEC_USE_COUNT outside of code that can sleep. | 1230 | * 24-May-2000 Moved MOD_DEC_USE_COUNT outside of code that can sleep. |
| 1235 | */ | 1231 | */ |
| 1236 | static int usbvideo_v4l_close(struct inode *inode, struct file *file) | 1232 | static int usbvideo_v4l_close(struct file *file) |
| 1237 | { | 1233 | { |
| 1238 | struct video_device *dev = file->private_data; | 1234 | struct video_device *dev = file->private_data; |
| 1239 | struct uvd *uvd = (struct uvd *) dev; | 1235 | struct uvd *uvd = (struct uvd *) dev; |
| @@ -1281,7 +1277,7 @@ static int usbvideo_v4l_close(struct inode *inode, struct file *file) | |||
| 1281 | * History: | 1277 | * History: |
| 1282 | * 22-Jan-2000 Corrected VIDIOCSPICT to reject unsupported settings. | 1278 | * 22-Jan-2000 Corrected VIDIOCSPICT to reject unsupported settings. |
| 1283 | */ | 1279 | */ |
| 1284 | static int usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 1280 | static long usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 1285 | { | 1281 | { |
| 1286 | struct uvd *uvd = file->private_data; | 1282 | struct uvd *uvd = file->private_data; |
| 1287 | 1283 | ||
| @@ -1501,7 +1497,7 @@ static int usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 1501 | return 0; | 1497 | return 0; |
| 1502 | } | 1498 | } |
| 1503 | 1499 | ||
| 1504 | static int usbvideo_v4l_ioctl(struct inode *inode, struct file *file, | 1500 | static long usbvideo_v4l_ioctl(struct file *file, |
| 1505 | unsigned int cmd, unsigned long arg) | 1501 | unsigned int cmd, unsigned long arg) |
| 1506 | { | 1502 | { |
| 1507 | return video_usercopy(file, cmd, arg, usbvideo_v4l_do_ioctl); | 1503 | return video_usercopy(file, cmd, arg, usbvideo_v4l_do_ioctl); |
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c index 4602597ed8d1..2f1106338c08 100644 --- a/drivers/media/video/usbvideo/vicam.c +++ b/drivers/media/video/usbvideo/vicam.c | |||
| @@ -229,12 +229,12 @@ set_camera_power(struct vicam_camera *cam, int state) | |||
| 229 | return 0; | 229 | return 0; |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | static int | 232 | static long |
| 233 | vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsigned long arg) | 233 | vicam_ioctl(struct file *file, unsigned int ioctlnr, unsigned long arg) |
| 234 | { | 234 | { |
| 235 | void __user *user_arg = (void __user *)arg; | 235 | void __user *user_arg = (void __user *)arg; |
| 236 | struct vicam_camera *cam = file->private_data; | 236 | struct vicam_camera *cam = file->private_data; |
| 237 | int retval = 0; | 237 | long retval = 0; |
| 238 | 238 | ||
| 239 | if (!cam) | 239 | if (!cam) |
| 240 | return -ENODEV; | 240 | return -ENODEV; |
| @@ -470,7 +470,7 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign | |||
| 470 | } | 470 | } |
| 471 | 471 | ||
| 472 | static int | 472 | static int |
| 473 | vicam_open(struct inode *inode, struct file *file) | 473 | vicam_open(struct file *file) |
| 474 | { | 474 | { |
| 475 | struct vicam_camera *cam = video_drvdata(file); | 475 | struct vicam_camera *cam = video_drvdata(file); |
| 476 | 476 | ||
| @@ -536,7 +536,7 @@ vicam_open(struct inode *inode, struct file *file) | |||
| 536 | } | 536 | } |
| 537 | 537 | ||
| 538 | static int | 538 | static int |
| 539 | vicam_close(struct inode *inode, struct file *file) | 539 | vicam_close(struct file *file) |
| 540 | { | 540 | { |
| 541 | struct vicam_camera *cam = file->private_data; | 541 | struct vicam_camera *cam = file->private_data; |
| 542 | int open_count; | 542 | int open_count; |
| @@ -783,17 +783,13 @@ vicam_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 783 | return 0; | 783 | return 0; |
| 784 | } | 784 | } |
| 785 | 785 | ||
| 786 | static const struct file_operations vicam_fops = { | 786 | static const struct v4l2_file_operations vicam_fops = { |
| 787 | .owner = THIS_MODULE, | 787 | .owner = THIS_MODULE, |
| 788 | .open = vicam_open, | 788 | .open = vicam_open, |
| 789 | .release = vicam_close, | 789 | .release = vicam_close, |
| 790 | .read = vicam_read, | 790 | .read = vicam_read, |
| 791 | .mmap = vicam_mmap, | 791 | .mmap = vicam_mmap, |
| 792 | .ioctl = vicam_ioctl, | 792 | .ioctl = vicam_ioctl, |
| 793 | #ifdef CONFIG_COMPAT | ||
| 794 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 795 | #endif | ||
| 796 | .llseek = no_llseek, | ||
| 797 | }; | 793 | }; |
| 798 | 794 | ||
| 799 | static struct video_device vicam_template = { | 795 | static struct video_device vicam_template = { |
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 85661b1848fe..2be5e47ed081 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c | |||
| @@ -355,7 +355,7 @@ static void usbvision_remove_sysfs(struct video_device *vdev) | |||
| 355 | * then allocates buffers needed for video processing. | 355 | * then allocates buffers needed for video processing. |
| 356 | * | 356 | * |
| 357 | */ | 357 | */ |
| 358 | static int usbvision_v4l2_open(struct inode *inode, struct file *file) | 358 | static int usbvision_v4l2_open(struct file *file) |
| 359 | { | 359 | { |
| 360 | struct usb_usbvision *usbvision = video_drvdata(file); | 360 | struct usb_usbvision *usbvision = video_drvdata(file); |
| 361 | int errCode = 0; | 361 | int errCode = 0; |
| @@ -432,7 +432,7 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file) | |||
| 432 | * allocated in usbvision_v4l2_open(). | 432 | * allocated in usbvision_v4l2_open(). |
| 433 | * | 433 | * |
| 434 | */ | 434 | */ |
| 435 | static int usbvision_v4l2_close(struct inode *inode, struct file *file) | 435 | static int usbvision_v4l2_close(struct file *file) |
| 436 | { | 436 | { |
| 437 | struct usb_usbvision *usbvision = video_drvdata(file); | 437 | struct usb_usbvision *usbvision = video_drvdata(file); |
| 438 | 438 | ||
| @@ -477,12 +477,12 @@ static int usbvision_v4l2_close(struct inode *inode, struct file *file) | |||
| 477 | */ | 477 | */ |
| 478 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 478 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 479 | static int vidioc_g_register (struct file *file, void *priv, | 479 | static int vidioc_g_register (struct file *file, void *priv, |
| 480 | struct v4l2_register *reg) | 480 | struct v4l2_dbg_register *reg) |
| 481 | { | 481 | { |
| 482 | struct usb_usbvision *usbvision = video_drvdata(file); | 482 | struct usb_usbvision *usbvision = video_drvdata(file); |
| 483 | int errCode; | 483 | int errCode; |
| 484 | 484 | ||
| 485 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 485 | if (!v4l2_chip_match_host(®->match)) |
| 486 | return -EINVAL; | 486 | return -EINVAL; |
| 487 | /* NT100x has a 8-bit register space */ | 487 | /* NT100x has a 8-bit register space */ |
| 488 | errCode = usbvision_read_reg(usbvision, reg->reg&0xff); | 488 | errCode = usbvision_read_reg(usbvision, reg->reg&0xff); |
| @@ -492,16 +492,17 @@ static int vidioc_g_register (struct file *file, void *priv, | |||
| 492 | return errCode; | 492 | return errCode; |
| 493 | } | 493 | } |
| 494 | reg->val = errCode; | 494 | reg->val = errCode; |
| 495 | reg->size = 1; | ||
| 495 | return 0; | 496 | return 0; |
| 496 | } | 497 | } |
| 497 | 498 | ||
| 498 | static int vidioc_s_register (struct file *file, void *priv, | 499 | static int vidioc_s_register (struct file *file, void *priv, |
| 499 | struct v4l2_register *reg) | 500 | struct v4l2_dbg_register *reg) |
| 500 | { | 501 | { |
| 501 | struct usb_usbvision *usbvision = video_drvdata(file); | 502 | struct usb_usbvision *usbvision = video_drvdata(file); |
| 502 | int errCode; | 503 | int errCode; |
| 503 | 504 | ||
| 504 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 505 | if (!v4l2_chip_match_host(®->match)) |
| 505 | return -EINVAL; | 506 | return -EINVAL; |
| 506 | /* NT100x has a 8-bit register space */ | 507 | /* NT100x has a 8-bit register space */ |
| 507 | errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val); | 508 | errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val); |
| @@ -1178,7 +1179,7 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 1178 | * Here comes the stuff for radio on usbvision based devices | 1179 | * Here comes the stuff for radio on usbvision based devices |
| 1179 | * | 1180 | * |
| 1180 | */ | 1181 | */ |
| 1181 | static int usbvision_radio_open(struct inode *inode, struct file *file) | 1182 | static int usbvision_radio_open(struct file *file) |
| 1182 | { | 1183 | { |
| 1183 | struct usb_usbvision *usbvision = video_drvdata(file); | 1184 | struct usb_usbvision *usbvision = video_drvdata(file); |
| 1184 | int errCode = 0; | 1185 | int errCode = 0; |
| @@ -1228,7 +1229,7 @@ out: | |||
| 1228 | } | 1229 | } |
| 1229 | 1230 | ||
| 1230 | 1231 | ||
| 1231 | static int usbvision_radio_close(struct inode *inode, struct file *file) | 1232 | static int usbvision_radio_close(struct file *file) |
| 1232 | { | 1233 | { |
| 1233 | struct usb_usbvision *usbvision = video_drvdata(file); | 1234 | struct usb_usbvision *usbvision = video_drvdata(file); |
| 1234 | int errCode = 0; | 1235 | int errCode = 0; |
| @@ -1266,26 +1267,26 @@ static int usbvision_radio_close(struct inode *inode, struct file *file) | |||
| 1266 | * Here comes the stuff for vbi on usbvision based devices | 1267 | * Here comes the stuff for vbi on usbvision based devices |
| 1267 | * | 1268 | * |
| 1268 | */ | 1269 | */ |
| 1269 | static int usbvision_vbi_open(struct inode *inode, struct file *file) | 1270 | static int usbvision_vbi_open(struct file *file) |
| 1270 | { | 1271 | { |
| 1271 | /* TODO */ | 1272 | /* TODO */ |
| 1272 | return -ENODEV; | 1273 | return -ENODEV; |
| 1273 | } | 1274 | } |
| 1274 | 1275 | ||
| 1275 | static int usbvision_vbi_close(struct inode *inode, struct file *file) | 1276 | static int usbvision_vbi_close(struct file *file) |
| 1276 | { | 1277 | { |
| 1277 | /* TODO */ | 1278 | /* TODO */ |
| 1278 | return -ENODEV; | 1279 | return -ENODEV; |
| 1279 | } | 1280 | } |
| 1280 | 1281 | ||
| 1281 | static int usbvision_do_vbi_ioctl(struct file *file, | 1282 | static long usbvision_do_vbi_ioctl(struct file *file, |
| 1282 | unsigned int cmd, void *arg) | 1283 | unsigned int cmd, void *arg) |
| 1283 | { | 1284 | { |
| 1284 | /* TODO */ | 1285 | /* TODO */ |
| 1285 | return -ENOIOCTLCMD; | 1286 | return -ENOIOCTLCMD; |
| 1286 | } | 1287 | } |
| 1287 | 1288 | ||
| 1288 | static int usbvision_vbi_ioctl(struct inode *inode, struct file *file, | 1289 | static long usbvision_vbi_ioctl(struct file *file, |
| 1289 | unsigned int cmd, unsigned long arg) | 1290 | unsigned int cmd, unsigned long arg) |
| 1290 | { | 1291 | { |
| 1291 | return video_usercopy(file, cmd, arg, usbvision_do_vbi_ioctl); | 1292 | return video_usercopy(file, cmd, arg, usbvision_do_vbi_ioctl); |
| @@ -1297,16 +1298,14 @@ static int usbvision_vbi_ioctl(struct inode *inode, struct file *file, | |||
| 1297 | // | 1298 | // |
| 1298 | 1299 | ||
| 1299 | // Video template | 1300 | // Video template |
| 1300 | static const struct file_operations usbvision_fops = { | 1301 | static const struct v4l2_file_operations usbvision_fops = { |
| 1301 | .owner = THIS_MODULE, | 1302 | .owner = THIS_MODULE, |
| 1302 | .open = usbvision_v4l2_open, | 1303 | .open = usbvision_v4l2_open, |
| 1303 | .release = usbvision_v4l2_close, | 1304 | .release = usbvision_v4l2_close, |
| 1304 | .read = usbvision_v4l2_read, | 1305 | .read = usbvision_v4l2_read, |
| 1305 | .mmap = usbvision_v4l2_mmap, | 1306 | .mmap = usbvision_v4l2_mmap, |
| 1306 | .ioctl = video_ioctl2, | 1307 | .ioctl = video_ioctl2, |
| 1307 | .llseek = no_llseek, | ||
| 1308 | /* .poll = video_poll, */ | 1308 | /* .poll = video_poll, */ |
| 1309 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1310 | }; | 1309 | }; |
| 1311 | 1310 | ||
| 1312 | static const struct v4l2_ioctl_ops usbvision_ioctl_ops = { | 1311 | static const struct v4l2_ioctl_ops usbvision_ioctl_ops = { |
| @@ -1355,13 +1354,11 @@ static struct video_device usbvision_video_template = { | |||
| 1355 | 1354 | ||
| 1356 | 1355 | ||
| 1357 | // Radio template | 1356 | // Radio template |
| 1358 | static const struct file_operations usbvision_radio_fops = { | 1357 | static const struct v4l2_file_operations usbvision_radio_fops = { |
| 1359 | .owner = THIS_MODULE, | 1358 | .owner = THIS_MODULE, |
| 1360 | .open = usbvision_radio_open, | 1359 | .open = usbvision_radio_open, |
| 1361 | .release = usbvision_radio_close, | 1360 | .release = usbvision_radio_close, |
| 1362 | .ioctl = video_ioctl2, | 1361 | .ioctl = video_ioctl2, |
| 1363 | .llseek = no_llseek, | ||
| 1364 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1365 | }; | 1362 | }; |
| 1366 | 1363 | ||
| 1367 | static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = { | 1364 | static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = { |
| @@ -1392,13 +1389,11 @@ static struct video_device usbvision_radio_template = { | |||
| 1392 | }; | 1389 | }; |
| 1393 | 1390 | ||
| 1394 | // vbi template | 1391 | // vbi template |
| 1395 | static const struct file_operations usbvision_vbi_fops = { | 1392 | static const struct v4l2_file_operations usbvision_vbi_fops = { |
| 1396 | .owner = THIS_MODULE, | 1393 | .owner = THIS_MODULE, |
| 1397 | .open = usbvision_vbi_open, | 1394 | .open = usbvision_vbi_open, |
| 1398 | .release = usbvision_vbi_close, | 1395 | .release = usbvision_vbi_close, |
| 1399 | .ioctl = usbvision_vbi_ioctl, | 1396 | .ioctl = usbvision_vbi_ioctl, |
| 1400 | .llseek = no_llseek, | ||
| 1401 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1402 | }; | 1397 | }; |
| 1403 | 1398 | ||
| 1404 | static struct video_device usbvision_vbi_template= | 1399 | static struct video_device usbvision_vbi_template= |
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index afcc6934559e..fa150fff2c10 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c | |||
| @@ -406,7 +406,7 @@ static int uvc_has_privileges(struct uvc_fh *handle) | |||
| 406 | * V4L2 file operations | 406 | * V4L2 file operations |
| 407 | */ | 407 | */ |
| 408 | 408 | ||
| 409 | static int uvc_v4l2_open(struct inode *inode, struct file *file) | 409 | static int uvc_v4l2_open(struct file *file) |
| 410 | { | 410 | { |
| 411 | struct uvc_video_device *video; | 411 | struct uvc_video_device *video; |
| 412 | struct uvc_fh *handle; | 412 | struct uvc_fh *handle; |
| @@ -444,7 +444,7 @@ done: | |||
| 444 | return ret; | 444 | return ret; |
| 445 | } | 445 | } |
| 446 | 446 | ||
| 447 | static int uvc_v4l2_release(struct inode *inode, struct file *file) | 447 | static int uvc_v4l2_release(struct file *file) |
| 448 | { | 448 | { |
| 449 | struct uvc_video_device *video = video_drvdata(file); | 449 | struct uvc_video_device *video = video_drvdata(file); |
| 450 | struct uvc_fh *handle = (struct uvc_fh *)file->private_data; | 450 | struct uvc_fh *handle = (struct uvc_fh *)file->private_data; |
| @@ -472,12 +472,12 @@ static int uvc_v4l2_release(struct inode *inode, struct file *file) | |||
| 472 | return 0; | 472 | return 0; |
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 475 | static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 476 | { | 476 | { |
| 477 | struct video_device *vdev = video_devdata(file); | 477 | struct video_device *vdev = video_devdata(file); |
| 478 | struct uvc_video_device *video = video_get_drvdata(vdev); | 478 | struct uvc_video_device *video = video_get_drvdata(vdev); |
| 479 | struct uvc_fh *handle = (struct uvc_fh *)file->private_data; | 479 | struct uvc_fh *handle = (struct uvc_fh *)file->private_data; |
| 480 | int ret = 0; | 480 | long ret = 0; |
| 481 | 481 | ||
| 482 | switch (cmd) { | 482 | switch (cmd) { |
| 483 | /* Query capabilities */ | 483 | /* Query capabilities */ |
| @@ -996,7 +996,7 @@ static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 996 | return ret; | 996 | return ret; |
| 997 | } | 997 | } |
| 998 | 998 | ||
| 999 | static int uvc_v4l2_ioctl(struct inode *inode, struct file *file, | 999 | static long uvc_v4l2_ioctl(struct file *file, |
| 1000 | unsigned int cmd, unsigned long arg) | 1000 | unsigned int cmd, unsigned long arg) |
| 1001 | { | 1001 | { |
| 1002 | if (uvc_trace_param & UVC_TRACE_IOCTL) { | 1002 | if (uvc_trace_param & UVC_TRACE_IOCTL) { |
| @@ -1097,13 +1097,11 @@ static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) | |||
| 1097 | return uvc_queue_poll(&video->queue, file, wait); | 1097 | return uvc_queue_poll(&video->queue, file, wait); |
| 1098 | } | 1098 | } |
| 1099 | 1099 | ||
| 1100 | struct file_operations uvc_fops = { | 1100 | const struct v4l2_file_operations uvc_fops = { |
| 1101 | .owner = THIS_MODULE, | 1101 | .owner = THIS_MODULE, |
| 1102 | .open = uvc_v4l2_open, | 1102 | .open = uvc_v4l2_open, |
| 1103 | .release = uvc_v4l2_release, | 1103 | .release = uvc_v4l2_release, |
| 1104 | .ioctl = uvc_v4l2_ioctl, | 1104 | .ioctl = uvc_v4l2_ioctl, |
| 1105 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1106 | .llseek = no_llseek, | ||
| 1107 | .read = uvc_v4l2_read, | 1105 | .read = uvc_v4l2_read, |
| 1108 | .mmap = uvc_v4l2_mmap, | 1106 | .mmap = uvc_v4l2_mmap, |
| 1109 | .poll = uvc_v4l2_poll, | 1107 | .poll = uvc_v4l2_poll, |
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index 896b791ece15..bcf4361dc1bc 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h | |||
| @@ -753,7 +753,7 @@ static inline int uvc_queue_streaming(struct uvc_video_queue *queue) | |||
| 753 | } | 753 | } |
| 754 | 754 | ||
| 755 | /* V4L2 interface */ | 755 | /* V4L2 interface */ |
| 756 | extern struct file_operations uvc_fops; | 756 | extern const struct v4l2_file_operations uvc_fops; |
| 757 | 757 | ||
| 758 | /* Video */ | 758 | /* Video */ |
| 759 | extern int uvc_video_init(struct uvc_video_device *video); | 759 | extern int uvc_video_init(struct uvc_video_device *video); |
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c index f13c0a9d684f..d450cab20be4 100644 --- a/drivers/media/video/v4l1-compat.c +++ b/drivers/media/video/v4l1-compat.c | |||
| @@ -267,12 +267,12 @@ done: | |||
| 267 | 267 | ||
| 268 | /* ----------------------------------------------------------------- */ | 268 | /* ----------------------------------------------------------------- */ |
| 269 | 269 | ||
| 270 | static noinline int v4l1_compat_get_capabilities( | 270 | static noinline long v4l1_compat_get_capabilities( |
| 271 | struct video_capability *cap, | 271 | struct video_capability *cap, |
| 272 | struct file *file, | 272 | struct file *file, |
| 273 | v4l2_kioctl drv) | 273 | v4l2_kioctl drv) |
| 274 | { | 274 | { |
| 275 | int err; | 275 | long err; |
| 276 | struct v4l2_framebuffer fbuf; | 276 | struct v4l2_framebuffer fbuf; |
| 277 | struct v4l2_capability *cap2; | 277 | struct v4l2_capability *cap2; |
| 278 | 278 | ||
| @@ -286,13 +286,13 @@ static noinline int v4l1_compat_get_capabilities( | |||
| 286 | 286 | ||
| 287 | err = drv(file, VIDIOC_QUERYCAP, cap2); | 287 | err = drv(file, VIDIOC_QUERYCAP, cap2); |
| 288 | if (err < 0) { | 288 | if (err < 0) { |
| 289 | dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %d\n", err); | 289 | dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %ld\n", err); |
| 290 | goto done; | 290 | goto done; |
| 291 | } | 291 | } |
| 292 | if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) { | 292 | if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) { |
| 293 | err = drv(file, VIDIOC_G_FBUF, &fbuf); | 293 | err = drv(file, VIDIOC_G_FBUF, &fbuf); |
| 294 | if (err < 0) { | 294 | if (err < 0) { |
| 295 | dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %d\n", err); | 295 | dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %ld\n", err); |
| 296 | memset(&fbuf, 0, sizeof(fbuf)); | 296 | memset(&fbuf, 0, sizeof(fbuf)); |
| 297 | } | 297 | } |
| 298 | err = 0; | 298 | err = 0; |
| @@ -324,12 +324,12 @@ done: | |||
| 324 | return err; | 324 | return err; |
| 325 | } | 325 | } |
| 326 | 326 | ||
| 327 | static noinline int v4l1_compat_get_frame_buffer( | 327 | static noinline long v4l1_compat_get_frame_buffer( |
| 328 | struct video_buffer *buffer, | 328 | struct video_buffer *buffer, |
| 329 | struct file *file, | 329 | struct file *file, |
| 330 | v4l2_kioctl drv) | 330 | v4l2_kioctl drv) |
| 331 | { | 331 | { |
| 332 | int err; | 332 | long err; |
| 333 | struct v4l2_framebuffer fbuf; | 333 | struct v4l2_framebuffer fbuf; |
| 334 | 334 | ||
| 335 | memset(buffer, 0, sizeof(*buffer)); | 335 | memset(buffer, 0, sizeof(*buffer)); |
| @@ -337,7 +337,7 @@ static noinline int v4l1_compat_get_frame_buffer( | |||
| 337 | 337 | ||
| 338 | err = drv(file, VIDIOC_G_FBUF, &fbuf); | 338 | err = drv(file, VIDIOC_G_FBUF, &fbuf); |
| 339 | if (err < 0) { | 339 | if (err < 0) { |
| 340 | dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %d\n", err); | 340 | dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %ld\n", err); |
| 341 | goto done; | 341 | goto done; |
| 342 | } | 342 | } |
| 343 | buffer->base = fbuf.base; | 343 | buffer->base = fbuf.base; |
| @@ -378,12 +378,12 @@ done: | |||
| 378 | return err; | 378 | return err; |
| 379 | } | 379 | } |
| 380 | 380 | ||
| 381 | static noinline int v4l1_compat_set_frame_buffer( | 381 | static noinline long v4l1_compat_set_frame_buffer( |
| 382 | struct video_buffer *buffer, | 382 | struct video_buffer *buffer, |
| 383 | struct file *file, | 383 | struct file *file, |
| 384 | v4l2_kioctl drv) | 384 | v4l2_kioctl drv) |
| 385 | { | 385 | { |
| 386 | int err; | 386 | long err; |
| 387 | struct v4l2_framebuffer fbuf; | 387 | struct v4l2_framebuffer fbuf; |
| 388 | 388 | ||
| 389 | memset(&fbuf, 0, sizeof(fbuf)); | 389 | memset(&fbuf, 0, sizeof(fbuf)); |
| @@ -410,16 +410,16 @@ static noinline int v4l1_compat_set_frame_buffer( | |||
| 410 | fbuf.fmt.bytesperline = buffer->bytesperline; | 410 | fbuf.fmt.bytesperline = buffer->bytesperline; |
| 411 | err = drv(file, VIDIOC_S_FBUF, &fbuf); | 411 | err = drv(file, VIDIOC_S_FBUF, &fbuf); |
| 412 | if (err < 0) | 412 | if (err < 0) |
| 413 | dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %d\n", err); | 413 | dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %ld\n", err); |
| 414 | return err; | 414 | return err; |
| 415 | } | 415 | } |
| 416 | 416 | ||
| 417 | static noinline int v4l1_compat_get_win_cap_dimensions( | 417 | static noinline long v4l1_compat_get_win_cap_dimensions( |
| 418 | struct video_window *win, | 418 | struct video_window *win, |
| 419 | struct file *file, | 419 | struct file *file, |
| 420 | v4l2_kioctl drv) | 420 | v4l2_kioctl drv) |
| 421 | { | 421 | { |
| 422 | int err; | 422 | long err; |
| 423 | struct v4l2_format *fmt; | 423 | struct v4l2_format *fmt; |
| 424 | 424 | ||
| 425 | fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); | 425 | fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); |
| @@ -432,7 +432,7 @@ static noinline int v4l1_compat_get_win_cap_dimensions( | |||
| 432 | fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY; | 432 | fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY; |
| 433 | err = drv(file, VIDIOC_G_FMT, fmt); | 433 | err = drv(file, VIDIOC_G_FMT, fmt); |
| 434 | if (err < 0) | 434 | if (err < 0) |
| 435 | dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %d\n", err); | 435 | dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %ld\n", err); |
| 436 | if (err == 0) { | 436 | if (err == 0) { |
| 437 | win->x = fmt->fmt.win.w.left; | 437 | win->x = fmt->fmt.win.w.left; |
| 438 | win->y = fmt->fmt.win.w.top; | 438 | win->y = fmt->fmt.win.w.top; |
| @@ -447,7 +447,7 @@ static noinline int v4l1_compat_get_win_cap_dimensions( | |||
| 447 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 447 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 448 | err = drv(file, VIDIOC_G_FMT, fmt); | 448 | err = drv(file, VIDIOC_G_FMT, fmt); |
| 449 | if (err < 0) { | 449 | if (err < 0) { |
| 450 | dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %d\n", err); | 450 | dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %ld\n", err); |
| 451 | goto done; | 451 | goto done; |
| 452 | } | 452 | } |
| 453 | win->x = 0; | 453 | win->x = 0; |
| @@ -462,12 +462,12 @@ done: | |||
| 462 | return err; | 462 | return err; |
| 463 | } | 463 | } |
| 464 | 464 | ||
| 465 | static noinline int v4l1_compat_set_win_cap_dimensions( | 465 | static noinline long v4l1_compat_set_win_cap_dimensions( |
| 466 | struct video_window *win, | 466 | struct video_window *win, |
| 467 | struct file *file, | 467 | struct file *file, |
| 468 | v4l2_kioctl drv) | 468 | v4l2_kioctl drv) |
| 469 | { | 469 | { |
| 470 | int err, err1, err2; | 470 | long err, err1, err2; |
| 471 | struct v4l2_format *fmt; | 471 | struct v4l2_format *fmt; |
| 472 | 472 | ||
| 473 | fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); | 473 | fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); |
| @@ -479,7 +479,7 @@ static noinline int v4l1_compat_set_win_cap_dimensions( | |||
| 479 | drv(file, VIDIOC_STREAMOFF, &fmt->type); | 479 | drv(file, VIDIOC_STREAMOFF, &fmt->type); |
| 480 | err1 = drv(file, VIDIOC_G_FMT, fmt); | 480 | err1 = drv(file, VIDIOC_G_FMT, fmt); |
| 481 | if (err1 < 0) | 481 | if (err1 < 0) |
| 482 | dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %d\n", err1); | 482 | dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %ld\n", err1); |
| 483 | if (err1 == 0) { | 483 | if (err1 == 0) { |
| 484 | fmt->fmt.pix.width = win->width; | 484 | fmt->fmt.pix.width = win->width; |
| 485 | fmt->fmt.pix.height = win->height; | 485 | fmt->fmt.pix.height = win->height; |
| @@ -487,7 +487,7 @@ static noinline int v4l1_compat_set_win_cap_dimensions( | |||
| 487 | fmt->fmt.pix.bytesperline = 0; | 487 | fmt->fmt.pix.bytesperline = 0; |
| 488 | err = drv(file, VIDIOC_S_FMT, fmt); | 488 | err = drv(file, VIDIOC_S_FMT, fmt); |
| 489 | if (err < 0) | 489 | if (err < 0) |
| 490 | dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %d\n", | 490 | dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %ld\n", |
| 491 | err); | 491 | err); |
| 492 | win->width = fmt->fmt.pix.width; | 492 | win->width = fmt->fmt.pix.width; |
| 493 | win->height = fmt->fmt.pix.height; | 493 | win->height = fmt->fmt.pix.height; |
| @@ -504,7 +504,7 @@ static noinline int v4l1_compat_set_win_cap_dimensions( | |||
| 504 | fmt->fmt.win.clipcount = win->clipcount; | 504 | fmt->fmt.win.clipcount = win->clipcount; |
| 505 | err2 = drv(file, VIDIOC_S_FMT, fmt); | 505 | err2 = drv(file, VIDIOC_S_FMT, fmt); |
| 506 | if (err2 < 0) | 506 | if (err2 < 0) |
| 507 | dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %d\n", err2); | 507 | dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %ld\n", err2); |
| 508 | 508 | ||
| 509 | if (err1 != 0 && err2 != 0) | 509 | if (err1 != 0 && err2 != 0) |
| 510 | err = err1; | 510 | err = err1; |
| @@ -514,12 +514,12 @@ static noinline int v4l1_compat_set_win_cap_dimensions( | |||
| 514 | return err; | 514 | return err; |
| 515 | } | 515 | } |
| 516 | 516 | ||
| 517 | static noinline int v4l1_compat_turn_preview_on_off( | 517 | static noinline long v4l1_compat_turn_preview_on_off( |
| 518 | int *on, | 518 | int *on, |
| 519 | struct file *file, | 519 | struct file *file, |
| 520 | v4l2_kioctl drv) | 520 | v4l2_kioctl drv) |
| 521 | { | 521 | { |
| 522 | int err; | 522 | long err; |
| 523 | enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 523 | enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 524 | 524 | ||
| 525 | if (0 == *on) { | 525 | if (0 == *on) { |
| @@ -530,16 +530,16 @@ static noinline int v4l1_compat_turn_preview_on_off( | |||
| 530 | } | 530 | } |
| 531 | err = drv(file, VIDIOC_OVERLAY, on); | 531 | err = drv(file, VIDIOC_OVERLAY, on); |
| 532 | if (err < 0) | 532 | if (err < 0) |
| 533 | dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %d\n", err); | 533 | dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %ld\n", err); |
| 534 | return err; | 534 | return err; |
| 535 | } | 535 | } |
| 536 | 536 | ||
| 537 | static noinline int v4l1_compat_get_input_info( | 537 | static noinline long v4l1_compat_get_input_info( |
| 538 | struct video_channel *chan, | 538 | struct video_channel *chan, |
| 539 | struct file *file, | 539 | struct file *file, |
| 540 | v4l2_kioctl drv) | 540 | v4l2_kioctl drv) |
| 541 | { | 541 | { |
| 542 | int err; | 542 | long err; |
| 543 | struct v4l2_input input2; | 543 | struct v4l2_input input2; |
| 544 | v4l2_std_id sid; | 544 | v4l2_std_id sid; |
| 545 | 545 | ||
| @@ -548,7 +548,7 @@ static noinline int v4l1_compat_get_input_info( | |||
| 548 | err = drv(file, VIDIOC_ENUMINPUT, &input2); | 548 | err = drv(file, VIDIOC_ENUMINPUT, &input2); |
| 549 | if (err < 0) { | 549 | if (err < 0) { |
| 550 | dprintk("VIDIOCGCHAN / VIDIOC_ENUMINPUT: " | 550 | dprintk("VIDIOCGCHAN / VIDIOC_ENUMINPUT: " |
| 551 | "channel=%d err=%d\n", chan->channel, err); | 551 | "channel=%d err=%ld\n", chan->channel, err); |
| 552 | goto done; | 552 | goto done; |
| 553 | } | 553 | } |
| 554 | chan->channel = input2.index; | 554 | chan->channel = input2.index; |
| @@ -569,7 +569,7 @@ static noinline int v4l1_compat_get_input_info( | |||
| 569 | chan->norm = 0; | 569 | chan->norm = 0; |
| 570 | err = drv(file, VIDIOC_G_STD, &sid); | 570 | err = drv(file, VIDIOC_G_STD, &sid); |
| 571 | if (err < 0) | 571 | if (err < 0) |
| 572 | dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %d\n", err); | 572 | dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %ld\n", err); |
| 573 | if (err == 0) { | 573 | if (err == 0) { |
| 574 | if (sid & V4L2_STD_PAL) | 574 | if (sid & V4L2_STD_PAL) |
| 575 | chan->norm = VIDEO_MODE_PAL; | 575 | chan->norm = VIDEO_MODE_PAL; |
| @@ -582,17 +582,17 @@ done: | |||
| 582 | return err; | 582 | return err; |
| 583 | } | 583 | } |
| 584 | 584 | ||
| 585 | static noinline int v4l1_compat_set_input( | 585 | static noinline long v4l1_compat_set_input( |
| 586 | struct video_channel *chan, | 586 | struct video_channel *chan, |
| 587 | struct file *file, | 587 | struct file *file, |
| 588 | v4l2_kioctl drv) | 588 | v4l2_kioctl drv) |
| 589 | { | 589 | { |
| 590 | int err; | 590 | long err; |
| 591 | v4l2_std_id sid = 0; | 591 | v4l2_std_id sid = 0; |
| 592 | 592 | ||
| 593 | err = drv(file, VIDIOC_S_INPUT, &chan->channel); | 593 | err = drv(file, VIDIOC_S_INPUT, &chan->channel); |
| 594 | if (err < 0) | 594 | if (err < 0) |
| 595 | dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %d\n", err); | 595 | dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %ld\n", err); |
| 596 | switch (chan->norm) { | 596 | switch (chan->norm) { |
| 597 | case VIDEO_MODE_PAL: | 597 | case VIDEO_MODE_PAL: |
| 598 | sid = V4L2_STD_PAL; | 598 | sid = V4L2_STD_PAL; |
| @@ -607,17 +607,17 @@ static noinline int v4l1_compat_set_input( | |||
| 607 | if (0 != sid) { | 607 | if (0 != sid) { |
| 608 | err = drv(file, VIDIOC_S_STD, &sid); | 608 | err = drv(file, VIDIOC_S_STD, &sid); |
| 609 | if (err < 0) | 609 | if (err < 0) |
| 610 | dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %d\n", err); | 610 | dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %ld\n", err); |
| 611 | } | 611 | } |
| 612 | return err; | 612 | return err; |
| 613 | } | 613 | } |
| 614 | 614 | ||
| 615 | static noinline int v4l1_compat_get_picture( | 615 | static noinline long v4l1_compat_get_picture( |
| 616 | struct video_picture *pict, | 616 | struct video_picture *pict, |
| 617 | struct file *file, | 617 | struct file *file, |
| 618 | v4l2_kioctl drv) | 618 | v4l2_kioctl drv) |
| 619 | { | 619 | { |
| 620 | int err; | 620 | long err; |
| 621 | struct v4l2_format *fmt; | 621 | struct v4l2_format *fmt; |
| 622 | 622 | ||
| 623 | fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); | 623 | fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); |
| @@ -640,7 +640,7 @@ static noinline int v4l1_compat_get_picture( | |||
| 640 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 640 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 641 | err = drv(file, VIDIOC_G_FMT, fmt); | 641 | err = drv(file, VIDIOC_G_FMT, fmt); |
| 642 | if (err < 0) { | 642 | if (err < 0) { |
| 643 | dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n", err); | 643 | dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %ld\n", err); |
| 644 | goto done; | 644 | goto done; |
| 645 | } | 645 | } |
| 646 | 646 | ||
| @@ -654,12 +654,12 @@ done: | |||
| 654 | return err; | 654 | return err; |
| 655 | } | 655 | } |
| 656 | 656 | ||
| 657 | static noinline int v4l1_compat_set_picture( | 657 | static noinline long v4l1_compat_set_picture( |
| 658 | struct video_picture *pict, | 658 | struct video_picture *pict, |
| 659 | struct file *file, | 659 | struct file *file, |
| 660 | v4l2_kioctl drv) | 660 | v4l2_kioctl drv) |
| 661 | { | 661 | { |
| 662 | int err; | 662 | long err; |
| 663 | struct v4l2_framebuffer fbuf; | 663 | struct v4l2_framebuffer fbuf; |
| 664 | int mem_err = 0, ovl_err = 0; | 664 | int mem_err = 0, ovl_err = 0; |
| 665 | struct v4l2_format *fmt; | 665 | struct v4l2_format *fmt; |
| @@ -694,7 +694,7 @@ static noinline int v4l1_compat_set_picture( | |||
| 694 | support memory capture. Trying to set the memory capture | 694 | support memory capture. Trying to set the memory capture |
| 695 | parameters would be pointless. */ | 695 | parameters would be pointless. */ |
| 696 | if (err < 0) { | 696 | if (err < 0) { |
| 697 | dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n", err); | 697 | dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %ld\n", err); |
| 698 | mem_err = -1000; /* didn't even try */ | 698 | mem_err = -1000; /* didn't even try */ |
| 699 | } else if (fmt->fmt.pix.pixelformat != | 699 | } else if (fmt->fmt.pix.pixelformat != |
| 700 | palette_to_pixelformat(pict->palette)) { | 700 | palette_to_pixelformat(pict->palette)) { |
| @@ -711,7 +711,7 @@ static noinline int v4l1_compat_set_picture( | |||
| 711 | support overlay. Trying to set the overlay parameters | 711 | support overlay. Trying to set the overlay parameters |
| 712 | would be quite pointless. */ | 712 | would be quite pointless. */ |
| 713 | if (err < 0) { | 713 | if (err < 0) { |
| 714 | dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n", err); | 714 | dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %ld\n", err); |
| 715 | ovl_err = -1000; /* didn't even try */ | 715 | ovl_err = -1000; /* didn't even try */ |
| 716 | } else if (fbuf.fmt.pixelformat != | 716 | } else if (fbuf.fmt.pixelformat != |
| 717 | palette_to_pixelformat(pict->palette)) { | 717 | palette_to_pixelformat(pict->palette)) { |
| @@ -736,12 +736,13 @@ static noinline int v4l1_compat_set_picture( | |||
| 736 | return err; | 736 | return err; |
| 737 | } | 737 | } |
| 738 | 738 | ||
| 739 | static noinline int v4l1_compat_get_tuner( | 739 | static noinline long v4l1_compat_get_tuner( |
| 740 | struct video_tuner *tun, | 740 | struct video_tuner *tun, |
| 741 | struct file *file, | 741 | struct file *file, |
| 742 | v4l2_kioctl drv) | 742 | v4l2_kioctl drv) |
| 743 | { | 743 | { |
| 744 | int err, i; | 744 | long err; |
| 745 | int i; | ||
| 745 | struct v4l2_tuner tun2; | 746 | struct v4l2_tuner tun2; |
| 746 | struct v4l2_standard std2; | 747 | struct v4l2_standard std2; |
| 747 | v4l2_std_id sid; | 748 | v4l2_std_id sid; |
| @@ -749,7 +750,7 @@ static noinline int v4l1_compat_get_tuner( | |||
| 749 | memset(&tun2, 0, sizeof(tun2)); | 750 | memset(&tun2, 0, sizeof(tun2)); |
| 750 | err = drv(file, VIDIOC_G_TUNER, &tun2); | 751 | err = drv(file, VIDIOC_G_TUNER, &tun2); |
| 751 | if (err < 0) { | 752 | if (err < 0) { |
| 752 | dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %d\n", err); | 753 | dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %ld\n", err); |
| 753 | goto done; | 754 | goto done; |
| 754 | } | 755 | } |
| 755 | memcpy(tun->name, tun2.name, | 756 | memcpy(tun->name, tun2.name, |
| @@ -775,7 +776,7 @@ static noinline int v4l1_compat_get_tuner( | |||
| 775 | 776 | ||
| 776 | err = drv(file, VIDIOC_G_STD, &sid); | 777 | err = drv(file, VIDIOC_G_STD, &sid); |
| 777 | if (err < 0) | 778 | if (err < 0) |
| 778 | dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %d\n", err); | 779 | dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %ld\n", err); |
| 779 | if (err == 0) { | 780 | if (err == 0) { |
| 780 | if (sid & V4L2_STD_PAL) | 781 | if (sid & V4L2_STD_PAL) |
| 781 | tun->mode = VIDEO_MODE_PAL; | 782 | tun->mode = VIDEO_MODE_PAL; |
| @@ -794,12 +795,12 @@ done: | |||
| 794 | return err; | 795 | return err; |
| 795 | } | 796 | } |
| 796 | 797 | ||
| 797 | static noinline int v4l1_compat_select_tuner( | 798 | static noinline long v4l1_compat_select_tuner( |
| 798 | struct video_tuner *tun, | 799 | struct video_tuner *tun, |
| 799 | struct file *file, | 800 | struct file *file, |
| 800 | v4l2_kioctl drv) | 801 | v4l2_kioctl drv) |
| 801 | { | 802 | { |
| 802 | int err; | 803 | long err; |
| 803 | struct v4l2_tuner t;/*84 bytes on x86_64*/ | 804 | struct v4l2_tuner t;/*84 bytes on x86_64*/ |
| 804 | memset(&t, 0, sizeof(t)); | 805 | memset(&t, 0, sizeof(t)); |
| 805 | 806 | ||
| @@ -807,34 +808,34 @@ static noinline int v4l1_compat_select_tuner( | |||
| 807 | 808 | ||
| 808 | err = drv(file, VIDIOC_S_INPUT, &t); | 809 | err = drv(file, VIDIOC_S_INPUT, &t); |
| 809 | if (err < 0) | 810 | if (err < 0) |
| 810 | dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n", err); | 811 | dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %ld\n", err); |
| 811 | return err; | 812 | return err; |
| 812 | } | 813 | } |
| 813 | 814 | ||
| 814 | static noinline int v4l1_compat_get_frequency( | 815 | static noinline long v4l1_compat_get_frequency( |
| 815 | unsigned long *freq, | 816 | unsigned long *freq, |
| 816 | struct file *file, | 817 | struct file *file, |
| 817 | v4l2_kioctl drv) | 818 | v4l2_kioctl drv) |
| 818 | { | 819 | { |
| 819 | int err; | 820 | long err; |
| 820 | struct v4l2_frequency freq2; | 821 | struct v4l2_frequency freq2; |
| 821 | memset(&freq2, 0, sizeof(freq2)); | 822 | memset(&freq2, 0, sizeof(freq2)); |
| 822 | 823 | ||
| 823 | freq2.tuner = 0; | 824 | freq2.tuner = 0; |
| 824 | err = drv(file, VIDIOC_G_FREQUENCY, &freq2); | 825 | err = drv(file, VIDIOC_G_FREQUENCY, &freq2); |
| 825 | if (err < 0) | 826 | if (err < 0) |
| 826 | dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %d\n", err); | 827 | dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %ld\n", err); |
| 827 | if (0 == err) | 828 | if (0 == err) |
| 828 | *freq = freq2.frequency; | 829 | *freq = freq2.frequency; |
| 829 | return err; | 830 | return err; |
| 830 | } | 831 | } |
| 831 | 832 | ||
| 832 | static noinline int v4l1_compat_set_frequency( | 833 | static noinline long v4l1_compat_set_frequency( |
| 833 | unsigned long *freq, | 834 | unsigned long *freq, |
| 834 | struct file *file, | 835 | struct file *file, |
| 835 | v4l2_kioctl drv) | 836 | v4l2_kioctl drv) |
| 836 | { | 837 | { |
| 837 | int err; | 838 | long err; |
| 838 | struct v4l2_frequency freq2; | 839 | struct v4l2_frequency freq2; |
| 839 | memset(&freq2, 0, sizeof(freq2)); | 840 | memset(&freq2, 0, sizeof(freq2)); |
| 840 | 841 | ||
| @@ -842,16 +843,17 @@ static noinline int v4l1_compat_set_frequency( | |||
| 842 | freq2.frequency = *freq; | 843 | freq2.frequency = *freq; |
| 843 | err = drv(file, VIDIOC_S_FREQUENCY, &freq2); | 844 | err = drv(file, VIDIOC_S_FREQUENCY, &freq2); |
| 844 | if (err < 0) | 845 | if (err < 0) |
| 845 | dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %d\n", err); | 846 | dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %ld\n", err); |
| 846 | return err; | 847 | return err; |
| 847 | } | 848 | } |
| 848 | 849 | ||
| 849 | static noinline int v4l1_compat_get_audio( | 850 | static noinline long v4l1_compat_get_audio( |
| 850 | struct video_audio *aud, | 851 | struct video_audio *aud, |
| 851 | struct file *file, | 852 | struct file *file, |
| 852 | v4l2_kioctl drv) | 853 | v4l2_kioctl drv) |
| 853 | { | 854 | { |
| 854 | int err, i; | 855 | long err; |
| 856 | int i; | ||
| 855 | struct v4l2_queryctrl qctrl2; | 857 | struct v4l2_queryctrl qctrl2; |
| 856 | struct v4l2_audio aud2; | 858 | struct v4l2_audio aud2; |
| 857 | struct v4l2_tuner tun2; | 859 | struct v4l2_tuner tun2; |
| @@ -859,7 +861,7 @@ static noinline int v4l1_compat_get_audio( | |||
| 859 | 861 | ||
| 860 | err = drv(file, VIDIOC_G_AUDIO, &aud2); | 862 | err = drv(file, VIDIOC_G_AUDIO, &aud2); |
| 861 | if (err < 0) { | 863 | if (err < 0) { |
| 862 | dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %d\n", err); | 864 | dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %ld\n", err); |
| 863 | goto done; | 865 | goto done; |
| 864 | } | 866 | } |
| 865 | memcpy(aud->name, aud2.name, | 867 | memcpy(aud->name, aud2.name, |
| @@ -903,7 +905,7 @@ static noinline int v4l1_compat_get_audio( | |||
| 903 | memset(&tun2, 0, sizeof(tun2)); | 905 | memset(&tun2, 0, sizeof(tun2)); |
| 904 | err = drv(file, VIDIOC_G_TUNER, &tun2); | 906 | err = drv(file, VIDIOC_G_TUNER, &tun2); |
| 905 | if (err < 0) { | 907 | if (err < 0) { |
| 906 | dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n", err); | 908 | dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %ld\n", err); |
| 907 | err = 0; | 909 | err = 0; |
| 908 | goto done; | 910 | goto done; |
| 909 | } | 911 | } |
| @@ -918,12 +920,12 @@ done: | |||
| 918 | return err; | 920 | return err; |
| 919 | } | 921 | } |
| 920 | 922 | ||
| 921 | static noinline int v4l1_compat_set_audio( | 923 | static noinline long v4l1_compat_set_audio( |
| 922 | struct video_audio *aud, | 924 | struct video_audio *aud, |
| 923 | struct file *file, | 925 | struct file *file, |
| 924 | v4l2_kioctl drv) | 926 | v4l2_kioctl drv) |
| 925 | { | 927 | { |
| 926 | int err; | 928 | long err; |
| 927 | struct v4l2_audio aud2; | 929 | struct v4l2_audio aud2; |
| 928 | struct v4l2_tuner tun2; | 930 | struct v4l2_tuner tun2; |
| 929 | 931 | ||
| @@ -933,7 +935,7 @@ static noinline int v4l1_compat_set_audio( | |||
| 933 | aud2.index = aud->audio; | 935 | aud2.index = aud->audio; |
| 934 | err = drv(file, VIDIOC_S_AUDIO, &aud2); | 936 | err = drv(file, VIDIOC_S_AUDIO, &aud2); |
| 935 | if (err < 0) { | 937 | if (err < 0) { |
| 936 | dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %d\n", err); | 938 | dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %ld\n", err); |
| 937 | goto done; | 939 | goto done; |
| 938 | } | 940 | } |
| 939 | 941 | ||
| @@ -950,7 +952,7 @@ static noinline int v4l1_compat_set_audio( | |||
| 950 | 952 | ||
| 951 | err = drv(file, VIDIOC_G_TUNER, &tun2); | 953 | err = drv(file, VIDIOC_G_TUNER, &tun2); |
| 952 | if (err < 0) | 954 | if (err < 0) |
| 953 | dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %d\n", err); | 955 | dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %ld\n", err); |
| 954 | if (err == 0) { | 956 | if (err == 0) { |
| 955 | switch (aud->mode) { | 957 | switch (aud->mode) { |
| 956 | default: | 958 | default: |
| @@ -967,19 +969,19 @@ static noinline int v4l1_compat_set_audio( | |||
| 967 | } | 969 | } |
| 968 | err = drv(file, VIDIOC_S_TUNER, &tun2); | 970 | err = drv(file, VIDIOC_S_TUNER, &tun2); |
| 969 | if (err < 0) | 971 | if (err < 0) |
| 970 | dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %d\n", err); | 972 | dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %ld\n", err); |
| 971 | } | 973 | } |
| 972 | err = 0; | 974 | err = 0; |
| 973 | done: | 975 | done: |
| 974 | return err; | 976 | return err; |
| 975 | } | 977 | } |
| 976 | 978 | ||
| 977 | static noinline int v4l1_compat_capture_frame( | 979 | static noinline long v4l1_compat_capture_frame( |
| 978 | struct video_mmap *mm, | 980 | struct video_mmap *mm, |
| 979 | struct file *file, | 981 | struct file *file, |
| 980 | v4l2_kioctl drv) | 982 | v4l2_kioctl drv) |
| 981 | { | 983 | { |
| 982 | int err; | 984 | long err; |
| 983 | enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 985 | enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 984 | struct v4l2_buffer buf; | 986 | struct v4l2_buffer buf; |
| 985 | struct v4l2_format *fmt; | 987 | struct v4l2_format *fmt; |
| @@ -994,7 +996,7 @@ static noinline int v4l1_compat_capture_frame( | |||
| 994 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 996 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 995 | err = drv(file, VIDIOC_G_FMT, fmt); | 997 | err = drv(file, VIDIOC_G_FMT, fmt); |
| 996 | if (err < 0) { | 998 | if (err < 0) { |
| 997 | dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n", err); | 999 | dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %ld\n", err); |
| 998 | goto done; | 1000 | goto done; |
| 999 | } | 1001 | } |
| 1000 | if (mm->width != fmt->fmt.pix.width || | 1002 | if (mm->width != fmt->fmt.pix.width || |
| @@ -1010,7 +1012,7 @@ static noinline int v4l1_compat_capture_frame( | |||
| 1010 | fmt->fmt.pix.bytesperline = 0; | 1012 | fmt->fmt.pix.bytesperline = 0; |
| 1011 | err = drv(file, VIDIOC_S_FMT, fmt); | 1013 | err = drv(file, VIDIOC_S_FMT, fmt); |
| 1012 | if (err < 0) { | 1014 | if (err < 0) { |
| 1013 | dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %d\n", err); | 1015 | dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %ld\n", err); |
| 1014 | goto done; | 1016 | goto done; |
| 1015 | } | 1017 | } |
| 1016 | } | 1018 | } |
| @@ -1018,28 +1020,28 @@ static noinline int v4l1_compat_capture_frame( | |||
| 1018 | buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1020 | buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 1019 | err = drv(file, VIDIOC_QUERYBUF, &buf); | 1021 | err = drv(file, VIDIOC_QUERYBUF, &buf); |
| 1020 | if (err < 0) { | 1022 | if (err < 0) { |
| 1021 | dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %d\n", err); | 1023 | dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %ld\n", err); |
| 1022 | goto done; | 1024 | goto done; |
| 1023 | } | 1025 | } |
| 1024 | err = drv(file, VIDIOC_QBUF, &buf); | 1026 | err = drv(file, VIDIOC_QBUF, &buf); |
| 1025 | if (err < 0) { | 1027 | if (err < 0) { |
| 1026 | dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %d\n", err); | 1028 | dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %ld\n", err); |
| 1027 | goto done; | 1029 | goto done; |
| 1028 | } | 1030 | } |
| 1029 | err = drv(file, VIDIOC_STREAMON, &captype); | 1031 | err = drv(file, VIDIOC_STREAMON, &captype); |
| 1030 | if (err < 0) | 1032 | if (err < 0) |
| 1031 | dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %d\n", err); | 1033 | dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %ld\n", err); |
| 1032 | done: | 1034 | done: |
| 1033 | kfree(fmt); | 1035 | kfree(fmt); |
| 1034 | return err; | 1036 | return err; |
| 1035 | } | 1037 | } |
| 1036 | 1038 | ||
| 1037 | static noinline int v4l1_compat_sync( | 1039 | static noinline long v4l1_compat_sync( |
| 1038 | int *i, | 1040 | int *i, |
| 1039 | struct file *file, | 1041 | struct file *file, |
| 1040 | v4l2_kioctl drv) | 1042 | v4l2_kioctl drv) |
| 1041 | { | 1043 | { |
| 1042 | int err; | 1044 | long err; |
| 1043 | enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1045 | enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 1044 | struct v4l2_buffer buf; | 1046 | struct v4l2_buffer buf; |
| 1045 | struct poll_wqueues *pwq; | 1047 | struct poll_wqueues *pwq; |
| @@ -1050,7 +1052,7 @@ static noinline int v4l1_compat_sync( | |||
| 1050 | err = drv(file, VIDIOC_QUERYBUF, &buf); | 1052 | err = drv(file, VIDIOC_QUERYBUF, &buf); |
| 1051 | if (err < 0) { | 1053 | if (err < 0) { |
| 1052 | /* No such buffer */ | 1054 | /* No such buffer */ |
| 1053 | dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n", err); | 1055 | dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %ld\n", err); |
| 1054 | goto done; | 1056 | goto done; |
| 1055 | } | 1057 | } |
| 1056 | if (!(buf.flags & V4L2_BUF_FLAG_MAPPED)) { | 1058 | if (!(buf.flags & V4L2_BUF_FLAG_MAPPED)) { |
| @@ -1062,7 +1064,7 @@ static noinline int v4l1_compat_sync( | |||
| 1062 | /* make sure capture actually runs so we don't block forever */ | 1064 | /* make sure capture actually runs so we don't block forever */ |
| 1063 | err = drv(file, VIDIOC_STREAMON, &captype); | 1065 | err = drv(file, VIDIOC_STREAMON, &captype); |
| 1064 | if (err < 0) { | 1066 | if (err < 0) { |
| 1065 | dprintk("VIDIOCSYNC / VIDIOC_STREAMON: %d\n", err); | 1067 | dprintk("VIDIOCSYNC / VIDIOC_STREAMON: %ld\n", err); |
| 1066 | goto done; | 1068 | goto done; |
| 1067 | } | 1069 | } |
| 1068 | 1070 | ||
| @@ -1076,7 +1078,7 @@ static noinline int v4l1_compat_sync( | |||
| 1076 | break; | 1078 | break; |
| 1077 | err = drv(file, VIDIOC_QUERYBUF, &buf); | 1079 | err = drv(file, VIDIOC_QUERYBUF, &buf); |
| 1078 | if (err < 0) | 1080 | if (err < 0) |
| 1079 | dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n", err); | 1081 | dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %ld\n", err); |
| 1080 | } | 1082 | } |
| 1081 | kfree(pwq); | 1083 | kfree(pwq); |
| 1082 | if (!(buf.flags & V4L2_BUF_FLAG_DONE)) /* not done */ | 1084 | if (!(buf.flags & V4L2_BUF_FLAG_DONE)) /* not done */ |
| @@ -1084,18 +1086,18 @@ static noinline int v4l1_compat_sync( | |||
| 1084 | do { | 1086 | do { |
| 1085 | err = drv(file, VIDIOC_DQBUF, &buf); | 1087 | err = drv(file, VIDIOC_DQBUF, &buf); |
| 1086 | if (err < 0) | 1088 | if (err < 0) |
| 1087 | dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %d\n", err); | 1089 | dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %ld\n", err); |
| 1088 | } while (err == 0 && buf.index != *i); | 1090 | } while (err == 0 && buf.index != *i); |
| 1089 | done: | 1091 | done: |
| 1090 | return err; | 1092 | return err; |
| 1091 | } | 1093 | } |
| 1092 | 1094 | ||
| 1093 | static noinline int v4l1_compat_get_vbi_format( | 1095 | static noinline long v4l1_compat_get_vbi_format( |
| 1094 | struct vbi_format *fmt, | 1096 | struct vbi_format *fmt, |
| 1095 | struct file *file, | 1097 | struct file *file, |
| 1096 | v4l2_kioctl drv) | 1098 | v4l2_kioctl drv) |
| 1097 | { | 1099 | { |
| 1098 | int err; | 1100 | long err; |
| 1099 | struct v4l2_format *fmt2; | 1101 | struct v4l2_format *fmt2; |
| 1100 | 1102 | ||
| 1101 | fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL); | 1103 | fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL); |
| @@ -1107,7 +1109,7 @@ static noinline int v4l1_compat_get_vbi_format( | |||
| 1107 | 1109 | ||
| 1108 | err = drv(file, VIDIOC_G_FMT, fmt2); | 1110 | err = drv(file, VIDIOC_G_FMT, fmt2); |
| 1109 | if (err < 0) { | 1111 | if (err < 0) { |
| 1110 | dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err); | 1112 | dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %ld\n", err); |
| 1111 | goto done; | 1113 | goto done; |
| 1112 | } | 1114 | } |
| 1113 | if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) { | 1115 | if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) { |
| @@ -1128,12 +1130,12 @@ done: | |||
| 1128 | return err; | 1130 | return err; |
| 1129 | } | 1131 | } |
| 1130 | 1132 | ||
| 1131 | static noinline int v4l1_compat_set_vbi_format( | 1133 | static noinline long v4l1_compat_set_vbi_format( |
| 1132 | struct vbi_format *fmt, | 1134 | struct vbi_format *fmt, |
| 1133 | struct file *file, | 1135 | struct file *file, |
| 1134 | v4l2_kioctl drv) | 1136 | v4l2_kioctl drv) |
| 1135 | { | 1137 | { |
| 1136 | int err; | 1138 | long err; |
| 1137 | struct v4l2_format *fmt2 = NULL; | 1139 | struct v4l2_format *fmt2 = NULL; |
| 1138 | 1140 | ||
| 1139 | if (VIDEO_PALETTE_RAW != fmt->sample_format) { | 1141 | if (VIDEO_PALETTE_RAW != fmt->sample_format) { |
| @@ -1157,7 +1159,7 @@ static noinline int v4l1_compat_set_vbi_format( | |||
| 1157 | fmt2->fmt.vbi.flags = fmt->flags; | 1159 | fmt2->fmt.vbi.flags = fmt->flags; |
| 1158 | err = drv(file, VIDIOC_TRY_FMT, fmt2); | 1160 | err = drv(file, VIDIOC_TRY_FMT, fmt2); |
| 1159 | if (err < 0) { | 1161 | if (err < 0) { |
| 1160 | dprintk("VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %d\n", err); | 1162 | dprintk("VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %ld\n", err); |
| 1161 | goto done; | 1163 | goto done; |
| 1162 | } | 1164 | } |
| 1163 | 1165 | ||
| @@ -1174,7 +1176,7 @@ static noinline int v4l1_compat_set_vbi_format( | |||
| 1174 | } | 1176 | } |
| 1175 | err = drv(file, VIDIOC_S_FMT, fmt2); | 1177 | err = drv(file, VIDIOC_S_FMT, fmt2); |
| 1176 | if (err < 0) | 1178 | if (err < 0) |
| 1177 | dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %d\n", err); | 1179 | dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %ld\n", err); |
| 1178 | done: | 1180 | done: |
| 1179 | kfree(fmt2); | 1181 | kfree(fmt2); |
| 1180 | return err; | 1182 | return err; |
| @@ -1183,13 +1185,13 @@ done: | |||
| 1183 | /* | 1185 | /* |
| 1184 | * This function is exported. | 1186 | * This function is exported. |
| 1185 | */ | 1187 | */ |
| 1186 | int | 1188 | long |
| 1187 | v4l_compat_translate_ioctl(struct file *file, | 1189 | v4l_compat_translate_ioctl(struct file *file, |
| 1188 | int cmd, | 1190 | int cmd, |
| 1189 | void *arg, | 1191 | void *arg, |
| 1190 | v4l2_kioctl drv) | 1192 | v4l2_kioctl drv) |
| 1191 | { | 1193 | { |
| 1192 | int err; | 1194 | long err; |
| 1193 | 1195 | ||
| 1194 | switch (cmd) { | 1196 | switch (cmd) { |
| 1195 | case VIDIOCGCAP: /* capability */ | 1197 | case VIDIOCGCAP: /* capability */ |
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index c676b0b0f708..b8f2be8d5c0e 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c | |||
| @@ -797,11 +797,11 @@ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id) | |||
| 797 | } | 797 | } |
| 798 | EXPORT_SYMBOL(v4l2_ctrl_next); | 798 | EXPORT_SYMBOL(v4l2_ctrl_next); |
| 799 | 799 | ||
| 800 | int v4l2_chip_match_host(u32 match_type, u32 match_chip) | 800 | int v4l2_chip_match_host(const struct v4l2_dbg_match *match) |
| 801 | { | 801 | { |
| 802 | switch (match_type) { | 802 | switch (match->type) { |
| 803 | case V4L2_CHIP_MATCH_HOST: | 803 | case V4L2_CHIP_MATCH_HOST: |
| 804 | return match_chip == 0; | 804 | return match->addr == 0; |
| 805 | default: | 805 | default: |
| 806 | return 0; | 806 | return 0; |
| 807 | } | 807 | } |
| @@ -809,23 +809,34 @@ int v4l2_chip_match_host(u32 match_type, u32 match_chip) | |||
| 809 | EXPORT_SYMBOL(v4l2_chip_match_host); | 809 | EXPORT_SYMBOL(v4l2_chip_match_host); |
| 810 | 810 | ||
| 811 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | 811 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) |
| 812 | int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_chip) | 812 | int v4l2_chip_match_i2c_client(struct i2c_client *c, const struct v4l2_dbg_match *match) |
| 813 | { | 813 | { |
| 814 | switch (match_type) { | 814 | int len; |
| 815 | |||
| 816 | if (c == NULL || match == NULL) | ||
| 817 | return 0; | ||
| 818 | |||
| 819 | switch (match->type) { | ||
| 815 | case V4L2_CHIP_MATCH_I2C_DRIVER: | 820 | case V4L2_CHIP_MATCH_I2C_DRIVER: |
| 816 | return (c != NULL && c->driver != NULL && c->driver->id == match_chip); | 821 | if (c->driver == NULL || c->driver->driver.name == NULL) |
| 822 | return 0; | ||
| 823 | len = strlen(c->driver->driver.name); | ||
| 824 | /* legacy drivers have a ' suffix, don't try to match that */ | ||
| 825 | if (len && c->driver->driver.name[len - 1] == '\'') | ||
| 826 | len--; | ||
| 827 | return len && !strncmp(c->driver->driver.name, match->name, len); | ||
| 817 | case V4L2_CHIP_MATCH_I2C_ADDR: | 828 | case V4L2_CHIP_MATCH_I2C_ADDR: |
| 818 | return (c != NULL && c->addr == match_chip); | 829 | return c->addr == match->addr; |
| 819 | default: | 830 | default: |
| 820 | return 0; | 831 | return 0; |
| 821 | } | 832 | } |
| 822 | } | 833 | } |
| 823 | EXPORT_SYMBOL(v4l2_chip_match_i2c_client); | 834 | EXPORT_SYMBOL(v4l2_chip_match_i2c_client); |
| 824 | 835 | ||
| 825 | int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chip, | 836 | int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_dbg_chip_ident *chip, |
| 826 | u32 ident, u32 revision) | 837 | u32 ident, u32 revision) |
| 827 | { | 838 | { |
| 828 | if (!v4l2_chip_match_i2c_client(c, chip->match_type, chip->match_chip)) | 839 | if (!v4l2_chip_match_i2c_client(c, &chip->match)) |
| 829 | return 0; | 840 | return 0; |
| 830 | if (chip->ident == V4L2_IDENT_NONE) { | 841 | if (chip->ident == V4L2_IDENT_NONE) { |
| 831 | chip->ident = ident; | 842 | chip->ident = ident; |
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c index d0e1bd3ace6a..110376be5d2b 100644 --- a/drivers/media/video/v4l2-compat-ioctl32.c +++ b/drivers/media/video/v4l2-compat-ioctl32.c | |||
| @@ -222,9 +222,9 @@ static int get_microcode32(struct video_code *kp, struct video_code32 __user *up | |||
| 222 | 222 | ||
| 223 | #endif | 223 | #endif |
| 224 | 224 | ||
| 225 | static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 225 | static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 226 | { | 226 | { |
| 227 | int ret = -ENOIOCTLCMD; | 227 | long ret = -ENOIOCTLCMD; |
| 228 | 228 | ||
| 229 | if (file->f_op->unlocked_ioctl) | 229 | if (file->f_op->unlocked_ioctl) |
| 230 | ret = file->f_op->unlocked_ioctl(file, cmd, arg); | 230 | ret = file->f_op->unlocked_ioctl(file, cmd, arg); |
| @@ -705,7 +705,7 @@ static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext | |||
| 705 | #define VIDIOC_G_OUTPUT32 _IOR ('V', 46, s32) | 705 | #define VIDIOC_G_OUTPUT32 _IOR ('V', 46, s32) |
| 706 | #define VIDIOC_S_OUTPUT32 _IOWR('V', 47, s32) | 706 | #define VIDIOC_S_OUTPUT32 _IOWR('V', 47, s32) |
| 707 | 707 | ||
| 708 | static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 708 | static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 709 | { | 709 | { |
| 710 | union { | 710 | union { |
| 711 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 711 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
| @@ -726,7 +726,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg | |||
| 726 | } karg; | 726 | } karg; |
| 727 | void __user *up = compat_ptr(arg); | 727 | void __user *up = compat_ptr(arg); |
| 728 | int compatible_arg = 1; | 728 | int compatible_arg = 1; |
| 729 | int err = 0; | 729 | long err = 0; |
| 730 | 730 | ||
| 731 | /* First, convert the command. */ | 731 | /* First, convert the command. */ |
| 732 | switch (cmd) { | 732 | switch (cmd) { |
| @@ -937,9 +937,9 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg | |||
| 937 | return err; | 937 | return err; |
| 938 | } | 938 | } |
| 939 | 939 | ||
| 940 | long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) | 940 | long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) |
| 941 | { | 941 | { |
| 942 | int ret = -ENOIOCTLCMD; | 942 | long ret = -ENOIOCTLCMD; |
| 943 | 943 | ||
| 944 | if (!file->f_op->ioctl && !file->f_op->unlocked_ioctl) | 944 | if (!file->f_op->ioctl && !file->f_op->unlocked_ioctl) |
| 945 | return ret; | 945 | return ret; |
| @@ -1046,7 +1046,8 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 1046 | case VIDIOC_TRY_ENCODER_CMD: | 1046 | case VIDIOC_TRY_ENCODER_CMD: |
| 1047 | case VIDIOC_DBG_S_REGISTER: | 1047 | case VIDIOC_DBG_S_REGISTER: |
| 1048 | case VIDIOC_DBG_G_REGISTER: | 1048 | case VIDIOC_DBG_G_REGISTER: |
| 1049 | case VIDIOC_G_CHIP_IDENT: | 1049 | case VIDIOC_DBG_G_CHIP_IDENT: |
| 1050 | case VIDIOC_G_CHIP_IDENT_OLD: | ||
| 1050 | case VIDIOC_S_HW_FREQ_SEEK: | 1051 | case VIDIOC_S_HW_FREQ_SEEK: |
| 1051 | ret = do_video_ioctl(file, cmd, arg); | 1052 | ret = do_video_ioctl(file, cmd, arg); |
| 1052 | break; | 1053 | break; |
| @@ -1065,18 +1066,14 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 1065 | break; | 1066 | break; |
| 1066 | #endif | 1067 | #endif |
| 1067 | default: | 1068 | default: |
| 1068 | v4l_print_ioctl("compat_ioctl32", cmd); | 1069 | printk(KERN_WARNING "compat_ioctl32: " |
| 1069 | printk(KERN_CONT "\n"); | 1070 | "unknown ioctl '%c', dir=%d, #%d (0x%08x)\n", |
| 1071 | _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), cmd); | ||
| 1070 | break; | 1072 | break; |
| 1071 | } | 1073 | } |
| 1072 | return ret; | 1074 | return ret; |
| 1073 | } | 1075 | } |
| 1074 | #else | 1076 | EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32); |
| 1075 | long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) | ||
| 1076 | { | ||
| 1077 | return -ENOIOCTLCMD; | ||
| 1078 | } | ||
| 1079 | #endif | 1077 | #endif |
| 1080 | EXPORT_SYMBOL_GPL(v4l_compat_ioctl32); | ||
| 1081 | 1078 | ||
| 1082 | MODULE_LICENSE("GPL"); | 1079 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 7ad6711ee327..13f87c22e78d 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | 31 | ||
| 32 | #include <media/v4l2-common.h> | 32 | #include <media/v4l2-common.h> |
| 33 | #include <media/v4l2-device.h> | 33 | #include <media/v4l2-device.h> |
| 34 | #include <media/v4l2-ioctl.h> | ||
| 34 | 35 | ||
| 35 | #define VIDEO_NUM_DEVICES 256 | 36 | #define VIDEO_NUM_DEVICES 256 |
| 36 | #define VIDEO_NAME "video4linux" | 37 | #define VIDEO_NAME "video4linux" |
| @@ -182,7 +183,7 @@ static int v4l2_ioctl(struct inode *inode, struct file *filp, | |||
| 182 | return -ENOTTY; | 183 | return -ENOTTY; |
| 183 | /* Allow ioctl to continue even if the device was unregistered. | 184 | /* Allow ioctl to continue even if the device was unregistered. |
| 184 | Things like dequeueing buffers might still be useful. */ | 185 | Things like dequeueing buffers might still be useful. */ |
| 185 | return vdev->fops->ioctl(inode, filp, cmd, arg); | 186 | return vdev->fops->ioctl(filp, cmd, arg); |
| 186 | } | 187 | } |
| 187 | 188 | ||
| 188 | static long v4l2_unlocked_ioctl(struct file *filp, | 189 | static long v4l2_unlocked_ioctl(struct file *filp, |
| @@ -197,20 +198,6 @@ static long v4l2_unlocked_ioctl(struct file *filp, | |||
| 197 | return vdev->fops->unlocked_ioctl(filp, cmd, arg); | 198 | return vdev->fops->unlocked_ioctl(filp, cmd, arg); |
| 198 | } | 199 | } |
| 199 | 200 | ||
| 200 | #ifdef CONFIG_COMPAT | ||
| 201 | static long v4l2_compat_ioctl(struct file *filp, | ||
| 202 | unsigned int cmd, unsigned long arg) | ||
| 203 | { | ||
| 204 | struct video_device *vdev = video_devdata(filp); | ||
| 205 | |||
| 206 | if (!vdev->fops->compat_ioctl) | ||
| 207 | return -ENOIOCTLCMD; | ||
| 208 | /* Allow ioctl to continue even if the device was unregistered. | ||
| 209 | Things like dequeueing buffers might still be useful. */ | ||
| 210 | return vdev->fops->compat_ioctl(filp, cmd, arg); | ||
| 211 | } | ||
| 212 | #endif | ||
| 213 | |||
| 214 | static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) | 201 | static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) |
| 215 | { | 202 | { |
| 216 | struct video_device *vdev = video_devdata(filp); | 203 | struct video_device *vdev = video_devdata(filp); |
| @@ -239,7 +226,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
| 239 | /* and increase the device refcount */ | 226 | /* and increase the device refcount */ |
| 240 | video_get(vdev); | 227 | video_get(vdev); |
| 241 | mutex_unlock(&videodev_lock); | 228 | mutex_unlock(&videodev_lock); |
| 242 | ret = vdev->fops->open(inode, filp); | 229 | ret = vdev->fops->open(filp); |
| 243 | /* decrease the refcount in case of an error */ | 230 | /* decrease the refcount in case of an error */ |
| 244 | if (ret) | 231 | if (ret) |
| 245 | video_put(vdev); | 232 | video_put(vdev); |
| @@ -250,7 +237,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
| 250 | static int v4l2_release(struct inode *inode, struct file *filp) | 237 | static int v4l2_release(struct inode *inode, struct file *filp) |
| 251 | { | 238 | { |
| 252 | struct video_device *vdev = video_devdata(filp); | 239 | struct video_device *vdev = video_devdata(filp); |
| 253 | int ret = vdev->fops->release(inode, filp); | 240 | int ret = vdev->fops->release(filp); |
| 254 | 241 | ||
| 255 | /* decrease the refcount unconditionally since the release() | 242 | /* decrease the refcount unconditionally since the release() |
| 256 | return value is ignored. */ | 243 | return value is ignored. */ |
| @@ -266,7 +253,7 @@ static const struct file_operations v4l2_unlocked_fops = { | |||
| 266 | .mmap = v4l2_mmap, | 253 | .mmap = v4l2_mmap, |
| 267 | .unlocked_ioctl = v4l2_unlocked_ioctl, | 254 | .unlocked_ioctl = v4l2_unlocked_ioctl, |
| 268 | #ifdef CONFIG_COMPAT | 255 | #ifdef CONFIG_COMPAT |
| 269 | .compat_ioctl = v4l2_compat_ioctl, | 256 | .compat_ioctl = v4l2_compat_ioctl32, |
| 270 | #endif | 257 | #endif |
| 271 | .release = v4l2_release, | 258 | .release = v4l2_release, |
| 272 | .poll = v4l2_poll, | 259 | .poll = v4l2_poll, |
| @@ -281,7 +268,7 @@ static const struct file_operations v4l2_fops = { | |||
| 281 | .mmap = v4l2_mmap, | 268 | .mmap = v4l2_mmap, |
| 282 | .ioctl = v4l2_ioctl, | 269 | .ioctl = v4l2_ioctl, |
| 283 | #ifdef CONFIG_COMPAT | 270 | #ifdef CONFIG_COMPAT |
| 284 | .compat_ioctl = v4l2_compat_ioctl, | 271 | .compat_ioctl = v4l2_compat_ioctl32, |
| 285 | #endif | 272 | #endif |
| 286 | .release = v4l2_release, | 273 | .release = v4l2_release, |
| 287 | .poll = v4l2_poll, | 274 | .poll = v4l2_poll, |
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index b063381f4b3b..52d687b165e0 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c | |||
| @@ -266,7 +266,7 @@ static const char *v4l2_ioctls[] = { | |||
| 266 | [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER", | 266 | [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER", |
| 267 | [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", | 267 | [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", |
| 268 | 268 | ||
| 269 | [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT", | 269 | [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT", |
| 270 | [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", | 270 | [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", |
| 271 | #endif | 271 | #endif |
| 272 | }; | 272 | }; |
| @@ -392,14 +392,14 @@ video_fix_command(unsigned int cmd) | |||
| 392 | /* | 392 | /* |
| 393 | * Obsolete usercopy function - Should be removed soon | 393 | * Obsolete usercopy function - Should be removed soon |
| 394 | */ | 394 | */ |
| 395 | int | 395 | long |
| 396 | video_usercopy(struct file *file, unsigned int cmd, unsigned long arg, | 396 | video_usercopy(struct file *file, unsigned int cmd, unsigned long arg, |
| 397 | v4l2_kioctl func) | 397 | v4l2_kioctl func) |
| 398 | { | 398 | { |
| 399 | char sbuf[128]; | 399 | char sbuf[128]; |
| 400 | void *mbuf = NULL; | 400 | void *mbuf = NULL; |
| 401 | void *parg = NULL; | 401 | void *parg = NULL; |
| 402 | int err = -EINVAL; | 402 | long err = -EINVAL; |
| 403 | int is_ext_ctrl; | 403 | int is_ext_ctrl; |
| 404 | size_t ctrls_size = 0; | 404 | size_t ctrls_size = 0; |
| 405 | void __user *user_ptr = NULL; | 405 | void __user *user_ptr = NULL; |
| @@ -623,13 +623,13 @@ static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type) | |||
| 623 | return -EINVAL; | 623 | return -EINVAL; |
| 624 | } | 624 | } |
| 625 | 625 | ||
| 626 | static int __video_do_ioctl(struct file *file, | 626 | static long __video_do_ioctl(struct file *file, |
| 627 | unsigned int cmd, void *arg) | 627 | unsigned int cmd, void *arg) |
| 628 | { | 628 | { |
| 629 | struct video_device *vfd = video_devdata(file); | 629 | struct video_device *vfd = video_devdata(file); |
| 630 | const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; | 630 | const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; |
| 631 | void *fh = file->private_data; | 631 | void *fh = file->private_data; |
| 632 | int ret = -EINVAL; | 632 | long ret = -EINVAL; |
| 633 | 633 | ||
| 634 | if ((vfd->debug & V4L2_DEBUG_IOCTL) && | 634 | if ((vfd->debug & V4L2_DEBUG_IOCTL) && |
| 635 | !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) { | 635 | !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) { |
| @@ -1720,7 +1720,7 @@ static int __video_do_ioctl(struct file *file, | |||
| 1720 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1720 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 1721 | case VIDIOC_DBG_G_REGISTER: | 1721 | case VIDIOC_DBG_G_REGISTER: |
| 1722 | { | 1722 | { |
| 1723 | struct v4l2_register *p = arg; | 1723 | struct v4l2_dbg_register *p = arg; |
| 1724 | 1724 | ||
| 1725 | if (!capable(CAP_SYS_ADMIN)) | 1725 | if (!capable(CAP_SYS_ADMIN)) |
| 1726 | ret = -EPERM; | 1726 | ret = -EPERM; |
| @@ -1730,7 +1730,7 @@ static int __video_do_ioctl(struct file *file, | |||
| 1730 | } | 1730 | } |
| 1731 | case VIDIOC_DBG_S_REGISTER: | 1731 | case VIDIOC_DBG_S_REGISTER: |
| 1732 | { | 1732 | { |
| 1733 | struct v4l2_register *p = arg; | 1733 | struct v4l2_dbg_register *p = arg; |
| 1734 | 1734 | ||
| 1735 | if (!capable(CAP_SYS_ADMIN)) | 1735 | if (!capable(CAP_SYS_ADMIN)) |
| 1736 | ret = -EPERM; | 1736 | ret = -EPERM; |
| @@ -1739,9 +1739,9 @@ static int __video_do_ioctl(struct file *file, | |||
| 1739 | break; | 1739 | break; |
| 1740 | } | 1740 | } |
| 1741 | #endif | 1741 | #endif |
| 1742 | case VIDIOC_G_CHIP_IDENT: | 1742 | case VIDIOC_DBG_G_CHIP_IDENT: |
| 1743 | { | 1743 | { |
| 1744 | struct v4l2_chip_ident *p = arg; | 1744 | struct v4l2_dbg_chip_ident *p = arg; |
| 1745 | 1745 | ||
| 1746 | if (!ops->vidioc_g_chip_ident) | 1746 | if (!ops->vidioc_g_chip_ident) |
| 1747 | break; | 1747 | break; |
| @@ -1750,6 +1750,11 @@ static int __video_do_ioctl(struct file *file, | |||
| 1750 | dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision); | 1750 | dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision); |
| 1751 | break; | 1751 | break; |
| 1752 | } | 1752 | } |
| 1753 | case VIDIOC_G_CHIP_IDENT_OLD: | ||
| 1754 | printk(KERN_ERR "VIDIOC_G_CHIP_IDENT has been deprecated and will disappear in 2.6.30.\n"); | ||
| 1755 | printk(KERN_ERR "It is a debugging ioctl and must not be used in applications!\n"); | ||
| 1756 | return -EINVAL; | ||
| 1757 | |||
| 1753 | case VIDIOC_S_HW_FREQ_SEEK: | 1758 | case VIDIOC_S_HW_FREQ_SEEK: |
| 1754 | { | 1759 | { |
| 1755 | struct v4l2_hw_freq_seek *p = arg; | 1760 | struct v4l2_hw_freq_seek *p = arg; |
| @@ -1845,20 +1850,20 @@ static int __video_do_ioctl(struct file *file, | |||
| 1845 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { | 1850 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { |
| 1846 | if (ret < 0) { | 1851 | if (ret < 0) { |
| 1847 | v4l_print_ioctl(vfd->name, cmd); | 1852 | v4l_print_ioctl(vfd->name, cmd); |
| 1848 | printk(KERN_CONT " error %d\n", ret); | 1853 | printk(KERN_CONT " error %ld\n", ret); |
| 1849 | } | 1854 | } |
| 1850 | } | 1855 | } |
| 1851 | 1856 | ||
| 1852 | return ret; | 1857 | return ret; |
| 1853 | } | 1858 | } |
| 1854 | 1859 | ||
| 1855 | long __video_ioctl2(struct file *file, | 1860 | long video_ioctl2(struct file *file, |
| 1856 | unsigned int cmd, unsigned long arg) | 1861 | unsigned int cmd, unsigned long arg) |
| 1857 | { | 1862 | { |
| 1858 | char sbuf[128]; | 1863 | char sbuf[128]; |
| 1859 | void *mbuf = NULL; | 1864 | void *mbuf = NULL; |
| 1860 | void *parg = NULL; | 1865 | void *parg = NULL; |
| 1861 | int err = -EINVAL; | 1866 | long err = -EINVAL; |
| 1862 | int is_ext_ctrl; | 1867 | int is_ext_ctrl; |
| 1863 | size_t ctrls_size = 0; | 1868 | size_t ctrls_size = 0; |
| 1864 | void __user *user_ptr = NULL; | 1869 | void __user *user_ptr = NULL; |
| @@ -1944,11 +1949,4 @@ out: | |||
| 1944 | kfree(mbuf); | 1949 | kfree(mbuf); |
| 1945 | return err; | 1950 | return err; |
| 1946 | } | 1951 | } |
| 1947 | EXPORT_SYMBOL(__video_ioctl2); | ||
| 1948 | |||
| 1949 | int video_ioctl2(struct inode *inode, struct file *file, | ||
| 1950 | unsigned int cmd, unsigned long arg) | ||
| 1951 | { | ||
| 1952 | return __video_ioctl2(file, cmd, arg); | ||
| 1953 | } | ||
| 1954 | EXPORT_SYMBOL(video_ioctl2); | 1952 | EXPORT_SYMBOL(video_ioctl2); |
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c index e3612f29d0df..fbe9cc0d433a 100644 --- a/drivers/media/video/v4l2-subdev.c +++ b/drivers/media/video/v4l2-subdev.c | |||
| @@ -37,7 +37,7 @@ int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg) | |||
| 37 | return v4l2_subdev_call(sd, core, queryctrl, arg); | 37 | return v4l2_subdev_call(sd, core, queryctrl, arg); |
| 38 | case VIDIOC_LOG_STATUS: | 38 | case VIDIOC_LOG_STATUS: |
| 39 | return v4l2_subdev_call(sd, core, log_status); | 39 | return v4l2_subdev_call(sd, core, log_status); |
| 40 | case VIDIOC_G_CHIP_IDENT: | 40 | case VIDIOC_DBG_G_CHIP_IDENT: |
| 41 | return v4l2_subdev_call(sd, core, g_chip_ident, arg); | 41 | return v4l2_subdev_call(sd, core, g_chip_ident, arg); |
| 42 | case VIDIOC_INT_S_STANDBY: | 42 | case VIDIOC_INT_S_STANDBY: |
| 43 | return v4l2_subdev_call(sd, core, s_standby, arg ? (*(u32 *)arg) : 0); | 43 | return v4l2_subdev_call(sd, core, s_standby, arg ? (*(u32 *)arg) : 0); |
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index a72a361daade..88bf845a3d56 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c | |||
| @@ -4019,7 +4019,7 @@ out: | |||
| 4019 | 4019 | ||
| 4020 | /* File operations */ | 4020 | /* File operations */ |
| 4021 | 4021 | ||
| 4022 | static int vino_open(struct inode *inode, struct file *file) | 4022 | static int vino_open(struct file *file) |
| 4023 | { | 4023 | { |
| 4024 | struct vino_channel_settings *vcs = video_drvdata(file); | 4024 | struct vino_channel_settings *vcs = video_drvdata(file); |
| 4025 | int ret = 0; | 4025 | int ret = 0; |
| @@ -4050,7 +4050,7 @@ static int vino_open(struct inode *inode, struct file *file) | |||
| 4050 | return ret; | 4050 | return ret; |
| 4051 | } | 4051 | } |
| 4052 | 4052 | ||
| 4053 | static int vino_close(struct inode *inode, struct file *file) | 4053 | static int vino_close(struct file *file) |
| 4054 | { | 4054 | { |
| 4055 | struct vino_channel_settings *vcs = video_drvdata(file); | 4055 | struct vino_channel_settings *vcs = video_drvdata(file); |
| 4056 | dprintk("close():\n"); | 4056 | dprintk("close():\n"); |
| @@ -4237,7 +4237,7 @@ error: | |||
| 4237 | return ret; | 4237 | return ret; |
| 4238 | } | 4238 | } |
| 4239 | 4239 | ||
| 4240 | static int vino_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 4240 | static long vino_do_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 4241 | { | 4241 | { |
| 4242 | struct vino_channel_settings *vcs = video_drvdata(file); | 4242 | struct vino_channel_settings *vcs = video_drvdata(file); |
| 4243 | 4243 | ||
| @@ -4343,11 +4343,11 @@ static int vino_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 4343 | return 0; | 4343 | return 0; |
| 4344 | } | 4344 | } |
| 4345 | 4345 | ||
| 4346 | static int vino_ioctl(struct inode *inode, struct file *file, | 4346 | static long vino_ioctl(struct file *file, |
| 4347 | unsigned int cmd, unsigned long arg) | 4347 | unsigned int cmd, unsigned long arg) |
| 4348 | { | 4348 | { |
| 4349 | struct vino_channel_settings *vcs = video_drvdata(file); | 4349 | struct vino_channel_settings *vcs = video_drvdata(file); |
| 4350 | int ret; | 4350 | long ret; |
| 4351 | 4351 | ||
| 4352 | if (mutex_lock_interruptible(&vcs->mutex)) | 4352 | if (mutex_lock_interruptible(&vcs->mutex)) |
| 4353 | return -EINTR; | 4353 | return -EINTR; |
| @@ -4364,14 +4364,13 @@ static int vino_ioctl(struct inode *inode, struct file *file, | |||
| 4364 | /* __initdata */ | 4364 | /* __initdata */ |
| 4365 | static int vino_init_stage; | 4365 | static int vino_init_stage; |
| 4366 | 4366 | ||
| 4367 | static const struct file_operations vino_fops = { | 4367 | static const struct v4l2_file_operations vino_fops = { |
| 4368 | .owner = THIS_MODULE, | 4368 | .owner = THIS_MODULE, |
| 4369 | .open = vino_open, | 4369 | .open = vino_open, |
| 4370 | .release = vino_close, | 4370 | .release = vino_close, |
| 4371 | .ioctl = vino_ioctl, | 4371 | .ioctl = vino_ioctl, |
| 4372 | .mmap = vino_mmap, | 4372 | .mmap = vino_mmap, |
| 4373 | .poll = vino_poll, | 4373 | .poll = vino_poll, |
| 4374 | .llseek = no_llseek, | ||
| 4375 | }; | 4374 | }; |
| 4376 | 4375 | ||
| 4377 | static struct video_device v4l_device_template = { | 4376 | static struct video_device v4l_device_template = { |
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index e15e48f04be7..81d5aa5cf331 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
| @@ -1024,9 +1024,9 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
| 1024 | File operations for the device | 1024 | File operations for the device |
| 1025 | ------------------------------------------------------------------*/ | 1025 | ------------------------------------------------------------------*/ |
| 1026 | 1026 | ||
| 1027 | static int vivi_open(struct inode *inode, struct file *file) | 1027 | static int vivi_open(struct file *file) |
| 1028 | { | 1028 | { |
| 1029 | int minor = iminor(inode); | 1029 | int minor = video_devdata(file)->minor; |
| 1030 | struct vivi_dev *dev; | 1030 | struct vivi_dev *dev; |
| 1031 | struct vivi_fh *fh = NULL; | 1031 | struct vivi_fh *fh = NULL; |
| 1032 | int i; | 1032 | int i; |
| @@ -1127,13 +1127,13 @@ vivi_poll(struct file *file, struct poll_table_struct *wait) | |||
| 1127 | return videobuf_poll_stream(file, q, wait); | 1127 | return videobuf_poll_stream(file, q, wait); |
| 1128 | } | 1128 | } |
| 1129 | 1129 | ||
| 1130 | static int vivi_close(struct inode *inode, struct file *file) | 1130 | static int vivi_close(struct file *file) |
| 1131 | { | 1131 | { |
| 1132 | struct vivi_fh *fh = file->private_data; | 1132 | struct vivi_fh *fh = file->private_data; |
| 1133 | struct vivi_dev *dev = fh->dev; | 1133 | struct vivi_dev *dev = fh->dev; |
| 1134 | struct vivi_dmaqueue *vidq = &dev->vidq; | 1134 | struct vivi_dmaqueue *vidq = &dev->vidq; |
| 1135 | 1135 | ||
| 1136 | int minor = iminor(inode); | 1136 | int minor = video_devdata(file)->minor; |
| 1137 | 1137 | ||
| 1138 | vivi_stop_thread(vidq); | 1138 | vivi_stop_thread(vidq); |
| 1139 | videobuf_stop(&fh->vb_vidq); | 1139 | videobuf_stop(&fh->vb_vidq); |
| @@ -1195,16 +1195,14 @@ static int vivi_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 1195 | return ret; | 1195 | return ret; |
| 1196 | } | 1196 | } |
| 1197 | 1197 | ||
| 1198 | static const struct file_operations vivi_fops = { | 1198 | static const struct v4l2_file_operations vivi_fops = { |
| 1199 | .owner = THIS_MODULE, | 1199 | .owner = THIS_MODULE, |
| 1200 | .open = vivi_open, | 1200 | .open = vivi_open, |
| 1201 | .release = vivi_close, | 1201 | .release = vivi_close, |
| 1202 | .read = vivi_read, | 1202 | .read = vivi_read, |
| 1203 | .poll = vivi_poll, | 1203 | .poll = vivi_poll, |
| 1204 | .ioctl = video_ioctl2, /* V4L2 ioctl handler */ | 1204 | .ioctl = video_ioctl2, /* V4L2 ioctl handler */ |
| 1205 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1206 | .mmap = vivi_mmap, | 1205 | .mmap = vivi_mmap, |
| 1207 | .llseek = no_llseek, | ||
| 1208 | }; | 1206 | }; |
| 1209 | 1207 | ||
| 1210 | static const struct v4l2_ioctl_ops vivi_ioctl_ops = { | 1208 | static const struct v4l2_ioctl_ops vivi_ioctl_ops = { |
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c index f72b859486ad..5d73f66d9f55 100644 --- a/drivers/media/video/vp27smpx.c +++ b/drivers/media/video/vp27smpx.c | |||
| @@ -113,7 +113,7 @@ static int vp27smpx_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) | |||
| 113 | return 0; | 113 | return 0; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | static int vp27smpx_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) | 116 | static int vp27smpx_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) |
| 117 | { | 117 | { |
| 118 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 118 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 119 | 119 | ||
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index 56c570c267ea..038ff32b01b8 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c | |||
| @@ -180,19 +180,19 @@ static int w9966_i2c_wbyte(struct w9966_dev* cam, int data); | |||
| 180 | static int w9966_i2c_rbyte(struct w9966_dev* cam); | 180 | static int w9966_i2c_rbyte(struct w9966_dev* cam); |
| 181 | #endif | 181 | #endif |
| 182 | 182 | ||
| 183 | static int w9966_v4l_ioctl(struct inode *inode, struct file *file, | 183 | static long w9966_v4l_ioctl(struct file *file, |
| 184 | unsigned int cmd, unsigned long arg); | 184 | unsigned int cmd, unsigned long arg); |
| 185 | static ssize_t w9966_v4l_read(struct file *file, char __user *buf, | 185 | static ssize_t w9966_v4l_read(struct file *file, char __user *buf, |
| 186 | size_t count, loff_t *ppos); | 186 | size_t count, loff_t *ppos); |
| 187 | 187 | ||
| 188 | static int w9966_exclusive_open(struct inode *inode, struct file *file) | 188 | static int w9966_exclusive_open(struct file *file) |
| 189 | { | 189 | { |
| 190 | struct w9966_dev *cam = video_drvdata(file); | 190 | struct w9966_dev *cam = video_drvdata(file); |
| 191 | 191 | ||
| 192 | return test_and_set_bit(0, &cam->in_use) ? -EBUSY : 0; | 192 | return test_and_set_bit(0, &cam->in_use) ? -EBUSY : 0; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | static int w9966_exclusive_release(struct inode *inode, struct file *file) | 195 | static int w9966_exclusive_release(struct file *file) |
| 196 | { | 196 | { |
| 197 | struct w9966_dev *cam = video_drvdata(file); | 197 | struct w9966_dev *cam = video_drvdata(file); |
| 198 | 198 | ||
| @@ -200,16 +200,12 @@ static int w9966_exclusive_release(struct inode *inode, struct file *file) | |||
| 200 | return 0; | 200 | return 0; |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | static const struct file_operations w9966_fops = { | 203 | static const struct v4l2_file_operations w9966_fops = { |
| 204 | .owner = THIS_MODULE, | 204 | .owner = THIS_MODULE, |
| 205 | .open = w9966_exclusive_open, | 205 | .open = w9966_exclusive_open, |
| 206 | .release = w9966_exclusive_release, | 206 | .release = w9966_exclusive_release, |
| 207 | .ioctl = w9966_v4l_ioctl, | 207 | .ioctl = w9966_v4l_ioctl, |
| 208 | #ifdef CONFIG_COMPAT | ||
| 209 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 210 | #endif | ||
| 211 | .read = w9966_v4l_read, | 208 | .read = w9966_v4l_read, |
| 212 | .llseek = no_llseek, | ||
| 213 | }; | 209 | }; |
| 214 | static struct video_device w9966_template = { | 210 | static struct video_device w9966_template = { |
| 215 | .name = W9966_DRIVERNAME, | 211 | .name = W9966_DRIVERNAME, |
| @@ -727,7 +723,7 @@ static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data) | |||
| 727 | * Video4linux interfacing | 723 | * Video4linux interfacing |
| 728 | */ | 724 | */ |
| 729 | 725 | ||
| 730 | static int w9966_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 726 | static long w9966_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 731 | { | 727 | { |
| 732 | struct w9966_dev *cam = video_drvdata(file); | 728 | struct w9966_dev *cam = video_drvdata(file); |
| 733 | 729 | ||
| @@ -877,7 +873,7 @@ static int w9966_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 877 | return 0; | 873 | return 0; |
| 878 | } | 874 | } |
| 879 | 875 | ||
| 880 | static int w9966_v4l_ioctl(struct inode *inode, struct file *file, | 876 | static long w9966_v4l_ioctl(struct file *file, |
| 881 | unsigned int cmd, unsigned long arg) | 877 | unsigned int cmd, unsigned long arg) |
| 882 | { | 878 | { |
| 883 | return video_usercopy(file, cmd, arg, w9966_v4l_do_ioctl); | 879 | return video_usercopy(file, cmd, arg, w9966_v4l_do_ioctl); |
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c index 4dfb43bd1846..a3997b7d4366 100644 --- a/drivers/media/video/w9968cf.c +++ b/drivers/media/video/w9968cf.c | |||
| @@ -399,13 +399,13 @@ MODULE_PARM_DESC(specific_debug, | |||
| 399 | ****************************************************************************/ | 399 | ****************************************************************************/ |
| 400 | 400 | ||
| 401 | /* Video4linux interface */ | 401 | /* Video4linux interface */ |
| 402 | static const struct file_operations w9968cf_fops; | 402 | static const struct v4l2_file_operations w9968cf_fops; |
| 403 | static int w9968cf_open(struct inode*, struct file*); | 403 | static int w9968cf_open(struct file *); |
| 404 | static int w9968cf_release(struct inode*, struct file*); | 404 | static int w9968cf_release(struct file *); |
| 405 | static int w9968cf_mmap(struct file*, struct vm_area_struct*); | 405 | static int w9968cf_mmap(struct file *, struct vm_area_struct *); |
| 406 | static int w9968cf_ioctl(struct inode*, struct file*, unsigned, unsigned long); | 406 | static long w9968cf_ioctl(struct file *, unsigned, unsigned long); |
| 407 | static ssize_t w9968cf_read(struct file*, char __user *, size_t, loff_t*); | 407 | static ssize_t w9968cf_read(struct file *, char __user *, size_t, loff_t *); |
| 408 | static int w9968cf_v4l_ioctl(struct inode*, struct file*, unsigned int, | 408 | static long w9968cf_v4l_ioctl(struct file *, unsigned int, |
| 409 | void __user *); | 409 | void __user *); |
| 410 | 410 | ||
| 411 | /* USB-specific */ | 411 | /* USB-specific */ |
| @@ -2662,7 +2662,7 @@ static void w9968cf_release_resources(struct w9968cf_device* cam) | |||
| 2662 | * Video4Linux interface * | 2662 | * Video4Linux interface * |
| 2663 | ****************************************************************************/ | 2663 | ****************************************************************************/ |
| 2664 | 2664 | ||
| 2665 | static int w9968cf_open(struct inode* inode, struct file* filp) | 2665 | static int w9968cf_open(struct file *filp) |
| 2666 | { | 2666 | { |
| 2667 | struct w9968cf_device* cam; | 2667 | struct w9968cf_device* cam; |
| 2668 | int err; | 2668 | int err; |
| @@ -2748,7 +2748,7 @@ deallocate_memory: | |||
| 2748 | } | 2748 | } |
| 2749 | 2749 | ||
| 2750 | 2750 | ||
| 2751 | static int w9968cf_release(struct inode* inode, struct file* filp) | 2751 | static int w9968cf_release(struct file *filp) |
| 2752 | { | 2752 | { |
| 2753 | struct w9968cf_device* cam; | 2753 | struct w9968cf_device* cam; |
| 2754 | 2754 | ||
| @@ -2885,12 +2885,12 @@ static int w9968cf_mmap(struct file* filp, struct vm_area_struct *vma) | |||
| 2885 | } | 2885 | } |
| 2886 | 2886 | ||
| 2887 | 2887 | ||
| 2888 | static int | 2888 | static long |
| 2889 | w9968cf_ioctl(struct inode* inode, struct file* filp, | 2889 | w9968cf_ioctl(struct file *filp, |
| 2890 | unsigned int cmd, unsigned long arg) | 2890 | unsigned int cmd, unsigned long arg) |
| 2891 | { | 2891 | { |
| 2892 | struct w9968cf_device* cam; | 2892 | struct w9968cf_device* cam; |
| 2893 | int err; | 2893 | long err; |
| 2894 | 2894 | ||
| 2895 | cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); | 2895 | cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); |
| 2896 | 2896 | ||
| @@ -2909,15 +2909,15 @@ w9968cf_ioctl(struct inode* inode, struct file* filp, | |||
| 2909 | return -EIO; | 2909 | return -EIO; |
| 2910 | } | 2910 | } |
| 2911 | 2911 | ||
| 2912 | err = w9968cf_v4l_ioctl(inode, filp, cmd, (void __user *)arg); | 2912 | err = w9968cf_v4l_ioctl(filp, cmd, (void __user *)arg); |
| 2913 | 2913 | ||
| 2914 | mutex_unlock(&cam->fileop_mutex); | 2914 | mutex_unlock(&cam->fileop_mutex); |
| 2915 | return err; | 2915 | return err; |
| 2916 | } | 2916 | } |
| 2917 | 2917 | ||
| 2918 | 2918 | ||
| 2919 | static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, | 2919 | static long w9968cf_v4l_ioctl(struct file *filp, |
| 2920 | unsigned int cmd, void __user * arg) | 2920 | unsigned int cmd, void __user *arg) |
| 2921 | { | 2921 | { |
| 2922 | struct w9968cf_device* cam; | 2922 | struct w9968cf_device* cam; |
| 2923 | const char* v4l1_ioctls[] = { | 2923 | const char* v4l1_ioctls[] = { |
| @@ -3456,17 +3456,13 @@ ioctl_fail: | |||
| 3456 | } | 3456 | } |
| 3457 | 3457 | ||
| 3458 | 3458 | ||
| 3459 | static const struct file_operations w9968cf_fops = { | 3459 | static const struct v4l2_file_operations w9968cf_fops = { |
| 3460 | .owner = THIS_MODULE, | 3460 | .owner = THIS_MODULE, |
| 3461 | .open = w9968cf_open, | 3461 | .open = w9968cf_open, |
| 3462 | .release = w9968cf_release, | 3462 | .release = w9968cf_release, |
| 3463 | .read = w9968cf_read, | 3463 | .read = w9968cf_read, |
| 3464 | .ioctl = w9968cf_ioctl, | 3464 | .ioctl = w9968cf_ioctl, |
| 3465 | #ifdef CONFIG_COMPAT | ||
| 3466 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 3467 | #endif | ||
| 3468 | .mmap = w9968cf_mmap, | 3465 | .mmap = w9968cf_mmap, |
| 3469 | .llseek = no_llseek, | ||
| 3470 | }; | 3466 | }; |
| 3471 | 3467 | ||
| 3472 | 3468 | ||
diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c index 12a31e7a5f6d..f2864d5cd180 100644 --- a/drivers/media/video/wm8739.c +++ b/drivers/media/video/wm8739.c | |||
| @@ -233,7 +233,7 @@ static int wm8739_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) | |||
| 233 | return -EINVAL; | 233 | return -EINVAL; |
| 234 | } | 234 | } |
| 235 | 235 | ||
| 236 | static int wm8739_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) | 236 | static int wm8739_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) |
| 237 | { | 237 | { |
| 238 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 238 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 239 | 239 | ||
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c index d0220b0ec0bc..53fcd42843e0 100644 --- a/drivers/media/video/wm8775.c +++ b/drivers/media/video/wm8775.c | |||
| @@ -130,7 +130,7 @@ static int wm8775_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
| 130 | return 0; | 130 | return 0; |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | static int wm8775_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) | 133 | static int wm8775_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) |
| 134 | { | 134 | { |
| 135 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 135 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 136 | 136 | ||
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c index 9d00e6056491..96971044fc78 100644 --- a/drivers/media/video/zc0301/zc0301_core.c +++ b/drivers/media/video/zc0301/zc0301_core.c | |||
| @@ -649,7 +649,7 @@ static void zc0301_release_resources(struct kref *kref) | |||
| 649 | } | 649 | } |
| 650 | 650 | ||
| 651 | 651 | ||
| 652 | static int zc0301_open(struct inode* inode, struct file* filp) | 652 | static int zc0301_open(struct file *filp) |
| 653 | { | 653 | { |
| 654 | struct zc0301_device* cam; | 654 | struct zc0301_device* cam; |
| 655 | int err = 0; | 655 | int err = 0; |
| @@ -733,7 +733,7 @@ out: | |||
| 733 | } | 733 | } |
| 734 | 734 | ||
| 735 | 735 | ||
| 736 | static int zc0301_release(struct inode* inode, struct file* filp) | 736 | static int zc0301_release(struct file *filp) |
| 737 | { | 737 | { |
| 738 | struct zc0301_device* cam; | 738 | struct zc0301_device* cam; |
| 739 | 739 | ||
| @@ -1793,8 +1793,8 @@ zc0301_vidioc_s_parm(struct zc0301_device* cam, void __user * arg) | |||
| 1793 | } | 1793 | } |
| 1794 | 1794 | ||
| 1795 | 1795 | ||
| 1796 | static int zc0301_ioctl_v4l2(struct inode* inode, struct file* filp, | 1796 | static long zc0301_ioctl_v4l2(struct file *filp, |
| 1797 | unsigned int cmd, void __user * arg) | 1797 | unsigned int cmd, void __user *arg) |
| 1798 | { | 1798 | { |
| 1799 | struct zc0301_device *cam = video_drvdata(filp); | 1799 | struct zc0301_device *cam = video_drvdata(filp); |
| 1800 | 1800 | ||
| @@ -1888,7 +1888,7 @@ static int zc0301_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
| 1888 | } | 1888 | } |
| 1889 | 1889 | ||
| 1890 | 1890 | ||
| 1891 | static int zc0301_ioctl(struct inode* inode, struct file* filp, | 1891 | static long zc0301_ioctl(struct file *filp, |
| 1892 | unsigned int cmd, unsigned long arg) | 1892 | unsigned int cmd, unsigned long arg) |
| 1893 | { | 1893 | { |
| 1894 | struct zc0301_device *cam = video_drvdata(filp); | 1894 | struct zc0301_device *cam = video_drvdata(filp); |
| @@ -1912,7 +1912,7 @@ static int zc0301_ioctl(struct inode* inode, struct file* filp, | |||
| 1912 | 1912 | ||
| 1913 | V4LDBG(3, "zc0301", cmd); | 1913 | V4LDBG(3, "zc0301", cmd); |
| 1914 | 1914 | ||
| 1915 | err = zc0301_ioctl_v4l2(inode, filp, cmd, (void __user *)arg); | 1915 | err = zc0301_ioctl_v4l2(filp, cmd, (void __user *)arg); |
| 1916 | 1916 | ||
| 1917 | mutex_unlock(&cam->fileop_mutex); | 1917 | mutex_unlock(&cam->fileop_mutex); |
| 1918 | 1918 | ||
| @@ -1920,18 +1920,14 @@ static int zc0301_ioctl(struct inode* inode, struct file* filp, | |||
| 1920 | } | 1920 | } |
| 1921 | 1921 | ||
| 1922 | 1922 | ||
| 1923 | static const struct file_operations zc0301_fops = { | 1923 | static const struct v4l2_file_operations zc0301_fops = { |
| 1924 | .owner = THIS_MODULE, | 1924 | .owner = THIS_MODULE, |
| 1925 | .open = zc0301_open, | 1925 | .open = zc0301_open, |
| 1926 | .release = zc0301_release, | 1926 | .release = zc0301_release, |
| 1927 | .ioctl = zc0301_ioctl, | 1927 | .ioctl = zc0301_ioctl, |
| 1928 | #ifdef CONFIG_COMPAT | ||
| 1929 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 1930 | #endif | ||
| 1931 | .read = zc0301_read, | 1928 | .read = zc0301_read, |
| 1932 | .poll = zc0301_poll, | 1929 | .poll = zc0301_poll, |
| 1933 | .mmap = zc0301_mmap, | 1930 | .mmap = zc0301_mmap, |
| 1934 | .llseek = no_llseek, | ||
| 1935 | }; | 1931 | }; |
| 1936 | 1932 | ||
| 1937 | /*****************************************************************************/ | 1933 | /*****************************************************************************/ |
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index 00b97d97aeaa..b58b9dda715c 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c | |||
| @@ -1197,10 +1197,9 @@ zoran_close_end_session (struct file *file) | |||
| 1197 | */ | 1197 | */ |
| 1198 | 1198 | ||
| 1199 | static int | 1199 | static int |
| 1200 | zoran_open (struct inode *inode, | 1200 | zoran_open(struct file *file) |
| 1201 | struct file *file) | ||
| 1202 | { | 1201 | { |
| 1203 | unsigned int minor = iminor(inode); | 1202 | unsigned int minor = video_devdata(file)->minor; |
| 1204 | struct zoran *zr = NULL; | 1203 | struct zoran *zr = NULL; |
| 1205 | struct zoran_fh *fh; | 1204 | struct zoran_fh *fh; |
| 1206 | int i, res, first_open = 0, have_module_locks = 0; | 1205 | int i, res, first_open = 0, have_module_locks = 0; |
| @@ -1340,8 +1339,7 @@ open_unlock_and_return: | |||
| 1340 | } | 1339 | } |
| 1341 | 1340 | ||
| 1342 | static int | 1341 | static int |
| 1343 | zoran_close (struct inode *inode, | 1342 | zoran_close(struct file *file) |
| 1344 | struct file *file) | ||
| 1345 | { | 1343 | { |
| 1346 | struct zoran_fh *fh = file->private_data; | 1344 | struct zoran_fh *fh = file->private_data; |
| 1347 | struct zoran *zr = fh->zr; | 1345 | struct zoran *zr = fh->zr; |
| @@ -1940,7 +1938,7 @@ zoran_set_input (struct zoran *zr, | |||
| 1940 | * ioctl routine | 1938 | * ioctl routine |
| 1941 | */ | 1939 | */ |
| 1942 | 1940 | ||
| 1943 | static int zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 1941 | static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) |
| 1944 | { | 1942 | { |
| 1945 | struct zoran_fh *fh = file->private_data; | 1943 | struct zoran_fh *fh = file->private_data; |
| 1946 | struct zoran *zr = fh->zr; | 1944 | struct zoran *zr = fh->zr; |
| @@ -4191,11 +4189,10 @@ static int zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 4191 | } | 4189 | } |
| 4192 | 4190 | ||
| 4193 | 4191 | ||
| 4194 | static int | 4192 | static long |
| 4195 | zoran_ioctl (struct inode *inode, | 4193 | zoran_ioctl(struct file *file, |
| 4196 | struct file *file, | 4194 | unsigned int cmd, |
| 4197 | unsigned int cmd, | 4195 | unsigned long arg) |
| 4198 | unsigned long arg) | ||
| 4199 | { | 4196 | { |
| 4200 | return video_usercopy(file, cmd, arg, zoran_do_ioctl); | 4197 | return video_usercopy(file, cmd, arg, zoran_do_ioctl); |
| 4201 | } | 4198 | } |
| @@ -4620,15 +4617,11 @@ zoran_mmap (struct file *file, | |||
| 4620 | return 0; | 4617 | return 0; |
| 4621 | } | 4618 | } |
| 4622 | 4619 | ||
| 4623 | static const struct file_operations zoran_fops = { | 4620 | static const struct v4l2_file_operations zoran_fops = { |
| 4624 | .owner = THIS_MODULE, | 4621 | .owner = THIS_MODULE, |
| 4625 | .open = zoran_open, | 4622 | .open = zoran_open, |
| 4626 | .release = zoran_close, | 4623 | .release = zoran_close, |
| 4627 | .ioctl = zoran_ioctl, | 4624 | .ioctl = zoran_ioctl, |
| 4628 | #ifdef CONFIG_COMPAT | ||
| 4629 | .compat_ioctl = v4l_compat_ioctl32, | ||
| 4630 | #endif | ||
| 4631 | .llseek = no_llseek, | ||
| 4632 | .read = zoran_read, | 4625 | .read = zoran_read, |
| 4633 | .write = zoran_write, | 4626 | .write = zoran_write, |
| 4634 | .mmap = zoran_mmap, | 4627 | .mmap = zoran_mmap, |
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index a1d81ed44c7c..93023560f324 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c | |||
| @@ -634,7 +634,7 @@ static int zr364xx_vidioc_streamoff(struct file *file, void *priv, | |||
| 634 | 634 | ||
| 635 | 635 | ||
| 636 | /* open the camera */ | 636 | /* open the camera */ |
| 637 | static int zr364xx_open(struct inode *inode, struct file *file) | 637 | static int zr364xx_open(struct file *file) |
| 638 | { | 638 | { |
| 639 | struct video_device *vdev = video_devdata(file); | 639 | struct video_device *vdev = video_devdata(file); |
| 640 | struct zr364xx_camera *cam = video_get_drvdata(vdev); | 640 | struct zr364xx_camera *cam = video_get_drvdata(vdev); |
| @@ -688,7 +688,7 @@ out: | |||
| 688 | 688 | ||
| 689 | 689 | ||
| 690 | /* release the camera */ | 690 | /* release the camera */ |
| 691 | static int zr364xx_release(struct inode *inode, struct file *file) | 691 | static int zr364xx_release(struct file *file) |
| 692 | { | 692 | { |
| 693 | struct video_device *vdev = video_devdata(file); | 693 | struct video_device *vdev = video_devdata(file); |
| 694 | struct zr364xx_camera *cam; | 694 | struct zr364xx_camera *cam; |
| @@ -761,14 +761,13 @@ static int zr364xx_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 761 | } | 761 | } |
| 762 | 762 | ||
| 763 | 763 | ||
| 764 | static const struct file_operations zr364xx_fops = { | 764 | static const struct v4l2_file_operations zr364xx_fops = { |
| 765 | .owner = THIS_MODULE, | 765 | .owner = THIS_MODULE, |
| 766 | .open = zr364xx_open, | 766 | .open = zr364xx_open, |
| 767 | .release = zr364xx_release, | 767 | .release = zr364xx_release, |
| 768 | .read = zr364xx_read, | 768 | .read = zr364xx_read, |
| 769 | .mmap = zr364xx_mmap, | 769 | .mmap = zr364xx_mmap, |
| 770 | .ioctl = video_ioctl2, | 770 | .ioctl = video_ioctl2, |
| 771 | .llseek = no_llseek, | ||
| 772 | }; | 771 | }; |
| 773 | 772 | ||
| 774 | static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = { | 773 | static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = { |
| @@ -894,7 +893,6 @@ static void zr364xx_disconnect(struct usb_interface *intf) | |||
| 894 | { | 893 | { |
| 895 | struct zr364xx_camera *cam = usb_get_intfdata(intf); | 894 | struct zr364xx_camera *cam = usb_get_intfdata(intf); |
| 896 | usb_set_intfdata(intf, NULL); | 895 | usb_set_intfdata(intf, NULL); |
| 897 | dev_set_drvdata(&intf->dev, NULL); | ||
| 898 | dev_info(&intf->dev, DRIVER_DESC " webcam unplugged\n"); | 896 | dev_info(&intf->dev, DRIVER_DESC " webcam unplugged\n"); |
| 899 | if (cam->vdev) | 897 | if (cam->vdev) |
| 900 | video_unregister_device(cam->vdev); | 898 | video_unregister_device(cam->vdev); |
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 3d067c35185d..45b1f430685f 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
| @@ -145,7 +145,7 @@ struct mmc_blk_request { | |||
| 145 | static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) | 145 | static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) |
| 146 | { | 146 | { |
| 147 | int err; | 147 | int err; |
| 148 | u32 blocks; | 148 | __be32 blocks; |
| 149 | 149 | ||
| 150 | struct mmc_request mrq; | 150 | struct mmc_request mrq; |
| 151 | struct mmc_command cmd; | 151 | struct mmc_command cmd; |
| @@ -204,9 +204,24 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) | |||
| 204 | if (cmd.error || data.error) | 204 | if (cmd.error || data.error) |
| 205 | return (u32)-1; | 205 | return (u32)-1; |
| 206 | 206 | ||
| 207 | blocks = ntohl(blocks); | 207 | return ntohl(blocks); |
| 208 | } | ||
| 209 | |||
| 210 | static u32 get_card_status(struct mmc_card *card, struct request *req) | ||
| 211 | { | ||
| 212 | struct mmc_command cmd; | ||
| 213 | int err; | ||
| 208 | 214 | ||
| 209 | return blocks; | 215 | memset(&cmd, 0, sizeof(struct mmc_command)); |
| 216 | cmd.opcode = MMC_SEND_STATUS; | ||
| 217 | if (!mmc_host_is_spi(card->host)) | ||
| 218 | cmd.arg = card->rca << 16; | ||
| 219 | cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; | ||
| 220 | err = mmc_wait_for_cmd(card->host, &cmd, 0); | ||
| 221 | if (err) | ||
| 222 | printk(KERN_ERR "%s: error %d sending status comand", | ||
| 223 | req->rq_disk->disk_name, err); | ||
| 224 | return cmd.resp[0]; | ||
| 210 | } | 225 | } |
| 211 | 226 | ||
| 212 | static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | 227 | static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) |
| @@ -214,13 +229,13 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
| 214 | struct mmc_blk_data *md = mq->data; | 229 | struct mmc_blk_data *md = mq->data; |
| 215 | struct mmc_card *card = md->queue.card; | 230 | struct mmc_card *card = md->queue.card; |
| 216 | struct mmc_blk_request brq; | 231 | struct mmc_blk_request brq; |
| 217 | int ret = 1; | 232 | int ret = 1, disable_multi = 0; |
| 218 | 233 | ||
| 219 | mmc_claim_host(card->host); | 234 | mmc_claim_host(card->host); |
| 220 | 235 | ||
| 221 | do { | 236 | do { |
| 222 | struct mmc_command cmd; | 237 | struct mmc_command cmd; |
| 223 | u32 readcmd, writecmd; | 238 | u32 readcmd, writecmd, status = 0; |
| 224 | 239 | ||
| 225 | memset(&brq, 0, sizeof(struct mmc_blk_request)); | 240 | memset(&brq, 0, sizeof(struct mmc_blk_request)); |
| 226 | brq.mrq.cmd = &brq.cmd; | 241 | brq.mrq.cmd = &brq.cmd; |
| @@ -236,6 +251,14 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
| 236 | brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; | 251 | brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; |
| 237 | brq.data.blocks = req->nr_sectors; | 252 | brq.data.blocks = req->nr_sectors; |
| 238 | 253 | ||
| 254 | /* | ||
| 255 | * After a read error, we redo the request one sector at a time | ||
| 256 | * in order to accurately determine which sectors can be read | ||
| 257 | * successfully. | ||
| 258 | */ | ||
| 259 | if (disable_multi && brq.data.blocks > 1) | ||
| 260 | brq.data.blocks = 1; | ||
| 261 | |||
| 239 | if (brq.data.blocks > 1) { | 262 | if (brq.data.blocks > 1) { |
| 240 | /* SPI multiblock writes terminate using a special | 263 | /* SPI multiblock writes terminate using a special |
| 241 | * token, not a STOP_TRANSMISSION request. | 264 | * token, not a STOP_TRANSMISSION request. |
| @@ -264,6 +287,25 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
| 264 | brq.data.sg = mq->sg; | 287 | brq.data.sg = mq->sg; |
| 265 | brq.data.sg_len = mmc_queue_map_sg(mq); | 288 | brq.data.sg_len = mmc_queue_map_sg(mq); |
| 266 | 289 | ||
| 290 | /* | ||
| 291 | * Adjust the sg list so it is the same size as the | ||
| 292 | * request. | ||
| 293 | */ | ||
| 294 | if (brq.data.blocks != req->nr_sectors) { | ||
| 295 | int i, data_size = brq.data.blocks << 9; | ||
| 296 | struct scatterlist *sg; | ||
| 297 | |||
| 298 | for_each_sg(brq.data.sg, sg, brq.data.sg_len, i) { | ||
| 299 | data_size -= sg->length; | ||
| 300 | if (data_size <= 0) { | ||
| 301 | sg->length += data_size; | ||
| 302 | i++; | ||
| 303 | break; | ||
| 304 | } | ||
| 305 | } | ||
| 306 | brq.data.sg_len = i; | ||
| 307 | } | ||
| 308 | |||
| 267 | mmc_queue_bounce_pre(mq); | 309 | mmc_queue_bounce_pre(mq); |
| 268 | 310 | ||
| 269 | mmc_wait_for_req(card->host, &brq.mrq); | 311 | mmc_wait_for_req(card->host, &brq.mrq); |
| @@ -275,19 +317,40 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
| 275 | * until later as we need to wait for the card to leave | 317 | * until later as we need to wait for the card to leave |
| 276 | * programming mode even when things go wrong. | 318 | * programming mode even when things go wrong. |
| 277 | */ | 319 | */ |
| 320 | if (brq.cmd.error || brq.data.error || brq.stop.error) { | ||
| 321 | if (brq.data.blocks > 1 && rq_data_dir(req) == READ) { | ||
| 322 | /* Redo read one sector at a time */ | ||
| 323 | printk(KERN_WARNING "%s: retrying using single " | ||
| 324 | "block read\n", req->rq_disk->disk_name); | ||
| 325 | disable_multi = 1; | ||
| 326 | continue; | ||
| 327 | } | ||
| 328 | status = get_card_status(card, req); | ||
| 329 | } | ||
| 330 | |||
| 278 | if (brq.cmd.error) { | 331 | if (brq.cmd.error) { |
| 279 | printk(KERN_ERR "%s: error %d sending read/write command\n", | 332 | printk(KERN_ERR "%s: error %d sending read/write " |
| 280 | req->rq_disk->disk_name, brq.cmd.error); | 333 | "command, response %#x, card status %#x\n", |
| 334 | req->rq_disk->disk_name, brq.cmd.error, | ||
| 335 | brq.cmd.resp[0], status); | ||
| 281 | } | 336 | } |
| 282 | 337 | ||
| 283 | if (brq.data.error) { | 338 | if (brq.data.error) { |
| 284 | printk(KERN_ERR "%s: error %d transferring data\n", | 339 | if (brq.data.error == -ETIMEDOUT && brq.mrq.stop) |
| 285 | req->rq_disk->disk_name, brq.data.error); | 340 | /* 'Stop' response contains card status */ |
| 341 | status = brq.mrq.stop->resp[0]; | ||
| 342 | printk(KERN_ERR "%s: error %d transferring data," | ||
| 343 | " sector %u, nr %u, card status %#x\n", | ||
| 344 | req->rq_disk->disk_name, brq.data.error, | ||
| 345 | (unsigned)req->sector, | ||
| 346 | (unsigned)req->nr_sectors, status); | ||
| 286 | } | 347 | } |
| 287 | 348 | ||
| 288 | if (brq.stop.error) { | 349 | if (brq.stop.error) { |
| 289 | printk(KERN_ERR "%s: error %d sending stop command\n", | 350 | printk(KERN_ERR "%s: error %d sending stop command, " |
| 290 | req->rq_disk->disk_name, brq.stop.error); | 351 | "response %#x, card status %#x\n", |
| 352 | req->rq_disk->disk_name, brq.stop.error, | ||
| 353 | brq.stop.resp[0], status); | ||
| 291 | } | 354 | } |
| 292 | 355 | ||
| 293 | if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { | 356 | if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { |
| @@ -320,8 +383,20 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
| 320 | #endif | 383 | #endif |
| 321 | } | 384 | } |
| 322 | 385 | ||
| 323 | if (brq.cmd.error || brq.data.error || brq.stop.error) | 386 | if (brq.cmd.error || brq.stop.error || brq.data.error) { |
| 387 | if (rq_data_dir(req) == READ) { | ||
| 388 | /* | ||
| 389 | * After an error, we redo I/O one sector at a | ||
| 390 | * time, so we only reach here after trying to | ||
| 391 | * read a single sector. | ||
| 392 | */ | ||
| 393 | spin_lock_irq(&md->lock); | ||
| 394 | ret = __blk_end_request(req, -EIO, brq.data.blksz); | ||
| 395 | spin_unlock_irq(&md->lock); | ||
| 396 | continue; | ||
| 397 | } | ||
| 324 | goto cmd_err; | 398 | goto cmd_err; |
| 399 | } | ||
| 325 | 400 | ||
| 326 | /* | 401 | /* |
| 327 | * A block was successfully transferred. | 402 | * A block was successfully transferred. |
| @@ -343,25 +418,20 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
| 343 | * If the card is not SD, we can still ok written sectors | 418 | * If the card is not SD, we can still ok written sectors |
| 344 | * as reported by the controller (which might be less than | 419 | * as reported by the controller (which might be less than |
| 345 | * the real number of written sectors, but never more). | 420 | * the real number of written sectors, but never more). |
| 346 | * | ||
| 347 | * For reads we just fail the entire chunk as that should | ||
| 348 | * be safe in all cases. | ||
| 349 | */ | 421 | */ |
| 350 | if (rq_data_dir(req) != READ) { | 422 | if (mmc_card_sd(card)) { |
| 351 | if (mmc_card_sd(card)) { | 423 | u32 blocks; |
| 352 | u32 blocks; | ||
| 353 | 424 | ||
| 354 | blocks = mmc_sd_num_wr_blocks(card); | 425 | blocks = mmc_sd_num_wr_blocks(card); |
| 355 | if (blocks != (u32)-1) { | 426 | if (blocks != (u32)-1) { |
| 356 | spin_lock_irq(&md->lock); | ||
| 357 | ret = __blk_end_request(req, 0, blocks << 9); | ||
| 358 | spin_unlock_irq(&md->lock); | ||
| 359 | } | ||
| 360 | } else { | ||
| 361 | spin_lock_irq(&md->lock); | 427 | spin_lock_irq(&md->lock); |
| 362 | ret = __blk_end_request(req, 0, brq.data.bytes_xfered); | 428 | ret = __blk_end_request(req, 0, blocks << 9); |
| 363 | spin_unlock_irq(&md->lock); | 429 | spin_unlock_irq(&md->lock); |
| 364 | } | 430 | } |
| 431 | } else { | ||
| 432 | spin_lock_irq(&md->lock); | ||
| 433 | ret = __blk_end_request(req, 0, brq.data.bytes_xfered); | ||
| 434 | spin_unlock_irq(&md->lock); | ||
| 365 | } | 435 | } |
| 366 | 436 | ||
| 367 | mmc_release_host(card->host); | 437 | mmc_release_host(card->host); |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index f7284b905eb3..df6ce4a06cf3 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
| 21 | #include <linux/leds.h> | 21 | #include <linux/leds.h> |
| 22 | #include <linux/scatterlist.h> | 22 | #include <linux/scatterlist.h> |
| 23 | #include <linux/log2.h> | ||
| 23 | 24 | ||
| 24 | #include <linux/mmc/card.h> | 25 | #include <linux/mmc/card.h> |
| 25 | #include <linux/mmc/host.h> | 26 | #include <linux/mmc/host.h> |
| @@ -448,6 +449,80 @@ void mmc_set_bus_width(struct mmc_host *host, unsigned int width) | |||
| 448 | mmc_set_ios(host); | 449 | mmc_set_ios(host); |
| 449 | } | 450 | } |
| 450 | 451 | ||
| 452 | /** | ||
| 453 | * mmc_vdd_to_ocrbitnum - Convert a voltage to the OCR bit number | ||
| 454 | * @vdd: voltage (mV) | ||
| 455 | * @low_bits: prefer low bits in boundary cases | ||
| 456 | * | ||
| 457 | * This function returns the OCR bit number according to the provided @vdd | ||
| 458 | * value. If conversion is not possible a negative errno value returned. | ||
| 459 | * | ||
| 460 | * Depending on the @low_bits flag the function prefers low or high OCR bits | ||
| 461 | * on boundary voltages. For example, | ||
| 462 | * with @low_bits = true, 3300 mV translates to ilog2(MMC_VDD_32_33); | ||
| 463 | * with @low_bits = false, 3300 mV translates to ilog2(MMC_VDD_33_34); | ||
| 464 | * | ||
| 465 | * Any value in the [1951:1999] range translates to the ilog2(MMC_VDD_20_21). | ||
| 466 | */ | ||
| 467 | static int mmc_vdd_to_ocrbitnum(int vdd, bool low_bits) | ||
| 468 | { | ||
| 469 | const int max_bit = ilog2(MMC_VDD_35_36); | ||
| 470 | int bit; | ||
| 471 | |||
| 472 | if (vdd < 1650 || vdd > 3600) | ||
| 473 | return -EINVAL; | ||
| 474 | |||
| 475 | if (vdd >= 1650 && vdd <= 1950) | ||
| 476 | return ilog2(MMC_VDD_165_195); | ||
| 477 | |||
| 478 | if (low_bits) | ||
| 479 | vdd -= 1; | ||
| 480 | |||
| 481 | /* Base 2000 mV, step 100 mV, bit's base 8. */ | ||
| 482 | bit = (vdd - 2000) / 100 + 8; | ||
| 483 | if (bit > max_bit) | ||
| 484 | return max_bit; | ||
| 485 | return bit; | ||
| 486 | } | ||
| 487 | |||
| 488 | /** | ||
| 489 | * mmc_vddrange_to_ocrmask - Convert a voltage range to the OCR mask | ||
| 490 | * @vdd_min: minimum voltage value (mV) | ||
| 491 | * @vdd_max: maximum voltage value (mV) | ||
| 492 | * | ||
| 493 | * This function returns the OCR mask bits according to the provided @vdd_min | ||
| 494 | * and @vdd_max values. If conversion is not possible the function returns 0. | ||
| 495 | * | ||
| 496 | * Notes wrt boundary cases: | ||
| 497 | * This function sets the OCR bits for all boundary voltages, for example | ||
| 498 | * [3300:3400] range is translated to MMC_VDD_32_33 | MMC_VDD_33_34 | | ||
| 499 | * MMC_VDD_34_35 mask. | ||
| 500 | */ | ||
| 501 | u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max) | ||
| 502 | { | ||
| 503 | u32 mask = 0; | ||
| 504 | |||
| 505 | if (vdd_max < vdd_min) | ||
| 506 | return 0; | ||
| 507 | |||
| 508 | /* Prefer high bits for the boundary vdd_max values. */ | ||
| 509 | vdd_max = mmc_vdd_to_ocrbitnum(vdd_max, false); | ||
| 510 | if (vdd_max < 0) | ||
| 511 | return 0; | ||
| 512 | |||
| 513 | /* Prefer low bits for the boundary vdd_min values. */ | ||
| 514 | vdd_min = mmc_vdd_to_ocrbitnum(vdd_min, true); | ||
| 515 | if (vdd_min < 0) | ||
| 516 | return 0; | ||
| 517 | |||
| 518 | /* Fill the mask, from max bit to min bit. */ | ||
| 519 | while (vdd_max >= vdd_min) | ||
| 520 | mask |= 1 << vdd_max--; | ||
| 521 | |||
| 522 | return mask; | ||
| 523 | } | ||
| 524 | EXPORT_SYMBOL(mmc_vddrange_to_ocrmask); | ||
| 525 | |||
| 451 | /* | 526 | /* |
| 452 | * Mask off any voltages we don't support and select | 527 | * Mask off any voltages we don't support and select |
| 453 | * the lowest voltage | 528 | * the lowest voltage |
| @@ -467,6 +542,8 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) | |||
| 467 | host->ios.vdd = bit; | 542 | host->ios.vdd = bit; |
| 468 | mmc_set_ios(host); | 543 | mmc_set_ios(host); |
| 469 | } else { | 544 | } else { |
| 545 | pr_warning("%s: host doesn't support card's voltages\n", | ||
| 546 | mmc_hostname(host)); | ||
| 470 | ocr = 0; | 547 | ocr = 0; |
| 471 | } | 548 | } |
| 472 | 549 | ||
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index fdd7c760be8c..c232d11a7ed4 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
| @@ -434,13 +434,24 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
| 434 | * Activate wide bus (if supported). | 434 | * Activate wide bus (if supported). |
| 435 | */ | 435 | */ |
| 436 | if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && | 436 | if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && |
| 437 | (host->caps & MMC_CAP_4_BIT_DATA)) { | 437 | (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { |
| 438 | unsigned ext_csd_bit, bus_width; | ||
| 439 | |||
| 440 | if (host->caps & MMC_CAP_8_BIT_DATA) { | ||
| 441 | ext_csd_bit = EXT_CSD_BUS_WIDTH_8; | ||
| 442 | bus_width = MMC_BUS_WIDTH_8; | ||
| 443 | } else { | ||
| 444 | ext_csd_bit = EXT_CSD_BUS_WIDTH_4; | ||
| 445 | bus_width = MMC_BUS_WIDTH_4; | ||
| 446 | } | ||
| 447 | |||
| 438 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 448 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
| 439 | EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4); | 449 | EXT_CSD_BUS_WIDTH, ext_csd_bit); |
| 450 | |||
| 440 | if (err) | 451 | if (err) |
| 441 | goto free_card; | 452 | goto free_card; |
| 442 | 453 | ||
| 443 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); | 454 | mmc_set_bus_width(card->host, bus_width); |
| 444 | } | 455 | } |
| 445 | 456 | ||
| 446 | if (!oldcard) | 457 | if (!oldcard) |
| @@ -624,4 +635,3 @@ err: | |||
| 624 | 635 | ||
| 625 | return err; | 636 | return err; |
| 626 | } | 637 | } |
| 627 | |||
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index c794cc5ce442..f4853288bbb1 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile | |||
| @@ -19,6 +19,9 @@ obj-$(CONFIG_MMC_AT91) += at91_mci.o | |||
| 19 | obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o | 19 | obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o |
| 20 | obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o | 20 | obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o |
| 21 | obj-$(CONFIG_MMC_SPI) += mmc_spi.o | 21 | obj-$(CONFIG_MMC_SPI) += mmc_spi.o |
| 22 | ifeq ($(CONFIG_OF),y) | ||
| 23 | obj-$(CONFIG_MMC_SPI) += of_mmc_spi.o | ||
| 24 | endif | ||
| 22 | obj-$(CONFIG_MMC_S3C) += s3cmci.o | 25 | obj-$(CONFIG_MMC_S3C) += s3cmci.o |
| 23 | obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_cs.o | 26 | obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_cs.o |
| 24 | obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o | 27 | obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o |
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 1f8b5b36222c..e556d42cc45a 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c | |||
| @@ -1088,6 +1088,8 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
| 1088 | goto fail0; | 1088 | goto fail0; |
| 1089 | } | 1089 | } |
| 1090 | 1090 | ||
| 1091 | setup_timer(&host->timer, at91_timeout_timer, (unsigned long)host); | ||
| 1092 | |||
| 1091 | platform_set_drvdata(pdev, mmc); | 1093 | platform_set_drvdata(pdev, mmc); |
| 1092 | 1094 | ||
| 1093 | /* | 1095 | /* |
| @@ -1101,8 +1103,6 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
| 1101 | 1103 | ||
| 1102 | mmc_add_host(mmc); | 1104 | mmc_add_host(mmc); |
| 1103 | 1105 | ||
| 1104 | setup_timer(&host->timer, at91_timeout_timer, (unsigned long)host); | ||
| 1105 | |||
| 1106 | /* | 1106 | /* |
| 1107 | * monitor card insertion/removal if we can | 1107 | * monitor card insertion/removal if we can |
| 1108 | */ | 1108 | */ |
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index ad00e1632317..87e211df68ac 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c | |||
| @@ -1285,7 +1285,7 @@ static int mmc_spi_probe(struct spi_device *spi) | |||
| 1285 | /* Platform data is used to hook up things like card sensing | 1285 | /* Platform data is used to hook up things like card sensing |
| 1286 | * and power switching gpios. | 1286 | * and power switching gpios. |
| 1287 | */ | 1287 | */ |
| 1288 | host->pdata = spi->dev.platform_data; | 1288 | host->pdata = mmc_spi_get_pdata(spi); |
| 1289 | if (host->pdata) | 1289 | if (host->pdata) |
| 1290 | mmc->ocr_avail = host->pdata->ocr_mask; | 1290 | mmc->ocr_avail = host->pdata->ocr_mask; |
| 1291 | if (!mmc->ocr_avail) { | 1291 | if (!mmc->ocr_avail) { |
| @@ -1368,6 +1368,7 @@ fail_glue_init: | |||
| 1368 | 1368 | ||
| 1369 | fail_nobuf1: | 1369 | fail_nobuf1: |
| 1370 | mmc_free_host(mmc); | 1370 | mmc_free_host(mmc); |
| 1371 | mmc_spi_put_pdata(spi); | ||
| 1371 | dev_set_drvdata(&spi->dev, NULL); | 1372 | dev_set_drvdata(&spi->dev, NULL); |
| 1372 | 1373 | ||
| 1373 | nomem: | 1374 | nomem: |
| @@ -1402,6 +1403,7 @@ static int __devexit mmc_spi_remove(struct spi_device *spi) | |||
| 1402 | 1403 | ||
| 1403 | spi->max_speed_hz = mmc->f_max; | 1404 | spi->max_speed_hz = mmc->f_max; |
| 1404 | mmc_free_host(mmc); | 1405 | mmc_free_host(mmc); |
| 1406 | mmc_spi_put_pdata(spi); | ||
| 1405 | dev_set_drvdata(&spi->dev, NULL); | 1407 | dev_set_drvdata(&spi->dev, NULL); |
| 1406 | } | 1408 | } |
| 1407 | return 0; | 1409 | return 0; |
diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c new file mode 100644 index 000000000000..fb2921f8099d --- /dev/null +++ b/drivers/mmc/host/of_mmc_spi.c | |||
| @@ -0,0 +1,149 @@ | |||
| 1 | /* | ||
| 2 | * OpenFirmware bindings for the MMC-over-SPI driver | ||
| 3 | * | ||
| 4 | * Copyright (c) MontaVista Software, Inc. 2008. | ||
| 5 | * | ||
| 6 | * Author: Anton Vorontsov <avorontsov@ru.mvista.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/device.h> | ||
| 17 | #include <linux/gpio.h> | ||
| 18 | #include <linux/of.h> | ||
| 19 | #include <linux/of_gpio.h> | ||
| 20 | #include <linux/spi/spi.h> | ||
| 21 | #include <linux/spi/mmc_spi.h> | ||
| 22 | #include <linux/mmc/core.h> | ||
| 23 | #include <linux/mmc/host.h> | ||
| 24 | |||
| 25 | enum { | ||
| 26 | CD_GPIO = 0, | ||
| 27 | WP_GPIO, | ||
| 28 | NUM_GPIOS, | ||
| 29 | }; | ||
| 30 | |||
| 31 | struct of_mmc_spi { | ||
| 32 | int gpios[NUM_GPIOS]; | ||
| 33 | bool alow_gpios[NUM_GPIOS]; | ||
| 34 | struct mmc_spi_platform_data pdata; | ||
| 35 | }; | ||
| 36 | |||
| 37 | static struct of_mmc_spi *to_of_mmc_spi(struct device *dev) | ||
| 38 | { | ||
| 39 | return container_of(dev->platform_data, struct of_mmc_spi, pdata); | ||
| 40 | } | ||
| 41 | |||
| 42 | static int of_mmc_spi_read_gpio(struct device *dev, int gpio_num) | ||
| 43 | { | ||
| 44 | struct of_mmc_spi *oms = to_of_mmc_spi(dev); | ||
| 45 | bool active_low = oms->alow_gpios[gpio_num]; | ||
| 46 | bool value = gpio_get_value(oms->gpios[gpio_num]); | ||
| 47 | |||
| 48 | return active_low ^ value; | ||
| 49 | } | ||
| 50 | |||
| 51 | static int of_mmc_spi_get_cd(struct device *dev) | ||
| 52 | { | ||
| 53 | return of_mmc_spi_read_gpio(dev, CD_GPIO); | ||
| 54 | } | ||
| 55 | |||
| 56 | static int of_mmc_spi_get_ro(struct device *dev) | ||
| 57 | { | ||
| 58 | return of_mmc_spi_read_gpio(dev, WP_GPIO); | ||
| 59 | } | ||
| 60 | |||
| 61 | struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi) | ||
| 62 | { | ||
| 63 | struct device *dev = &spi->dev; | ||
| 64 | struct device_node *np = dev_archdata_get_node(&dev->archdata); | ||
| 65 | struct of_mmc_spi *oms; | ||
| 66 | const u32 *voltage_ranges; | ||
| 67 | int num_ranges; | ||
| 68 | int i; | ||
| 69 | int ret = -EINVAL; | ||
| 70 | |||
| 71 | if (dev->platform_data || !np) | ||
| 72 | return dev->platform_data; | ||
| 73 | |||
| 74 | oms = kzalloc(sizeof(*oms), GFP_KERNEL); | ||
| 75 | if (!oms) | ||
| 76 | return NULL; | ||
| 77 | |||
| 78 | voltage_ranges = of_get_property(np, "voltage-ranges", &num_ranges); | ||
| 79 | num_ranges = num_ranges / sizeof(*voltage_ranges) / 2; | ||
| 80 | if (!voltage_ranges || !num_ranges) { | ||
| 81 | dev_err(dev, "OF: voltage-ranges unspecified\n"); | ||
| 82 | goto err_ocr; | ||
| 83 | } | ||
| 84 | |||
| 85 | for (i = 0; i < num_ranges; i++) { | ||
| 86 | const int j = i * 2; | ||
| 87 | u32 mask; | ||
| 88 | |||
| 89 | mask = mmc_vddrange_to_ocrmask(voltage_ranges[j], | ||
| 90 | voltage_ranges[j + 1]); | ||
| 91 | if (!mask) { | ||
| 92 | ret = -EINVAL; | ||
| 93 | dev_err(dev, "OF: voltage-range #%d is invalid\n", i); | ||
| 94 | goto err_ocr; | ||
| 95 | } | ||
| 96 | oms->pdata.ocr_mask |= mask; | ||
| 97 | } | ||
| 98 | |||
| 99 | for (i = 0; i < ARRAY_SIZE(oms->gpios); i++) { | ||
| 100 | enum of_gpio_flags gpio_flags; | ||
| 101 | |||
| 102 | oms->gpios[i] = of_get_gpio_flags(np, i, &gpio_flags); | ||
| 103 | if (!gpio_is_valid(oms->gpios[i])) | ||
| 104 | continue; | ||
| 105 | |||
| 106 | ret = gpio_request(oms->gpios[i], dev->bus_id); | ||
| 107 | if (ret < 0) { | ||
| 108 | oms->gpios[i] = -EINVAL; | ||
| 109 | continue; | ||
| 110 | } | ||
| 111 | |||
| 112 | if (gpio_flags & OF_GPIO_ACTIVE_LOW) | ||
| 113 | oms->alow_gpios[i] = true; | ||
| 114 | } | ||
| 115 | |||
| 116 | if (gpio_is_valid(oms->gpios[CD_GPIO])) | ||
| 117 | oms->pdata.get_cd = of_mmc_spi_get_cd; | ||
| 118 | if (gpio_is_valid(oms->gpios[WP_GPIO])) | ||
| 119 | oms->pdata.get_ro = of_mmc_spi_get_ro; | ||
| 120 | |||
| 121 | /* We don't support interrupts yet, let's poll. */ | ||
| 122 | oms->pdata.caps |= MMC_CAP_NEEDS_POLL; | ||
| 123 | |||
| 124 | dev->platform_data = &oms->pdata; | ||
| 125 | return dev->platform_data; | ||
| 126 | err_ocr: | ||
| 127 | kfree(oms); | ||
| 128 | return NULL; | ||
| 129 | } | ||
| 130 | EXPORT_SYMBOL(mmc_spi_get_pdata); | ||
| 131 | |||
| 132 | void mmc_spi_put_pdata(struct spi_device *spi) | ||
| 133 | { | ||
| 134 | struct device *dev = &spi->dev; | ||
| 135 | struct device_node *np = dev_archdata_get_node(&dev->archdata); | ||
| 136 | struct of_mmc_spi *oms = to_of_mmc_spi(dev); | ||
| 137 | int i; | ||
| 138 | |||
| 139 | if (!dev->platform_data || !np) | ||
| 140 | return; | ||
| 141 | |||
| 142 | for (i = 0; i < ARRAY_SIZE(oms->gpios); i++) { | ||
| 143 | if (gpio_is_valid(oms->gpios[i])) | ||
| 144 | gpio_free(oms->gpios[i]); | ||
| 145 | } | ||
| 146 | kfree(oms); | ||
| 147 | dev->platform_data = NULL; | ||
| 148 | } | ||
| 149 | EXPORT_SYMBOL(mmc_spi_put_pdata); | ||
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index f88cc7406354..3c5483b75da4 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
| @@ -283,7 +283,7 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat) | |||
| 283 | return 0; | 283 | return 0; |
| 284 | 284 | ||
| 285 | DCSR(host->dma) = 0; | 285 | DCSR(host->dma) = 0; |
| 286 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len, | 286 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, |
| 287 | host->dma_dir); | 287 | host->dma_dir); |
| 288 | 288 | ||
| 289 | if (stat & STAT_READ_TIME_OUT) | 289 | if (stat & STAT_READ_TIME_OUT) |
diff --git a/drivers/mmc/host/ricoh_mmc.c b/drivers/mmc/host/ricoh_mmc.c index a16d7609e4ee..be9e7b32b34e 100644 --- a/drivers/mmc/host/ricoh_mmc.c +++ b/drivers/mmc/host/ricoh_mmc.c | |||
| @@ -11,9 +11,10 @@ | |||
| 11 | 11 | ||
| 12 | /* | 12 | /* |
| 13 | * This is a conceptually ridiculous driver, but it is required by the way | 13 | * This is a conceptually ridiculous driver, but it is required by the way |
| 14 | * the Ricoh multi-function R5C832 works. This chip implements firewire | 14 | * the Ricoh multi-function chips (R5CXXX) work. These chips implement |
| 15 | * and four different memory card controllers. Two of those controllers are | 15 | * the four main memory card controllers (SD, MMC, MS, xD) and one or both |
| 16 | * an SDHCI controller and a proprietary MMC controller. The linux SDHCI | 16 | * of cardbus or firewire. It happens that they implement SD and MMC |
| 17 | * support as separate controllers (and PCI functions). The linux SDHCI | ||
| 17 | * driver supports MMC cards but the chip detects MMC cards in hardware | 18 | * driver supports MMC cards but the chip detects MMC cards in hardware |
| 18 | * and directs them to the MMC controller - so the SDHCI driver never sees | 19 | * and directs them to the MMC controller - so the SDHCI driver never sees |
| 19 | * them. To get around this, we must disable the useless MMC controller. | 20 | * them. To get around this, we must disable the useless MMC controller. |
| @@ -21,8 +22,10 @@ | |||
| 21 | * a detection event occurs immediately, even if the MMC card is already | 22 | * a detection event occurs immediately, even if the MMC card is already |
| 22 | * in the reader. | 23 | * in the reader. |
| 23 | * | 24 | * |
| 24 | * The relevant registers live on the firewire function, so this is unavoidably | 25 | * It seems to be the case that the relevant PCI registers to deactivate the |
| 25 | * ugly. Such is life. | 26 | * MMC controller live on PCI function 0, which might be the cardbus controller |
| 27 | * or the firewire controller, depending on the particular chip in question. As | ||
| 28 | * such, it makes what this driver has to do unavoidably ugly. Such is life. | ||
| 26 | */ | 29 | */ |
| 27 | 30 | ||
| 28 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
| @@ -143,6 +146,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, | |||
| 143 | pci_get_device(PCI_VENDOR_ID_RICOH, | 146 | pci_get_device(PCI_VENDOR_ID_RICOH, |
| 144 | PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) { | 147 | PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) { |
| 145 | if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && | 148 | if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && |
| 149 | PCI_FUNC(fw_dev->devfn) == 0 && | ||
| 146 | pdev->bus == fw_dev->bus) { | 150 | pdev->bus == fw_dev->bus) { |
| 147 | if (ricoh_mmc_disable(fw_dev) != 0) | 151 | if (ricoh_mmc_disable(fw_dev) != 0) |
| 148 | return -ENODEV; | 152 | return -ENODEV; |
| @@ -160,6 +164,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, | |||
| 160 | (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, | 164 | (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, |
| 161 | PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) { | 165 | PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) { |
| 162 | if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && | 166 | if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && |
| 167 | PCI_FUNC(fw_dev->devfn) == 0 && | ||
| 163 | pdev->bus == fw_dev->bus) { | 168 | pdev->bus == fw_dev->bus) { |
| 164 | if (ricoh_mmc_disable(fw_dev) != 0) | 169 | if (ricoh_mmc_disable(fw_dev) != 0) |
| 165 | return -ENODEV; | 170 | return -ENODEV; |
| @@ -172,7 +177,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, | |||
| 172 | 177 | ||
| 173 | if (!ctrlfound) { | 178 | if (!ctrlfound) { |
| 174 | printk(KERN_WARNING DRIVER_NAME | 179 | printk(KERN_WARNING DRIVER_NAME |
| 175 | ": Main firewire function not found. Cannot disable controller.\n"); | 180 | ": Main Ricoh function not found. Cannot disable controller.\n"); |
| 176 | return -ENODEV; | 181 | return -ENODEV; |
| 177 | } | 182 | } |
| 178 | 183 | ||
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 9bd7026b0021..f07255cb17ee 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
| @@ -545,7 +545,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | |||
| 545 | } | 545 | } |
| 546 | 546 | ||
| 547 | addr = pci_resource_start(pdev, bar); | 547 | addr = pci_resource_start(pdev, bar); |
| 548 | host->ioaddr = ioremap_nocache(addr, pci_resource_len(pdev, bar)); | 548 | host->ioaddr = pci_ioremap_bar(pdev, bar); |
| 549 | if (!host->ioaddr) { | 549 | if (!host->ioaddr) { |
| 550 | dev_err(&pdev->dev, "failed to remap registers\n"); | 550 | dev_err(&pdev->dev, "failed to remap registers\n"); |
| 551 | goto release; | 551 | goto release; |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 4d010a984bed..6b2d1f99af67 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
| @@ -30,6 +30,11 @@ | |||
| 30 | #define DBG(f, x...) \ | 30 | #define DBG(f, x...) \ |
| 31 | pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x) | 31 | pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x) |
| 32 | 32 | ||
| 33 | #if defined(CONFIG_LEDS_CLASS) || (defined(CONFIG_LEDS_CLASS_MODULE) && \ | ||
| 34 | defined(CONFIG_MMC_SDHCI_MODULE)) | ||
| 35 | #define SDHCI_USE_LEDS_CLASS | ||
| 36 | #endif | ||
| 37 | |||
| 33 | static unsigned int debug_quirks = 0; | 38 | static unsigned int debug_quirks = 0; |
| 34 | 39 | ||
| 35 | static void sdhci_prepare_data(struct sdhci_host *, struct mmc_data *); | 40 | static void sdhci_prepare_data(struct sdhci_host *, struct mmc_data *); |
| @@ -149,7 +154,7 @@ static void sdhci_deactivate_led(struct sdhci_host *host) | |||
| 149 | writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); | 154 | writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); |
| 150 | } | 155 | } |
| 151 | 156 | ||
| 152 | #ifdef CONFIG_LEDS_CLASS | 157 | #ifdef SDHCI_USE_LEDS_CLASS |
| 153 | static void sdhci_led_control(struct led_classdev *led, | 158 | static void sdhci_led_control(struct led_classdev *led, |
| 154 | enum led_brightness brightness) | 159 | enum led_brightness brightness) |
| 155 | { | 160 | { |
| @@ -994,7 +999,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 994 | 999 | ||
| 995 | WARN_ON(host->mrq != NULL); | 1000 | WARN_ON(host->mrq != NULL); |
| 996 | 1001 | ||
| 997 | #ifndef CONFIG_LEDS_CLASS | 1002 | #ifndef SDHCI_USE_LEDS_CLASS |
| 998 | sdhci_activate_led(host); | 1003 | sdhci_activate_led(host); |
| 999 | #endif | 1004 | #endif |
| 1000 | 1005 | ||
| @@ -1201,7 +1206,7 @@ static void sdhci_tasklet_finish(unsigned long param) | |||
| 1201 | host->cmd = NULL; | 1206 | host->cmd = NULL; |
| 1202 | host->data = NULL; | 1207 | host->data = NULL; |
| 1203 | 1208 | ||
| 1204 | #ifndef CONFIG_LEDS_CLASS | 1209 | #ifndef SDHCI_USE_LEDS_CLASS |
| 1205 | sdhci_deactivate_led(host); | 1210 | sdhci_deactivate_led(host); |
| 1206 | #endif | 1211 | #endif |
| 1207 | 1212 | ||
| @@ -1717,7 +1722,7 @@ int sdhci_add_host(struct sdhci_host *host) | |||
| 1717 | sdhci_dumpregs(host); | 1722 | sdhci_dumpregs(host); |
| 1718 | #endif | 1723 | #endif |
| 1719 | 1724 | ||
| 1720 | #ifdef CONFIG_LEDS_CLASS | 1725 | #ifdef SDHCI_USE_LEDS_CLASS |
| 1721 | host->led.name = mmc_hostname(mmc); | 1726 | host->led.name = mmc_hostname(mmc); |
| 1722 | host->led.brightness = LED_OFF; | 1727 | host->led.brightness = LED_OFF; |
| 1723 | host->led.default_trigger = mmc_hostname(mmc); | 1728 | host->led.default_trigger = mmc_hostname(mmc); |
| @@ -1739,7 +1744,7 @@ int sdhci_add_host(struct sdhci_host *host) | |||
| 1739 | 1744 | ||
| 1740 | return 0; | 1745 | return 0; |
| 1741 | 1746 | ||
| 1742 | #ifdef CONFIG_LEDS_CLASS | 1747 | #ifdef SDHCI_USE_LEDS_CLASS |
| 1743 | reset: | 1748 | reset: |
| 1744 | sdhci_reset(host, SDHCI_RESET_ALL); | 1749 | sdhci_reset(host, SDHCI_RESET_ALL); |
| 1745 | free_irq(host->irq, host); | 1750 | free_irq(host->irq, host); |
| @@ -1775,7 +1780,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) | |||
| 1775 | 1780 | ||
| 1776 | mmc_remove_host(host->mmc); | 1781 | mmc_remove_host(host->mmc); |
| 1777 | 1782 | ||
| 1778 | #ifdef CONFIG_LEDS_CLASS | 1783 | #ifdef SDHCI_USE_LEDS_CLASS |
| 1779 | led_classdev_unregister(&host->led); | 1784 | led_classdev_unregister(&host->led); |
| 1780 | #endif | 1785 | #endif |
| 1781 | 1786 | ||
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 31f4b1528e76..3efba2363941 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
| @@ -220,7 +220,7 @@ struct sdhci_host { | |||
| 220 | struct mmc_host *mmc; /* MMC structure */ | 220 | struct mmc_host *mmc; /* MMC structure */ |
| 221 | u64 dma_mask; /* custom DMA mask */ | 221 | u64 dma_mask; /* custom DMA mask */ |
| 222 | 222 | ||
| 223 | #ifdef CONFIG_LEDS_CLASS | 223 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) |
| 224 | struct led_classdev led; /* LED control */ | 224 | struct led_classdev led; /* LED control */ |
| 225 | #endif | 225 | #endif |
| 226 | 226 | ||
diff --git a/drivers/mmc/host/sdricoh_cs.c b/drivers/mmc/host/sdricoh_cs.c index 1df44d966bdb..cb41e9c3ac07 100644 --- a/drivers/mmc/host/sdricoh_cs.c +++ b/drivers/mmc/host/sdricoh_cs.c | |||
| @@ -82,6 +82,8 @@ static struct pcmcia_device_id pcmcia_ids[] = { | |||
| 82 | /* vendor and device strings followed by their crc32 hashes */ | 82 | /* vendor and device strings followed by their crc32 hashes */ |
| 83 | PCMCIA_DEVICE_PROD_ID12("RICOH", "Bay1Controller", 0xd9f522ed, | 83 | PCMCIA_DEVICE_PROD_ID12("RICOH", "Bay1Controller", 0xd9f522ed, |
| 84 | 0xc3901202), | 84 | 0xc3901202), |
| 85 | PCMCIA_DEVICE_PROD_ID12("RICOH", "Bay Controller", 0xd9f522ed, | ||
| 86 | 0xace80909), | ||
| 85 | PCMCIA_DEVICE_NULL, | 87 | PCMCIA_DEVICE_NULL, |
| 86 | }; | 88 | }; |
| 87 | 89 | ||
| @@ -463,7 +465,7 @@ static int sdricoh_init_mmc(struct pci_dev *pci_dev, | |||
| 463 | 465 | ||
| 464 | err: | 466 | err: |
| 465 | if (iobase) | 467 | if (iobase) |
| 466 | iounmap(iobase); | 468 | pci_iounmap(pci_dev, iobase); |
| 467 | if (mmc) | 469 | if (mmc) |
| 468 | mmc_free_host(mmc); | 470 | mmc_free_host(mmc); |
| 469 | 471 | ||
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 95430b81ec11..6a7a61904833 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c | |||
| @@ -224,7 +224,7 @@ static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) | |||
| 224 | { | 224 | { |
| 225 | void __iomem *ctl = host->ctl; | 225 | void __iomem *ctl = host->ctl; |
| 226 | struct mmc_data *data = host->data; | 226 | struct mmc_data *data = host->data; |
| 227 | struct mmc_command *stop = data->stop; | 227 | struct mmc_command *stop; |
| 228 | 228 | ||
| 229 | host->data = NULL; | 229 | host->data = NULL; |
| 230 | 230 | ||
| @@ -232,6 +232,7 @@ static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) | |||
| 232 | pr_debug("Spurious data end IRQ\n"); | 232 | pr_debug("Spurious data end IRQ\n"); |
| 233 | return; | 233 | return; |
| 234 | } | 234 | } |
| 235 | stop = data->stop; | ||
| 235 | 236 | ||
| 236 | /* FIXME - return correct transfer count on errors */ | 237 | /* FIXME - return correct transfer count on errors */ |
| 237 | if (!data->error) | 238 | if (!data->error) |
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index c7630a228310..ba0bd3d5775b 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
| @@ -815,19 +815,20 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
| 815 | if (err) | 815 | if (err) |
| 816 | goto out_free; | 816 | goto out_free; |
| 817 | 817 | ||
| 818 | err = -ENOMEM; | ||
| 818 | ubi->peb_buf1 = vmalloc(ubi->peb_size); | 819 | ubi->peb_buf1 = vmalloc(ubi->peb_size); |
| 819 | if (!ubi->peb_buf1) | 820 | if (!ubi->peb_buf1) |
| 820 | goto out_free; | 821 | goto out_free; |
| 821 | 822 | ||
| 822 | ubi->peb_buf2 = vmalloc(ubi->peb_size); | 823 | ubi->peb_buf2 = vmalloc(ubi->peb_size); |
| 823 | if (!ubi->peb_buf2) | 824 | if (!ubi->peb_buf2) |
| 824 | goto out_free; | 825 | goto out_free; |
| 825 | 826 | ||
| 826 | #ifdef CONFIG_MTD_UBI_DEBUG | 827 | #ifdef CONFIG_MTD_UBI_DEBUG |
| 827 | mutex_init(&ubi->dbg_buf_mutex); | 828 | mutex_init(&ubi->dbg_buf_mutex); |
| 828 | ubi->dbg_peb_buf = vmalloc(ubi->peb_size); | 829 | ubi->dbg_peb_buf = vmalloc(ubi->peb_size); |
| 829 | if (!ubi->dbg_peb_buf) | 830 | if (!ubi->dbg_peb_buf) |
| 830 | goto out_free; | 831 | goto out_free; |
| 831 | #endif | 832 | #endif |
| 832 | 833 | ||
| 833 | err = attach_by_scanning(ubi); | 834 | err = attach_by_scanning(ubi); |
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index b30a0b83d7f1..98cf31ed0814 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c | |||
| @@ -721,7 +721,8 @@ static int rename_volumes(struct ubi_device *ubi, | |||
| 721 | * It seems we need to remove volume with name @re->new_name, | 721 | * It seems we need to remove volume with name @re->new_name, |
| 722 | * if it exists. | 722 | * if it exists. |
| 723 | */ | 723 | */ |
| 724 | desc = ubi_open_volume_nm(ubi->ubi_num, re->new_name, UBI_EXCLUSIVE); | 724 | desc = ubi_open_volume_nm(ubi->ubi_num, re->new_name, |
| 725 | UBI_EXCLUSIVE); | ||
| 725 | if (IS_ERR(desc)) { | 726 | if (IS_ERR(desc)) { |
| 726 | err = PTR_ERR(desc); | 727 | err = PTR_ERR(desc); |
| 727 | if (err == -ENODEV) | 728 | if (err == -ENODEV) |
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 78e914d23ece..13777e5beac9 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h | |||
| @@ -27,11 +27,11 @@ | |||
| 27 | #define dbg_err(fmt, ...) ubi_err(fmt, ##__VA_ARGS__) | 27 | #define dbg_err(fmt, ...) ubi_err(fmt, ##__VA_ARGS__) |
| 28 | 28 | ||
| 29 | #define ubi_assert(expr) do { \ | 29 | #define ubi_assert(expr) do { \ |
| 30 | if (unlikely(!(expr))) { \ | 30 | if (unlikely(!(expr))) { \ |
| 31 | printk(KERN_CRIT "UBI assert failed in %s at %u (pid %d)\n", \ | 31 | printk(KERN_CRIT "UBI assert failed in %s at %u (pid %d)\n", \ |
| 32 | __func__, __LINE__, current->pid); \ | 32 | __func__, __LINE__, current->pid); \ |
| 33 | ubi_dbg_dump_stack(); \ | 33 | ubi_dbg_dump_stack(); \ |
| 34 | } \ | 34 | } \ |
| 35 | } while (0) | 35 | } while (0) |
| 36 | 36 | ||
| 37 | #define dbg_msg(fmt, ...) \ | 37 | #define dbg_msg(fmt, ...) \ |
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index d8966bae0e0b..048a606cebde 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c | |||
| @@ -504,12 +504,9 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, | |||
| 504 | if (!vid_hdr) | 504 | if (!vid_hdr) |
| 505 | return -ENOMEM; | 505 | return -ENOMEM; |
| 506 | 506 | ||
| 507 | mutex_lock(&ubi->buf_mutex); | ||
| 508 | |||
| 509 | retry: | 507 | retry: |
| 510 | new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN); | 508 | new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN); |
| 511 | if (new_pnum < 0) { | 509 | if (new_pnum < 0) { |
| 512 | mutex_unlock(&ubi->buf_mutex); | ||
| 513 | ubi_free_vid_hdr(ubi, vid_hdr); | 510 | ubi_free_vid_hdr(ubi, vid_hdr); |
| 514 | return new_pnum; | 511 | return new_pnum; |
| 515 | } | 512 | } |
| @@ -529,20 +526,23 @@ retry: | |||
| 529 | goto write_error; | 526 | goto write_error; |
| 530 | 527 | ||
| 531 | data_size = offset + len; | 528 | data_size = offset + len; |
| 529 | mutex_lock(&ubi->buf_mutex); | ||
| 532 | memset(ubi->peb_buf1 + offset, 0xFF, len); | 530 | memset(ubi->peb_buf1 + offset, 0xFF, len); |
| 533 | 531 | ||
| 534 | /* Read everything before the area where the write failure happened */ | 532 | /* Read everything before the area where the write failure happened */ |
| 535 | if (offset > 0) { | 533 | if (offset > 0) { |
| 536 | err = ubi_io_read_data(ubi, ubi->peb_buf1, pnum, 0, offset); | 534 | err = ubi_io_read_data(ubi, ubi->peb_buf1, pnum, 0, offset); |
| 537 | if (err && err != UBI_IO_BITFLIPS) | 535 | if (err && err != UBI_IO_BITFLIPS) |
| 538 | goto out_put; | 536 | goto out_unlock; |
| 539 | } | 537 | } |
| 540 | 538 | ||
| 541 | memcpy(ubi->peb_buf1 + offset, buf, len); | 539 | memcpy(ubi->peb_buf1 + offset, buf, len); |
| 542 | 540 | ||
| 543 | err = ubi_io_write_data(ubi, ubi->peb_buf1, new_pnum, 0, data_size); | 541 | err = ubi_io_write_data(ubi, ubi->peb_buf1, new_pnum, 0, data_size); |
| 544 | if (err) | 542 | if (err) { |
| 543 | mutex_unlock(&ubi->buf_mutex); | ||
| 545 | goto write_error; | 544 | goto write_error; |
| 545 | } | ||
| 546 | 546 | ||
| 547 | mutex_unlock(&ubi->buf_mutex); | 547 | mutex_unlock(&ubi->buf_mutex); |
| 548 | ubi_free_vid_hdr(ubi, vid_hdr); | 548 | ubi_free_vid_hdr(ubi, vid_hdr); |
| @@ -553,8 +553,9 @@ retry: | |||
| 553 | ubi_msg("data was successfully recovered"); | 553 | ubi_msg("data was successfully recovered"); |
| 554 | return 0; | 554 | return 0; |
| 555 | 555 | ||
| 556 | out_put: | 556 | out_unlock: |
| 557 | mutex_unlock(&ubi->buf_mutex); | 557 | mutex_unlock(&ubi->buf_mutex); |
| 558 | out_put: | ||
| 558 | ubi_wl_put_peb(ubi, new_pnum, 1); | 559 | ubi_wl_put_peb(ubi, new_pnum, 1); |
| 559 | ubi_free_vid_hdr(ubi, vid_hdr); | 560 | ubi_free_vid_hdr(ubi, vid_hdr); |
| 560 | return err; | 561 | return err; |
| @@ -567,7 +568,6 @@ write_error: | |||
| 567 | ubi_warn("failed to write to PEB %d", new_pnum); | 568 | ubi_warn("failed to write to PEB %d", new_pnum); |
| 568 | ubi_wl_put_peb(ubi, new_pnum, 1); | 569 | ubi_wl_put_peb(ubi, new_pnum, 1); |
| 569 | if (++tries > UBI_IO_RETRIES) { | 570 | if (++tries > UBI_IO_RETRIES) { |
| 570 | mutex_unlock(&ubi->buf_mutex); | ||
| 571 | ubi_free_vid_hdr(ubi, vid_hdr); | 571 | ubi_free_vid_hdr(ubi, vid_hdr); |
| 572 | return err; | 572 | return err; |
| 573 | } | 573 | } |
| @@ -949,10 +949,14 @@ write_error: | |||
| 949 | * This function copies logical eraseblock from physical eraseblock @from to | 949 | * This function copies logical eraseblock from physical eraseblock @from to |
| 950 | * physical eraseblock @to. The @vid_hdr buffer may be changed by this | 950 | * physical eraseblock @to. The @vid_hdr buffer may be changed by this |
| 951 | * function. Returns: | 951 | * function. Returns: |
| 952 | * o %0 in case of success; | 952 | * o %0 in case of success; |
| 953 | * o %1 if the operation was canceled and should be tried later (e.g., | 953 | * o %1 if the operation was canceled because the volume is being deleted |
| 954 | * because a bit-flip was detected at the target PEB); | 954 | * or because the PEB was put meanwhile; |
| 955 | * o %2 if the volume is being deleted and this LEB should not be moved. | 955 | * o %2 if the operation was canceled because there was a write error to the |
| 956 | * target PEB; | ||
| 957 | * o %-EAGAIN if the operation was canceled because a bit-flip was detected | ||
| 958 | * in the target PEB; | ||
| 959 | * o a negative error code in case of failure. | ||
| 956 | */ | 960 | */ |
| 957 | int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | 961 | int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, |
| 958 | struct ubi_vid_hdr *vid_hdr) | 962 | struct ubi_vid_hdr *vid_hdr) |
| @@ -978,7 +982,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
| 978 | /* | 982 | /* |
| 979 | * Note, we may race with volume deletion, which means that the volume | 983 | * Note, we may race with volume deletion, which means that the volume |
| 980 | * this logical eraseblock belongs to might be being deleted. Since the | 984 | * this logical eraseblock belongs to might be being deleted. Since the |
| 981 | * volume deletion unmaps all the volume's logical eraseblocks, it will | 985 | * volume deletion un-maps all the volume's logical eraseblocks, it will |
| 982 | * be locked in 'ubi_wl_put_peb()' and wait for the WL worker to finish. | 986 | * be locked in 'ubi_wl_put_peb()' and wait for the WL worker to finish. |
| 983 | */ | 987 | */ |
| 984 | vol = ubi->volumes[idx]; | 988 | vol = ubi->volumes[idx]; |
| @@ -986,7 +990,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
| 986 | /* No need to do further work, cancel */ | 990 | /* No need to do further work, cancel */ |
| 987 | dbg_eba("volume %d is being removed, cancel", vol_id); | 991 | dbg_eba("volume %d is being removed, cancel", vol_id); |
| 988 | spin_unlock(&ubi->volumes_lock); | 992 | spin_unlock(&ubi->volumes_lock); |
| 989 | return 2; | 993 | return 1; |
| 990 | } | 994 | } |
| 991 | spin_unlock(&ubi->volumes_lock); | 995 | spin_unlock(&ubi->volumes_lock); |
| 992 | 996 | ||
| @@ -1023,7 +1027,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
| 1023 | 1027 | ||
| 1024 | /* | 1028 | /* |
| 1025 | * OK, now the LEB is locked and we can safely start moving it. Since | 1029 | * OK, now the LEB is locked and we can safely start moving it. Since |
| 1026 | * this function utilizes thie @ubi->peb1_buf buffer which is shared | 1030 | * this function utilizes the @ubi->peb1_buf buffer which is shared |
| 1027 | * with some other functions, so lock the buffer by taking the | 1031 | * with some other functions, so lock the buffer by taking the |
| 1028 | * @ubi->buf_mutex. | 1032 | * @ubi->buf_mutex. |
| 1029 | */ | 1033 | */ |
| @@ -1068,8 +1072,11 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
| 1068 | vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); | 1072 | vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); |
| 1069 | 1073 | ||
| 1070 | err = ubi_io_write_vid_hdr(ubi, to, vid_hdr); | 1074 | err = ubi_io_write_vid_hdr(ubi, to, vid_hdr); |
| 1071 | if (err) | 1075 | if (err) { |
| 1076 | if (err == -EIO) | ||
| 1077 | err = 2; | ||
| 1072 | goto out_unlock_buf; | 1078 | goto out_unlock_buf; |
| 1079 | } | ||
| 1073 | 1080 | ||
| 1074 | cond_resched(); | 1081 | cond_resched(); |
| 1075 | 1082 | ||
| @@ -1079,14 +1086,17 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
| 1079 | if (err != UBI_IO_BITFLIPS) | 1086 | if (err != UBI_IO_BITFLIPS) |
| 1080 | ubi_warn("cannot read VID header back from PEB %d", to); | 1087 | ubi_warn("cannot read VID header back from PEB %d", to); |
| 1081 | else | 1088 | else |
| 1082 | err = 1; | 1089 | err = -EAGAIN; |
| 1083 | goto out_unlock_buf; | 1090 | goto out_unlock_buf; |
| 1084 | } | 1091 | } |
| 1085 | 1092 | ||
| 1086 | if (data_size > 0) { | 1093 | if (data_size > 0) { |
| 1087 | err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size); | 1094 | err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size); |
| 1088 | if (err) | 1095 | if (err) { |
| 1096 | if (err == -EIO) | ||
| 1097 | err = 2; | ||
| 1089 | goto out_unlock_buf; | 1098 | goto out_unlock_buf; |
| 1099 | } | ||
| 1090 | 1100 | ||
| 1091 | cond_resched(); | 1101 | cond_resched(); |
| 1092 | 1102 | ||
| @@ -1101,15 +1111,16 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
| 1101 | ubi_warn("cannot read data back from PEB %d", | 1111 | ubi_warn("cannot read data back from PEB %d", |
| 1102 | to); | 1112 | to); |
| 1103 | else | 1113 | else |
| 1104 | err = 1; | 1114 | err = -EAGAIN; |
| 1105 | goto out_unlock_buf; | 1115 | goto out_unlock_buf; |
| 1106 | } | 1116 | } |
| 1107 | 1117 | ||
| 1108 | cond_resched(); | 1118 | cond_resched(); |
| 1109 | 1119 | ||
| 1110 | if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) { | 1120 | if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) { |
| 1111 | ubi_warn("read data back from PEB %d - it is different", | 1121 | ubi_warn("read data back from PEB %d and it is " |
| 1112 | to); | 1122 | "different", to); |
| 1123 | err = -EINVAL; | ||
| 1113 | goto out_unlock_buf; | 1124 | goto out_unlock_buf; |
| 1114 | } | 1125 | } |
| 1115 | } | 1126 | } |
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 2fb64be44f1b..a74118c05745 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c | |||
| @@ -637,8 +637,6 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, | |||
| 637 | 637 | ||
| 638 | dbg_io("read EC header from PEB %d", pnum); | 638 | dbg_io("read EC header from PEB %d", pnum); |
| 639 | ubi_assert(pnum >= 0 && pnum < ubi->peb_count); | 639 | ubi_assert(pnum >= 0 && pnum < ubi->peb_count); |
| 640 | if (UBI_IO_DEBUG) | ||
| 641 | verbose = 1; | ||
| 642 | 640 | ||
| 643 | err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE); | 641 | err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE); |
| 644 | if (err) { | 642 | if (err) { |
| @@ -685,6 +683,9 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, | |||
| 685 | if (verbose) | 683 | if (verbose) |
| 686 | ubi_warn("no EC header found at PEB %d, " | 684 | ubi_warn("no EC header found at PEB %d, " |
| 687 | "only 0xFF bytes", pnum); | 685 | "only 0xFF bytes", pnum); |
| 686 | else if (UBI_IO_DEBUG) | ||
| 687 | dbg_msg("no EC header found at PEB %d, " | ||
| 688 | "only 0xFF bytes", pnum); | ||
| 688 | return UBI_IO_PEB_EMPTY; | 689 | return UBI_IO_PEB_EMPTY; |
| 689 | } | 690 | } |
| 690 | 691 | ||
| @@ -696,7 +697,9 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, | |||
| 696 | ubi_warn("bad magic number at PEB %d: %08x instead of " | 697 | ubi_warn("bad magic number at PEB %d: %08x instead of " |
| 697 | "%08x", pnum, magic, UBI_EC_HDR_MAGIC); | 698 | "%08x", pnum, magic, UBI_EC_HDR_MAGIC); |
| 698 | ubi_dbg_dump_ec_hdr(ec_hdr); | 699 | ubi_dbg_dump_ec_hdr(ec_hdr); |
| 699 | } | 700 | } else if (UBI_IO_DEBUG) |
| 701 | dbg_msg("bad magic number at PEB %d: %08x instead of " | ||
| 702 | "%08x", pnum, magic, UBI_EC_HDR_MAGIC); | ||
| 700 | return UBI_IO_BAD_EC_HDR; | 703 | return UBI_IO_BAD_EC_HDR; |
| 701 | } | 704 | } |
| 702 | 705 | ||
| @@ -708,7 +711,9 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, | |||
| 708 | ubi_warn("bad EC header CRC at PEB %d, calculated " | 711 | ubi_warn("bad EC header CRC at PEB %d, calculated " |
| 709 | "%#08x, read %#08x", pnum, crc, hdr_crc); | 712 | "%#08x, read %#08x", pnum, crc, hdr_crc); |
| 710 | ubi_dbg_dump_ec_hdr(ec_hdr); | 713 | ubi_dbg_dump_ec_hdr(ec_hdr); |
| 711 | } | 714 | } else if (UBI_IO_DEBUG) |
| 715 | dbg_msg("bad EC header CRC at PEB %d, calculated " | ||
| 716 | "%#08x, read %#08x", pnum, crc, hdr_crc); | ||
| 712 | return UBI_IO_BAD_EC_HDR; | 717 | return UBI_IO_BAD_EC_HDR; |
| 713 | } | 718 | } |
| 714 | 719 | ||
| @@ -912,8 +917,6 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, | |||
| 912 | 917 | ||
| 913 | dbg_io("read VID header from PEB %d", pnum); | 918 | dbg_io("read VID header from PEB %d", pnum); |
| 914 | ubi_assert(pnum >= 0 && pnum < ubi->peb_count); | 919 | ubi_assert(pnum >= 0 && pnum < ubi->peb_count); |
| 915 | if (UBI_IO_DEBUG) | ||
| 916 | verbose = 1; | ||
| 917 | 920 | ||
| 918 | p = (char *)vid_hdr - ubi->vid_hdr_shift; | 921 | p = (char *)vid_hdr - ubi->vid_hdr_shift; |
| 919 | err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset, | 922 | err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset, |
| @@ -960,6 +963,9 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, | |||
| 960 | if (verbose) | 963 | if (verbose) |
| 961 | ubi_warn("no VID header found at PEB %d, " | 964 | ubi_warn("no VID header found at PEB %d, " |
| 962 | "only 0xFF bytes", pnum); | 965 | "only 0xFF bytes", pnum); |
| 966 | else if (UBI_IO_DEBUG) | ||
| 967 | dbg_msg("no VID header found at PEB %d, " | ||
| 968 | "only 0xFF bytes", pnum); | ||
| 963 | return UBI_IO_PEB_FREE; | 969 | return UBI_IO_PEB_FREE; |
| 964 | } | 970 | } |
| 965 | 971 | ||
| @@ -971,7 +977,9 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, | |||
| 971 | ubi_warn("bad magic number at PEB %d: %08x instead of " | 977 | ubi_warn("bad magic number at PEB %d: %08x instead of " |
| 972 | "%08x", pnum, magic, UBI_VID_HDR_MAGIC); | 978 | "%08x", pnum, magic, UBI_VID_HDR_MAGIC); |
| 973 | ubi_dbg_dump_vid_hdr(vid_hdr); | 979 | ubi_dbg_dump_vid_hdr(vid_hdr); |
| 974 | } | 980 | } else if (UBI_IO_DEBUG) |
| 981 | dbg_msg("bad magic number at PEB %d: %08x instead of " | ||
| 982 | "%08x", pnum, magic, UBI_VID_HDR_MAGIC); | ||
| 975 | return UBI_IO_BAD_VID_HDR; | 983 | return UBI_IO_BAD_VID_HDR; |
| 976 | } | 984 | } |
| 977 | 985 | ||
| @@ -983,7 +991,9 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, | |||
| 983 | ubi_warn("bad CRC at PEB %d, calculated %#08x, " | 991 | ubi_warn("bad CRC at PEB %d, calculated %#08x, " |
| 984 | "read %#08x", pnum, crc, hdr_crc); | 992 | "read %#08x", pnum, crc, hdr_crc); |
| 985 | ubi_dbg_dump_vid_hdr(vid_hdr); | 993 | ubi_dbg_dump_vid_hdr(vid_hdr); |
| 986 | } | 994 | } else if (UBI_IO_DEBUG) |
| 995 | dbg_msg("bad CRC at PEB %d, calculated %#08x, " | ||
| 996 | "read %#08x", pnum, crc, hdr_crc); | ||
| 987 | return UBI_IO_BAD_VID_HDR; | 997 | return UBI_IO_BAD_VID_HDR; |
| 988 | } | 998 | } |
| 989 | 999 | ||
| @@ -1024,7 +1034,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, | |||
| 1024 | 1034 | ||
| 1025 | err = paranoid_check_peb_ec_hdr(ubi, pnum); | 1035 | err = paranoid_check_peb_ec_hdr(ubi, pnum); |
| 1026 | if (err) | 1036 | if (err) |
| 1027 | return err > 0 ? -EINVAL: err; | 1037 | return err > 0 ? -EINVAL : err; |
| 1028 | 1038 | ||
| 1029 | vid_hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC); | 1039 | vid_hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC); |
| 1030 | vid_hdr->version = UBI_VERSION; | 1040 | vid_hdr->version = UBI_VERSION; |
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 1c3fa18c26a7..4a8ec485c91d 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
| @@ -74,6 +74,13 @@ | |||
| 74 | #define UBI_IO_RETRIES 3 | 74 | #define UBI_IO_RETRIES 3 |
| 75 | 75 | ||
| 76 | /* | 76 | /* |
| 77 | * Length of the protection queue. The length is effectively equivalent to the | ||
| 78 | * number of (global) erase cycles PEBs are protected from the wear-leveling | ||
| 79 | * worker. | ||
| 80 | */ | ||
| 81 | #define UBI_PROT_QUEUE_LEN 10 | ||
| 82 | |||
| 83 | /* | ||
| 77 | * Error codes returned by the I/O sub-system. | 84 | * Error codes returned by the I/O sub-system. |
| 78 | * | 85 | * |
| 79 | * UBI_IO_PEB_EMPTY: the physical eraseblock is empty, i.e. it contains only | 86 | * UBI_IO_PEB_EMPTY: the physical eraseblock is empty, i.e. it contains only |
| @@ -95,7 +102,8 @@ enum { | |||
| 95 | 102 | ||
| 96 | /** | 103 | /** |
| 97 | * struct ubi_wl_entry - wear-leveling entry. | 104 | * struct ubi_wl_entry - wear-leveling entry. |
| 98 | * @rb: link in the corresponding RB-tree | 105 | * @u.rb: link in the corresponding (free/used) RB-tree |
| 106 | * @u.list: link in the protection queue | ||
| 99 | * @ec: erase counter | 107 | * @ec: erase counter |
| 100 | * @pnum: physical eraseblock number | 108 | * @pnum: physical eraseblock number |
| 101 | * | 109 | * |
| @@ -104,7 +112,10 @@ enum { | |||
| 104 | * RB-trees. See WL sub-system for details. | 112 | * RB-trees. See WL sub-system for details. |
| 105 | */ | 113 | */ |
| 106 | struct ubi_wl_entry { | 114 | struct ubi_wl_entry { |
| 107 | struct rb_node rb; | 115 | union { |
| 116 | struct rb_node rb; | ||
| 117 | struct list_head list; | ||
| 118 | } u; | ||
| 108 | int ec; | 119 | int ec; |
| 109 | int pnum; | 120 | int pnum; |
| 110 | }; | 121 | }; |
| @@ -288,7 +299,7 @@ struct ubi_wl_entry; | |||
| 288 | * @beb_rsvd_level: normal level of PEBs reserved for bad PEB handling | 299 | * @beb_rsvd_level: normal level of PEBs reserved for bad PEB handling |
| 289 | * | 300 | * |
| 290 | * @autoresize_vol_id: ID of the volume which has to be auto-resized at the end | 301 | * @autoresize_vol_id: ID of the volume which has to be auto-resized at the end |
| 291 | * of UBI ititializetion | 302 | * of UBI initialization |
| 292 | * @vtbl_slots: how many slots are available in the volume table | 303 | * @vtbl_slots: how many slots are available in the volume table |
| 293 | * @vtbl_size: size of the volume table in bytes | 304 | * @vtbl_size: size of the volume table in bytes |
| 294 | * @vtbl: in-RAM volume table copy | 305 | * @vtbl: in-RAM volume table copy |
| @@ -306,18 +317,17 @@ struct ubi_wl_entry; | |||
| 306 | * @used: RB-tree of used physical eraseblocks | 317 | * @used: RB-tree of used physical eraseblocks |
| 307 | * @free: RB-tree of free physical eraseblocks | 318 | * @free: RB-tree of free physical eraseblocks |
| 308 | * @scrub: RB-tree of physical eraseblocks which need scrubbing | 319 | * @scrub: RB-tree of physical eraseblocks which need scrubbing |
| 309 | * @prot: protection trees | 320 | * @pq: protection queue (contain physical eraseblocks which are temporarily |
| 310 | * @prot.pnum: protection tree indexed by physical eraseblock numbers | 321 | * protected from the wear-leveling worker) |
| 311 | * @prot.aec: protection tree indexed by absolute erase counter value | 322 | * @pq_head: protection queue head |
| 312 | * @wl_lock: protects the @used, @free, @prot, @lookuptbl, @abs_ec, @move_from, | 323 | * @wl_lock: protects the @used, @free, @pq, @pq_head, @lookuptbl, @move_from, |
| 313 | * @move_to, @move_to_put @erase_pending, @wl_scheduled, and @works | 324 | * @move_to, @move_to_put @erase_pending, @wl_scheduled and @works |
| 314 | * fields | 325 | * fields |
| 315 | * @move_mutex: serializes eraseblock moves | 326 | * @move_mutex: serializes eraseblock moves |
| 316 | * @work_sem: sycnhronizes the WL worker with use tasks | 327 | * @work_sem: synchronizes the WL worker with use tasks |
| 317 | * @wl_scheduled: non-zero if the wear-leveling was scheduled | 328 | * @wl_scheduled: non-zero if the wear-leveling was scheduled |
| 318 | * @lookuptbl: a table to quickly find a &struct ubi_wl_entry object for any | 329 | * @lookuptbl: a table to quickly find a &struct ubi_wl_entry object for any |
| 319 | * physical eraseblock | 330 | * physical eraseblock |
| 320 | * @abs_ec: absolute erase counter | ||
| 321 | * @move_from: physical eraseblock from where the data is being moved | 331 | * @move_from: physical eraseblock from where the data is being moved |
| 322 | * @move_to: physical eraseblock where the data is being moved to | 332 | * @move_to: physical eraseblock where the data is being moved to |
| 323 | * @move_to_put: if the "to" PEB was put | 333 | * @move_to_put: if the "to" PEB was put |
| @@ -351,11 +361,11 @@ struct ubi_wl_entry; | |||
| 351 | * | 361 | * |
| 352 | * @peb_buf1: a buffer of PEB size used for different purposes | 362 | * @peb_buf1: a buffer of PEB size used for different purposes |
| 353 | * @peb_buf2: another buffer of PEB size used for different purposes | 363 | * @peb_buf2: another buffer of PEB size used for different purposes |
| 354 | * @buf_mutex: proptects @peb_buf1 and @peb_buf2 | 364 | * @buf_mutex: protects @peb_buf1 and @peb_buf2 |
| 355 | * @ckvol_mutex: serializes static volume checking when opening | 365 | * @ckvol_mutex: serializes static volume checking when opening |
| 356 | * @mult_mutex: serializes operations on multiple volumes, like re-nameing | 366 | * @mult_mutex: serializes operations on multiple volumes, like re-naming |
| 357 | * @dbg_peb_buf: buffer of PEB size used for debugging | 367 | * @dbg_peb_buf: buffer of PEB size used for debugging |
| 358 | * @dbg_buf_mutex: proptects @dbg_peb_buf | 368 | * @dbg_buf_mutex: protects @dbg_peb_buf |
| 359 | */ | 369 | */ |
| 360 | struct ubi_device { | 370 | struct ubi_device { |
| 361 | struct cdev cdev; | 371 | struct cdev cdev; |
| @@ -392,16 +402,13 @@ struct ubi_device { | |||
| 392 | struct rb_root used; | 402 | struct rb_root used; |
| 393 | struct rb_root free; | 403 | struct rb_root free; |
| 394 | struct rb_root scrub; | 404 | struct rb_root scrub; |
| 395 | struct { | 405 | struct list_head pq[UBI_PROT_QUEUE_LEN]; |
| 396 | struct rb_root pnum; | 406 | int pq_head; |
| 397 | struct rb_root aec; | ||
| 398 | } prot; | ||
| 399 | spinlock_t wl_lock; | 407 | spinlock_t wl_lock; |
| 400 | struct mutex move_mutex; | 408 | struct mutex move_mutex; |
| 401 | struct rw_semaphore work_sem; | 409 | struct rw_semaphore work_sem; |
| 402 | int wl_scheduled; | 410 | int wl_scheduled; |
| 403 | struct ubi_wl_entry **lookuptbl; | 411 | struct ubi_wl_entry **lookuptbl; |
| 404 | unsigned long long abs_ec; | ||
| 405 | struct ubi_wl_entry *move_from; | 412 | struct ubi_wl_entry *move_from; |
| 406 | struct ubi_wl_entry *move_to; | 413 | struct ubi_wl_entry *move_to; |
| 407 | int move_to_put; | 414 | int move_to_put; |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index dcb6dac1dc54..14901cb82c18 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * UBI wear-leveling sub-system. | 22 | * UBI wear-leveling sub-system. |
| 23 | * | 23 | * |
| 24 | * This sub-system is responsible for wear-leveling. It works in terms of | 24 | * This sub-system is responsible for wear-leveling. It works in terms of |
| 25 | * physical* eraseblocks and erase counters and knows nothing about logical | 25 | * physical eraseblocks and erase counters and knows nothing about logical |
| 26 | * eraseblocks, volumes, etc. From this sub-system's perspective all physical | 26 | * eraseblocks, volumes, etc. From this sub-system's perspective all physical |
| 27 | * eraseblocks are of two types - used and free. Used physical eraseblocks are | 27 | * eraseblocks are of two types - used and free. Used physical eraseblocks are |
| 28 | * those that were "get" by the 'ubi_wl_get_peb()' function, and free physical | 28 | * those that were "get" by the 'ubi_wl_get_peb()' function, and free physical |
| @@ -55,8 +55,39 @@ | |||
| 55 | * | 55 | * |
| 56 | * As it was said, for the UBI sub-system all physical eraseblocks are either | 56 | * As it was said, for the UBI sub-system all physical eraseblocks are either |
| 57 | * "free" or "used". Free eraseblock are kept in the @wl->free RB-tree, while | 57 | * "free" or "used". Free eraseblock are kept in the @wl->free RB-tree, while |
| 58 | * used eraseblocks are kept in a set of different RB-trees: @wl->used, | 58 | * used eraseblocks are kept in @wl->used or @wl->scrub RB-trees, or |
| 59 | * @wl->prot.pnum, @wl->prot.aec, and @wl->scrub. | 59 | * (temporarily) in the @wl->pq queue. |
| 60 | * | ||
| 61 | * When the WL sub-system returns a physical eraseblock, the physical | ||
| 62 | * eraseblock is protected from being moved for some "time". For this reason, | ||
| 63 | * the physical eraseblock is not directly moved from the @wl->free tree to the | ||
| 64 | * @wl->used tree. There is a protection queue in between where this | ||
| 65 | * physical eraseblock is temporarily stored (@wl->pq). | ||
| 66 | * | ||
| 67 | * All this protection stuff is needed because: | ||
| 68 | * o we don't want to move physical eraseblocks just after we have given them | ||
| 69 | * to the user; instead, we first want to let users fill them up with data; | ||
| 70 | * | ||
| 71 | * o there is a chance that the user will put the physical eraseblock very | ||
| 72 | * soon, so it makes sense not to move it for some time, but wait; this is | ||
| 73 | * especially important in case of "short term" physical eraseblocks. | ||
| 74 | * | ||
| 75 | * Physical eraseblocks stay protected only for limited time. But the "time" is | ||
| 76 | * measured in erase cycles in this case. This is implemented with help of the | ||
| 77 | * protection queue. Eraseblocks are put to the tail of this queue when they | ||
| 78 | * are returned by the 'ubi_wl_get_peb()', and eraseblocks are removed from the | ||
| 79 | * head of the queue on each erase operation (for any eraseblock). So the | ||
| 80 | * length of the queue defines how may (global) erase cycles PEBs are protected. | ||
| 81 | * | ||
| 82 | * To put it differently, each physical eraseblock has 2 main states: free and | ||
| 83 | * used. The former state corresponds to the @wl->free tree. The latter state | ||
| 84 | * is split up on several sub-states: | ||
| 85 | * o the WL movement is allowed (@wl->used tree); | ||
| 86 | * o the WL movement is temporarily prohibited (@wl->pq queue); | ||
| 87 | * o scrubbing is needed (@wl->scrub tree). | ||
| 88 | * | ||
| 89 | * Depending on the sub-state, wear-leveling entries of the used physical | ||
| 90 | * eraseblocks may be kept in one of those structures. | ||
| 60 | * | 91 | * |
| 61 | * Note, in this implementation, we keep a small in-RAM object for each physical | 92 | * Note, in this implementation, we keep a small in-RAM object for each physical |
| 62 | * eraseblock. This is surely not a scalable solution. But it appears to be good | 93 | * eraseblock. This is surely not a scalable solution. But it appears to be good |
| @@ -70,9 +101,6 @@ | |||
| 70 | * target PEB, we pick a PEB with the highest EC if our PEB is "old" and we | 101 | * target PEB, we pick a PEB with the highest EC if our PEB is "old" and we |
| 71 | * pick target PEB with an average EC if our PEB is not very "old". This is a | 102 | * pick target PEB with an average EC if our PEB is not very "old". This is a |
| 72 | * room for future re-works of the WL sub-system. | 103 | * room for future re-works of the WL sub-system. |
| 73 | * | ||
| 74 | * Note: the stuff with protection trees looks too complex and is difficult to | ||
| 75 | * understand. Should be fixed. | ||
| 76 | */ | 104 | */ |
| 77 | 105 | ||
| 78 | #include <linux/slab.h> | 106 | #include <linux/slab.h> |
| @@ -85,14 +113,6 @@ | |||
| 85 | #define WL_RESERVED_PEBS 1 | 113 | #define WL_RESERVED_PEBS 1 |
| 86 | 114 | ||
| 87 | /* | 115 | /* |
| 88 | * How many erase cycles are short term, unknown, and long term physical | ||
| 89 | * eraseblocks protected. | ||
| 90 | */ | ||
| 91 | #define ST_PROTECTION 16 | ||
| 92 | #define U_PROTECTION 10 | ||
| 93 | #define LT_PROTECTION 4 | ||
| 94 | |||
| 95 | /* | ||
| 96 | * Maximum difference between two erase counters. If this threshold is | 116 | * Maximum difference between two erase counters. If this threshold is |
| 97 | * exceeded, the WL sub-system starts moving data from used physical | 117 | * exceeded, the WL sub-system starts moving data from used physical |
| 98 | * eraseblocks with low erase counter to free physical eraseblocks with high | 118 | * eraseblocks with low erase counter to free physical eraseblocks with high |
| @@ -120,64 +140,9 @@ | |||
| 120 | #define WL_MAX_FAILURES 32 | 140 | #define WL_MAX_FAILURES 32 |
| 121 | 141 | ||
| 122 | /** | 142 | /** |
| 123 | * struct ubi_wl_prot_entry - PEB protection entry. | ||
| 124 | * @rb_pnum: link in the @wl->prot.pnum RB-tree | ||
| 125 | * @rb_aec: link in the @wl->prot.aec RB-tree | ||
| 126 | * @abs_ec: the absolute erase counter value when the protection ends | ||
| 127 | * @e: the wear-leveling entry of the physical eraseblock under protection | ||
| 128 | * | ||
| 129 | * When the WL sub-system returns a physical eraseblock, the physical | ||
| 130 | * eraseblock is protected from being moved for some "time". For this reason, | ||
| 131 | * the physical eraseblock is not directly moved from the @wl->free tree to the | ||
| 132 | * @wl->used tree. There is one more tree in between where this physical | ||
| 133 | * eraseblock is temporarily stored (@wl->prot). | ||
| 134 | * | ||
| 135 | * All this protection stuff is needed because: | ||
| 136 | * o we don't want to move physical eraseblocks just after we have given them | ||
| 137 | * to the user; instead, we first want to let users fill them up with data; | ||
| 138 | * | ||
| 139 | * o there is a chance that the user will put the physical eraseblock very | ||
| 140 | * soon, so it makes sense not to move it for some time, but wait; this is | ||
| 141 | * especially important in case of "short term" physical eraseblocks. | ||
| 142 | * | ||
| 143 | * Physical eraseblocks stay protected only for limited time. But the "time" is | ||
| 144 | * measured in erase cycles in this case. This is implemented with help of the | ||
| 145 | * absolute erase counter (@wl->abs_ec). When it reaches certain value, the | ||
| 146 | * physical eraseblocks are moved from the protection trees (@wl->prot.*) to | ||
| 147 | * the @wl->used tree. | ||
| 148 | * | ||
| 149 | * Protected physical eraseblocks are searched by physical eraseblock number | ||
| 150 | * (when they are put) and by the absolute erase counter (to check if it is | ||
| 151 | * time to move them to the @wl->used tree). So there are actually 2 RB-trees | ||
| 152 | * storing the protected physical eraseblocks: @wl->prot.pnum and | ||
| 153 | * @wl->prot.aec. They are referred to as the "protection" trees. The | ||
| 154 | * first one is indexed by the physical eraseblock number. The second one is | ||
| 155 | * indexed by the absolute erase counter. Both trees store | ||
| 156 | * &struct ubi_wl_prot_entry objects. | ||
| 157 | * | ||
| 158 | * Each physical eraseblock has 2 main states: free and used. The former state | ||
| 159 | * corresponds to the @wl->free tree. The latter state is split up on several | ||
| 160 | * sub-states: | ||
| 161 | * o the WL movement is allowed (@wl->used tree); | ||
| 162 | * o the WL movement is temporarily prohibited (@wl->prot.pnum and | ||
| 163 | * @wl->prot.aec trees); | ||
| 164 | * o scrubbing is needed (@wl->scrub tree). | ||
| 165 | * | ||
| 166 | * Depending on the sub-state, wear-leveling entries of the used physical | ||
| 167 | * eraseblocks may be kept in one of those trees. | ||
| 168 | */ | ||
| 169 | struct ubi_wl_prot_entry { | ||
| 170 | struct rb_node rb_pnum; | ||
| 171 | struct rb_node rb_aec; | ||
| 172 | unsigned long long abs_ec; | ||
| 173 | struct ubi_wl_entry *e; | ||
| 174 | }; | ||
| 175 | |||
| 176 | /** | ||
| 177 | * struct ubi_work - UBI work description data structure. | 143 | * struct ubi_work - UBI work description data structure. |
| 178 | * @list: a link in the list of pending works | 144 | * @list: a link in the list of pending works |
| 179 | * @func: worker function | 145 | * @func: worker function |
| 180 | * @priv: private data of the worker function | ||
| 181 | * @e: physical eraseblock to erase | 146 | * @e: physical eraseblock to erase |
| 182 | * @torture: if the physical eraseblock has to be tortured | 147 | * @torture: if the physical eraseblock has to be tortured |
| 183 | * | 148 | * |
| @@ -198,9 +163,11 @@ struct ubi_work { | |||
| 198 | static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec); | 163 | static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec); |
| 199 | static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, | 164 | static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, |
| 200 | struct rb_root *root); | 165 | struct rb_root *root); |
| 166 | static int paranoid_check_in_pq(struct ubi_device *ubi, struct ubi_wl_entry *e); | ||
| 201 | #else | 167 | #else |
| 202 | #define paranoid_check_ec(ubi, pnum, ec) 0 | 168 | #define paranoid_check_ec(ubi, pnum, ec) 0 |
| 203 | #define paranoid_check_in_wl_tree(e, root) | 169 | #define paranoid_check_in_wl_tree(e, root) |
| 170 | #define paranoid_check_in_pq(ubi, e) 0 | ||
| 204 | #endif | 171 | #endif |
| 205 | 172 | ||
| 206 | /** | 173 | /** |
| @@ -220,7 +187,7 @@ static void wl_tree_add(struct ubi_wl_entry *e, struct rb_root *root) | |||
| 220 | struct ubi_wl_entry *e1; | 187 | struct ubi_wl_entry *e1; |
| 221 | 188 | ||
| 222 | parent = *p; | 189 | parent = *p; |
| 223 | e1 = rb_entry(parent, struct ubi_wl_entry, rb); | 190 | e1 = rb_entry(parent, struct ubi_wl_entry, u.rb); |
| 224 | 191 | ||
| 225 | if (e->ec < e1->ec) | 192 | if (e->ec < e1->ec) |
| 226 | p = &(*p)->rb_left; | 193 | p = &(*p)->rb_left; |
| @@ -235,8 +202,8 @@ static void wl_tree_add(struct ubi_wl_entry *e, struct rb_root *root) | |||
| 235 | } | 202 | } |
| 236 | } | 203 | } |
| 237 | 204 | ||
| 238 | rb_link_node(&e->rb, parent, p); | 205 | rb_link_node(&e->u.rb, parent, p); |
| 239 | rb_insert_color(&e->rb, root); | 206 | rb_insert_color(&e->u.rb, root); |
| 240 | } | 207 | } |
| 241 | 208 | ||
| 242 | /** | 209 | /** |
| @@ -331,7 +298,7 @@ static int in_wl_tree(struct ubi_wl_entry *e, struct rb_root *root) | |||
| 331 | while (p) { | 298 | while (p) { |
| 332 | struct ubi_wl_entry *e1; | 299 | struct ubi_wl_entry *e1; |
| 333 | 300 | ||
| 334 | e1 = rb_entry(p, struct ubi_wl_entry, rb); | 301 | e1 = rb_entry(p, struct ubi_wl_entry, u.rb); |
| 335 | 302 | ||
| 336 | if (e->pnum == e1->pnum) { | 303 | if (e->pnum == e1->pnum) { |
| 337 | ubi_assert(e == e1); | 304 | ubi_assert(e == e1); |
| @@ -355,50 +322,24 @@ static int in_wl_tree(struct ubi_wl_entry *e, struct rb_root *root) | |||
| 355 | } | 322 | } |
| 356 | 323 | ||
| 357 | /** | 324 | /** |
| 358 | * prot_tree_add - add physical eraseblock to protection trees. | 325 | * prot_queue_add - add physical eraseblock to the protection queue. |
| 359 | * @ubi: UBI device description object | 326 | * @ubi: UBI device description object |
| 360 | * @e: the physical eraseblock to add | 327 | * @e: the physical eraseblock to add |
| 361 | * @pe: protection entry object to use | ||
| 362 | * @abs_ec: absolute erase counter value when this physical eraseblock has | ||
| 363 | * to be removed from the protection trees. | ||
| 364 | * | 328 | * |
| 365 | * @wl->lock has to be locked. | 329 | * This function adds @e to the tail of the protection queue @ubi->pq, where |
| 330 | * @e will stay for %UBI_PROT_QUEUE_LEN erase operations and will be | ||
| 331 | * temporarily protected from the wear-leveling worker. Note, @wl->lock has to | ||
| 332 | * be locked. | ||
| 366 | */ | 333 | */ |
| 367 | static void prot_tree_add(struct ubi_device *ubi, struct ubi_wl_entry *e, | 334 | static void prot_queue_add(struct ubi_device *ubi, struct ubi_wl_entry *e) |
| 368 | struct ubi_wl_prot_entry *pe, int abs_ec) | ||
| 369 | { | 335 | { |
| 370 | struct rb_node **p, *parent = NULL; | 336 | int pq_tail = ubi->pq_head - 1; |
| 371 | struct ubi_wl_prot_entry *pe1; | ||
| 372 | |||
| 373 | pe->e = e; | ||
| 374 | pe->abs_ec = ubi->abs_ec + abs_ec; | ||
| 375 | |||
| 376 | p = &ubi->prot.pnum.rb_node; | ||
| 377 | while (*p) { | ||
| 378 | parent = *p; | ||
| 379 | pe1 = rb_entry(parent, struct ubi_wl_prot_entry, rb_pnum); | ||
| 380 | |||
| 381 | if (e->pnum < pe1->e->pnum) | ||
| 382 | p = &(*p)->rb_left; | ||
| 383 | else | ||
| 384 | p = &(*p)->rb_right; | ||
| 385 | } | ||
| 386 | rb_link_node(&pe->rb_pnum, parent, p); | ||
| 387 | rb_insert_color(&pe->rb_pnum, &ubi->prot.pnum); | ||
| 388 | |||
| 389 | p = &ubi->prot.aec.rb_node; | ||
| 390 | parent = NULL; | ||
| 391 | while (*p) { | ||
| 392 | parent = *p; | ||
| 393 | pe1 = rb_entry(parent, struct ubi_wl_prot_entry, rb_aec); | ||
| 394 | 337 | ||
| 395 | if (pe->abs_ec < pe1->abs_ec) | 338 | if (pq_tail < 0) |
| 396 | p = &(*p)->rb_left; | 339 | pq_tail = UBI_PROT_QUEUE_LEN - 1; |
| 397 | else | 340 | ubi_assert(pq_tail >= 0 && pq_tail < UBI_PROT_QUEUE_LEN); |
| 398 | p = &(*p)->rb_right; | 341 | list_add_tail(&e->u.list, &ubi->pq[pq_tail]); |
| 399 | } | 342 | dbg_wl("added PEB %d EC %d to the protection queue", e->pnum, e->ec); |
| 400 | rb_link_node(&pe->rb_aec, parent, p); | ||
| 401 | rb_insert_color(&pe->rb_aec, &ubi->prot.aec); | ||
| 402 | } | 343 | } |
| 403 | 344 | ||
| 404 | /** | 345 | /** |
| @@ -414,14 +355,14 @@ static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int max) | |||
| 414 | struct rb_node *p; | 355 | struct rb_node *p; |
| 415 | struct ubi_wl_entry *e; | 356 | struct ubi_wl_entry *e; |
| 416 | 357 | ||
| 417 | e = rb_entry(rb_first(root), struct ubi_wl_entry, rb); | 358 | e = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb); |
| 418 | max += e->ec; | 359 | max += e->ec; |
| 419 | 360 | ||
| 420 | p = root->rb_node; | 361 | p = root->rb_node; |
| 421 | while (p) { | 362 | while (p) { |
| 422 | struct ubi_wl_entry *e1; | 363 | struct ubi_wl_entry *e1; |
| 423 | 364 | ||
| 424 | e1 = rb_entry(p, struct ubi_wl_entry, rb); | 365 | e1 = rb_entry(p, struct ubi_wl_entry, u.rb); |
| 425 | if (e1->ec >= max) | 366 | if (e1->ec >= max) |
| 426 | p = p->rb_left; | 367 | p = p->rb_left; |
| 427 | else { | 368 | else { |
| @@ -443,17 +384,12 @@ static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int max) | |||
| 443 | */ | 384 | */ |
| 444 | int ubi_wl_get_peb(struct ubi_device *ubi, int dtype) | 385 | int ubi_wl_get_peb(struct ubi_device *ubi, int dtype) |
| 445 | { | 386 | { |
| 446 | int err, protect, medium_ec; | 387 | int err, medium_ec; |
| 447 | struct ubi_wl_entry *e, *first, *last; | 388 | struct ubi_wl_entry *e, *first, *last; |
| 448 | struct ubi_wl_prot_entry *pe; | ||
| 449 | 389 | ||
| 450 | ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM || | 390 | ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM || |
| 451 | dtype == UBI_UNKNOWN); | 391 | dtype == UBI_UNKNOWN); |
| 452 | 392 | ||
| 453 | pe = kmalloc(sizeof(struct ubi_wl_prot_entry), GFP_NOFS); | ||
| 454 | if (!pe) | ||
| 455 | return -ENOMEM; | ||
| 456 | |||
| 457 | retry: | 393 | retry: |
| 458 | spin_lock(&ubi->wl_lock); | 394 | spin_lock(&ubi->wl_lock); |
| 459 | if (!ubi->free.rb_node) { | 395 | if (!ubi->free.rb_node) { |
| @@ -461,16 +397,13 @@ retry: | |||
| 461 | ubi_assert(list_empty(&ubi->works)); | 397 | ubi_assert(list_empty(&ubi->works)); |
| 462 | ubi_err("no free eraseblocks"); | 398 | ubi_err("no free eraseblocks"); |
| 463 | spin_unlock(&ubi->wl_lock); | 399 | spin_unlock(&ubi->wl_lock); |
| 464 | kfree(pe); | ||
| 465 | return -ENOSPC; | 400 | return -ENOSPC; |
| 466 | } | 401 | } |
| 467 | spin_unlock(&ubi->wl_lock); | 402 | spin_unlock(&ubi->wl_lock); |
| 468 | 403 | ||
| 469 | err = produce_free_peb(ubi); | 404 | err = produce_free_peb(ubi); |
| 470 | if (err < 0) { | 405 | if (err < 0) |
| 471 | kfree(pe); | ||
| 472 | return err; | 406 | return err; |
| 473 | } | ||
| 474 | goto retry; | 407 | goto retry; |
| 475 | } | 408 | } |
| 476 | 409 | ||
| @@ -483,7 +416,6 @@ retry: | |||
| 483 | * %WL_FREE_MAX_DIFF. | 416 | * %WL_FREE_MAX_DIFF. |
| 484 | */ | 417 | */ |
| 485 | e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); | 418 | e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); |
| 486 | protect = LT_PROTECTION; | ||
| 487 | break; | 419 | break; |
| 488 | case UBI_UNKNOWN: | 420 | case UBI_UNKNOWN: |
| 489 | /* | 421 | /* |
| @@ -492,81 +424,63 @@ retry: | |||
| 492 | * eraseblock with erase counter greater or equivalent than the | 424 | * eraseblock with erase counter greater or equivalent than the |
| 493 | * lowest erase counter plus %WL_FREE_MAX_DIFF. | 425 | * lowest erase counter plus %WL_FREE_MAX_DIFF. |
| 494 | */ | 426 | */ |
| 495 | first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, rb); | 427 | first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, |
| 496 | last = rb_entry(rb_last(&ubi->free), struct ubi_wl_entry, rb); | 428 | u.rb); |
| 429 | last = rb_entry(rb_last(&ubi->free), struct ubi_wl_entry, u.rb); | ||
| 497 | 430 | ||
| 498 | if (last->ec - first->ec < WL_FREE_MAX_DIFF) | 431 | if (last->ec - first->ec < WL_FREE_MAX_DIFF) |
| 499 | e = rb_entry(ubi->free.rb_node, | 432 | e = rb_entry(ubi->free.rb_node, |
| 500 | struct ubi_wl_entry, rb); | 433 | struct ubi_wl_entry, u.rb); |
| 501 | else { | 434 | else { |
| 502 | medium_ec = (first->ec + WL_FREE_MAX_DIFF)/2; | 435 | medium_ec = (first->ec + WL_FREE_MAX_DIFF)/2; |
| 503 | e = find_wl_entry(&ubi->free, medium_ec); | 436 | e = find_wl_entry(&ubi->free, medium_ec); |
| 504 | } | 437 | } |
| 505 | protect = U_PROTECTION; | ||
| 506 | break; | 438 | break; |
| 507 | case UBI_SHORTTERM: | 439 | case UBI_SHORTTERM: |
| 508 | /* | 440 | /* |
| 509 | * For short term data we pick a physical eraseblock with the | 441 | * For short term data we pick a physical eraseblock with the |
| 510 | * lowest erase counter as we expect it will be erased soon. | 442 | * lowest erase counter as we expect it will be erased soon. |
| 511 | */ | 443 | */ |
| 512 | e = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, rb); | 444 | e = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, u.rb); |
| 513 | protect = ST_PROTECTION; | ||
| 514 | break; | 445 | break; |
| 515 | default: | 446 | default: |
| 516 | protect = 0; | ||
| 517 | e = NULL; | ||
| 518 | BUG(); | 447 | BUG(); |
| 519 | } | 448 | } |
| 520 | 449 | ||
| 450 | paranoid_check_in_wl_tree(e, &ubi->free); | ||
| 451 | |||
| 521 | /* | 452 | /* |
| 522 | * Move the physical eraseblock to the protection trees where it will | 453 | * Move the physical eraseblock to the protection queue where it will |
| 523 | * be protected from being moved for some time. | 454 | * be protected from being moved for some time. |
| 524 | */ | 455 | */ |
| 525 | paranoid_check_in_wl_tree(e, &ubi->free); | 456 | rb_erase(&e->u.rb, &ubi->free); |
| 526 | rb_erase(&e->rb, &ubi->free); | 457 | dbg_wl("PEB %d EC %d", e->pnum, e->ec); |
| 527 | prot_tree_add(ubi, e, pe, protect); | 458 | prot_queue_add(ubi, e); |
| 528 | |||
| 529 | dbg_wl("PEB %d EC %d, protection %d", e->pnum, e->ec, protect); | ||
| 530 | spin_unlock(&ubi->wl_lock); | 459 | spin_unlock(&ubi->wl_lock); |
| 531 | |||
| 532 | return e->pnum; | 460 | return e->pnum; |
| 533 | } | 461 | } |
| 534 | 462 | ||
| 535 | /** | 463 | /** |
| 536 | * prot_tree_del - remove a physical eraseblock from the protection trees | 464 | * prot_queue_del - remove a physical eraseblock from the protection queue. |
| 537 | * @ubi: UBI device description object | 465 | * @ubi: UBI device description object |
| 538 | * @pnum: the physical eraseblock to remove | 466 | * @pnum: the physical eraseblock to remove |
| 539 | * | 467 | * |
| 540 | * This function returns PEB @pnum from the protection trees and returns zero | 468 | * This function deletes PEB @pnum from the protection queue and returns zero |
| 541 | * in case of success and %-ENODEV if the PEB was not found in the protection | 469 | * in case of success and %-ENODEV if the PEB was not found. |
| 542 | * trees. | ||
| 543 | */ | 470 | */ |
| 544 | static int prot_tree_del(struct ubi_device *ubi, int pnum) | 471 | static int prot_queue_del(struct ubi_device *ubi, int pnum) |
| 545 | { | 472 | { |
| 546 | struct rb_node *p; | 473 | struct ubi_wl_entry *e; |
| 547 | struct ubi_wl_prot_entry *pe = NULL; | ||
| 548 | |||
| 549 | p = ubi->prot.pnum.rb_node; | ||
| 550 | while (p) { | ||
| 551 | |||
| 552 | pe = rb_entry(p, struct ubi_wl_prot_entry, rb_pnum); | ||
| 553 | |||
| 554 | if (pnum == pe->e->pnum) | ||
| 555 | goto found; | ||
| 556 | 474 | ||
| 557 | if (pnum < pe->e->pnum) | 475 | e = ubi->lookuptbl[pnum]; |
| 558 | p = p->rb_left; | 476 | if (!e) |
| 559 | else | 477 | return -ENODEV; |
| 560 | p = p->rb_right; | ||
| 561 | } | ||
| 562 | 478 | ||
| 563 | return -ENODEV; | 479 | if (paranoid_check_in_pq(ubi, e)) |
| 480 | return -ENODEV; | ||
| 564 | 481 | ||
| 565 | found: | 482 | list_del(&e->u.list); |
| 566 | ubi_assert(pe->e->pnum == pnum); | 483 | dbg_wl("deleted PEB %d from the protection queue", e->pnum); |
| 567 | rb_erase(&pe->rb_aec, &ubi->prot.aec); | ||
| 568 | rb_erase(&pe->rb_pnum, &ubi->prot.pnum); | ||
| 569 | kfree(pe); | ||
| 570 | return 0; | 484 | return 0; |
| 571 | } | 485 | } |
| 572 | 486 | ||
| @@ -632,47 +546,47 @@ out_free: | |||
| 632 | } | 546 | } |
| 633 | 547 | ||
| 634 | /** | 548 | /** |
| 635 | * check_protection_over - check if it is time to stop protecting some PEBs. | 549 | * serve_prot_queue - check if it is time to stop protecting PEBs. |
| 636 | * @ubi: UBI device description object | 550 | * @ubi: UBI device description object |
| 637 | * | 551 | * |
| 638 | * This function is called after each erase operation, when the absolute erase | 552 | * This function is called after each erase operation and removes PEBs from the |
| 639 | * counter is incremented, to check if some physical eraseblock have not to be | 553 | * tail of the protection queue. These PEBs have been protected for long enough |
| 640 | * protected any longer. These physical eraseblocks are moved from the | 554 | * and should be moved to the used tree. |
| 641 | * protection trees to the used tree. | ||
| 642 | */ | 555 | */ |
| 643 | static void check_protection_over(struct ubi_device *ubi) | 556 | static void serve_prot_queue(struct ubi_device *ubi) |
| 644 | { | 557 | { |
| 645 | struct ubi_wl_prot_entry *pe; | 558 | struct ubi_wl_entry *e, *tmp; |
| 559 | int count; | ||
| 646 | 560 | ||
| 647 | /* | 561 | /* |
| 648 | * There may be several protected physical eraseblock to remove, | 562 | * There may be several protected physical eraseblock to remove, |
| 649 | * process them all. | 563 | * process them all. |
| 650 | */ | 564 | */ |
| 651 | while (1) { | 565 | repeat: |
| 652 | spin_lock(&ubi->wl_lock); | 566 | count = 0; |
| 653 | if (!ubi->prot.aec.rb_node) { | 567 | spin_lock(&ubi->wl_lock); |
| 654 | spin_unlock(&ubi->wl_lock); | 568 | list_for_each_entry_safe(e, tmp, &ubi->pq[ubi->pq_head], u.list) { |
| 655 | break; | 569 | dbg_wl("PEB %d EC %d protection over, move to used tree", |
| 656 | } | 570 | e->pnum, e->ec); |
| 657 | |||
| 658 | pe = rb_entry(rb_first(&ubi->prot.aec), | ||
| 659 | struct ubi_wl_prot_entry, rb_aec); | ||
| 660 | 571 | ||
| 661 | if (pe->abs_ec > ubi->abs_ec) { | 572 | list_del(&e->u.list); |
| 573 | wl_tree_add(e, &ubi->used); | ||
| 574 | if (count++ > 32) { | ||
| 575 | /* | ||
| 576 | * Let's be nice and avoid holding the spinlock for | ||
| 577 | * too long. | ||
| 578 | */ | ||
| 662 | spin_unlock(&ubi->wl_lock); | 579 | spin_unlock(&ubi->wl_lock); |
| 663 | break; | 580 | cond_resched(); |
| 581 | goto repeat; | ||
| 664 | } | 582 | } |
| 665 | |||
| 666 | dbg_wl("PEB %d protection over, abs_ec %llu, PEB abs_ec %llu", | ||
| 667 | pe->e->pnum, ubi->abs_ec, pe->abs_ec); | ||
| 668 | rb_erase(&pe->rb_aec, &ubi->prot.aec); | ||
| 669 | rb_erase(&pe->rb_pnum, &ubi->prot.pnum); | ||
| 670 | wl_tree_add(pe->e, &ubi->used); | ||
| 671 | spin_unlock(&ubi->wl_lock); | ||
| 672 | |||
| 673 | kfree(pe); | ||
| 674 | cond_resched(); | ||
| 675 | } | 583 | } |
| 584 | |||
| 585 | ubi->pq_head += 1; | ||
| 586 | if (ubi->pq_head == UBI_PROT_QUEUE_LEN) | ||
| 587 | ubi->pq_head = 0; | ||
| 588 | ubi_assert(ubi->pq_head >= 0 && ubi->pq_head < UBI_PROT_QUEUE_LEN); | ||
| 589 | spin_unlock(&ubi->wl_lock); | ||
| 676 | } | 590 | } |
| 677 | 591 | ||
| 678 | /** | 592 | /** |
| @@ -680,8 +594,8 @@ static void check_protection_over(struct ubi_device *ubi) | |||
| 680 | * @ubi: UBI device description object | 594 | * @ubi: UBI device description object |
| 681 | * @wrk: the work to schedule | 595 | * @wrk: the work to schedule |
| 682 | * | 596 | * |
| 683 | * This function enqueues a work defined by @wrk to the tail of the pending | 597 | * This function adds a work defined by @wrk to the tail of the pending works |
| 684 | * works list. | 598 | * list. |
| 685 | */ | 599 | */ |
| 686 | static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk) | 600 | static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk) |
| 687 | { | 601 | { |
| @@ -739,13 +653,11 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, | |||
| 739 | static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | 653 | static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, |
| 740 | int cancel) | 654 | int cancel) |
| 741 | { | 655 | { |
| 742 | int err, put = 0, scrubbing = 0, protect = 0; | 656 | int err, scrubbing = 0, torture = 0; |
| 743 | struct ubi_wl_prot_entry *uninitialized_var(pe); | ||
| 744 | struct ubi_wl_entry *e1, *e2; | 657 | struct ubi_wl_entry *e1, *e2; |
| 745 | struct ubi_vid_hdr *vid_hdr; | 658 | struct ubi_vid_hdr *vid_hdr; |
| 746 | 659 | ||
| 747 | kfree(wrk); | 660 | kfree(wrk); |
| 748 | |||
| 749 | if (cancel) | 661 | if (cancel) |
| 750 | return 0; | 662 | return 0; |
| 751 | 663 | ||
| @@ -781,7 +693,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
| 781 | * highly worn-out free physical eraseblock. If the erase | 693 | * highly worn-out free physical eraseblock. If the erase |
| 782 | * counters differ much enough, start wear-leveling. | 694 | * counters differ much enough, start wear-leveling. |
| 783 | */ | 695 | */ |
| 784 | e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, rb); | 696 | e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb); |
| 785 | e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); | 697 | e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); |
| 786 | 698 | ||
| 787 | if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) { | 699 | if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) { |
| @@ -790,21 +702,21 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
| 790 | goto out_cancel; | 702 | goto out_cancel; |
| 791 | } | 703 | } |
| 792 | paranoid_check_in_wl_tree(e1, &ubi->used); | 704 | paranoid_check_in_wl_tree(e1, &ubi->used); |
| 793 | rb_erase(&e1->rb, &ubi->used); | 705 | rb_erase(&e1->u.rb, &ubi->used); |
| 794 | dbg_wl("move PEB %d EC %d to PEB %d EC %d", | 706 | dbg_wl("move PEB %d EC %d to PEB %d EC %d", |
| 795 | e1->pnum, e1->ec, e2->pnum, e2->ec); | 707 | e1->pnum, e1->ec, e2->pnum, e2->ec); |
| 796 | } else { | 708 | } else { |
| 797 | /* Perform scrubbing */ | 709 | /* Perform scrubbing */ |
| 798 | scrubbing = 1; | 710 | scrubbing = 1; |
| 799 | e1 = rb_entry(rb_first(&ubi->scrub), struct ubi_wl_entry, rb); | 711 | e1 = rb_entry(rb_first(&ubi->scrub), struct ubi_wl_entry, u.rb); |
| 800 | e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); | 712 | e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); |
| 801 | paranoid_check_in_wl_tree(e1, &ubi->scrub); | 713 | paranoid_check_in_wl_tree(e1, &ubi->scrub); |
| 802 | rb_erase(&e1->rb, &ubi->scrub); | 714 | rb_erase(&e1->u.rb, &ubi->scrub); |
| 803 | dbg_wl("scrub PEB %d to PEB %d", e1->pnum, e2->pnum); | 715 | dbg_wl("scrub PEB %d to PEB %d", e1->pnum, e2->pnum); |
| 804 | } | 716 | } |
| 805 | 717 | ||
| 806 | paranoid_check_in_wl_tree(e2, &ubi->free); | 718 | paranoid_check_in_wl_tree(e2, &ubi->free); |
| 807 | rb_erase(&e2->rb, &ubi->free); | 719 | rb_erase(&e2->u.rb, &ubi->free); |
| 808 | ubi->move_from = e1; | 720 | ubi->move_from = e1; |
| 809 | ubi->move_to = e2; | 721 | ubi->move_to = e2; |
| 810 | spin_unlock(&ubi->wl_lock); | 722 | spin_unlock(&ubi->wl_lock); |
| @@ -844,46 +756,67 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
| 844 | 756 | ||
| 845 | err = ubi_eba_copy_leb(ubi, e1->pnum, e2->pnum, vid_hdr); | 757 | err = ubi_eba_copy_leb(ubi, e1->pnum, e2->pnum, vid_hdr); |
| 846 | if (err) { | 758 | if (err) { |
| 847 | 759 | if (err == -EAGAIN) | |
| 760 | goto out_not_moved; | ||
| 848 | if (err < 0) | 761 | if (err < 0) |
| 849 | goto out_error; | 762 | goto out_error; |
| 850 | if (err == 1) | 763 | if (err == 2) { |
| 764 | /* Target PEB write error, torture it */ | ||
| 765 | torture = 1; | ||
| 851 | goto out_not_moved; | 766 | goto out_not_moved; |
| 767 | } | ||
| 852 | 768 | ||
| 853 | /* | 769 | /* |
| 854 | * For some reason the LEB was not moved - it might be because | 770 | * The LEB has not been moved because the volume is being |
| 855 | * the volume is being deleted. We should prevent this PEB from | 771 | * deleted or the PEB has been put meanwhile. We should prevent |
| 856 | * being selected for wear-levelling movement for some "time", | 772 | * this PEB from being selected for wear-leveling movement |
| 857 | * so put it to the protection tree. | 773 | * again, so put it to the protection queue. |
| 858 | */ | 774 | */ |
| 859 | 775 | ||
| 860 | dbg_wl("cancelled moving PEB %d", e1->pnum); | 776 | dbg_wl("canceled moving PEB %d", e1->pnum); |
| 861 | pe = kmalloc(sizeof(struct ubi_wl_prot_entry), GFP_NOFS); | 777 | ubi_assert(err == 1); |
| 862 | if (!pe) { | 778 | |
| 863 | err = -ENOMEM; | 779 | ubi_free_vid_hdr(ubi, vid_hdr); |
| 864 | goto out_error; | 780 | vid_hdr = NULL; |
| 865 | } | 781 | |
| 782 | spin_lock(&ubi->wl_lock); | ||
| 783 | prot_queue_add(ubi, e1); | ||
| 784 | ubi_assert(!ubi->move_to_put); | ||
| 785 | ubi->move_from = ubi->move_to = NULL; | ||
| 786 | ubi->wl_scheduled = 0; | ||
| 787 | spin_unlock(&ubi->wl_lock); | ||
| 866 | 788 | ||
| 867 | protect = 1; | 789 | e1 = NULL; |
| 790 | err = schedule_erase(ubi, e2, 0); | ||
| 791 | if (err) | ||
| 792 | goto out_error; | ||
| 793 | mutex_unlock(&ubi->move_mutex); | ||
| 794 | return 0; | ||
| 868 | } | 795 | } |
| 869 | 796 | ||
| 797 | /* The PEB has been successfully moved */ | ||
| 870 | ubi_free_vid_hdr(ubi, vid_hdr); | 798 | ubi_free_vid_hdr(ubi, vid_hdr); |
| 871 | if (scrubbing && !protect) | 799 | vid_hdr = NULL; |
| 800 | if (scrubbing) | ||
| 872 | ubi_msg("scrubbed PEB %d, data moved to PEB %d", | 801 | ubi_msg("scrubbed PEB %d, data moved to PEB %d", |
| 873 | e1->pnum, e2->pnum); | 802 | e1->pnum, e2->pnum); |
| 874 | 803 | ||
| 875 | spin_lock(&ubi->wl_lock); | 804 | spin_lock(&ubi->wl_lock); |
| 876 | if (protect) | 805 | if (!ubi->move_to_put) { |
| 877 | prot_tree_add(ubi, e1, pe, protect); | ||
| 878 | if (!ubi->move_to_put) | ||
| 879 | wl_tree_add(e2, &ubi->used); | 806 | wl_tree_add(e2, &ubi->used); |
| 880 | else | 807 | e2 = NULL; |
| 881 | put = 1; | 808 | } |
| 882 | ubi->move_from = ubi->move_to = NULL; | 809 | ubi->move_from = ubi->move_to = NULL; |
| 883 | ubi->move_to_put = ubi->wl_scheduled = 0; | 810 | ubi->move_to_put = ubi->wl_scheduled = 0; |
| 884 | spin_unlock(&ubi->wl_lock); | 811 | spin_unlock(&ubi->wl_lock); |
| 885 | 812 | ||
| 886 | if (put) { | 813 | err = schedule_erase(ubi, e1, 0); |
| 814 | if (err) { | ||
| 815 | e1 = NULL; | ||
| 816 | goto out_error; | ||
| 817 | } | ||
| 818 | |||
| 819 | if (e2) { | ||
| 887 | /* | 820 | /* |
| 888 | * Well, the target PEB was put meanwhile, schedule it for | 821 | * Well, the target PEB was put meanwhile, schedule it for |
| 889 | * erasure. | 822 | * erasure. |
| @@ -894,13 +827,6 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
| 894 | goto out_error; | 827 | goto out_error; |
| 895 | } | 828 | } |
| 896 | 829 | ||
| 897 | if (!protect) { | ||
| 898 | err = schedule_erase(ubi, e1, 0); | ||
| 899 | if (err) | ||
| 900 | goto out_error; | ||
| 901 | } | ||
| 902 | |||
| 903 | |||
| 904 | dbg_wl("done"); | 830 | dbg_wl("done"); |
| 905 | mutex_unlock(&ubi->move_mutex); | 831 | mutex_unlock(&ubi->move_mutex); |
| 906 | return 0; | 832 | return 0; |
| @@ -908,20 +834,24 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
| 908 | /* | 834 | /* |
| 909 | * For some reasons the LEB was not moved, might be an error, might be | 835 | * For some reasons the LEB was not moved, might be an error, might be |
| 910 | * something else. @e1 was not changed, so return it back. @e2 might | 836 | * something else. @e1 was not changed, so return it back. @e2 might |
| 911 | * be changed, schedule it for erasure. | 837 | * have been changed, schedule it for erasure. |
| 912 | */ | 838 | */ |
| 913 | out_not_moved: | 839 | out_not_moved: |
| 840 | dbg_wl("canceled moving PEB %d", e1->pnum); | ||
| 914 | ubi_free_vid_hdr(ubi, vid_hdr); | 841 | ubi_free_vid_hdr(ubi, vid_hdr); |
| 842 | vid_hdr = NULL; | ||
| 915 | spin_lock(&ubi->wl_lock); | 843 | spin_lock(&ubi->wl_lock); |
| 916 | if (scrubbing) | 844 | if (scrubbing) |
| 917 | wl_tree_add(e1, &ubi->scrub); | 845 | wl_tree_add(e1, &ubi->scrub); |
| 918 | else | 846 | else |
| 919 | wl_tree_add(e1, &ubi->used); | 847 | wl_tree_add(e1, &ubi->used); |
| 848 | ubi_assert(!ubi->move_to_put); | ||
| 920 | ubi->move_from = ubi->move_to = NULL; | 849 | ubi->move_from = ubi->move_to = NULL; |
| 921 | ubi->move_to_put = ubi->wl_scheduled = 0; | 850 | ubi->wl_scheduled = 0; |
| 922 | spin_unlock(&ubi->wl_lock); | 851 | spin_unlock(&ubi->wl_lock); |
| 923 | 852 | ||
| 924 | err = schedule_erase(ubi, e2, 0); | 853 | e1 = NULL; |
| 854 | err = schedule_erase(ubi, e2, torture); | ||
| 925 | if (err) | 855 | if (err) |
| 926 | goto out_error; | 856 | goto out_error; |
| 927 | 857 | ||
| @@ -938,8 +868,10 @@ out_error: | |||
| 938 | ubi->move_to_put = ubi->wl_scheduled = 0; | 868 | ubi->move_to_put = ubi->wl_scheduled = 0; |
| 939 | spin_unlock(&ubi->wl_lock); | 869 | spin_unlock(&ubi->wl_lock); |
| 940 | 870 | ||
| 941 | kmem_cache_free(ubi_wl_entry_slab, e1); | 871 | if (e1) |
| 942 | kmem_cache_free(ubi_wl_entry_slab, e2); | 872 | kmem_cache_free(ubi_wl_entry_slab, e1); |
| 873 | if (e2) | ||
| 874 | kmem_cache_free(ubi_wl_entry_slab, e2); | ||
| 943 | ubi_ro_mode(ubi); | 875 | ubi_ro_mode(ubi); |
| 944 | 876 | ||
| 945 | mutex_unlock(&ubi->move_mutex); | 877 | mutex_unlock(&ubi->move_mutex); |
| @@ -988,7 +920,7 @@ static int ensure_wear_leveling(struct ubi_device *ubi) | |||
| 988 | * erase counter of free physical eraseblocks is greater then | 920 | * erase counter of free physical eraseblocks is greater then |
| 989 | * %UBI_WL_THRESHOLD. | 921 | * %UBI_WL_THRESHOLD. |
| 990 | */ | 922 | */ |
| 991 | e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, rb); | 923 | e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb); |
| 992 | e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); | 924 | e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); |
| 993 | 925 | ||
| 994 | if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) | 926 | if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) |
| @@ -1050,7 +982,6 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, | |||
| 1050 | kfree(wl_wrk); | 982 | kfree(wl_wrk); |
| 1051 | 983 | ||
| 1052 | spin_lock(&ubi->wl_lock); | 984 | spin_lock(&ubi->wl_lock); |
| 1053 | ubi->abs_ec += 1; | ||
| 1054 | wl_tree_add(e, &ubi->free); | 985 | wl_tree_add(e, &ubi->free); |
| 1055 | spin_unlock(&ubi->wl_lock); | 986 | spin_unlock(&ubi->wl_lock); |
| 1056 | 987 | ||
| @@ -1058,7 +989,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, | |||
| 1058 | * One more erase operation has happened, take care about | 989 | * One more erase operation has happened, take care about |
| 1059 | * protected physical eraseblocks. | 990 | * protected physical eraseblocks. |
| 1060 | */ | 991 | */ |
| 1061 | check_protection_over(ubi); | 992 | serve_prot_queue(ubi); |
| 1062 | 993 | ||
| 1063 | /* And take care about wear-leveling */ | 994 | /* And take care about wear-leveling */ |
| 1064 | err = ensure_wear_leveling(ubi); | 995 | err = ensure_wear_leveling(ubi); |
| @@ -1190,12 +1121,12 @@ retry: | |||
| 1190 | } else { | 1121 | } else { |
| 1191 | if (in_wl_tree(e, &ubi->used)) { | 1122 | if (in_wl_tree(e, &ubi->used)) { |
| 1192 | paranoid_check_in_wl_tree(e, &ubi->used); | 1123 | paranoid_check_in_wl_tree(e, &ubi->used); |
| 1193 | rb_erase(&e->rb, &ubi->used); | 1124 | rb_erase(&e->u.rb, &ubi->used); |
| 1194 | } else if (in_wl_tree(e, &ubi->scrub)) { | 1125 | } else if (in_wl_tree(e, &ubi->scrub)) { |
| 1195 | paranoid_check_in_wl_tree(e, &ubi->scrub); | 1126 | paranoid_check_in_wl_tree(e, &ubi->scrub); |
| 1196 | rb_erase(&e->rb, &ubi->scrub); | 1127 | rb_erase(&e->u.rb, &ubi->scrub); |
| 1197 | } else { | 1128 | } else { |
| 1198 | err = prot_tree_del(ubi, e->pnum); | 1129 | err = prot_queue_del(ubi, e->pnum); |
| 1199 | if (err) { | 1130 | if (err) { |
| 1200 | ubi_err("PEB %d not found", pnum); | 1131 | ubi_err("PEB %d not found", pnum); |
| 1201 | ubi_ro_mode(ubi); | 1132 | ubi_ro_mode(ubi); |
| @@ -1255,11 +1186,11 @@ retry: | |||
| 1255 | 1186 | ||
| 1256 | if (in_wl_tree(e, &ubi->used)) { | 1187 | if (in_wl_tree(e, &ubi->used)) { |
| 1257 | paranoid_check_in_wl_tree(e, &ubi->used); | 1188 | paranoid_check_in_wl_tree(e, &ubi->used); |
| 1258 | rb_erase(&e->rb, &ubi->used); | 1189 | rb_erase(&e->u.rb, &ubi->used); |
| 1259 | } else { | 1190 | } else { |
| 1260 | int err; | 1191 | int err; |
| 1261 | 1192 | ||
| 1262 | err = prot_tree_del(ubi, e->pnum); | 1193 | err = prot_queue_del(ubi, e->pnum); |
| 1263 | if (err) { | 1194 | if (err) { |
| 1264 | ubi_err("PEB %d not found", pnum); | 1195 | ubi_err("PEB %d not found", pnum); |
| 1265 | ubi_ro_mode(ubi); | 1196 | ubi_ro_mode(ubi); |
| @@ -1290,7 +1221,7 @@ int ubi_wl_flush(struct ubi_device *ubi) | |||
| 1290 | int err; | 1221 | int err; |
| 1291 | 1222 | ||
| 1292 | /* | 1223 | /* |
| 1293 | * Erase while the pending works queue is not empty, but not more then | 1224 | * Erase while the pending works queue is not empty, but not more than |
| 1294 | * the number of currently pending works. | 1225 | * the number of currently pending works. |
| 1295 | */ | 1226 | */ |
| 1296 | dbg_wl("flush (%d pending works)", ubi->works_count); | 1227 | dbg_wl("flush (%d pending works)", ubi->works_count); |
| @@ -1308,7 +1239,7 @@ int ubi_wl_flush(struct ubi_device *ubi) | |||
| 1308 | up_write(&ubi->work_sem); | 1239 | up_write(&ubi->work_sem); |
| 1309 | 1240 | ||
| 1310 | /* | 1241 | /* |
| 1311 | * And in case last was the WL worker and it cancelled the LEB | 1242 | * And in case last was the WL worker and it canceled the LEB |
| 1312 | * movement, flush again. | 1243 | * movement, flush again. |
| 1313 | */ | 1244 | */ |
| 1314 | while (ubi->works_count) { | 1245 | while (ubi->works_count) { |
| @@ -1337,11 +1268,11 @@ static void tree_destroy(struct rb_root *root) | |||
| 1337 | else if (rb->rb_right) | 1268 | else if (rb->rb_right) |
| 1338 | rb = rb->rb_right; | 1269 | rb = rb->rb_right; |
| 1339 | else { | 1270 | else { |
| 1340 | e = rb_entry(rb, struct ubi_wl_entry, rb); | 1271 | e = rb_entry(rb, struct ubi_wl_entry, u.rb); |
| 1341 | 1272 | ||
| 1342 | rb = rb_parent(rb); | 1273 | rb = rb_parent(rb); |
| 1343 | if (rb) { | 1274 | if (rb) { |
| 1344 | if (rb->rb_left == &e->rb) | 1275 | if (rb->rb_left == &e->u.rb) |
| 1345 | rb->rb_left = NULL; | 1276 | rb->rb_left = NULL; |
| 1346 | else | 1277 | else |
| 1347 | rb->rb_right = NULL; | 1278 | rb->rb_right = NULL; |
| @@ -1436,15 +1367,13 @@ static void cancel_pending(struct ubi_device *ubi) | |||
| 1436 | */ | 1367 | */ |
| 1437 | int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) | 1368 | int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) |
| 1438 | { | 1369 | { |
| 1439 | int err; | 1370 | int err, i; |
| 1440 | struct rb_node *rb1, *rb2; | 1371 | struct rb_node *rb1, *rb2; |
| 1441 | struct ubi_scan_volume *sv; | 1372 | struct ubi_scan_volume *sv; |
| 1442 | struct ubi_scan_leb *seb, *tmp; | 1373 | struct ubi_scan_leb *seb, *tmp; |
| 1443 | struct ubi_wl_entry *e; | 1374 | struct ubi_wl_entry *e; |
| 1444 | 1375 | ||
| 1445 | |||
| 1446 | ubi->used = ubi->free = ubi->scrub = RB_ROOT; | 1376 | ubi->used = ubi->free = ubi->scrub = RB_ROOT; |
| 1447 | ubi->prot.pnum = ubi->prot.aec = RB_ROOT; | ||
| 1448 | spin_lock_init(&ubi->wl_lock); | 1377 | spin_lock_init(&ubi->wl_lock); |
| 1449 | mutex_init(&ubi->move_mutex); | 1378 | mutex_init(&ubi->move_mutex); |
| 1450 | init_rwsem(&ubi->work_sem); | 1379 | init_rwsem(&ubi->work_sem); |
| @@ -1458,6 +1387,10 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) | |||
| 1458 | if (!ubi->lookuptbl) | 1387 | if (!ubi->lookuptbl) |
| 1459 | return err; | 1388 | return err; |
| 1460 | 1389 | ||
| 1390 | for (i = 0; i < UBI_PROT_QUEUE_LEN; i++) | ||
| 1391 | INIT_LIST_HEAD(&ubi->pq[i]); | ||
| 1392 | ubi->pq_head = 0; | ||
| 1393 | |||
| 1461 | list_for_each_entry_safe(seb, tmp, &si->erase, u.list) { | 1394 | list_for_each_entry_safe(seb, tmp, &si->erase, u.list) { |
| 1462 | cond_resched(); | 1395 | cond_resched(); |
| 1463 | 1396 | ||
| @@ -1552,33 +1485,18 @@ out_free: | |||
| 1552 | } | 1485 | } |
| 1553 | 1486 | ||
| 1554 | /** | 1487 | /** |
| 1555 | * protection_trees_destroy - destroy the protection RB-trees. | 1488 | * protection_queue_destroy - destroy the protection queue. |
| 1556 | * @ubi: UBI device description object | 1489 | * @ubi: UBI device description object |
| 1557 | */ | 1490 | */ |
| 1558 | static void protection_trees_destroy(struct ubi_device *ubi) | 1491 | static void protection_queue_destroy(struct ubi_device *ubi) |
| 1559 | { | 1492 | { |
| 1560 | struct rb_node *rb; | 1493 | int i; |
| 1561 | struct ubi_wl_prot_entry *pe; | 1494 | struct ubi_wl_entry *e, *tmp; |
| 1562 | |||
| 1563 | rb = ubi->prot.aec.rb_node; | ||
| 1564 | while (rb) { | ||
| 1565 | if (rb->rb_left) | ||
| 1566 | rb = rb->rb_left; | ||
| 1567 | else if (rb->rb_right) | ||
| 1568 | rb = rb->rb_right; | ||
| 1569 | else { | ||
| 1570 | pe = rb_entry(rb, struct ubi_wl_prot_entry, rb_aec); | ||
| 1571 | |||
| 1572 | rb = rb_parent(rb); | ||
| 1573 | if (rb) { | ||
| 1574 | if (rb->rb_left == &pe->rb_aec) | ||
| 1575 | rb->rb_left = NULL; | ||
| 1576 | else | ||
| 1577 | rb->rb_right = NULL; | ||
| 1578 | } | ||
| 1579 | 1495 | ||
| 1580 | kmem_cache_free(ubi_wl_entry_slab, pe->e); | 1496 | for (i = 0; i < UBI_PROT_QUEUE_LEN; ++i) { |
| 1581 | kfree(pe); | 1497 | list_for_each_entry_safe(e, tmp, &ubi->pq[i], u.list) { |
| 1498 | list_del(&e->u.list); | ||
| 1499 | kmem_cache_free(ubi_wl_entry_slab, e); | ||
| 1582 | } | 1500 | } |
| 1583 | } | 1501 | } |
| 1584 | } | 1502 | } |
| @@ -1591,7 +1509,7 @@ void ubi_wl_close(struct ubi_device *ubi) | |||
| 1591 | { | 1509 | { |
| 1592 | dbg_wl("close the WL sub-system"); | 1510 | dbg_wl("close the WL sub-system"); |
| 1593 | cancel_pending(ubi); | 1511 | cancel_pending(ubi); |
| 1594 | protection_trees_destroy(ubi); | 1512 | protection_queue_destroy(ubi); |
| 1595 | tree_destroy(&ubi->used); | 1513 | tree_destroy(&ubi->used); |
| 1596 | tree_destroy(&ubi->free); | 1514 | tree_destroy(&ubi->free); |
| 1597 | tree_destroy(&ubi->scrub); | 1515 | tree_destroy(&ubi->scrub); |
| @@ -1661,4 +1579,27 @@ static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, | |||
| 1661 | return 1; | 1579 | return 1; |
| 1662 | } | 1580 | } |
| 1663 | 1581 | ||
| 1582 | /** | ||
| 1583 | * paranoid_check_in_pq - check if wear-leveling entry is in the protection | ||
| 1584 | * queue. | ||
| 1585 | * @ubi: UBI device description object | ||
| 1586 | * @e: the wear-leveling entry to check | ||
| 1587 | * | ||
| 1588 | * This function returns zero if @e is in @ubi->pq and %1 if it is not. | ||
| 1589 | */ | ||
| 1590 | static int paranoid_check_in_pq(struct ubi_device *ubi, struct ubi_wl_entry *e) | ||
| 1591 | { | ||
| 1592 | struct ubi_wl_entry *p; | ||
| 1593 | int i; | ||
| 1594 | |||
| 1595 | for (i = 0; i < UBI_PROT_QUEUE_LEN; ++i) | ||
| 1596 | list_for_each_entry(p, &ubi->pq[i], u.list) | ||
| 1597 | if (p == e) | ||
| 1598 | return 0; | ||
| 1599 | |||
| 1600 | ubi_err("paranoid check failed for PEB %d, EC %d, Protect queue", | ||
| 1601 | e->pnum, e->ec); | ||
| 1602 | ubi_dbg_dump_stack(); | ||
| 1603 | return 1; | ||
| 1604 | } | ||
| 1664 | #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ | 1605 | #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 691b3adeb870..f5a662a50acb 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
| @@ -191,26 +191,17 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header) | |||
| 191 | static int __init dmar_parse_dev(struct dmar_drhd_unit *dmaru) | 191 | static int __init dmar_parse_dev(struct dmar_drhd_unit *dmaru) |
| 192 | { | 192 | { |
| 193 | struct acpi_dmar_hardware_unit *drhd; | 193 | struct acpi_dmar_hardware_unit *drhd; |
| 194 | static int include_all; | ||
| 195 | int ret = 0; | 194 | int ret = 0; |
| 196 | 195 | ||
| 197 | drhd = (struct acpi_dmar_hardware_unit *) dmaru->hdr; | 196 | drhd = (struct acpi_dmar_hardware_unit *) dmaru->hdr; |
| 198 | 197 | ||
| 199 | if (!dmaru->include_all) | 198 | if (dmaru->include_all) |
| 200 | ret = dmar_parse_dev_scope((void *)(drhd + 1), | 199 | return 0; |
| 200 | |||
| 201 | ret = dmar_parse_dev_scope((void *)(drhd + 1), | ||
| 201 | ((void *)drhd) + drhd->header.length, | 202 | ((void *)drhd) + drhd->header.length, |
| 202 | &dmaru->devices_cnt, &dmaru->devices, | 203 | &dmaru->devices_cnt, &dmaru->devices, |
| 203 | drhd->segment); | 204 | drhd->segment); |
| 204 | else { | ||
| 205 | /* Only allow one INCLUDE_ALL */ | ||
| 206 | if (include_all) { | ||
| 207 | printk(KERN_WARNING PREFIX "Only one INCLUDE_ALL " | ||
| 208 | "device scope is allowed\n"); | ||
| 209 | ret = -EINVAL; | ||
| 210 | } | ||
| 211 | include_all = 1; | ||
| 212 | } | ||
| 213 | |||
| 214 | if (ret) { | 205 | if (ret) { |
| 215 | list_del(&dmaru->list); | 206 | list_del(&dmaru->list); |
| 216 | kfree(dmaru); | 207 | kfree(dmaru); |
| @@ -384,12 +375,21 @@ int dmar_pci_device_match(struct pci_dev *devices[], int cnt, | |||
| 384 | struct dmar_drhd_unit * | 375 | struct dmar_drhd_unit * |
| 385 | dmar_find_matched_drhd_unit(struct pci_dev *dev) | 376 | dmar_find_matched_drhd_unit(struct pci_dev *dev) |
| 386 | { | 377 | { |
| 387 | struct dmar_drhd_unit *drhd = NULL; | 378 | struct dmar_drhd_unit *dmaru = NULL; |
| 379 | struct acpi_dmar_hardware_unit *drhd; | ||
| 388 | 380 | ||
| 389 | list_for_each_entry(drhd, &dmar_drhd_units, list) { | 381 | list_for_each_entry(dmaru, &dmar_drhd_units, list) { |
| 390 | if (drhd->include_all || dmar_pci_device_match(drhd->devices, | 382 | drhd = container_of(dmaru->hdr, |
| 391 | drhd->devices_cnt, dev)) | 383 | struct acpi_dmar_hardware_unit, |
| 392 | return drhd; | 384 | header); |
| 385 | |||
| 386 | if (dmaru->include_all && | ||
| 387 | drhd->segment == pci_domain_nr(dev->bus)) | ||
| 388 | return dmaru; | ||
| 389 | |||
| 390 | if (dmar_pci_device_match(dmaru->devices, | ||
| 391 | dmaru->devices_cnt, dev)) | ||
| 392 | return dmaru; | ||
| 393 | } | 393 | } |
| 394 | 394 | ||
| 395 | return NULL; | 395 | return NULL; |
| @@ -491,6 +491,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
| 491 | int map_size; | 491 | int map_size; |
| 492 | u32 ver; | 492 | u32 ver; |
| 493 | static int iommu_allocated = 0; | 493 | static int iommu_allocated = 0; |
| 494 | int agaw; | ||
| 494 | 495 | ||
| 495 | iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); | 496 | iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); |
| 496 | if (!iommu) | 497 | if (!iommu) |
| @@ -506,6 +507,15 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
| 506 | iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG); | 507 | iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG); |
| 507 | iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); | 508 | iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); |
| 508 | 509 | ||
| 510 | agaw = iommu_calculate_agaw(iommu); | ||
| 511 | if (agaw < 0) { | ||
| 512 | printk(KERN_ERR | ||
| 513 | "Cannot get a valid agaw for iommu (seq_id = %d)\n", | ||
| 514 | iommu->seq_id); | ||
| 515 | goto error; | ||
| 516 | } | ||
| 517 | iommu->agaw = agaw; | ||
| 518 | |||
| 509 | /* the registers might be more than one page */ | 519 | /* the registers might be more than one page */ |
| 510 | map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap), | 520 | map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap), |
| 511 | cap_max_fault_reg_offset(iommu->cap)); | 521 | cap_max_fault_reg_offset(iommu->cap)); |
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 8514c3a1746a..c2e1bcbb28a7 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c | |||
| @@ -45,7 +45,7 @@ | |||
| 45 | 45 | ||
| 46 | #include "cpqphp.h" | 46 | #include "cpqphp.h" |
| 47 | #include "cpqphp_nvram.h" | 47 | #include "cpqphp_nvram.h" |
| 48 | #include "../../../arch/x86/pci/pci.h" /* horrible hack showing how processor dependent we are... */ | 48 | #include <asm/pci_x86.h> |
| 49 | 49 | ||
| 50 | 50 | ||
| 51 | /* Global variables */ | 51 | /* Global variables */ |
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c index 09021930589f..df146be9d2e9 100644 --- a/drivers/pci/hotplug/cpqphp_pci.c +++ b/drivers/pci/hotplug/cpqphp_pci.c | |||
| @@ -37,7 +37,7 @@ | |||
| 37 | #include "../pci.h" | 37 | #include "../pci.h" |
| 38 | #include "cpqphp.h" | 38 | #include "cpqphp.h" |
| 39 | #include "cpqphp_nvram.h" | 39 | #include "cpqphp_nvram.h" |
| 40 | #include "../../../arch/x86/pci/pci.h" /* horrible hack showing how processor dependent we are... */ | 40 | #include <asm/pci_x86.h> |
| 41 | 41 | ||
| 42 | 42 | ||
| 43 | u8 cpqhp_nic_irq; | 43 | u8 cpqhp_nic_irq; |
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 633e743442ac..dd18f857dfb0 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c | |||
| @@ -35,7 +35,7 @@ | |||
| 35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
| 36 | #include <linux/wait.h> | 36 | #include <linux/wait.h> |
| 37 | #include "../pci.h" | 37 | #include "../pci.h" |
| 38 | #include "../../../arch/x86/pci/pci.h" /* for struct irq_routing_table */ | 38 | #include <asm/pci_x86.h> /* for struct irq_routing_table */ |
| 39 | #include "ibmphp.h" | 39 | #include "ibmphp.h" |
| 40 | 40 | ||
| 41 | #define attn_on(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON) | 41 | #define attn_on(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON) |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 5c8baa43ac9c..235fb7a5a8a5 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
| 28 | #include <linux/irq.h> | 28 | #include <linux/irq.h> |
| 29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
| 30 | #include <linux/sysdev.h> | ||
| 31 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
| 32 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
| 33 | #include <linux/dmar.h> | 32 | #include <linux/dmar.h> |
| @@ -35,6 +34,7 @@ | |||
| 35 | #include <linux/mempool.h> | 34 | #include <linux/mempool.h> |
| 36 | #include <linux/timer.h> | 35 | #include <linux/timer.h> |
| 37 | #include <linux/iova.h> | 36 | #include <linux/iova.h> |
| 37 | #include <linux/iommu.h> | ||
| 38 | #include <linux/intel-iommu.h> | 38 | #include <linux/intel-iommu.h> |
| 39 | #include <asm/cacheflush.h> | 39 | #include <asm/cacheflush.h> |
| 40 | #include <asm/iommu.h> | 40 | #include <asm/iommu.h> |
| @@ -54,6 +54,195 @@ | |||
| 54 | 54 | ||
| 55 | #define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1) | 55 | #define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1) |
| 56 | 56 | ||
| 57 | #define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT) | ||
| 58 | #define DMA_32BIT_PFN IOVA_PFN(DMA_32BIT_MASK) | ||
| 59 | #define DMA_64BIT_PFN IOVA_PFN(DMA_64BIT_MASK) | ||
| 60 | |||
| 61 | /* global iommu list, set NULL for ignored DMAR units */ | ||
| 62 | static struct intel_iommu **g_iommus; | ||
| 63 | |||
| 64 | /* | ||
| 65 | * 0: Present | ||
| 66 | * 1-11: Reserved | ||
| 67 | * 12-63: Context Ptr (12 - (haw-1)) | ||
| 68 | * 64-127: Reserved | ||
| 69 | */ | ||
| 70 | struct root_entry { | ||
| 71 | u64 val; | ||
| 72 | u64 rsvd1; | ||
| 73 | }; | ||
| 74 | #define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry)) | ||
| 75 | static inline bool root_present(struct root_entry *root) | ||
| 76 | { | ||
| 77 | return (root->val & 1); | ||
| 78 | } | ||
| 79 | static inline void set_root_present(struct root_entry *root) | ||
| 80 | { | ||
| 81 | root->val |= 1; | ||
| 82 | } | ||
| 83 | static inline void set_root_value(struct root_entry *root, unsigned long value) | ||
| 84 | { | ||
| 85 | root->val |= value & VTD_PAGE_MASK; | ||
| 86 | } | ||
| 87 | |||
| 88 | static inline struct context_entry * | ||
| 89 | get_context_addr_from_root(struct root_entry *root) | ||
| 90 | { | ||
| 91 | return (struct context_entry *) | ||
| 92 | (root_present(root)?phys_to_virt( | ||
| 93 | root->val & VTD_PAGE_MASK) : | ||
| 94 | NULL); | ||
| 95 | } | ||
| 96 | |||
| 97 | /* | ||
| 98 | * low 64 bits: | ||
| 99 | * 0: present | ||
| 100 | * 1: fault processing disable | ||
| 101 | * 2-3: translation type | ||
| 102 | * 12-63: address space root | ||
| 103 | * high 64 bits: | ||
| 104 | * 0-2: address width | ||
| 105 | * 3-6: aval | ||
| 106 | * 8-23: domain id | ||
| 107 | */ | ||
| 108 | struct context_entry { | ||
| 109 | u64 lo; | ||
| 110 | u64 hi; | ||
| 111 | }; | ||
| 112 | |||
| 113 | static inline bool context_present(struct context_entry *context) | ||
| 114 | { | ||
| 115 | return (context->lo & 1); | ||
| 116 | } | ||
| 117 | static inline void context_set_present(struct context_entry *context) | ||
| 118 | { | ||
| 119 | context->lo |= 1; | ||
| 120 | } | ||
| 121 | |||
| 122 | static inline void context_set_fault_enable(struct context_entry *context) | ||
| 123 | { | ||
| 124 | context->lo &= (((u64)-1) << 2) | 1; | ||
| 125 | } | ||
| 126 | |||
| 127 | #define CONTEXT_TT_MULTI_LEVEL 0 | ||
| 128 | |||
| 129 | static inline void context_set_translation_type(struct context_entry *context, | ||
| 130 | unsigned long value) | ||
| 131 | { | ||
| 132 | context->lo &= (((u64)-1) << 4) | 3; | ||
| 133 | context->lo |= (value & 3) << 2; | ||
| 134 | } | ||
| 135 | |||
| 136 | static inline void context_set_address_root(struct context_entry *context, | ||
| 137 | unsigned long value) | ||
| 138 | { | ||
| 139 | context->lo |= value & VTD_PAGE_MASK; | ||
| 140 | } | ||
| 141 | |||
| 142 | static inline void context_set_address_width(struct context_entry *context, | ||
| 143 | unsigned long value) | ||
| 144 | { | ||
| 145 | context->hi |= value & 7; | ||
| 146 | } | ||
| 147 | |||
| 148 | static inline void context_set_domain_id(struct context_entry *context, | ||
| 149 | unsigned long value) | ||
| 150 | { | ||
| 151 | context->hi |= (value & ((1 << 16) - 1)) << 8; | ||
| 152 | } | ||
| 153 | |||
| 154 | static inline void context_clear_entry(struct context_entry *context) | ||
| 155 | { | ||
| 156 | context->lo = 0; | ||
| 157 | context->hi = 0; | ||
| 158 | } | ||
| 159 | |||
| 160 | /* | ||
| 161 | * 0: readable | ||
| 162 | * 1: writable | ||
| 163 | * 2-6: reserved | ||
| 164 | * 7: super page | ||
| 165 | * 8-11: available | ||
| 166 | * 12-63: Host physcial address | ||
| 167 | */ | ||
| 168 | struct dma_pte { | ||
| 169 | u64 val; | ||
| 170 | }; | ||
| 171 | |||
| 172 | static inline void dma_clear_pte(struct dma_pte *pte) | ||
| 173 | { | ||
| 174 | pte->val = 0; | ||
| 175 | } | ||
| 176 | |||
| 177 | static inline void dma_set_pte_readable(struct dma_pte *pte) | ||
| 178 | { | ||
| 179 | pte->val |= DMA_PTE_READ; | ||
| 180 | } | ||
| 181 | |||
| 182 | static inline void dma_set_pte_writable(struct dma_pte *pte) | ||
| 183 | { | ||
| 184 | pte->val |= DMA_PTE_WRITE; | ||
| 185 | } | ||
| 186 | |||
| 187 | static inline void dma_set_pte_prot(struct dma_pte *pte, unsigned long prot) | ||
| 188 | { | ||
| 189 | pte->val = (pte->val & ~3) | (prot & 3); | ||
| 190 | } | ||
| 191 | |||
| 192 | static inline u64 dma_pte_addr(struct dma_pte *pte) | ||
| 193 | { | ||
| 194 | return (pte->val & VTD_PAGE_MASK); | ||
| 195 | } | ||
| 196 | |||
| 197 | static inline void dma_set_pte_addr(struct dma_pte *pte, u64 addr) | ||
| 198 | { | ||
| 199 | pte->val |= (addr & VTD_PAGE_MASK); | ||
| 200 | } | ||
| 201 | |||
| 202 | static inline bool dma_pte_present(struct dma_pte *pte) | ||
| 203 | { | ||
| 204 | return (pte->val & 3) != 0; | ||
| 205 | } | ||
| 206 | |||
| 207 | /* devices under the same p2p bridge are owned in one domain */ | ||
| 208 | #define DOMAIN_FLAG_P2P_MULTIPLE_DEVICES (1 << 0) | ||
| 209 | |||
| 210 | /* domain represents a virtual machine, more than one devices | ||
| 211 | * across iommus may be owned in one domain, e.g. kvm guest. | ||
| 212 | */ | ||
| 213 | #define DOMAIN_FLAG_VIRTUAL_MACHINE (1 << 1) | ||
| 214 | |||
| 215 | struct dmar_domain { | ||
| 216 | int id; /* domain id */ | ||
| 217 | unsigned long iommu_bmp; /* bitmap of iommus this domain uses*/ | ||
| 218 | |||
| 219 | struct list_head devices; /* all devices' list */ | ||
| 220 | struct iova_domain iovad; /* iova's that belong to this domain */ | ||
| 221 | |||
| 222 | struct dma_pte *pgd; /* virtual address */ | ||
| 223 | spinlock_t mapping_lock; /* page table lock */ | ||
| 224 | int gaw; /* max guest address width */ | ||
| 225 | |||
| 226 | /* adjusted guest address width, 0 is level 2 30-bit */ | ||
| 227 | int agaw; | ||
| 228 | |||
| 229 | int flags; /* flags to find out type of domain */ | ||
| 230 | |||
| 231 | int iommu_coherency;/* indicate coherency of iommu access */ | ||
| 232 | int iommu_count; /* reference count of iommu */ | ||
| 233 | spinlock_t iommu_lock; /* protect iommu set in domain */ | ||
| 234 | u64 max_addr; /* maximum mapped address */ | ||
| 235 | }; | ||
| 236 | |||
| 237 | /* PCI domain-device relationship */ | ||
| 238 | struct device_domain_info { | ||
| 239 | struct list_head link; /* link to domain siblings */ | ||
| 240 | struct list_head global; /* link to global list */ | ||
| 241 | u8 bus; /* PCI bus numer */ | ||
| 242 | u8 devfn; /* PCI devfn number */ | ||
| 243 | struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */ | ||
| 244 | struct dmar_domain *domain; /* pointer to domain */ | ||
| 245 | }; | ||
| 57 | 246 | ||
| 58 | static void flush_unmaps_timeout(unsigned long data); | 247 | static void flush_unmaps_timeout(unsigned long data); |
| 59 | 248 | ||
| @@ -88,6 +277,8 @@ static int intel_iommu_strict; | |||
| 88 | static DEFINE_SPINLOCK(device_domain_lock); | 277 | static DEFINE_SPINLOCK(device_domain_lock); |
| 89 | static LIST_HEAD(device_domain_list); | 278 | static LIST_HEAD(device_domain_list); |
| 90 | 279 | ||
| 280 | static struct iommu_ops intel_iommu_ops; | ||
| 281 | |||
| 91 | static int __init intel_iommu_setup(char *str) | 282 | static int __init intel_iommu_setup(char *str) |
| 92 | { | 283 | { |
| 93 | if (!str) | 284 | if (!str) |
| @@ -184,6 +375,87 @@ void free_iova_mem(struct iova *iova) | |||
| 184 | kmem_cache_free(iommu_iova_cache, iova); | 375 | kmem_cache_free(iommu_iova_cache, iova); |
| 185 | } | 376 | } |
| 186 | 377 | ||
| 378 | |||
| 379 | static inline int width_to_agaw(int width); | ||
| 380 | |||
| 381 | /* calculate agaw for each iommu. | ||
| 382 | * "SAGAW" may be different across iommus, use a default agaw, and | ||
| 383 | * get a supported less agaw for iommus that don't support the default agaw. | ||
| 384 | */ | ||
| 385 | int iommu_calculate_agaw(struct intel_iommu *iommu) | ||
| 386 | { | ||
| 387 | unsigned long sagaw; | ||
| 388 | int agaw = -1; | ||
| 389 | |||
| 390 | sagaw = cap_sagaw(iommu->cap); | ||
| 391 | for (agaw = width_to_agaw(DEFAULT_DOMAIN_ADDRESS_WIDTH); | ||
| 392 | agaw >= 0; agaw--) { | ||
| 393 | if (test_bit(agaw, &sagaw)) | ||
| 394 | break; | ||
| 395 | } | ||
| 396 | |||
| 397 | return agaw; | ||
| 398 | } | ||
| 399 | |||
| 400 | /* in native case, each domain is related to only one iommu */ | ||
| 401 | static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain) | ||
| 402 | { | ||
| 403 | int iommu_id; | ||
| 404 | |||
| 405 | BUG_ON(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE); | ||
| 406 | |||
| 407 | iommu_id = find_first_bit(&domain->iommu_bmp, g_num_of_iommus); | ||
| 408 | if (iommu_id < 0 || iommu_id >= g_num_of_iommus) | ||
| 409 | return NULL; | ||
| 410 | |||
| 411 | return g_iommus[iommu_id]; | ||
| 412 | } | ||
| 413 | |||
| 414 | /* "Coherency" capability may be different across iommus */ | ||
| 415 | static void domain_update_iommu_coherency(struct dmar_domain *domain) | ||
| 416 | { | ||
| 417 | int i; | ||
| 418 | |||
| 419 | domain->iommu_coherency = 1; | ||
| 420 | |||
| 421 | i = find_first_bit(&domain->iommu_bmp, g_num_of_iommus); | ||
| 422 | for (; i < g_num_of_iommus; ) { | ||
| 423 | if (!ecap_coherent(g_iommus[i]->ecap)) { | ||
| 424 | domain->iommu_coherency = 0; | ||
| 425 | break; | ||
| 426 | } | ||
| 427 | i = find_next_bit(&domain->iommu_bmp, g_num_of_iommus, i+1); | ||
| 428 | } | ||
| 429 | } | ||
| 430 | |||
| 431 | static struct intel_iommu *device_to_iommu(u8 bus, u8 devfn) | ||
| 432 | { | ||
| 433 | struct dmar_drhd_unit *drhd = NULL; | ||
| 434 | int i; | ||
| 435 | |||
| 436 | for_each_drhd_unit(drhd) { | ||
| 437 | if (drhd->ignored) | ||
| 438 | continue; | ||
| 439 | |||
| 440 | for (i = 0; i < drhd->devices_cnt; i++) | ||
| 441 | if (drhd->devices[i]->bus->number == bus && | ||
| 442 | drhd->devices[i]->devfn == devfn) | ||
| 443 | return drhd->iommu; | ||
| 444 | |||
| 445 | if (drhd->include_all) | ||
| 446 | return drhd->iommu; | ||
| 447 | } | ||
| 448 | |||
| 449 | return NULL; | ||
| 450 | } | ||
| 451 | |||
| 452 | static void domain_flush_cache(struct dmar_domain *domain, | ||
| 453 | void *addr, int size) | ||
| 454 | { | ||
| 455 | if (!domain->iommu_coherency) | ||
| 456 | clflush_cache_range(addr, size); | ||
| 457 | } | ||
| 458 | |||
| 187 | /* Gets context entry for a given bus and devfn */ | 459 | /* Gets context entry for a given bus and devfn */ |
| 188 | static struct context_entry * device_to_context_entry(struct intel_iommu *iommu, | 460 | static struct context_entry * device_to_context_entry(struct intel_iommu *iommu, |
| 189 | u8 bus, u8 devfn) | 461 | u8 bus, u8 devfn) |
| @@ -226,7 +498,7 @@ static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn) | |||
| 226 | ret = 0; | 498 | ret = 0; |
| 227 | goto out; | 499 | goto out; |
| 228 | } | 500 | } |
| 229 | ret = context_present(context[devfn]); | 501 | ret = context_present(&context[devfn]); |
| 230 | out: | 502 | out: |
| 231 | spin_unlock_irqrestore(&iommu->lock, flags); | 503 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 232 | return ret; | 504 | return ret; |
| @@ -242,7 +514,7 @@ static void clear_context_table(struct intel_iommu *iommu, u8 bus, u8 devfn) | |||
| 242 | root = &iommu->root_entry[bus]; | 514 | root = &iommu->root_entry[bus]; |
| 243 | context = get_context_addr_from_root(root); | 515 | context = get_context_addr_from_root(root); |
| 244 | if (context) { | 516 | if (context) { |
| 245 | context_clear_entry(context[devfn]); | 517 | context_clear_entry(&context[devfn]); |
| 246 | __iommu_flush_cache(iommu, &context[devfn], \ | 518 | __iommu_flush_cache(iommu, &context[devfn], \ |
| 247 | sizeof(*context)); | 519 | sizeof(*context)); |
| 248 | } | 520 | } |
| @@ -339,7 +611,7 @@ static struct dma_pte * addr_to_dma_pte(struct dmar_domain *domain, u64 addr) | |||
| 339 | if (level == 1) | 611 | if (level == 1) |
| 340 | break; | 612 | break; |
| 341 | 613 | ||
| 342 | if (!dma_pte_present(*pte)) { | 614 | if (!dma_pte_present(pte)) { |
| 343 | tmp_page = alloc_pgtable_page(); | 615 | tmp_page = alloc_pgtable_page(); |
| 344 | 616 | ||
| 345 | if (!tmp_page) { | 617 | if (!tmp_page) { |
| @@ -347,18 +619,17 @@ static struct dma_pte * addr_to_dma_pte(struct dmar_domain *domain, u64 addr) | |||
| 347 | flags); | 619 | flags); |
| 348 | return NULL; | 620 | return NULL; |
| 349 | } | 621 | } |
| 350 | __iommu_flush_cache(domain->iommu, tmp_page, | 622 | domain_flush_cache(domain, tmp_page, PAGE_SIZE); |
| 351 | PAGE_SIZE); | 623 | dma_set_pte_addr(pte, virt_to_phys(tmp_page)); |
| 352 | dma_set_pte_addr(*pte, virt_to_phys(tmp_page)); | ||
| 353 | /* | 624 | /* |
| 354 | * high level table always sets r/w, last level page | 625 | * high level table always sets r/w, last level page |
| 355 | * table control read/write | 626 | * table control read/write |
| 356 | */ | 627 | */ |
| 357 | dma_set_pte_readable(*pte); | 628 | dma_set_pte_readable(pte); |
| 358 | dma_set_pte_writable(*pte); | 629 | dma_set_pte_writable(pte); |
| 359 | __iommu_flush_cache(domain->iommu, pte, sizeof(*pte)); | 630 | domain_flush_cache(domain, pte, sizeof(*pte)); |
| 360 | } | 631 | } |
| 361 | parent = phys_to_virt(dma_pte_addr(*pte)); | 632 | parent = phys_to_virt(dma_pte_addr(pte)); |
| 362 | level--; | 633 | level--; |
| 363 | } | 634 | } |
| 364 | 635 | ||
| @@ -381,9 +652,9 @@ static struct dma_pte *dma_addr_level_pte(struct dmar_domain *domain, u64 addr, | |||
| 381 | if (level == total) | 652 | if (level == total) |
| 382 | return pte; | 653 | return pte; |
| 383 | 654 | ||
| 384 | if (!dma_pte_present(*pte)) | 655 | if (!dma_pte_present(pte)) |
| 385 | break; | 656 | break; |
| 386 | parent = phys_to_virt(dma_pte_addr(*pte)); | 657 | parent = phys_to_virt(dma_pte_addr(pte)); |
| 387 | total--; | 658 | total--; |
| 388 | } | 659 | } |
| 389 | return NULL; | 660 | return NULL; |
| @@ -398,8 +669,8 @@ static void dma_pte_clear_one(struct dmar_domain *domain, u64 addr) | |||
| 398 | pte = dma_addr_level_pte(domain, addr, 1); | 669 | pte = dma_addr_level_pte(domain, addr, 1); |
| 399 | 670 | ||
| 400 | if (pte) { | 671 | if (pte) { |
| 401 | dma_clear_pte(*pte); | 672 | dma_clear_pte(pte); |
| 402 | __iommu_flush_cache(domain->iommu, pte, sizeof(*pte)); | 673 | domain_flush_cache(domain, pte, sizeof(*pte)); |
| 403 | } | 674 | } |
| 404 | } | 675 | } |
| 405 | 676 | ||
| @@ -445,10 +716,9 @@ static void dma_pte_free_pagetable(struct dmar_domain *domain, | |||
| 445 | pte = dma_addr_level_pte(domain, tmp, level); | 716 | pte = dma_addr_level_pte(domain, tmp, level); |
| 446 | if (pte) { | 717 | if (pte) { |
| 447 | free_pgtable_page( | 718 | free_pgtable_page( |
| 448 | phys_to_virt(dma_pte_addr(*pte))); | 719 | phys_to_virt(dma_pte_addr(pte))); |
| 449 | dma_clear_pte(*pte); | 720 | dma_clear_pte(pte); |
| 450 | __iommu_flush_cache(domain->iommu, | 721 | domain_flush_cache(domain, pte, sizeof(*pte)); |
| 451 | pte, sizeof(*pte)); | ||
| 452 | } | 722 | } |
| 453 | tmp += level_size(level); | 723 | tmp += level_size(level); |
| 454 | } | 724 | } |
| @@ -950,17 +1220,28 @@ static int iommu_init_domains(struct intel_iommu *iommu) | |||
| 950 | 1220 | ||
| 951 | 1221 | ||
| 952 | static void domain_exit(struct dmar_domain *domain); | 1222 | static void domain_exit(struct dmar_domain *domain); |
| 1223 | static void vm_domain_exit(struct dmar_domain *domain); | ||
| 953 | 1224 | ||
| 954 | void free_dmar_iommu(struct intel_iommu *iommu) | 1225 | void free_dmar_iommu(struct intel_iommu *iommu) |
| 955 | { | 1226 | { |
| 956 | struct dmar_domain *domain; | 1227 | struct dmar_domain *domain; |
| 957 | int i; | 1228 | int i; |
| 1229 | unsigned long flags; | ||
| 958 | 1230 | ||
| 959 | i = find_first_bit(iommu->domain_ids, cap_ndoms(iommu->cap)); | 1231 | i = find_first_bit(iommu->domain_ids, cap_ndoms(iommu->cap)); |
| 960 | for (; i < cap_ndoms(iommu->cap); ) { | 1232 | for (; i < cap_ndoms(iommu->cap); ) { |
| 961 | domain = iommu->domains[i]; | 1233 | domain = iommu->domains[i]; |
| 962 | clear_bit(i, iommu->domain_ids); | 1234 | clear_bit(i, iommu->domain_ids); |
| 963 | domain_exit(domain); | 1235 | |
| 1236 | spin_lock_irqsave(&domain->iommu_lock, flags); | ||
| 1237 | if (--domain->iommu_count == 0) { | ||
| 1238 | if (domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) | ||
| 1239 | vm_domain_exit(domain); | ||
| 1240 | else | ||
| 1241 | domain_exit(domain); | ||
| 1242 | } | ||
| 1243 | spin_unlock_irqrestore(&domain->iommu_lock, flags); | ||
| 1244 | |||
| 964 | i = find_next_bit(iommu->domain_ids, | 1245 | i = find_next_bit(iommu->domain_ids, |
| 965 | cap_ndoms(iommu->cap), i+1); | 1246 | cap_ndoms(iommu->cap), i+1); |
| 966 | } | 1247 | } |
| @@ -978,6 +1259,17 @@ void free_dmar_iommu(struct intel_iommu *iommu) | |||
| 978 | kfree(iommu->domains); | 1259 | kfree(iommu->domains); |
| 979 | kfree(iommu->domain_ids); | 1260 | kfree(iommu->domain_ids); |
| 980 | 1261 | ||
| 1262 | g_iommus[iommu->seq_id] = NULL; | ||
| 1263 | |||
| 1264 | /* if all iommus are freed, free g_iommus */ | ||
| 1265 | for (i = 0; i < g_num_of_iommus; i++) { | ||
| 1266 | if (g_iommus[i]) | ||
| 1267 | break; | ||
| 1268 | } | ||
| 1269 | |||
| 1270 | if (i == g_num_of_iommus) | ||
| 1271 | kfree(g_iommus); | ||
| 1272 | |||
| 981 | /* free context mapping */ | 1273 | /* free context mapping */ |
| 982 | free_context_table(iommu); | 1274 | free_context_table(iommu); |
| 983 | } | 1275 | } |
| @@ -1006,7 +1298,9 @@ static struct dmar_domain * iommu_alloc_domain(struct intel_iommu *iommu) | |||
| 1006 | 1298 | ||
| 1007 | set_bit(num, iommu->domain_ids); | 1299 | set_bit(num, iommu->domain_ids); |
| 1008 | domain->id = num; | 1300 | domain->id = num; |
| 1009 | domain->iommu = iommu; | 1301 | memset(&domain->iommu_bmp, 0, sizeof(unsigned long)); |
| 1302 | set_bit(iommu->seq_id, &domain->iommu_bmp); | ||
| 1303 | domain->flags = 0; | ||
| 1010 | iommu->domains[num] = domain; | 1304 | iommu->domains[num] = domain; |
| 1011 | spin_unlock_irqrestore(&iommu->lock, flags); | 1305 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 1012 | 1306 | ||
| @@ -1016,10 +1310,13 @@ static struct dmar_domain * iommu_alloc_domain(struct intel_iommu *iommu) | |||
| 1016 | static void iommu_free_domain(struct dmar_domain *domain) | 1310 | static void iommu_free_domain(struct dmar_domain *domain) |
| 1017 | { | 1311 | { |
| 1018 | unsigned long flags; | 1312 | unsigned long flags; |
| 1313 | struct intel_iommu *iommu; | ||
| 1314 | |||
| 1315 | iommu = domain_get_iommu(domain); | ||
| 1019 | 1316 | ||
| 1020 | spin_lock_irqsave(&domain->iommu->lock, flags); | 1317 | spin_lock_irqsave(&iommu->lock, flags); |
| 1021 | clear_bit(domain->id, domain->iommu->domain_ids); | 1318 | clear_bit(domain->id, iommu->domain_ids); |
| 1022 | spin_unlock_irqrestore(&domain->iommu->lock, flags); | 1319 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 1023 | } | 1320 | } |
| 1024 | 1321 | ||
| 1025 | static struct iova_domain reserved_iova_list; | 1322 | static struct iova_domain reserved_iova_list; |
| @@ -1094,11 +1391,12 @@ static int domain_init(struct dmar_domain *domain, int guest_width) | |||
| 1094 | 1391 | ||
| 1095 | init_iova_domain(&domain->iovad, DMA_32BIT_PFN); | 1392 | init_iova_domain(&domain->iovad, DMA_32BIT_PFN); |
| 1096 | spin_lock_init(&domain->mapping_lock); | 1393 | spin_lock_init(&domain->mapping_lock); |
| 1394 | spin_lock_init(&domain->iommu_lock); | ||
| 1097 | 1395 | ||
| 1098 | domain_reserve_special_ranges(domain); | 1396 | domain_reserve_special_ranges(domain); |
| 1099 | 1397 | ||
| 1100 | /* calculate AGAW */ | 1398 | /* calculate AGAW */ |
| 1101 | iommu = domain->iommu; | 1399 | iommu = domain_get_iommu(domain); |
| 1102 | if (guest_width > cap_mgaw(iommu->cap)) | 1400 | if (guest_width > cap_mgaw(iommu->cap)) |
| 1103 | guest_width = cap_mgaw(iommu->cap); | 1401 | guest_width = cap_mgaw(iommu->cap); |
| 1104 | domain->gaw = guest_width; | 1402 | domain->gaw = guest_width; |
| @@ -1115,6 +1413,13 @@ static int domain_init(struct dmar_domain *domain, int guest_width) | |||
| 1115 | domain->agaw = agaw; | 1413 | domain->agaw = agaw; |
| 1116 | INIT_LIST_HEAD(&domain->devices); | 1414 | INIT_LIST_HEAD(&domain->devices); |
| 1117 | 1415 | ||
| 1416 | if (ecap_coherent(iommu->ecap)) | ||
| 1417 | domain->iommu_coherency = 1; | ||
| 1418 | else | ||
| 1419 | domain->iommu_coherency = 0; | ||
| 1420 | |||
| 1421 | domain->iommu_count = 1; | ||
| 1422 | |||
| 1118 | /* always allocate the top pgd */ | 1423 | /* always allocate the top pgd */ |
| 1119 | domain->pgd = (struct dma_pte *)alloc_pgtable_page(); | 1424 | domain->pgd = (struct dma_pte *)alloc_pgtable_page(); |
| 1120 | if (!domain->pgd) | 1425 | if (!domain->pgd) |
| @@ -1151,28 +1456,82 @@ static int domain_context_mapping_one(struct dmar_domain *domain, | |||
| 1151 | u8 bus, u8 devfn) | 1456 | u8 bus, u8 devfn) |
| 1152 | { | 1457 | { |
| 1153 | struct context_entry *context; | 1458 | struct context_entry *context; |
| 1154 | struct intel_iommu *iommu = domain->iommu; | ||
| 1155 | unsigned long flags; | 1459 | unsigned long flags; |
| 1460 | struct intel_iommu *iommu; | ||
| 1461 | struct dma_pte *pgd; | ||
| 1462 | unsigned long num; | ||
| 1463 | unsigned long ndomains; | ||
| 1464 | int id; | ||
| 1465 | int agaw; | ||
| 1156 | 1466 | ||
| 1157 | pr_debug("Set context mapping for %02x:%02x.%d\n", | 1467 | pr_debug("Set context mapping for %02x:%02x.%d\n", |
| 1158 | bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); | 1468 | bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); |
| 1159 | BUG_ON(!domain->pgd); | 1469 | BUG_ON(!domain->pgd); |
| 1470 | |||
| 1471 | iommu = device_to_iommu(bus, devfn); | ||
| 1472 | if (!iommu) | ||
| 1473 | return -ENODEV; | ||
| 1474 | |||
| 1160 | context = device_to_context_entry(iommu, bus, devfn); | 1475 | context = device_to_context_entry(iommu, bus, devfn); |
| 1161 | if (!context) | 1476 | if (!context) |
| 1162 | return -ENOMEM; | 1477 | return -ENOMEM; |
| 1163 | spin_lock_irqsave(&iommu->lock, flags); | 1478 | spin_lock_irqsave(&iommu->lock, flags); |
| 1164 | if (context_present(*context)) { | 1479 | if (context_present(context)) { |
| 1165 | spin_unlock_irqrestore(&iommu->lock, flags); | 1480 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 1166 | return 0; | 1481 | return 0; |
| 1167 | } | 1482 | } |
| 1168 | 1483 | ||
| 1169 | context_set_domain_id(*context, domain->id); | 1484 | id = domain->id; |
| 1170 | context_set_address_width(*context, domain->agaw); | 1485 | pgd = domain->pgd; |
| 1171 | context_set_address_root(*context, virt_to_phys(domain->pgd)); | 1486 | |
| 1172 | context_set_translation_type(*context, CONTEXT_TT_MULTI_LEVEL); | 1487 | if (domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) { |
| 1173 | context_set_fault_enable(*context); | 1488 | int found = 0; |
| 1174 | context_set_present(*context); | 1489 | |
| 1175 | __iommu_flush_cache(iommu, context, sizeof(*context)); | 1490 | /* find an available domain id for this device in iommu */ |
| 1491 | ndomains = cap_ndoms(iommu->cap); | ||
| 1492 | num = find_first_bit(iommu->domain_ids, ndomains); | ||
| 1493 | for (; num < ndomains; ) { | ||
| 1494 | if (iommu->domains[num] == domain) { | ||
| 1495 | id = num; | ||
| 1496 | found = 1; | ||
| 1497 | break; | ||
| 1498 | } | ||
| 1499 | num = find_next_bit(iommu->domain_ids, | ||
| 1500 | cap_ndoms(iommu->cap), num+1); | ||
| 1501 | } | ||
| 1502 | |||
| 1503 | if (found == 0) { | ||
| 1504 | num = find_first_zero_bit(iommu->domain_ids, ndomains); | ||
| 1505 | if (num >= ndomains) { | ||
| 1506 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
| 1507 | printk(KERN_ERR "IOMMU: no free domain ids\n"); | ||
| 1508 | return -EFAULT; | ||
| 1509 | } | ||
| 1510 | |||
| 1511 | set_bit(num, iommu->domain_ids); | ||
| 1512 | iommu->domains[num] = domain; | ||
| 1513 | id = num; | ||
| 1514 | } | ||
| 1515 | |||
| 1516 | /* Skip top levels of page tables for | ||
| 1517 | * iommu which has less agaw than default. | ||
| 1518 | */ | ||
| 1519 | for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) { | ||
| 1520 | pgd = phys_to_virt(dma_pte_addr(pgd)); | ||
| 1521 | if (!dma_pte_present(pgd)) { | ||
| 1522 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
| 1523 | return -ENOMEM; | ||
| 1524 | } | ||
| 1525 | } | ||
| 1526 | } | ||
| 1527 | |||
| 1528 | context_set_domain_id(context, id); | ||
| 1529 | context_set_address_width(context, iommu->agaw); | ||
| 1530 | context_set_address_root(context, virt_to_phys(pgd)); | ||
| 1531 | context_set_translation_type(context, CONTEXT_TT_MULTI_LEVEL); | ||
| 1532 | context_set_fault_enable(context); | ||
| 1533 | context_set_present(context); | ||
| 1534 | domain_flush_cache(domain, context, sizeof(*context)); | ||
| 1176 | 1535 | ||
| 1177 | /* it's a non-present to present mapping */ | 1536 | /* it's a non-present to present mapping */ |
| 1178 | if (iommu->flush.flush_context(iommu, domain->id, | 1537 | if (iommu->flush.flush_context(iommu, domain->id, |
| @@ -1183,6 +1542,13 @@ static int domain_context_mapping_one(struct dmar_domain *domain, | |||
| 1183 | iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_DSI_FLUSH, 0); | 1542 | iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_DSI_FLUSH, 0); |
| 1184 | 1543 | ||
| 1185 | spin_unlock_irqrestore(&iommu->lock, flags); | 1544 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 1545 | |||
| 1546 | spin_lock_irqsave(&domain->iommu_lock, flags); | ||
| 1547 | if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) { | ||
| 1548 | domain->iommu_count++; | ||
| 1549 | domain_update_iommu_coherency(domain); | ||
| 1550 | } | ||
| 1551 | spin_unlock_irqrestore(&domain->iommu_lock, flags); | ||
| 1186 | return 0; | 1552 | return 0; |
| 1187 | } | 1553 | } |
| 1188 | 1554 | ||
| @@ -1218,13 +1584,17 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev) | |||
| 1218 | tmp->bus->number, tmp->devfn); | 1584 | tmp->bus->number, tmp->devfn); |
| 1219 | } | 1585 | } |
| 1220 | 1586 | ||
| 1221 | static int domain_context_mapped(struct dmar_domain *domain, | 1587 | static int domain_context_mapped(struct pci_dev *pdev) |
| 1222 | struct pci_dev *pdev) | ||
| 1223 | { | 1588 | { |
| 1224 | int ret; | 1589 | int ret; |
| 1225 | struct pci_dev *tmp, *parent; | 1590 | struct pci_dev *tmp, *parent; |
| 1591 | struct intel_iommu *iommu; | ||
| 1592 | |||
| 1593 | iommu = device_to_iommu(pdev->bus->number, pdev->devfn); | ||
| 1594 | if (!iommu) | ||
| 1595 | return -ENODEV; | ||
| 1226 | 1596 | ||
| 1227 | ret = device_context_mapped(domain->iommu, | 1597 | ret = device_context_mapped(iommu, |
| 1228 | pdev->bus->number, pdev->devfn); | 1598 | pdev->bus->number, pdev->devfn); |
| 1229 | if (!ret) | 1599 | if (!ret) |
| 1230 | return ret; | 1600 | return ret; |
| @@ -1235,17 +1605,17 @@ static int domain_context_mapped(struct dmar_domain *domain, | |||
| 1235 | /* Secondary interface's bus number and devfn 0 */ | 1605 | /* Secondary interface's bus number and devfn 0 */ |
| 1236 | parent = pdev->bus->self; | 1606 | parent = pdev->bus->self; |
| 1237 | while (parent != tmp) { | 1607 | while (parent != tmp) { |
| 1238 | ret = device_context_mapped(domain->iommu, parent->bus->number, | 1608 | ret = device_context_mapped(iommu, parent->bus->number, |
| 1239 | parent->devfn); | 1609 | parent->devfn); |
| 1240 | if (!ret) | 1610 | if (!ret) |
| 1241 | return ret; | 1611 | return ret; |
| 1242 | parent = parent->bus->self; | 1612 | parent = parent->bus->self; |
| 1243 | } | 1613 | } |
| 1244 | if (tmp->is_pcie) | 1614 | if (tmp->is_pcie) |
| 1245 | return device_context_mapped(domain->iommu, | 1615 | return device_context_mapped(iommu, |
| 1246 | tmp->subordinate->number, 0); | 1616 | tmp->subordinate->number, 0); |
| 1247 | else | 1617 | else |
| 1248 | return device_context_mapped(domain->iommu, | 1618 | return device_context_mapped(iommu, |
| 1249 | tmp->bus->number, tmp->devfn); | 1619 | tmp->bus->number, tmp->devfn); |
| 1250 | } | 1620 | } |
| 1251 | 1621 | ||
| @@ -1273,22 +1643,25 @@ domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova, | |||
| 1273 | /* We don't need lock here, nobody else | 1643 | /* We don't need lock here, nobody else |
| 1274 | * touches the iova range | 1644 | * touches the iova range |
| 1275 | */ | 1645 | */ |
| 1276 | BUG_ON(dma_pte_addr(*pte)); | 1646 | BUG_ON(dma_pte_addr(pte)); |
| 1277 | dma_set_pte_addr(*pte, start_pfn << VTD_PAGE_SHIFT); | 1647 | dma_set_pte_addr(pte, start_pfn << VTD_PAGE_SHIFT); |
| 1278 | dma_set_pte_prot(*pte, prot); | 1648 | dma_set_pte_prot(pte, prot); |
| 1279 | __iommu_flush_cache(domain->iommu, pte, sizeof(*pte)); | 1649 | domain_flush_cache(domain, pte, sizeof(*pte)); |
| 1280 | start_pfn++; | 1650 | start_pfn++; |
| 1281 | index++; | 1651 | index++; |
| 1282 | } | 1652 | } |
| 1283 | return 0; | 1653 | return 0; |
| 1284 | } | 1654 | } |
| 1285 | 1655 | ||
| 1286 | static void detach_domain_for_dev(struct dmar_domain *domain, u8 bus, u8 devfn) | 1656 | static void iommu_detach_dev(struct intel_iommu *iommu, u8 bus, u8 devfn) |
| 1287 | { | 1657 | { |
| 1288 | clear_context_table(domain->iommu, bus, devfn); | 1658 | if (!iommu) |
| 1289 | domain->iommu->flush.flush_context(domain->iommu, 0, 0, 0, | 1659 | return; |
| 1660 | |||
| 1661 | clear_context_table(iommu, bus, devfn); | ||
| 1662 | iommu->flush.flush_context(iommu, 0, 0, 0, | ||
| 1290 | DMA_CCMD_GLOBAL_INVL, 0); | 1663 | DMA_CCMD_GLOBAL_INVL, 0); |
| 1291 | domain->iommu->flush.flush_iotlb(domain->iommu, 0, 0, 0, | 1664 | iommu->flush.flush_iotlb(iommu, 0, 0, 0, |
| 1292 | DMA_TLB_GLOBAL_FLUSH, 0); | 1665 | DMA_TLB_GLOBAL_FLUSH, 0); |
| 1293 | } | 1666 | } |
| 1294 | 1667 | ||
| @@ -1296,6 +1669,7 @@ static void domain_remove_dev_info(struct dmar_domain *domain) | |||
| 1296 | { | 1669 | { |
| 1297 | struct device_domain_info *info; | 1670 | struct device_domain_info *info; |
| 1298 | unsigned long flags; | 1671 | unsigned long flags; |
| 1672 | struct intel_iommu *iommu; | ||
| 1299 | 1673 | ||
| 1300 | spin_lock_irqsave(&device_domain_lock, flags); | 1674 | spin_lock_irqsave(&device_domain_lock, flags); |
| 1301 | while (!list_empty(&domain->devices)) { | 1675 | while (!list_empty(&domain->devices)) { |
| @@ -1307,7 +1681,8 @@ static void domain_remove_dev_info(struct dmar_domain *domain) | |||
| 1307 | info->dev->dev.archdata.iommu = NULL; | 1681 | info->dev->dev.archdata.iommu = NULL; |
| 1308 | spin_unlock_irqrestore(&device_domain_lock, flags); | 1682 | spin_unlock_irqrestore(&device_domain_lock, flags); |
| 1309 | 1683 | ||
| 1310 | detach_domain_for_dev(info->domain, info->bus, info->devfn); | 1684 | iommu = device_to_iommu(info->bus, info->devfn); |
| 1685 | iommu_detach_dev(iommu, info->bus, info->devfn); | ||
| 1311 | free_devinfo_mem(info); | 1686 | free_devinfo_mem(info); |
| 1312 | 1687 | ||
| 1313 | spin_lock_irqsave(&device_domain_lock, flags); | 1688 | spin_lock_irqsave(&device_domain_lock, flags); |
| @@ -1400,7 +1775,7 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) | |||
| 1400 | info->dev = NULL; | 1775 | info->dev = NULL; |
| 1401 | info->domain = domain; | 1776 | info->domain = domain; |
| 1402 | /* This domain is shared by devices under p2p bridge */ | 1777 | /* This domain is shared by devices under p2p bridge */ |
| 1403 | domain->flags |= DOMAIN_FLAG_MULTIPLE_DEVICES; | 1778 | domain->flags |= DOMAIN_FLAG_P2P_MULTIPLE_DEVICES; |
| 1404 | 1779 | ||
| 1405 | /* pcie-to-pci bridge already has a domain, uses it */ | 1780 | /* pcie-to-pci bridge already has a domain, uses it */ |
| 1406 | found = NULL; | 1781 | found = NULL; |
| @@ -1563,6 +1938,11 @@ static void __init iommu_prepare_gfx_mapping(void) | |||
| 1563 | printk(KERN_ERR "IOMMU: mapping reserved region failed\n"); | 1938 | printk(KERN_ERR "IOMMU: mapping reserved region failed\n"); |
| 1564 | } | 1939 | } |
| 1565 | } | 1940 | } |
| 1941 | #else /* !CONFIG_DMAR_GFX_WA */ | ||
| 1942 | static inline void iommu_prepare_gfx_mapping(void) | ||
| 1943 | { | ||
| 1944 | return; | ||
| 1945 | } | ||
| 1566 | #endif | 1946 | #endif |
| 1567 | 1947 | ||
| 1568 | #ifdef CONFIG_DMAR_FLOPPY_WA | 1948 | #ifdef CONFIG_DMAR_FLOPPY_WA |
| @@ -1590,7 +1970,7 @@ static inline void iommu_prepare_isa(void) | |||
| 1590 | } | 1970 | } |
| 1591 | #endif /* !CONFIG_DMAR_FLPY_WA */ | 1971 | #endif /* !CONFIG_DMAR_FLPY_WA */ |
| 1592 | 1972 | ||
| 1593 | int __init init_dmars(void) | 1973 | static int __init init_dmars(void) |
| 1594 | { | 1974 | { |
| 1595 | struct dmar_drhd_unit *drhd; | 1975 | struct dmar_drhd_unit *drhd; |
| 1596 | struct dmar_rmrr_unit *rmrr; | 1976 | struct dmar_rmrr_unit *rmrr; |
| @@ -1613,9 +1993,18 @@ int __init init_dmars(void) | |||
| 1613 | */ | 1993 | */ |
| 1614 | } | 1994 | } |
| 1615 | 1995 | ||
| 1996 | g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *), | ||
| 1997 | GFP_KERNEL); | ||
| 1998 | if (!g_iommus) { | ||
| 1999 | printk(KERN_ERR "Allocating global iommu array failed\n"); | ||
| 2000 | ret = -ENOMEM; | ||
| 2001 | goto error; | ||
| 2002 | } | ||
| 2003 | |||
| 1616 | deferred_flush = kzalloc(g_num_of_iommus * | 2004 | deferred_flush = kzalloc(g_num_of_iommus * |
| 1617 | sizeof(struct deferred_flush_tables), GFP_KERNEL); | 2005 | sizeof(struct deferred_flush_tables), GFP_KERNEL); |
| 1618 | if (!deferred_flush) { | 2006 | if (!deferred_flush) { |
| 2007 | kfree(g_iommus); | ||
| 1619 | ret = -ENOMEM; | 2008 | ret = -ENOMEM; |
| 1620 | goto error; | 2009 | goto error; |
| 1621 | } | 2010 | } |
| @@ -1625,6 +2014,7 @@ int __init init_dmars(void) | |||
| 1625 | continue; | 2014 | continue; |
| 1626 | 2015 | ||
| 1627 | iommu = drhd->iommu; | 2016 | iommu = drhd->iommu; |
| 2017 | g_iommus[iommu->seq_id] = iommu; | ||
| 1628 | 2018 | ||
| 1629 | ret = iommu_init_domains(iommu); | 2019 | ret = iommu_init_domains(iommu); |
| 1630 | if (ret) | 2020 | if (ret) |
| @@ -1737,6 +2127,7 @@ error: | |||
| 1737 | iommu = drhd->iommu; | 2127 | iommu = drhd->iommu; |
| 1738 | free_iommu(iommu); | 2128 | free_iommu(iommu); |
| 1739 | } | 2129 | } |
| 2130 | kfree(g_iommus); | ||
| 1740 | return ret; | 2131 | return ret; |
| 1741 | } | 2132 | } |
| 1742 | 2133 | ||
| @@ -1805,7 +2196,7 @@ get_valid_domain_for_dev(struct pci_dev *pdev) | |||
| 1805 | } | 2196 | } |
| 1806 | 2197 | ||
| 1807 | /* make sure context mapping is ok */ | 2198 | /* make sure context mapping is ok */ |
| 1808 | if (unlikely(!domain_context_mapped(domain, pdev))) { | 2199 | if (unlikely(!domain_context_mapped(pdev))) { |
| 1809 | ret = domain_context_mapping(domain, pdev); | 2200 | ret = domain_context_mapping(domain, pdev); |
| 1810 | if (ret) { | 2201 | if (ret) { |
| 1811 | printk(KERN_ERR | 2202 | printk(KERN_ERR |
| @@ -1827,6 +2218,7 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, | |||
| 1827 | struct iova *iova; | 2218 | struct iova *iova; |
| 1828 | int prot = 0; | 2219 | int prot = 0; |
| 1829 | int ret; | 2220 | int ret; |
| 2221 | struct intel_iommu *iommu; | ||
| 1830 | 2222 | ||
| 1831 | BUG_ON(dir == DMA_NONE); | 2223 | BUG_ON(dir == DMA_NONE); |
| 1832 | if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) | 2224 | if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) |
| @@ -1836,6 +2228,7 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, | |||
| 1836 | if (!domain) | 2228 | if (!domain) |
| 1837 | return 0; | 2229 | return 0; |
| 1838 | 2230 | ||
| 2231 | iommu = domain_get_iommu(domain); | ||
| 1839 | size = aligned_size((u64)paddr, size); | 2232 | size = aligned_size((u64)paddr, size); |
| 1840 | 2233 | ||
| 1841 | iova = __intel_alloc_iova(hwdev, domain, size, pdev->dma_mask); | 2234 | iova = __intel_alloc_iova(hwdev, domain, size, pdev->dma_mask); |
| @@ -1849,7 +2242,7 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, | |||
| 1849 | * mappings.. | 2242 | * mappings.. |
| 1850 | */ | 2243 | */ |
| 1851 | if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \ | 2244 | if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \ |
| 1852 | !cap_zlr(domain->iommu->cap)) | 2245 | !cap_zlr(iommu->cap)) |
| 1853 | prot |= DMA_PTE_READ; | 2246 | prot |= DMA_PTE_READ; |
| 1854 | if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) | 2247 | if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) |
| 1855 | prot |= DMA_PTE_WRITE; | 2248 | prot |= DMA_PTE_WRITE; |
| @@ -1865,10 +2258,10 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, | |||
| 1865 | goto error; | 2258 | goto error; |
| 1866 | 2259 | ||
| 1867 | /* it's a non-present to present mapping */ | 2260 | /* it's a non-present to present mapping */ |
| 1868 | ret = iommu_flush_iotlb_psi(domain->iommu, domain->id, | 2261 | ret = iommu_flush_iotlb_psi(iommu, domain->id, |
| 1869 | start_paddr, size >> VTD_PAGE_SHIFT, 1); | 2262 | start_paddr, size >> VTD_PAGE_SHIFT, 1); |
| 1870 | if (ret) | 2263 | if (ret) |
| 1871 | iommu_flush_write_buffer(domain->iommu); | 2264 | iommu_flush_write_buffer(iommu); |
| 1872 | 2265 | ||
| 1873 | return start_paddr + ((u64)paddr & (~PAGE_MASK)); | 2266 | return start_paddr + ((u64)paddr & (~PAGE_MASK)); |
| 1874 | 2267 | ||
| @@ -1895,10 +2288,11 @@ static void flush_unmaps(void) | |||
| 1895 | 2288 | ||
| 1896 | /* just flush them all */ | 2289 | /* just flush them all */ |
| 1897 | for (i = 0; i < g_num_of_iommus; i++) { | 2290 | for (i = 0; i < g_num_of_iommus; i++) { |
| 1898 | if (deferred_flush[i].next) { | 2291 | struct intel_iommu *iommu = g_iommus[i]; |
| 1899 | struct intel_iommu *iommu = | 2292 | if (!iommu) |
| 1900 | deferred_flush[i].domain[0]->iommu; | 2293 | continue; |
| 1901 | 2294 | ||
| 2295 | if (deferred_flush[i].next) { | ||
| 1902 | iommu->flush.flush_iotlb(iommu, 0, 0, 0, | 2296 | iommu->flush.flush_iotlb(iommu, 0, 0, 0, |
| 1903 | DMA_TLB_GLOBAL_FLUSH, 0); | 2297 | DMA_TLB_GLOBAL_FLUSH, 0); |
| 1904 | for (j = 0; j < deferred_flush[i].next; j++) { | 2298 | for (j = 0; j < deferred_flush[i].next; j++) { |
| @@ -1925,12 +2319,14 @@ static void add_unmap(struct dmar_domain *dom, struct iova *iova) | |||
| 1925 | { | 2319 | { |
| 1926 | unsigned long flags; | 2320 | unsigned long flags; |
| 1927 | int next, iommu_id; | 2321 | int next, iommu_id; |
| 2322 | struct intel_iommu *iommu; | ||
| 1928 | 2323 | ||
| 1929 | spin_lock_irqsave(&async_umap_flush_lock, flags); | 2324 | spin_lock_irqsave(&async_umap_flush_lock, flags); |
| 1930 | if (list_size == HIGH_WATER_MARK) | 2325 | if (list_size == HIGH_WATER_MARK) |
| 1931 | flush_unmaps(); | 2326 | flush_unmaps(); |
| 1932 | 2327 | ||
| 1933 | iommu_id = dom->iommu->seq_id; | 2328 | iommu = domain_get_iommu(dom); |
| 2329 | iommu_id = iommu->seq_id; | ||
| 1934 | 2330 | ||
| 1935 | next = deferred_flush[iommu_id].next; | 2331 | next = deferred_flush[iommu_id].next; |
| 1936 | deferred_flush[iommu_id].domain[next] = dom; | 2332 | deferred_flush[iommu_id].domain[next] = dom; |
| @@ -1952,12 +2348,15 @@ void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size, | |||
| 1952 | struct dmar_domain *domain; | 2348 | struct dmar_domain *domain; |
| 1953 | unsigned long start_addr; | 2349 | unsigned long start_addr; |
| 1954 | struct iova *iova; | 2350 | struct iova *iova; |
| 2351 | struct intel_iommu *iommu; | ||
| 1955 | 2352 | ||
| 1956 | if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) | 2353 | if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) |
| 1957 | return; | 2354 | return; |
| 1958 | domain = find_domain(pdev); | 2355 | domain = find_domain(pdev); |
| 1959 | BUG_ON(!domain); | 2356 | BUG_ON(!domain); |
| 1960 | 2357 | ||
| 2358 | iommu = domain_get_iommu(domain); | ||
| 2359 | |||
| 1961 | iova = find_iova(&domain->iovad, IOVA_PFN(dev_addr)); | 2360 | iova = find_iova(&domain->iovad, IOVA_PFN(dev_addr)); |
| 1962 | if (!iova) | 2361 | if (!iova) |
| 1963 | return; | 2362 | return; |
| @@ -1973,9 +2372,9 @@ void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size, | |||
| 1973 | /* free page tables */ | 2372 | /* free page tables */ |
| 1974 | dma_pte_free_pagetable(domain, start_addr, start_addr + size); | 2373 | dma_pte_free_pagetable(domain, start_addr, start_addr + size); |
| 1975 | if (intel_iommu_strict) { | 2374 | if (intel_iommu_strict) { |
| 1976 | if (iommu_flush_iotlb_psi(domain->iommu, | 2375 | if (iommu_flush_iotlb_psi(iommu, |
| 1977 | domain->id, start_addr, size >> VTD_PAGE_SHIFT, 0)) | 2376 | domain->id, start_addr, size >> VTD_PAGE_SHIFT, 0)) |
| 1978 | iommu_flush_write_buffer(domain->iommu); | 2377 | iommu_flush_write_buffer(iommu); |
| 1979 | /* free iova */ | 2378 | /* free iova */ |
| 1980 | __free_iova(&domain->iovad, iova); | 2379 | __free_iova(&domain->iovad, iova); |
| 1981 | } else { | 2380 | } else { |
| @@ -2036,11 +2435,15 @@ void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, | |||
| 2036 | size_t size = 0; | 2435 | size_t size = 0; |
| 2037 | void *addr; | 2436 | void *addr; |
| 2038 | struct scatterlist *sg; | 2437 | struct scatterlist *sg; |
| 2438 | struct intel_iommu *iommu; | ||
| 2039 | 2439 | ||
| 2040 | if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) | 2440 | if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) |
| 2041 | return; | 2441 | return; |
| 2042 | 2442 | ||
| 2043 | domain = find_domain(pdev); | 2443 | domain = find_domain(pdev); |
| 2444 | BUG_ON(!domain); | ||
| 2445 | |||
| 2446 | iommu = domain_get_iommu(domain); | ||
| 2044 | 2447 | ||
| 2045 | iova = find_iova(&domain->iovad, IOVA_PFN(sglist[0].dma_address)); | 2448 | iova = find_iova(&domain->iovad, IOVA_PFN(sglist[0].dma_address)); |
| 2046 | if (!iova) | 2449 | if (!iova) |
| @@ -2057,9 +2460,9 @@ void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, | |||
| 2057 | /* free page tables */ | 2460 | /* free page tables */ |
| 2058 | dma_pte_free_pagetable(domain, start_addr, start_addr + size); | 2461 | dma_pte_free_pagetable(domain, start_addr, start_addr + size); |
| 2059 | 2462 | ||
| 2060 | if (iommu_flush_iotlb_psi(domain->iommu, domain->id, start_addr, | 2463 | if (iommu_flush_iotlb_psi(iommu, domain->id, start_addr, |
| 2061 | size >> VTD_PAGE_SHIFT, 0)) | 2464 | size >> VTD_PAGE_SHIFT, 0)) |
| 2062 | iommu_flush_write_buffer(domain->iommu); | 2465 | iommu_flush_write_buffer(iommu); |
| 2063 | 2466 | ||
| 2064 | /* free iova */ | 2467 | /* free iova */ |
| 2065 | __free_iova(&domain->iovad, iova); | 2468 | __free_iova(&domain->iovad, iova); |
| @@ -2093,6 +2496,7 @@ int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, | |||
| 2093 | int ret; | 2496 | int ret; |
| 2094 | struct scatterlist *sg; | 2497 | struct scatterlist *sg; |
| 2095 | unsigned long start_addr; | 2498 | unsigned long start_addr; |
| 2499 | struct intel_iommu *iommu; | ||
| 2096 | 2500 | ||
| 2097 | BUG_ON(dir == DMA_NONE); | 2501 | BUG_ON(dir == DMA_NONE); |
| 2098 | if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) | 2502 | if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) |
| @@ -2102,6 +2506,8 @@ int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, | |||
| 2102 | if (!domain) | 2506 | if (!domain) |
| 2103 | return 0; | 2507 | return 0; |
| 2104 | 2508 | ||
| 2509 | iommu = domain_get_iommu(domain); | ||
| 2510 | |||
| 2105 | for_each_sg(sglist, sg, nelems, i) { | 2511 | for_each_sg(sglist, sg, nelems, i) { |
| 2106 | addr = SG_ENT_VIRT_ADDRESS(sg); | 2512 | addr = SG_ENT_VIRT_ADDRESS(sg); |
| 2107 | addr = (void *)virt_to_phys(addr); | 2513 | addr = (void *)virt_to_phys(addr); |
| @@ -2119,7 +2525,7 @@ int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, | |||
| 2119 | * mappings.. | 2525 | * mappings.. |
| 2120 | */ | 2526 | */ |
| 2121 | if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \ | 2527 | if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \ |
| 2122 | !cap_zlr(domain->iommu->cap)) | 2528 | !cap_zlr(iommu->cap)) |
| 2123 | prot |= DMA_PTE_READ; | 2529 | prot |= DMA_PTE_READ; |
| 2124 | if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) | 2530 | if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) |
| 2125 | prot |= DMA_PTE_WRITE; | 2531 | prot |= DMA_PTE_WRITE; |
| @@ -2151,9 +2557,9 @@ int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, | |||
| 2151 | } | 2557 | } |
| 2152 | 2558 | ||
| 2153 | /* it's a non-present to present mapping */ | 2559 | /* it's a non-present to present mapping */ |
| 2154 | if (iommu_flush_iotlb_psi(domain->iommu, domain->id, | 2560 | if (iommu_flush_iotlb_psi(iommu, domain->id, |
| 2155 | start_addr, offset >> VTD_PAGE_SHIFT, 1)) | 2561 | start_addr, offset >> VTD_PAGE_SHIFT, 1)) |
| 2156 | iommu_flush_write_buffer(domain->iommu); | 2562 | iommu_flush_write_buffer(iommu); |
| 2157 | return nelems; | 2563 | return nelems; |
| 2158 | } | 2564 | } |
| 2159 | 2565 | ||
| @@ -2325,10 +2731,220 @@ int __init intel_iommu_init(void) | |||
| 2325 | init_timer(&unmap_timer); | 2731 | init_timer(&unmap_timer); |
| 2326 | force_iommu = 1; | 2732 | force_iommu = 1; |
| 2327 | dma_ops = &intel_dma_ops; | 2733 | dma_ops = &intel_dma_ops; |
| 2734 | |||
| 2735 | register_iommu(&intel_iommu_ops); | ||
| 2736 | |||
| 2737 | return 0; | ||
| 2738 | } | ||
| 2739 | |||
| 2740 | static int vm_domain_add_dev_info(struct dmar_domain *domain, | ||
| 2741 | struct pci_dev *pdev) | ||
| 2742 | { | ||
| 2743 | struct device_domain_info *info; | ||
| 2744 | unsigned long flags; | ||
| 2745 | |||
| 2746 | info = alloc_devinfo_mem(); | ||
| 2747 | if (!info) | ||
| 2748 | return -ENOMEM; | ||
| 2749 | |||
| 2750 | info->bus = pdev->bus->number; | ||
| 2751 | info->devfn = pdev->devfn; | ||
| 2752 | info->dev = pdev; | ||
| 2753 | info->domain = domain; | ||
| 2754 | |||
| 2755 | spin_lock_irqsave(&device_domain_lock, flags); | ||
| 2756 | list_add(&info->link, &domain->devices); | ||
| 2757 | list_add(&info->global, &device_domain_list); | ||
| 2758 | pdev->dev.archdata.iommu = info; | ||
| 2759 | spin_unlock_irqrestore(&device_domain_lock, flags); | ||
| 2760 | |||
| 2761 | return 0; | ||
| 2762 | } | ||
| 2763 | |||
| 2764 | static void vm_domain_remove_one_dev_info(struct dmar_domain *domain, | ||
| 2765 | struct pci_dev *pdev) | ||
| 2766 | { | ||
| 2767 | struct device_domain_info *info; | ||
| 2768 | struct intel_iommu *iommu; | ||
| 2769 | unsigned long flags; | ||
| 2770 | int found = 0; | ||
| 2771 | struct list_head *entry, *tmp; | ||
| 2772 | |||
| 2773 | iommu = device_to_iommu(pdev->bus->number, pdev->devfn); | ||
| 2774 | if (!iommu) | ||
| 2775 | return; | ||
| 2776 | |||
| 2777 | spin_lock_irqsave(&device_domain_lock, flags); | ||
| 2778 | list_for_each_safe(entry, tmp, &domain->devices) { | ||
| 2779 | info = list_entry(entry, struct device_domain_info, link); | ||
| 2780 | if (info->bus == pdev->bus->number && | ||
| 2781 | info->devfn == pdev->devfn) { | ||
| 2782 | list_del(&info->link); | ||
| 2783 | list_del(&info->global); | ||
| 2784 | if (info->dev) | ||
| 2785 | info->dev->dev.archdata.iommu = NULL; | ||
| 2786 | spin_unlock_irqrestore(&device_domain_lock, flags); | ||
| 2787 | |||
| 2788 | iommu_detach_dev(iommu, info->bus, info->devfn); | ||
| 2789 | free_devinfo_mem(info); | ||
| 2790 | |||
| 2791 | spin_lock_irqsave(&device_domain_lock, flags); | ||
| 2792 | |||
| 2793 | if (found) | ||
| 2794 | break; | ||
| 2795 | else | ||
| 2796 | continue; | ||
| 2797 | } | ||
| 2798 | |||
| 2799 | /* if there is no other devices under the same iommu | ||
| 2800 | * owned by this domain, clear this iommu in iommu_bmp | ||
| 2801 | * update iommu count and coherency | ||
| 2802 | */ | ||
| 2803 | if (device_to_iommu(info->bus, info->devfn) == iommu) | ||
| 2804 | found = 1; | ||
| 2805 | } | ||
| 2806 | |||
| 2807 | if (found == 0) { | ||
| 2808 | unsigned long tmp_flags; | ||
| 2809 | spin_lock_irqsave(&domain->iommu_lock, tmp_flags); | ||
| 2810 | clear_bit(iommu->seq_id, &domain->iommu_bmp); | ||
| 2811 | domain->iommu_count--; | ||
| 2812 | domain_update_iommu_coherency(domain); | ||
| 2813 | spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); | ||
| 2814 | } | ||
| 2815 | |||
| 2816 | spin_unlock_irqrestore(&device_domain_lock, flags); | ||
| 2817 | } | ||
| 2818 | |||
| 2819 | static void vm_domain_remove_all_dev_info(struct dmar_domain *domain) | ||
| 2820 | { | ||
| 2821 | struct device_domain_info *info; | ||
| 2822 | struct intel_iommu *iommu; | ||
| 2823 | unsigned long flags1, flags2; | ||
| 2824 | |||
| 2825 | spin_lock_irqsave(&device_domain_lock, flags1); | ||
| 2826 | while (!list_empty(&domain->devices)) { | ||
| 2827 | info = list_entry(domain->devices.next, | ||
| 2828 | struct device_domain_info, link); | ||
| 2829 | list_del(&info->link); | ||
| 2830 | list_del(&info->global); | ||
| 2831 | if (info->dev) | ||
| 2832 | info->dev->dev.archdata.iommu = NULL; | ||
| 2833 | |||
| 2834 | spin_unlock_irqrestore(&device_domain_lock, flags1); | ||
| 2835 | |||
| 2836 | iommu = device_to_iommu(info->bus, info->devfn); | ||
| 2837 | iommu_detach_dev(iommu, info->bus, info->devfn); | ||
| 2838 | |||
| 2839 | /* clear this iommu in iommu_bmp, update iommu count | ||
| 2840 | * and coherency | ||
| 2841 | */ | ||
| 2842 | spin_lock_irqsave(&domain->iommu_lock, flags2); | ||
| 2843 | if (test_and_clear_bit(iommu->seq_id, | ||
| 2844 | &domain->iommu_bmp)) { | ||
| 2845 | domain->iommu_count--; | ||
| 2846 | domain_update_iommu_coherency(domain); | ||
| 2847 | } | ||
| 2848 | spin_unlock_irqrestore(&domain->iommu_lock, flags2); | ||
| 2849 | |||
| 2850 | free_devinfo_mem(info); | ||
| 2851 | spin_lock_irqsave(&device_domain_lock, flags1); | ||
| 2852 | } | ||
| 2853 | spin_unlock_irqrestore(&device_domain_lock, flags1); | ||
| 2854 | } | ||
| 2855 | |||
| 2856 | /* domain id for virtual machine, it won't be set in context */ | ||
| 2857 | static unsigned long vm_domid; | ||
| 2858 | |||
| 2859 | static int vm_domain_min_agaw(struct dmar_domain *domain) | ||
| 2860 | { | ||
| 2861 | int i; | ||
| 2862 | int min_agaw = domain->agaw; | ||
| 2863 | |||
| 2864 | i = find_first_bit(&domain->iommu_bmp, g_num_of_iommus); | ||
| 2865 | for (; i < g_num_of_iommus; ) { | ||
| 2866 | if (min_agaw > g_iommus[i]->agaw) | ||
| 2867 | min_agaw = g_iommus[i]->agaw; | ||
| 2868 | |||
| 2869 | i = find_next_bit(&domain->iommu_bmp, g_num_of_iommus, i+1); | ||
| 2870 | } | ||
| 2871 | |||
| 2872 | return min_agaw; | ||
| 2873 | } | ||
| 2874 | |||
| 2875 | static struct dmar_domain *iommu_alloc_vm_domain(void) | ||
| 2876 | { | ||
| 2877 | struct dmar_domain *domain; | ||
| 2878 | |||
| 2879 | domain = alloc_domain_mem(); | ||
| 2880 | if (!domain) | ||
| 2881 | return NULL; | ||
| 2882 | |||
| 2883 | domain->id = vm_domid++; | ||
| 2884 | memset(&domain->iommu_bmp, 0, sizeof(unsigned long)); | ||
| 2885 | domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE; | ||
| 2886 | |||
| 2887 | return domain; | ||
| 2888 | } | ||
| 2889 | |||
| 2890 | static int vm_domain_init(struct dmar_domain *domain, int guest_width) | ||
| 2891 | { | ||
| 2892 | int adjust_width; | ||
| 2893 | |||
| 2894 | init_iova_domain(&domain->iovad, DMA_32BIT_PFN); | ||
| 2895 | spin_lock_init(&domain->mapping_lock); | ||
| 2896 | spin_lock_init(&domain->iommu_lock); | ||
| 2897 | |||
| 2898 | domain_reserve_special_ranges(domain); | ||
| 2899 | |||
| 2900 | /* calculate AGAW */ | ||
| 2901 | domain->gaw = guest_width; | ||
| 2902 | adjust_width = guestwidth_to_adjustwidth(guest_width); | ||
| 2903 | domain->agaw = width_to_agaw(adjust_width); | ||
| 2904 | |||
| 2905 | INIT_LIST_HEAD(&domain->devices); | ||
| 2906 | |||
| 2907 | domain->iommu_count = 0; | ||
| 2908 | domain->iommu_coherency = 0; | ||
| 2909 | domain->max_addr = 0; | ||
| 2910 | |||
| 2911 | /* always allocate the top pgd */ | ||
| 2912 | domain->pgd = (struct dma_pte *)alloc_pgtable_page(); | ||
| 2913 | if (!domain->pgd) | ||
| 2914 | return -ENOMEM; | ||
| 2915 | domain_flush_cache(domain, domain->pgd, PAGE_SIZE); | ||
| 2328 | return 0; | 2916 | return 0; |
| 2329 | } | 2917 | } |
| 2330 | 2918 | ||
| 2331 | void intel_iommu_domain_exit(struct dmar_domain *domain) | 2919 | static void iommu_free_vm_domain(struct dmar_domain *domain) |
| 2920 | { | ||
| 2921 | unsigned long flags; | ||
| 2922 | struct dmar_drhd_unit *drhd; | ||
| 2923 | struct intel_iommu *iommu; | ||
| 2924 | unsigned long i; | ||
| 2925 | unsigned long ndomains; | ||
| 2926 | |||
| 2927 | for_each_drhd_unit(drhd) { | ||
| 2928 | if (drhd->ignored) | ||
| 2929 | continue; | ||
| 2930 | iommu = drhd->iommu; | ||
| 2931 | |||
| 2932 | ndomains = cap_ndoms(iommu->cap); | ||
| 2933 | i = find_first_bit(iommu->domain_ids, ndomains); | ||
| 2934 | for (; i < ndomains; ) { | ||
| 2935 | if (iommu->domains[i] == domain) { | ||
| 2936 | spin_lock_irqsave(&iommu->lock, flags); | ||
| 2937 | clear_bit(i, iommu->domain_ids); | ||
| 2938 | iommu->domains[i] = NULL; | ||
| 2939 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
| 2940 | break; | ||
| 2941 | } | ||
| 2942 | i = find_next_bit(iommu->domain_ids, ndomains, i+1); | ||
| 2943 | } | ||
| 2944 | } | ||
| 2945 | } | ||
| 2946 | |||
| 2947 | static void vm_domain_exit(struct dmar_domain *domain) | ||
| 2332 | { | 2948 | { |
| 2333 | u64 end; | 2949 | u64 end; |
| 2334 | 2950 | ||
| @@ -2336,6 +2952,9 @@ void intel_iommu_domain_exit(struct dmar_domain *domain) | |||
| 2336 | if (!domain) | 2952 | if (!domain) |
| 2337 | return; | 2953 | return; |
| 2338 | 2954 | ||
| 2955 | vm_domain_remove_all_dev_info(domain); | ||
| 2956 | /* destroy iovas */ | ||
| 2957 | put_iova_domain(&domain->iovad); | ||
| 2339 | end = DOMAIN_MAX_ADDR(domain->gaw); | 2958 | end = DOMAIN_MAX_ADDR(domain->gaw); |
| 2340 | end = end & (~VTD_PAGE_MASK); | 2959 | end = end & (~VTD_PAGE_MASK); |
| 2341 | 2960 | ||
| @@ -2345,94 +2964,167 @@ void intel_iommu_domain_exit(struct dmar_domain *domain) | |||
| 2345 | /* free page tables */ | 2964 | /* free page tables */ |
| 2346 | dma_pte_free_pagetable(domain, 0, end); | 2965 | dma_pte_free_pagetable(domain, 0, end); |
| 2347 | 2966 | ||
| 2348 | iommu_free_domain(domain); | 2967 | iommu_free_vm_domain(domain); |
| 2349 | free_domain_mem(domain); | 2968 | free_domain_mem(domain); |
| 2350 | } | 2969 | } |
| 2351 | EXPORT_SYMBOL_GPL(intel_iommu_domain_exit); | ||
| 2352 | 2970 | ||
| 2353 | struct dmar_domain *intel_iommu_domain_alloc(struct pci_dev *pdev) | 2971 | static int intel_iommu_domain_init(struct iommu_domain *domain) |
| 2354 | { | 2972 | { |
| 2355 | struct dmar_drhd_unit *drhd; | 2973 | struct dmar_domain *dmar_domain; |
| 2356 | struct dmar_domain *domain; | ||
| 2357 | struct intel_iommu *iommu; | ||
| 2358 | |||
| 2359 | drhd = dmar_find_matched_drhd_unit(pdev); | ||
| 2360 | if (!drhd) { | ||
| 2361 | printk(KERN_ERR "intel_iommu_domain_alloc: drhd == NULL\n"); | ||
| 2362 | return NULL; | ||
| 2363 | } | ||
| 2364 | 2974 | ||
| 2365 | iommu = drhd->iommu; | 2975 | dmar_domain = iommu_alloc_vm_domain(); |
| 2366 | if (!iommu) { | 2976 | if (!dmar_domain) { |
| 2367 | printk(KERN_ERR | ||
| 2368 | "intel_iommu_domain_alloc: iommu == NULL\n"); | ||
| 2369 | return NULL; | ||
| 2370 | } | ||
| 2371 | domain = iommu_alloc_domain(iommu); | ||
| 2372 | if (!domain) { | ||
| 2373 | printk(KERN_ERR | 2977 | printk(KERN_ERR |
| 2374 | "intel_iommu_domain_alloc: domain == NULL\n"); | 2978 | "intel_iommu_domain_init: dmar_domain == NULL\n"); |
| 2375 | return NULL; | 2979 | return -ENOMEM; |
| 2376 | } | 2980 | } |
| 2377 | if (domain_init(domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) { | 2981 | if (vm_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) { |
| 2378 | printk(KERN_ERR | 2982 | printk(KERN_ERR |
| 2379 | "intel_iommu_domain_alloc: domain_init() failed\n"); | 2983 | "intel_iommu_domain_init() failed\n"); |
| 2380 | intel_iommu_domain_exit(domain); | 2984 | vm_domain_exit(dmar_domain); |
| 2381 | return NULL; | 2985 | return -ENOMEM; |
| 2382 | } | 2986 | } |
| 2383 | return domain; | 2987 | domain->priv = dmar_domain; |
| 2988 | |||
| 2989 | return 0; | ||
| 2384 | } | 2990 | } |
| 2385 | EXPORT_SYMBOL_GPL(intel_iommu_domain_alloc); | ||
| 2386 | 2991 | ||
| 2387 | int intel_iommu_context_mapping( | 2992 | static void intel_iommu_domain_destroy(struct iommu_domain *domain) |
| 2388 | struct dmar_domain *domain, struct pci_dev *pdev) | ||
| 2389 | { | 2993 | { |
| 2390 | int rc; | 2994 | struct dmar_domain *dmar_domain = domain->priv; |
| 2391 | rc = domain_context_mapping(domain, pdev); | 2995 | |
| 2392 | return rc; | 2996 | domain->priv = NULL; |
| 2997 | vm_domain_exit(dmar_domain); | ||
| 2393 | } | 2998 | } |
| 2394 | EXPORT_SYMBOL_GPL(intel_iommu_context_mapping); | ||
| 2395 | 2999 | ||
| 2396 | int intel_iommu_page_mapping( | 3000 | static int intel_iommu_attach_device(struct iommu_domain *domain, |
| 2397 | struct dmar_domain *domain, dma_addr_t iova, | 3001 | struct device *dev) |
| 2398 | u64 hpa, size_t size, int prot) | ||
| 2399 | { | 3002 | { |
| 2400 | int rc; | 3003 | struct dmar_domain *dmar_domain = domain->priv; |
| 2401 | rc = domain_page_mapping(domain, iova, hpa, size, prot); | 3004 | struct pci_dev *pdev = to_pci_dev(dev); |
| 2402 | return rc; | 3005 | struct intel_iommu *iommu; |
| 3006 | int addr_width; | ||
| 3007 | u64 end; | ||
| 3008 | int ret; | ||
| 3009 | |||
| 3010 | /* normally pdev is not mapped */ | ||
| 3011 | if (unlikely(domain_context_mapped(pdev))) { | ||
| 3012 | struct dmar_domain *old_domain; | ||
| 3013 | |||
| 3014 | old_domain = find_domain(pdev); | ||
| 3015 | if (old_domain) { | ||
| 3016 | if (dmar_domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) | ||
| 3017 | vm_domain_remove_one_dev_info(old_domain, pdev); | ||
| 3018 | else | ||
| 3019 | domain_remove_dev_info(old_domain); | ||
| 3020 | } | ||
| 3021 | } | ||
| 3022 | |||
| 3023 | iommu = device_to_iommu(pdev->bus->number, pdev->devfn); | ||
| 3024 | if (!iommu) | ||
| 3025 | return -ENODEV; | ||
| 3026 | |||
| 3027 | /* check if this iommu agaw is sufficient for max mapped address */ | ||
| 3028 | addr_width = agaw_to_width(iommu->agaw); | ||
| 3029 | end = DOMAIN_MAX_ADDR(addr_width); | ||
| 3030 | end = end & VTD_PAGE_MASK; | ||
| 3031 | if (end < dmar_domain->max_addr) { | ||
| 3032 | printk(KERN_ERR "%s: iommu agaw (%d) is not " | ||
| 3033 | "sufficient for the mapped address (%llx)\n", | ||
| 3034 | __func__, iommu->agaw, dmar_domain->max_addr); | ||
| 3035 | return -EFAULT; | ||
| 3036 | } | ||
| 3037 | |||
| 3038 | ret = domain_context_mapping(dmar_domain, pdev); | ||
| 3039 | if (ret) | ||
| 3040 | return ret; | ||
| 3041 | |||
| 3042 | ret = vm_domain_add_dev_info(dmar_domain, pdev); | ||
| 3043 | return ret; | ||
| 2403 | } | 3044 | } |
| 2404 | EXPORT_SYMBOL_GPL(intel_iommu_page_mapping); | ||
| 2405 | 3045 | ||
| 2406 | void intel_iommu_detach_dev(struct dmar_domain *domain, u8 bus, u8 devfn) | 3046 | static void intel_iommu_detach_device(struct iommu_domain *domain, |
| 3047 | struct device *dev) | ||
| 2407 | { | 3048 | { |
| 2408 | detach_domain_for_dev(domain, bus, devfn); | 3049 | struct dmar_domain *dmar_domain = domain->priv; |
| 3050 | struct pci_dev *pdev = to_pci_dev(dev); | ||
| 3051 | |||
| 3052 | vm_domain_remove_one_dev_info(dmar_domain, pdev); | ||
| 2409 | } | 3053 | } |
| 2410 | EXPORT_SYMBOL_GPL(intel_iommu_detach_dev); | ||
| 2411 | 3054 | ||
| 2412 | struct dmar_domain * | 3055 | static int intel_iommu_map_range(struct iommu_domain *domain, |
| 2413 | intel_iommu_find_domain(struct pci_dev *pdev) | 3056 | unsigned long iova, phys_addr_t hpa, |
| 3057 | size_t size, int iommu_prot) | ||
| 2414 | { | 3058 | { |
| 2415 | return find_domain(pdev); | 3059 | struct dmar_domain *dmar_domain = domain->priv; |
| 3060 | u64 max_addr; | ||
| 3061 | int addr_width; | ||
| 3062 | int prot = 0; | ||
| 3063 | int ret; | ||
| 3064 | |||
| 3065 | if (iommu_prot & IOMMU_READ) | ||
| 3066 | prot |= DMA_PTE_READ; | ||
| 3067 | if (iommu_prot & IOMMU_WRITE) | ||
| 3068 | prot |= DMA_PTE_WRITE; | ||
| 3069 | |||
| 3070 | max_addr = (iova & VTD_PAGE_MASK) + VTD_PAGE_ALIGN(size); | ||
| 3071 | if (dmar_domain->max_addr < max_addr) { | ||
| 3072 | int min_agaw; | ||
| 3073 | u64 end; | ||
| 3074 | |||
| 3075 | /* check if minimum agaw is sufficient for mapped address */ | ||
| 3076 | min_agaw = vm_domain_min_agaw(dmar_domain); | ||
| 3077 | addr_width = agaw_to_width(min_agaw); | ||
| 3078 | end = DOMAIN_MAX_ADDR(addr_width); | ||
| 3079 | end = end & VTD_PAGE_MASK; | ||
| 3080 | if (end < max_addr) { | ||
| 3081 | printk(KERN_ERR "%s: iommu agaw (%d) is not " | ||
| 3082 | "sufficient for the mapped address (%llx)\n", | ||
| 3083 | __func__, min_agaw, max_addr); | ||
| 3084 | return -EFAULT; | ||
| 3085 | } | ||
| 3086 | dmar_domain->max_addr = max_addr; | ||
| 3087 | } | ||
| 3088 | |||
| 3089 | ret = domain_page_mapping(dmar_domain, iova, hpa, size, prot); | ||
| 3090 | return ret; | ||
| 2416 | } | 3091 | } |
| 2417 | EXPORT_SYMBOL_GPL(intel_iommu_find_domain); | ||
| 2418 | 3092 | ||
| 2419 | int intel_iommu_found(void) | 3093 | static void intel_iommu_unmap_range(struct iommu_domain *domain, |
| 3094 | unsigned long iova, size_t size) | ||
| 2420 | { | 3095 | { |
| 2421 | return g_num_of_iommus; | 3096 | struct dmar_domain *dmar_domain = domain->priv; |
| 3097 | dma_addr_t base; | ||
| 3098 | |||
| 3099 | /* The address might not be aligned */ | ||
| 3100 | base = iova & VTD_PAGE_MASK; | ||
| 3101 | size = VTD_PAGE_ALIGN(size); | ||
| 3102 | dma_pte_clear_range(dmar_domain, base, base + size); | ||
| 3103 | |||
| 3104 | if (dmar_domain->max_addr == base + size) | ||
| 3105 | dmar_domain->max_addr = base; | ||
| 2422 | } | 3106 | } |
| 2423 | EXPORT_SYMBOL_GPL(intel_iommu_found); | ||
| 2424 | 3107 | ||
| 2425 | u64 intel_iommu_iova_to_pfn(struct dmar_domain *domain, u64 iova) | 3108 | static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, |
| 3109 | unsigned long iova) | ||
| 2426 | { | 3110 | { |
| 3111 | struct dmar_domain *dmar_domain = domain->priv; | ||
| 2427 | struct dma_pte *pte; | 3112 | struct dma_pte *pte; |
| 2428 | u64 pfn; | 3113 | u64 phys = 0; |
| 2429 | |||
| 2430 | pfn = 0; | ||
| 2431 | pte = addr_to_dma_pte(domain, iova); | ||
| 2432 | 3114 | ||
| 3115 | pte = addr_to_dma_pte(dmar_domain, iova); | ||
| 2433 | if (pte) | 3116 | if (pte) |
| 2434 | pfn = dma_pte_addr(*pte); | 3117 | phys = dma_pte_addr(pte); |
| 2435 | 3118 | ||
| 2436 | return pfn >> VTD_PAGE_SHIFT; | 3119 | return phys; |
| 2437 | } | 3120 | } |
| 2438 | EXPORT_SYMBOL_GPL(intel_iommu_iova_to_pfn); | 3121 | |
| 3122 | static struct iommu_ops intel_iommu_ops = { | ||
| 3123 | .domain_init = intel_iommu_domain_init, | ||
| 3124 | .domain_destroy = intel_iommu_domain_destroy, | ||
| 3125 | .attach_dev = intel_iommu_attach_device, | ||
| 3126 | .detach_dev = intel_iommu_detach_device, | ||
| 3127 | .map = intel_iommu_map_range, | ||
| 3128 | .unmap = intel_iommu_unmap_range, | ||
| 3129 | .iova_to_phys = intel_iommu_iova_to_phys, | ||
| 3130 | }; | ||
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c index 7ff824496b39..7e6b5a3b3281 100644 --- a/drivers/pnp/pnpbios/bioscalls.c +++ b/drivers/pnp/pnpbios/bioscalls.c | |||
| @@ -481,7 +481,7 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header) | |||
| 481 | 481 | ||
| 482 | set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); | 482 | set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); |
| 483 | _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); | 483 | _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); |
| 484 | for (i = 0; i < NR_CPUS; i++) { | 484 | for_each_possible_cpu(i) { |
| 485 | struct desc_struct *gdt = get_cpu_gdt_table(i); | 485 | struct desc_struct *gdt = get_cpu_gdt_table(i); |
| 486 | if (!gdt) | 486 | if (!gdt) |
| 487 | continue; | 487 | continue; |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 8a8df7552969..06b71823f399 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
| @@ -632,8 +632,8 @@ do_IRQ (struct pt_regs *regs) | |||
| 632 | struct pt_regs *old_regs; | 632 | struct pt_regs *old_regs; |
| 633 | 633 | ||
| 634 | old_regs = set_irq_regs(regs); | 634 | old_regs = set_irq_regs(regs); |
| 635 | irq_enter(); | ||
| 636 | s390_idle_check(); | 635 | s390_idle_check(); |
| 636 | irq_enter(); | ||
| 637 | if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) | 637 | if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) |
| 638 | /* Serve timer interrupts first. */ | 638 | /* Serve timer interrupts first. */ |
| 639 | clock_comparator_work(); | 639 | clock_comparator_work(); |
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c index 834e9ee7e934..92b0417f8e12 100644 --- a/drivers/s390/s390mach.c +++ b/drivers/s390/s390mach.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <asm/etr.h> | 18 | #include <asm/etr.h> |
| 19 | #include <asm/lowcore.h> | 19 | #include <asm/lowcore.h> |
| 20 | #include <asm/cio.h> | 20 | #include <asm/cio.h> |
| 21 | #include <asm/cpu.h> | ||
| 21 | #include "s390mach.h" | 22 | #include "s390mach.h" |
| 22 | 23 | ||
| 23 | static struct semaphore m_sem; | 24 | static struct semaphore m_sem; |
| @@ -369,6 +370,8 @@ s390_do_machine_check(struct pt_regs *regs) | |||
| 369 | 370 | ||
| 370 | lockdep_off(); | 371 | lockdep_off(); |
| 371 | 372 | ||
| 373 | s390_idle_check(); | ||
| 374 | |||
| 372 | mci = (struct mci *) &S390_lowcore.mcck_interruption_code; | 375 | mci = (struct mci *) &S390_lowcore.mcck_interruption_code; |
| 373 | mcck = &__get_cpu_var(cpu_mcck); | 376 | mcck = &__get_cpu_var(cpu_mcck); |
| 374 | umode = user_mode(regs); | 377 | umode = user_mode(regs); |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 4fd3fa5546b1..ec68c741b564 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
| @@ -55,6 +55,13 @@ config SOFT_WATCHDOG | |||
| 55 | To compile this driver as a module, choose M here: the | 55 | To compile this driver as a module, choose M here: the |
| 56 | module will be called softdog. | 56 | module will be called softdog. |
| 57 | 57 | ||
| 58 | config WM8350_WATCHDOG | ||
| 59 | tristate "WM8350 watchdog" | ||
| 60 | depends on MFD_WM8350 | ||
| 61 | help | ||
| 62 | Support for the watchdog in the WM8350 AudioPlus PMIC. When | ||
| 63 | the watchdog triggers the system will be reset. | ||
| 64 | |||
| 58 | # ALPHA Architecture | 65 | # ALPHA Architecture |
| 59 | 66 | ||
| 60 | # ARM Architecture | 67 | # ARM Architecture |
| @@ -551,6 +558,18 @@ config CPU5_WDT | |||
| 551 | To compile this driver as a module, choose M here: the | 558 | To compile this driver as a module, choose M here: the |
| 552 | module will be called cpu5wdt. | 559 | module will be called cpu5wdt. |
| 553 | 560 | ||
| 561 | config SMSC_SCH311X_WDT | ||
| 562 | tristate "SMSC SCH311X Watchdog Timer" | ||
| 563 | depends on X86 | ||
| 564 | ---help--- | ||
| 565 | This is the driver for the hardware watchdog timer on the | ||
| 566 | SMSC SCH3112, SCH3114 and SCH3116 Super IO chipset | ||
| 567 | (LPC IO with 8042 KBC, Reset Generation, HWM and multiple | ||
| 568 | serial ports). | ||
| 569 | |||
| 570 | To compile this driver as a module, choose M here: the | ||
| 571 | module will be called sch311x_wdt. | ||
| 572 | |||
| 554 | config SMSC37B787_WDT | 573 | config SMSC37B787_WDT |
| 555 | tristate "Winbond SMsC37B787 Watchdog Timer" | 574 | tristate "Winbond SMsC37B787 Watchdog Timer" |
| 556 | depends on X86 | 575 | depends on X86 |
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index e352bbb7630b..c19b866f5ed1 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile | |||
| @@ -83,6 +83,7 @@ obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o | |||
| 83 | obj-$(CONFIG_SBC8360_WDT) += sbc8360.o | 83 | obj-$(CONFIG_SBC8360_WDT) += sbc8360.o |
| 84 | obj-$(CONFIG_SBC7240_WDT) += sbc7240_wdt.o | 84 | obj-$(CONFIG_SBC7240_WDT) += sbc7240_wdt.o |
| 85 | obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o | 85 | obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o |
| 86 | obj-$(CONFIG_SMSC_SCH311X_WDT) += sch311x_wdt.o | ||
| 86 | obj-$(CONFIG_SMSC37B787_WDT) += smsc37b787_wdt.o | 87 | obj-$(CONFIG_SMSC37B787_WDT) += smsc37b787_wdt.o |
| 87 | obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o | 88 | obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o |
| 88 | obj-$(CONFIG_W83697HF_WDT) += w83697hf_wdt.o | 89 | obj-$(CONFIG_W83697HF_WDT) += w83697hf_wdt.o |
| @@ -133,4 +134,5 @@ obj-$(CONFIG_WATCHDOG_CP1XXX) += cpwd.o | |||
| 133 | # XTENSA Architecture | 134 | # XTENSA Architecture |
| 134 | 135 | ||
| 135 | # Architecture Independant | 136 | # Architecture Independant |
| 137 | obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o | ||
| 136 | obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o | 138 | obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o |
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c index 317ef2b16cff..4bef3ddff4a5 100644 --- a/drivers/watchdog/ib700wdt.c +++ b/drivers/watchdog/ib700wdt.c | |||
| @@ -91,32 +91,16 @@ static char expect_close; | |||
| 91 | * | 91 | * |
| 92 | */ | 92 | */ |
| 93 | 93 | ||
| 94 | static int wd_times[] = { | ||
| 95 | 30, /* 0x0 */ | ||
| 96 | 28, /* 0x1 */ | ||
| 97 | 26, /* 0x2 */ | ||
| 98 | 24, /* 0x3 */ | ||
| 99 | 22, /* 0x4 */ | ||
| 100 | 20, /* 0x5 */ | ||
| 101 | 18, /* 0x6 */ | ||
| 102 | 16, /* 0x7 */ | ||
| 103 | 14, /* 0x8 */ | ||
| 104 | 12, /* 0x9 */ | ||
| 105 | 10, /* 0xA */ | ||
| 106 | 8, /* 0xB */ | ||
| 107 | 6, /* 0xC */ | ||
| 108 | 4, /* 0xD */ | ||
| 109 | 2, /* 0xE */ | ||
| 110 | 0, /* 0xF */ | ||
| 111 | }; | ||
| 112 | |||
| 113 | #define WDT_STOP 0x441 | 94 | #define WDT_STOP 0x441 |
| 114 | #define WDT_START 0x443 | 95 | #define WDT_START 0x443 |
| 115 | 96 | ||
| 116 | /* Default timeout */ | 97 | /* Default timeout */ |
| 117 | #define WD_TIMO 0 /* 30 seconds +/- 20%, from table */ | 98 | #define WATCHDOG_TIMEOUT 30 /* 30 seconds +/- 20% */ |
| 118 | 99 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ | |
| 119 | static int wd_margin = WD_TIMO; | 100 | module_param(timeout, int, 0); |
| 101 | MODULE_PARM_DESC(timeout, | ||
| 102 | "Watchdog timeout in seconds. 0<= timeout <=30, default=" | ||
| 103 | __MODULE_STRING(WATCHDOG_TIMEOUT) "."); | ||
| 120 | 104 | ||
| 121 | static int nowayout = WATCHDOG_NOWAYOUT; | 105 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 122 | module_param(nowayout, int, 0); | 106 | module_param(nowayout, int, 0); |
| @@ -131,6 +115,8 @@ MODULE_PARM_DESC(nowayout, | |||
| 131 | 115 | ||
| 132 | static void ibwdt_ping(void) | 116 | static void ibwdt_ping(void) |
| 133 | { | 117 | { |
| 118 | int wd_margin = 15 - ((timeout + 1) / 2); | ||
| 119 | |||
| 134 | spin_lock(&ibwdt_lock); | 120 | spin_lock(&ibwdt_lock); |
| 135 | 121 | ||
| 136 | /* Write a watchdog value */ | 122 | /* Write a watchdog value */ |
| @@ -148,15 +134,10 @@ static void ibwdt_disable(void) | |||
| 148 | 134 | ||
| 149 | static int ibwdt_set_heartbeat(int t) | 135 | static int ibwdt_set_heartbeat(int t) |
| 150 | { | 136 | { |
| 151 | int i; | 137 | if (t < 0 || t > 30) |
| 152 | |||
| 153 | if ((t < 0) || (t > 30)) | ||
| 154 | return -EINVAL; | 138 | return -EINVAL; |
| 155 | 139 | ||
| 156 | for (i = 0x0F; i > -1; i--) | 140 | timeout = t; |
| 157 | if (wd_times[i] >= t) | ||
| 158 | break; | ||
| 159 | wd_margin = i; | ||
| 160 | return 0; | 141 | return 0; |
| 161 | } | 142 | } |
| 162 | 143 | ||
| @@ -240,7 +221,7 @@ static long ibwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 240 | /* Fall */ | 221 | /* Fall */ |
| 241 | 222 | ||
| 242 | case WDIOC_GETTIMEOUT: | 223 | case WDIOC_GETTIMEOUT: |
| 243 | return put_user(wd_times[wd_margin], p); | 224 | return put_user(timeout, p); |
| 244 | 225 | ||
| 245 | default: | 226 | default: |
| 246 | return -ENOTTY; | 227 | return -ENOTTY; |
| @@ -317,6 +298,14 @@ static int __devinit ibwdt_probe(struct platform_device *dev) | |||
| 317 | goto out_nostartreg; | 298 | goto out_nostartreg; |
| 318 | } | 299 | } |
| 319 | 300 | ||
| 301 | /* Check that the heartbeat value is within it's range ; | ||
| 302 | * if not reset to the default */ | ||
| 303 | if (ibwdt_set_heartbeat(timeout)) { | ||
| 304 | ibwdt_set_heartbeat(WATCHDOG_TIMEOUT); | ||
| 305 | printk(KERN_INFO PFX | ||
| 306 | "timeout value must be 0<=x<=30, using %d\n", timeout); | ||
| 307 | } | ||
| 308 | |||
| 320 | res = misc_register(&ibwdt_miscdev); | 309 | res = misc_register(&ibwdt_miscdev); |
| 321 | if (res) { | 310 | if (res) { |
| 322 | printk(KERN_ERR PFX "failed to register misc device\n"); | 311 | printk(KERN_ERR PFX "failed to register misc device\n"); |
diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c new file mode 100644 index 000000000000..569eb295a7a8 --- /dev/null +++ b/drivers/watchdog/sch311x_wdt.c | |||
| @@ -0,0 +1,578 @@ | |||
| 1 | /* | ||
| 2 | * sch311x_wdt.c - Driver for the SCH311x Super-I/O chips | ||
| 3 | * integrated watchdog. | ||
| 4 | * | ||
| 5 | * (c) Copyright 2008 Wim Van Sebroeck <wim@iguana.be>. | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version | ||
| 10 | * 2 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * Neither Wim Van Sebroeck nor Iguana vzw. admit liability nor | ||
| 13 | * provide warranty for any of this software. This material is | ||
| 14 | * provided "AS-IS" and at no charge. | ||
| 15 | */ | ||
| 16 | |||
| 17 | /* | ||
| 18 | * Includes, defines, variables, module parameters, ... | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* Includes */ | ||
| 22 | #include <linux/module.h> /* For module specific items */ | ||
| 23 | #include <linux/moduleparam.h> /* For new moduleparam's */ | ||
| 24 | #include <linux/types.h> /* For standard types (like size_t) */ | ||
| 25 | #include <linux/errno.h> /* For the -ENODEV/... values */ | ||
| 26 | #include <linux/kernel.h> /* For printk/... */ | ||
| 27 | #include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV | ||
| 28 | (WATCHDOG_MINOR) */ | ||
| 29 | #include <linux/watchdog.h> /* For the watchdog specific items */ | ||
| 30 | #include <linux/init.h> /* For __init/__exit/... */ | ||
| 31 | #include <linux/fs.h> /* For file operations */ | ||
| 32 | #include <linux/platform_device.h> /* For platform_driver framework */ | ||
| 33 | #include <linux/ioport.h> /* For io-port access */ | ||
| 34 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ | ||
| 35 | #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ | ||
| 36 | #include <linux/io.h> /* For inb/outb/... */ | ||
| 37 | |||
| 38 | /* Module and version information */ | ||
| 39 | #define DRV_NAME "sch311x_wdt" | ||
| 40 | #define PFX DRV_NAME ": " | ||
| 41 | |||
| 42 | /* Runtime registers */ | ||
| 43 | #define RESGEN 0x1d | ||
| 44 | #define GP60 0x47 | ||
| 45 | #define WDT_TIME_OUT 0x65 | ||
| 46 | #define WDT_VAL 0x66 | ||
| 47 | #define WDT_CFG 0x67 | ||
| 48 | #define WDT_CTRL 0x68 | ||
| 49 | |||
| 50 | /* internal variables */ | ||
| 51 | static unsigned long sch311x_wdt_is_open; | ||
| 52 | static char sch311x_wdt_expect_close; | ||
| 53 | static struct platform_device *sch311x_wdt_pdev; | ||
| 54 | |||
| 55 | static int sch311x_ioports[] = { 0x2e, 0x4e, 0x162e, 0x164e, 0x00 }; | ||
| 56 | |||
| 57 | static struct { /* The devices private data */ | ||
| 58 | /* the Runtime Register base address */ | ||
| 59 | unsigned short runtime_reg; | ||
| 60 | /* The card's boot status */ | ||
| 61 | int boot_status; | ||
| 62 | /* the lock for io operations */ | ||
| 63 | spinlock_t io_lock; | ||
| 64 | } sch311x_wdt_data; | ||
| 65 | |||
| 66 | /* Module load parameters */ | ||
| 67 | static unsigned short force_id; | ||
| 68 | module_param(force_id, ushort, 0); | ||
| 69 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | ||
| 70 | |||
| 71 | static unsigned short therm_trip; | ||
| 72 | module_param(therm_trip, ushort, 0); | ||
| 73 | MODULE_PARM_DESC(therm_trip, "Should a ThermTrip trigger the reset generator"); | ||
| 74 | |||
| 75 | #define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ | ||
| 76 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ | ||
| 77 | module_param(timeout, int, 0); | ||
| 78 | MODULE_PARM_DESC(timeout, | ||
| 79 | "Watchdog timeout in seconds. 1<= timeout <=15300, default=" | ||
| 80 | __MODULE_STRING(WATCHDOG_TIMEOUT) "."); | ||
| 81 | |||
| 82 | static int nowayout = WATCHDOG_NOWAYOUT; | ||
| 83 | module_param(nowayout, int, 0); | ||
| 84 | MODULE_PARM_DESC(nowayout, | ||
| 85 | "Watchdog cannot be stopped once started (default=" | ||
| 86 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 87 | |||
| 88 | /* | ||
| 89 | * Super-IO functions | ||
| 90 | */ | ||
| 91 | |||
| 92 | static inline void sch311x_sio_enter(int sio_config_port) | ||
| 93 | { | ||
| 94 | outb(0x55, sio_config_port); | ||
| 95 | } | ||
| 96 | |||
| 97 | static inline void sch311x_sio_exit(int sio_config_port) | ||
| 98 | { | ||
| 99 | outb(0xaa, sio_config_port); | ||
| 100 | } | ||
| 101 | |||
| 102 | static inline int sch311x_sio_inb(int sio_config_port, int reg) | ||
| 103 | { | ||
| 104 | outb(reg, sio_config_port); | ||
| 105 | return inb(sio_config_port + 1); | ||
| 106 | } | ||
| 107 | |||
| 108 | static inline void sch311x_sio_outb(int sio_config_port, int reg, int val) | ||
| 109 | { | ||
| 110 | outb(reg, sio_config_port); | ||
| 111 | outb(val, sio_config_port + 1); | ||
| 112 | } | ||
| 113 | |||
| 114 | /* | ||
| 115 | * Watchdog Operations | ||
| 116 | */ | ||
| 117 | |||
| 118 | static void sch311x_wdt_set_timeout(int t) | ||
| 119 | { | ||
| 120 | unsigned char timeout_unit = 0x80; | ||
| 121 | |||
| 122 | /* When new timeout is bigger then 255 seconds, we will use minutes */ | ||
| 123 | if (t > 255) { | ||
| 124 | timeout_unit = 0; | ||
| 125 | t /= 60; | ||
| 126 | } | ||
| 127 | |||
| 128 | /* -- Watchdog Timeout -- | ||
| 129 | * Bit 0-6 (Reserved) | ||
| 130 | * Bit 7 WDT Time-out Value Units Select | ||
| 131 | * (0 = Minutes, 1 = Seconds) | ||
| 132 | */ | ||
| 133 | outb(timeout_unit, sch311x_wdt_data.runtime_reg + WDT_TIME_OUT); | ||
| 134 | |||
| 135 | /* -- Watchdog Timer Time-out Value -- | ||
| 136 | * Bit 0-7 Binary coded units (0=Disabled, 1..255) | ||
| 137 | */ | ||
| 138 | outb(t, sch311x_wdt_data.runtime_reg + WDT_VAL); | ||
| 139 | } | ||
| 140 | |||
| 141 | static void sch311x_wdt_start(void) | ||
| 142 | { | ||
| 143 | spin_lock(&sch311x_wdt_data.io_lock); | ||
| 144 | |||
| 145 | /* set watchdog's timeout */ | ||
| 146 | sch311x_wdt_set_timeout(timeout); | ||
| 147 | /* enable the watchdog */ | ||
| 148 | /* -- General Purpose I/O Bit 6.0 -- | ||
| 149 | * Bit 0, In/Out: 0 = Output, 1 = Input | ||
| 150 | * Bit 1, Polarity: 0 = No Invert, 1 = Invert | ||
| 151 | * Bit 2-3, Function select: 00 = GPI/O, 01 = LED1, 11 = WDT, | ||
| 152 | * 10 = Either Edge Triggered Intr.4 | ||
| 153 | * Bit 4-6 (Reserved) | ||
| 154 | * Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain | ||
| 155 | */ | ||
| 156 | outb(0x0e, sch311x_wdt_data.runtime_reg + GP60); | ||
| 157 | |||
| 158 | spin_unlock(&sch311x_wdt_data.io_lock); | ||
| 159 | |||
| 160 | } | ||
| 161 | |||
| 162 | static void sch311x_wdt_stop(void) | ||
| 163 | { | ||
| 164 | spin_lock(&sch311x_wdt_data.io_lock); | ||
| 165 | |||
| 166 | /* stop the watchdog */ | ||
| 167 | outb(0x01, sch311x_wdt_data.runtime_reg + GP60); | ||
| 168 | /* disable timeout by setting it to 0 */ | ||
| 169 | sch311x_wdt_set_timeout(0); | ||
| 170 | |||
| 171 | spin_unlock(&sch311x_wdt_data.io_lock); | ||
| 172 | } | ||
| 173 | |||
| 174 | static void sch311x_wdt_keepalive(void) | ||
| 175 | { | ||
| 176 | spin_lock(&sch311x_wdt_data.io_lock); | ||
| 177 | sch311x_wdt_set_timeout(timeout); | ||
| 178 | spin_unlock(&sch311x_wdt_data.io_lock); | ||
| 179 | } | ||
| 180 | |||
| 181 | static int sch311x_wdt_set_heartbeat(int t) | ||
| 182 | { | ||
| 183 | if (t < 1 || t > (255*60)) | ||
| 184 | return -EINVAL; | ||
| 185 | |||
| 186 | /* When new timeout is bigger then 255 seconds, | ||
| 187 | * we will round up to minutes (with a max of 255) */ | ||
| 188 | if (t > 255) | ||
| 189 | t = (((t - 1) / 60) + 1) * 60; | ||
| 190 | |||
| 191 | timeout = t; | ||
| 192 | return 0; | ||
| 193 | } | ||
| 194 | |||
| 195 | static void sch311x_wdt_get_status(int *status) | ||
| 196 | { | ||
| 197 | unsigned char new_status; | ||
| 198 | |||
| 199 | *status = 0; | ||
| 200 | |||
| 201 | spin_lock(&sch311x_wdt_data.io_lock); | ||
| 202 | |||
| 203 | /* -- Watchdog timer control -- | ||
| 204 | * Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured | ||
| 205 | * Bit 1 Reserved | ||
| 206 | * Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning) | ||
| 207 | * Bit 3 P20 Force Timeout enabled: | ||
| 208 | * 0 = P20 activity does not generate the WD timeout event | ||
| 209 | * 1 = P20 Allows rising edge of P20, from the keyboard | ||
| 210 | * controller, to force the WD timeout event. | ||
| 211 | * Bit 4-7 Reserved | ||
| 212 | */ | ||
| 213 | new_status = inb(sch311x_wdt_data.runtime_reg + WDT_CTRL); | ||
| 214 | if (new_status & 0x01) | ||
| 215 | *status |= WDIOF_CARDRESET; | ||
| 216 | |||
| 217 | spin_unlock(&sch311x_wdt_data.io_lock); | ||
| 218 | } | ||
| 219 | |||
| 220 | /* | ||
| 221 | * /dev/watchdog handling | ||
| 222 | */ | ||
| 223 | |||
| 224 | static ssize_t sch311x_wdt_write(struct file *file, const char __user *buf, | ||
| 225 | size_t count, loff_t *ppos) | ||
| 226 | { | ||
| 227 | if (count) { | ||
| 228 | if (!nowayout) { | ||
| 229 | size_t i; | ||
| 230 | |||
| 231 | sch311x_wdt_expect_close = 0; | ||
| 232 | |||
| 233 | for (i = 0; i != count; i++) { | ||
| 234 | char c; | ||
| 235 | if (get_user(c, buf + i)) | ||
| 236 | return -EFAULT; | ||
| 237 | if (c == 'V') | ||
| 238 | sch311x_wdt_expect_close = 42; | ||
| 239 | } | ||
| 240 | } | ||
| 241 | sch311x_wdt_keepalive(); | ||
| 242 | } | ||
| 243 | return count; | ||
| 244 | } | ||
| 245 | |||
| 246 | static long sch311x_wdt_ioctl(struct file *file, unsigned int cmd, | ||
| 247 | unsigned long arg) | ||
| 248 | { | ||
| 249 | int status; | ||
| 250 | int new_timeout; | ||
| 251 | void __user *argp = (void __user *)arg; | ||
| 252 | int __user *p = argp; | ||
| 253 | static struct watchdog_info ident = { | ||
| 254 | .options = WDIOF_KEEPALIVEPING | | ||
| 255 | WDIOF_SETTIMEOUT | | ||
| 256 | WDIOF_MAGICCLOSE, | ||
| 257 | .firmware_version = 1, | ||
| 258 | .identity = DRV_NAME, | ||
| 259 | }; | ||
| 260 | |||
| 261 | switch (cmd) { | ||
| 262 | case WDIOC_GETSUPPORT: | ||
| 263 | if (copy_to_user(argp, &ident, sizeof(ident))) | ||
| 264 | return -EFAULT; | ||
| 265 | break; | ||
| 266 | |||
| 267 | case WDIOC_GETSTATUS: | ||
| 268 | { | ||
| 269 | sch311x_wdt_get_status(&status); | ||
| 270 | return put_user(status, p); | ||
| 271 | } | ||
| 272 | case WDIOC_GETBOOTSTATUS: | ||
| 273 | return put_user(sch311x_wdt_data.boot_status, p); | ||
| 274 | |||
| 275 | case WDIOC_SETOPTIONS: | ||
| 276 | { | ||
| 277 | int options, retval = -EINVAL; | ||
| 278 | |||
| 279 | if (get_user(options, p)) | ||
| 280 | return -EFAULT; | ||
| 281 | if (options & WDIOS_DISABLECARD) { | ||
| 282 | sch311x_wdt_stop(); | ||
| 283 | retval = 0; | ||
| 284 | } | ||
| 285 | if (options & WDIOS_ENABLECARD) { | ||
| 286 | sch311x_wdt_start(); | ||
| 287 | retval = 0; | ||
| 288 | } | ||
| 289 | return retval; | ||
| 290 | } | ||
| 291 | case WDIOC_KEEPALIVE: | ||
| 292 | sch311x_wdt_keepalive(); | ||
| 293 | break; | ||
| 294 | |||
| 295 | case WDIOC_SETTIMEOUT: | ||
| 296 | if (get_user(new_timeout, p)) | ||
| 297 | return -EFAULT; | ||
| 298 | if (sch311x_wdt_set_heartbeat(new_timeout)) | ||
| 299 | return -EINVAL; | ||
| 300 | sch311x_wdt_keepalive(); | ||
| 301 | /* Fall */ | ||
| 302 | case WDIOC_GETTIMEOUT: | ||
| 303 | return put_user(timeout, p); | ||
| 304 | default: | ||
| 305 | return -ENOTTY; | ||
| 306 | } | ||
| 307 | return 0; | ||
| 308 | } | ||
| 309 | |||
| 310 | static int sch311x_wdt_open(struct inode *inode, struct file *file) | ||
| 311 | { | ||
| 312 | if (test_and_set_bit(0, &sch311x_wdt_is_open)) | ||
| 313 | return -EBUSY; | ||
| 314 | /* | ||
| 315 | * Activate | ||
| 316 | */ | ||
| 317 | sch311x_wdt_start(); | ||
| 318 | return nonseekable_open(inode, file); | ||
| 319 | } | ||
| 320 | |||
| 321 | static int sch311x_wdt_close(struct inode *inode, struct file *file) | ||
| 322 | { | ||
| 323 | if (sch311x_wdt_expect_close == 42) { | ||
| 324 | sch311x_wdt_stop(); | ||
| 325 | } else { | ||
| 326 | printk(KERN_CRIT PFX | ||
| 327 | "Unexpected close, not stopping watchdog!\n"); | ||
| 328 | sch311x_wdt_keepalive(); | ||
| 329 | } | ||
| 330 | clear_bit(0, &sch311x_wdt_is_open); | ||
| 331 | sch311x_wdt_expect_close = 0; | ||
| 332 | return 0; | ||
| 333 | } | ||
| 334 | |||
| 335 | /* | ||
| 336 | * Kernel Interfaces | ||
| 337 | */ | ||
| 338 | |||
| 339 | static const struct file_operations sch311x_wdt_fops = { | ||
| 340 | .owner = THIS_MODULE, | ||
| 341 | .llseek = no_llseek, | ||
| 342 | .write = sch311x_wdt_write, | ||
| 343 | .unlocked_ioctl = sch311x_wdt_ioctl, | ||
| 344 | .open = sch311x_wdt_open, | ||
| 345 | .release = sch311x_wdt_close, | ||
| 346 | }; | ||
| 347 | |||
| 348 | static struct miscdevice sch311x_wdt_miscdev = { | ||
| 349 | .minor = WATCHDOG_MINOR, | ||
| 350 | .name = "watchdog", | ||
| 351 | .fops = &sch311x_wdt_fops, | ||
| 352 | }; | ||
| 353 | |||
| 354 | /* | ||
| 355 | * Init & exit routines | ||
| 356 | */ | ||
| 357 | |||
| 358 | static int __devinit sch311x_wdt_probe(struct platform_device *pdev) | ||
| 359 | { | ||
| 360 | struct device *dev = &pdev->dev; | ||
| 361 | unsigned char val; | ||
| 362 | int err; | ||
| 363 | |||
| 364 | spin_lock_init(&sch311x_wdt_data.io_lock); | ||
| 365 | |||
| 366 | if (!request_region(sch311x_wdt_data.runtime_reg + RESGEN, 1, | ||
| 367 | DRV_NAME)) { | ||
| 368 | dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n", | ||
| 369 | sch311x_wdt_data.runtime_reg + RESGEN, | ||
| 370 | sch311x_wdt_data.runtime_reg + RESGEN); | ||
| 371 | err = -EBUSY; | ||
| 372 | goto exit; | ||
| 373 | } | ||
| 374 | |||
| 375 | if (!request_region(sch311x_wdt_data.runtime_reg + GP60, 1, DRV_NAME)) { | ||
| 376 | dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n", | ||
| 377 | sch311x_wdt_data.runtime_reg + GP60, | ||
| 378 | sch311x_wdt_data.runtime_reg + GP60); | ||
| 379 | err = -EBUSY; | ||
| 380 | goto exit_release_region; | ||
| 381 | } | ||
| 382 | |||
| 383 | if (!request_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4, | ||
| 384 | DRV_NAME)) { | ||
| 385 | dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n", | ||
| 386 | sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, | ||
| 387 | sch311x_wdt_data.runtime_reg + WDT_CTRL); | ||
| 388 | err = -EBUSY; | ||
| 389 | goto exit_release_region2; | ||
| 390 | } | ||
| 391 | |||
| 392 | /* Make sure that the watchdog is not running */ | ||
| 393 | sch311x_wdt_stop(); | ||
| 394 | |||
| 395 | /* Disable keyboard and mouse interaction and interrupt */ | ||
| 396 | /* -- Watchdog timer configuration -- | ||
| 397 | * Bit 0 Reserved | ||
| 398 | * Bit 1 Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr. | ||
| 399 | * Bit 2 Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr | ||
| 400 | * Bit 3 Reserved | ||
| 401 | * Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled, | ||
| 402 | * 0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15) | ||
| 403 | */ | ||
| 404 | outb(0, sch311x_wdt_data.runtime_reg + WDT_CFG); | ||
| 405 | |||
| 406 | /* Check that the heartbeat value is within it's range ; | ||
| 407 | * if not reset to the default */ | ||
| 408 | if (sch311x_wdt_set_heartbeat(timeout)) { | ||
| 409 | sch311x_wdt_set_heartbeat(WATCHDOG_TIMEOUT); | ||
| 410 | dev_info(dev, "timeout value must be 1<=x<=15300, using %d\n", | ||
| 411 | timeout); | ||
| 412 | } | ||
| 413 | |||
| 414 | /* Get status at boot */ | ||
| 415 | sch311x_wdt_get_status(&sch311x_wdt_data.boot_status); | ||
| 416 | |||
| 417 | /* enable watchdog */ | ||
| 418 | /* -- Reset Generator -- | ||
| 419 | * Bit 0 Enable Watchdog Timer Generation: 0* = Enabled, 1 = Disabled | ||
| 420 | * Bit 1 Thermtrip Source Select: O* = No Source, 1 = Source | ||
| 421 | * Bit 2 WDT2_CTL: WDT input bit | ||
| 422 | * Bit 3-7 Reserved | ||
| 423 | */ | ||
| 424 | outb(0, sch311x_wdt_data.runtime_reg + RESGEN); | ||
| 425 | val = therm_trip ? 0x06 : 0x04; | ||
| 426 | outb(val, sch311x_wdt_data.runtime_reg + RESGEN); | ||
| 427 | |||
| 428 | err = misc_register(&sch311x_wdt_miscdev); | ||
| 429 | if (err != 0) { | ||
| 430 | dev_err(dev, "cannot register miscdev on minor=%d (err=%d)\n", | ||
| 431 | WATCHDOG_MINOR, err); | ||
| 432 | goto exit_release_region3; | ||
| 433 | } | ||
| 434 | |||
| 435 | sch311x_wdt_miscdev.parent = dev; | ||
| 436 | |||
| 437 | dev_info(dev, | ||
| 438 | "SMSC SCH311x WDT initialized. timeout=%d sec (nowayout=%d)\n", | ||
| 439 | timeout, nowayout); | ||
| 440 | |||
| 441 | return 0; | ||
| 442 | |||
| 443 | exit_release_region3: | ||
| 444 | release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4); | ||
| 445 | exit_release_region2: | ||
| 446 | release_region(sch311x_wdt_data.runtime_reg + GP60, 1); | ||
| 447 | exit_release_region: | ||
| 448 | release_region(sch311x_wdt_data.runtime_reg + RESGEN, 1); | ||
| 449 | sch311x_wdt_data.runtime_reg = 0; | ||
| 450 | exit: | ||
| 451 | return err; | ||
| 452 | } | ||
| 453 | |||
| 454 | static int __devexit sch311x_wdt_remove(struct platform_device *pdev) | ||
| 455 | { | ||
| 456 | /* Stop the timer before we leave */ | ||
| 457 | if (!nowayout) | ||
| 458 | sch311x_wdt_stop(); | ||
| 459 | |||
| 460 | /* Deregister */ | ||
| 461 | misc_deregister(&sch311x_wdt_miscdev); | ||
| 462 | release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4); | ||
| 463 | release_region(sch311x_wdt_data.runtime_reg + GP60, 1); | ||
| 464 | release_region(sch311x_wdt_data.runtime_reg + RESGEN, 1); | ||
| 465 | sch311x_wdt_data.runtime_reg = 0; | ||
| 466 | return 0; | ||
| 467 | } | ||
| 468 | |||
| 469 | static void sch311x_wdt_shutdown(struct platform_device *dev) | ||
| 470 | { | ||
| 471 | /* Turn the WDT off if we have a soft shutdown */ | ||
| 472 | sch311x_wdt_stop(); | ||
| 473 | } | ||
| 474 | |||
| 475 | #define sch311x_wdt_suspend NULL | ||
| 476 | #define sch311x_wdt_resume NULL | ||
| 477 | |||
| 478 | static struct platform_driver sch311x_wdt_driver = { | ||
| 479 | .probe = sch311x_wdt_probe, | ||
| 480 | .remove = __devexit_p(sch311x_wdt_remove), | ||
| 481 | .shutdown = sch311x_wdt_shutdown, | ||
| 482 | .suspend = sch311x_wdt_suspend, | ||
| 483 | .resume = sch311x_wdt_resume, | ||
| 484 | .driver = { | ||
| 485 | .owner = THIS_MODULE, | ||
| 486 | .name = DRV_NAME, | ||
| 487 | }, | ||
| 488 | }; | ||
| 489 | |||
| 490 | static int __init sch311x_detect(int sio_config_port, unsigned short *addr) | ||
| 491 | { | ||
| 492 | int err = 0, reg; | ||
| 493 | unsigned short base_addr; | ||
| 494 | unsigned char dev_id; | ||
| 495 | |||
| 496 | sch311x_sio_enter(sio_config_port); | ||
| 497 | |||
| 498 | /* Check device ID. We currently know about: | ||
| 499 | * SCH3112 (0x7c), SCH3114 (0x7d), and SCH3116 (0x7f). */ | ||
| 500 | reg = force_id ? force_id : sch311x_sio_inb(sio_config_port, 0x20); | ||
| 501 | if (!(reg == 0x7c || reg == 0x7d || reg == 0x7f)) { | ||
| 502 | err = -ENODEV; | ||
| 503 | goto exit; | ||
| 504 | } | ||
| 505 | dev_id = reg == 0x7c ? 2 : reg == 0x7d ? 4 : 6; | ||
| 506 | |||
| 507 | /* Select logical device A (runtime registers) */ | ||
| 508 | sch311x_sio_outb(sio_config_port, 0x07, 0x0a); | ||
| 509 | |||
| 510 | /* Check if Logical Device Register is currently active */ | ||
| 511 | if (sch311x_sio_inb(sio_config_port, 0x30) && 0x01 == 0) | ||
| 512 | printk(KERN_INFO PFX "Seems that LDN 0x0a is not active...\n"); | ||
| 513 | |||
| 514 | /* Get the base address of the runtime registers */ | ||
| 515 | base_addr = (sch311x_sio_inb(sio_config_port, 0x60) << 8) | | ||
| 516 | sch311x_sio_inb(sio_config_port, 0x61); | ||
| 517 | if (!base_addr) { | ||
| 518 | printk(KERN_ERR PFX "Base address not set.\n"); | ||
| 519 | err = -ENODEV; | ||
| 520 | goto exit; | ||
| 521 | } | ||
| 522 | *addr = base_addr; | ||
| 523 | |||
| 524 | printk(KERN_INFO PFX "Found an SMSC SCH311%d chip at 0x%04x\n", | ||
| 525 | dev_id, base_addr); | ||
| 526 | |||
| 527 | exit: | ||
| 528 | sch311x_sio_exit(sio_config_port); | ||
| 529 | return err; | ||
| 530 | } | ||
| 531 | |||
| 532 | static int __init sch311x_wdt_init(void) | ||
| 533 | { | ||
| 534 | int err, i, found = 0; | ||
| 535 | unsigned short addr = 0; | ||
| 536 | |||
| 537 | for (i = 0; !found && sch311x_ioports[i]; i++) | ||
| 538 | if (sch311x_detect(sch311x_ioports[i], &addr) == 0) | ||
| 539 | found++; | ||
| 540 | |||
| 541 | if (!found) | ||
| 542 | return -ENODEV; | ||
| 543 | |||
| 544 | sch311x_wdt_data.runtime_reg = addr; | ||
| 545 | |||
| 546 | err = platform_driver_register(&sch311x_wdt_driver); | ||
| 547 | if (err) | ||
| 548 | return err; | ||
| 549 | |||
| 550 | sch311x_wdt_pdev = platform_device_register_simple(DRV_NAME, addr, | ||
| 551 | NULL, 0); | ||
| 552 | |||
| 553 | if (IS_ERR(sch311x_wdt_pdev)) { | ||
| 554 | err = PTR_ERR(sch311x_wdt_pdev); | ||
| 555 | goto unreg_platform_driver; | ||
| 556 | } | ||
| 557 | |||
| 558 | return 0; | ||
| 559 | |||
| 560 | unreg_platform_driver: | ||
| 561 | platform_driver_unregister(&sch311x_wdt_driver); | ||
| 562 | return err; | ||
| 563 | } | ||
| 564 | |||
| 565 | static void __exit sch311x_wdt_exit(void) | ||
| 566 | { | ||
| 567 | platform_device_unregister(sch311x_wdt_pdev); | ||
| 568 | platform_driver_unregister(&sch311x_wdt_driver); | ||
| 569 | } | ||
| 570 | |||
| 571 | module_init(sch311x_wdt_init); | ||
| 572 | module_exit(sch311x_wdt_exit); | ||
| 573 | |||
| 574 | MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>"); | ||
| 575 | MODULE_DESCRIPTION("SMSC SCH311x WatchDog Timer Driver"); | ||
| 576 | MODULE_LICENSE("GPL"); | ||
| 577 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
| 578 | |||
diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c new file mode 100644 index 000000000000..2bc0d4d4b415 --- /dev/null +++ b/drivers/watchdog/wm8350_wdt.c | |||
| @@ -0,0 +1,329 @@ | |||
| 1 | /* | ||
| 2 | * Watchdog driver for the wm8350 | ||
| 3 | * | ||
| 4 | * Copyright (C) 2007, 2008 Wolfson Microelectronics <linux@wolfsonmicro.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/moduleparam.h> | ||
| 13 | #include <linux/types.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/fs.h> | ||
| 16 | #include <linux/miscdevice.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | #include <linux/watchdog.h> | ||
| 19 | #include <linux/uaccess.h> | ||
| 20 | #include <linux/mfd/wm8350/core.h> | ||
| 21 | |||
| 22 | static int nowayout = WATCHDOG_NOWAYOUT; | ||
| 23 | module_param(nowayout, int, 0); | ||
| 24 | MODULE_PARM_DESC(nowayout, | ||
| 25 | "Watchdog cannot be stopped once started (default=" | ||
| 26 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 27 | |||
| 28 | static unsigned long wm8350_wdt_users; | ||
| 29 | static struct miscdevice wm8350_wdt_miscdev; | ||
| 30 | static int wm8350_wdt_expect_close; | ||
| 31 | static DEFINE_MUTEX(wdt_mutex); | ||
| 32 | |||
| 33 | static struct { | ||
| 34 | int time; /* Seconds */ | ||
| 35 | u16 val; /* To be set in WM8350_SYSTEM_CONTROL_2 */ | ||
| 36 | } wm8350_wdt_cfgs[] = { | ||
| 37 | { 1, 0x02 }, | ||
| 38 | { 2, 0x04 }, | ||
| 39 | { 4, 0x05 }, | ||
| 40 | }; | ||
| 41 | |||
| 42 | static struct wm8350 *get_wm8350(void) | ||
| 43 | { | ||
| 44 | return dev_get_drvdata(wm8350_wdt_miscdev.parent); | ||
| 45 | } | ||
| 46 | |||
| 47 | static int wm8350_wdt_set_timeout(struct wm8350 *wm8350, u16 value) | ||
| 48 | { | ||
| 49 | int ret; | ||
| 50 | u16 reg; | ||
| 51 | |||
| 52 | mutex_lock(&wdt_mutex); | ||
| 53 | wm8350_reg_unlock(wm8350); | ||
| 54 | |||
| 55 | reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2); | ||
| 56 | reg &= ~WM8350_WDOG_TO_MASK; | ||
| 57 | reg |= value; | ||
| 58 | ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg); | ||
| 59 | |||
| 60 | wm8350_reg_lock(wm8350); | ||
| 61 | mutex_unlock(&wdt_mutex); | ||
| 62 | |||
| 63 | return ret; | ||
| 64 | } | ||
| 65 | |||
| 66 | static int wm8350_wdt_start(struct wm8350 *wm8350) | ||
| 67 | { | ||
| 68 | int ret; | ||
| 69 | u16 reg; | ||
| 70 | |||
| 71 | mutex_lock(&wdt_mutex); | ||
| 72 | wm8350_reg_unlock(wm8350); | ||
| 73 | |||
| 74 | reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2); | ||
| 75 | reg &= ~WM8350_WDOG_MODE_MASK; | ||
| 76 | reg |= 0x20; | ||
| 77 | ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg); | ||
| 78 | |||
| 79 | wm8350_reg_lock(wm8350); | ||
| 80 | mutex_unlock(&wdt_mutex); | ||
| 81 | |||
| 82 | return ret; | ||
| 83 | } | ||
| 84 | |||
| 85 | static int wm8350_wdt_stop(struct wm8350 *wm8350) | ||
| 86 | { | ||
| 87 | int ret; | ||
| 88 | u16 reg; | ||
| 89 | |||
| 90 | mutex_lock(&wdt_mutex); | ||
| 91 | wm8350_reg_unlock(wm8350); | ||
| 92 | |||
| 93 | reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2); | ||
| 94 | reg &= ~WM8350_WDOG_MODE_MASK; | ||
| 95 | ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg); | ||
| 96 | |||
| 97 | wm8350_reg_lock(wm8350); | ||
| 98 | mutex_unlock(&wdt_mutex); | ||
| 99 | |||
| 100 | return ret; | ||
| 101 | } | ||
| 102 | |||
| 103 | static int wm8350_wdt_kick(struct wm8350 *wm8350) | ||
| 104 | { | ||
| 105 | int ret; | ||
| 106 | u16 reg; | ||
| 107 | |||
| 108 | mutex_lock(&wdt_mutex); | ||
| 109 | |||
| 110 | reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2); | ||
| 111 | ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg); | ||
| 112 | |||
| 113 | mutex_unlock(&wdt_mutex); | ||
| 114 | |||
| 115 | return ret; | ||
| 116 | } | ||
| 117 | |||
| 118 | static int wm8350_wdt_open(struct inode *inode, struct file *file) | ||
| 119 | { | ||
| 120 | struct wm8350 *wm8350 = get_wm8350(); | ||
| 121 | int ret; | ||
| 122 | |||
| 123 | if (!wm8350) | ||
| 124 | return -ENODEV; | ||
| 125 | |||
| 126 | if (test_and_set_bit(0, &wm8350_wdt_users)) | ||
| 127 | return -EBUSY; | ||
| 128 | |||
| 129 | ret = wm8350_wdt_start(wm8350); | ||
| 130 | if (ret != 0) | ||
| 131 | return ret; | ||
| 132 | |||
| 133 | return nonseekable_open(inode, file); | ||
| 134 | } | ||
| 135 | |||
| 136 | static int wm8350_wdt_release(struct inode *inode, struct file *file) | ||
| 137 | { | ||
| 138 | struct wm8350 *wm8350 = get_wm8350(); | ||
| 139 | |||
| 140 | if (wm8350_wdt_expect_close) | ||
| 141 | wm8350_wdt_stop(wm8350); | ||
| 142 | else { | ||
| 143 | dev_warn(wm8350->dev, "Watchdog device closed uncleanly\n"); | ||
| 144 | wm8350_wdt_kick(wm8350); | ||
| 145 | } | ||
| 146 | |||
| 147 | clear_bit(0, &wm8350_wdt_users); | ||
| 148 | |||
| 149 | return 0; | ||
| 150 | } | ||
| 151 | |||
| 152 | static ssize_t wm8350_wdt_write(struct file *file, | ||
| 153 | const char __user *data, size_t count, | ||
| 154 | loff_t *ppos) | ||
| 155 | { | ||
| 156 | struct wm8350 *wm8350 = get_wm8350(); | ||
| 157 | size_t i; | ||
| 158 | |||
| 159 | if (count) { | ||
| 160 | wm8350_wdt_kick(wm8350); | ||
| 161 | |||
| 162 | if (!nowayout) { | ||
| 163 | /* In case it was set long ago */ | ||
| 164 | wm8350_wdt_expect_close = 0; | ||
| 165 | |||
| 166 | /* scan to see whether or not we got the magic | ||
| 167 | character */ | ||
| 168 | for (i = 0; i != count; i++) { | ||
| 169 | char c; | ||
| 170 | if (get_user(c, data + i)) | ||
| 171 | return -EFAULT; | ||
| 172 | if (c == 'V') | ||
| 173 | wm8350_wdt_expect_close = 42; | ||
| 174 | } | ||
| 175 | } | ||
| 176 | } | ||
| 177 | return count; | ||
| 178 | } | ||
| 179 | |||
| 180 | static struct watchdog_info ident = { | ||
| 181 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, | ||
| 182 | .identity = "WM8350 Watchdog", | ||
| 183 | }; | ||
| 184 | |||
| 185 | static long wm8350_wdt_ioctl(struct file *file, unsigned int cmd, | ||
| 186 | unsigned long arg) | ||
| 187 | { | ||
| 188 | struct wm8350 *wm8350 = get_wm8350(); | ||
| 189 | int ret = -ENOTTY, time, i; | ||
| 190 | void __user *argp = (void __user *)arg; | ||
| 191 | int __user *p = argp; | ||
| 192 | u16 reg; | ||
| 193 | |||
| 194 | switch (cmd) { | ||
| 195 | case WDIOC_GETSUPPORT: | ||
| 196 | ret = copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; | ||
| 197 | break; | ||
| 198 | |||
| 199 | case WDIOC_GETSTATUS: | ||
| 200 | case WDIOC_GETBOOTSTATUS: | ||
| 201 | ret = put_user(0, p); | ||
| 202 | break; | ||
| 203 | |||
| 204 | case WDIOC_SETOPTIONS: | ||
| 205 | { | ||
| 206 | int options; | ||
| 207 | |||
| 208 | if (get_user(options, p)) | ||
| 209 | return -EFAULT; | ||
| 210 | |||
| 211 | ret = -EINVAL; | ||
| 212 | |||
| 213 | /* Setting both simultaneously means at least one must fail */ | ||
| 214 | if (options == WDIOS_DISABLECARD) | ||
| 215 | ret = wm8350_wdt_start(wm8350); | ||
| 216 | |||
| 217 | if (options == WDIOS_ENABLECARD) | ||
| 218 | ret = wm8350_wdt_stop(wm8350); | ||
| 219 | break; | ||
| 220 | } | ||
| 221 | |||
| 222 | case WDIOC_KEEPALIVE: | ||
| 223 | ret = wm8350_wdt_kick(wm8350); | ||
| 224 | break; | ||
| 225 | |||
| 226 | case WDIOC_SETTIMEOUT: | ||
| 227 | ret = get_user(time, p); | ||
| 228 | if (ret) | ||
| 229 | break; | ||
| 230 | |||
| 231 | if (time == 0) { | ||
| 232 | if (nowayout) | ||
| 233 | ret = -EINVAL; | ||
| 234 | else | ||
| 235 | wm8350_wdt_stop(wm8350); | ||
| 236 | break; | ||
| 237 | } | ||
| 238 | |||
| 239 | for (i = 0; i < ARRAY_SIZE(wm8350_wdt_cfgs); i++) | ||
| 240 | if (wm8350_wdt_cfgs[i].time == time) | ||
| 241 | break; | ||
| 242 | if (i == ARRAY_SIZE(wm8350_wdt_cfgs)) | ||
| 243 | ret = -EINVAL; | ||
| 244 | else | ||
| 245 | ret = wm8350_wdt_set_timeout(wm8350, | ||
| 246 | wm8350_wdt_cfgs[i].val); | ||
| 247 | break; | ||
| 248 | |||
| 249 | case WDIOC_GETTIMEOUT: | ||
| 250 | reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2); | ||
| 251 | reg &= WM8350_WDOG_TO_MASK; | ||
| 252 | for (i = 0; i < ARRAY_SIZE(wm8350_wdt_cfgs); i++) | ||
| 253 | if (wm8350_wdt_cfgs[i].val == reg) | ||
| 254 | break; | ||
| 255 | if (i == ARRAY_SIZE(wm8350_wdt_cfgs)) { | ||
| 256 | dev_warn(wm8350->dev, | ||
| 257 | "Unknown watchdog configuration: %x\n", reg); | ||
| 258 | ret = -EINVAL; | ||
| 259 | } else | ||
| 260 | ret = put_user(wm8350_wdt_cfgs[i].time, p); | ||
| 261 | |||
| 262 | } | ||
| 263 | |||
| 264 | return ret; | ||
| 265 | } | ||
| 266 | |||
| 267 | static const struct file_operations wm8350_wdt_fops = { | ||
| 268 | .owner = THIS_MODULE, | ||
| 269 | .llseek = no_llseek, | ||
| 270 | .write = wm8350_wdt_write, | ||
| 271 | .unlocked_ioctl = wm8350_wdt_ioctl, | ||
| 272 | .open = wm8350_wdt_open, | ||
| 273 | .release = wm8350_wdt_release, | ||
| 274 | }; | ||
| 275 | |||
| 276 | static struct miscdevice wm8350_wdt_miscdev = { | ||
| 277 | .minor = WATCHDOG_MINOR, | ||
| 278 | .name = "watchdog", | ||
| 279 | .fops = &wm8350_wdt_fops, | ||
| 280 | }; | ||
| 281 | |||
| 282 | static int wm8350_wdt_probe(struct platform_device *pdev) | ||
| 283 | { | ||
| 284 | struct wm8350 *wm8350 = platform_get_drvdata(pdev); | ||
| 285 | |||
| 286 | if (!wm8350) { | ||
| 287 | dev_err(wm8350->dev, "No driver data supplied\n"); | ||
| 288 | return -ENODEV; | ||
| 289 | } | ||
| 290 | |||
| 291 | /* Default to 4s timeout */ | ||
| 292 | wm8350_wdt_set_timeout(wm8350, 0x05); | ||
| 293 | |||
| 294 | wm8350_wdt_miscdev.parent = &pdev->dev; | ||
| 295 | |||
| 296 | return misc_register(&wm8350_wdt_miscdev); | ||
| 297 | } | ||
| 298 | |||
| 299 | static int __exit wm8350_wdt_remove(struct platform_device *pdev) | ||
| 300 | { | ||
| 301 | misc_deregister(&wm8350_wdt_miscdev); | ||
| 302 | |||
| 303 | return 0; | ||
| 304 | } | ||
| 305 | |||
| 306 | static struct platform_driver wm8350_wdt_driver = { | ||
| 307 | .probe = wm8350_wdt_probe, | ||
| 308 | .remove = wm8350_wdt_remove, | ||
| 309 | .driver = { | ||
| 310 | .name = "wm8350-wdt", | ||
| 311 | }, | ||
| 312 | }; | ||
| 313 | |||
| 314 | static int __init wm8350_wdt_init(void) | ||
| 315 | { | ||
| 316 | return platform_driver_register(&wm8350_wdt_driver); | ||
| 317 | } | ||
| 318 | module_init(wm8350_wdt_init); | ||
| 319 | |||
| 320 | static void __exit wm8350_wdt_exit(void) | ||
| 321 | { | ||
| 322 | platform_driver_unregister(&wm8350_wdt_driver); | ||
| 323 | } | ||
| 324 | module_exit(wm8350_wdt_exit); | ||
| 325 | |||
| 326 | MODULE_AUTHOR("Mark Brown"); | ||
| 327 | MODULE_DESCRIPTION("WM8350 Watchdog"); | ||
| 328 | MODULE_LICENSE("GPL"); | ||
| 329 | MODULE_ALIAS("platform:wm8350-wdt"); | ||
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index f1f3f4192a60..b639dcf7c778 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c | |||
| @@ -95,92 +95,55 @@ static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, u | |||
| 95 | int has_dumped = 0; | 95 | int has_dumped = 0; |
| 96 | unsigned long dump_start, dump_size; | 96 | unsigned long dump_start, dump_size; |
| 97 | struct user dump; | 97 | struct user dump; |
| 98 | #if defined(__alpha__) | 98 | #ifdef __alpha__ |
| 99 | # define START_DATA(u) (u.start_data) | 99 | # define START_DATA(u) (u.start_data) |
| 100 | #elif defined(__arm__) | 100 | #else |
| 101 | # define START_DATA(u) ((u.u_tsize << PAGE_SHIFT) + u.start_code) | 101 | # define START_DATA(u) ((u.u_tsize << PAGE_SHIFT) + u.start_code) |
| 102 | #elif defined(__sparc__) | ||
| 103 | # define START_DATA(u) (u.u_tsize) | ||
| 104 | #elif defined(__i386__) || defined(__mc68000__) || defined(__arch_um__) | ||
| 105 | # define START_DATA(u) (u.u_tsize << PAGE_SHIFT) | ||
| 106 | #endif | 102 | #endif |
| 107 | #ifdef __sparc__ | ||
| 108 | # define START_STACK(u) ((regs->u_regs[UREG_FP]) & ~(PAGE_SIZE - 1)) | ||
| 109 | #else | ||
| 110 | # define START_STACK(u) (u.start_stack) | 103 | # define START_STACK(u) (u.start_stack) |
| 111 | #endif | ||
| 112 | 104 | ||
| 113 | fs = get_fs(); | 105 | fs = get_fs(); |
| 114 | set_fs(KERNEL_DS); | 106 | set_fs(KERNEL_DS); |
| 115 | has_dumped = 1; | 107 | has_dumped = 1; |
| 116 | current->flags |= PF_DUMPCORE; | 108 | current->flags |= PF_DUMPCORE; |
| 117 | strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm)); | 109 | strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm)); |
| 118 | #ifndef __sparc__ | ||
| 119 | dump.u_ar0 = offsetof(struct user, regs); | 110 | dump.u_ar0 = offsetof(struct user, regs); |
| 120 | #endif | ||
| 121 | dump.signal = signr; | 111 | dump.signal = signr; |
| 122 | aout_dump_thread(regs, &dump); | 112 | aout_dump_thread(regs, &dump); |
| 123 | 113 | ||
| 124 | /* If the size of the dump file exceeds the rlimit, then see what would happen | 114 | /* If the size of the dump file exceeds the rlimit, then see what would happen |
| 125 | if we wrote the stack, but not the data area. */ | 115 | if we wrote the stack, but not the data area. */ |
| 126 | #ifdef __sparc__ | ||
| 127 | if ((dump.u_dsize + dump.u_ssize) > limit) | ||
| 128 | dump.u_dsize = 0; | ||
| 129 | #else | ||
| 130 | if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit) | 116 | if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit) |
| 131 | dump.u_dsize = 0; | 117 | dump.u_dsize = 0; |
| 132 | #endif | ||
| 133 | 118 | ||
| 134 | /* Make sure we have enough room to write the stack and data areas. */ | 119 | /* Make sure we have enough room to write the stack and data areas. */ |
| 135 | #ifdef __sparc__ | ||
| 136 | if (dump.u_ssize > limit) | ||
| 137 | dump.u_ssize = 0; | ||
| 138 | #else | ||
| 139 | if ((dump.u_ssize + 1) * PAGE_SIZE > limit) | 120 | if ((dump.u_ssize + 1) * PAGE_SIZE > limit) |
| 140 | dump.u_ssize = 0; | 121 | dump.u_ssize = 0; |
| 141 | #endif | ||
| 142 | 122 | ||
| 143 | /* make sure we actually have a data and stack area to dump */ | 123 | /* make sure we actually have a data and stack area to dump */ |
| 144 | set_fs(USER_DS); | 124 | set_fs(USER_DS); |
| 145 | #ifdef __sparc__ | ||
| 146 | if (!access_ok(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize)) | ||
| 147 | dump.u_dsize = 0; | ||
| 148 | if (!access_ok(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize)) | ||
| 149 | dump.u_ssize = 0; | ||
| 150 | #else | ||
| 151 | if (!access_ok(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize << PAGE_SHIFT)) | 125 | if (!access_ok(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize << PAGE_SHIFT)) |
| 152 | dump.u_dsize = 0; | 126 | dump.u_dsize = 0; |
| 153 | if (!access_ok(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize << PAGE_SHIFT)) | 127 | if (!access_ok(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize << PAGE_SHIFT)) |
| 154 | dump.u_ssize = 0; | 128 | dump.u_ssize = 0; |
| 155 | #endif | ||
| 156 | 129 | ||
| 157 | set_fs(KERNEL_DS); | 130 | set_fs(KERNEL_DS); |
| 158 | /* struct user */ | 131 | /* struct user */ |
| 159 | DUMP_WRITE(&dump,sizeof(dump)); | 132 | DUMP_WRITE(&dump,sizeof(dump)); |
| 160 | /* Now dump all of the user data. Include malloced stuff as well */ | 133 | /* Now dump all of the user data. Include malloced stuff as well */ |
| 161 | #ifndef __sparc__ | ||
| 162 | DUMP_SEEK(PAGE_SIZE); | 134 | DUMP_SEEK(PAGE_SIZE); |
| 163 | #endif | ||
| 164 | /* now we start writing out the user space info */ | 135 | /* now we start writing out the user space info */ |
| 165 | set_fs(USER_DS); | 136 | set_fs(USER_DS); |
| 166 | /* Dump the data area */ | 137 | /* Dump the data area */ |
| 167 | if (dump.u_dsize != 0) { | 138 | if (dump.u_dsize != 0) { |
| 168 | dump_start = START_DATA(dump); | 139 | dump_start = START_DATA(dump); |
| 169 | #ifdef __sparc__ | ||
| 170 | dump_size = dump.u_dsize; | ||
| 171 | #else | ||
| 172 | dump_size = dump.u_dsize << PAGE_SHIFT; | 140 | dump_size = dump.u_dsize << PAGE_SHIFT; |
| 173 | #endif | ||
| 174 | DUMP_WRITE(dump_start,dump_size); | 141 | DUMP_WRITE(dump_start,dump_size); |
| 175 | } | 142 | } |
| 176 | /* Now prepare to dump the stack area */ | 143 | /* Now prepare to dump the stack area */ |
| 177 | if (dump.u_ssize != 0) { | 144 | if (dump.u_ssize != 0) { |
| 178 | dump_start = START_STACK(dump); | 145 | dump_start = START_STACK(dump); |
| 179 | #ifdef __sparc__ | ||
| 180 | dump_size = dump.u_ssize; | ||
| 181 | #else | ||
| 182 | dump_size = dump.u_ssize << PAGE_SHIFT; | 146 | dump_size = dump.u_ssize << PAGE_SHIFT; |
| 183 | #endif | ||
| 184 | DUMP_WRITE(dump_start,dump_size); | 147 | DUMP_WRITE(dump_start,dump_size); |
| 185 | } | 148 | } |
| 186 | /* Finally dump the task struct. Not be used by gdb, but could be useful */ | 149 | /* Finally dump the task struct. Not be used by gdb, but could be useful */ |
| @@ -205,29 +168,24 @@ static unsigned long __user *create_aout_tables(char __user *p, struct linux_bin | |||
| 205 | int envc = bprm->envc; | 168 | int envc = bprm->envc; |
| 206 | 169 | ||
| 207 | sp = (void __user *)((-(unsigned long)sizeof(char *)) & (unsigned long) p); | 170 | sp = (void __user *)((-(unsigned long)sizeof(char *)) & (unsigned long) p); |
| 208 | #ifdef __sparc__ | ||
| 209 | /* This imposes the proper stack alignment for a new process. */ | ||
| 210 | sp = (void __user *) (((unsigned long) sp) & ~7); | ||
| 211 | if ((envc+argc+3)&1) --sp; | ||
| 212 | #endif | ||
| 213 | #ifdef __alpha__ | 171 | #ifdef __alpha__ |
| 214 | /* whee.. test-programs are so much fun. */ | 172 | /* whee.. test-programs are so much fun. */ |
| 215 | put_user(0, --sp); | 173 | put_user(0, --sp); |
| 216 | put_user(0, --sp); | 174 | put_user(0, --sp); |
| 217 | if (bprm->loader) { | 175 | if (bprm->loader) { |
| 218 | put_user(0, --sp); | 176 | put_user(0, --sp); |
| 219 | put_user(0x3eb, --sp); | 177 | put_user(1003, --sp); |
| 220 | put_user(bprm->loader, --sp); | 178 | put_user(bprm->loader, --sp); |
| 221 | put_user(0x3ea, --sp); | 179 | put_user(1002, --sp); |
| 222 | } | 180 | } |
| 223 | put_user(bprm->exec, --sp); | 181 | put_user(bprm->exec, --sp); |
| 224 | put_user(0x3e9, --sp); | 182 | put_user(1001, --sp); |
| 225 | #endif | 183 | #endif |
| 226 | sp -= envc+1; | 184 | sp -= envc+1; |
| 227 | envp = (char __user * __user *) sp; | 185 | envp = (char __user * __user *) sp; |
| 228 | sp -= argc+1; | 186 | sp -= argc+1; |
| 229 | argv = (char __user * __user *) sp; | 187 | argv = (char __user * __user *) sp; |
| 230 | #if defined(__i386__) || defined(__mc68000__) || defined(__arm__) || defined(__arch_um__) | 188 | #ifndef __alpha__ |
| 231 | put_user((unsigned long) envp,--sp); | 189 | put_user((unsigned long) envp,--sp); |
| 232 | put_user((unsigned long) argv,--sp); | 190 | put_user((unsigned long) argv,--sp); |
| 233 | #endif | 191 | #endif |
| @@ -300,13 +258,8 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
| 300 | return retval; | 258 | return retval; |
| 301 | 259 | ||
| 302 | /* OK, This is the point of no return */ | 260 | /* OK, This is the point of no return */ |
| 303 | #if defined(__alpha__) | 261 | #ifdef __alpha__ |
| 304 | SET_AOUT_PERSONALITY(bprm, ex); | 262 | SET_AOUT_PERSONALITY(bprm, ex); |
| 305 | #elif defined(__sparc__) | ||
| 306 | set_personality(PER_SUNOS); | ||
| 307 | #if !defined(__sparc_v9__) | ||
| 308 | memcpy(¤t->thread.core_exec, &ex, sizeof(struct exec)); | ||
| 309 | #endif | ||
| 310 | #else | 263 | #else |
| 311 | set_personality(PER_LINUX); | 264 | set_personality(PER_LINUX); |
| 312 | #endif | 265 | #endif |
| @@ -322,24 +275,6 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
| 322 | 275 | ||
| 323 | install_exec_creds(bprm); | 276 | install_exec_creds(bprm); |
| 324 | current->flags &= ~PF_FORKNOEXEC; | 277 | current->flags &= ~PF_FORKNOEXEC; |
| 325 | #ifdef __sparc__ | ||
| 326 | if (N_MAGIC(ex) == NMAGIC) { | ||
| 327 | loff_t pos = fd_offset; | ||
| 328 | /* Fuck me plenty... */ | ||
| 329 | /* <AOL></AOL> */ | ||
| 330 | down_write(¤t->mm->mmap_sem); | ||
| 331 | error = do_brk(N_TXTADDR(ex), ex.a_text); | ||
| 332 | up_write(¤t->mm->mmap_sem); | ||
| 333 | bprm->file->f_op->read(bprm->file, (char *) N_TXTADDR(ex), | ||
| 334 | ex.a_text, &pos); | ||
| 335 | down_write(¤t->mm->mmap_sem); | ||
| 336 | error = do_brk(N_DATADDR(ex), ex.a_data); | ||
| 337 | up_write(¤t->mm->mmap_sem); | ||
| 338 | bprm->file->f_op->read(bprm->file, (char *) N_DATADDR(ex), | ||
| 339 | ex.a_data, &pos); | ||
| 340 | goto beyond_if; | ||
| 341 | } | ||
| 342 | #endif | ||
| 343 | 278 | ||
| 344 | if (N_MAGIC(ex) == OMAGIC) { | 279 | if (N_MAGIC(ex) == OMAGIC) { |
| 345 | unsigned long text_addr, map_size; | 280 | unsigned long text_addr, map_size; |
| @@ -347,7 +282,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
| 347 | 282 | ||
| 348 | text_addr = N_TXTADDR(ex); | 283 | text_addr = N_TXTADDR(ex); |
| 349 | 284 | ||
| 350 | #if defined(__alpha__) || defined(__sparc__) | 285 | #ifdef __alpha__ |
| 351 | pos = fd_offset; | 286 | pos = fd_offset; |
| 352 | map_size = ex.a_text+ex.a_data + PAGE_SIZE - 1; | 287 | map_size = ex.a_text+ex.a_data + PAGE_SIZE - 1; |
| 353 | #else | 288 | #else |
| @@ -57,11 +57,6 @@ | |||
| 57 | #include <asm/tlb.h> | 57 | #include <asm/tlb.h> |
| 58 | #include "internal.h" | 58 | #include "internal.h" |
| 59 | 59 | ||
| 60 | #ifdef __alpha__ | ||
| 61 | /* for /sbin/loader handling in search_binary_handler() */ | ||
| 62 | #include <linux/a.out.h> | ||
| 63 | #endif | ||
| 64 | |||
| 65 | int core_uses_pid; | 60 | int core_uses_pid; |
| 66 | char core_pattern[CORENAME_MAX_SIZE] = "core"; | 61 | char core_pattern[CORENAME_MAX_SIZE] = "core"; |
| 67 | int suid_dumpable = 0; | 62 | int suid_dumpable = 0; |
| @@ -1172,41 +1167,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) | |||
| 1172 | unsigned int depth = bprm->recursion_depth; | 1167 | unsigned int depth = bprm->recursion_depth; |
| 1173 | int try,retval; | 1168 | int try,retval; |
| 1174 | struct linux_binfmt *fmt; | 1169 | struct linux_binfmt *fmt; |
| 1175 | #ifdef __alpha__ | ||
| 1176 | /* handle /sbin/loader.. */ | ||
| 1177 | { | ||
| 1178 | struct exec * eh = (struct exec *) bprm->buf; | ||
| 1179 | 1170 | ||
| 1180 | if (!bprm->loader && eh->fh.f_magic == 0x183 && | ||
| 1181 | (eh->fh.f_flags & 0x3000) == 0x3000) | ||
| 1182 | { | ||
| 1183 | struct file * file; | ||
| 1184 | unsigned long loader; | ||
| 1185 | |||
| 1186 | allow_write_access(bprm->file); | ||
| 1187 | fput(bprm->file); | ||
| 1188 | bprm->file = NULL; | ||
| 1189 | |||
| 1190 | loader = bprm->vma->vm_end - sizeof(void *); | ||
| 1191 | |||
| 1192 | file = open_exec("/sbin/loader"); | ||
| 1193 | retval = PTR_ERR(file); | ||
| 1194 | if (IS_ERR(file)) | ||
| 1195 | return retval; | ||
| 1196 | |||
| 1197 | /* Remember if the application is TASO. */ | ||
| 1198 | bprm->taso = eh->ah.entry < 0x100000000UL; | ||
| 1199 | |||
| 1200 | bprm->file = file; | ||
| 1201 | bprm->loader = loader; | ||
| 1202 | retval = prepare_binprm(bprm); | ||
| 1203 | if (retval<0) | ||
| 1204 | return retval; | ||
| 1205 | /* should call search_binary_handler recursively here, | ||
| 1206 | but it does not matter */ | ||
| 1207 | } | ||
| 1208 | } | ||
| 1209 | #endif | ||
| 1210 | retval = security_bprm_check(bprm); | 1171 | retval = security_bprm_check(bprm); |
| 1211 | if (retval) | 1172 | if (retval) |
| 1212 | return retval; | 1173 | return retval; |
diff --git a/fs/seq_file.c b/fs/seq_file.c index 99d8b8cfc9b7..b569ff1c4dc8 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
| @@ -468,7 +468,8 @@ int seq_dentry(struct seq_file *m, struct dentry *dentry, char *esc) | |||
| 468 | return -1; | 468 | return -1; |
| 469 | } | 469 | } |
| 470 | 470 | ||
| 471 | int seq_bitmap(struct seq_file *m, unsigned long *bits, unsigned int nr_bits) | 471 | int seq_bitmap(struct seq_file *m, const unsigned long *bits, |
| 472 | unsigned int nr_bits) | ||
| 472 | { | 473 | { |
| 473 | if (m->count < m->size) { | 474 | if (m->count < m->size) { |
| 474 | int len = bitmap_scnprintf(m->buf + m->count, | 475 | int len = bitmap_scnprintf(m->buf + m->count, |
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c index 4a18f084cc42..0e5e54d82924 100644 --- a/fs/ubifs/budget.c +++ b/fs/ubifs/budget.c | |||
| @@ -32,18 +32,15 @@ | |||
| 32 | 32 | ||
| 33 | #include "ubifs.h" | 33 | #include "ubifs.h" |
| 34 | #include <linux/writeback.h> | 34 | #include <linux/writeback.h> |
| 35 | #include <asm/div64.h> | 35 | #include <linux/math64.h> |
| 36 | 36 | ||
| 37 | /* | 37 | /* |
| 38 | * When pessimistic budget calculations say that there is no enough space, | 38 | * When pessimistic budget calculations say that there is no enough space, |
| 39 | * UBIFS starts writing back dirty inodes and pages, doing garbage collection, | 39 | * UBIFS starts writing back dirty inodes and pages, doing garbage collection, |
| 40 | * or committing. The below constants define maximum number of times UBIFS | 40 | * or committing. The below constant defines maximum number of times UBIFS |
| 41 | * repeats the operations. | 41 | * repeats the operations. |
| 42 | */ | 42 | */ |
| 43 | #define MAX_SHRINK_RETRIES 8 | 43 | #define MAX_MKSPC_RETRIES 3 |
| 44 | #define MAX_GC_RETRIES 4 | ||
| 45 | #define MAX_CMT_RETRIES 2 | ||
| 46 | #define MAX_NOSPC_RETRIES 1 | ||
| 47 | 44 | ||
| 48 | /* | 45 | /* |
| 49 | * The below constant defines amount of dirty pages which should be written | 46 | * The below constant defines amount of dirty pages which should be written |
| @@ -52,30 +49,6 @@ | |||
| 52 | #define NR_TO_WRITE 16 | 49 | #define NR_TO_WRITE 16 |
| 53 | 50 | ||
| 54 | /** | 51 | /** |
| 55 | * struct retries_info - information about re-tries while making free space. | ||
| 56 | * @prev_liability: previous liability | ||
| 57 | * @shrink_cnt: how many times the liability was shrinked | ||
| 58 | * @shrink_retries: count of liability shrink re-tries (increased when | ||
| 59 | * liability does not shrink) | ||
| 60 | * @try_gc: GC should be tried first | ||
| 61 | * @gc_retries: how many times GC was run | ||
| 62 | * @cmt_retries: how many times commit has been done | ||
| 63 | * @nospc_retries: how many times GC returned %-ENOSPC | ||
| 64 | * | ||
| 65 | * Since we consider budgeting to be the fast-path, and this structure has to | ||
| 66 | * be allocated on stack and zeroed out, we make it smaller using bit-fields. | ||
| 67 | */ | ||
| 68 | struct retries_info { | ||
| 69 | long long prev_liability; | ||
| 70 | unsigned int shrink_cnt; | ||
| 71 | unsigned int shrink_retries:5; | ||
| 72 | unsigned int try_gc:1; | ||
| 73 | unsigned int gc_retries:4; | ||
| 74 | unsigned int cmt_retries:3; | ||
| 75 | unsigned int nospc_retries:1; | ||
| 76 | }; | ||
| 77 | |||
| 78 | /** | ||
| 79 | * shrink_liability - write-back some dirty pages/inodes. | 52 | * shrink_liability - write-back some dirty pages/inodes. |
| 80 | * @c: UBIFS file-system description object | 53 | * @c: UBIFS file-system description object |
| 81 | * @nr_to_write: how many dirty pages to write-back | 54 | * @nr_to_write: how many dirty pages to write-back |
| @@ -147,9 +120,25 @@ static int run_gc(struct ubifs_info *c) | |||
| 147 | } | 120 | } |
| 148 | 121 | ||
| 149 | /** | 122 | /** |
| 123 | * get_liability - calculate current liability. | ||
| 124 | * @c: UBIFS file-system description object | ||
| 125 | * | ||
| 126 | * This function calculates and returns current UBIFS liability, i.e. the | ||
| 127 | * amount of bytes UBIFS has "promised" to write to the media. | ||
| 128 | */ | ||
| 129 | static long long get_liability(struct ubifs_info *c) | ||
| 130 | { | ||
| 131 | long long liab; | ||
| 132 | |||
| 133 | spin_lock(&c->space_lock); | ||
| 134 | liab = c->budg_idx_growth + c->budg_data_growth + c->budg_dd_growth; | ||
| 135 | spin_unlock(&c->space_lock); | ||
| 136 | return liab; | ||
| 137 | } | ||
| 138 | |||
| 139 | /** | ||
| 150 | * make_free_space - make more free space on the file-system. | 140 | * make_free_space - make more free space on the file-system. |
| 151 | * @c: UBIFS file-system description object | 141 | * @c: UBIFS file-system description object |
| 152 | * @ri: information about previous invocations of this function | ||
| 153 | * | 142 | * |
| 154 | * This function is called when an operation cannot be budgeted because there | 143 | * This function is called when an operation cannot be budgeted because there |
| 155 | * is supposedly no free space. But in most cases there is some free space: | 144 | * is supposedly no free space. But in most cases there is some free space: |
| @@ -165,87 +154,42 @@ static int run_gc(struct ubifs_info *c) | |||
| 165 | * Returns %-ENOSPC if it couldn't do more free space, and other negative error | 154 | * Returns %-ENOSPC if it couldn't do more free space, and other negative error |
| 166 | * codes on failures. | 155 | * codes on failures. |
| 167 | */ | 156 | */ |
| 168 | static int make_free_space(struct ubifs_info *c, struct retries_info *ri) | 157 | static int make_free_space(struct ubifs_info *c) |
| 169 | { | 158 | { |
| 170 | int err; | 159 | int err, retries = 0; |
| 171 | 160 | long long liab1, liab2; | |
| 172 | /* | ||
| 173 | * If we have some dirty pages and inodes (liability), try to write | ||
| 174 | * them back unless this was tried too many times without effect | ||
| 175 | * already. | ||
| 176 | */ | ||
| 177 | if (ri->shrink_retries < MAX_SHRINK_RETRIES && !ri->try_gc) { | ||
| 178 | long long liability; | ||
| 179 | |||
| 180 | spin_lock(&c->space_lock); | ||
| 181 | liability = c->budg_idx_growth + c->budg_data_growth + | ||
| 182 | c->budg_dd_growth; | ||
| 183 | spin_unlock(&c->space_lock); | ||
| 184 | 161 | ||
| 185 | if (ri->prev_liability >= liability) { | 162 | do { |
| 186 | /* Liability does not shrink, next time try GC then */ | 163 | liab1 = get_liability(c); |
| 187 | ri->shrink_retries += 1; | 164 | /* |
| 188 | if (ri->gc_retries < MAX_GC_RETRIES) | 165 | * We probably have some dirty pages or inodes (liability), try |
| 189 | ri->try_gc = 1; | 166 | * to write them back. |
| 190 | dbg_budg("liability did not shrink: retries %d of %d", | 167 | */ |
| 191 | ri->shrink_retries, MAX_SHRINK_RETRIES); | 168 | dbg_budg("liability %lld, run write-back", liab1); |
| 192 | } | 169 | shrink_liability(c, NR_TO_WRITE); |
| 193 | 170 | ||
| 194 | dbg_budg("force write-back (count %d)", ri->shrink_cnt); | 171 | liab2 = get_liability(c); |
| 195 | shrink_liability(c, NR_TO_WRITE + ri->shrink_cnt); | 172 | if (liab2 < liab1) |
| 173 | return -EAGAIN; | ||
| 196 | 174 | ||
| 197 | ri->prev_liability = liability; | 175 | dbg_budg("new liability %lld (not shrinked)", liab2); |
| 198 | ri->shrink_cnt += 1; | ||
| 199 | return -EAGAIN; | ||
| 200 | } | ||
| 201 | 176 | ||
| 202 | /* | 177 | /* Liability did not shrink again, try GC */ |
| 203 | * Try to run garbage collector unless it was already tried too many | 178 | dbg_budg("Run GC"); |
| 204 | * times. | ||
| 205 | */ | ||
| 206 | if (ri->gc_retries < MAX_GC_RETRIES) { | ||
| 207 | ri->gc_retries += 1; | ||
| 208 | dbg_budg("run GC, retries %d of %d", | ||
| 209 | ri->gc_retries, MAX_GC_RETRIES); | ||
| 210 | |||
| 211 | ri->try_gc = 0; | ||
| 212 | err = run_gc(c); | 179 | err = run_gc(c); |
| 213 | if (!err) | 180 | if (!err) |
| 214 | return -EAGAIN; | 181 | return -EAGAIN; |
| 215 | 182 | ||
| 216 | if (err == -EAGAIN) { | 183 | if (err != -EAGAIN && err != -ENOSPC) |
| 217 | dbg_budg("GC asked to commit"); | 184 | /* Some real error happened */ |
| 218 | err = ubifs_run_commit(c); | ||
| 219 | if (err) | ||
| 220 | return err; | ||
| 221 | return -EAGAIN; | ||
| 222 | } | ||
| 223 | |||
| 224 | if (err != -ENOSPC) | ||
| 225 | return err; | ||
| 226 | |||
| 227 | /* | ||
| 228 | * GC could not make any progress. If this is the first time, | ||
| 229 | * then it makes sense to try to commit, because it might make | ||
| 230 | * some dirty space. | ||
| 231 | */ | ||
| 232 | dbg_budg("GC returned -ENOSPC, retries %d", | ||
| 233 | ri->nospc_retries); | ||
| 234 | if (ri->nospc_retries >= MAX_NOSPC_RETRIES) | ||
| 235 | return err; | 185 | return err; |
| 236 | ri->nospc_retries += 1; | ||
| 237 | } | ||
| 238 | 186 | ||
| 239 | /* Neither GC nor write-back helped, try to commit */ | 187 | dbg_budg("Run commit (retries %d)", retries); |
| 240 | if (ri->cmt_retries < MAX_CMT_RETRIES) { | ||
| 241 | ri->cmt_retries += 1; | ||
| 242 | dbg_budg("run commit, retries %d of %d", | ||
| 243 | ri->cmt_retries, MAX_CMT_RETRIES); | ||
| 244 | err = ubifs_run_commit(c); | 188 | err = ubifs_run_commit(c); |
| 245 | if (err) | 189 | if (err) |
| 246 | return err; | 190 | return err; |
| 247 | return -EAGAIN; | 191 | } while (retries++ < MAX_MKSPC_RETRIES); |
| 248 | } | 192 | |
| 249 | return -ENOSPC; | 193 | return -ENOSPC; |
| 250 | } | 194 | } |
| 251 | 195 | ||
| @@ -258,8 +202,8 @@ static int make_free_space(struct ubifs_info *c, struct retries_info *ri) | |||
| 258 | */ | 202 | */ |
| 259 | int ubifs_calc_min_idx_lebs(struct ubifs_info *c) | 203 | int ubifs_calc_min_idx_lebs(struct ubifs_info *c) |
| 260 | { | 204 | { |
| 261 | int ret; | 205 | int idx_lebs, eff_leb_size = c->leb_size - c->max_idx_node_sz; |
| 262 | uint64_t idx_size; | 206 | long long idx_size; |
| 263 | 207 | ||
| 264 | idx_size = c->old_idx_sz + c->budg_idx_growth + c->budg_uncommitted_idx; | 208 | idx_size = c->old_idx_sz + c->budg_idx_growth + c->budg_uncommitted_idx; |
| 265 | 209 | ||
| @@ -271,23 +215,16 @@ int ubifs_calc_min_idx_lebs(struct ubifs_info *c) | |||
| 271 | * pair, nor similarly the two variables for the new index size, so we | 215 | * pair, nor similarly the two variables for the new index size, so we |
| 272 | * have to do this costly 64-bit division on fast-path. | 216 | * have to do this costly 64-bit division on fast-path. |
| 273 | */ | 217 | */ |
| 274 | if (do_div(idx_size, c->leb_size - c->max_idx_node_sz)) | 218 | idx_size += eff_leb_size - 1; |
| 275 | ret = idx_size + 1; | 219 | idx_lebs = div_u64(idx_size, eff_leb_size); |
| 276 | else | ||
| 277 | ret = idx_size; | ||
| 278 | /* | 220 | /* |
| 279 | * The index head is not available for the in-the-gaps method, so add an | 221 | * The index head is not available for the in-the-gaps method, so add an |
| 280 | * extra LEB to compensate. | 222 | * extra LEB to compensate. |
| 281 | */ | 223 | */ |
| 282 | ret += 1; | 224 | idx_lebs += 1; |
| 283 | /* | 225 | if (idx_lebs < MIN_INDEX_LEBS) |
| 284 | * At present the index needs at least 2 LEBs: one for the index head | 226 | idx_lebs = MIN_INDEX_LEBS; |
| 285 | * and one for in-the-gaps method (which currently does not cater for | 227 | return idx_lebs; |
| 286 | * the index head and so excludes it from consideration). | ||
| 287 | */ | ||
| 288 | if (ret < 2) | ||
| 289 | ret = 2; | ||
| 290 | return ret; | ||
| 291 | } | 228 | } |
| 292 | 229 | ||
| 293 | /** | 230 | /** |
| @@ -530,8 +467,7 @@ static int calc_dd_growth(const struct ubifs_info *c, | |||
| 530 | int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req) | 467 | int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req) |
| 531 | { | 468 | { |
| 532 | int uninitialized_var(cmt_retries), uninitialized_var(wb_retries); | 469 | int uninitialized_var(cmt_retries), uninitialized_var(wb_retries); |
| 533 | int err, idx_growth, data_growth, dd_growth; | 470 | int err, idx_growth, data_growth, dd_growth, retried = 0; |
| 534 | struct retries_info ri; | ||
| 535 | 471 | ||
| 536 | ubifs_assert(req->new_page <= 1); | 472 | ubifs_assert(req->new_page <= 1); |
| 537 | ubifs_assert(req->dirtied_page <= 1); | 473 | ubifs_assert(req->dirtied_page <= 1); |
| @@ -549,7 +485,6 @@ int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req) | |||
| 549 | if (!data_growth && !dd_growth) | 485 | if (!data_growth && !dd_growth) |
| 550 | return 0; | 486 | return 0; |
| 551 | idx_growth = calc_idx_growth(c, req); | 487 | idx_growth = calc_idx_growth(c, req); |
| 552 | memset(&ri, 0, sizeof(struct retries_info)); | ||
| 553 | 488 | ||
| 554 | again: | 489 | again: |
| 555 | spin_lock(&c->space_lock); | 490 | spin_lock(&c->space_lock); |
| @@ -587,12 +522,17 @@ again: | |||
| 587 | return err; | 522 | return err; |
| 588 | } | 523 | } |
| 589 | 524 | ||
| 590 | err = make_free_space(c, &ri); | 525 | err = make_free_space(c); |
| 526 | cond_resched(); | ||
| 591 | if (err == -EAGAIN) { | 527 | if (err == -EAGAIN) { |
| 592 | dbg_budg("try again"); | 528 | dbg_budg("try again"); |
| 593 | cond_resched(); | ||
| 594 | goto again; | 529 | goto again; |
| 595 | } else if (err == -ENOSPC) { | 530 | } else if (err == -ENOSPC) { |
| 531 | if (!retried) { | ||
| 532 | retried = 1; | ||
| 533 | dbg_budg("-ENOSPC, but anyway try once again"); | ||
| 534 | goto again; | ||
| 535 | } | ||
| 596 | dbg_budg("FS is full, -ENOSPC"); | 536 | dbg_budg("FS is full, -ENOSPC"); |
| 597 | c->nospace = 1; | 537 | c->nospace = 1; |
| 598 | if (can_use_rp(c) || c->rp_size == 0) | 538 | if (can_use_rp(c) || c->rp_size == 0) |
| @@ -712,9 +652,9 @@ void ubifs_release_dirty_inode_budget(struct ubifs_info *c, | |||
| 712 | * user-space. User-space application tend to expect that if the file-system | 652 | * user-space. User-space application tend to expect that if the file-system |
| 713 | * (e.g., via the 'statfs()' call) reports that it has N bytes available, they | 653 | * (e.g., via the 'statfs()' call) reports that it has N bytes available, they |
| 714 | * are able to write a file of size N. UBIFS attaches node headers to each data | 654 | * are able to write a file of size N. UBIFS attaches node headers to each data |
| 715 | * node and it has to write indexind nodes as well. This introduces additional | 655 | * node and it has to write indexing nodes as well. This introduces additional |
| 716 | * overhead, and UBIFS it has to report sligtly less free space to meet the | 656 | * overhead, and UBIFS has to report slightly less free space to meet the above |
| 717 | * above expectetion. | 657 | * expectations. |
| 718 | * | 658 | * |
| 719 | * This function assumes free space is made up of uncompressed data nodes and | 659 | * This function assumes free space is made up of uncompressed data nodes and |
| 720 | * full index nodes (one per data node, tripled because we always allow enough | 660 | * full index nodes (one per data node, tripled because we always allow enough |
| @@ -723,7 +663,7 @@ void ubifs_release_dirty_inode_budget(struct ubifs_info *c, | |||
| 723 | * Note, the calculation is pessimistic, which means that most of the time | 663 | * Note, the calculation is pessimistic, which means that most of the time |
| 724 | * UBIFS reports less space than it actually has. | 664 | * UBIFS reports less space than it actually has. |
| 725 | */ | 665 | */ |
| 726 | long long ubifs_reported_space(const struct ubifs_info *c, uint64_t free) | 666 | long long ubifs_reported_space(const struct ubifs_info *c, long long free) |
| 727 | { | 667 | { |
| 728 | int divisor, factor, f; | 668 | int divisor, factor, f; |
| 729 | 669 | ||
| @@ -737,7 +677,7 @@ long long ubifs_reported_space(const struct ubifs_info *c, uint64_t free) | |||
| 737 | * of data nodes, f - fanout. Because effective UBIFS fanout is twice | 677 | * of data nodes, f - fanout. Because effective UBIFS fanout is twice |
| 738 | * as less than maximum fanout, we assume that each data node | 678 | * as less than maximum fanout, we assume that each data node |
| 739 | * introduces 3 * @c->max_idx_node_sz / (@c->fanout/2 - 1) bytes. | 679 | * introduces 3 * @c->max_idx_node_sz / (@c->fanout/2 - 1) bytes. |
| 740 | * Note, the multiplier 3 is because UBIFS reseves thrice as more space | 680 | * Note, the multiplier 3 is because UBIFS reserves thrice as more space |
| 741 | * for the index. | 681 | * for the index. |
| 742 | */ | 682 | */ |
| 743 | f = c->fanout > 3 ? c->fanout >> 1 : 2; | 683 | f = c->fanout > 3 ? c->fanout >> 1 : 2; |
| @@ -745,8 +685,7 @@ long long ubifs_reported_space(const struct ubifs_info *c, uint64_t free) | |||
| 745 | divisor = UBIFS_MAX_DATA_NODE_SZ; | 685 | divisor = UBIFS_MAX_DATA_NODE_SZ; |
| 746 | divisor += (c->max_idx_node_sz * 3) / (f - 1); | 686 | divisor += (c->max_idx_node_sz * 3) / (f - 1); |
| 747 | free *= factor; | 687 | free *= factor; |
| 748 | do_div(free, divisor); | 688 | return div_u64(free, divisor); |
| 749 | return free; | ||
| 750 | } | 689 | } |
| 751 | 690 | ||
| 752 | /** | 691 | /** |
| @@ -756,10 +695,10 @@ long long ubifs_reported_space(const struct ubifs_info *c, uint64_t free) | |||
| 756 | * This function calculates amount of free space to report to user-space. | 695 | * This function calculates amount of free space to report to user-space. |
| 757 | * | 696 | * |
| 758 | * Because UBIFS may introduce substantial overhead (the index, node headers, | 697 | * Because UBIFS may introduce substantial overhead (the index, node headers, |
| 759 | * alighment, wastage at the end of eraseblocks, etc), it cannot report real | 698 | * alignment, wastage at the end of eraseblocks, etc), it cannot report real |
| 760 | * amount of free flash space it has (well, because not all dirty space is | 699 | * amount of free flash space it has (well, because not all dirty space is |
| 761 | * reclamable, UBIFS does not actually know the real amount). If UBIFS did so, | 700 | * reclaimable, UBIFS does not actually know the real amount). If UBIFS did so, |
| 762 | * it would bread user expectetion about what free space is. Users seem to | 701 | * it would bread user expectations about what free space is. Users seem to |
| 763 | * accustomed to assume that if the file-system reports N bytes of free space, | 702 | * accustomed to assume that if the file-system reports N bytes of free space, |
| 764 | * they would be able to fit a file of N bytes to the FS. This almost works for | 703 | * they would be able to fit a file of N bytes to the FS. This almost works for |
| 765 | * traditional file-systems, because they have way less overhead than UBIFS. | 704 | * traditional file-systems, because they have way less overhead than UBIFS. |
| @@ -771,18 +710,9 @@ long long ubifs_get_free_space(struct ubifs_info *c) | |||
| 771 | long long available, outstanding, free; | 710 | long long available, outstanding, free; |
| 772 | 711 | ||
| 773 | spin_lock(&c->space_lock); | 712 | spin_lock(&c->space_lock); |
| 774 | min_idx_lebs = ubifs_calc_min_idx_lebs(c); | 713 | min_idx_lebs = c->min_idx_lebs; |
| 714 | ubifs_assert(min_idx_lebs == ubifs_calc_min_idx_lebs(c)); | ||
| 775 | outstanding = c->budg_data_growth + c->budg_dd_growth; | 715 | outstanding = c->budg_data_growth + c->budg_dd_growth; |
| 776 | |||
| 777 | /* | ||
| 778 | * Force the amount available to the total size reported if the used | ||
| 779 | * space is zero. | ||
| 780 | */ | ||
| 781 | if (c->lst.total_used <= UBIFS_INO_NODE_SZ && !outstanding) { | ||
| 782 | spin_unlock(&c->space_lock); | ||
| 783 | return (long long)c->block_cnt << UBIFS_BLOCK_SHIFT; | ||
| 784 | } | ||
| 785 | |||
| 786 | available = ubifs_calc_available(c, min_idx_lebs); | 716 | available = ubifs_calc_available(c, min_idx_lebs); |
| 787 | 717 | ||
| 788 | /* | 718 | /* |
diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c index b49884c8c10e..f3a7945527fb 100644 --- a/fs/ubifs/commit.c +++ b/fs/ubifs/commit.c | |||
| @@ -470,12 +470,12 @@ int dbg_old_index_check_init(struct ubifs_info *c, struct ubifs_zbranch *zroot) | |||
| 470 | { | 470 | { |
| 471 | struct ubifs_idx_node *idx; | 471 | struct ubifs_idx_node *idx; |
| 472 | int lnum, offs, len, err = 0; | 472 | int lnum, offs, len, err = 0; |
| 473 | struct ubifs_debug_info *d = c->dbg; | ||
| 473 | 474 | ||
| 474 | c->old_zroot = *zroot; | 475 | d->old_zroot = *zroot; |
| 475 | 476 | lnum = d->old_zroot.lnum; | |
| 476 | lnum = c->old_zroot.lnum; | 477 | offs = d->old_zroot.offs; |
| 477 | offs = c->old_zroot.offs; | 478 | len = d->old_zroot.len; |
| 478 | len = c->old_zroot.len; | ||
| 479 | 479 | ||
| 480 | idx = kmalloc(c->max_idx_node_sz, GFP_NOFS); | 480 | idx = kmalloc(c->max_idx_node_sz, GFP_NOFS); |
| 481 | if (!idx) | 481 | if (!idx) |
| @@ -485,8 +485,8 @@ int dbg_old_index_check_init(struct ubifs_info *c, struct ubifs_zbranch *zroot) | |||
| 485 | if (err) | 485 | if (err) |
| 486 | goto out; | 486 | goto out; |
| 487 | 487 | ||
| 488 | c->old_zroot_level = le16_to_cpu(idx->level); | 488 | d->old_zroot_level = le16_to_cpu(idx->level); |
| 489 | c->old_zroot_sqnum = le64_to_cpu(idx->ch.sqnum); | 489 | d->old_zroot_sqnum = le64_to_cpu(idx->ch.sqnum); |
| 490 | out: | 490 | out: |
| 491 | kfree(idx); | 491 | kfree(idx); |
| 492 | return err; | 492 | return err; |
| @@ -509,6 +509,7 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot) | |||
| 509 | { | 509 | { |
| 510 | int lnum, offs, len, err = 0, uninitialized_var(last_level), child_cnt; | 510 | int lnum, offs, len, err = 0, uninitialized_var(last_level), child_cnt; |
| 511 | int first = 1, iip; | 511 | int first = 1, iip; |
| 512 | struct ubifs_debug_info *d = c->dbg; | ||
| 512 | union ubifs_key lower_key, upper_key, l_key, u_key; | 513 | union ubifs_key lower_key, upper_key, l_key, u_key; |
| 513 | unsigned long long uninitialized_var(last_sqnum); | 514 | unsigned long long uninitialized_var(last_sqnum); |
| 514 | struct ubifs_idx_node *idx; | 515 | struct ubifs_idx_node *idx; |
| @@ -525,9 +526,9 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot) | |||
| 525 | UBIFS_IDX_NODE_SZ; | 526 | UBIFS_IDX_NODE_SZ; |
| 526 | 527 | ||
| 527 | /* Start at the old zroot */ | 528 | /* Start at the old zroot */ |
| 528 | lnum = c->old_zroot.lnum; | 529 | lnum = d->old_zroot.lnum; |
| 529 | offs = c->old_zroot.offs; | 530 | offs = d->old_zroot.offs; |
| 530 | len = c->old_zroot.len; | 531 | len = d->old_zroot.len; |
| 531 | iip = 0; | 532 | iip = 0; |
| 532 | 533 | ||
| 533 | /* | 534 | /* |
| @@ -560,11 +561,11 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot) | |||
| 560 | if (first) { | 561 | if (first) { |
| 561 | first = 0; | 562 | first = 0; |
| 562 | /* Check root level and sqnum */ | 563 | /* Check root level and sqnum */ |
| 563 | if (le16_to_cpu(idx->level) != c->old_zroot_level) { | 564 | if (le16_to_cpu(idx->level) != d->old_zroot_level) { |
| 564 | err = 2; | 565 | err = 2; |
| 565 | goto out_dump; | 566 | goto out_dump; |
| 566 | } | 567 | } |
| 567 | if (le64_to_cpu(idx->ch.sqnum) != c->old_zroot_sqnum) { | 568 | if (le64_to_cpu(idx->ch.sqnum) != d->old_zroot_sqnum) { |
| 568 | err = 3; | 569 | err = 3; |
| 569 | goto out_dump; | 570 | goto out_dump; |
| 570 | } | 571 | } |
diff --git a/fs/ubifs/compress.c b/fs/ubifs/compress.c index a0ada596b17c..11e4132f314a 100644 --- a/fs/ubifs/compress.c +++ b/fs/ubifs/compress.c | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | /* Fake description object for the "none" compressor */ | 33 | /* Fake description object for the "none" compressor */ |
| 34 | static struct ubifs_compressor none_compr = { | 34 | static struct ubifs_compressor none_compr = { |
| 35 | .compr_type = UBIFS_COMPR_NONE, | 35 | .compr_type = UBIFS_COMPR_NONE, |
| 36 | .name = "no compression", | 36 | .name = "none", |
| 37 | .capi_name = "", | 37 | .capi_name = "", |
| 38 | }; | 38 | }; |
| 39 | 39 | ||
| @@ -43,13 +43,13 @@ static DEFINE_MUTEX(lzo_mutex); | |||
| 43 | static struct ubifs_compressor lzo_compr = { | 43 | static struct ubifs_compressor lzo_compr = { |
| 44 | .compr_type = UBIFS_COMPR_LZO, | 44 | .compr_type = UBIFS_COMPR_LZO, |
| 45 | .comp_mutex = &lzo_mutex, | 45 | .comp_mutex = &lzo_mutex, |
| 46 | .name = "LZO", | 46 | .name = "lzo", |
| 47 | .capi_name = "lzo", | 47 | .capi_name = "lzo", |
| 48 | }; | 48 | }; |
| 49 | #else | 49 | #else |
| 50 | static struct ubifs_compressor lzo_compr = { | 50 | static struct ubifs_compressor lzo_compr = { |
| 51 | .compr_type = UBIFS_COMPR_LZO, | 51 | .compr_type = UBIFS_COMPR_LZO, |
| 52 | .name = "LZO", | 52 | .name = "lzo", |
| 53 | }; | 53 | }; |
| 54 | #endif | 54 | #endif |
| 55 | 55 | ||
| @@ -108,7 +108,7 @@ void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len, | |||
| 108 | if (compr->comp_mutex) | 108 | if (compr->comp_mutex) |
| 109 | mutex_lock(compr->comp_mutex); | 109 | mutex_lock(compr->comp_mutex); |
| 110 | err = crypto_comp_compress(compr->cc, in_buf, in_len, out_buf, | 110 | err = crypto_comp_compress(compr->cc, in_buf, in_len, out_buf, |
| 111 | out_len); | 111 | (unsigned int *)out_len); |
| 112 | if (compr->comp_mutex) | 112 | if (compr->comp_mutex) |
| 113 | mutex_unlock(compr->comp_mutex); | 113 | mutex_unlock(compr->comp_mutex); |
| 114 | if (unlikely(err)) { | 114 | if (unlikely(err)) { |
| @@ -119,10 +119,10 @@ void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len, | |||
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | /* | 121 | /* |
| 122 | * Presently, we just require that compression results in less data, | 122 | * If the data compressed only slightly, it is better to leave it |
| 123 | * rather than any defined minimum compression ratio or amount. | 123 | * uncompressed to improve read speed. |
| 124 | */ | 124 | */ |
| 125 | if (ALIGN(*out_len, 8) >= ALIGN(in_len, 8)) | 125 | if (in_len - *out_len < UBIFS_MIN_COMPRESS_DIFF) |
| 126 | goto no_compr; | 126 | goto no_compr; |
| 127 | 127 | ||
| 128 | return; | 128 | return; |
| @@ -172,7 +172,7 @@ int ubifs_decompress(const void *in_buf, int in_len, void *out_buf, | |||
| 172 | if (compr->decomp_mutex) | 172 | if (compr->decomp_mutex) |
| 173 | mutex_lock(compr->decomp_mutex); | 173 | mutex_lock(compr->decomp_mutex); |
| 174 | err = crypto_comp_decompress(compr->cc, in_buf, in_len, out_buf, | 174 | err = crypto_comp_decompress(compr->cc, in_buf, in_len, out_buf, |
| 175 | out_len); | 175 | (unsigned int *)out_len); |
| 176 | if (compr->decomp_mutex) | 176 | if (compr->decomp_mutex) |
| 177 | mutex_unlock(compr->decomp_mutex); | 177 | mutex_unlock(compr->decomp_mutex); |
| 178 | if (err) | 178 | if (err) |
| @@ -244,7 +244,7 @@ out_lzo: | |||
| 244 | /** | 244 | /** |
| 245 | * ubifs_compressors_exit - de-initialize UBIFS compressors. | 245 | * ubifs_compressors_exit - de-initialize UBIFS compressors. |
| 246 | */ | 246 | */ |
| 247 | void __exit ubifs_compressors_exit(void) | 247 | void ubifs_compressors_exit(void) |
| 248 | { | 248 | { |
| 249 | compr_exit(&lzo_compr); | 249 | compr_exit(&lzo_compr); |
| 250 | compr_exit(&zlib_compr); | 250 | compr_exit(&zlib_compr); |
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index 510ffa0bbda4..792c5a16c182 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c | |||
| @@ -32,6 +32,8 @@ | |||
| 32 | #include "ubifs.h" | 32 | #include "ubifs.h" |
| 33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
| 34 | #include <linux/moduleparam.h> | 34 | #include <linux/moduleparam.h> |
| 35 | #include <linux/debugfs.h> | ||
| 36 | #include <linux/math64.h> | ||
| 35 | 37 | ||
| 36 | #ifdef CONFIG_UBIFS_FS_DEBUG | 38 | #ifdef CONFIG_UBIFS_FS_DEBUG |
| 37 | 39 | ||
| @@ -596,7 +598,9 @@ void dbg_dump_budg(struct ubifs_info *c) | |||
| 596 | struct rb_node *rb; | 598 | struct rb_node *rb; |
| 597 | struct ubifs_bud *bud; | 599 | struct ubifs_bud *bud; |
| 598 | struct ubifs_gced_idx_leb *idx_gc; | 600 | struct ubifs_gced_idx_leb *idx_gc; |
| 601 | long long available, outstanding, free; | ||
| 599 | 602 | ||
| 603 | ubifs_assert(spin_is_locked(&c->space_lock)); | ||
| 600 | spin_lock(&dbg_lock); | 604 | spin_lock(&dbg_lock); |
| 601 | printk(KERN_DEBUG "(pid %d) Budgeting info: budg_data_growth %lld, " | 605 | printk(KERN_DEBUG "(pid %d) Budgeting info: budg_data_growth %lld, " |
| 602 | "budg_dd_growth %lld, budg_idx_growth %lld\n", current->pid, | 606 | "budg_dd_growth %lld, budg_idx_growth %lld\n", current->pid, |
| @@ -629,6 +633,17 @@ void dbg_dump_budg(struct ubifs_info *c) | |||
| 629 | printk(KERN_DEBUG "\tGC'ed idx LEB %d unmap %d\n", | 633 | printk(KERN_DEBUG "\tGC'ed idx LEB %d unmap %d\n", |
| 630 | idx_gc->lnum, idx_gc->unmap); | 634 | idx_gc->lnum, idx_gc->unmap); |
| 631 | printk(KERN_DEBUG "\tcommit state %d\n", c->cmt_state); | 635 | printk(KERN_DEBUG "\tcommit state %d\n", c->cmt_state); |
| 636 | |||
| 637 | /* Print budgeting predictions */ | ||
| 638 | available = ubifs_calc_available(c, c->min_idx_lebs); | ||
| 639 | outstanding = c->budg_data_growth + c->budg_dd_growth; | ||
| 640 | if (available > outstanding) | ||
| 641 | free = ubifs_reported_space(c, available - outstanding); | ||
| 642 | else | ||
| 643 | free = 0; | ||
| 644 | printk(KERN_DEBUG "Budgeting predictions:\n"); | ||
| 645 | printk(KERN_DEBUG "\tavailable: %lld, outstanding %lld, free %lld\n", | ||
| 646 | available, outstanding, free); | ||
| 632 | spin_unlock(&dbg_lock); | 647 | spin_unlock(&dbg_lock); |
| 633 | } | 648 | } |
| 634 | 649 | ||
| @@ -645,7 +660,8 @@ void dbg_dump_lprops(struct ubifs_info *c) | |||
| 645 | struct ubifs_lprops lp; | 660 | struct ubifs_lprops lp; |
| 646 | struct ubifs_lp_stats lst; | 661 | struct ubifs_lp_stats lst; |
| 647 | 662 | ||
| 648 | printk(KERN_DEBUG "(pid %d) Dumping LEB properties\n", current->pid); | 663 | printk(KERN_DEBUG "(pid %d) start dumping LEB properties\n", |
| 664 | current->pid); | ||
| 649 | ubifs_get_lp_stats(c, &lst); | 665 | ubifs_get_lp_stats(c, &lst); |
| 650 | dbg_dump_lstats(&lst); | 666 | dbg_dump_lstats(&lst); |
| 651 | 667 | ||
| @@ -656,6 +672,8 @@ void dbg_dump_lprops(struct ubifs_info *c) | |||
| 656 | 672 | ||
| 657 | dbg_dump_lprop(c, &lp); | 673 | dbg_dump_lprop(c, &lp); |
| 658 | } | 674 | } |
| 675 | printk(KERN_DEBUG "(pid %d) finish dumping LEB properties\n", | ||
| 676 | current->pid); | ||
| 659 | } | 677 | } |
| 660 | 678 | ||
| 661 | void dbg_dump_lpt_info(struct ubifs_info *c) | 679 | void dbg_dump_lpt_info(struct ubifs_info *c) |
| @@ -663,6 +681,7 @@ void dbg_dump_lpt_info(struct ubifs_info *c) | |||
| 663 | int i; | 681 | int i; |
| 664 | 682 | ||
| 665 | spin_lock(&dbg_lock); | 683 | spin_lock(&dbg_lock); |
| 684 | printk(KERN_DEBUG "(pid %d) dumping LPT information\n", current->pid); | ||
| 666 | printk(KERN_DEBUG "\tlpt_sz: %lld\n", c->lpt_sz); | 685 | printk(KERN_DEBUG "\tlpt_sz: %lld\n", c->lpt_sz); |
| 667 | printk(KERN_DEBUG "\tpnode_sz: %d\n", c->pnode_sz); | 686 | printk(KERN_DEBUG "\tpnode_sz: %d\n", c->pnode_sz); |
| 668 | printk(KERN_DEBUG "\tnnode_sz: %d\n", c->nnode_sz); | 687 | printk(KERN_DEBUG "\tnnode_sz: %d\n", c->nnode_sz); |
| @@ -684,7 +703,8 @@ void dbg_dump_lpt_info(struct ubifs_info *c) | |||
| 684 | printk(KERN_DEBUG "\tLPT root is at %d:%d\n", c->lpt_lnum, c->lpt_offs); | 703 | printk(KERN_DEBUG "\tLPT root is at %d:%d\n", c->lpt_lnum, c->lpt_offs); |
| 685 | printk(KERN_DEBUG "\tLPT head is at %d:%d\n", | 704 | printk(KERN_DEBUG "\tLPT head is at %d:%d\n", |
| 686 | c->nhead_lnum, c->nhead_offs); | 705 | c->nhead_lnum, c->nhead_offs); |
| 687 | printk(KERN_DEBUG "\tLPT ltab is at %d:%d\n", c->ltab_lnum, c->ltab_offs); | 706 | printk(KERN_DEBUG "\tLPT ltab is at %d:%d\n", |
| 707 | c->ltab_lnum, c->ltab_offs); | ||
| 688 | if (c->big_lpt) | 708 | if (c->big_lpt) |
| 689 | printk(KERN_DEBUG "\tLPT lsave is at %d:%d\n", | 709 | printk(KERN_DEBUG "\tLPT lsave is at %d:%d\n", |
| 690 | c->lsave_lnum, c->lsave_offs); | 710 | c->lsave_lnum, c->lsave_offs); |
| @@ -703,9 +723,9 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum) | |||
| 703 | if (dbg_failure_mode) | 723 | if (dbg_failure_mode) |
| 704 | return; | 724 | return; |
| 705 | 725 | ||
| 706 | printk(KERN_DEBUG "(pid %d) Dumping LEB %d\n", current->pid, lnum); | 726 | printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n", |
| 707 | 727 | current->pid, lnum); | |
| 708 | sleb = ubifs_scan(c, lnum, 0, c->dbg_buf); | 728 | sleb = ubifs_scan(c, lnum, 0, c->dbg->buf); |
| 709 | if (IS_ERR(sleb)) { | 729 | if (IS_ERR(sleb)) { |
| 710 | ubifs_err("scan error %d", (int)PTR_ERR(sleb)); | 730 | ubifs_err("scan error %d", (int)PTR_ERR(sleb)); |
| 711 | return; | 731 | return; |
| @@ -721,6 +741,8 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum) | |||
| 721 | dbg_dump_node(c, snod->node); | 741 | dbg_dump_node(c, snod->node); |
| 722 | } | 742 | } |
| 723 | 743 | ||
| 744 | printk(KERN_DEBUG "(pid %d) finish dumping LEB %d\n", | ||
| 745 | current->pid, lnum); | ||
| 724 | ubifs_scan_destroy(sleb); | 746 | ubifs_scan_destroy(sleb); |
| 725 | return; | 747 | return; |
| 726 | } | 748 | } |
| @@ -768,7 +790,7 @@ void dbg_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat) | |||
| 768 | { | 790 | { |
| 769 | int i; | 791 | int i; |
| 770 | 792 | ||
| 771 | printk(KERN_DEBUG "(pid %d) Dumping heap cat %d (%d elements)\n", | 793 | printk(KERN_DEBUG "(pid %d) start dumping heap cat %d (%d elements)\n", |
| 772 | current->pid, cat, heap->cnt); | 794 | current->pid, cat, heap->cnt); |
| 773 | for (i = 0; i < heap->cnt; i++) { | 795 | for (i = 0; i < heap->cnt; i++) { |
| 774 | struct ubifs_lprops *lprops = heap->arr[i]; | 796 | struct ubifs_lprops *lprops = heap->arr[i]; |
| @@ -777,6 +799,7 @@ void dbg_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat) | |||
| 777 | "flags %d\n", i, lprops->lnum, lprops->hpos, | 799 | "flags %d\n", i, lprops->lnum, lprops->hpos, |
| 778 | lprops->free, lprops->dirty, lprops->flags); | 800 | lprops->free, lprops->dirty, lprops->flags); |
| 779 | } | 801 | } |
| 802 | printk(KERN_DEBUG "(pid %d) finish dumping heap\n", current->pid); | ||
| 780 | } | 803 | } |
| 781 | 804 | ||
| 782 | void dbg_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, | 805 | void dbg_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, |
| @@ -784,7 +807,7 @@ void dbg_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, | |||
| 784 | { | 807 | { |
| 785 | int i; | 808 | int i; |
| 786 | 809 | ||
| 787 | printk(KERN_DEBUG "(pid %d) Dumping pnode:\n", current->pid); | 810 | printk(KERN_DEBUG "(pid %d) dumping pnode:\n", current->pid); |
| 788 | printk(KERN_DEBUG "\taddress %zx parent %zx cnext %zx\n", | 811 | printk(KERN_DEBUG "\taddress %zx parent %zx cnext %zx\n", |
| 789 | (size_t)pnode, (size_t)parent, (size_t)pnode->cnext); | 812 | (size_t)pnode, (size_t)parent, (size_t)pnode->cnext); |
| 790 | printk(KERN_DEBUG "\tflags %lu iip %d level %d num %d\n", | 813 | printk(KERN_DEBUG "\tflags %lu iip %d level %d num %d\n", |
| @@ -803,7 +826,7 @@ void dbg_dump_tnc(struct ubifs_info *c) | |||
| 803 | int level; | 826 | int level; |
| 804 | 827 | ||
| 805 | printk(KERN_DEBUG "\n"); | 828 | printk(KERN_DEBUG "\n"); |
| 806 | printk(KERN_DEBUG "(pid %d) Dumping the TNC tree\n", current->pid); | 829 | printk(KERN_DEBUG "(pid %d) start dumping TNC tree\n", current->pid); |
| 807 | znode = ubifs_tnc_levelorder_next(c->zroot.znode, NULL); | 830 | znode = ubifs_tnc_levelorder_next(c->zroot.znode, NULL); |
| 808 | level = znode->level; | 831 | level = znode->level; |
| 809 | printk(KERN_DEBUG "== Level %d ==\n", level); | 832 | printk(KERN_DEBUG "== Level %d ==\n", level); |
| @@ -815,8 +838,7 @@ void dbg_dump_tnc(struct ubifs_info *c) | |||
| 815 | dbg_dump_znode(c, znode); | 838 | dbg_dump_znode(c, znode); |
| 816 | znode = ubifs_tnc_levelorder_next(c->zroot.znode, znode); | 839 | znode = ubifs_tnc_levelorder_next(c->zroot.znode, znode); |
| 817 | } | 840 | } |
| 818 | 841 | printk(KERN_DEBUG "(pid %d) finish dumping TNC tree\n", current->pid); | |
| 819 | printk(KERN_DEBUG "\n"); | ||
| 820 | } | 842 | } |
| 821 | 843 | ||
| 822 | static int dump_znode(struct ubifs_info *c, struct ubifs_znode *znode, | 844 | static int dump_znode(struct ubifs_info *c, struct ubifs_znode *znode, |
| @@ -992,8 +1014,8 @@ static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1, | |||
| 992 | zbr1->offs, DBGKEY(&key)); | 1014 | zbr1->offs, DBGKEY(&key)); |
| 993 | dbg_err("but it should have key %s according to tnc", | 1015 | dbg_err("but it should have key %s according to tnc", |
| 994 | DBGKEY(&zbr1->key)); | 1016 | DBGKEY(&zbr1->key)); |
| 995 | dbg_dump_node(c, dent1); | 1017 | dbg_dump_node(c, dent1); |
| 996 | goto out_free; | 1018 | goto out_free; |
| 997 | } | 1019 | } |
| 998 | 1020 | ||
| 999 | key_read(c, &dent2->key, &key); | 1021 | key_read(c, &dent2->key, &key); |
| @@ -1002,8 +1024,8 @@ static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1, | |||
| 1002 | zbr1->offs, DBGKEY(&key)); | 1024 | zbr1->offs, DBGKEY(&key)); |
| 1003 | dbg_err("but it should have key %s according to tnc", | 1025 | dbg_err("but it should have key %s according to tnc", |
| 1004 | DBGKEY(&zbr2->key)); | 1026 | DBGKEY(&zbr2->key)); |
| 1005 | dbg_dump_node(c, dent2); | 1027 | dbg_dump_node(c, dent2); |
| 1006 | goto out_free; | 1028 | goto out_free; |
| 1007 | } | 1029 | } |
| 1008 | 1030 | ||
| 1009 | nlen1 = le16_to_cpu(dent1->nlen); | 1031 | nlen1 = le16_to_cpu(dent1->nlen); |
| @@ -1020,9 +1042,9 @@ static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1, | |||
| 1020 | dbg_err("bad order of colliding key %s", | 1042 | dbg_err("bad order of colliding key %s", |
| 1021 | DBGKEY(&key)); | 1043 | DBGKEY(&key)); |
| 1022 | 1044 | ||
| 1023 | dbg_msg("first node at %d:%d\n", zbr1->lnum, zbr1->offs); | 1045 | ubifs_msg("first node at %d:%d\n", zbr1->lnum, zbr1->offs); |
| 1024 | dbg_dump_node(c, dent1); | 1046 | dbg_dump_node(c, dent1); |
| 1025 | dbg_msg("second node at %d:%d\n", zbr2->lnum, zbr2->offs); | 1047 | ubifs_msg("second node at %d:%d\n", zbr2->lnum, zbr2->offs); |
| 1026 | dbg_dump_node(c, dent2); | 1048 | dbg_dump_node(c, dent2); |
| 1027 | 1049 | ||
| 1028 | out_free: | 1050 | out_free: |
| @@ -2097,13 +2119,13 @@ static int simple_rand(void) | |||
| 2097 | return (next >> 16) & 32767; | 2119 | return (next >> 16) & 32767; |
| 2098 | } | 2120 | } |
| 2099 | 2121 | ||
| 2100 | void dbg_failure_mode_registration(struct ubifs_info *c) | 2122 | static void failure_mode_init(struct ubifs_info *c) |
| 2101 | { | 2123 | { |
| 2102 | struct failure_mode_info *fmi; | 2124 | struct failure_mode_info *fmi; |
| 2103 | 2125 | ||
| 2104 | fmi = kmalloc(sizeof(struct failure_mode_info), GFP_NOFS); | 2126 | fmi = kmalloc(sizeof(struct failure_mode_info), GFP_NOFS); |
| 2105 | if (!fmi) { | 2127 | if (!fmi) { |
| 2106 | dbg_err("Failed to register failure mode - no memory"); | 2128 | ubifs_err("Failed to register failure mode - no memory"); |
| 2107 | return; | 2129 | return; |
| 2108 | } | 2130 | } |
| 2109 | fmi->c = c; | 2131 | fmi->c = c; |
| @@ -2112,7 +2134,7 @@ void dbg_failure_mode_registration(struct ubifs_info *c) | |||
| 2112 | spin_unlock(&fmi_lock); | 2134 | spin_unlock(&fmi_lock); |
| 2113 | } | 2135 | } |
| 2114 | 2136 | ||
| 2115 | void dbg_failure_mode_deregistration(struct ubifs_info *c) | 2137 | static void failure_mode_exit(struct ubifs_info *c) |
| 2116 | { | 2138 | { |
| 2117 | struct failure_mode_info *fmi, *tmp; | 2139 | struct failure_mode_info *fmi, *tmp; |
| 2118 | 2140 | ||
| @@ -2146,42 +2168,44 @@ static int in_failure_mode(struct ubi_volume_desc *desc) | |||
| 2146 | struct ubifs_info *c = dbg_find_info(desc); | 2168 | struct ubifs_info *c = dbg_find_info(desc); |
| 2147 | 2169 | ||
| 2148 | if (c && dbg_failure_mode) | 2170 | if (c && dbg_failure_mode) |
| 2149 | return c->failure_mode; | 2171 | return c->dbg->failure_mode; |
| 2150 | return 0; | 2172 | return 0; |
| 2151 | } | 2173 | } |
| 2152 | 2174 | ||
| 2153 | static int do_fail(struct ubi_volume_desc *desc, int lnum, int write) | 2175 | static int do_fail(struct ubi_volume_desc *desc, int lnum, int write) |
| 2154 | { | 2176 | { |
| 2155 | struct ubifs_info *c = dbg_find_info(desc); | 2177 | struct ubifs_info *c = dbg_find_info(desc); |
| 2178 | struct ubifs_debug_info *d; | ||
| 2156 | 2179 | ||
| 2157 | if (!c || !dbg_failure_mode) | 2180 | if (!c || !dbg_failure_mode) |
| 2158 | return 0; | 2181 | return 0; |
| 2159 | if (c->failure_mode) | 2182 | d = c->dbg; |
| 2183 | if (d->failure_mode) | ||
| 2160 | return 1; | 2184 | return 1; |
| 2161 | if (!c->fail_cnt) { | 2185 | if (!d->fail_cnt) { |
| 2162 | /* First call - decide delay to failure */ | 2186 | /* First call - decide delay to failure */ |
| 2163 | if (chance(1, 2)) { | 2187 | if (chance(1, 2)) { |
| 2164 | unsigned int delay = 1 << (simple_rand() >> 11); | 2188 | unsigned int delay = 1 << (simple_rand() >> 11); |
| 2165 | 2189 | ||
| 2166 | if (chance(1, 2)) { | 2190 | if (chance(1, 2)) { |
| 2167 | c->fail_delay = 1; | 2191 | d->fail_delay = 1; |
| 2168 | c->fail_timeout = jiffies + | 2192 | d->fail_timeout = jiffies + |
| 2169 | msecs_to_jiffies(delay); | 2193 | msecs_to_jiffies(delay); |
| 2170 | dbg_rcvry("failing after %ums", delay); | 2194 | dbg_rcvry("failing after %ums", delay); |
| 2171 | } else { | 2195 | } else { |
| 2172 | c->fail_delay = 2; | 2196 | d->fail_delay = 2; |
| 2173 | c->fail_cnt_max = delay; | 2197 | d->fail_cnt_max = delay; |
| 2174 | dbg_rcvry("failing after %u calls", delay); | 2198 | dbg_rcvry("failing after %u calls", delay); |
| 2175 | } | 2199 | } |
| 2176 | } | 2200 | } |
| 2177 | c->fail_cnt += 1; | 2201 | d->fail_cnt += 1; |
| 2178 | } | 2202 | } |
| 2179 | /* Determine if failure delay has expired */ | 2203 | /* Determine if failure delay has expired */ |
| 2180 | if (c->fail_delay == 1) { | 2204 | if (d->fail_delay == 1) { |
| 2181 | if (time_before(jiffies, c->fail_timeout)) | 2205 | if (time_before(jiffies, d->fail_timeout)) |
| 2182 | return 0; | 2206 | return 0; |
| 2183 | } else if (c->fail_delay == 2) | 2207 | } else if (d->fail_delay == 2) |
| 2184 | if (c->fail_cnt++ < c->fail_cnt_max) | 2208 | if (d->fail_cnt++ < d->fail_cnt_max) |
| 2185 | return 0; | 2209 | return 0; |
| 2186 | if (lnum == UBIFS_SB_LNUM) { | 2210 | if (lnum == UBIFS_SB_LNUM) { |
| 2187 | if (write) { | 2211 | if (write) { |
| @@ -2239,7 +2263,7 @@ static int do_fail(struct ubi_volume_desc *desc, int lnum, int write) | |||
| 2239 | dbg_rcvry("failing in bud LEB %d commit not running", lnum); | 2263 | dbg_rcvry("failing in bud LEB %d commit not running", lnum); |
| 2240 | } | 2264 | } |
| 2241 | ubifs_err("*** SETTING FAILURE MODE ON (LEB %d) ***", lnum); | 2265 | ubifs_err("*** SETTING FAILURE MODE ON (LEB %d) ***", lnum); |
| 2242 | c->failure_mode = 1; | 2266 | d->failure_mode = 1; |
| 2243 | dump_stack(); | 2267 | dump_stack(); |
| 2244 | return 1; | 2268 | return 1; |
| 2245 | } | 2269 | } |
| @@ -2344,4 +2368,181 @@ int dbg_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype) | |||
| 2344 | return 0; | 2368 | return 0; |
| 2345 | } | 2369 | } |
| 2346 | 2370 | ||
| 2371 | /** | ||
| 2372 | * ubifs_debugging_init - initialize UBIFS debugging. | ||
| 2373 | * @c: UBIFS file-system description object | ||
| 2374 | * | ||
| 2375 | * This function initializes debugging-related data for the file system. | ||
| 2376 | * Returns zero in case of success and a negative error code in case of | ||
| 2377 | * failure. | ||
| 2378 | */ | ||
| 2379 | int ubifs_debugging_init(struct ubifs_info *c) | ||
| 2380 | { | ||
| 2381 | c->dbg = kzalloc(sizeof(struct ubifs_debug_info), GFP_KERNEL); | ||
| 2382 | if (!c->dbg) | ||
| 2383 | return -ENOMEM; | ||
| 2384 | |||
| 2385 | c->dbg->buf = vmalloc(c->leb_size); | ||
| 2386 | if (!c->dbg->buf) | ||
| 2387 | goto out; | ||
| 2388 | |||
| 2389 | failure_mode_init(c); | ||
| 2390 | return 0; | ||
| 2391 | |||
| 2392 | out: | ||
| 2393 | kfree(c->dbg); | ||
| 2394 | return -ENOMEM; | ||
| 2395 | } | ||
| 2396 | |||
| 2397 | /** | ||
| 2398 | * ubifs_debugging_exit - free debugging data. | ||
| 2399 | * @c: UBIFS file-system description object | ||
| 2400 | */ | ||
| 2401 | void ubifs_debugging_exit(struct ubifs_info *c) | ||
| 2402 | { | ||
| 2403 | failure_mode_exit(c); | ||
| 2404 | vfree(c->dbg->buf); | ||
| 2405 | kfree(c->dbg); | ||
| 2406 | } | ||
| 2407 | |||
| 2408 | /* | ||
| 2409 | * Root directory for UBIFS stuff in debugfs. Contains sub-directories which | ||
| 2410 | * contain the stuff specific to particular file-system mounts. | ||
| 2411 | */ | ||
| 2412 | static struct dentry *debugfs_rootdir; | ||
| 2413 | |||
| 2414 | /** | ||
| 2415 | * dbg_debugfs_init - initialize debugfs file-system. | ||
| 2416 | * | ||
| 2417 | * UBIFS uses debugfs file-system to expose various debugging knobs to | ||
| 2418 | * user-space. This function creates "ubifs" directory in the debugfs | ||
| 2419 | * file-system. Returns zero in case of success and a negative error code in | ||
| 2420 | * case of failure. | ||
| 2421 | */ | ||
| 2422 | int dbg_debugfs_init(void) | ||
| 2423 | { | ||
| 2424 | debugfs_rootdir = debugfs_create_dir("ubifs", NULL); | ||
| 2425 | if (IS_ERR(debugfs_rootdir)) { | ||
| 2426 | int err = PTR_ERR(debugfs_rootdir); | ||
| 2427 | ubifs_err("cannot create \"ubifs\" debugfs directory, " | ||
| 2428 | "error %d\n", err); | ||
| 2429 | return err; | ||
| 2430 | } | ||
| 2431 | |||
| 2432 | return 0; | ||
| 2433 | } | ||
| 2434 | |||
| 2435 | /** | ||
| 2436 | * dbg_debugfs_exit - remove the "ubifs" directory from debugfs file-system. | ||
| 2437 | */ | ||
| 2438 | void dbg_debugfs_exit(void) | ||
| 2439 | { | ||
| 2440 | debugfs_remove(debugfs_rootdir); | ||
| 2441 | } | ||
| 2442 | |||
| 2443 | static int open_debugfs_file(struct inode *inode, struct file *file) | ||
| 2444 | { | ||
| 2445 | file->private_data = inode->i_private; | ||
| 2446 | return 0; | ||
| 2447 | } | ||
| 2448 | |||
| 2449 | static ssize_t write_debugfs_file(struct file *file, const char __user *buf, | ||
| 2450 | size_t count, loff_t *ppos) | ||
| 2451 | { | ||
| 2452 | struct ubifs_info *c = file->private_data; | ||
| 2453 | struct ubifs_debug_info *d = c->dbg; | ||
| 2454 | |||
| 2455 | if (file->f_path.dentry == d->dump_lprops) | ||
| 2456 | dbg_dump_lprops(c); | ||
| 2457 | else if (file->f_path.dentry == d->dump_budg) { | ||
| 2458 | spin_lock(&c->space_lock); | ||
| 2459 | dbg_dump_budg(c); | ||
| 2460 | spin_unlock(&c->space_lock); | ||
| 2461 | } else if (file->f_path.dentry == d->dump_tnc) { | ||
| 2462 | mutex_lock(&c->tnc_mutex); | ||
| 2463 | dbg_dump_tnc(c); | ||
| 2464 | mutex_unlock(&c->tnc_mutex); | ||
| 2465 | } else | ||
| 2466 | return -EINVAL; | ||
| 2467 | |||
| 2468 | *ppos += count; | ||
| 2469 | return count; | ||
| 2470 | } | ||
| 2471 | |||
| 2472 | static const struct file_operations debugfs_fops = { | ||
| 2473 | .open = open_debugfs_file, | ||
| 2474 | .write = write_debugfs_file, | ||
| 2475 | .owner = THIS_MODULE, | ||
| 2476 | }; | ||
| 2477 | |||
| 2478 | /** | ||
| 2479 | * dbg_debugfs_init_fs - initialize debugfs for UBIFS instance. | ||
| 2480 | * @c: UBIFS file-system description object | ||
| 2481 | * | ||
| 2482 | * This function creates all debugfs files for this instance of UBIFS. Returns | ||
| 2483 | * zero in case of success and a negative error code in case of failure. | ||
| 2484 | * | ||
| 2485 | * Note, the only reason we have not merged this function with the | ||
| 2486 | * 'ubifs_debugging_init()' function is because it is better to initialize | ||
| 2487 | * debugfs interfaces at the very end of the mount process, and remove them at | ||
| 2488 | * the very beginning of the mount process. | ||
| 2489 | */ | ||
| 2490 | int dbg_debugfs_init_fs(struct ubifs_info *c) | ||
| 2491 | { | ||
| 2492 | int err; | ||
| 2493 | const char *fname; | ||
| 2494 | struct dentry *dent; | ||
| 2495 | struct ubifs_debug_info *d = c->dbg; | ||
| 2496 | |||
| 2497 | sprintf(d->debugfs_dir_name, "ubi%d_%d", c->vi.ubi_num, c->vi.vol_id); | ||
| 2498 | d->debugfs_dir = debugfs_create_dir(d->debugfs_dir_name, | ||
| 2499 | debugfs_rootdir); | ||
| 2500 | if (IS_ERR(d->debugfs_dir)) { | ||
| 2501 | err = PTR_ERR(d->debugfs_dir); | ||
| 2502 | ubifs_err("cannot create \"%s\" debugfs directory, error %d\n", | ||
| 2503 | d->debugfs_dir_name, err); | ||
| 2504 | goto out; | ||
| 2505 | } | ||
| 2506 | |||
| 2507 | fname = "dump_lprops"; | ||
| 2508 | dent = debugfs_create_file(fname, S_IWUGO, d->debugfs_dir, c, | ||
| 2509 | &debugfs_fops); | ||
| 2510 | if (IS_ERR(dent)) | ||
| 2511 | goto out_remove; | ||
| 2512 | d->dump_lprops = dent; | ||
| 2513 | |||
| 2514 | fname = "dump_budg"; | ||
| 2515 | dent = debugfs_create_file(fname, S_IWUGO, d->debugfs_dir, c, | ||
| 2516 | &debugfs_fops); | ||
| 2517 | if (IS_ERR(dent)) | ||
| 2518 | goto out_remove; | ||
| 2519 | d->dump_budg = dent; | ||
| 2520 | |||
| 2521 | fname = "dump_tnc"; | ||
| 2522 | dent = debugfs_create_file(fname, S_IWUGO, d->debugfs_dir, c, | ||
| 2523 | &debugfs_fops); | ||
| 2524 | if (IS_ERR(dent)) | ||
| 2525 | goto out_remove; | ||
| 2526 | d->dump_tnc = dent; | ||
| 2527 | |||
| 2528 | return 0; | ||
| 2529 | |||
| 2530 | out_remove: | ||
| 2531 | err = PTR_ERR(dent); | ||
| 2532 | ubifs_err("cannot create \"%s\" debugfs directory, error %d\n", | ||
| 2533 | fname, err); | ||
| 2534 | debugfs_remove_recursive(d->debugfs_dir); | ||
| 2535 | out: | ||
| 2536 | return err; | ||
| 2537 | } | ||
| 2538 | |||
| 2539 | /** | ||
| 2540 | * dbg_debugfs_exit_fs - remove all debugfs files. | ||
| 2541 | * @c: UBIFS file-system description object | ||
| 2542 | */ | ||
| 2543 | void dbg_debugfs_exit_fs(struct ubifs_info *c) | ||
| 2544 | { | ||
| 2545 | debugfs_remove_recursive(c->dbg->debugfs_dir); | ||
| 2546 | } | ||
| 2547 | |||
| 2347 | #endif /* CONFIG_UBIFS_FS_DEBUG */ | 2548 | #endif /* CONFIG_UBIFS_FS_DEBUG */ |
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h index 33d6b95071e4..9820d6999f7e 100644 --- a/fs/ubifs/debug.h +++ b/fs/ubifs/debug.h | |||
| @@ -25,7 +25,56 @@ | |||
| 25 | 25 | ||
| 26 | #ifdef CONFIG_UBIFS_FS_DEBUG | 26 | #ifdef CONFIG_UBIFS_FS_DEBUG |
| 27 | 27 | ||
| 28 | #define UBIFS_DBG(op) op | 28 | /** |
| 29 | * ubifs_debug_info - per-FS debugging information. | ||
| 30 | * @buf: a buffer of LEB size, used for various purposes | ||
| 31 | * @old_zroot: old index root - used by 'dbg_check_old_index()' | ||
| 32 | * @old_zroot_level: old index root level - used by 'dbg_check_old_index()' | ||
| 33 | * @old_zroot_sqnum: old index root sqnum - used by 'dbg_check_old_index()' | ||
| 34 | * @failure_mode: failure mode for recovery testing | ||
| 35 | * @fail_delay: 0=>don't delay, 1=>delay a time, 2=>delay a number of calls | ||
| 36 | * @fail_timeout: time in jiffies when delay of failure mode expires | ||
| 37 | * @fail_cnt: current number of calls to failure mode I/O functions | ||
| 38 | * @fail_cnt_max: number of calls by which to delay failure mode | ||
| 39 | * @chk_lpt_sz: used by LPT tree size checker | ||
| 40 | * @chk_lpt_sz2: used by LPT tree size checker | ||
| 41 | * @chk_lpt_wastage: used by LPT tree size checker | ||
| 42 | * @chk_lpt_lebs: used by LPT tree size checker | ||
| 43 | * @new_nhead_offs: used by LPT tree size checker | ||
| 44 | * @new_ihead_lnum: used by debugging to check ihead_lnum | ||
| 45 | * @new_ihead_offs: used by debugging to check ihead_offs | ||
| 46 | * | ||
| 47 | * debugfs_dir_name: name of debugfs directory containing this file-system's | ||
| 48 | * files | ||
| 49 | * debugfs_dir: direntry object of the file-system debugfs directory | ||
| 50 | * dump_lprops: "dump lprops" debugfs knob | ||
| 51 | * dump_budg: "dump budgeting information" debugfs knob | ||
| 52 | * dump_tnc: "dump TNC" debugfs knob | ||
| 53 | */ | ||
| 54 | struct ubifs_debug_info { | ||
| 55 | void *buf; | ||
| 56 | struct ubifs_zbranch old_zroot; | ||
| 57 | int old_zroot_level; | ||
| 58 | unsigned long long old_zroot_sqnum; | ||
| 59 | int failure_mode; | ||
| 60 | int fail_delay; | ||
| 61 | unsigned long fail_timeout; | ||
| 62 | unsigned int fail_cnt; | ||
| 63 | unsigned int fail_cnt_max; | ||
| 64 | long long chk_lpt_sz; | ||
| 65 | long long chk_lpt_sz2; | ||
| 66 | long long chk_lpt_wastage; | ||
| 67 | int chk_lpt_lebs; | ||
| 68 | int new_nhead_offs; | ||
| 69 | int new_ihead_lnum; | ||
| 70 | int new_ihead_offs; | ||
| 71 | |||
| 72 | char debugfs_dir_name[100]; | ||
| 73 | struct dentry *debugfs_dir; | ||
| 74 | struct dentry *dump_lprops; | ||
| 75 | struct dentry *dump_budg; | ||
| 76 | struct dentry *dump_tnc; | ||
| 77 | }; | ||
| 29 | 78 | ||
| 30 | #define ubifs_assert(expr) do { \ | 79 | #define ubifs_assert(expr) do { \ |
| 31 | if (unlikely(!(expr))) { \ | 80 | if (unlikely(!(expr))) { \ |
| @@ -211,14 +260,18 @@ extern unsigned int ubifs_msg_flags; | |||
| 211 | extern unsigned int ubifs_chk_flags; | 260 | extern unsigned int ubifs_chk_flags; |
| 212 | extern unsigned int ubifs_tst_flags; | 261 | extern unsigned int ubifs_tst_flags; |
| 213 | 262 | ||
| 214 | /* Dump functions */ | 263 | int ubifs_debugging_init(struct ubifs_info *c); |
| 264 | void ubifs_debugging_exit(struct ubifs_info *c); | ||
| 215 | 265 | ||
| 266 | /* Dump functions */ | ||
| 216 | const char *dbg_ntype(int type); | 267 | const char *dbg_ntype(int type); |
| 217 | const char *dbg_cstate(int cmt_state); | 268 | const char *dbg_cstate(int cmt_state); |
| 218 | const char *dbg_get_key_dump(const struct ubifs_info *c, | 269 | const char *dbg_get_key_dump(const struct ubifs_info *c, |
| 219 | const union ubifs_key *key); | 270 | const union ubifs_key *key); |
| 220 | void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode); | 271 | void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode); |
| 221 | void dbg_dump_node(const struct ubifs_info *c, const void *node); | 272 | void dbg_dump_node(const struct ubifs_info *c, const void *node); |
| 273 | void dbg_dump_lpt_node(const struct ubifs_info *c, void *node, int lnum, | ||
| 274 | int offs); | ||
| 222 | void dbg_dump_budget_req(const struct ubifs_budget_req *req); | 275 | void dbg_dump_budget_req(const struct ubifs_budget_req *req); |
| 223 | void dbg_dump_lstats(const struct ubifs_lp_stats *lst); | 276 | void dbg_dump_lstats(const struct ubifs_lp_stats *lst); |
| 224 | void dbg_dump_budg(struct ubifs_info *c); | 277 | void dbg_dump_budg(struct ubifs_info *c); |
| @@ -233,9 +286,9 @@ void dbg_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, | |||
| 233 | struct ubifs_nnode *parent, int iip); | 286 | struct ubifs_nnode *parent, int iip); |
| 234 | void dbg_dump_tnc(struct ubifs_info *c); | 287 | void dbg_dump_tnc(struct ubifs_info *c); |
| 235 | void dbg_dump_index(struct ubifs_info *c); | 288 | void dbg_dump_index(struct ubifs_info *c); |
| 289 | void dbg_dump_lpt_lebs(const struct ubifs_info *c); | ||
| 236 | 290 | ||
| 237 | /* Checking helper functions */ | 291 | /* Checking helper functions */ |
| 238 | |||
| 239 | typedef int (*dbg_leaf_callback)(struct ubifs_info *c, | 292 | typedef int (*dbg_leaf_callback)(struct ubifs_info *c, |
| 240 | struct ubifs_zbranch *zbr, void *priv); | 293 | struct ubifs_zbranch *zbr, void *priv); |
| 241 | typedef int (*dbg_znode_callback)(struct ubifs_info *c, | 294 | typedef int (*dbg_znode_callback)(struct ubifs_info *c, |
| @@ -274,9 +327,6 @@ int dbg_force_in_the_gaps(void); | |||
| 274 | 327 | ||
| 275 | #define dbg_failure_mode (ubifs_tst_flags & UBIFS_TST_RCVRY) | 328 | #define dbg_failure_mode (ubifs_tst_flags & UBIFS_TST_RCVRY) |
| 276 | 329 | ||
| 277 | void dbg_failure_mode_registration(struct ubifs_info *c); | ||
| 278 | void dbg_failure_mode_deregistration(struct ubifs_info *c); | ||
| 279 | |||
| 280 | #ifndef UBIFS_DBG_PRESERVE_UBI | 330 | #ifndef UBIFS_DBG_PRESERVE_UBI |
| 281 | 331 | ||
| 282 | #define ubi_leb_read dbg_leb_read | 332 | #define ubi_leb_read dbg_leb_read |
| @@ -318,9 +368,13 @@ static inline int dbg_change(struct ubi_volume_desc *desc, int lnum, | |||
| 318 | return dbg_leb_change(desc, lnum, buf, len, UBI_UNKNOWN); | 368 | return dbg_leb_change(desc, lnum, buf, len, UBI_UNKNOWN); |
| 319 | } | 369 | } |
| 320 | 370 | ||
| 321 | #else /* !CONFIG_UBIFS_FS_DEBUG */ | 371 | /* Debugfs-related stuff */ |
| 372 | int dbg_debugfs_init(void); | ||
| 373 | void dbg_debugfs_exit(void); | ||
| 374 | int dbg_debugfs_init_fs(struct ubifs_info *c); | ||
| 375 | void dbg_debugfs_exit_fs(struct ubifs_info *c); | ||
| 322 | 376 | ||
| 323 | #define UBIFS_DBG(op) | 377 | #else /* !CONFIG_UBIFS_FS_DEBUG */ |
| 324 | 378 | ||
| 325 | /* Use "if (0)" to make compiler check arguments even if debugging is off */ | 379 | /* Use "if (0)" to make compiler check arguments even if debugging is off */ |
| 326 | #define ubifs_assert(expr) do { \ | 380 | #define ubifs_assert(expr) do { \ |
| @@ -360,23 +414,28 @@ static inline int dbg_change(struct ubi_volume_desc *desc, int lnum, | |||
| 360 | #define DBGKEY(key) ((char *)(key)) | 414 | #define DBGKEY(key) ((char *)(key)) |
| 361 | #define DBGKEY1(key) ((char *)(key)) | 415 | #define DBGKEY1(key) ((char *)(key)) |
| 362 | 416 | ||
| 363 | #define dbg_ntype(type) "" | 417 | #define ubifs_debugging_init(c) 0 |
| 364 | #define dbg_cstate(cmt_state) "" | 418 | #define ubifs_debugging_exit(c) ({}) |
| 365 | #define dbg_get_key_dump(c, key) ({}) | 419 | |
| 366 | #define dbg_dump_inode(c, inode) ({}) | 420 | #define dbg_ntype(type) "" |
| 367 | #define dbg_dump_node(c, node) ({}) | 421 | #define dbg_cstate(cmt_state) "" |
| 368 | #define dbg_dump_budget_req(req) ({}) | 422 | #define dbg_get_key_dump(c, key) ({}) |
| 369 | #define dbg_dump_lstats(lst) ({}) | 423 | #define dbg_dump_inode(c, inode) ({}) |
| 370 | #define dbg_dump_budg(c) ({}) | 424 | #define dbg_dump_node(c, node) ({}) |
| 371 | #define dbg_dump_lprop(c, lp) ({}) | 425 | #define dbg_dump_lpt_node(c, node, lnum, offs) ({}) |
| 372 | #define dbg_dump_lprops(c) ({}) | 426 | #define dbg_dump_budget_req(req) ({}) |
| 373 | #define dbg_dump_lpt_info(c) ({}) | 427 | #define dbg_dump_lstats(lst) ({}) |
| 374 | #define dbg_dump_leb(c, lnum) ({}) | 428 | #define dbg_dump_budg(c) ({}) |
| 375 | #define dbg_dump_znode(c, znode) ({}) | 429 | #define dbg_dump_lprop(c, lp) ({}) |
| 376 | #define dbg_dump_heap(c, heap, cat) ({}) | 430 | #define dbg_dump_lprops(c) ({}) |
| 377 | #define dbg_dump_pnode(c, pnode, parent, iip) ({}) | 431 | #define dbg_dump_lpt_info(c) ({}) |
| 378 | #define dbg_dump_tnc(c) ({}) | 432 | #define dbg_dump_leb(c, lnum) ({}) |
| 379 | #define dbg_dump_index(c) ({}) | 433 | #define dbg_dump_znode(c, znode) ({}) |
| 434 | #define dbg_dump_heap(c, heap, cat) ({}) | ||
| 435 | #define dbg_dump_pnode(c, pnode, parent, iip) ({}) | ||
| 436 | #define dbg_dump_tnc(c) ({}) | ||
| 437 | #define dbg_dump_index(c) ({}) | ||
| 438 | #define dbg_dump_lpt_lebs(c) ({}) | ||
| 380 | 439 | ||
| 381 | #define dbg_walk_index(c, leaf_cb, znode_cb, priv) 0 | 440 | #define dbg_walk_index(c, leaf_cb, znode_cb, priv) 0 |
| 382 | #define dbg_old_index_check_init(c, zroot) 0 | 441 | #define dbg_old_index_check_init(c, zroot) 0 |
| @@ -396,9 +455,11 @@ static inline int dbg_change(struct ubi_volume_desc *desc, int lnum, | |||
| 396 | #define dbg_force_in_the_gaps_enabled 0 | 455 | #define dbg_force_in_the_gaps_enabled 0 |
| 397 | #define dbg_force_in_the_gaps() 0 | 456 | #define dbg_force_in_the_gaps() 0 |
| 398 | #define dbg_failure_mode 0 | 457 | #define dbg_failure_mode 0 |
| 399 | #define dbg_failure_mode_registration(c) ({}) | ||
| 400 | #define dbg_failure_mode_deregistration(c) ({}) | ||
| 401 | 458 | ||
| 402 | #endif /* !CONFIG_UBIFS_FS_DEBUG */ | 459 | #define dbg_debugfs_init() 0 |
| 460 | #define dbg_debugfs_exit() | ||
| 461 | #define dbg_debugfs_init_fs(c) 0 | ||
| 462 | #define dbg_debugfs_exit_fs(c) 0 | ||
| 403 | 463 | ||
| 464 | #endif /* !CONFIG_UBIFS_FS_DEBUG */ | ||
| 404 | #endif /* !__UBIFS_DEBUG_H__ */ | 465 | #endif /* !__UBIFS_DEBUG_H__ */ |
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 2624411d9758..fe82d2464d46 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c | |||
| @@ -72,8 +72,8 @@ static int read_block(struct inode *inode, void *addr, unsigned int block, | |||
| 72 | return err; | 72 | return err; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | ubifs_assert(le64_to_cpu(dn->ch.sqnum) > ubifs_inode(inode)->creat_sqnum); | 75 | ubifs_assert(le64_to_cpu(dn->ch.sqnum) > |
| 76 | 76 | ubifs_inode(inode)->creat_sqnum); | |
| 77 | len = le32_to_cpu(dn->size); | 77 | len = le32_to_cpu(dn->size); |
| 78 | if (len <= 0 || len > UBIFS_BLOCK_SIZE) | 78 | if (len <= 0 || len > UBIFS_BLOCK_SIZE) |
| 79 | goto dump; | 79 | goto dump; |
| @@ -254,7 +254,7 @@ static int write_begin_slow(struct address_space *mapping, | |||
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | if (!PageUptodate(page)) { | 256 | if (!PageUptodate(page)) { |
| 257 | if (!(pos & PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE) | 257 | if (!(pos & ~PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE) |
| 258 | SetPageChecked(page); | 258 | SetPageChecked(page); |
| 259 | else { | 259 | else { |
| 260 | err = do_readpage(page); | 260 | err = do_readpage(page); |
| @@ -444,7 +444,7 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, | |||
| 444 | 444 | ||
| 445 | if (!PageUptodate(page)) { | 445 | if (!PageUptodate(page)) { |
| 446 | /* The page is not loaded from the flash */ | 446 | /* The page is not loaded from the flash */ |
| 447 | if (!(pos & PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE) | 447 | if (!(pos & ~PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE) |
| 448 | /* | 448 | /* |
| 449 | * We change whole page so no need to load it. But we | 449 | * We change whole page so no need to load it. But we |
| 450 | * have to set the @PG_checked flag to make the further | 450 | * have to set the @PG_checked flag to make the further |
diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c index 5e82cffe9695..6db7a6be6c97 100644 --- a/fs/ubifs/ioctl.c +++ b/fs/ubifs/ioctl.c | |||
| @@ -154,6 +154,7 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 154 | case FS_IOC_GETFLAGS: | 154 | case FS_IOC_GETFLAGS: |
| 155 | flags = ubifs2ioctl(ubifs_inode(inode)->flags); | 155 | flags = ubifs2ioctl(ubifs_inode(inode)->flags); |
| 156 | 156 | ||
| 157 | dbg_gen("get flags: %#x, i_flags %#x", flags, inode->i_flags); | ||
| 157 | return put_user(flags, (int __user *) arg); | 158 | return put_user(flags, (int __user *) arg); |
| 158 | 159 | ||
| 159 | case FS_IOC_SETFLAGS: { | 160 | case FS_IOC_SETFLAGS: { |
| @@ -176,6 +177,7 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 176 | err = mnt_want_write(file->f_path.mnt); | 177 | err = mnt_want_write(file->f_path.mnt); |
| 177 | if (err) | 178 | if (err) |
| 178 | return err; | 179 | return err; |
| 180 | dbg_gen("set flags: %#x, i_flags %#x", flags, inode->i_flags); | ||
| 179 | err = setflags(inode, flags); | 181 | err = setflags(inode, flags); |
| 180 | mnt_drop_write(file->f_path.mnt); | 182 | mnt_drop_write(file->f_path.mnt); |
| 181 | return err; | 183 | return err; |
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index f91b745908ea..10ae25b7d1db 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c | |||
| @@ -704,7 +704,7 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode, | |||
| 704 | data->size = cpu_to_le32(len); | 704 | data->size = cpu_to_le32(len); |
| 705 | zero_data_node_unused(data); | 705 | zero_data_node_unused(data); |
| 706 | 706 | ||
| 707 | if (!(ui->flags && UBIFS_COMPR_FL)) | 707 | if (!(ui->flags & UBIFS_COMPR_FL)) |
| 708 | /* Compression is disabled for this inode */ | 708 | /* Compression is disabled for this inode */ |
| 709 | compr_type = UBIFS_COMPR_NONE; | 709 | compr_type = UBIFS_COMPR_NONE; |
| 710 | else | 710 | else |
| @@ -1220,7 +1220,7 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode, | |||
| 1220 | data_key_init(c, &key, inum, blk); | 1220 | data_key_init(c, &key, inum, blk); |
| 1221 | 1221 | ||
| 1222 | bit = old_size & (UBIFS_BLOCK_SIZE - 1); | 1222 | bit = old_size & (UBIFS_BLOCK_SIZE - 1); |
| 1223 | blk = (old_size >> UBIFS_BLOCK_SHIFT) - (bit ? 0: 1); | 1223 | blk = (old_size >> UBIFS_BLOCK_SHIFT) - (bit ? 0 : 1); |
| 1224 | data_key_init(c, &to_key, inum, blk); | 1224 | data_key_init(c, &to_key, inum, blk); |
| 1225 | 1225 | ||
| 1226 | err = ubifs_tnc_remove_range(c, &key, &to_key); | 1226 | err = ubifs_tnc_remove_range(c, &key, &to_key); |
diff --git a/fs/ubifs/key.h b/fs/ubifs/key.h index 3f1f16bc25c9..efb3430a2581 100644 --- a/fs/ubifs/key.h +++ b/fs/ubifs/key.h | |||
| @@ -38,6 +38,22 @@ | |||
| 38 | #define __UBIFS_KEY_H__ | 38 | #define __UBIFS_KEY_H__ |
| 39 | 39 | ||
| 40 | /** | 40 | /** |
| 41 | * key_mask_hash - mask a valid hash value. | ||
| 42 | * @val: value to be masked | ||
| 43 | * | ||
| 44 | * We use hash values as offset in directories, so values %0 and %1 are | ||
| 45 | * reserved for "." and "..". %2 is reserved for "end of readdir" marker. This | ||
| 46 | * function makes sure the reserved values are not used. | ||
| 47 | */ | ||
| 48 | static inline uint32_t key_mask_hash(uint32_t hash) | ||
| 49 | { | ||
| 50 | hash &= UBIFS_S_KEY_HASH_MASK; | ||
| 51 | if (unlikely(hash <= 2)) | ||
| 52 | hash += 3; | ||
| 53 | return hash; | ||
| 54 | } | ||
| 55 | |||
| 56 | /** | ||
| 41 | * key_r5_hash - R5 hash function (borrowed from reiserfs). | 57 | * key_r5_hash - R5 hash function (borrowed from reiserfs). |
| 42 | * @s: direntry name | 58 | * @s: direntry name |
| 43 | * @len: name length | 59 | * @len: name length |
| @@ -54,16 +70,7 @@ static inline uint32_t key_r5_hash(const char *s, int len) | |||
| 54 | str++; | 70 | str++; |
| 55 | } | 71 | } |
| 56 | 72 | ||
| 57 | a &= UBIFS_S_KEY_HASH_MASK; | 73 | return key_mask_hash(a); |
| 58 | |||
| 59 | /* | ||
| 60 | * We use hash values as offset in directories, so values %0 and %1 are | ||
| 61 | * reserved for "." and "..". %2 is reserved for "end of readdir" | ||
| 62 | * marker. | ||
| 63 | */ | ||
| 64 | if (unlikely(a >= 0 && a <= 2)) | ||
| 65 | a += 3; | ||
| 66 | return a; | ||
| 67 | } | 74 | } |
| 68 | 75 | ||
| 69 | /** | 76 | /** |
| @@ -77,10 +84,7 @@ static inline uint32_t key_test_hash(const char *str, int len) | |||
| 77 | 84 | ||
| 78 | len = min_t(uint32_t, len, 4); | 85 | len = min_t(uint32_t, len, 4); |
| 79 | memcpy(&a, str, len); | 86 | memcpy(&a, str, len); |
| 80 | a &= UBIFS_S_KEY_HASH_MASK; | 87 | return key_mask_hash(a); |
| 81 | if (unlikely(a >= 0 && a <= 2)) | ||
| 82 | a += 3; | ||
| 83 | return a; | ||
| 84 | } | 88 | } |
| 85 | 89 | ||
| 86 | /** | 90 | /** |
diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c index f27176e9b70d..dfd2bcece27a 100644 --- a/fs/ubifs/lprops.c +++ b/fs/ubifs/lprops.c | |||
| @@ -520,13 +520,13 @@ static int is_lprops_dirty(struct ubifs_info *c, struct ubifs_lprops *lprops) | |||
| 520 | * @flags: new flags | 520 | * @flags: new flags |
| 521 | * @idx_gc_cnt: change to the count of idx_gc list | 521 | * @idx_gc_cnt: change to the count of idx_gc list |
| 522 | * | 522 | * |
| 523 | * This function changes LEB properties. This function does not change a LEB | 523 | * This function changes LEB properties (@free, @dirty or @flag). However, the |
| 524 | * property (@free, @dirty or @flag) if the value passed is %LPROPS_NC. | 524 | * property which has the %LPROPS_NC value is not changed. Returns a pointer to |
| 525 | * the updated LEB properties on success and a negative error code on failure. | ||
| 525 | * | 526 | * |
| 526 | * This function returns a pointer to the updated LEB properties on success | 527 | * Note, the LEB properties may have had to be copied (due to COW) and |
| 527 | * and a negative error code on failure. N.B. the LEB properties may have had to | 528 | * consequently the pointer returned may not be the same as the pointer |
| 528 | * be copied (due to COW) and consequently the pointer returned may not be the | 529 | * passed. |
| 529 | * same as the pointer passed. | ||
| 530 | */ | 530 | */ |
| 531 | const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c, | 531 | const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c, |
| 532 | const struct ubifs_lprops *lp, | 532 | const struct ubifs_lprops *lp, |
| @@ -1088,7 +1088,7 @@ static int scan_check_cb(struct ubifs_info *c, | |||
| 1088 | } | 1088 | } |
| 1089 | } | 1089 | } |
| 1090 | 1090 | ||
| 1091 | sleb = ubifs_scan(c, lnum, 0, c->dbg_buf); | 1091 | sleb = ubifs_scan(c, lnum, 0, c->dbg->buf); |
| 1092 | if (IS_ERR(sleb)) { | 1092 | if (IS_ERR(sleb)) { |
| 1093 | /* | 1093 | /* |
| 1094 | * After an unclean unmount, empty and freeable LEBs | 1094 | * After an unclean unmount, empty and freeable LEBs |
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c index db8bd0e518b2..b2792e84d245 100644 --- a/fs/ubifs/lpt.c +++ b/fs/ubifs/lpt.c | |||
| @@ -36,15 +36,16 @@ | |||
| 36 | * can be written into a single eraseblock. In that case, garbage collection | 36 | * can be written into a single eraseblock. In that case, garbage collection |
| 37 | * consists of just writing the whole table, which therefore makes all other | 37 | * consists of just writing the whole table, which therefore makes all other |
| 38 | * eraseblocks reusable. In the case of the big model, dirty eraseblocks are | 38 | * eraseblocks reusable. In the case of the big model, dirty eraseblocks are |
| 39 | * selected for garbage collection, which consists are marking the nodes in | 39 | * selected for garbage collection, which consists of marking the clean nodes in |
| 40 | * that LEB as dirty, and then only the dirty nodes are written out. Also, in | 40 | * that LEB as dirty, and then only the dirty nodes are written out. Also, in |
| 41 | * the case of the big model, a table of LEB numbers is saved so that the entire | 41 | * the case of the big model, a table of LEB numbers is saved so that the entire |
| 42 | * LPT does not to be scanned looking for empty eraseblocks when UBIFS is first | 42 | * LPT does not to be scanned looking for empty eraseblocks when UBIFS is first |
| 43 | * mounted. | 43 | * mounted. |
| 44 | */ | 44 | */ |
| 45 | 45 | ||
| 46 | #include <linux/crc16.h> | ||
| 47 | #include "ubifs.h" | 46 | #include "ubifs.h" |
| 47 | #include <linux/crc16.h> | ||
| 48 | #include <linux/math64.h> | ||
| 48 | 49 | ||
| 49 | /** | 50 | /** |
| 50 | * do_calc_lpt_geom - calculate sizes for the LPT area. | 51 | * do_calc_lpt_geom - calculate sizes for the LPT area. |
| @@ -135,15 +136,13 @@ static void do_calc_lpt_geom(struct ubifs_info *c) | |||
| 135 | int ubifs_calc_lpt_geom(struct ubifs_info *c) | 136 | int ubifs_calc_lpt_geom(struct ubifs_info *c) |
| 136 | { | 137 | { |
| 137 | int lebs_needed; | 138 | int lebs_needed; |
| 138 | uint64_t sz; | 139 | long long sz; |
| 139 | 140 | ||
| 140 | do_calc_lpt_geom(c); | 141 | do_calc_lpt_geom(c); |
| 141 | 142 | ||
| 142 | /* Verify that lpt_lebs is big enough */ | 143 | /* Verify that lpt_lebs is big enough */ |
| 143 | sz = c->lpt_sz * 2; /* Must have at least 2 times the size */ | 144 | sz = c->lpt_sz * 2; /* Must have at least 2 times the size */ |
| 144 | sz += c->leb_size - 1; | 145 | lebs_needed = div_u64(sz + c->leb_size - 1, c->leb_size); |
| 145 | do_div(sz, c->leb_size); | ||
| 146 | lebs_needed = sz; | ||
| 147 | if (lebs_needed > c->lpt_lebs) { | 146 | if (lebs_needed > c->lpt_lebs) { |
| 148 | ubifs_err("too few LPT LEBs"); | 147 | ubifs_err("too few LPT LEBs"); |
| 149 | return -EINVAL; | 148 | return -EINVAL; |
| @@ -156,7 +155,6 @@ int ubifs_calc_lpt_geom(struct ubifs_info *c) | |||
| 156 | } | 155 | } |
| 157 | 156 | ||
| 158 | c->check_lpt_free = c->big_lpt; | 157 | c->check_lpt_free = c->big_lpt; |
| 159 | |||
| 160 | return 0; | 158 | return 0; |
| 161 | } | 159 | } |
| 162 | 160 | ||
| @@ -176,7 +174,7 @@ static int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs, | |||
| 176 | int *big_lpt) | 174 | int *big_lpt) |
| 177 | { | 175 | { |
| 178 | int i, lebs_needed; | 176 | int i, lebs_needed; |
| 179 | uint64_t sz; | 177 | long long sz; |
| 180 | 178 | ||
| 181 | /* Start by assuming the minimum number of LPT LEBs */ | 179 | /* Start by assuming the minimum number of LPT LEBs */ |
| 182 | c->lpt_lebs = UBIFS_MIN_LPT_LEBS; | 180 | c->lpt_lebs = UBIFS_MIN_LPT_LEBS; |
| @@ -203,9 +201,7 @@ static int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs, | |||
| 203 | /* Now check there are enough LPT LEBs */ | 201 | /* Now check there are enough LPT LEBs */ |
| 204 | for (i = 0; i < 64 ; i++) { | 202 | for (i = 0; i < 64 ; i++) { |
| 205 | sz = c->lpt_sz * 4; /* Allow 4 times the size */ | 203 | sz = c->lpt_sz * 4; /* Allow 4 times the size */ |
| 206 | sz += c->leb_size - 1; | 204 | lebs_needed = div_u64(sz + c->leb_size - 1, c->leb_size); |
| 207 | do_div(sz, c->leb_size); | ||
| 208 | lebs_needed = sz; | ||
| 209 | if (lebs_needed > c->lpt_lebs) { | 205 | if (lebs_needed > c->lpt_lebs) { |
| 210 | /* Not enough LPT LEBs so try again with more */ | 206 | /* Not enough LPT LEBs so try again with more */ |
| 211 | c->lpt_lebs = lebs_needed; | 207 | c->lpt_lebs = lebs_needed; |
| @@ -558,7 +554,7 @@ static int calc_nnode_num(int row, int col) | |||
| 558 | * This function calculates and returns the nnode number based on the parent's | 554 | * This function calculates and returns the nnode number based on the parent's |
| 559 | * nnode number and the index in parent. | 555 | * nnode number and the index in parent. |
| 560 | */ | 556 | */ |
| 561 | static int calc_nnode_num_from_parent(struct ubifs_info *c, | 557 | static int calc_nnode_num_from_parent(const struct ubifs_info *c, |
| 562 | struct ubifs_nnode *parent, int iip) | 558 | struct ubifs_nnode *parent, int iip) |
| 563 | { | 559 | { |
| 564 | int num, shft; | 560 | int num, shft; |
| @@ -583,7 +579,7 @@ static int calc_nnode_num_from_parent(struct ubifs_info *c, | |||
| 583 | * This function calculates and returns the pnode number based on the parent's | 579 | * This function calculates and returns the pnode number based on the parent's |
| 584 | * nnode number and the index in parent. | 580 | * nnode number and the index in parent. |
| 585 | */ | 581 | */ |
| 586 | static int calc_pnode_num_from_parent(struct ubifs_info *c, | 582 | static int calc_pnode_num_from_parent(const struct ubifs_info *c, |
| 587 | struct ubifs_nnode *parent, int iip) | 583 | struct ubifs_nnode *parent, int iip) |
| 588 | { | 584 | { |
| 589 | int i, n = c->lpt_hght - 1, pnum = parent->num, num = 0; | 585 | int i, n = c->lpt_hght - 1, pnum = parent->num, num = 0; |
| @@ -966,7 +962,7 @@ static int check_lpt_type(uint8_t **addr, int *pos, int type) | |||
| 966 | * | 962 | * |
| 967 | * This function returns %0 on success and a negative error code on failure. | 963 | * This function returns %0 on success and a negative error code on failure. |
| 968 | */ | 964 | */ |
| 969 | static int unpack_pnode(struct ubifs_info *c, void *buf, | 965 | static int unpack_pnode(const struct ubifs_info *c, void *buf, |
| 970 | struct ubifs_pnode *pnode) | 966 | struct ubifs_pnode *pnode) |
| 971 | { | 967 | { |
| 972 | uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; | 968 | uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; |
| @@ -996,15 +992,15 @@ static int unpack_pnode(struct ubifs_info *c, void *buf, | |||
| 996 | } | 992 | } |
| 997 | 993 | ||
| 998 | /** | 994 | /** |
| 999 | * unpack_nnode - unpack a nnode. | 995 | * ubifs_unpack_nnode - unpack a nnode. |
| 1000 | * @c: UBIFS file-system description object | 996 | * @c: UBIFS file-system description object |
| 1001 | * @buf: buffer containing packed nnode to unpack | 997 | * @buf: buffer containing packed nnode to unpack |
| 1002 | * @nnode: nnode structure to fill | 998 | * @nnode: nnode structure to fill |
| 1003 | * | 999 | * |
| 1004 | * This function returns %0 on success and a negative error code on failure. | 1000 | * This function returns %0 on success and a negative error code on failure. |
| 1005 | */ | 1001 | */ |
| 1006 | static int unpack_nnode(struct ubifs_info *c, void *buf, | 1002 | int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf, |
| 1007 | struct ubifs_nnode *nnode) | 1003 | struct ubifs_nnode *nnode) |
| 1008 | { | 1004 | { |
| 1009 | uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; | 1005 | uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; |
| 1010 | int i, pos = 0, err; | 1006 | int i, pos = 0, err; |
| @@ -1036,7 +1032,7 @@ static int unpack_nnode(struct ubifs_info *c, void *buf, | |||
| 1036 | * | 1032 | * |
| 1037 | * This function returns %0 on success and a negative error code on failure. | 1033 | * This function returns %0 on success and a negative error code on failure. |
| 1038 | */ | 1034 | */ |
| 1039 | static int unpack_ltab(struct ubifs_info *c, void *buf) | 1035 | static int unpack_ltab(const struct ubifs_info *c, void *buf) |
| 1040 | { | 1036 | { |
| 1041 | uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; | 1037 | uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; |
| 1042 | int i, pos = 0, err; | 1038 | int i, pos = 0, err; |
| @@ -1068,7 +1064,7 @@ static int unpack_ltab(struct ubifs_info *c, void *buf) | |||
| 1068 | * | 1064 | * |
| 1069 | * This function returns %0 on success and a negative error code on failure. | 1065 | * This function returns %0 on success and a negative error code on failure. |
| 1070 | */ | 1066 | */ |
| 1071 | static int unpack_lsave(struct ubifs_info *c, void *buf) | 1067 | static int unpack_lsave(const struct ubifs_info *c, void *buf) |
| 1072 | { | 1068 | { |
| 1073 | uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; | 1069 | uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; |
| 1074 | int i, pos = 0, err; | 1070 | int i, pos = 0, err; |
| @@ -1096,7 +1092,7 @@ static int unpack_lsave(struct ubifs_info *c, void *buf) | |||
| 1096 | * | 1092 | * |
| 1097 | * This function returns %0 on success and a negative error code on failure. | 1093 | * This function returns %0 on success and a negative error code on failure. |
| 1098 | */ | 1094 | */ |
| 1099 | static int validate_nnode(struct ubifs_info *c, struct ubifs_nnode *nnode, | 1095 | static int validate_nnode(const struct ubifs_info *c, struct ubifs_nnode *nnode, |
| 1100 | struct ubifs_nnode *parent, int iip) | 1096 | struct ubifs_nnode *parent, int iip) |
| 1101 | { | 1097 | { |
| 1102 | int i, lvl, max_offs; | 1098 | int i, lvl, max_offs; |
| @@ -1140,7 +1136,7 @@ static int validate_nnode(struct ubifs_info *c, struct ubifs_nnode *nnode, | |||
| 1140 | * | 1136 | * |
| 1141 | * This function returns %0 on success and a negative error code on failure. | 1137 | * This function returns %0 on success and a negative error code on failure. |
| 1142 | */ | 1138 | */ |
| 1143 | static int validate_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, | 1139 | static int validate_pnode(const struct ubifs_info *c, struct ubifs_pnode *pnode, |
| 1144 | struct ubifs_nnode *parent, int iip) | 1140 | struct ubifs_nnode *parent, int iip) |
| 1145 | { | 1141 | { |
| 1146 | int i; | 1142 | int i; |
| @@ -1174,7 +1170,8 @@ static int validate_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, | |||
| 1174 | * This function calculates the LEB numbers for the LEB properties it contains | 1170 | * This function calculates the LEB numbers for the LEB properties it contains |
| 1175 | * based on the pnode number. | 1171 | * based on the pnode number. |
| 1176 | */ | 1172 | */ |
| 1177 | static void set_pnode_lnum(struct ubifs_info *c, struct ubifs_pnode *pnode) | 1173 | static void set_pnode_lnum(const struct ubifs_info *c, |
| 1174 | struct ubifs_pnode *pnode) | ||
| 1178 | { | 1175 | { |
| 1179 | int i, lnum; | 1176 | int i, lnum; |
| 1180 | 1177 | ||
| @@ -1227,7 +1224,7 @@ int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip) | |||
| 1227 | err = ubi_read(c->ubi, lnum, buf, offs, c->nnode_sz); | 1224 | err = ubi_read(c->ubi, lnum, buf, offs, c->nnode_sz); |
| 1228 | if (err) | 1225 | if (err) |
| 1229 | goto out; | 1226 | goto out; |
| 1230 | err = unpack_nnode(c, buf, nnode); | 1227 | err = ubifs_unpack_nnode(c, buf, nnode); |
| 1231 | if (err) | 1228 | if (err) |
| 1232 | goto out; | 1229 | goto out; |
| 1233 | } | 1230 | } |
| @@ -1816,7 +1813,7 @@ static struct ubifs_nnode *scan_get_nnode(struct ubifs_info *c, | |||
| 1816 | c->nnode_sz); | 1813 | c->nnode_sz); |
| 1817 | if (err) | 1814 | if (err) |
| 1818 | return ERR_PTR(err); | 1815 | return ERR_PTR(err); |
| 1819 | err = unpack_nnode(c, buf, nnode); | 1816 | err = ubifs_unpack_nnode(c, buf, nnode); |
| 1820 | if (err) | 1817 | if (err) |
| 1821 | return ERR_PTR(err); | 1818 | return ERR_PTR(err); |
| 1822 | } | 1819 | } |
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c index a41434b42785..96ca95707175 100644 --- a/fs/ubifs/lpt_commit.c +++ b/fs/ubifs/lpt_commit.c | |||
| @@ -320,6 +320,8 @@ no_space: | |||
| 320 | dbg_err("LPT out of space at LEB %d:%d needing %d, done_ltab %d, " | 320 | dbg_err("LPT out of space at LEB %d:%d needing %d, done_ltab %d, " |
| 321 | "done_lsave %d", lnum, offs, len, done_ltab, done_lsave); | 321 | "done_lsave %d", lnum, offs, len, done_ltab, done_lsave); |
| 322 | dbg_dump_lpt_info(c); | 322 | dbg_dump_lpt_info(c); |
| 323 | dbg_dump_lpt_lebs(c); | ||
| 324 | dump_stack(); | ||
| 323 | return err; | 325 | return err; |
| 324 | } | 326 | } |
| 325 | 327 | ||
| @@ -546,8 +548,10 @@ static int write_cnodes(struct ubifs_info *c) | |||
| 546 | no_space: | 548 | no_space: |
| 547 | ubifs_err("LPT out of space mismatch"); | 549 | ubifs_err("LPT out of space mismatch"); |
| 548 | dbg_err("LPT out of space mismatch at LEB %d:%d needing %d, done_ltab " | 550 | dbg_err("LPT out of space mismatch at LEB %d:%d needing %d, done_ltab " |
| 549 | "%d, done_lsave %d", lnum, offs, len, done_ltab, done_lsave); | 551 | "%d, done_lsave %d", lnum, offs, len, done_ltab, done_lsave); |
| 550 | dbg_dump_lpt_info(c); | 552 | dbg_dump_lpt_info(c); |
| 553 | dbg_dump_lpt_lebs(c); | ||
| 554 | dump_stack(); | ||
| 551 | return err; | 555 | return err; |
| 552 | } | 556 | } |
| 553 | 557 | ||
| @@ -749,7 +753,7 @@ static void lpt_tgc_start(struct ubifs_info *c) | |||
| 749 | * LPT trivial garbage collection is where a LPT LEB contains only dirty and | 753 | * LPT trivial garbage collection is where a LPT LEB contains only dirty and |
| 750 | * free space and so may be reused as soon as the next commit is completed. | 754 | * free space and so may be reused as soon as the next commit is completed. |
| 751 | * This function is called after the commit is completed (master node has been | 755 | * This function is called after the commit is completed (master node has been |
| 752 | * written) and unmaps LPT LEBs that were marked for trivial GC. | 756 | * written) and un-maps LPT LEBs that were marked for trivial GC. |
| 753 | */ | 757 | */ |
| 754 | static int lpt_tgc_end(struct ubifs_info *c) | 758 | static int lpt_tgc_end(struct ubifs_info *c) |
| 755 | { | 759 | { |
| @@ -1025,7 +1029,7 @@ static int make_node_dirty(struct ubifs_info *c, int node_type, int node_num, | |||
| 1025 | * @c: UBIFS file-system description object | 1029 | * @c: UBIFS file-system description object |
| 1026 | * @node_type: LPT node type | 1030 | * @node_type: LPT node type |
| 1027 | */ | 1031 | */ |
| 1028 | static int get_lpt_node_len(struct ubifs_info *c, int node_type) | 1032 | static int get_lpt_node_len(const struct ubifs_info *c, int node_type) |
| 1029 | { | 1033 | { |
| 1030 | switch (node_type) { | 1034 | switch (node_type) { |
| 1031 | case UBIFS_LPT_NNODE: | 1035 | case UBIFS_LPT_NNODE: |
| @@ -1046,7 +1050,7 @@ static int get_lpt_node_len(struct ubifs_info *c, int node_type) | |||
| 1046 | * @buf: buffer | 1050 | * @buf: buffer |
| 1047 | * @len: length of buffer | 1051 | * @len: length of buffer |
| 1048 | */ | 1052 | */ |
| 1049 | static int get_pad_len(struct ubifs_info *c, uint8_t *buf, int len) | 1053 | static int get_pad_len(const struct ubifs_info *c, uint8_t *buf, int len) |
| 1050 | { | 1054 | { |
| 1051 | int offs, pad_len; | 1055 | int offs, pad_len; |
| 1052 | 1056 | ||
| @@ -1063,7 +1067,8 @@ static int get_pad_len(struct ubifs_info *c, uint8_t *buf, int len) | |||
| 1063 | * @buf: buffer | 1067 | * @buf: buffer |
| 1064 | * @node_num: node number is returned here | 1068 | * @node_num: node number is returned here |
| 1065 | */ | 1069 | */ |
| 1066 | static int get_lpt_node_type(struct ubifs_info *c, uint8_t *buf, int *node_num) | 1070 | static int get_lpt_node_type(const struct ubifs_info *c, uint8_t *buf, |
| 1071 | int *node_num) | ||
| 1067 | { | 1072 | { |
| 1068 | uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; | 1073 | uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; |
| 1069 | int pos = 0, node_type; | 1074 | int pos = 0, node_type; |
| @@ -1081,7 +1086,7 @@ static int get_lpt_node_type(struct ubifs_info *c, uint8_t *buf, int *node_num) | |||
| 1081 | * | 1086 | * |
| 1082 | * This function returns %1 if the buffer contains a node or %0 if it does not. | 1087 | * This function returns %1 if the buffer contains a node or %0 if it does not. |
| 1083 | */ | 1088 | */ |
| 1084 | static int is_a_node(struct ubifs_info *c, uint8_t *buf, int len) | 1089 | static int is_a_node(const struct ubifs_info *c, uint8_t *buf, int len) |
| 1085 | { | 1090 | { |
| 1086 | uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; | 1091 | uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; |
| 1087 | int pos = 0, node_type, node_len; | 1092 | int pos = 0, node_type, node_len; |
| @@ -1105,7 +1110,6 @@ static int is_a_node(struct ubifs_info *c, uint8_t *buf, int len) | |||
| 1105 | return 1; | 1110 | return 1; |
| 1106 | } | 1111 | } |
| 1107 | 1112 | ||
| 1108 | |||
| 1109 | /** | 1113 | /** |
| 1110 | * lpt_gc_lnum - garbage collect a LPT LEB. | 1114 | * lpt_gc_lnum - garbage collect a LPT LEB. |
| 1111 | * @c: UBIFS file-system description object | 1115 | * @c: UBIFS file-system description object |
| @@ -1463,7 +1467,7 @@ void ubifs_lpt_free(struct ubifs_info *c, int wr_only) | |||
| 1463 | #ifdef CONFIG_UBIFS_FS_DEBUG | 1467 | #ifdef CONFIG_UBIFS_FS_DEBUG |
| 1464 | 1468 | ||
| 1465 | /** | 1469 | /** |
| 1466 | * dbg_is_all_ff - determine if a buffer contains only 0xff bytes. | 1470 | * dbg_is_all_ff - determine if a buffer contains only 0xFF bytes. |
| 1467 | * @buf: buffer | 1471 | * @buf: buffer |
| 1468 | * @len: buffer length | 1472 | * @len: buffer length |
| 1469 | */ | 1473 | */ |
| @@ -1488,7 +1492,7 @@ static int dbg_is_nnode_dirty(struct ubifs_info *c, int lnum, int offs) | |||
| 1488 | struct ubifs_nnode *nnode; | 1492 | struct ubifs_nnode *nnode; |
| 1489 | int hght; | 1493 | int hght; |
| 1490 | 1494 | ||
| 1491 | /* Entire tree is in memory so first_nnode / next_nnode are ok */ | 1495 | /* Entire tree is in memory so first_nnode / next_nnode are OK */ |
| 1492 | nnode = first_nnode(c, &hght); | 1496 | nnode = first_nnode(c, &hght); |
| 1493 | for (; nnode; nnode = next_nnode(c, nnode, &hght)) { | 1497 | for (; nnode; nnode = next_nnode(c, nnode, &hght)) { |
| 1494 | struct ubifs_nbranch *branch; | 1498 | struct ubifs_nbranch *branch; |
| @@ -1602,7 +1606,10 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum) | |||
| 1602 | { | 1606 | { |
| 1603 | int err, len = c->leb_size, dirty = 0, node_type, node_num, node_len; | 1607 | int err, len = c->leb_size, dirty = 0, node_type, node_num, node_len; |
| 1604 | int ret; | 1608 | int ret; |
| 1605 | void *buf = c->dbg_buf; | 1609 | void *buf = c->dbg->buf; |
| 1610 | |||
| 1611 | if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS)) | ||
| 1612 | return 0; | ||
| 1606 | 1613 | ||
| 1607 | dbg_lp("LEB %d", lnum); | 1614 | dbg_lp("LEB %d", lnum); |
| 1608 | err = ubi_read(c->ubi, lnum, buf, 0, c->leb_size); | 1615 | err = ubi_read(c->ubi, lnum, buf, 0, c->leb_size); |
| @@ -1704,6 +1711,9 @@ int dbg_chk_lpt_free_spc(struct ubifs_info *c) | |||
| 1704 | long long free = 0; | 1711 | long long free = 0; |
| 1705 | int i; | 1712 | int i; |
| 1706 | 1713 | ||
| 1714 | if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS)) | ||
| 1715 | return 0; | ||
| 1716 | |||
| 1707 | for (i = 0; i < c->lpt_lebs; i++) { | 1717 | for (i = 0; i < c->lpt_lebs; i++) { |
| 1708 | if (c->ltab[i].tgc || c->ltab[i].cmt) | 1718 | if (c->ltab[i].tgc || c->ltab[i].cmt) |
| 1709 | continue; | 1719 | continue; |
| @@ -1716,6 +1726,8 @@ int dbg_chk_lpt_free_spc(struct ubifs_info *c) | |||
| 1716 | dbg_err("LPT space error: free %lld lpt_sz %lld", | 1726 | dbg_err("LPT space error: free %lld lpt_sz %lld", |
| 1717 | free, c->lpt_sz); | 1727 | free, c->lpt_sz); |
| 1718 | dbg_dump_lpt_info(c); | 1728 | dbg_dump_lpt_info(c); |
| 1729 | dbg_dump_lpt_lebs(c); | ||
| 1730 | dump_stack(); | ||
| 1719 | return -EINVAL; | 1731 | return -EINVAL; |
| 1720 | } | 1732 | } |
| 1721 | return 0; | 1733 | return 0; |
| @@ -1731,15 +1743,19 @@ int dbg_chk_lpt_free_spc(struct ubifs_info *c) | |||
| 1731 | */ | 1743 | */ |
| 1732 | int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len) | 1744 | int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len) |
| 1733 | { | 1745 | { |
| 1746 | struct ubifs_debug_info *d = c->dbg; | ||
| 1734 | long long chk_lpt_sz, lpt_sz; | 1747 | long long chk_lpt_sz, lpt_sz; |
| 1735 | int err = 0; | 1748 | int err = 0; |
| 1736 | 1749 | ||
| 1750 | if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS)) | ||
| 1751 | return 0; | ||
| 1752 | |||
| 1737 | switch (action) { | 1753 | switch (action) { |
| 1738 | case 0: | 1754 | case 0: |
| 1739 | c->chk_lpt_sz = 0; | 1755 | d->chk_lpt_sz = 0; |
| 1740 | c->chk_lpt_sz2 = 0; | 1756 | d->chk_lpt_sz2 = 0; |
| 1741 | c->chk_lpt_lebs = 0; | 1757 | d->chk_lpt_lebs = 0; |
| 1742 | c->chk_lpt_wastage = 0; | 1758 | d->chk_lpt_wastage = 0; |
| 1743 | if (c->dirty_pn_cnt > c->pnode_cnt) { | 1759 | if (c->dirty_pn_cnt > c->pnode_cnt) { |
| 1744 | dbg_err("dirty pnodes %d exceed max %d", | 1760 | dbg_err("dirty pnodes %d exceed max %d", |
| 1745 | c->dirty_pn_cnt, c->pnode_cnt); | 1761 | c->dirty_pn_cnt, c->pnode_cnt); |
| @@ -1752,35 +1768,35 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len) | |||
| 1752 | } | 1768 | } |
| 1753 | return err; | 1769 | return err; |
| 1754 | case 1: | 1770 | case 1: |
| 1755 | c->chk_lpt_sz += len; | 1771 | d->chk_lpt_sz += len; |
| 1756 | return 0; | 1772 | return 0; |
| 1757 | case 2: | 1773 | case 2: |
| 1758 | c->chk_lpt_sz += len; | 1774 | d->chk_lpt_sz += len; |
| 1759 | c->chk_lpt_wastage += len; | 1775 | d->chk_lpt_wastage += len; |
| 1760 | c->chk_lpt_lebs += 1; | 1776 | d->chk_lpt_lebs += 1; |
| 1761 | return 0; | 1777 | return 0; |
| 1762 | case 3: | 1778 | case 3: |
| 1763 | chk_lpt_sz = c->leb_size; | 1779 | chk_lpt_sz = c->leb_size; |
| 1764 | chk_lpt_sz *= c->chk_lpt_lebs; | 1780 | chk_lpt_sz *= d->chk_lpt_lebs; |
| 1765 | chk_lpt_sz += len - c->nhead_offs; | 1781 | chk_lpt_sz += len - c->nhead_offs; |
| 1766 | if (c->chk_lpt_sz != chk_lpt_sz) { | 1782 | if (d->chk_lpt_sz != chk_lpt_sz) { |
| 1767 | dbg_err("LPT wrote %lld but space used was %lld", | 1783 | dbg_err("LPT wrote %lld but space used was %lld", |
| 1768 | c->chk_lpt_sz, chk_lpt_sz); | 1784 | d->chk_lpt_sz, chk_lpt_sz); |
| 1769 | err = -EINVAL; | 1785 | err = -EINVAL; |
| 1770 | } | 1786 | } |
| 1771 | if (c->chk_lpt_sz > c->lpt_sz) { | 1787 | if (d->chk_lpt_sz > c->lpt_sz) { |
| 1772 | dbg_err("LPT wrote %lld but lpt_sz is %lld", | 1788 | dbg_err("LPT wrote %lld but lpt_sz is %lld", |
| 1773 | c->chk_lpt_sz, c->lpt_sz); | 1789 | d->chk_lpt_sz, c->lpt_sz); |
| 1774 | err = -EINVAL; | 1790 | err = -EINVAL; |
| 1775 | } | 1791 | } |
| 1776 | if (c->chk_lpt_sz2 && c->chk_lpt_sz != c->chk_lpt_sz2) { | 1792 | if (d->chk_lpt_sz2 && d->chk_lpt_sz != d->chk_lpt_sz2) { |
| 1777 | dbg_err("LPT layout size %lld but wrote %lld", | 1793 | dbg_err("LPT layout size %lld but wrote %lld", |
| 1778 | c->chk_lpt_sz, c->chk_lpt_sz2); | 1794 | d->chk_lpt_sz, d->chk_lpt_sz2); |
| 1779 | err = -EINVAL; | 1795 | err = -EINVAL; |
| 1780 | } | 1796 | } |
| 1781 | if (c->chk_lpt_sz2 && c->new_nhead_offs != len) { | 1797 | if (d->chk_lpt_sz2 && d->new_nhead_offs != len) { |
| 1782 | dbg_err("LPT new nhead offs: expected %d was %d", | 1798 | dbg_err("LPT new nhead offs: expected %d was %d", |
| 1783 | c->new_nhead_offs, len); | 1799 | d->new_nhead_offs, len); |
| 1784 | err = -EINVAL; | 1800 | err = -EINVAL; |
| 1785 | } | 1801 | } |
| 1786 | lpt_sz = (long long)c->pnode_cnt * c->pnode_sz; | 1802 | lpt_sz = (long long)c->pnode_cnt * c->pnode_sz; |
| @@ -1788,26 +1804,146 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len) | |||
| 1788 | lpt_sz += c->ltab_sz; | 1804 | lpt_sz += c->ltab_sz; |
| 1789 | if (c->big_lpt) | 1805 | if (c->big_lpt) |
| 1790 | lpt_sz += c->lsave_sz; | 1806 | lpt_sz += c->lsave_sz; |
| 1791 | if (c->chk_lpt_sz - c->chk_lpt_wastage > lpt_sz) { | 1807 | if (d->chk_lpt_sz - d->chk_lpt_wastage > lpt_sz) { |
| 1792 | dbg_err("LPT chk_lpt_sz %lld + waste %lld exceeds %lld", | 1808 | dbg_err("LPT chk_lpt_sz %lld + waste %lld exceeds %lld", |
| 1793 | c->chk_lpt_sz, c->chk_lpt_wastage, lpt_sz); | 1809 | d->chk_lpt_sz, d->chk_lpt_wastage, lpt_sz); |
| 1794 | err = -EINVAL; | 1810 | err = -EINVAL; |
| 1795 | } | 1811 | } |
| 1796 | if (err) | 1812 | if (err) { |
| 1797 | dbg_dump_lpt_info(c); | 1813 | dbg_dump_lpt_info(c); |
| 1798 | c->chk_lpt_sz2 = c->chk_lpt_sz; | 1814 | dbg_dump_lpt_lebs(c); |
| 1799 | c->chk_lpt_sz = 0; | 1815 | dump_stack(); |
| 1800 | c->chk_lpt_wastage = 0; | 1816 | } |
| 1801 | c->chk_lpt_lebs = 0; | 1817 | d->chk_lpt_sz2 = d->chk_lpt_sz; |
| 1802 | c->new_nhead_offs = len; | 1818 | d->chk_lpt_sz = 0; |
| 1819 | d->chk_lpt_wastage = 0; | ||
| 1820 | d->chk_lpt_lebs = 0; | ||
| 1821 | d->new_nhead_offs = len; | ||
| 1803 | return err; | 1822 | return err; |
| 1804 | case 4: | 1823 | case 4: |
| 1805 | c->chk_lpt_sz += len; | 1824 | d->chk_lpt_sz += len; |
| 1806 | c->chk_lpt_wastage += len; | 1825 | d->chk_lpt_wastage += len; |
| 1807 | return 0; | 1826 | return 0; |
| 1808 | default: | 1827 | default: |
| 1809 | return -EINVAL; | 1828 | return -EINVAL; |
| 1810 | } | 1829 | } |
| 1811 | } | 1830 | } |
| 1812 | 1831 | ||
| 1832 | /** | ||
| 1833 | * dbg_dump_lpt_leb - dump an LPT LEB. | ||
| 1834 | * @c: UBIFS file-system description object | ||
| 1835 | * @lnum: LEB number to dump | ||
| 1836 | * | ||
| 1837 | * This function dumps an LEB from LPT area. Nodes in this area are very | ||
| 1838 | * different to nodes in the main area (e.g., they do not have common headers, | ||
| 1839 | * they do not have 8-byte alignments, etc), so we have a separate function to | ||
| 1840 | * dump LPT area LEBs. Note, LPT has to be locked by the caller. | ||
| 1841 | */ | ||
| 1842 | static void dump_lpt_leb(const struct ubifs_info *c, int lnum) | ||
| 1843 | { | ||
| 1844 | int err, len = c->leb_size, node_type, node_num, node_len, offs; | ||
| 1845 | void *buf = c->dbg->buf; | ||
| 1846 | |||
| 1847 | printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n", | ||
| 1848 | current->pid, lnum); | ||
| 1849 | err = ubi_read(c->ubi, lnum, buf, 0, c->leb_size); | ||
| 1850 | if (err) { | ||
| 1851 | ubifs_err("cannot read LEB %d, error %d", lnum, err); | ||
| 1852 | return; | ||
| 1853 | } | ||
| 1854 | while (1) { | ||
| 1855 | offs = c->leb_size - len; | ||
| 1856 | if (!is_a_node(c, buf, len)) { | ||
| 1857 | int pad_len; | ||
| 1858 | |||
| 1859 | pad_len = get_pad_len(c, buf, len); | ||
| 1860 | if (pad_len) { | ||
| 1861 | printk(KERN_DEBUG "LEB %d:%d, pad %d bytes\n", | ||
| 1862 | lnum, offs, pad_len); | ||
| 1863 | buf += pad_len; | ||
| 1864 | len -= pad_len; | ||
| 1865 | continue; | ||
| 1866 | } | ||
| 1867 | if (len) | ||
| 1868 | printk(KERN_DEBUG "LEB %d:%d, free %d bytes\n", | ||
| 1869 | lnum, offs, len); | ||
| 1870 | break; | ||
| 1871 | } | ||
| 1872 | |||
| 1873 | node_type = get_lpt_node_type(c, buf, &node_num); | ||
| 1874 | switch (node_type) { | ||
| 1875 | case UBIFS_LPT_PNODE: | ||
| 1876 | { | ||
| 1877 | node_len = c->pnode_sz; | ||
| 1878 | if (c->big_lpt) | ||
| 1879 | printk(KERN_DEBUG "LEB %d:%d, pnode num %d\n", | ||
| 1880 | lnum, offs, node_num); | ||
| 1881 | else | ||
| 1882 | printk(KERN_DEBUG "LEB %d:%d, pnode\n", | ||
| 1883 | lnum, offs); | ||
| 1884 | break; | ||
| 1885 | } | ||
| 1886 | case UBIFS_LPT_NNODE: | ||
| 1887 | { | ||
| 1888 | int i; | ||
| 1889 | struct ubifs_nnode nnode; | ||
| 1890 | |||
| 1891 | node_len = c->nnode_sz; | ||
| 1892 | if (c->big_lpt) | ||
| 1893 | printk(KERN_DEBUG "LEB %d:%d, nnode num %d, ", | ||
| 1894 | lnum, offs, node_num); | ||
| 1895 | else | ||
| 1896 | printk(KERN_DEBUG "LEB %d:%d, nnode, ", | ||
| 1897 | lnum, offs); | ||
| 1898 | err = ubifs_unpack_nnode(c, buf, &nnode); | ||
| 1899 | for (i = 0; i < UBIFS_LPT_FANOUT; i++) { | ||
| 1900 | printk("%d:%d", nnode.nbranch[i].lnum, | ||
| 1901 | nnode.nbranch[i].offs); | ||
| 1902 | if (i != UBIFS_LPT_FANOUT - 1) | ||
| 1903 | printk(", "); | ||
| 1904 | } | ||
| 1905 | printk("\n"); | ||
| 1906 | break; | ||
| 1907 | } | ||
| 1908 | case UBIFS_LPT_LTAB: | ||
| 1909 | node_len = c->ltab_sz; | ||
| 1910 | printk(KERN_DEBUG "LEB %d:%d, ltab\n", | ||
| 1911 | lnum, offs); | ||
| 1912 | break; | ||
| 1913 | case UBIFS_LPT_LSAVE: | ||
| 1914 | node_len = c->lsave_sz; | ||
| 1915 | printk(KERN_DEBUG "LEB %d:%d, lsave len\n", lnum, offs); | ||
| 1916 | break; | ||
| 1917 | default: | ||
| 1918 | ubifs_err("LPT node type %d not recognized", node_type); | ||
| 1919 | return; | ||
| 1920 | } | ||
| 1921 | |||
| 1922 | buf += node_len; | ||
| 1923 | len -= node_len; | ||
| 1924 | } | ||
| 1925 | |||
| 1926 | printk(KERN_DEBUG "(pid %d) finish dumping LEB %d\n", | ||
| 1927 | current->pid, lnum); | ||
| 1928 | } | ||
| 1929 | |||
| 1930 | /** | ||
| 1931 | * dbg_dump_lpt_lebs - dump LPT lebs. | ||
| 1932 | * @c: UBIFS file-system description object | ||
| 1933 | * | ||
| 1934 | * This function dumps all LPT LEBs. The caller has to make sure the LPT is | ||
| 1935 | * locked. | ||
| 1936 | */ | ||
| 1937 | void dbg_dump_lpt_lebs(const struct ubifs_info *c) | ||
| 1938 | { | ||
| 1939 | int i; | ||
| 1940 | |||
| 1941 | printk(KERN_DEBUG "(pid %d) start dumping all LPT LEBs\n", | ||
| 1942 | current->pid); | ||
| 1943 | for (i = 0; i < c->lpt_lebs; i++) | ||
| 1944 | dump_lpt_leb(c, i + c->lpt_first); | ||
| 1945 | printk(KERN_DEBUG "(pid %d) finish dumping all LPT LEBs\n", | ||
| 1946 | current->pid); | ||
| 1947 | } | ||
| 1948 | |||
| 1813 | #endif /* CONFIG_UBIFS_FS_DEBUG */ | 1949 | #endif /* CONFIG_UBIFS_FS_DEBUG */ |
diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c index 9bd5a43d4526..9e6f403f170e 100644 --- a/fs/ubifs/orphan.c +++ b/fs/ubifs/orphan.c | |||
| @@ -899,7 +899,7 @@ static int dbg_scan_orphans(struct ubifs_info *c, struct check_info *ci) | |||
| 899 | for (lnum = c->orph_first; lnum <= c->orph_last; lnum++) { | 899 | for (lnum = c->orph_first; lnum <= c->orph_last; lnum++) { |
| 900 | struct ubifs_scan_leb *sleb; | 900 | struct ubifs_scan_leb *sleb; |
| 901 | 901 | ||
| 902 | sleb = ubifs_scan(c, lnum, 0, c->dbg_buf); | 902 | sleb = ubifs_scan(c, lnum, 0, c->dbg->buf); |
| 903 | if (IS_ERR(sleb)) { | 903 | if (IS_ERR(sleb)) { |
| 904 | err = PTR_ERR(sleb); | 904 | err = PTR_ERR(sleb); |
| 905 | break; | 905 | break; |
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c index 21f7d047c306..ce42a7b0ca5a 100644 --- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c | |||
| @@ -144,7 +144,7 @@ static int set_bud_lprops(struct ubifs_info *c, struct replay_entry *r) | |||
| 144 | /* | 144 | /* |
| 145 | * If the replay order was perfect the dirty space would now be | 145 | * If the replay order was perfect the dirty space would now be |
| 146 | * zero. The order is not perfect because the the journal heads | 146 | * zero. The order is not perfect because the the journal heads |
| 147 | * race with eachother. This is not a problem but is does mean | 147 | * race with each other. This is not a problem but is does mean |
| 148 | * that the dirty space may temporarily exceed c->leb_size | 148 | * that the dirty space may temporarily exceed c->leb_size |
| 149 | * during the replay. | 149 | * during the replay. |
| 150 | */ | 150 | */ |
| @@ -656,7 +656,7 @@ out_dump: | |||
| 656 | * @dirty: amount of dirty space from padding and deletion nodes | 656 | * @dirty: amount of dirty space from padding and deletion nodes |
| 657 | * | 657 | * |
| 658 | * This function inserts a reference node to the replay tree and returns zero | 658 | * This function inserts a reference node to the replay tree and returns zero |
| 659 | * in case of success ort a negative error code in case of failure. | 659 | * in case of success or a negative error code in case of failure. |
| 660 | */ | 660 | */ |
| 661 | static int insert_ref_node(struct ubifs_info *c, int lnum, int offs, | 661 | static int insert_ref_node(struct ubifs_info *c, int lnum, int offs, |
| 662 | unsigned long long sqnum, int free, int dirty) | 662 | unsigned long long sqnum, int free, int dirty) |
| @@ -883,7 +883,7 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) | |||
| 883 | * This means that we reached end of log and now | 883 | * This means that we reached end of log and now |
| 884 | * look to the older log data, which was already | 884 | * look to the older log data, which was already |
| 885 | * committed but the eraseblock was not erased (UBIFS | 885 | * committed but the eraseblock was not erased (UBIFS |
| 886 | * only unmaps it). So this basically means we have to | 886 | * only un-maps it). So this basically means we have to |
| 887 | * exit with "end of log" code. | 887 | * exit with "end of log" code. |
| 888 | */ | 888 | */ |
| 889 | err = 1; | 889 | err = 1; |
| @@ -1062,6 +1062,15 @@ int ubifs_replay_journal(struct ubifs_info *c) | |||
| 1062 | if (err) | 1062 | if (err) |
| 1063 | goto out; | 1063 | goto out; |
| 1064 | 1064 | ||
| 1065 | /* | ||
| 1066 | * UBIFS budgeting calculations use @c->budg_uncommitted_idx variable | ||
| 1067 | * to roughly estimate index growth. Things like @c->min_idx_lebs | ||
| 1068 | * depend on it. This means we have to initialize it to make sure | ||
| 1069 | * budgeting works properly. | ||
| 1070 | */ | ||
| 1071 | c->budg_uncommitted_idx = atomic_long_read(&c->dirty_zn_cnt); | ||
| 1072 | c->budg_uncommitted_idx *= c->max_idx_node_sz; | ||
| 1073 | |||
| 1065 | ubifs_assert(c->bud_bytes <= c->max_bud_bytes || c->need_recovery); | 1074 | ubifs_assert(c->bud_bytes <= c->max_bud_bytes || c->need_recovery); |
| 1066 | dbg_mnt("finished, log head LEB %d:%d, max_sqnum %llu, " | 1075 | dbg_mnt("finished, log head LEB %d:%d, max_sqnum %llu, " |
| 1067 | "highest_inum %lu", c->lhead_lnum, c->lhead_offs, c->max_sqnum, | 1076 | "highest_inum %lu", c->lhead_lnum, c->lhead_offs, c->max_sqnum, |
diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c index 0f392351dc5a..e070c643d1bb 100644 --- a/fs/ubifs/sb.c +++ b/fs/ubifs/sb.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | 28 | ||
| 29 | #include "ubifs.h" | 29 | #include "ubifs.h" |
| 30 | #include <linux/random.h> | 30 | #include <linux/random.h> |
| 31 | #include <linux/math64.h> | ||
| 31 | 32 | ||
| 32 | /* | 33 | /* |
| 33 | * Default journal size in logical eraseblocks as a percent of total | 34 | * Default journal size in logical eraseblocks as a percent of total |
| @@ -80,7 +81,7 @@ static int create_default_filesystem(struct ubifs_info *c) | |||
| 80 | int err, tmp, jnl_lebs, log_lebs, max_buds, main_lebs, main_first; | 81 | int err, tmp, jnl_lebs, log_lebs, max_buds, main_lebs, main_first; |
| 81 | int lpt_lebs, lpt_first, orph_lebs, big_lpt, ino_waste, sup_flags = 0; | 82 | int lpt_lebs, lpt_first, orph_lebs, big_lpt, ino_waste, sup_flags = 0; |
| 82 | int min_leb_cnt = UBIFS_MIN_LEB_CNT; | 83 | int min_leb_cnt = UBIFS_MIN_LEB_CNT; |
| 83 | uint64_t tmp64, main_bytes; | 84 | long long tmp64, main_bytes; |
| 84 | __le64 tmp_le64; | 85 | __le64 tmp_le64; |
| 85 | 86 | ||
| 86 | /* Some functions called from here depend on the @c->key_len filed */ | 87 | /* Some functions called from here depend on the @c->key_len filed */ |
| @@ -160,7 +161,7 @@ static int create_default_filesystem(struct ubifs_info *c) | |||
| 160 | if (!sup) | 161 | if (!sup) |
| 161 | return -ENOMEM; | 162 | return -ENOMEM; |
| 162 | 163 | ||
| 163 | tmp64 = (uint64_t)max_buds * c->leb_size; | 164 | tmp64 = (long long)max_buds * c->leb_size; |
| 164 | if (big_lpt) | 165 | if (big_lpt) |
| 165 | sup_flags |= UBIFS_FLG_BIGLPT; | 166 | sup_flags |= UBIFS_FLG_BIGLPT; |
| 166 | 167 | ||
| @@ -179,14 +180,16 @@ static int create_default_filesystem(struct ubifs_info *c) | |||
| 179 | sup->fanout = cpu_to_le32(DEFAULT_FANOUT); | 180 | sup->fanout = cpu_to_le32(DEFAULT_FANOUT); |
| 180 | sup->lsave_cnt = cpu_to_le32(c->lsave_cnt); | 181 | sup->lsave_cnt = cpu_to_le32(c->lsave_cnt); |
| 181 | sup->fmt_version = cpu_to_le32(UBIFS_FORMAT_VERSION); | 182 | sup->fmt_version = cpu_to_le32(UBIFS_FORMAT_VERSION); |
| 182 | sup->default_compr = cpu_to_le16(UBIFS_COMPR_LZO); | ||
| 183 | sup->time_gran = cpu_to_le32(DEFAULT_TIME_GRAN); | 183 | sup->time_gran = cpu_to_le32(DEFAULT_TIME_GRAN); |
| 184 | if (c->mount_opts.override_compr) | ||
| 185 | sup->default_compr = cpu_to_le16(c->mount_opts.compr_type); | ||
| 186 | else | ||
| 187 | sup->default_compr = cpu_to_le16(UBIFS_COMPR_LZO); | ||
| 184 | 188 | ||
| 185 | generate_random_uuid(sup->uuid); | 189 | generate_random_uuid(sup->uuid); |
| 186 | 190 | ||
| 187 | main_bytes = (uint64_t)main_lebs * c->leb_size; | 191 | main_bytes = (long long)main_lebs * c->leb_size; |
| 188 | tmp64 = main_bytes * DEFAULT_RP_PERCENT; | 192 | tmp64 = div_u64(main_bytes * DEFAULT_RP_PERCENT, 100); |
| 189 | do_div(tmp64, 100); | ||
| 190 | if (tmp64 > DEFAULT_MAX_RP_SIZE) | 193 | if (tmp64 > DEFAULT_MAX_RP_SIZE) |
| 191 | tmp64 = DEFAULT_MAX_RP_SIZE; | 194 | tmp64 = DEFAULT_MAX_RP_SIZE; |
| 192 | sup->rp_size = cpu_to_le64(tmp64); | 195 | sup->rp_size = cpu_to_le64(tmp64); |
| @@ -582,16 +585,15 @@ int ubifs_read_superblock(struct ubifs_info *c) | |||
| 582 | c->jhead_cnt = le32_to_cpu(sup->jhead_cnt) + NONDATA_JHEADS_CNT; | 585 | c->jhead_cnt = le32_to_cpu(sup->jhead_cnt) + NONDATA_JHEADS_CNT; |
| 583 | c->fanout = le32_to_cpu(sup->fanout); | 586 | c->fanout = le32_to_cpu(sup->fanout); |
| 584 | c->lsave_cnt = le32_to_cpu(sup->lsave_cnt); | 587 | c->lsave_cnt = le32_to_cpu(sup->lsave_cnt); |
| 585 | c->default_compr = le16_to_cpu(sup->default_compr); | ||
| 586 | c->rp_size = le64_to_cpu(sup->rp_size); | 588 | c->rp_size = le64_to_cpu(sup->rp_size); |
| 587 | c->rp_uid = le32_to_cpu(sup->rp_uid); | 589 | c->rp_uid = le32_to_cpu(sup->rp_uid); |
| 588 | c->rp_gid = le32_to_cpu(sup->rp_gid); | 590 | c->rp_gid = le32_to_cpu(sup->rp_gid); |
| 589 | sup_flags = le32_to_cpu(sup->flags); | 591 | sup_flags = le32_to_cpu(sup->flags); |
| 592 | if (!c->mount_opts.override_compr) | ||
| 593 | c->default_compr = le16_to_cpu(sup->default_compr); | ||
| 590 | 594 | ||
| 591 | c->vfs_sb->s_time_gran = le32_to_cpu(sup->time_gran); | 595 | c->vfs_sb->s_time_gran = le32_to_cpu(sup->time_gran); |
| 592 | |||
| 593 | memcpy(&c->uuid, &sup->uuid, 16); | 596 | memcpy(&c->uuid, &sup->uuid, 16); |
| 594 | |||
| 595 | c->big_lpt = !!(sup_flags & UBIFS_FLG_BIGLPT); | 597 | c->big_lpt = !!(sup_flags & UBIFS_FLG_BIGLPT); |
| 596 | 598 | ||
| 597 | /* Automatically increase file system size to the maximum size */ | 599 | /* Automatically increase file system size to the maximum size */ |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index d80b2aef42b6..0d7564b95f8e 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
| @@ -34,6 +34,8 @@ | |||
| 34 | #include <linux/parser.h> | 34 | #include <linux/parser.h> |
| 35 | #include <linux/seq_file.h> | 35 | #include <linux/seq_file.h> |
| 36 | #include <linux/mount.h> | 36 | #include <linux/mount.h> |
| 37 | #include <linux/math64.h> | ||
| 38 | #include <linux/writeback.h> | ||
| 37 | #include "ubifs.h" | 39 | #include "ubifs.h" |
| 38 | 40 | ||
| 39 | /* | 41 | /* |
| @@ -417,39 +419,54 @@ static int ubifs_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
| 417 | else if (c->mount_opts.chk_data_crc == 1) | 419 | else if (c->mount_opts.chk_data_crc == 1) |
| 418 | seq_printf(s, ",no_chk_data_crc"); | 420 | seq_printf(s, ",no_chk_data_crc"); |
| 419 | 421 | ||
| 422 | if (c->mount_opts.override_compr) { | ||
| 423 | seq_printf(s, ",compr="); | ||
| 424 | seq_printf(s, ubifs_compr_name(c->mount_opts.compr_type)); | ||
| 425 | } | ||
| 426 | |||
| 420 | return 0; | 427 | return 0; |
| 421 | } | 428 | } |
| 422 | 429 | ||
| 423 | static int ubifs_sync_fs(struct super_block *sb, int wait) | 430 | static int ubifs_sync_fs(struct super_block *sb, int wait) |
| 424 | { | 431 | { |
| 432 | int i, err; | ||
| 425 | struct ubifs_info *c = sb->s_fs_info; | 433 | struct ubifs_info *c = sb->s_fs_info; |
| 426 | int i, ret = 0, err; | 434 | struct writeback_control wbc = { |
| 427 | long long bud_bytes; | 435 | .sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_HOLD, |
| 428 | 436 | .range_start = 0, | |
| 429 | if (c->jheads) { | 437 | .range_end = LLONG_MAX, |
| 430 | for (i = 0; i < c->jhead_cnt; i++) { | 438 | .nr_to_write = LONG_MAX, |
| 431 | err = ubifs_wbuf_sync(&c->jheads[i].wbuf); | 439 | }; |
| 432 | if (err && !ret) | 440 | |
| 433 | ret = err; | 441 | if (sb->s_flags & MS_RDONLY) |
| 434 | } | 442 | return 0; |
| 435 | 443 | ||
| 436 | /* Commit the journal unless it has too little data */ | 444 | /* |
| 437 | spin_lock(&c->buds_lock); | 445 | * Synchronize write buffers, because 'ubifs_run_commit()' does not |
| 438 | bud_bytes = c->bud_bytes; | 446 | * do this if it waits for an already running commit. |
| 439 | spin_unlock(&c->buds_lock); | 447 | */ |
| 440 | if (bud_bytes > c->leb_size) { | 448 | for (i = 0; i < c->jhead_cnt; i++) { |
| 441 | err = ubifs_run_commit(c); | 449 | err = ubifs_wbuf_sync(&c->jheads[i].wbuf); |
| 442 | if (err) | 450 | if (err) |
| 443 | return err; | 451 | return err; |
| 444 | } | ||
| 445 | } | 452 | } |
| 446 | 453 | ||
| 447 | /* | 454 | /* |
| 448 | * We ought to call sync for c->ubi but it does not have one. If it had | 455 | * VFS calls '->sync_fs()' before synchronizing all dirty inodes and |
| 449 | * it would in turn call mtd->sync, however mtd operations are | 456 | * pages, so synchronize them first, then commit the journal. Strictly |
| 450 | * synchronous anyway, so we don't lose any sleep here. | 457 | * speaking, it is not necessary to commit the journal here, |
| 458 | * synchronizing write-buffers would be enough. But committing makes | ||
| 459 | * UBIFS free space predictions much more accurate, so we want to let | ||
| 460 | * the user be able to get more accurate results of 'statfs()' after | ||
| 461 | * they synchronize the file system. | ||
| 451 | */ | 462 | */ |
| 452 | return ret; | 463 | generic_sync_sb_inodes(sb, &wbc); |
| 464 | |||
| 465 | err = ubifs_run_commit(c); | ||
| 466 | if (err) | ||
| 467 | return err; | ||
| 468 | |||
| 469 | return ubi_sync(c->vi.ubi_num); | ||
| 453 | } | 470 | } |
| 454 | 471 | ||
| 455 | /** | 472 | /** |
| @@ -596,7 +613,7 @@ static int bud_wbuf_callback(struct ubifs_info *c, int lnum, int free, int pad) | |||
| 596 | } | 613 | } |
| 597 | 614 | ||
| 598 | /* | 615 | /* |
| 599 | * init_constants_late - initialize UBIFS constants. | 616 | * init_constants_sb - initialize UBIFS constants. |
| 600 | * @c: UBIFS file-system description object | 617 | * @c: UBIFS file-system description object |
| 601 | * | 618 | * |
| 602 | * This is a helper function which initializes various UBIFS constants after | 619 | * This is a helper function which initializes various UBIFS constants after |
| @@ -604,10 +621,10 @@ static int bud_wbuf_callback(struct ubifs_info *c, int lnum, int free, int pad) | |||
| 604 | * makes sure they are all right. Returns zero in case of success and a | 621 | * makes sure they are all right. Returns zero in case of success and a |
| 605 | * negative error code in case of failure. | 622 | * negative error code in case of failure. |
| 606 | */ | 623 | */ |
| 607 | static int init_constants_late(struct ubifs_info *c) | 624 | static int init_constants_sb(struct ubifs_info *c) |
| 608 | { | 625 | { |
| 609 | int tmp, err; | 626 | int tmp, err; |
| 610 | uint64_t tmp64; | 627 | long long tmp64; |
| 611 | 628 | ||
| 612 | c->main_bytes = (long long)c->main_lebs * c->leb_size; | 629 | c->main_bytes = (long long)c->main_lebs * c->leb_size; |
| 613 | c->max_znode_sz = sizeof(struct ubifs_znode) + | 630 | c->max_znode_sz = sizeof(struct ubifs_znode) + |
| @@ -634,9 +651,8 @@ static int init_constants_late(struct ubifs_info *c) | |||
| 634 | * Make sure that the log is large enough to fit reference nodes for | 651 | * Make sure that the log is large enough to fit reference nodes for |
| 635 | * all buds plus one reserved LEB. | 652 | * all buds plus one reserved LEB. |
| 636 | */ | 653 | */ |
| 637 | tmp64 = c->max_bud_bytes; | 654 | tmp64 = c->max_bud_bytes + c->leb_size - 1; |
| 638 | tmp = do_div(tmp64, c->leb_size); | 655 | c->max_bud_cnt = div_u64(tmp64, c->leb_size); |
| 639 | c->max_bud_cnt = tmp64 + !!tmp; | ||
| 640 | tmp = (c->ref_node_alsz * c->max_bud_cnt + c->leb_size - 1); | 656 | tmp = (c->ref_node_alsz * c->max_bud_cnt + c->leb_size - 1); |
| 641 | tmp /= c->leb_size; | 657 | tmp /= c->leb_size; |
| 642 | tmp += 1; | 658 | tmp += 1; |
| @@ -672,7 +688,7 @@ static int init_constants_late(struct ubifs_info *c) | |||
| 672 | * Consequently, if the journal is too small, UBIFS will treat it as | 688 | * Consequently, if the journal is too small, UBIFS will treat it as |
| 673 | * always full. | 689 | * always full. |
| 674 | */ | 690 | */ |
| 675 | tmp64 = (uint64_t)(c->jhead_cnt + 1) * c->leb_size + 1; | 691 | tmp64 = (long long)(c->jhead_cnt + 1) * c->leb_size + 1; |
| 676 | if (c->bg_bud_bytes < tmp64) | 692 | if (c->bg_bud_bytes < tmp64) |
| 677 | c->bg_bud_bytes = tmp64; | 693 | c->bg_bud_bytes = tmp64; |
| 678 | if (c->max_bud_bytes < tmp64 + c->leb_size) | 694 | if (c->max_bud_bytes < tmp64 + c->leb_size) |
| @@ -682,6 +698,21 @@ static int init_constants_late(struct ubifs_info *c) | |||
| 682 | if (err) | 698 | if (err) |
| 683 | return err; | 699 | return err; |
| 684 | 700 | ||
| 701 | return 0; | ||
| 702 | } | ||
| 703 | |||
| 704 | /* | ||
| 705 | * init_constants_master - initialize UBIFS constants. | ||
| 706 | * @c: UBIFS file-system description object | ||
| 707 | * | ||
| 708 | * This is a helper function which initializes various UBIFS constants after | ||
| 709 | * the master node has been read. It also checks various UBIFS parameters and | ||
| 710 | * makes sure they are all right. | ||
| 711 | */ | ||
| 712 | static void init_constants_master(struct ubifs_info *c) | ||
| 713 | { | ||
| 714 | long long tmp64; | ||
| 715 | |||
| 685 | c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); | 716 | c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); |
| 686 | 717 | ||
| 687 | /* | 718 | /* |
| @@ -690,14 +721,13 @@ static int init_constants_late(struct ubifs_info *c) | |||
| 690 | * necessary to report something for the 'statfs()' call. | 721 | * necessary to report something for the 'statfs()' call. |
| 691 | * | 722 | * |
| 692 | * Subtract the LEB reserved for GC, the LEB which is reserved for | 723 | * Subtract the LEB reserved for GC, the LEB which is reserved for |
| 693 | * deletions, and assume only one journal head is available. | 724 | * deletions, minimum LEBs for the index, and assume only one journal |
| 725 | * head is available. | ||
| 694 | */ | 726 | */ |
| 695 | tmp64 = c->main_lebs - 2 - c->jhead_cnt + 1; | 727 | tmp64 = c->main_lebs - 1 - 1 - MIN_INDEX_LEBS - c->jhead_cnt + 1; |
| 696 | tmp64 *= (uint64_t)c->leb_size - c->leb_overhead; | 728 | tmp64 *= (long long)c->leb_size - c->leb_overhead; |
| 697 | tmp64 = ubifs_reported_space(c, tmp64); | 729 | tmp64 = ubifs_reported_space(c, tmp64); |
| 698 | c->block_cnt = tmp64 >> UBIFS_BLOCK_SHIFT; | 730 | c->block_cnt = tmp64 >> UBIFS_BLOCK_SHIFT; |
| 699 | |||
| 700 | return 0; | ||
| 701 | } | 731 | } |
| 702 | 732 | ||
| 703 | /** | 733 | /** |
| @@ -878,6 +908,7 @@ static int check_volume_empty(struct ubifs_info *c) | |||
| 878 | * Opt_no_bulk_read: disable bulk-reads | 908 | * Opt_no_bulk_read: disable bulk-reads |
| 879 | * Opt_chk_data_crc: check CRCs when reading data nodes | 909 | * Opt_chk_data_crc: check CRCs when reading data nodes |
| 880 | * Opt_no_chk_data_crc: do not check CRCs when reading data nodes | 910 | * Opt_no_chk_data_crc: do not check CRCs when reading data nodes |
| 911 | * Opt_override_compr: override default compressor | ||
| 881 | * Opt_err: just end of array marker | 912 | * Opt_err: just end of array marker |
| 882 | */ | 913 | */ |
| 883 | enum { | 914 | enum { |
| @@ -887,6 +918,7 @@ enum { | |||
| 887 | Opt_no_bulk_read, | 918 | Opt_no_bulk_read, |
| 888 | Opt_chk_data_crc, | 919 | Opt_chk_data_crc, |
| 889 | Opt_no_chk_data_crc, | 920 | Opt_no_chk_data_crc, |
| 921 | Opt_override_compr, | ||
| 890 | Opt_err, | 922 | Opt_err, |
| 891 | }; | 923 | }; |
| 892 | 924 | ||
| @@ -897,6 +929,7 @@ static const match_table_t tokens = { | |||
| 897 | {Opt_no_bulk_read, "no_bulk_read"}, | 929 | {Opt_no_bulk_read, "no_bulk_read"}, |
| 898 | {Opt_chk_data_crc, "chk_data_crc"}, | 930 | {Opt_chk_data_crc, "chk_data_crc"}, |
| 899 | {Opt_no_chk_data_crc, "no_chk_data_crc"}, | 931 | {Opt_no_chk_data_crc, "no_chk_data_crc"}, |
| 932 | {Opt_override_compr, "compr=%s"}, | ||
| 900 | {Opt_err, NULL}, | 933 | {Opt_err, NULL}, |
| 901 | }; | 934 | }; |
| 902 | 935 | ||
| @@ -950,6 +983,28 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options, | |||
| 950 | c->mount_opts.chk_data_crc = 1; | 983 | c->mount_opts.chk_data_crc = 1; |
| 951 | c->no_chk_data_crc = 1; | 984 | c->no_chk_data_crc = 1; |
| 952 | break; | 985 | break; |
| 986 | case Opt_override_compr: | ||
| 987 | { | ||
| 988 | char *name = match_strdup(&args[0]); | ||
| 989 | |||
| 990 | if (!name) | ||
| 991 | return -ENOMEM; | ||
| 992 | if (!strcmp(name, "none")) | ||
| 993 | c->mount_opts.compr_type = UBIFS_COMPR_NONE; | ||
| 994 | else if (!strcmp(name, "lzo")) | ||
| 995 | c->mount_opts.compr_type = UBIFS_COMPR_LZO; | ||
| 996 | else if (!strcmp(name, "zlib")) | ||
| 997 | c->mount_opts.compr_type = UBIFS_COMPR_ZLIB; | ||
| 998 | else { | ||
| 999 | ubifs_err("unknown compressor \"%s\"", name); | ||
| 1000 | kfree(name); | ||
| 1001 | return -EINVAL; | ||
| 1002 | } | ||
| 1003 | kfree(name); | ||
| 1004 | c->mount_opts.override_compr = 1; | ||
| 1005 | c->default_compr = c->mount_opts.compr_type; | ||
| 1006 | break; | ||
| 1007 | } | ||
| 953 | default: | 1008 | default: |
| 954 | ubifs_err("unrecognized mount option \"%s\" " | 1009 | ubifs_err("unrecognized mount option \"%s\" " |
| 955 | "or missing value", p); | 1010 | "or missing value", p); |
| @@ -1019,6 +1074,30 @@ again: | |||
| 1019 | } | 1074 | } |
| 1020 | 1075 | ||
| 1021 | /** | 1076 | /** |
| 1077 | * check_free_space - check if there is enough free space to mount. | ||
| 1078 | * @c: UBIFS file-system description object | ||
| 1079 | * | ||
| 1080 | * This function makes sure UBIFS has enough free space to be mounted in | ||
| 1081 | * read/write mode. UBIFS must always have some free space to allow deletions. | ||
| 1082 | */ | ||
| 1083 | static int check_free_space(struct ubifs_info *c) | ||
| 1084 | { | ||
| 1085 | ubifs_assert(c->dark_wm > 0); | ||
| 1086 | if (c->lst.total_free + c->lst.total_dirty < c->dark_wm) { | ||
| 1087 | ubifs_err("insufficient free space to mount in read/write mode"); | ||
| 1088 | dbg_dump_budg(c); | ||
| 1089 | dbg_dump_lprops(c); | ||
| 1090 | /* | ||
| 1091 | * We return %-EINVAL instead of %-ENOSPC because it seems to | ||
| 1092 | * be the closest error code mentioned in the mount function | ||
| 1093 | * documentation. | ||
| 1094 | */ | ||
| 1095 | return -EINVAL; | ||
| 1096 | } | ||
| 1097 | return 0; | ||
| 1098 | } | ||
| 1099 | |||
| 1100 | /** | ||
| 1022 | * mount_ubifs - mount UBIFS file-system. | 1101 | * mount_ubifs - mount UBIFS file-system. |
| 1023 | * @c: UBIFS file-system description object | 1102 | * @c: UBIFS file-system description object |
| 1024 | * | 1103 | * |
| @@ -1039,11 +1118,9 @@ static int mount_ubifs(struct ubifs_info *c) | |||
| 1039 | if (err) | 1118 | if (err) |
| 1040 | return err; | 1119 | return err; |
| 1041 | 1120 | ||
| 1042 | #ifdef CONFIG_UBIFS_FS_DEBUG | 1121 | err = ubifs_debugging_init(c); |
| 1043 | c->dbg_buf = vmalloc(c->leb_size); | 1122 | if (err) |
| 1044 | if (!c->dbg_buf) | 1123 | return err; |
| 1045 | return -ENOMEM; | ||
| 1046 | #endif | ||
| 1047 | 1124 | ||
| 1048 | err = check_volume_empty(c); | 1125 | err = check_volume_empty(c); |
| 1049 | if (err) | 1126 | if (err) |
| @@ -1100,27 +1177,25 @@ static int mount_ubifs(struct ubifs_info *c) | |||
| 1100 | goto out_free; | 1177 | goto out_free; |
| 1101 | 1178 | ||
| 1102 | /* | 1179 | /* |
| 1103 | * Make sure the compressor which is set as the default on in the | 1180 | * Make sure the compressor which is set as default in the superblock |
| 1104 | * superblock was actually compiled in. | 1181 | * or overridden by mount options is actually compiled in. |
| 1105 | */ | 1182 | */ |
| 1106 | if (!ubifs_compr_present(c->default_compr)) { | 1183 | if (!ubifs_compr_present(c->default_compr)) { |
| 1107 | ubifs_warn("'%s' compressor is set by superblock, but not " | 1184 | ubifs_err("'compressor \"%s\" is not compiled in", |
| 1108 | "compiled in", ubifs_compr_name(c->default_compr)); | 1185 | ubifs_compr_name(c->default_compr)); |
| 1109 | c->default_compr = UBIFS_COMPR_NONE; | 1186 | goto out_free; |
| 1110 | } | 1187 | } |
| 1111 | 1188 | ||
| 1112 | dbg_failure_mode_registration(c); | 1189 | err = init_constants_sb(c); |
| 1113 | |||
| 1114 | err = init_constants_late(c); | ||
| 1115 | if (err) | 1190 | if (err) |
| 1116 | goto out_dereg; | 1191 | goto out_free; |
| 1117 | 1192 | ||
| 1118 | sz = ALIGN(c->max_idx_node_sz, c->min_io_size); | 1193 | sz = ALIGN(c->max_idx_node_sz, c->min_io_size); |
| 1119 | sz = ALIGN(sz + c->max_idx_node_sz, c->min_io_size); | 1194 | sz = ALIGN(sz + c->max_idx_node_sz, c->min_io_size); |
| 1120 | c->cbuf = kmalloc(sz, GFP_NOFS); | 1195 | c->cbuf = kmalloc(sz, GFP_NOFS); |
| 1121 | if (!c->cbuf) { | 1196 | if (!c->cbuf) { |
| 1122 | err = -ENOMEM; | 1197 | err = -ENOMEM; |
| 1123 | goto out_dereg; | 1198 | goto out_free; |
| 1124 | } | 1199 | } |
| 1125 | 1200 | ||
| 1126 | sprintf(c->bgt_name, BGT_NAME_PATTERN, c->vi.ubi_num, c->vi.vol_id); | 1201 | sprintf(c->bgt_name, BGT_NAME_PATTERN, c->vi.ubi_num, c->vi.vol_id); |
| @@ -1145,6 +1220,8 @@ static int mount_ubifs(struct ubifs_info *c) | |||
| 1145 | if (err) | 1220 | if (err) |
| 1146 | goto out_master; | 1221 | goto out_master; |
| 1147 | 1222 | ||
| 1223 | init_constants_master(c); | ||
| 1224 | |||
| 1148 | if ((c->mst_node->flags & cpu_to_le32(UBIFS_MST_DIRTY)) != 0) { | 1225 | if ((c->mst_node->flags & cpu_to_le32(UBIFS_MST_DIRTY)) != 0) { |
| 1149 | ubifs_msg("recovery needed"); | 1226 | ubifs_msg("recovery needed"); |
| 1150 | c->need_recovery = 1; | 1227 | c->need_recovery = 1; |
| @@ -1183,12 +1260,9 @@ static int mount_ubifs(struct ubifs_info *c) | |||
| 1183 | if (!mounted_read_only) { | 1260 | if (!mounted_read_only) { |
| 1184 | int lnum; | 1261 | int lnum; |
| 1185 | 1262 | ||
| 1186 | /* Check for enough free space */ | 1263 | err = check_free_space(c); |
| 1187 | if (ubifs_calc_available(c, c->min_idx_lebs) <= 0) { | 1264 | if (err) |
| 1188 | ubifs_err("insufficient available space"); | ||
| 1189 | err = -EINVAL; | ||
| 1190 | goto out_orphans; | 1265 | goto out_orphans; |
| 1191 | } | ||
| 1192 | 1266 | ||
| 1193 | /* Check for enough log space */ | 1267 | /* Check for enough log space */ |
| 1194 | lnum = c->lhead_lnum + 1; | 1268 | lnum = c->lhead_lnum + 1; |
| @@ -1232,6 +1306,10 @@ static int mount_ubifs(struct ubifs_info *c) | |||
| 1232 | } | 1306 | } |
| 1233 | } | 1307 | } |
| 1234 | 1308 | ||
| 1309 | err = dbg_debugfs_init_fs(c); | ||
| 1310 | if (err) | ||
| 1311 | goto out_infos; | ||
| 1312 | |||
| 1235 | err = dbg_check_filesystem(c); | 1313 | err = dbg_check_filesystem(c); |
| 1236 | if (err) | 1314 | if (err) |
| 1237 | goto out_infos; | 1315 | goto out_infos; |
| @@ -1283,8 +1361,20 @@ static int mount_ubifs(struct ubifs_info *c) | |||
| 1283 | dbg_msg("tree fanout: %d", c->fanout); | 1361 | dbg_msg("tree fanout: %d", c->fanout); |
| 1284 | dbg_msg("reserved GC LEB: %d", c->gc_lnum); | 1362 | dbg_msg("reserved GC LEB: %d", c->gc_lnum); |
| 1285 | dbg_msg("first main LEB: %d", c->main_first); | 1363 | dbg_msg("first main LEB: %d", c->main_first); |
| 1364 | dbg_msg("max. znode size %d", c->max_znode_sz); | ||
| 1365 | dbg_msg("max. index node size %d", c->max_idx_node_sz); | ||
| 1366 | dbg_msg("node sizes: data %zu, inode %zu, dentry %zu", | ||
| 1367 | UBIFS_DATA_NODE_SZ, UBIFS_INO_NODE_SZ, UBIFS_DENT_NODE_SZ); | ||
| 1368 | dbg_msg("node sizes: trun %zu, sb %zu, master %zu", | ||
| 1369 | UBIFS_TRUN_NODE_SZ, UBIFS_SB_NODE_SZ, UBIFS_MST_NODE_SZ); | ||
| 1370 | dbg_msg("node sizes: ref %zu, cmt. start %zu, orph %zu", | ||
| 1371 | UBIFS_REF_NODE_SZ, UBIFS_CS_NODE_SZ, UBIFS_ORPH_NODE_SZ); | ||
| 1372 | dbg_msg("max. node sizes: data %zu, inode %zu dentry %zu", | ||
| 1373 | UBIFS_MAX_DATA_NODE_SZ, UBIFS_MAX_INO_NODE_SZ, | ||
| 1374 | UBIFS_MAX_DENT_NODE_SZ); | ||
| 1286 | dbg_msg("dead watermark: %d", c->dead_wm); | 1375 | dbg_msg("dead watermark: %d", c->dead_wm); |
| 1287 | dbg_msg("dark watermark: %d", c->dark_wm); | 1376 | dbg_msg("dark watermark: %d", c->dark_wm); |
| 1377 | dbg_msg("LEB overhead: %d", c->leb_overhead); | ||
| 1288 | x = (long long)c->main_lebs * c->dark_wm; | 1378 | x = (long long)c->main_lebs * c->dark_wm; |
| 1289 | dbg_msg("max. dark space: %lld (%lld KiB, %lld MiB)", | 1379 | dbg_msg("max. dark space: %lld (%lld KiB, %lld MiB)", |
| 1290 | x, x >> 10, x >> 20); | 1380 | x, x >> 10, x >> 20); |
| @@ -1320,14 +1410,12 @@ out_wbufs: | |||
| 1320 | free_wbufs(c); | 1410 | free_wbufs(c); |
| 1321 | out_cbuf: | 1411 | out_cbuf: |
| 1322 | kfree(c->cbuf); | 1412 | kfree(c->cbuf); |
| 1323 | out_dereg: | ||
| 1324 | dbg_failure_mode_deregistration(c); | ||
| 1325 | out_free: | 1413 | out_free: |
| 1326 | kfree(c->bu.buf); | 1414 | kfree(c->bu.buf); |
| 1327 | vfree(c->ileb_buf); | 1415 | vfree(c->ileb_buf); |
| 1328 | vfree(c->sbuf); | 1416 | vfree(c->sbuf); |
| 1329 | kfree(c->bottom_up_buf); | 1417 | kfree(c->bottom_up_buf); |
| 1330 | UBIFS_DBG(vfree(c->dbg_buf)); | 1418 | ubifs_debugging_exit(c); |
| 1331 | return err; | 1419 | return err; |
| 1332 | } | 1420 | } |
| 1333 | 1421 | ||
| @@ -1345,6 +1433,7 @@ static void ubifs_umount(struct ubifs_info *c) | |||
| 1345 | dbg_gen("un-mounting UBI device %d, volume %d", c->vi.ubi_num, | 1433 | dbg_gen("un-mounting UBI device %d, volume %d", c->vi.ubi_num, |
| 1346 | c->vi.vol_id); | 1434 | c->vi.vol_id); |
| 1347 | 1435 | ||
| 1436 | dbg_debugfs_exit_fs(c); | ||
| 1348 | spin_lock(&ubifs_infos_lock); | 1437 | spin_lock(&ubifs_infos_lock); |
| 1349 | list_del(&c->infos_list); | 1438 | list_del(&c->infos_list); |
| 1350 | spin_unlock(&ubifs_infos_lock); | 1439 | spin_unlock(&ubifs_infos_lock); |
| @@ -1364,8 +1453,7 @@ static void ubifs_umount(struct ubifs_info *c) | |||
| 1364 | vfree(c->ileb_buf); | 1453 | vfree(c->ileb_buf); |
| 1365 | vfree(c->sbuf); | 1454 | vfree(c->sbuf); |
| 1366 | kfree(c->bottom_up_buf); | 1455 | kfree(c->bottom_up_buf); |
| 1367 | UBIFS_DBG(vfree(c->dbg_buf)); | 1456 | ubifs_debugging_exit(c); |
| 1368 | dbg_failure_mode_deregistration(c); | ||
| 1369 | } | 1457 | } |
| 1370 | 1458 | ||
| 1371 | /** | 1459 | /** |
| @@ -1387,12 +1475,9 @@ static int ubifs_remount_rw(struct ubifs_info *c) | |||
| 1387 | c->remounting_rw = 1; | 1475 | c->remounting_rw = 1; |
| 1388 | c->always_chk_crc = 1; | 1476 | c->always_chk_crc = 1; |
| 1389 | 1477 | ||
| 1390 | /* Check for enough free space */ | 1478 | err = check_free_space(c); |
| 1391 | if (ubifs_calc_available(c, c->min_idx_lebs) <= 0) { | 1479 | if (err) |
| 1392 | ubifs_err("insufficient available space"); | ||
| 1393 | err = -EINVAL; | ||
| 1394 | goto out; | 1480 | goto out; |
| 1395 | } | ||
| 1396 | 1481 | ||
| 1397 | if (c->old_leb_cnt != c->leb_cnt) { | 1482 | if (c->old_leb_cnt != c->leb_cnt) { |
| 1398 | struct ubifs_sb_node *sup; | 1483 | struct ubifs_sb_node *sup; |
| @@ -1515,20 +1600,24 @@ out: | |||
| 1515 | * @c: UBIFS file-system description object | 1600 | * @c: UBIFS file-system description object |
| 1516 | * | 1601 | * |
| 1517 | * This function is called during un-mounting and re-mounting, and it commits | 1602 | * This function is called during un-mounting and re-mounting, and it commits |
| 1518 | * the journal unless the "fast unmount" mode is enabled. It also avoids | 1603 | * the journal unless the "fast unmount" mode is enabled. |
| 1519 | * committing the journal if it contains too few data. | ||
| 1520 | */ | 1604 | */ |
| 1521 | static void commit_on_unmount(struct ubifs_info *c) | 1605 | static void commit_on_unmount(struct ubifs_info *c) |
| 1522 | { | 1606 | { |
| 1523 | if (!c->fast_unmount) { | 1607 | struct super_block *sb = c->vfs_sb; |
| 1524 | long long bud_bytes; | 1608 | long long bud_bytes; |
| 1525 | 1609 | ||
| 1526 | spin_lock(&c->buds_lock); | 1610 | /* |
| 1527 | bud_bytes = c->bud_bytes; | 1611 | * This function is called before the background thread is stopped, so |
| 1528 | spin_unlock(&c->buds_lock); | 1612 | * we may race with ongoing commit, which means we have to take |
| 1529 | if (bud_bytes > c->leb_size) | 1613 | * @c->bud_lock to access @c->bud_bytes. |
| 1530 | ubifs_run_commit(c); | 1614 | */ |
| 1531 | } | 1615 | spin_lock(&c->buds_lock); |
| 1616 | bud_bytes = c->bud_bytes; | ||
| 1617 | spin_unlock(&c->buds_lock); | ||
| 1618 | |||
| 1619 | if (!c->fast_unmount && !(sb->s_flags & MS_RDONLY) && bud_bytes) | ||
| 1620 | ubifs_run_commit(c); | ||
| 1532 | } | 1621 | } |
| 1533 | 1622 | ||
| 1534 | /** | 1623 | /** |
| @@ -1849,7 +1938,6 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1849 | goto out_iput; | 1938 | goto out_iput; |
| 1850 | 1939 | ||
| 1851 | mutex_unlock(&c->umount_mutex); | 1940 | mutex_unlock(&c->umount_mutex); |
| 1852 | |||
| 1853 | return 0; | 1941 | return 0; |
| 1854 | 1942 | ||
| 1855 | out_iput: | 1943 | out_iput: |
| @@ -1955,7 +2043,7 @@ static void ubifs_kill_sb(struct super_block *sb) | |||
| 1955 | * We do 'commit_on_unmount()' here instead of 'ubifs_put_super()' | 2043 | * We do 'commit_on_unmount()' here instead of 'ubifs_put_super()' |
| 1956 | * in order to be outside BKL. | 2044 | * in order to be outside BKL. |
| 1957 | */ | 2045 | */ |
| 1958 | if (sb->s_root && !(sb->s_flags & MS_RDONLY)) | 2046 | if (sb->s_root) |
| 1959 | commit_on_unmount(c); | 2047 | commit_on_unmount(c); |
| 1960 | /* The un-mount routine is actually done in put_super() */ | 2048 | /* The un-mount routine is actually done in put_super() */ |
| 1961 | generic_shutdown_super(sb); | 2049 | generic_shutdown_super(sb); |
| @@ -2021,6 +2109,14 @@ static int __init ubifs_init(void) | |||
| 2021 | BUILD_BUG_ON(UBIFS_REF_NODE_SZ != 64); | 2109 | BUILD_BUG_ON(UBIFS_REF_NODE_SZ != 64); |
| 2022 | 2110 | ||
| 2023 | /* | 2111 | /* |
| 2112 | * We use 2 bit wide bit-fields to store compression type, which should | ||
| 2113 | * be amended if more compressors are added. The bit-fields are: | ||
| 2114 | * @compr_type in 'struct ubifs_inode', @default_compr in | ||
| 2115 | * 'struct ubifs_info' and @compr_type in 'struct ubifs_mount_opts'. | ||
| 2116 | */ | ||
| 2117 | BUILD_BUG_ON(UBIFS_COMPR_TYPES_CNT > 4); | ||
| 2118 | |||
| 2119 | /* | ||
| 2024 | * We require that PAGE_CACHE_SIZE is greater-than-or-equal-to | 2120 | * We require that PAGE_CACHE_SIZE is greater-than-or-equal-to |
| 2025 | * UBIFS_BLOCK_SIZE. It is assumed that both are powers of 2. | 2121 | * UBIFS_BLOCK_SIZE. It is assumed that both are powers of 2. |
| 2026 | */ | 2122 | */ |
| @@ -2049,11 +2145,17 @@ static int __init ubifs_init(void) | |||
| 2049 | 2145 | ||
| 2050 | err = ubifs_compressors_init(); | 2146 | err = ubifs_compressors_init(); |
| 2051 | if (err) | 2147 | if (err) |
| 2148 | goto out_shrinker; | ||
| 2149 | |||
| 2150 | err = dbg_debugfs_init(); | ||
| 2151 | if (err) | ||
| 2052 | goto out_compr; | 2152 | goto out_compr; |
| 2053 | 2153 | ||
| 2054 | return 0; | 2154 | return 0; |
| 2055 | 2155 | ||
| 2056 | out_compr: | 2156 | out_compr: |
| 2157 | ubifs_compressors_exit(); | ||
| 2158 | out_shrinker: | ||
| 2057 | unregister_shrinker(&ubifs_shrinker_info); | 2159 | unregister_shrinker(&ubifs_shrinker_info); |
| 2058 | kmem_cache_destroy(ubifs_inode_slab); | 2160 | kmem_cache_destroy(ubifs_inode_slab); |
| 2059 | out_reg: | 2161 | out_reg: |
| @@ -2068,6 +2170,7 @@ static void __exit ubifs_exit(void) | |||
| 2068 | ubifs_assert(list_empty(&ubifs_infos)); | 2170 | ubifs_assert(list_empty(&ubifs_infos)); |
| 2069 | ubifs_assert(atomic_long_read(&ubifs_clean_zn_cnt) == 0); | 2171 | ubifs_assert(atomic_long_read(&ubifs_clean_zn_cnt) == 0); |
| 2070 | 2172 | ||
| 2173 | dbg_debugfs_exit(); | ||
| 2071 | ubifs_compressors_exit(); | 2174 | ubifs_compressors_exit(); |
| 2072 | unregister_shrinker(&ubifs_shrinker_info); | 2175 | unregister_shrinker(&ubifs_shrinker_info); |
| 2073 | kmem_cache_destroy(ubifs_inode_slab); | 2176 | kmem_cache_destroy(ubifs_inode_slab); |
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 6eef5344a145..f7e36f545527 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c | |||
| @@ -2245,12 +2245,11 @@ int ubifs_tnc_replace(struct ubifs_info *c, const union ubifs_key *key, | |||
| 2245 | if (found) { | 2245 | if (found) { |
| 2246 | /* Ensure the znode is dirtied */ | 2246 | /* Ensure the znode is dirtied */ |
| 2247 | if (znode->cnext || !ubifs_zn_dirty(znode)) { | 2247 | if (znode->cnext || !ubifs_zn_dirty(znode)) { |
| 2248 | znode = dirty_cow_bottom_up(c, | 2248 | znode = dirty_cow_bottom_up(c, znode); |
| 2249 | znode); | 2249 | if (IS_ERR(znode)) { |
| 2250 | if (IS_ERR(znode)) { | 2250 | err = PTR_ERR(znode); |
| 2251 | err = PTR_ERR(znode); | 2251 | goto out_unlock; |
| 2252 | goto out_unlock; | 2252 | } |
| 2253 | } | ||
| 2254 | } | 2253 | } |
| 2255 | zbr = &znode->zbranch[n]; | 2254 | zbr = &znode->zbranch[n]; |
| 2256 | lnc_free(zbr); | 2255 | lnc_free(zbr); |
| @@ -2317,11 +2316,11 @@ int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, | |||
| 2317 | 2316 | ||
| 2318 | /* Ensure the znode is dirtied */ | 2317 | /* Ensure the znode is dirtied */ |
| 2319 | if (znode->cnext || !ubifs_zn_dirty(znode)) { | 2318 | if (znode->cnext || !ubifs_zn_dirty(znode)) { |
| 2320 | znode = dirty_cow_bottom_up(c, znode); | 2319 | znode = dirty_cow_bottom_up(c, znode); |
| 2321 | if (IS_ERR(znode)) { | 2320 | if (IS_ERR(znode)) { |
| 2322 | err = PTR_ERR(znode); | 2321 | err = PTR_ERR(znode); |
| 2323 | goto out_unlock; | 2322 | goto out_unlock; |
| 2324 | } | 2323 | } |
| 2325 | } | 2324 | } |
| 2326 | 2325 | ||
| 2327 | if (found == 1) { | 2326 | if (found == 1) { |
| @@ -2627,11 +2626,11 @@ int ubifs_tnc_remove_range(struct ubifs_info *c, union ubifs_key *from_key, | |||
| 2627 | 2626 | ||
| 2628 | /* Ensure the znode is dirtied */ | 2627 | /* Ensure the znode is dirtied */ |
| 2629 | if (znode->cnext || !ubifs_zn_dirty(znode)) { | 2628 | if (znode->cnext || !ubifs_zn_dirty(znode)) { |
| 2630 | znode = dirty_cow_bottom_up(c, znode); | 2629 | znode = dirty_cow_bottom_up(c, znode); |
| 2631 | if (IS_ERR(znode)) { | 2630 | if (IS_ERR(znode)) { |
| 2632 | err = PTR_ERR(znode); | 2631 | err = PTR_ERR(znode); |
| 2633 | goto out_unlock; | 2632 | goto out_unlock; |
| 2634 | } | 2633 | } |
| 2635 | } | 2634 | } |
| 2636 | 2635 | ||
| 2637 | /* Remove all keys in range except the first */ | 2636 | /* Remove all keys in range except the first */ |
diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c index 8ac76b1c2d55..fde8d127c768 100644 --- a/fs/ubifs/tnc_commit.c +++ b/fs/ubifs/tnc_commit.c | |||
| @@ -553,8 +553,8 @@ static int layout_in_empty_space(struct ubifs_info *c) | |||
| 553 | } | 553 | } |
| 554 | 554 | ||
| 555 | #ifdef CONFIG_UBIFS_FS_DEBUG | 555 | #ifdef CONFIG_UBIFS_FS_DEBUG |
| 556 | c->new_ihead_lnum = lnum; | 556 | c->dbg->new_ihead_lnum = lnum; |
| 557 | c->new_ihead_offs = buf_offs; | 557 | c->dbg->new_ihead_offs = buf_offs; |
| 558 | #endif | 558 | #endif |
| 559 | 559 | ||
| 560 | return 0; | 560 | return 0; |
| @@ -802,8 +802,10 @@ int ubifs_tnc_start_commit(struct ubifs_info *c, struct ubifs_zbranch *zroot) | |||
| 802 | * budgeting subsystem to assume the index is already committed, | 802 | * budgeting subsystem to assume the index is already committed, |
| 803 | * even though it is not. | 803 | * even though it is not. |
| 804 | */ | 804 | */ |
| 805 | ubifs_assert(c->min_idx_lebs == ubifs_calc_min_idx_lebs(c)); | ||
| 805 | c->old_idx_sz = c->calc_idx_sz; | 806 | c->old_idx_sz = c->calc_idx_sz; |
| 806 | c->budg_uncommitted_idx = 0; | 807 | c->budg_uncommitted_idx = 0; |
| 808 | c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); | ||
| 807 | spin_unlock(&c->space_lock); | 809 | spin_unlock(&c->space_lock); |
| 808 | mutex_unlock(&c->tnc_mutex); | 810 | mutex_unlock(&c->tnc_mutex); |
| 809 | 811 | ||
| @@ -1002,7 +1004,8 @@ static int write_index(struct ubifs_info *c) | |||
| 1002 | } | 1004 | } |
| 1003 | 1005 | ||
| 1004 | #ifdef CONFIG_UBIFS_FS_DEBUG | 1006 | #ifdef CONFIG_UBIFS_FS_DEBUG |
| 1005 | if (lnum != c->new_ihead_lnum || buf_offs != c->new_ihead_offs) { | 1007 | if (lnum != c->dbg->new_ihead_lnum || |
| 1008 | buf_offs != c->dbg->new_ihead_offs) { | ||
| 1006 | ubifs_err("inconsistent ihead"); | 1009 | ubifs_err("inconsistent ihead"); |
| 1007 | return -EINVAL; | 1010 | return -EINVAL; |
| 1008 | } | 1011 | } |
diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h index 0b378042a3a2..b25fc36cf72f 100644 --- a/fs/ubifs/ubifs-media.h +++ b/fs/ubifs/ubifs-media.h | |||
| @@ -51,6 +51,13 @@ | |||
| 51 | */ | 51 | */ |
| 52 | #define UBIFS_MIN_COMPR_LEN 128 | 52 | #define UBIFS_MIN_COMPR_LEN 128 |
| 53 | 53 | ||
| 54 | /* | ||
| 55 | * If compressed data length is less than %UBIFS_MIN_COMPRESS_DIFF bytes | ||
| 56 | * shorter than uncompressed data length, UBIFS preferes to leave this data | ||
| 57 | * node uncompress, because it'll be read faster. | ||
| 58 | */ | ||
| 59 | #define UBIFS_MIN_COMPRESS_DIFF 64 | ||
| 60 | |||
| 54 | /* Root inode number */ | 61 | /* Root inode number */ |
| 55 | #define UBIFS_ROOT_INO 1 | 62 | #define UBIFS_ROOT_INO 1 |
| 56 | 63 | ||
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 46b172560a06..fc2a4cc66d03 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
| @@ -63,6 +63,14 @@ | |||
| 63 | #define SQNUM_WARN_WATERMARK 0xFFFFFFFF00000000ULL | 63 | #define SQNUM_WARN_WATERMARK 0xFFFFFFFF00000000ULL |
| 64 | #define SQNUM_WATERMARK 0xFFFFFFFFFF000000ULL | 64 | #define SQNUM_WATERMARK 0xFFFFFFFFFF000000ULL |
| 65 | 65 | ||
| 66 | /* | ||
| 67 | * Minimum amount of LEBs reserved for the index. At present the index needs at | ||
| 68 | * least 2 LEBs: one for the index head and one for in-the-gaps method (which | ||
| 69 | * currently does not cater for the index head and so excludes it from | ||
| 70 | * consideration). | ||
| 71 | */ | ||
| 72 | #define MIN_INDEX_LEBS 2 | ||
| 73 | |||
| 66 | /* Minimum amount of data UBIFS writes to the flash */ | 74 | /* Minimum amount of data UBIFS writes to the flash */ |
| 67 | #define MIN_WRITE_SZ (UBIFS_DATA_NODE_SZ + 8) | 75 | #define MIN_WRITE_SZ (UBIFS_DATA_NODE_SZ + 8) |
| 68 | 76 | ||
| @@ -386,12 +394,12 @@ struct ubifs_inode { | |||
| 386 | unsigned int dirty:1; | 394 | unsigned int dirty:1; |
| 387 | unsigned int xattr:1; | 395 | unsigned int xattr:1; |
| 388 | unsigned int bulk_read:1; | 396 | unsigned int bulk_read:1; |
| 397 | unsigned int compr_type:2; | ||
| 389 | struct mutex ui_mutex; | 398 | struct mutex ui_mutex; |
| 390 | spinlock_t ui_lock; | 399 | spinlock_t ui_lock; |
| 391 | loff_t synced_i_size; | 400 | loff_t synced_i_size; |
| 392 | loff_t ui_size; | 401 | loff_t ui_size; |
| 393 | int flags; | 402 | int flags; |
| 394 | int compr_type; | ||
| 395 | pgoff_t last_page_read; | 403 | pgoff_t last_page_read; |
| 396 | pgoff_t read_in_a_row; | 404 | pgoff_t read_in_a_row; |
| 397 | int data_len; | 405 | int data_len; |
| @@ -419,7 +427,7 @@ struct ubifs_unclean_leb { | |||
| 419 | * | 427 | * |
| 420 | * LPROPS_UNCAT: not categorized | 428 | * LPROPS_UNCAT: not categorized |
| 421 | * LPROPS_DIRTY: dirty > 0, not index | 429 | * LPROPS_DIRTY: dirty > 0, not index |
| 422 | * LPROPS_DIRTY_IDX: dirty + free > UBIFS_CH_SZ and index | 430 | * LPROPS_DIRTY_IDX: dirty + free > @c->min_idx_node_sze and index |
| 423 | * LPROPS_FREE: free > 0, not empty, not index | 431 | * LPROPS_FREE: free > 0, not empty, not index |
| 424 | * LPROPS_HEAP_CNT: number of heaps used for storing categorized LEBs | 432 | * LPROPS_HEAP_CNT: number of heaps used for storing categorized LEBs |
| 425 | * LPROPS_EMPTY: LEB is empty, not taken | 433 | * LPROPS_EMPTY: LEB is empty, not taken |
| @@ -473,8 +481,8 @@ struct ubifs_lprops { | |||
| 473 | struct ubifs_lpt_lprops { | 481 | struct ubifs_lpt_lprops { |
| 474 | int free; | 482 | int free; |
| 475 | int dirty; | 483 | int dirty; |
| 476 | unsigned tgc : 1; | 484 | unsigned tgc:1; |
| 477 | unsigned cmt : 1; | 485 | unsigned cmt:1; |
| 478 | }; | 486 | }; |
| 479 | 487 | ||
| 480 | /** | 488 | /** |
| @@ -482,24 +490,26 @@ struct ubifs_lpt_lprops { | |||
| 482 | * @empty_lebs: number of empty LEBs | 490 | * @empty_lebs: number of empty LEBs |
| 483 | * @taken_empty_lebs: number of taken LEBs | 491 | * @taken_empty_lebs: number of taken LEBs |
| 484 | * @idx_lebs: number of indexing LEBs | 492 | * @idx_lebs: number of indexing LEBs |
| 485 | * @total_free: total free space in bytes | 493 | * @total_free: total free space in bytes (includes all LEBs) |
| 486 | * @total_dirty: total dirty space in bytes | 494 | * @total_dirty: total dirty space in bytes (includes all LEBs) |
| 487 | * @total_used: total used space in bytes (includes only data LEBs) | 495 | * @total_used: total used space in bytes (does not include index LEBs) |
| 488 | * @total_dead: total dead space in bytes (includes only data LEBs) | 496 | * @total_dead: total dead space in bytes (does not include index LEBs) |
| 489 | * @total_dark: total dark space in bytes (includes only data LEBs) | 497 | * @total_dark: total dark space in bytes (does not include index LEBs) |
| 498 | * | ||
| 499 | * The @taken_empty_lebs field counts the LEBs that are in the transient state | ||
| 500 | * of having been "taken" for use but not yet written to. @taken_empty_lebs is | ||
| 501 | * needed to account correctly for @gc_lnum, otherwise @empty_lebs could be | ||
| 502 | * used by itself (in which case 'unused_lebs' would be a better name). In the | ||
| 503 | * case of @gc_lnum, it is "taken" at mount time or whenever a LEB is retained | ||
| 504 | * by GC, but unlike other empty LEBs that are "taken", it may not be written | ||
| 505 | * straight away (i.e. before the next commit start or unmount), so either | ||
| 506 | * @gc_lnum must be specially accounted for, or the current approach followed | ||
| 507 | * i.e. count it under @taken_empty_lebs. | ||
| 490 | * | 508 | * |
| 491 | * N.B. total_dirty and total_used are different to other total_* fields, | 509 | * @empty_lebs includes @taken_empty_lebs. |
| 492 | * because they account _all_ LEBs, not just data LEBs. | ||
| 493 | * | 510 | * |
| 494 | * 'taken_empty_lebs' counts the LEBs that are in the transient state of having | 511 | * @total_used, @total_dead and @total_dark fields do not account indexing |
| 495 | * been 'taken' for use but not yet written to. 'taken_empty_lebs' is needed | 512 | * LEBs. |
| 496 | * to account correctly for gc_lnum, otherwise 'empty_lebs' could be used | ||
| 497 | * by itself (in which case 'unused_lebs' would be a better name). In the case | ||
| 498 | * of gc_lnum, it is 'taken' at mount time or whenever a LEB is retained by GC, | ||
| 499 | * but unlike other empty LEBs that are 'taken', it may not be written straight | ||
| 500 | * away (i.e. before the next commit start or unmount), so either gc_lnum must | ||
| 501 | * be specially accounted for, or the current approach followed i.e. count it | ||
| 502 | * under 'taken_empty_lebs'. | ||
| 503 | */ | 513 | */ |
| 504 | struct ubifs_lp_stats { | 514 | struct ubifs_lp_stats { |
| 505 | int empty_lebs; | 515 | int empty_lebs; |
| @@ -893,15 +903,25 @@ struct ubifs_orphan { | |||
| 893 | /** | 903 | /** |
| 894 | * struct ubifs_mount_opts - UBIFS-specific mount options information. | 904 | * struct ubifs_mount_opts - UBIFS-specific mount options information. |
| 895 | * @unmount_mode: selected unmount mode (%0 default, %1 normal, %2 fast) | 905 | * @unmount_mode: selected unmount mode (%0 default, %1 normal, %2 fast) |
| 896 | * @bulk_read: enable bulk-reads | 906 | * @bulk_read: enable/disable bulk-reads (%0 default, %1 disabe, %2 enable) |
| 897 | * @chk_data_crc: check CRCs when reading data nodes | 907 | * @chk_data_crc: enable/disable CRC data checking when reading data nodes |
| 908 | * (%0 default, %1 disabe, %2 enable) | ||
| 909 | * @override_compr: override default compressor (%0 - do not override and use | ||
| 910 | * superblock compressor, %1 - override and use compressor | ||
| 911 | * specified in @compr_type) | ||
| 912 | * @compr_type: compressor type to override the superblock compressor with | ||
| 913 | * (%UBIFS_COMPR_NONE, etc) | ||
| 898 | */ | 914 | */ |
| 899 | struct ubifs_mount_opts { | 915 | struct ubifs_mount_opts { |
| 900 | unsigned int unmount_mode:2; | 916 | unsigned int unmount_mode:2; |
| 901 | unsigned int bulk_read:2; | 917 | unsigned int bulk_read:2; |
| 902 | unsigned int chk_data_crc:2; | 918 | unsigned int chk_data_crc:2; |
| 919 | unsigned int override_compr:1; | ||
| 920 | unsigned int compr_type:2; | ||
| 903 | }; | 921 | }; |
| 904 | 922 | ||
| 923 | struct ubifs_debug_info; | ||
| 924 | |||
| 905 | /** | 925 | /** |
| 906 | * struct ubifs_info - UBIFS file-system description data structure | 926 | * struct ubifs_info - UBIFS file-system description data structure |
| 907 | * (per-superblock). | 927 | * (per-superblock). |
| @@ -946,6 +966,7 @@ struct ubifs_mount_opts { | |||
| 946 | * @no_chk_data_crc: do not check CRCs when reading data nodes (except during | 966 | * @no_chk_data_crc: do not check CRCs when reading data nodes (except during |
| 947 | * recovery) | 967 | * recovery) |
| 948 | * @bulk_read: enable bulk-reads | 968 | * @bulk_read: enable bulk-reads |
| 969 | * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc) | ||
| 949 | * | 970 | * |
| 950 | * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and | 971 | * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and |
| 951 | * @calc_idx_sz | 972 | * @calc_idx_sz |
| @@ -963,8 +984,6 @@ struct ubifs_mount_opts { | |||
| 963 | * @ileb_nxt: next pre-allocated index LEBs | 984 | * @ileb_nxt: next pre-allocated index LEBs |
| 964 | * @old_idx: tree of index nodes obsoleted since the last commit start | 985 | * @old_idx: tree of index nodes obsoleted since the last commit start |
| 965 | * @bottom_up_buf: a buffer which is used by 'dirty_cow_bottom_up()' in tnc.c | 986 | * @bottom_up_buf: a buffer which is used by 'dirty_cow_bottom_up()' in tnc.c |
| 966 | * @new_ihead_lnum: used by debugging to check ihead_lnum | ||
| 967 | * @new_ihead_offs: used by debugging to check ihead_offs | ||
| 968 | * | 987 | * |
| 969 | * @mst_node: master node | 988 | * @mst_node: master node |
| 970 | * @mst_offs: offset of valid master node | 989 | * @mst_offs: offset of valid master node |
| @@ -986,7 +1005,6 @@ struct ubifs_mount_opts { | |||
| 986 | * @main_lebs: count of LEBs in the main area | 1005 | * @main_lebs: count of LEBs in the main area |
| 987 | * @main_first: first LEB of the main area | 1006 | * @main_first: first LEB of the main area |
| 988 | * @main_bytes: main area size in bytes | 1007 | * @main_bytes: main area size in bytes |
| 989 | * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc) | ||
| 990 | * | 1008 | * |
| 991 | * @key_hash_type: type of the key hash | 1009 | * @key_hash_type: type of the key hash |
| 992 | * @key_hash: direntry key hash function | 1010 | * @key_hash: direntry key hash function |
| @@ -1149,15 +1167,7 @@ struct ubifs_mount_opts { | |||
| 1149 | * @always_chk_crc: always check CRCs (while mounting and remounting rw) | 1167 | * @always_chk_crc: always check CRCs (while mounting and remounting rw) |
| 1150 | * @mount_opts: UBIFS-specific mount options | 1168 | * @mount_opts: UBIFS-specific mount options |
| 1151 | * | 1169 | * |
| 1152 | * @dbg_buf: a buffer of LEB size used for debugging purposes | 1170 | * @dbg: debugging-related information |
| 1153 | * @old_zroot: old index root - used by 'dbg_check_old_index()' | ||
| 1154 | * @old_zroot_level: old index root level - used by 'dbg_check_old_index()' | ||
| 1155 | * @old_zroot_sqnum: old index root sqnum - used by 'dbg_check_old_index()' | ||
| 1156 | * @failure_mode: failure mode for recovery testing | ||
| 1157 | * @fail_delay: 0=>don't delay, 1=>delay a time, 2=>delay a number of calls | ||
| 1158 | * @fail_timeout: time in jiffies when delay of failure mode expires | ||
| 1159 | * @fail_cnt: current number of calls to failure mode I/O functions | ||
| 1160 | * @fail_cnt_max: number of calls by which to delay failure mode | ||
| 1161 | */ | 1171 | */ |
| 1162 | struct ubifs_info { | 1172 | struct ubifs_info { |
| 1163 | struct super_block *vfs_sb; | 1173 | struct super_block *vfs_sb; |
| @@ -1196,6 +1206,7 @@ struct ubifs_info { | |||
| 1196 | unsigned int big_lpt:1; | 1206 | unsigned int big_lpt:1; |
| 1197 | unsigned int no_chk_data_crc:1; | 1207 | unsigned int no_chk_data_crc:1; |
| 1198 | unsigned int bulk_read:1; | 1208 | unsigned int bulk_read:1; |
| 1209 | unsigned int default_compr:2; | ||
| 1199 | 1210 | ||
| 1200 | struct mutex tnc_mutex; | 1211 | struct mutex tnc_mutex; |
| 1201 | struct ubifs_zbranch zroot; | 1212 | struct ubifs_zbranch zroot; |
| @@ -1212,10 +1223,6 @@ struct ubifs_info { | |||
| 1212 | int ileb_nxt; | 1223 | int ileb_nxt; |
| 1213 | struct rb_root old_idx; | 1224 | struct rb_root old_idx; |
| 1214 | int *bottom_up_buf; | 1225 | int *bottom_up_buf; |
| 1215 | #ifdef CONFIG_UBIFS_FS_DEBUG | ||
| 1216 | int new_ihead_lnum; | ||
| 1217 | int new_ihead_offs; | ||
| 1218 | #endif | ||
| 1219 | 1226 | ||
| 1220 | struct ubifs_mst_node *mst_node; | 1227 | struct ubifs_mst_node *mst_node; |
| 1221 | int mst_offs; | 1228 | int mst_offs; |
| @@ -1237,7 +1244,6 @@ struct ubifs_info { | |||
| 1237 | int main_lebs; | 1244 | int main_lebs; |
| 1238 | int main_first; | 1245 | int main_first; |
| 1239 | long long main_bytes; | 1246 | long long main_bytes; |
| 1240 | int default_compr; | ||
| 1241 | 1247 | ||
| 1242 | uint8_t key_hash_type; | 1248 | uint8_t key_hash_type; |
| 1243 | uint32_t (*key_hash)(const char *str, int len); | 1249 | uint32_t (*key_hash)(const char *str, int len); |
| @@ -1315,8 +1321,8 @@ struct ubifs_info { | |||
| 1315 | void *sbuf; | 1321 | void *sbuf; |
| 1316 | struct list_head idx_gc; | 1322 | struct list_head idx_gc; |
| 1317 | int idx_gc_cnt; | 1323 | int idx_gc_cnt; |
| 1318 | volatile int gc_seq; | 1324 | int gc_seq; |
| 1319 | volatile int gced_lnum; | 1325 | int gced_lnum; |
| 1320 | 1326 | ||
| 1321 | struct list_head infos_list; | 1327 | struct list_head infos_list; |
| 1322 | struct mutex umount_mutex; | 1328 | struct mutex umount_mutex; |
| @@ -1391,21 +1397,7 @@ struct ubifs_info { | |||
| 1391 | struct ubifs_mount_opts mount_opts; | 1397 | struct ubifs_mount_opts mount_opts; |
| 1392 | 1398 | ||
| 1393 | #ifdef CONFIG_UBIFS_FS_DEBUG | 1399 | #ifdef CONFIG_UBIFS_FS_DEBUG |
| 1394 | void *dbg_buf; | 1400 | struct ubifs_debug_info *dbg; |
| 1395 | struct ubifs_zbranch old_zroot; | ||
| 1396 | int old_zroot_level; | ||
| 1397 | unsigned long long old_zroot_sqnum; | ||
| 1398 | int failure_mode; | ||
| 1399 | int fail_delay; | ||
| 1400 | unsigned long fail_timeout; | ||
| 1401 | unsigned int fail_cnt; | ||
| 1402 | unsigned int fail_cnt_max; | ||
| 1403 | long long chk_lpt_sz; | ||
| 1404 | long long chk_lpt_sz2; | ||
| 1405 | long long chk_lpt_wastage; | ||
| 1406 | int chk_lpt_lebs; | ||
| 1407 | int new_nhead_lnum; | ||
| 1408 | int new_nhead_offs; | ||
| 1409 | #endif | 1401 | #endif |
| 1410 | }; | 1402 | }; |
| 1411 | 1403 | ||
| @@ -1505,7 +1497,7 @@ void ubifs_cancel_ino_op(struct ubifs_info *c, struct inode *inode, | |||
| 1505 | long long ubifs_get_free_space(struct ubifs_info *c); | 1497 | long long ubifs_get_free_space(struct ubifs_info *c); |
| 1506 | int ubifs_calc_min_idx_lebs(struct ubifs_info *c); | 1498 | int ubifs_calc_min_idx_lebs(struct ubifs_info *c); |
| 1507 | void ubifs_convert_page_budget(struct ubifs_info *c); | 1499 | void ubifs_convert_page_budget(struct ubifs_info *c); |
| 1508 | long long ubifs_reported_space(const struct ubifs_info *c, uint64_t free); | 1500 | long long ubifs_reported_space(const struct ubifs_info *c, long long free); |
| 1509 | long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs); | 1501 | long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs); |
| 1510 | 1502 | ||
| 1511 | /* find.c */ | 1503 | /* find.c */ |
| @@ -1639,6 +1631,9 @@ void ubifs_add_lpt_dirt(struct ubifs_info *c, int lnum, int dirty); | |||
| 1639 | void ubifs_add_nnode_dirt(struct ubifs_info *c, struct ubifs_nnode *nnode); | 1631 | void ubifs_add_nnode_dirt(struct ubifs_info *c, struct ubifs_nnode *nnode); |
| 1640 | uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits); | 1632 | uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits); |
| 1641 | struct ubifs_nnode *ubifs_first_nnode(struct ubifs_info *c, int *hght); | 1633 | struct ubifs_nnode *ubifs_first_nnode(struct ubifs_info *c, int *hght); |
| 1634 | /* Needed only in debugging code in lpt_commit.c */ | ||
| 1635 | int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf, | ||
| 1636 | struct ubifs_nnode *nnode); | ||
| 1642 | 1637 | ||
| 1643 | /* lpt_commit.c */ | 1638 | /* lpt_commit.c */ |
| 1644 | int ubifs_lpt_start_commit(struct ubifs_info *c); | 1639 | int ubifs_lpt_start_commit(struct ubifs_info *c); |
| @@ -1714,7 +1709,7 @@ long ubifs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); | |||
| 1714 | 1709 | ||
| 1715 | /* compressor.c */ | 1710 | /* compressor.c */ |
| 1716 | int __init ubifs_compressors_init(void); | 1711 | int __init ubifs_compressors_init(void); |
| 1717 | void __exit ubifs_compressors_exit(void); | 1712 | void ubifs_compressors_exit(void); |
| 1718 | void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len, | 1713 | void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len, |
| 1719 | int *compr_type); | 1714 | int *compr_type); |
| 1720 | int ubifs_decompress(const void *buf, int len, void *out, int *out_len, | 1715 | int ubifs_decompress(const void *buf, int len, void *out, int *out_len, |
diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 3795590e152a..0574add2a1e3 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h | |||
| @@ -127,7 +127,7 @@ struct acpi_processor_performance { | |||
| 127 | unsigned int state_count; | 127 | unsigned int state_count; |
| 128 | struct acpi_processor_px *states; | 128 | struct acpi_processor_px *states; |
| 129 | struct acpi_psd_package domain_info; | 129 | struct acpi_psd_package domain_info; |
| 130 | cpumask_t shared_cpu_map; | 130 | cpumask_var_t shared_cpu_map; |
| 131 | unsigned int shared_type; | 131 | unsigned int shared_type; |
| 132 | }; | 132 | }; |
| 133 | 133 | ||
| @@ -172,7 +172,7 @@ struct acpi_processor_throttling { | |||
| 172 | unsigned int state_count; | 172 | unsigned int state_count; |
| 173 | struct acpi_processor_tx_tss *states_tss; | 173 | struct acpi_processor_tx_tss *states_tss; |
| 174 | struct acpi_tsd_package domain_info; | 174 | struct acpi_tsd_package domain_info; |
| 175 | cpumask_t shared_cpu_map; | 175 | cpumask_var_t shared_cpu_map; |
| 176 | int (*acpi_processor_get_throttling) (struct acpi_processor * pr); | 176 | int (*acpi_processor_get_throttling) (struct acpi_processor * pr); |
| 177 | int (*acpi_processor_set_throttling) (struct acpi_processor * pr, | 177 | int (*acpi_processor_set_throttling) (struct acpi_processor * pr, |
| 178 | int state); | 178 | int state); |
diff --git a/include/asm-frv/bitops.h b/include/asm-frv/bitops.h index 39456ba0ec17..287f6f697ce2 100644 --- a/include/asm-frv/bitops.h +++ b/include/asm-frv/bitops.h | |||
| @@ -339,6 +339,19 @@ int __ffs(unsigned long x) | |||
| 339 | return 31 - bit; | 339 | return 31 - bit; |
| 340 | } | 340 | } |
| 341 | 341 | ||
| 342 | /** | ||
| 343 | * __fls - find last (most-significant) set bit in a long word | ||
| 344 | * @word: the word to search | ||
| 345 | * | ||
| 346 | * Undefined if no set bit exists, so code should check against 0 first. | ||
| 347 | */ | ||
| 348 | static inline unsigned long __fls(unsigned long word) | ||
| 349 | { | ||
| 350 | unsigned long bit; | ||
| 351 | asm("scan %1,gr0,%0" : "=r"(bit) : "r"(word)); | ||
| 352 | return bit; | ||
| 353 | } | ||
| 354 | |||
| 342 | /* | 355 | /* |
| 343 | * special slimline version of fls() for calculating ilog2_u32() | 356 | * special slimline version of fls() for calculating ilog2_u32() |
| 344 | * - note: no protection against n == 0 | 357 | * - note: no protection against n == 0 |
diff --git a/include/asm-m32r/bitops.h b/include/asm-m32r/bitops.h index 6dc9b81bf9f3..aaddf0d57603 100644 --- a/include/asm-m32r/bitops.h +++ b/include/asm-m32r/bitops.h | |||
| @@ -251,6 +251,7 @@ static __inline__ int test_and_change_bit(int nr, volatile void * addr) | |||
| 251 | #include <asm-generic/bitops/ffz.h> | 251 | #include <asm-generic/bitops/ffz.h> |
| 252 | #include <asm-generic/bitops/__ffs.h> | 252 | #include <asm-generic/bitops/__ffs.h> |
| 253 | #include <asm-generic/bitops/fls.h> | 253 | #include <asm-generic/bitops/fls.h> |
| 254 | #include <asm-generic/bitops/__fls.h> | ||
| 254 | #include <asm-generic/bitops/fls64.h> | 255 | #include <asm-generic/bitops/fls64.h> |
| 255 | 256 | ||
| 256 | #ifdef __KERNEL__ | 257 | #ifdef __KERNEL__ |
diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h index 3e8106442d5a..9bde784e7bad 100644 --- a/include/asm-m68k/bitops.h +++ b/include/asm-m68k/bitops.h | |||
| @@ -315,6 +315,11 @@ static inline int fls(int x) | |||
| 315 | return 32 - cnt; | 315 | return 32 - cnt; |
| 316 | } | 316 | } |
| 317 | 317 | ||
| 318 | static inline int __fls(int x) | ||
| 319 | { | ||
| 320 | return fls(x) - 1; | ||
| 321 | } | ||
| 322 | |||
| 318 | #include <asm-generic/bitops/fls64.h> | 323 | #include <asm-generic/bitops/fls64.h> |
| 319 | #include <asm-generic/bitops/sched.h> | 324 | #include <asm-generic/bitops/sched.h> |
| 320 | #include <asm-generic/bitops/hweight.h> | 325 | #include <asm-generic/bitops/hweight.h> |
diff --git a/include/asm-mn10300/bitops.h b/include/asm-mn10300/bitops.h index cc6d40c05cf3..0b610f482abb 100644 --- a/include/asm-mn10300/bitops.h +++ b/include/asm-mn10300/bitops.h | |||
| @@ -196,6 +196,17 @@ int fls(int x) | |||
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | /** | 198 | /** |
| 199 | * __fls - find last (most-significant) set bit in a long word | ||
| 200 | * @word: the word to search | ||
| 201 | * | ||
| 202 | * Undefined if no set bit exists, so code should check against 0 first. | ||
| 203 | */ | ||
| 204 | static inline unsigned long __fls(unsigned long word) | ||
| 205 | { | ||
| 206 | return __ilog2_u32(word); | ||
| 207 | } | ||
| 208 | |||
| 209 | /** | ||
| 199 | * ffs - find first bit set | 210 | * ffs - find first bit set |
| 200 | * @x: the word to search | 211 | * @x: the word to search |
| 201 | * | 212 | * |
diff --git a/include/asm-xtensa/bitops.h b/include/asm-xtensa/bitops.h index 23261e8f2e5a..6c3930397bd3 100644 --- a/include/asm-xtensa/bitops.h +++ b/include/asm-xtensa/bitops.h | |||
| @@ -82,6 +82,16 @@ static inline int fls (unsigned int x) | |||
| 82 | return 32 - __cntlz(x); | 82 | return 32 - __cntlz(x); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | /** | ||
| 86 | * __fls - find last (most-significant) set bit in a long word | ||
| 87 | * @word: the word to search | ||
| 88 | * | ||
| 89 | * Undefined if no set bit exists, so code should check against 0 first. | ||
| 90 | */ | ||
| 91 | static inline unsigned long __fls(unsigned long word) | ||
| 92 | { | ||
| 93 | return 31 - __cntlz(word); | ||
| 94 | } | ||
| 85 | #else | 95 | #else |
| 86 | 96 | ||
| 87 | /* Use the generic implementation if we don't have the nsa/nsau instructions. */ | 97 | /* Use the generic implementation if we don't have the nsa/nsau instructions. */ |
| @@ -90,6 +100,7 @@ static inline int fls (unsigned int x) | |||
| 90 | # include <asm-generic/bitops/__ffs.h> | 100 | # include <asm-generic/bitops/__ffs.h> |
| 91 | # include <asm-generic/bitops/ffz.h> | 101 | # include <asm-generic/bitops/ffz.h> |
| 92 | # include <asm-generic/bitops/fls.h> | 102 | # include <asm-generic/bitops/fls.h> |
| 103 | # include <asm-generic/bitops/__fls.h> | ||
| 93 | 104 | ||
| 94 | #endif | 105 | #endif |
| 95 | 106 | ||
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index a08c33a26ca9..2878811c6134 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h | |||
| @@ -137,9 +137,12 @@ extern void bitmap_copy_le(void *dst, const unsigned long *src, int nbits); | |||
| 137 | (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \ | 137 | (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \ |
| 138 | ) | 138 | ) |
| 139 | 139 | ||
| 140 | #define small_const_nbits(nbits) \ | ||
| 141 | (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG) | ||
| 142 | |||
| 140 | static inline void bitmap_zero(unsigned long *dst, int nbits) | 143 | static inline void bitmap_zero(unsigned long *dst, int nbits) |
| 141 | { | 144 | { |
| 142 | if (nbits <= BITS_PER_LONG) | 145 | if (small_const_nbits(nbits)) |
| 143 | *dst = 0UL; | 146 | *dst = 0UL; |
| 144 | else { | 147 | else { |
| 145 | int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); | 148 | int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); |
| @@ -150,7 +153,7 @@ static inline void bitmap_zero(unsigned long *dst, int nbits) | |||
| 150 | static inline void bitmap_fill(unsigned long *dst, int nbits) | 153 | static inline void bitmap_fill(unsigned long *dst, int nbits) |
| 151 | { | 154 | { |
| 152 | size_t nlongs = BITS_TO_LONGS(nbits); | 155 | size_t nlongs = BITS_TO_LONGS(nbits); |
| 153 | if (nlongs > 1) { | 156 | if (!small_const_nbits(nbits)) { |
| 154 | int len = (nlongs - 1) * sizeof(unsigned long); | 157 | int len = (nlongs - 1) * sizeof(unsigned long); |
| 155 | memset(dst, 0xff, len); | 158 | memset(dst, 0xff, len); |
| 156 | } | 159 | } |
| @@ -160,7 +163,7 @@ static inline void bitmap_fill(unsigned long *dst, int nbits) | |||
| 160 | static inline void bitmap_copy(unsigned long *dst, const unsigned long *src, | 163 | static inline void bitmap_copy(unsigned long *dst, const unsigned long *src, |
| 161 | int nbits) | 164 | int nbits) |
| 162 | { | 165 | { |
| 163 | if (nbits <= BITS_PER_LONG) | 166 | if (small_const_nbits(nbits)) |
| 164 | *dst = *src; | 167 | *dst = *src; |
| 165 | else { | 168 | else { |
| 166 | int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); | 169 | int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); |
| @@ -171,7 +174,7 @@ static inline void bitmap_copy(unsigned long *dst, const unsigned long *src, | |||
| 171 | static inline void bitmap_and(unsigned long *dst, const unsigned long *src1, | 174 | static inline void bitmap_and(unsigned long *dst, const unsigned long *src1, |
| 172 | const unsigned long *src2, int nbits) | 175 | const unsigned long *src2, int nbits) |
| 173 | { | 176 | { |
| 174 | if (nbits <= BITS_PER_LONG) | 177 | if (small_const_nbits(nbits)) |
| 175 | *dst = *src1 & *src2; | 178 | *dst = *src1 & *src2; |
| 176 | else | 179 | else |
| 177 | __bitmap_and(dst, src1, src2, nbits); | 180 | __bitmap_and(dst, src1, src2, nbits); |
| @@ -180,7 +183,7 @@ static inline void bitmap_and(unsigned long *dst, const unsigned long *src1, | |||
| 180 | static inline void bitmap_or(unsigned long *dst, const unsigned long *src1, | 183 | static inline void bitmap_or(unsigned long *dst, const unsigned long *src1, |
| 181 | const unsigned long *src2, int nbits) | 184 | const unsigned long *src2, int nbits) |
| 182 | { | 185 | { |
| 183 | if (nbits <= BITS_PER_LONG) | 186 | if (small_const_nbits(nbits)) |
| 184 | *dst = *src1 | *src2; | 187 | *dst = *src1 | *src2; |
| 185 | else | 188 | else |
| 186 | __bitmap_or(dst, src1, src2, nbits); | 189 | __bitmap_or(dst, src1, src2, nbits); |
| @@ -189,7 +192,7 @@ static inline void bitmap_or(unsigned long *dst, const unsigned long *src1, | |||
| 189 | static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1, | 192 | static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1, |
| 190 | const unsigned long *src2, int nbits) | 193 | const unsigned long *src2, int nbits) |
| 191 | { | 194 | { |
| 192 | if (nbits <= BITS_PER_LONG) | 195 | if (small_const_nbits(nbits)) |
| 193 | *dst = *src1 ^ *src2; | 196 | *dst = *src1 ^ *src2; |
| 194 | else | 197 | else |
| 195 | __bitmap_xor(dst, src1, src2, nbits); | 198 | __bitmap_xor(dst, src1, src2, nbits); |
| @@ -198,7 +201,7 @@ static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1, | |||
| 198 | static inline void bitmap_andnot(unsigned long *dst, const unsigned long *src1, | 201 | static inline void bitmap_andnot(unsigned long *dst, const unsigned long *src1, |
| 199 | const unsigned long *src2, int nbits) | 202 | const unsigned long *src2, int nbits) |
| 200 | { | 203 | { |
| 201 | if (nbits <= BITS_PER_LONG) | 204 | if (small_const_nbits(nbits)) |
| 202 | *dst = *src1 & ~(*src2); | 205 | *dst = *src1 & ~(*src2); |
| 203 | else | 206 | else |
| 204 | __bitmap_andnot(dst, src1, src2, nbits); | 207 | __bitmap_andnot(dst, src1, src2, nbits); |
| @@ -207,7 +210,7 @@ static inline void bitmap_andnot(unsigned long *dst, const unsigned long *src1, | |||
| 207 | static inline void bitmap_complement(unsigned long *dst, const unsigned long *src, | 210 | static inline void bitmap_complement(unsigned long *dst, const unsigned long *src, |
| 208 | int nbits) | 211 | int nbits) |
| 209 | { | 212 | { |
| 210 | if (nbits <= BITS_PER_LONG) | 213 | if (small_const_nbits(nbits)) |
| 211 | *dst = ~(*src) & BITMAP_LAST_WORD_MASK(nbits); | 214 | *dst = ~(*src) & BITMAP_LAST_WORD_MASK(nbits); |
| 212 | else | 215 | else |
| 213 | __bitmap_complement(dst, src, nbits); | 216 | __bitmap_complement(dst, src, nbits); |
| @@ -216,7 +219,7 @@ static inline void bitmap_complement(unsigned long *dst, const unsigned long *sr | |||
| 216 | static inline int bitmap_equal(const unsigned long *src1, | 219 | static inline int bitmap_equal(const unsigned long *src1, |
| 217 | const unsigned long *src2, int nbits) | 220 | const unsigned long *src2, int nbits) |
| 218 | { | 221 | { |
| 219 | if (nbits <= BITS_PER_LONG) | 222 | if (small_const_nbits(nbits)) |
| 220 | return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits)); | 223 | return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits)); |
| 221 | else | 224 | else |
| 222 | return __bitmap_equal(src1, src2, nbits); | 225 | return __bitmap_equal(src1, src2, nbits); |
| @@ -225,7 +228,7 @@ static inline int bitmap_equal(const unsigned long *src1, | |||
| 225 | static inline int bitmap_intersects(const unsigned long *src1, | 228 | static inline int bitmap_intersects(const unsigned long *src1, |
| 226 | const unsigned long *src2, int nbits) | 229 | const unsigned long *src2, int nbits) |
| 227 | { | 230 | { |
| 228 | if (nbits <= BITS_PER_LONG) | 231 | if (small_const_nbits(nbits)) |
| 229 | return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0; | 232 | return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0; |
| 230 | else | 233 | else |
| 231 | return __bitmap_intersects(src1, src2, nbits); | 234 | return __bitmap_intersects(src1, src2, nbits); |
| @@ -234,7 +237,7 @@ static inline int bitmap_intersects(const unsigned long *src1, | |||
| 234 | static inline int bitmap_subset(const unsigned long *src1, | 237 | static inline int bitmap_subset(const unsigned long *src1, |
| 235 | const unsigned long *src2, int nbits) | 238 | const unsigned long *src2, int nbits) |
| 236 | { | 239 | { |
| 237 | if (nbits <= BITS_PER_LONG) | 240 | if (small_const_nbits(nbits)) |
| 238 | return ! ((*src1 & ~(*src2)) & BITMAP_LAST_WORD_MASK(nbits)); | 241 | return ! ((*src1 & ~(*src2)) & BITMAP_LAST_WORD_MASK(nbits)); |
| 239 | else | 242 | else |
| 240 | return __bitmap_subset(src1, src2, nbits); | 243 | return __bitmap_subset(src1, src2, nbits); |
| @@ -242,7 +245,7 @@ static inline int bitmap_subset(const unsigned long *src1, | |||
| 242 | 245 | ||
| 243 | static inline int bitmap_empty(const unsigned long *src, int nbits) | 246 | static inline int bitmap_empty(const unsigned long *src, int nbits) |
| 244 | { | 247 | { |
| 245 | if (nbits <= BITS_PER_LONG) | 248 | if (small_const_nbits(nbits)) |
| 246 | return ! (*src & BITMAP_LAST_WORD_MASK(nbits)); | 249 | return ! (*src & BITMAP_LAST_WORD_MASK(nbits)); |
| 247 | else | 250 | else |
| 248 | return __bitmap_empty(src, nbits); | 251 | return __bitmap_empty(src, nbits); |
| @@ -250,7 +253,7 @@ static inline int bitmap_empty(const unsigned long *src, int nbits) | |||
| 250 | 253 | ||
| 251 | static inline int bitmap_full(const unsigned long *src, int nbits) | 254 | static inline int bitmap_full(const unsigned long *src, int nbits) |
| 252 | { | 255 | { |
| 253 | if (nbits <= BITS_PER_LONG) | 256 | if (small_const_nbits(nbits)) |
| 254 | return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits)); | 257 | return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits)); |
| 255 | else | 258 | else |
| 256 | return __bitmap_full(src, nbits); | 259 | return __bitmap_full(src, nbits); |
| @@ -258,7 +261,7 @@ static inline int bitmap_full(const unsigned long *src, int nbits) | |||
| 258 | 261 | ||
| 259 | static inline int bitmap_weight(const unsigned long *src, int nbits) | 262 | static inline int bitmap_weight(const unsigned long *src, int nbits) |
| 260 | { | 263 | { |
| 261 | if (nbits <= BITS_PER_LONG) | 264 | if (small_const_nbits(nbits)) |
| 262 | return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits)); | 265 | return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits)); |
| 263 | return __bitmap_weight(src, nbits); | 266 | return __bitmap_weight(src, nbits); |
| 264 | } | 267 | } |
| @@ -266,7 +269,7 @@ static inline int bitmap_weight(const unsigned long *src, int nbits) | |||
| 266 | static inline void bitmap_shift_right(unsigned long *dst, | 269 | static inline void bitmap_shift_right(unsigned long *dst, |
| 267 | const unsigned long *src, int n, int nbits) | 270 | const unsigned long *src, int n, int nbits) |
| 268 | { | 271 | { |
| 269 | if (nbits <= BITS_PER_LONG) | 272 | if (small_const_nbits(nbits)) |
| 270 | *dst = *src >> n; | 273 | *dst = *src >> n; |
| 271 | else | 274 | else |
| 272 | __bitmap_shift_right(dst, src, n, nbits); | 275 | __bitmap_shift_right(dst, src, n, nbits); |
| @@ -275,7 +278,7 @@ static inline void bitmap_shift_right(unsigned long *dst, | |||
| 275 | static inline void bitmap_shift_left(unsigned long *dst, | 278 | static inline void bitmap_shift_left(unsigned long *dst, |
| 276 | const unsigned long *src, int n, int nbits) | 279 | const unsigned long *src, int n, int nbits) |
| 277 | { | 280 | { |
| 278 | if (nbits <= BITS_PER_LONG) | 281 | if (small_const_nbits(nbits)) |
| 279 | *dst = (*src << n) & BITMAP_LAST_WORD_MASK(nbits); | 282 | *dst = (*src << n) & BITMAP_LAST_WORD_MASK(nbits); |
| 280 | else | 283 | else |
| 281 | __bitmap_shift_left(dst, src, n, nbits); | 284 | __bitmap_shift_left(dst, src, n, nbits); |
diff --git a/include/linux/bitops.h b/include/linux/bitops.h index 024f2b027244..61829139795a 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h | |||
| @@ -134,9 +134,20 @@ extern unsigned long find_first_bit(const unsigned long *addr, | |||
| 134 | */ | 134 | */ |
| 135 | extern unsigned long find_first_zero_bit(const unsigned long *addr, | 135 | extern unsigned long find_first_zero_bit(const unsigned long *addr, |
| 136 | unsigned long size); | 136 | unsigned long size); |
| 137 | |||
| 138 | #endif /* CONFIG_GENERIC_FIND_FIRST_BIT */ | 137 | #endif /* CONFIG_GENERIC_FIND_FIRST_BIT */ |
| 139 | 138 | ||
| 139 | #ifdef CONFIG_GENERIC_FIND_LAST_BIT | ||
| 140 | /** | ||
| 141 | * find_last_bit - find the last set bit in a memory region | ||
| 142 | * @addr: The address to start the search at | ||
| 143 | * @size: The maximum size to search | ||
| 144 | * | ||
| 145 | * Returns the bit number of the first set bit, or size. | ||
| 146 | */ | ||
| 147 | extern unsigned long find_last_bit(const unsigned long *addr, | ||
| 148 | unsigned long size); | ||
| 149 | #endif /* CONFIG_GENERIC_FIND_LAST_BIT */ | ||
| 150 | |||
| 140 | #ifdef CONFIG_GENERIC_FIND_NEXT_BIT | 151 | #ifdef CONFIG_GENERIC_FIND_NEXT_BIT |
| 141 | 152 | ||
| 142 | /** | 153 | /** |
diff --git a/include/linux/compiler-gcc3.h b/include/linux/compiler-gcc3.h index 2befe6513ce4..8005effc04f1 100644 --- a/include/linux/compiler-gcc3.h +++ b/include/linux/compiler-gcc3.h | |||
| @@ -2,6 +2,10 @@ | |||
| 2 | #error "Please don't include <linux/compiler-gcc3.h> directly, include <linux/compiler.h> instead." | 2 | #error "Please don't include <linux/compiler-gcc3.h> directly, include <linux/compiler.h> instead." |
| 3 | #endif | 3 | #endif |
| 4 | 4 | ||
| 5 | #if __GNUC_MINOR__ < 2 | ||
| 6 | # error Sorry, your compiler is too old - please upgrade it. | ||
| 7 | #endif | ||
| 8 | |||
| 5 | #if __GNUC_MINOR__ >= 3 | 9 | #if __GNUC_MINOR__ >= 3 |
| 6 | # define __used __attribute__((__used__)) | 10 | # define __used __attribute__((__used__)) |
| 7 | #else | 11 | #else |
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index d4bf52603e6b..9f315382610b 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h | |||
| @@ -144,6 +144,7 @@ | |||
| 144 | typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; | 144 | typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; |
| 145 | extern cpumask_t _unused_cpumask_arg_; | 145 | extern cpumask_t _unused_cpumask_arg_; |
| 146 | 146 | ||
| 147 | #ifndef CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS | ||
| 147 | #define cpu_set(cpu, dst) __cpu_set((cpu), &(dst)) | 148 | #define cpu_set(cpu, dst) __cpu_set((cpu), &(dst)) |
| 148 | static inline void __cpu_set(int cpu, volatile cpumask_t *dstp) | 149 | static inline void __cpu_set(int cpu, volatile cpumask_t *dstp) |
| 149 | { | 150 | { |
| @@ -267,6 +268,26 @@ static inline void __cpus_shift_left(cpumask_t *dstp, | |||
| 267 | { | 268 | { |
| 268 | bitmap_shift_left(dstp->bits, srcp->bits, n, nbits); | 269 | bitmap_shift_left(dstp->bits, srcp->bits, n, nbits); |
| 269 | } | 270 | } |
| 271 | #endif /* !CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS */ | ||
| 272 | |||
| 273 | /** | ||
| 274 | * to_cpumask - convert an NR_CPUS bitmap to a struct cpumask * | ||
| 275 | * @bitmap: the bitmap | ||
| 276 | * | ||
| 277 | * There are a few places where cpumask_var_t isn't appropriate and | ||
| 278 | * static cpumasks must be used (eg. very early boot), yet we don't | ||
| 279 | * expose the definition of 'struct cpumask'. | ||
| 280 | * | ||
| 281 | * This does the conversion, and can be used as a constant initializer. | ||
| 282 | */ | ||
| 283 | #define to_cpumask(bitmap) \ | ||
| 284 | ((struct cpumask *)(1 ? (bitmap) \ | ||
| 285 | : (void *)sizeof(__check_is_bitmap(bitmap)))) | ||
| 286 | |||
| 287 | static inline int __check_is_bitmap(const unsigned long *bitmap) | ||
| 288 | { | ||
| 289 | return 1; | ||
| 290 | } | ||
| 270 | 291 | ||
| 271 | /* | 292 | /* |
| 272 | * Special-case data structure for "single bit set only" constant CPU masks. | 293 | * Special-case data structure for "single bit set only" constant CPU masks. |
| @@ -278,13 +299,14 @@ static inline void __cpus_shift_left(cpumask_t *dstp, | |||
| 278 | extern const unsigned long | 299 | extern const unsigned long |
| 279 | cpu_bit_bitmap[BITS_PER_LONG+1][BITS_TO_LONGS(NR_CPUS)]; | 300 | cpu_bit_bitmap[BITS_PER_LONG+1][BITS_TO_LONGS(NR_CPUS)]; |
| 280 | 301 | ||
| 281 | static inline const cpumask_t *get_cpu_mask(unsigned int cpu) | 302 | static inline const struct cpumask *get_cpu_mask(unsigned int cpu) |
| 282 | { | 303 | { |
| 283 | const unsigned long *p = cpu_bit_bitmap[1 + cpu % BITS_PER_LONG]; | 304 | const unsigned long *p = cpu_bit_bitmap[1 + cpu % BITS_PER_LONG]; |
| 284 | p -= cpu / BITS_PER_LONG; | 305 | p -= cpu / BITS_PER_LONG; |
| 285 | return (const cpumask_t *)p; | 306 | return to_cpumask(p); |
| 286 | } | 307 | } |
| 287 | 308 | ||
| 309 | #ifndef CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS | ||
| 288 | /* | 310 | /* |
| 289 | * In cases where we take the address of the cpumask immediately, | 311 | * In cases where we take the address of the cpumask immediately, |
| 290 | * gcc optimizes it out (it's a constant) and there's no huge stack | 312 | * gcc optimizes it out (it's a constant) and there's no huge stack |
| @@ -370,19 +392,22 @@ static inline void __cpus_fold(cpumask_t *dstp, const cpumask_t *origp, | |||
| 370 | { | 392 | { |
| 371 | bitmap_fold(dstp->bits, origp->bits, sz, nbits); | 393 | bitmap_fold(dstp->bits, origp->bits, sz, nbits); |
| 372 | } | 394 | } |
| 395 | #endif /* !CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS */ | ||
| 373 | 396 | ||
| 374 | #if NR_CPUS == 1 | 397 | #if NR_CPUS == 1 |
| 375 | 398 | ||
| 376 | #define nr_cpu_ids 1 | 399 | #define nr_cpu_ids 1 |
| 400 | #ifndef CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS | ||
| 377 | #define first_cpu(src) ({ (void)(src); 0; }) | 401 | #define first_cpu(src) ({ (void)(src); 0; }) |
| 378 | #define next_cpu(n, src) ({ (void)(src); 1; }) | 402 | #define next_cpu(n, src) ({ (void)(src); 1; }) |
| 379 | #define any_online_cpu(mask) 0 | 403 | #define any_online_cpu(mask) 0 |
| 380 | #define for_each_cpu_mask(cpu, mask) \ | 404 | #define for_each_cpu_mask(cpu, mask) \ |
| 381 | for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask) | 405 | for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask) |
| 382 | 406 | #endif /* !CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS */ | |
| 383 | #else /* NR_CPUS > 1 */ | 407 | #else /* NR_CPUS > 1 */ |
| 384 | 408 | ||
| 385 | extern int nr_cpu_ids; | 409 | extern int nr_cpu_ids; |
| 410 | #ifndef CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS | ||
| 386 | int __first_cpu(const cpumask_t *srcp); | 411 | int __first_cpu(const cpumask_t *srcp); |
| 387 | int __next_cpu(int n, const cpumask_t *srcp); | 412 | int __next_cpu(int n, const cpumask_t *srcp); |
| 388 | int __any_online_cpu(const cpumask_t *mask); | 413 | int __any_online_cpu(const cpumask_t *mask); |
| @@ -394,8 +419,10 @@ int __any_online_cpu(const cpumask_t *mask); | |||
| 394 | for ((cpu) = -1; \ | 419 | for ((cpu) = -1; \ |
| 395 | (cpu) = next_cpu((cpu), (mask)), \ | 420 | (cpu) = next_cpu((cpu), (mask)), \ |
| 396 | (cpu) < NR_CPUS; ) | 421 | (cpu) < NR_CPUS; ) |
| 422 | #endif /* !CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS */ | ||
| 397 | #endif | 423 | #endif |
| 398 | 424 | ||
| 425 | #ifndef CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS | ||
| 399 | #if NR_CPUS <= 64 | 426 | #if NR_CPUS <= 64 |
| 400 | 427 | ||
| 401 | #define next_cpu_nr(n, src) next_cpu(n, src) | 428 | #define next_cpu_nr(n, src) next_cpu(n, src) |
| @@ -413,77 +440,67 @@ int __next_cpu_nr(int n, const cpumask_t *srcp); | |||
| 413 | (cpu) < nr_cpu_ids; ) | 440 | (cpu) < nr_cpu_ids; ) |
| 414 | 441 | ||
| 415 | #endif /* NR_CPUS > 64 */ | 442 | #endif /* NR_CPUS > 64 */ |
| 443 | #endif /* !CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS */ | ||
| 416 | 444 | ||
| 417 | /* | 445 | /* |
| 418 | * The following particular system cpumasks and operations manage | 446 | * The following particular system cpumasks and operations manage |
| 419 | * possible, present, active and online cpus. Each of them is a fixed size | 447 | * possible, present, active and online cpus. |
| 420 | * bitmap of size NR_CPUS. | ||
| 421 | * | 448 | * |
| 422 | * #ifdef CONFIG_HOTPLUG_CPU | 449 | * cpu_possible_mask- has bit 'cpu' set iff cpu is populatable |
| 423 | * cpu_possible_map - has bit 'cpu' set iff cpu is populatable | 450 | * cpu_present_mask - has bit 'cpu' set iff cpu is populated |
| 424 | * cpu_present_map - has bit 'cpu' set iff cpu is populated | 451 | * cpu_online_mask - has bit 'cpu' set iff cpu available to scheduler |
| 425 | * cpu_online_map - has bit 'cpu' set iff cpu available to scheduler | 452 | * cpu_active_mask - has bit 'cpu' set iff cpu available to migration |
| 426 | * cpu_active_map - has bit 'cpu' set iff cpu available to migration | ||
| 427 | * #else | ||
| 428 | * cpu_possible_map - has bit 'cpu' set iff cpu is populated | ||
| 429 | * cpu_present_map - copy of cpu_possible_map | ||
| 430 | * cpu_online_map - has bit 'cpu' set iff cpu available to scheduler | ||
| 431 | * #endif | ||
| 432 | * | 453 | * |
| 433 | * In either case, NR_CPUS is fixed at compile time, as the static | 454 | * If !CONFIG_HOTPLUG_CPU, present == possible, and active == online. |
| 434 | * size of these bitmaps. The cpu_possible_map is fixed at boot | ||
| 435 | * time, as the set of CPU id's that it is possible might ever | ||
| 436 | * be plugged in at anytime during the life of that system boot. | ||
| 437 | * The cpu_present_map is dynamic(*), representing which CPUs | ||
| 438 | * are currently plugged in. And cpu_online_map is the dynamic | ||
| 439 | * subset of cpu_present_map, indicating those CPUs available | ||
| 440 | * for scheduling. | ||
| 441 | * | 455 | * |
| 442 | * If HOTPLUG is enabled, then cpu_possible_map is forced to have | 456 | * The cpu_possible_mask is fixed at boot time, as the set of CPU id's |
| 457 | * that it is possible might ever be plugged in at anytime during the | ||
| 458 | * life of that system boot. The cpu_present_mask is dynamic(*), | ||
| 459 | * representing which CPUs are currently plugged in. And | ||
| 460 | * cpu_online_mask is the dynamic subset of cpu_present_mask, | ||
| 461 | * indicating those CPUs available for scheduling. | ||
| 462 | * | ||
| 463 | * If HOTPLUG is enabled, then cpu_possible_mask is forced to have | ||
| 443 | * all NR_CPUS bits set, otherwise it is just the set of CPUs that | 464 | * all NR_CPUS bits set, otherwise it is just the set of CPUs that |
| 444 | * ACPI reports present at boot. | 465 | * ACPI reports present at boot. |
| 445 | * | 466 | * |
| 446 | * If HOTPLUG is enabled, then cpu_present_map varies dynamically, | 467 | * If HOTPLUG is enabled, then cpu_present_mask varies dynamically, |
| 447 | * depending on what ACPI reports as currently plugged in, otherwise | 468 | * depending on what ACPI reports as currently plugged in, otherwise |
| 448 | * cpu_present_map is just a copy of cpu_possible_map. | 469 | * cpu_present_mask is just a copy of cpu_possible_mask. |
| 449 | * | 470 | * |
| 450 | * (*) Well, cpu_present_map is dynamic in the hotplug case. If not | 471 | * (*) Well, cpu_present_mask is dynamic in the hotplug case. If not |
| 451 | * hotplug, it's a copy of cpu_possible_map, hence fixed at boot. | 472 | * hotplug, it's a copy of cpu_possible_mask, hence fixed at boot. |
| 452 | * | 473 | * |
| 453 | * Subtleties: | 474 | * Subtleties: |
| 454 | * 1) UP arch's (NR_CPUS == 1, CONFIG_SMP not defined) hardcode | 475 | * 1) UP arch's (NR_CPUS == 1, CONFIG_SMP not defined) hardcode |
| 455 | * assumption that their single CPU is online. The UP | 476 | * assumption that their single CPU is online. The UP |
| 456 | * cpu_{online,possible,present}_maps are placebos. Changing them | 477 | * cpu_{online,possible,present}_masks are placebos. Changing them |
| 457 | * will have no useful affect on the following num_*_cpus() | 478 | * will have no useful affect on the following num_*_cpus() |
| 458 | * and cpu_*() macros in the UP case. This ugliness is a UP | 479 | * and cpu_*() macros in the UP case. This ugliness is a UP |
| 459 | * optimization - don't waste any instructions or memory references | 480 | * optimization - don't waste any instructions or memory references |
| 460 | * asking if you're online or how many CPUs there are if there is | 481 | * asking if you're online or how many CPUs there are if there is |
| 461 | * only one CPU. | 482 | * only one CPU. |
| 462 | * 2) Most SMP arch's #define some of these maps to be some | ||
| 463 | * other map specific to that arch. Therefore, the following | ||
| 464 | * must be #define macros, not inlines. To see why, examine | ||
| 465 | * the assembly code produced by the following. Note that | ||
| 466 | * set1() writes phys_x_map, but set2() writes x_map: | ||
| 467 | * int x_map, phys_x_map; | ||
| 468 | * #define set1(a) x_map = a | ||
| 469 | * inline void set2(int a) { x_map = a; } | ||
| 470 | * #define x_map phys_x_map | ||
| 471 | * main(){ set1(3); set2(5); } | ||
| 472 | */ | 483 | */ |
| 473 | 484 | ||
| 474 | extern cpumask_t cpu_possible_map; | 485 | extern const struct cpumask *const cpu_possible_mask; |
| 475 | extern cpumask_t cpu_online_map; | 486 | extern const struct cpumask *const cpu_online_mask; |
| 476 | extern cpumask_t cpu_present_map; | 487 | extern const struct cpumask *const cpu_present_mask; |
| 477 | extern cpumask_t cpu_active_map; | 488 | extern const struct cpumask *const cpu_active_mask; |
| 489 | |||
| 490 | /* These strip const, as traditionally they weren't const. */ | ||
| 491 | #define cpu_possible_map (*(cpumask_t *)cpu_possible_mask) | ||
| 492 | #define cpu_online_map (*(cpumask_t *)cpu_online_mask) | ||
| 493 | #define cpu_present_map (*(cpumask_t *)cpu_present_mask) | ||
| 494 | #define cpu_active_map (*(cpumask_t *)cpu_active_mask) | ||
| 478 | 495 | ||
| 479 | #if NR_CPUS > 1 | 496 | #if NR_CPUS > 1 |
| 480 | #define num_online_cpus() cpus_weight_nr(cpu_online_map) | 497 | #define num_online_cpus() cpumask_weight(cpu_online_mask) |
| 481 | #define num_possible_cpus() cpus_weight_nr(cpu_possible_map) | 498 | #define num_possible_cpus() cpumask_weight(cpu_possible_mask) |
| 482 | #define num_present_cpus() cpus_weight_nr(cpu_present_map) | 499 | #define num_present_cpus() cpumask_weight(cpu_present_mask) |
| 483 | #define cpu_online(cpu) cpu_isset((cpu), cpu_online_map) | 500 | #define cpu_online(cpu) cpumask_test_cpu((cpu), cpu_online_mask) |
| 484 | #define cpu_possible(cpu) cpu_isset((cpu), cpu_possible_map) | 501 | #define cpu_possible(cpu) cpumask_test_cpu((cpu), cpu_possible_mask) |
| 485 | #define cpu_present(cpu) cpu_isset((cpu), cpu_present_map) | 502 | #define cpu_present(cpu) cpumask_test_cpu((cpu), cpu_present_mask) |
| 486 | #define cpu_active(cpu) cpu_isset((cpu), cpu_active_map) | 503 | #define cpu_active(cpu) cpumask_test_cpu((cpu), cpu_active_mask) |
| 487 | #else | 504 | #else |
| 488 | #define num_online_cpus() 1 | 505 | #define num_online_cpus() 1 |
| 489 | #define num_possible_cpus() 1 | 506 | #define num_possible_cpus() 1 |
| @@ -496,10 +513,6 @@ extern cpumask_t cpu_active_map; | |||
| 496 | 513 | ||
| 497 | #define cpu_is_offline(cpu) unlikely(!cpu_online(cpu)) | 514 | #define cpu_is_offline(cpu) unlikely(!cpu_online(cpu)) |
| 498 | 515 | ||
| 499 | #define for_each_possible_cpu(cpu) for_each_cpu_mask_nr((cpu), cpu_possible_map) | ||
| 500 | #define for_each_online_cpu(cpu) for_each_cpu_mask_nr((cpu), cpu_online_map) | ||
| 501 | #define for_each_present_cpu(cpu) for_each_cpu_mask_nr((cpu), cpu_present_map) | ||
| 502 | |||
| 503 | /* These are the new versions of the cpumask operators: passed by pointer. | 516 | /* These are the new versions of the cpumask operators: passed by pointer. |
| 504 | * The older versions will be implemented in terms of these, then deleted. */ | 517 | * The older versions will be implemented in terms of these, then deleted. */ |
| 505 | #define cpumask_bits(maskp) ((maskp)->bits) | 518 | #define cpumask_bits(maskp) ((maskp)->bits) |
| @@ -687,7 +700,7 @@ static inline void cpumask_clear_cpu(int cpu, struct cpumask *dstp) | |||
| 687 | * No static inline type checking - see Subtlety (1) above. | 700 | * No static inline type checking - see Subtlety (1) above. |
| 688 | */ | 701 | */ |
| 689 | #define cpumask_test_cpu(cpu, cpumask) \ | 702 | #define cpumask_test_cpu(cpu, cpumask) \ |
| 690 | test_bit(cpumask_check(cpu), (cpumask)->bits) | 703 | test_bit(cpumask_check(cpu), cpumask_bits((cpumask))) |
| 691 | 704 | ||
| 692 | /** | 705 | /** |
| 693 | * cpumask_test_and_set_cpu - atomically test and set a cpu in a cpumask | 706 | * cpumask_test_and_set_cpu - atomically test and set a cpu in a cpumask |
| @@ -930,7 +943,7 @@ static inline void cpumask_copy(struct cpumask *dstp, | |||
| 930 | static inline int cpumask_scnprintf(char *buf, int len, | 943 | static inline int cpumask_scnprintf(char *buf, int len, |
| 931 | const struct cpumask *srcp) | 944 | const struct cpumask *srcp) |
| 932 | { | 945 | { |
| 933 | return bitmap_scnprintf(buf, len, srcp->bits, nr_cpumask_bits); | 946 | return bitmap_scnprintf(buf, len, cpumask_bits(srcp), nr_cpumask_bits); |
| 934 | } | 947 | } |
| 935 | 948 | ||
| 936 | /** | 949 | /** |
| @@ -944,7 +957,7 @@ static inline int cpumask_scnprintf(char *buf, int len, | |||
| 944 | static inline int cpumask_parse_user(const char __user *buf, int len, | 957 | static inline int cpumask_parse_user(const char __user *buf, int len, |
| 945 | struct cpumask *dstp) | 958 | struct cpumask *dstp) |
| 946 | { | 959 | { |
| 947 | return bitmap_parse_user(buf, len, dstp->bits, nr_cpumask_bits); | 960 | return bitmap_parse_user(buf, len, cpumask_bits(dstp), nr_cpumask_bits); |
| 948 | } | 961 | } |
| 949 | 962 | ||
| 950 | /** | 963 | /** |
| @@ -959,7 +972,8 @@ static inline int cpumask_parse_user(const char __user *buf, int len, | |||
| 959 | static inline int cpulist_scnprintf(char *buf, int len, | 972 | static inline int cpulist_scnprintf(char *buf, int len, |
| 960 | const struct cpumask *srcp) | 973 | const struct cpumask *srcp) |
| 961 | { | 974 | { |
| 962 | return bitmap_scnlistprintf(buf, len, srcp->bits, nr_cpumask_bits); | 975 | return bitmap_scnlistprintf(buf, len, cpumask_bits(srcp), |
| 976 | nr_cpumask_bits); | ||
| 963 | } | 977 | } |
| 964 | 978 | ||
| 965 | /** | 979 | /** |
| @@ -972,26 +986,7 @@ static inline int cpulist_scnprintf(char *buf, int len, | |||
| 972 | */ | 986 | */ |
| 973 | static inline int cpulist_parse(const char *buf, struct cpumask *dstp) | 987 | static inline int cpulist_parse(const char *buf, struct cpumask *dstp) |
| 974 | { | 988 | { |
| 975 | return bitmap_parselist(buf, dstp->bits, nr_cpumask_bits); | 989 | return bitmap_parselist(buf, cpumask_bits(dstp), nr_cpumask_bits); |
| 976 | } | ||
| 977 | |||
| 978 | /** | ||
| 979 | * to_cpumask - convert an NR_CPUS bitmap to a struct cpumask * | ||
| 980 | * @bitmap: the bitmap | ||
| 981 | * | ||
| 982 | * There are a few places where cpumask_var_t isn't appropriate and | ||
| 983 | * static cpumasks must be used (eg. very early boot), yet we don't | ||
| 984 | * expose the definition of 'struct cpumask'. | ||
| 985 | * | ||
| 986 | * This does the conversion, and can be used as a constant initializer. | ||
| 987 | */ | ||
| 988 | #define to_cpumask(bitmap) \ | ||
| 989 | ((struct cpumask *)(1 ? (bitmap) \ | ||
| 990 | : (void *)sizeof(__check_is_bitmap(bitmap)))) | ||
| 991 | |||
| 992 | static inline int __check_is_bitmap(const unsigned long *bitmap) | ||
| 993 | { | ||
| 994 | return 1; | ||
| 995 | } | 990 | } |
| 996 | 991 | ||
| 997 | /** | 992 | /** |
| @@ -1025,6 +1020,7 @@ static inline size_t cpumask_size(void) | |||
| 1025 | #ifdef CONFIG_CPUMASK_OFFSTACK | 1020 | #ifdef CONFIG_CPUMASK_OFFSTACK |
| 1026 | typedef struct cpumask *cpumask_var_t; | 1021 | typedef struct cpumask *cpumask_var_t; |
| 1027 | 1022 | ||
| 1023 | bool alloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, int node); | ||
| 1028 | bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags); | 1024 | bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags); |
| 1029 | void alloc_bootmem_cpumask_var(cpumask_var_t *mask); | 1025 | void alloc_bootmem_cpumask_var(cpumask_var_t *mask); |
| 1030 | void free_cpumask_var(cpumask_var_t mask); | 1026 | void free_cpumask_var(cpumask_var_t mask); |
| @@ -1038,6 +1034,12 @@ static inline bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags) | |||
| 1038 | return true; | 1034 | return true; |
| 1039 | } | 1035 | } |
| 1040 | 1036 | ||
| 1037 | static inline bool alloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, | ||
| 1038 | int node) | ||
| 1039 | { | ||
| 1040 | return true; | ||
| 1041 | } | ||
| 1042 | |||
| 1041 | static inline void alloc_bootmem_cpumask_var(cpumask_var_t *mask) | 1043 | static inline void alloc_bootmem_cpumask_var(cpumask_var_t *mask) |
| 1042 | { | 1044 | { |
| 1043 | } | 1045 | } |
| @@ -1051,12 +1053,6 @@ static inline void free_bootmem_cpumask_var(cpumask_var_t mask) | |||
| 1051 | } | 1053 | } |
| 1052 | #endif /* CONFIG_CPUMASK_OFFSTACK */ | 1054 | #endif /* CONFIG_CPUMASK_OFFSTACK */ |
| 1053 | 1055 | ||
| 1054 | /* The pointer versions of the maps, these will become the primary versions. */ | ||
| 1055 | #define cpu_possible_mask ((const struct cpumask *)&cpu_possible_map) | ||
| 1056 | #define cpu_online_mask ((const struct cpumask *)&cpu_online_map) | ||
| 1057 | #define cpu_present_mask ((const struct cpumask *)&cpu_present_map) | ||
| 1058 | #define cpu_active_mask ((const struct cpumask *)&cpu_active_map) | ||
| 1059 | |||
| 1060 | /* It's common to want to use cpu_all_mask in struct member initializers, | 1056 | /* It's common to want to use cpu_all_mask in struct member initializers, |
| 1061 | * so it has to refer to an address rather than a pointer. */ | 1057 | * so it has to refer to an address rather than a pointer. */ |
| 1062 | extern const DECLARE_BITMAP(cpu_all_bits, NR_CPUS); | 1058 | extern const DECLARE_BITMAP(cpu_all_bits, NR_CPUS); |
| @@ -1065,51 +1061,16 @@ extern const DECLARE_BITMAP(cpu_all_bits, NR_CPUS); | |||
| 1065 | /* First bits of cpu_bit_bitmap are in fact unset. */ | 1061 | /* First bits of cpu_bit_bitmap are in fact unset. */ |
| 1066 | #define cpu_none_mask to_cpumask(cpu_bit_bitmap[0]) | 1062 | #define cpu_none_mask to_cpumask(cpu_bit_bitmap[0]) |
| 1067 | 1063 | ||
| 1068 | /* Wrappers for arch boot code to manipulate normally-constant masks */ | 1064 | #define for_each_possible_cpu(cpu) for_each_cpu((cpu), cpu_possible_mask) |
| 1069 | static inline void set_cpu_possible(unsigned int cpu, bool possible) | 1065 | #define for_each_online_cpu(cpu) for_each_cpu((cpu), cpu_online_mask) |
| 1070 | { | 1066 | #define for_each_present_cpu(cpu) for_each_cpu((cpu), cpu_present_mask) |
| 1071 | if (possible) | ||
| 1072 | cpumask_set_cpu(cpu, &cpu_possible_map); | ||
| 1073 | else | ||
| 1074 | cpumask_clear_cpu(cpu, &cpu_possible_map); | ||
| 1075 | } | ||
| 1076 | |||
| 1077 | static inline void set_cpu_present(unsigned int cpu, bool present) | ||
| 1078 | { | ||
| 1079 | if (present) | ||
| 1080 | cpumask_set_cpu(cpu, &cpu_present_map); | ||
| 1081 | else | ||
| 1082 | cpumask_clear_cpu(cpu, &cpu_present_map); | ||
| 1083 | } | ||
| 1084 | |||
| 1085 | static inline void set_cpu_online(unsigned int cpu, bool online) | ||
| 1086 | { | ||
| 1087 | if (online) | ||
| 1088 | cpumask_set_cpu(cpu, &cpu_online_map); | ||
| 1089 | else | ||
| 1090 | cpumask_clear_cpu(cpu, &cpu_online_map); | ||
| 1091 | } | ||
| 1092 | 1067 | ||
| 1093 | static inline void set_cpu_active(unsigned int cpu, bool active) | 1068 | /* Wrappers for arch boot code to manipulate normally-constant masks */ |
| 1094 | { | 1069 | void set_cpu_possible(unsigned int cpu, bool possible); |
| 1095 | if (active) | 1070 | void set_cpu_present(unsigned int cpu, bool present); |
| 1096 | cpumask_set_cpu(cpu, &cpu_active_map); | 1071 | void set_cpu_online(unsigned int cpu, bool online); |
| 1097 | else | 1072 | void set_cpu_active(unsigned int cpu, bool active); |
| 1098 | cpumask_clear_cpu(cpu, &cpu_active_map); | 1073 | void init_cpu_present(const struct cpumask *src); |
| 1099 | } | 1074 | void init_cpu_possible(const struct cpumask *src); |
| 1100 | 1075 | void init_cpu_online(const struct cpumask *src); | |
| 1101 | static inline void init_cpu_present(const struct cpumask *src) | ||
| 1102 | { | ||
| 1103 | cpumask_copy(&cpu_present_map, src); | ||
| 1104 | } | ||
| 1105 | |||
| 1106 | static inline void init_cpu_possible(const struct cpumask *src) | ||
| 1107 | { | ||
| 1108 | cpumask_copy(&cpu_possible_map, src); | ||
| 1109 | } | ||
| 1110 | |||
| 1111 | static inline void init_cpu_online(const struct cpumask *src) | ||
| 1112 | { | ||
| 1113 | cpumask_copy(&cpu_online_map, src); | ||
| 1114 | } | ||
| 1115 | #endif /* __LINUX_CPUMASK_H */ | 1076 | #endif /* __LINUX_CPUMASK_H */ |
diff --git a/include/linux/dma_remapping.h b/include/linux/dma_remapping.h index 952df39c989d..136f170cecc2 100644 --- a/include/linux/dma_remapping.h +++ b/include/linux/dma_remapping.h | |||
| @@ -9,148 +9,16 @@ | |||
| 9 | #define VTD_PAGE_MASK (((u64)-1) << VTD_PAGE_SHIFT) | 9 | #define VTD_PAGE_MASK (((u64)-1) << VTD_PAGE_SHIFT) |
| 10 | #define VTD_PAGE_ALIGN(addr) (((addr) + VTD_PAGE_SIZE - 1) & VTD_PAGE_MASK) | 10 | #define VTD_PAGE_ALIGN(addr) (((addr) + VTD_PAGE_SIZE - 1) & VTD_PAGE_MASK) |
| 11 | 11 | ||
| 12 | #define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT) | ||
| 13 | #define DMA_32BIT_PFN IOVA_PFN(DMA_32BIT_MASK) | ||
| 14 | #define DMA_64BIT_PFN IOVA_PFN(DMA_64BIT_MASK) | ||
| 15 | |||
| 16 | |||
| 17 | /* | ||
| 18 | * 0: Present | ||
| 19 | * 1-11: Reserved | ||
| 20 | * 12-63: Context Ptr (12 - (haw-1)) | ||
| 21 | * 64-127: Reserved | ||
| 22 | */ | ||
| 23 | struct root_entry { | ||
| 24 | u64 val; | ||
| 25 | u64 rsvd1; | ||
| 26 | }; | ||
| 27 | #define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry)) | ||
| 28 | static inline bool root_present(struct root_entry *root) | ||
| 29 | { | ||
| 30 | return (root->val & 1); | ||
| 31 | } | ||
| 32 | static inline void set_root_present(struct root_entry *root) | ||
| 33 | { | ||
| 34 | root->val |= 1; | ||
| 35 | } | ||
| 36 | static inline void set_root_value(struct root_entry *root, unsigned long value) | ||
| 37 | { | ||
| 38 | root->val |= value & VTD_PAGE_MASK; | ||
| 39 | } | ||
| 40 | |||
| 41 | struct context_entry; | ||
| 42 | static inline struct context_entry * | ||
| 43 | get_context_addr_from_root(struct root_entry *root) | ||
| 44 | { | ||
| 45 | return (struct context_entry *) | ||
| 46 | (root_present(root)?phys_to_virt( | ||
| 47 | root->val & VTD_PAGE_MASK) : | ||
| 48 | NULL); | ||
| 49 | } | ||
| 50 | |||
| 51 | /* | ||
| 52 | * low 64 bits: | ||
| 53 | * 0: present | ||
| 54 | * 1: fault processing disable | ||
| 55 | * 2-3: translation type | ||
| 56 | * 12-63: address space root | ||
| 57 | * high 64 bits: | ||
| 58 | * 0-2: address width | ||
| 59 | * 3-6: aval | ||
| 60 | * 8-23: domain id | ||
| 61 | */ | ||
| 62 | struct context_entry { | ||
| 63 | u64 lo; | ||
| 64 | u64 hi; | ||
| 65 | }; | ||
| 66 | #define context_present(c) ((c).lo & 1) | ||
| 67 | #define context_fault_disable(c) (((c).lo >> 1) & 1) | ||
| 68 | #define context_translation_type(c) (((c).lo >> 2) & 3) | ||
| 69 | #define context_address_root(c) ((c).lo & VTD_PAGE_MASK) | ||
| 70 | #define context_address_width(c) ((c).hi & 7) | ||
| 71 | #define context_domain_id(c) (((c).hi >> 8) & ((1 << 16) - 1)) | ||
| 72 | |||
| 73 | #define context_set_present(c) do {(c).lo |= 1;} while (0) | ||
| 74 | #define context_set_fault_enable(c) \ | ||
| 75 | do {(c).lo &= (((u64)-1) << 2) | 1;} while (0) | ||
| 76 | #define context_set_translation_type(c, val) \ | ||
| 77 | do { \ | ||
| 78 | (c).lo &= (((u64)-1) << 4) | 3; \ | ||
| 79 | (c).lo |= ((val) & 3) << 2; \ | ||
| 80 | } while (0) | ||
| 81 | #define CONTEXT_TT_MULTI_LEVEL 0 | ||
| 82 | #define context_set_address_root(c, val) \ | ||
| 83 | do {(c).lo |= (val) & VTD_PAGE_MASK; } while (0) | ||
| 84 | #define context_set_address_width(c, val) do {(c).hi |= (val) & 7;} while (0) | ||
| 85 | #define context_set_domain_id(c, val) \ | ||
| 86 | do {(c).hi |= ((val) & ((1 << 16) - 1)) << 8;} while (0) | ||
| 87 | #define context_clear_entry(c) do {(c).lo = 0; (c).hi = 0;} while (0) | ||
| 88 | |||
| 89 | /* | ||
| 90 | * 0: readable | ||
| 91 | * 1: writable | ||
| 92 | * 2-6: reserved | ||
| 93 | * 7: super page | ||
| 94 | * 8-11: available | ||
| 95 | * 12-63: Host physcial address | ||
| 96 | */ | ||
| 97 | struct dma_pte { | ||
| 98 | u64 val; | ||
| 99 | }; | ||
| 100 | #define dma_clear_pte(p) do {(p).val = 0;} while (0) | ||
| 101 | |||
| 102 | #define DMA_PTE_READ (1) | 12 | #define DMA_PTE_READ (1) |
| 103 | #define DMA_PTE_WRITE (2) | 13 | #define DMA_PTE_WRITE (2) |
| 104 | 14 | ||
| 105 | #define dma_set_pte_readable(p) do {(p).val |= DMA_PTE_READ;} while (0) | ||
| 106 | #define dma_set_pte_writable(p) do {(p).val |= DMA_PTE_WRITE;} while (0) | ||
| 107 | #define dma_set_pte_prot(p, prot) \ | ||
| 108 | do {(p).val = ((p).val & ~3) | ((prot) & 3); } while (0) | ||
| 109 | #define dma_pte_addr(p) ((p).val & VTD_PAGE_MASK) | ||
| 110 | #define dma_set_pte_addr(p, addr) do {\ | ||
| 111 | (p).val |= ((addr) & VTD_PAGE_MASK); } while (0) | ||
| 112 | #define dma_pte_present(p) (((p).val & 3) != 0) | ||
| 113 | |||
| 114 | struct intel_iommu; | 15 | struct intel_iommu; |
| 16 | struct dmar_domain; | ||
| 17 | struct root_entry; | ||
| 115 | 18 | ||
| 116 | struct dmar_domain { | ||
| 117 | int id; /* domain id */ | ||
| 118 | struct intel_iommu *iommu; /* back pointer to owning iommu */ | ||
| 119 | |||
| 120 | struct list_head devices; /* all devices' list */ | ||
| 121 | struct iova_domain iovad; /* iova's that belong to this domain */ | ||
| 122 | |||
| 123 | struct dma_pte *pgd; /* virtual address */ | ||
| 124 | spinlock_t mapping_lock; /* page table lock */ | ||
| 125 | int gaw; /* max guest address width */ | ||
| 126 | |||
| 127 | /* adjusted guest address width, 0 is level 2 30-bit */ | ||
| 128 | int agaw; | ||
| 129 | |||
| 130 | #define DOMAIN_FLAG_MULTIPLE_DEVICES 1 | ||
| 131 | int flags; | ||
| 132 | }; | ||
| 133 | |||
| 134 | /* PCI domain-device relationship */ | ||
| 135 | struct device_domain_info { | ||
| 136 | struct list_head link; /* link to domain siblings */ | ||
| 137 | struct list_head global; /* link to global list */ | ||
| 138 | u8 bus; /* PCI bus numer */ | ||
| 139 | u8 devfn; /* PCI devfn number */ | ||
| 140 | struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */ | ||
| 141 | struct dmar_domain *domain; /* pointer to domain */ | ||
| 142 | }; | ||
| 143 | |||
| 144 | extern int init_dmars(void); | ||
| 145 | extern void free_dmar_iommu(struct intel_iommu *iommu); | 19 | extern void free_dmar_iommu(struct intel_iommu *iommu); |
| 20 | extern int iommu_calculate_agaw(struct intel_iommu *iommu); | ||
| 146 | 21 | ||
| 147 | extern int dmar_disabled; | 22 | extern int dmar_disabled; |
| 148 | 23 | ||
| 149 | #ifndef CONFIG_DMAR_GFX_WA | ||
| 150 | static inline void iommu_prepare_gfx_mapping(void) | ||
| 151 | { | ||
| 152 | return; | ||
| 153 | } | ||
| 154 | #endif /* !CONFIG_DMAR_GFX_WA */ | ||
| 155 | |||
| 156 | #endif | 24 | #endif |
diff --git a/include/linux/dmar.h b/include/linux/dmar.h index f1984fc3e06d..f28440784cf0 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h | |||
| @@ -144,7 +144,6 @@ struct dmar_rmrr_unit { | |||
| 144 | list_for_each_entry(rmrr, &dmar_rmrr_units, list) | 144 | list_for_each_entry(rmrr, &dmar_rmrr_units, list) |
| 145 | /* Intel DMAR initialization functions */ | 145 | /* Intel DMAR initialization functions */ |
| 146 | extern int intel_iommu_init(void); | 146 | extern int intel_iommu_init(void); |
| 147 | extern int dmar_disabled; | ||
| 148 | #else | 147 | #else |
| 149 | static inline int intel_iommu_init(void) | 148 | static inline int intel_iommu_init(void) |
| 150 | { | 149 | { |
diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 79a8ed8e6a7d..55026b1a40bd 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h | |||
| @@ -62,10 +62,11 @@ typedef enum fe_caps { | |||
| 62 | FE_CAN_HIERARCHY_AUTO = 0x100000, | 62 | FE_CAN_HIERARCHY_AUTO = 0x100000, |
| 63 | FE_CAN_8VSB = 0x200000, | 63 | FE_CAN_8VSB = 0x200000, |
| 64 | FE_CAN_16VSB = 0x400000, | 64 | FE_CAN_16VSB = 0x400000, |
| 65 | FE_HAS_EXTENDED_CAPS = 0x800000, // We need more bitspace for newer APIs, indicate this. | 65 | FE_HAS_EXTENDED_CAPS = 0x800000, /* We need more bitspace for newer APIs, indicate this. */ |
| 66 | FE_NEEDS_BENDING = 0x20000000, // not supported anymore, don't use (frontend requires frequency bending) | 66 | FE_CAN_2G_MODULATION = 0x10000000, /* frontend supports "2nd generation modulation" (DVB-S2) */ |
| 67 | FE_CAN_RECOVER = 0x40000000, // frontend can recover from a cable unplug automatically | 67 | FE_NEEDS_BENDING = 0x20000000, /* not supported anymore, don't use (frontend requires frequency bending) */ |
| 68 | FE_CAN_MUTE_TS = 0x80000000 // frontend can stop spurious TS data output | 68 | FE_CAN_RECOVER = 0x40000000, /* frontend can recover from a cable unplug automatically */ |
| 69 | FE_CAN_MUTE_TS = 0x80000000 /* frontend can stop spurious TS data output */ | ||
| 69 | } fe_caps_t; | 70 | } fe_caps_t; |
| 70 | 71 | ||
| 71 | 72 | ||
| @@ -121,15 +122,15 @@ typedef enum fe_sec_mini_cmd { | |||
| 121 | 122 | ||
| 122 | 123 | ||
| 123 | typedef enum fe_status { | 124 | typedef enum fe_status { |
| 124 | FE_HAS_SIGNAL = 0x01, /* found something above the noise level */ | 125 | FE_HAS_SIGNAL = 0x01, /* found something above the noise level */ |
| 125 | FE_HAS_CARRIER = 0x02, /* found a DVB signal */ | 126 | FE_HAS_CARRIER = 0x02, /* found a DVB signal */ |
| 126 | FE_HAS_VITERBI = 0x04, /* FEC is stable */ | 127 | FE_HAS_VITERBI = 0x04, /* FEC is stable */ |
| 127 | FE_HAS_SYNC = 0x08, /* found sync bytes */ | 128 | FE_HAS_SYNC = 0x08, /* found sync bytes */ |
| 128 | FE_HAS_LOCK = 0x10, /* everything's working... */ | 129 | FE_HAS_LOCK = 0x10, /* everything's working... */ |
| 129 | FE_TIMEDOUT = 0x20, /* no lock within the last ~2 seconds */ | 130 | FE_TIMEDOUT = 0x20, /* no lock within the last ~2 seconds */ |
| 130 | FE_REINIT = 0x40 /* frontend was reinitialized, */ | 131 | FE_REINIT = 0x40 /* frontend was reinitialized, */ |
| 131 | } fe_status_t; /* application is recommended to reset */ | 132 | } fe_status_t; /* application is recommended to reset */ |
| 132 | /* DiSEqC, tone and parameters */ | 133 | /* DiSEqC, tone and parameters */ |
| 133 | 134 | ||
| 134 | typedef enum fe_spectral_inversion { | 135 | typedef enum fe_spectral_inversion { |
| 135 | INVERSION_OFF, | 136 | INVERSION_OFF, |
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 3d017cfd245b..c4f6c101dbcd 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h | |||
| @@ -23,8 +23,6 @@ | |||
| 23 | #define _INTEL_IOMMU_H_ | 23 | #define _INTEL_IOMMU_H_ |
| 24 | 24 | ||
| 25 | #include <linux/types.h> | 25 | #include <linux/types.h> |
| 26 | #include <linux/msi.h> | ||
| 27 | #include <linux/sysdev.h> | ||
| 28 | #include <linux/iova.h> | 26 | #include <linux/iova.h> |
| 29 | #include <linux/io.h> | 27 | #include <linux/io.h> |
| 30 | #include <linux/dma_remapping.h> | 28 | #include <linux/dma_remapping.h> |
| @@ -289,10 +287,10 @@ struct intel_iommu { | |||
| 289 | void __iomem *reg; /* Pointer to hardware regs, virtual addr */ | 287 | void __iomem *reg; /* Pointer to hardware regs, virtual addr */ |
| 290 | u64 cap; | 288 | u64 cap; |
| 291 | u64 ecap; | 289 | u64 ecap; |
| 292 | int seg; | ||
| 293 | u32 gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */ | 290 | u32 gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */ |
| 294 | spinlock_t register_lock; /* protect register handling */ | 291 | spinlock_t register_lock; /* protect register handling */ |
| 295 | int seq_id; /* sequence id of the iommu */ | 292 | int seq_id; /* sequence id of the iommu */ |
| 293 | int agaw; /* agaw of this iommu */ | ||
| 296 | 294 | ||
| 297 | #ifdef CONFIG_DMAR | 295 | #ifdef CONFIG_DMAR |
| 298 | unsigned long *domain_ids; /* bitmap of domains */ | 296 | unsigned long *domain_ids; /* bitmap of domains */ |
| @@ -302,8 +300,6 @@ struct intel_iommu { | |||
| 302 | 300 | ||
| 303 | unsigned int irq; | 301 | unsigned int irq; |
| 304 | unsigned char name[7]; /* Device Name */ | 302 | unsigned char name[7]; /* Device Name */ |
| 305 | struct msi_msg saved_msg; | ||
| 306 | struct sys_device sysdev; | ||
| 307 | struct iommu_flush flush; | 303 | struct iommu_flush flush; |
| 308 | #endif | 304 | #endif |
| 309 | struct q_inval *qi; /* Queued invalidation info */ | 305 | struct q_inval *qi; /* Queued invalidation info */ |
| @@ -334,25 +330,6 @@ extern int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, | |||
| 334 | 330 | ||
| 335 | extern void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu); | 331 | extern void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu); |
| 336 | 332 | ||
| 337 | void intel_iommu_domain_exit(struct dmar_domain *domain); | ||
| 338 | struct dmar_domain *intel_iommu_domain_alloc(struct pci_dev *pdev); | ||
| 339 | int intel_iommu_context_mapping(struct dmar_domain *domain, | ||
| 340 | struct pci_dev *pdev); | ||
| 341 | int intel_iommu_page_mapping(struct dmar_domain *domain, dma_addr_t iova, | ||
| 342 | u64 hpa, size_t size, int prot); | ||
| 343 | void intel_iommu_detach_dev(struct dmar_domain *domain, u8 bus, u8 devfn); | ||
| 344 | struct dmar_domain *intel_iommu_find_domain(struct pci_dev *pdev); | ||
| 345 | u64 intel_iommu_iova_to_pfn(struct dmar_domain *domain, u64 iova); | ||
| 346 | |||
| 347 | #ifdef CONFIG_DMAR | ||
| 348 | int intel_iommu_found(void); | ||
| 349 | #else /* CONFIG_DMAR */ | ||
| 350 | static inline int intel_iommu_found(void) | ||
| 351 | { | ||
| 352 | return 0; | ||
| 353 | } | ||
| 354 | #endif /* CONFIG_DMAR */ | ||
| 355 | |||
| 356 | extern void *intel_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t); | 333 | extern void *intel_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t); |
| 357 | extern void intel_free_coherent(struct device *, size_t, void *, dma_addr_t); | 334 | extern void intel_free_coherent(struct device *, size_t, void *, dma_addr_t); |
| 358 | extern dma_addr_t intel_map_single(struct device *, phys_addr_t, size_t, int); | 335 | extern dma_addr_t intel_map_single(struct device *, phys_addr_t, size_t, int); |
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 990355fbc54e..0702c4d7bdf0 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
| @@ -109,7 +109,7 @@ extern void enable_irq(unsigned int irq); | |||
| 109 | 109 | ||
| 110 | #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS) | 110 | #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS) |
| 111 | 111 | ||
| 112 | extern cpumask_t irq_default_affinity; | 112 | extern cpumask_var_t irq_default_affinity; |
| 113 | 113 | ||
| 114 | extern int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask); | 114 | extern int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask); |
| 115 | extern int irq_can_set_affinity(unsigned int irq); | 115 | extern int irq_can_set_affinity(unsigned int irq); |
diff --git a/include/linux/iommu.h b/include/linux/iommu.h new file mode 100644 index 000000000000..8a7bfb1b6ca0 --- /dev/null +++ b/include/linux/iommu.h | |||
| @@ -0,0 +1,112 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2007-2008 Advanced Micro Devices, Inc. | ||
| 3 | * Author: Joerg Roedel <joerg.roedel@amd.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 as published | ||
| 7 | * by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 17 | */ | ||
| 18 | |||
| 19 | #ifndef __LINUX_IOMMU_H | ||
| 20 | #define __LINUX_IOMMU_H | ||
| 21 | |||
| 22 | #define IOMMU_READ (1) | ||
| 23 | #define IOMMU_WRITE (2) | ||
| 24 | |||
| 25 | struct device; | ||
| 26 | |||
| 27 | struct iommu_domain { | ||
| 28 | void *priv; | ||
| 29 | }; | ||
| 30 | |||
| 31 | struct iommu_ops { | ||
| 32 | int (*domain_init)(struct iommu_domain *domain); | ||
| 33 | void (*domain_destroy)(struct iommu_domain *domain); | ||
| 34 | int (*attach_dev)(struct iommu_domain *domain, struct device *dev); | ||
| 35 | void (*detach_dev)(struct iommu_domain *domain, struct device *dev); | ||
| 36 | int (*map)(struct iommu_domain *domain, unsigned long iova, | ||
| 37 | phys_addr_t paddr, size_t size, int prot); | ||
| 38 | void (*unmap)(struct iommu_domain *domain, unsigned long iova, | ||
| 39 | size_t size); | ||
| 40 | phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, | ||
| 41 | unsigned long iova); | ||
| 42 | }; | ||
| 43 | |||
| 44 | #ifdef CONFIG_IOMMU_API | ||
| 45 | |||
| 46 | extern void register_iommu(struct iommu_ops *ops); | ||
| 47 | extern bool iommu_found(void); | ||
| 48 | extern struct iommu_domain *iommu_domain_alloc(void); | ||
| 49 | extern void iommu_domain_free(struct iommu_domain *domain); | ||
| 50 | extern int iommu_attach_device(struct iommu_domain *domain, | ||
| 51 | struct device *dev); | ||
| 52 | extern void iommu_detach_device(struct iommu_domain *domain, | ||
| 53 | struct device *dev); | ||
| 54 | extern int iommu_map_range(struct iommu_domain *domain, unsigned long iova, | ||
| 55 | phys_addr_t paddr, size_t size, int prot); | ||
| 56 | extern void iommu_unmap_range(struct iommu_domain *domain, unsigned long iova, | ||
| 57 | size_t size); | ||
| 58 | extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, | ||
| 59 | unsigned long iova); | ||
| 60 | |||
| 61 | #else /* CONFIG_IOMMU_API */ | ||
| 62 | |||
| 63 | static inline void register_iommu(struct iommu_ops *ops) | ||
| 64 | { | ||
| 65 | } | ||
| 66 | |||
| 67 | static inline bool iommu_found(void) | ||
| 68 | { | ||
| 69 | return false; | ||
| 70 | } | ||
| 71 | |||
| 72 | static inline struct iommu_domain *iommu_domain_alloc(void) | ||
| 73 | { | ||
| 74 | return NULL; | ||
| 75 | } | ||
| 76 | |||
| 77 | static inline void iommu_domain_free(struct iommu_domain *domain) | ||
| 78 | { | ||
| 79 | } | ||
| 80 | |||
| 81 | static inline int iommu_attach_device(struct iommu_domain *domain, | ||
| 82 | struct device *dev) | ||
| 83 | { | ||
| 84 | return -ENODEV; | ||
| 85 | } | ||
| 86 | |||
| 87 | static inline void iommu_detach_device(struct iommu_domain *domain, | ||
| 88 | struct device *dev) | ||
| 89 | { | ||
| 90 | } | ||
| 91 | |||
| 92 | static inline int iommu_map_range(struct iommu_domain *domain, | ||
| 93 | unsigned long iova, phys_addr_t paddr, | ||
| 94 | size_t size, int prot) | ||
| 95 | { | ||
| 96 | return -ENODEV; | ||
| 97 | } | ||
| 98 | |||
| 99 | static inline void iommu_unmap_range(struct iommu_domain *domain, | ||
| 100 | unsigned long iova, size_t size) | ||
| 101 | { | ||
| 102 | } | ||
| 103 | |||
| 104 | static inline phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, | ||
| 105 | unsigned long iova) | ||
| 106 | { | ||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | |||
| 110 | #endif /* CONFIG_IOMMU_API */ | ||
| 111 | |||
| 112 | #endif /* __LINUX_IOMMU_H */ | ||
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 4ee4b3d2316f..570d20413119 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h | |||
| @@ -79,10 +79,13 @@ static inline unsigned int kstat_irqs(unsigned int irq) | |||
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | extern unsigned long long task_delta_exec(struct task_struct *); | 81 | extern unsigned long long task_delta_exec(struct task_struct *); |
| 82 | extern void account_user_time(struct task_struct *, cputime_t); | 82 | extern void account_user_time(struct task_struct *, cputime_t, cputime_t); |
| 83 | extern void account_user_time_scaled(struct task_struct *, cputime_t); | 83 | extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t); |
| 84 | extern void account_system_time(struct task_struct *, int, cputime_t); | 84 | extern void account_steal_time(cputime_t); |
| 85 | extern void account_system_time_scaled(struct task_struct *, cputime_t); | 85 | extern void account_idle_time(cputime_t); |
| 86 | extern void account_steal_time(struct task_struct *, cputime_t); | 86 | |
| 87 | extern void account_process_tick(struct task_struct *, int user); | ||
| 88 | extern void account_steal_ticks(unsigned long ticks); | ||
| 89 | extern void account_idle_ticks(unsigned long ticks); | ||
| 87 | 90 | ||
| 88 | #endif /* _LINUX_KERNEL_STAT_H */ | 91 | #endif /* _LINUX_KERNEL_STAT_H */ |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index eafabd5c66b2..ec49d0be7f52 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
| @@ -316,6 +316,7 @@ struct kvm_assigned_dev_kernel { | |||
| 316 | #define KVM_ASSIGNED_DEV_HOST_MSI (1 << 9) | 316 | #define KVM_ASSIGNED_DEV_HOST_MSI (1 << 9) |
| 317 | unsigned long irq_requested_type; | 317 | unsigned long irq_requested_type; |
| 318 | int irq_source_id; | 318 | int irq_source_id; |
| 319 | int flags; | ||
| 319 | struct pci_dev *dev; | 320 | struct pci_dev *dev; |
| 320 | struct kvm *kvm; | 321 | struct kvm *kvm; |
| 321 | }; | 322 | }; |
| @@ -327,13 +328,16 @@ void kvm_unregister_irq_ack_notifier(struct kvm_irq_ack_notifier *kian); | |||
| 327 | int kvm_request_irq_source_id(struct kvm *kvm); | 328 | int kvm_request_irq_source_id(struct kvm *kvm); |
| 328 | void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id); | 329 | void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id); |
| 329 | 330 | ||
| 330 | #ifdef CONFIG_DMAR | 331 | #ifdef CONFIG_IOMMU_API |
| 331 | int kvm_iommu_map_pages(struct kvm *kvm, gfn_t base_gfn, | 332 | int kvm_iommu_map_pages(struct kvm *kvm, gfn_t base_gfn, |
| 332 | unsigned long npages); | 333 | unsigned long npages); |
| 333 | int kvm_iommu_map_guest(struct kvm *kvm, | 334 | int kvm_iommu_map_guest(struct kvm *kvm); |
| 334 | struct kvm_assigned_dev_kernel *assigned_dev); | ||
| 335 | int kvm_iommu_unmap_guest(struct kvm *kvm); | 335 | int kvm_iommu_unmap_guest(struct kvm *kvm); |
| 336 | #else /* CONFIG_DMAR */ | 336 | int kvm_assign_device(struct kvm *kvm, |
| 337 | struct kvm_assigned_dev_kernel *assigned_dev); | ||
| 338 | int kvm_deassign_device(struct kvm *kvm, | ||
| 339 | struct kvm_assigned_dev_kernel *assigned_dev); | ||
| 340 | #else /* CONFIG_IOMMU_API */ | ||
| 337 | static inline int kvm_iommu_map_pages(struct kvm *kvm, | 341 | static inline int kvm_iommu_map_pages(struct kvm *kvm, |
| 338 | gfn_t base_gfn, | 342 | gfn_t base_gfn, |
| 339 | unsigned long npages) | 343 | unsigned long npages) |
| @@ -341,9 +345,7 @@ static inline int kvm_iommu_map_pages(struct kvm *kvm, | |||
| 341 | return 0; | 345 | return 0; |
| 342 | } | 346 | } |
| 343 | 347 | ||
| 344 | static inline int kvm_iommu_map_guest(struct kvm *kvm, | 348 | static inline int kvm_iommu_map_guest(struct kvm *kvm) |
| 345 | struct kvm_assigned_dev_kernel | ||
| 346 | *assigned_dev) | ||
| 347 | { | 349 | { |
| 348 | return -ENODEV; | 350 | return -ENODEV; |
| 349 | } | 351 | } |
| @@ -352,7 +354,19 @@ static inline int kvm_iommu_unmap_guest(struct kvm *kvm) | |||
| 352 | { | 354 | { |
| 353 | return 0; | 355 | return 0; |
| 354 | } | 356 | } |
| 355 | #endif /* CONFIG_DMAR */ | 357 | |
| 358 | static inline int kvm_assign_device(struct kvm *kvm, | ||
| 359 | struct kvm_assigned_dev_kernel *assigned_dev) | ||
| 360 | { | ||
| 361 | return 0; | ||
| 362 | } | ||
| 363 | |||
| 364 | static inline int kvm_deassign_device(struct kvm *kvm, | ||
| 365 | struct kvm_assigned_dev_kernel *assigned_dev) | ||
| 366 | { | ||
| 367 | return 0; | ||
| 368 | } | ||
| 369 | #endif /* CONFIG_IOMMU_API */ | ||
| 356 | 370 | ||
| 357 | static inline void kvm_guest_enter(void) | 371 | static inline void kvm_guest_enter(void) |
| 358 | { | 372 | { |
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 143cebf0586f..7ac8b500d55c 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h | |||
| @@ -151,4 +151,6 @@ static inline void mmc_claim_host(struct mmc_host *host) | |||
| 151 | __mmc_claim_host(host, NULL); | 151 | __mmc_claim_host(host, NULL); |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | extern u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max); | ||
| 155 | |||
| 154 | #endif | 156 | #endif |
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index f842f234e44f..4e457256bd33 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h | |||
| @@ -41,6 +41,7 @@ struct mmc_ios { | |||
| 41 | 41 | ||
| 42 | #define MMC_BUS_WIDTH_1 0 | 42 | #define MMC_BUS_WIDTH_1 0 |
| 43 | #define MMC_BUS_WIDTH_4 2 | 43 | #define MMC_BUS_WIDTH_4 2 |
| 44 | #define MMC_BUS_WIDTH_8 3 | ||
| 44 | 45 | ||
| 45 | unsigned char timing; /* timing specification used */ | 46 | unsigned char timing; /* timing specification used */ |
| 46 | 47 | ||
| @@ -116,6 +117,7 @@ struct mmc_host { | |||
| 116 | #define MMC_CAP_SDIO_IRQ (1 << 3) /* Can signal pending SDIO IRQs */ | 117 | #define MMC_CAP_SDIO_IRQ (1 << 3) /* Can signal pending SDIO IRQs */ |
| 117 | #define MMC_CAP_SPI (1 << 4) /* Talks only SPI protocols */ | 118 | #define MMC_CAP_SPI (1 << 4) /* Talks only SPI protocols */ |
| 118 | #define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */ | 119 | #define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */ |
| 120 | #define MMC_CAP_8_BIT_DATA (1 << 6) /* Can the host do 8 bit transfers */ | ||
| 119 | 121 | ||
| 120 | /* host specific block data */ | 122 | /* host specific block data */ |
| 121 | unsigned int max_seg_size; /* see blk_queue_max_segment_size */ | 123 | unsigned int max_seg_size; /* see blk_queue_max_segment_size */ |
diff --git a/include/linux/random.h b/include/linux/random.h index adbf3bd3c6b3..407ea3646f8f 100644 --- a/include/linux/random.h +++ b/include/linux/random.h | |||
| @@ -45,56 +45,6 @@ struct rand_pool_info { | |||
| 45 | 45 | ||
| 46 | extern void rand_initialize_irq(int irq); | 46 | extern void rand_initialize_irq(int irq); |
| 47 | 47 | ||
| 48 | struct timer_rand_state; | ||
| 49 | #ifndef CONFIG_SPARSE_IRQ | ||
| 50 | |||
| 51 | extern struct timer_rand_state *irq_timer_state[]; | ||
| 52 | |||
| 53 | static inline struct timer_rand_state *get_timer_rand_state(unsigned int irq) | ||
| 54 | { | ||
| 55 | if (irq >= nr_irqs) | ||
| 56 | return NULL; | ||
| 57 | |||
| 58 | return irq_timer_state[irq]; | ||
| 59 | } | ||
| 60 | |||
| 61 | static inline void set_timer_rand_state(unsigned int irq, struct timer_rand_state *state) | ||
| 62 | { | ||
| 63 | if (irq >= nr_irqs) | ||
| 64 | return; | ||
| 65 | |||
| 66 | irq_timer_state[irq] = state; | ||
| 67 | } | ||
| 68 | |||
| 69 | #else | ||
| 70 | |||
| 71 | #include <linux/irq.h> | ||
| 72 | static inline struct timer_rand_state *get_timer_rand_state(unsigned int irq) | ||
| 73 | { | ||
| 74 | struct irq_desc *desc; | ||
| 75 | |||
| 76 | desc = irq_to_desc(irq); | ||
| 77 | |||
| 78 | if (!desc) | ||
| 79 | return NULL; | ||
| 80 | |||
| 81 | return desc->timer_rand_state; | ||
| 82 | } | ||
| 83 | |||
| 84 | static inline void set_timer_rand_state(unsigned int irq, struct timer_rand_state *state) | ||
| 85 | { | ||
| 86 | struct irq_desc *desc; | ||
| 87 | |||
| 88 | desc = irq_to_desc(irq); | ||
| 89 | |||
| 90 | if (!desc) | ||
| 91 | return; | ||
| 92 | |||
| 93 | desc->timer_rand_state = state; | ||
| 94 | } | ||
| 95 | #endif | ||
| 96 | |||
| 97 | |||
| 98 | extern void add_input_randomness(unsigned int type, unsigned int code, | 48 | extern void add_input_randomness(unsigned int type, unsigned int code, |
| 99 | unsigned int value); | 49 | unsigned int value); |
| 100 | extern void add_interrupt_randomness(int irq); | 50 | extern void add_interrupt_randomness(int irq); |
diff --git a/include/linux/rcuclassic.h b/include/linux/rcuclassic.h index 301dda829e37..f3f697df1d71 100644 --- a/include/linux/rcuclassic.h +++ b/include/linux/rcuclassic.h | |||
| @@ -59,8 +59,8 @@ struct rcu_ctrlblk { | |||
| 59 | int signaled; | 59 | int signaled; |
| 60 | 60 | ||
| 61 | spinlock_t lock ____cacheline_internodealigned_in_smp; | 61 | spinlock_t lock ____cacheline_internodealigned_in_smp; |
| 62 | cpumask_t cpumask; /* CPUs that need to switch in order */ | 62 | DECLARE_BITMAP(cpumask, NR_CPUS); /* CPUs that need to switch for */ |
| 63 | /* for current batch to proceed. */ | 63 | /* current batch to proceed. */ |
| 64 | } ____cacheline_internodealigned_in_smp; | 64 | } ____cacheline_internodealigned_in_smp; |
| 65 | 65 | ||
| 66 | /* Is batch a before batch b ? */ | 66 | /* Is batch a before batch b ? */ |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 158d53d07765..38a3f4b15394 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
| @@ -284,7 +284,6 @@ long io_schedule_timeout(long timeout); | |||
| 284 | 284 | ||
| 285 | extern void cpu_init (void); | 285 | extern void cpu_init (void); |
| 286 | extern void trap_init(void); | 286 | extern void trap_init(void); |
| 287 | extern void account_process_tick(struct task_struct *task, int user); | ||
| 288 | extern void update_process_times(int user); | 287 | extern void update_process_times(int user); |
| 289 | extern void scheduler_tick(void); | 288 | extern void scheduler_tick(void); |
| 290 | 289 | ||
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index b3dfa72f13b9..40ea5058c2ec 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h | |||
| @@ -50,10 +50,11 @@ int seq_path(struct seq_file *, struct path *, char *); | |||
| 50 | int seq_dentry(struct seq_file *, struct dentry *, char *); | 50 | int seq_dentry(struct seq_file *, struct dentry *, char *); |
| 51 | int seq_path_root(struct seq_file *m, struct path *path, struct path *root, | 51 | int seq_path_root(struct seq_file *m, struct path *path, struct path *root, |
| 52 | char *esc); | 52 | char *esc); |
| 53 | int seq_bitmap(struct seq_file *m, unsigned long *bits, unsigned int nr_bits); | 53 | int seq_bitmap(struct seq_file *m, const unsigned long *bits, |
| 54 | static inline int seq_cpumask(struct seq_file *m, cpumask_t *mask) | 54 | unsigned int nr_bits); |
| 55 | static inline int seq_cpumask(struct seq_file *m, const struct cpumask *mask) | ||
| 55 | { | 56 | { |
| 56 | return seq_bitmap(m, mask->bits, NR_CPUS); | 57 | return seq_bitmap(m, mask->bits, nr_cpu_ids); |
| 57 | } | 58 | } |
| 58 | 59 | ||
| 59 | static inline int seq_nodemask(struct seq_file *m, nodemask_t *mask) | 60 | static inline int seq_nodemask(struct seq_file *m, nodemask_t *mask) |
diff --git a/include/linux/smp.h b/include/linux/smp.h index 6e7ba16ff454..b82466968101 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h | |||
| @@ -21,6 +21,9 @@ struct call_single_data { | |||
| 21 | u16 priv; | 21 | u16 priv; |
| 22 | }; | 22 | }; |
| 23 | 23 | ||
| 24 | /* total number of cpus in this system (may exceed NR_CPUS) */ | ||
| 25 | extern unsigned int total_cpus; | ||
| 26 | |||
| 24 | #ifdef CONFIG_SMP | 27 | #ifdef CONFIG_SMP |
| 25 | 28 | ||
| 26 | #include <linux/preempt.h> | 29 | #include <linux/preempt.h> |
| @@ -64,15 +67,16 @@ extern void smp_cpus_done(unsigned int max_cpus); | |||
| 64 | * Call a function on all other processors | 67 | * Call a function on all other processors |
| 65 | */ | 68 | */ |
| 66 | int smp_call_function(void(*func)(void *info), void *info, int wait); | 69 | int smp_call_function(void(*func)(void *info), void *info, int wait); |
| 67 | /* Deprecated: use smp_call_function_many() which uses a cpumask ptr. */ | 70 | void smp_call_function_many(const struct cpumask *mask, |
| 68 | int smp_call_function_mask(cpumask_t mask, void(*func)(void *info), void *info, | 71 | void (*func)(void *info), void *info, bool wait); |
| 69 | int wait); | ||
| 70 | 72 | ||
| 71 | static inline void smp_call_function_many(const struct cpumask *mask, | 73 | /* Deprecated: Use smp_call_function_many which takes a pointer to the mask. */ |
| 72 | void (*func)(void *info), void *info, | 74 | static inline int |
| 73 | int wait) | 75 | smp_call_function_mask(cpumask_t mask, void(*func)(void *info), void *info, |
| 76 | int wait) | ||
| 74 | { | 77 | { |
| 75 | smp_call_function_mask(*mask, func, info, wait); | 78 | smp_call_function_many(&mask, func, info, wait); |
| 79 | return 0; | ||
| 76 | } | 80 | } |
| 77 | 81 | ||
| 78 | int smp_call_function_single(int cpuid, void (*func) (void *info), void *info, | 82 | int smp_call_function_single(int cpuid, void (*func) (void *info), void *info, |
diff --git a/include/linux/spi/mmc_spi.h b/include/linux/spi/mmc_spi.h index a3626aedaec9..0f4eb165f254 100644 --- a/include/linux/spi/mmc_spi.h +++ b/include/linux/spi/mmc_spi.h | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | #ifndef __LINUX_SPI_MMC_SPI_H | 1 | #ifndef __LINUX_SPI_MMC_SPI_H |
| 2 | #define __LINUX_SPI_MMC_SPI_H | 2 | #define __LINUX_SPI_MMC_SPI_H |
| 3 | 3 | ||
| 4 | #include <linux/device.h> | ||
| 5 | #include <linux/spi/spi.h> | ||
| 4 | #include <linux/interrupt.h> | 6 | #include <linux/interrupt.h> |
| 5 | 7 | ||
| 6 | struct device; | ||
| 7 | struct mmc_host; | 8 | struct mmc_host; |
| 8 | 9 | ||
| 9 | /* Put this in platform_data of a device being used to manage an MMC/SD | 10 | /* Put this in platform_data of a device being used to manage an MMC/SD |
| @@ -41,4 +42,16 @@ struct mmc_spi_platform_data { | |||
| 41 | void (*setpower)(struct device *, unsigned int maskval); | 42 | void (*setpower)(struct device *, unsigned int maskval); |
| 42 | }; | 43 | }; |
| 43 | 44 | ||
| 45 | #ifdef CONFIG_OF | ||
| 46 | extern struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi); | ||
| 47 | extern void mmc_spi_put_pdata(struct spi_device *spi); | ||
| 48 | #else | ||
| 49 | static inline struct mmc_spi_platform_data * | ||
| 50 | mmc_spi_get_pdata(struct spi_device *spi) | ||
| 51 | { | ||
| 52 | return spi->dev.platform_data; | ||
| 53 | } | ||
| 54 | static inline void mmc_spi_put_pdata(struct spi_device *spi) {} | ||
| 55 | #endif /* CONFIG_OF */ | ||
| 56 | |||
| 44 | #endif /* __LINUX_SPI_MMC_SPI_H */ | 57 | #endif /* __LINUX_SPI_MMC_SPI_H */ |
diff --git a/include/linux/stop_machine.h b/include/linux/stop_machine.h index faf1519b5adc..74d59a641362 100644 --- a/include/linux/stop_machine.h +++ b/include/linux/stop_machine.h | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | * | 23 | * |
| 24 | * This can be thought of as a very heavy write lock, equivalent to | 24 | * This can be thought of as a very heavy write lock, equivalent to |
| 25 | * grabbing every spinlock in the kernel. */ | 25 | * grabbing every spinlock in the kernel. */ |
| 26 | int stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus); | 26 | int stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus); |
| 27 | 27 | ||
| 28 | /** | 28 | /** |
| 29 | * __stop_machine: freeze the machine on all CPUs and run this function | 29 | * __stop_machine: freeze the machine on all CPUs and run this function |
| @@ -34,11 +34,11 @@ int stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus); | |||
| 34 | * Description: This is a special version of the above, which assumes cpus | 34 | * Description: This is a special version of the above, which assumes cpus |
| 35 | * won't come or go while it's being called. Used by hotplug cpu. | 35 | * won't come or go while it's being called. Used by hotplug cpu. |
| 36 | */ | 36 | */ |
| 37 | int __stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus); | 37 | int __stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus); |
| 38 | #else | 38 | #else |
| 39 | 39 | ||
| 40 | static inline int stop_machine(int (*fn)(void *), void *data, | 40 | static inline int stop_machine(int (*fn)(void *), void *data, |
| 41 | const cpumask_t *cpus) | 41 | const struct cpumask *cpus) |
| 42 | { | 42 | { |
| 43 | int ret; | 43 | int ret; |
| 44 | local_irq_disable(); | 44 | local_irq_disable(); |
diff --git a/include/linux/threads.h b/include/linux/threads.h index 38d1a5d6568e..052b12bec8bd 100644 --- a/include/linux/threads.h +++ b/include/linux/threads.h | |||
| @@ -8,17 +8,17 @@ | |||
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | /* | 10 | /* |
| 11 | * Maximum supported processors that can run under SMP. This value is | 11 | * Maximum supported processors. Setting this smaller saves quite a |
| 12 | * set via configure setting. The maximum is equal to the size of the | 12 | * bit of memory. Use nr_cpu_ids instead of this except for static bitmaps. |
| 13 | * bitmasks used on that platform, i.e. 32 or 64. Setting this smaller | ||
| 14 | * saves quite a bit of memory. | ||
| 15 | */ | 13 | */ |
| 16 | #ifdef CONFIG_SMP | 14 | #ifndef CONFIG_NR_CPUS |
| 17 | #define NR_CPUS CONFIG_NR_CPUS | 15 | /* FIXME: This should be fixed in the arch's Kconfig */ |
| 18 | #else | 16 | #define CONFIG_NR_CPUS 1 |
| 19 | #define NR_CPUS 1 | ||
| 20 | #endif | 17 | #endif |
| 21 | 18 | ||
| 19 | /* Places which use this should consider cpumask_var_t. */ | ||
| 20 | #define NR_CPUS CONFIG_NR_CPUS | ||
| 21 | |||
| 22 | #define MIN_THREADS_LEFT_FOR_ROOT 4 | 22 | #define MIN_THREADS_LEFT_FOR_ROOT 4 |
| 23 | 23 | ||
| 24 | /* | 24 | /* |
diff --git a/include/linux/tick.h b/include/linux/tick.h index b6ec8189ac0c..469b82d88b3b 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h | |||
| @@ -84,10 +84,10 @@ static inline void tick_cancel_sched_timer(int cpu) { } | |||
| 84 | 84 | ||
| 85 | # ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST | 85 | # ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST |
| 86 | extern struct tick_device *tick_get_broadcast_device(void); | 86 | extern struct tick_device *tick_get_broadcast_device(void); |
| 87 | extern cpumask_t *tick_get_broadcast_mask(void); | 87 | extern struct cpumask *tick_get_broadcast_mask(void); |
| 88 | 88 | ||
| 89 | # ifdef CONFIG_TICK_ONESHOT | 89 | # ifdef CONFIG_TICK_ONESHOT |
| 90 | extern cpumask_t *tick_get_broadcast_oneshot_mask(void); | 90 | extern struct cpumask *tick_get_broadcast_oneshot_mask(void); |
| 91 | # endif | 91 | # endif |
| 92 | 92 | ||
| 93 | # endif /* BROADCAST */ | 93 | # endif /* BROADCAST */ |
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 1f126e30766c..5571dbe1c0ad 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h | |||
| @@ -1370,25 +1370,41 @@ struct v4l2_streamparm { | |||
| 1370 | /* | 1370 | /* |
| 1371 | * A D V A N C E D D E B U G G I N G | 1371 | * A D V A N C E D D E B U G G I N G |
| 1372 | * | 1372 | * |
| 1373 | * NOTE: EXPERIMENTAL API | 1373 | * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS! |
| 1374 | * FOR DEBUGGING, TESTING AND INTERNAL USE ONLY! | ||
| 1374 | */ | 1375 | */ |
| 1375 | 1376 | ||
| 1376 | /* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */ | 1377 | /* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */ |
| 1377 | 1378 | ||
| 1378 | #define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0 for the host) */ | 1379 | #define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0 for the host) */ |
| 1379 | #define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver ID */ | 1380 | #define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver name */ |
| 1380 | #define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */ | 1381 | #define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */ |
| 1381 | #define V4L2_CHIP_MATCH_AC97 3 /* Match against anciliary AC97 chip */ | 1382 | #define V4L2_CHIP_MATCH_AC97 3 /* Match against anciliary AC97 chip */ |
| 1382 | 1383 | ||
| 1383 | struct v4l2_register { | 1384 | struct v4l2_dbg_match { |
| 1384 | __u32 match_type; /* Match type */ | 1385 | __u32 type; /* Match type */ |
| 1385 | __u32 match_chip; /* Match this chip, meaning determined by match_type */ | 1386 | union { /* Match this chip, meaning determined by type */ |
| 1387 | __u32 addr; | ||
| 1388 | char name[32]; | ||
| 1389 | }; | ||
| 1390 | } __attribute__ ((packed)); | ||
| 1391 | |||
| 1392 | struct v4l2_dbg_register { | ||
| 1393 | struct v4l2_dbg_match match; | ||
| 1394 | __u32 size; /* register size in bytes */ | ||
| 1386 | __u64 reg; | 1395 | __u64 reg; |
| 1387 | __u64 val; | 1396 | __u64 val; |
| 1388 | }; | 1397 | } __attribute__ ((packed)); |
| 1398 | |||
| 1399 | /* VIDIOC_DBG_G_CHIP_IDENT */ | ||
| 1400 | struct v4l2_dbg_chip_ident { | ||
| 1401 | struct v4l2_dbg_match match; | ||
| 1402 | __u32 ident; /* chip identifier as specified in <media/v4l2-chip-ident.h> */ | ||
| 1403 | __u32 revision; /* chip revision, chip specific */ | ||
| 1404 | } __attribute__ ((packed)); | ||
| 1389 | 1405 | ||
| 1390 | /* VIDIOC_G_CHIP_IDENT */ | 1406 | /* VIDIOC_G_CHIP_IDENT_OLD: Deprecated, do not use */ |
| 1391 | struct v4l2_chip_ident { | 1407 | struct v4l2_chip_ident_old { |
| 1392 | __u32 match_type; /* Match type */ | 1408 | __u32 match_type; /* Match type */ |
| 1393 | __u32 match_chip; /* Match this chip, meaning determined by match_type */ | 1409 | __u32 match_chip; /* Match this chip, meaning determined by match_type */ |
| 1394 | __u32 ident; /* chip identifier as specified in <media/v4l2-chip-ident.h> */ | 1410 | __u32 ident; /* chip identifier as specified in <media/v4l2-chip-ident.h> */ |
| @@ -1460,13 +1476,22 @@ struct v4l2_chip_ident { | |||
| 1460 | #define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct v4l2_enc_idx) | 1476 | #define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct v4l2_enc_idx) |
| 1461 | #define VIDIOC_ENCODER_CMD _IOWR('V', 77, struct v4l2_encoder_cmd) | 1477 | #define VIDIOC_ENCODER_CMD _IOWR('V', 77, struct v4l2_encoder_cmd) |
| 1462 | #define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct v4l2_encoder_cmd) | 1478 | #define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct v4l2_encoder_cmd) |
| 1479 | #endif | ||
| 1463 | 1480 | ||
| 1464 | /* Experimental, only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */ | 1481 | #if 1 |
| 1465 | #define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_register) | 1482 | /* Experimental, meant for debugging, testing and internal use. |
| 1466 | #define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_register) | 1483 | Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined. |
| 1467 | 1484 | You must be root to use these ioctls. Never use these in applications! */ | |
| 1468 | #define VIDIOC_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_chip_ident) | 1485 | #define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register) |
| 1486 | #define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register) | ||
| 1487 | |||
| 1488 | /* Experimental, meant for debugging, testing and internal use. | ||
| 1489 | Never use this ioctl in applications! */ | ||
| 1490 | #define VIDIOC_DBG_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_dbg_chip_ident) | ||
| 1491 | /* This is deprecated and will go away in 2.6.30 */ | ||
| 1492 | #define VIDIOC_G_CHIP_IDENT_OLD _IOWR('V', 81, struct v4l2_chip_ident_old) | ||
| 1469 | #endif | 1493 | #endif |
| 1494 | |||
| 1470 | #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) | 1495 | #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) |
| 1471 | /* Reminder: when adding new ioctls please add support for them to | 1496 | /* Reminder: when adding new ioctls please add support for them to |
| 1472 | drivers/media/video/v4l2-compat-ioctl32.c as well! */ | 1497 | drivers/media/video/v4l2-compat-ioctl32.c as well! */ |
diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h index 6bbb0d93bb5f..c8d0b23fde29 100644 --- a/include/media/saa7146_vv.h +++ b/include/media/saa7146_vv.h | |||
| @@ -177,9 +177,9 @@ struct saa7146_ext_vv | |||
| 177 | int (*std_callback)(struct saa7146_dev*, struct saa7146_standard *); | 177 | int (*std_callback)(struct saa7146_dev*, struct saa7146_standard *); |
| 178 | 178 | ||
| 179 | struct saa7146_extension_ioctls *ioctls; | 179 | struct saa7146_extension_ioctls *ioctls; |
| 180 | int (*ioctl)(struct saa7146_fh*, unsigned int cmd, void *arg); | 180 | long (*ioctl)(struct saa7146_fh *, unsigned int cmd, void *arg); |
| 181 | 181 | ||
| 182 | struct file_operations vbi_fops; | 182 | struct v4l2_file_operations vbi_fops; |
| 183 | }; | 183 | }; |
| 184 | 184 | ||
| 185 | struct saa7146_use_ops { | 185 | struct saa7146_use_ops { |
| @@ -216,7 +216,7 @@ void saa7146_set_gpio(struct saa7146_dev *saa, u8 pin, u8 data); | |||
| 216 | extern struct saa7146_use_ops saa7146_video_uops; | 216 | extern struct saa7146_use_ops saa7146_video_uops; |
| 217 | int saa7146_start_preview(struct saa7146_fh *fh); | 217 | int saa7146_start_preview(struct saa7146_fh *fh); |
| 218 | int saa7146_stop_preview(struct saa7146_fh *fh); | 218 | int saa7146_stop_preview(struct saa7146_fh *fh); |
| 219 | int saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg); | 219 | long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg); |
| 220 | 220 | ||
| 221 | /* from saa7146_vbi.c */ | 221 | /* from saa7146_vbi.c */ |
| 222 | extern struct saa7146_use_ops saa7146_vbi_uops; | 222 | extern struct saa7146_use_ops saa7146_vbi_uops; |
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 425b6a98c95c..7440d9250665 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h | |||
| @@ -164,12 +164,12 @@ struct soc_camera_ops { | |||
| 164 | unsigned long (*query_bus_param)(struct soc_camera_device *); | 164 | unsigned long (*query_bus_param)(struct soc_camera_device *); |
| 165 | int (*set_bus_param)(struct soc_camera_device *, unsigned long); | 165 | int (*set_bus_param)(struct soc_camera_device *, unsigned long); |
| 166 | int (*get_chip_id)(struct soc_camera_device *, | 166 | int (*get_chip_id)(struct soc_camera_device *, |
| 167 | struct v4l2_chip_ident *); | 167 | struct v4l2_dbg_chip_ident *); |
| 168 | int (*set_std)(struct soc_camera_device *, v4l2_std_id *); | 168 | int (*set_std)(struct soc_camera_device *, v4l2_std_id *); |
| 169 | int (*enum_input)(struct soc_camera_device *, struct v4l2_input *); | 169 | int (*enum_input)(struct soc_camera_device *, struct v4l2_input *); |
| 170 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 170 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 171 | int (*get_register)(struct soc_camera_device *, struct v4l2_register *); | 171 | int (*get_register)(struct soc_camera_device *, struct v4l2_dbg_register *); |
| 172 | int (*set_register)(struct soc_camera_device *, struct v4l2_register *); | 172 | int (*set_register)(struct soc_camera_device *, struct v4l2_dbg_register *); |
| 173 | #endif | 173 | #endif |
| 174 | int (*get_control)(struct soc_camera_device *, struct v4l2_control *); | 174 | int (*get_control)(struct soc_camera_device *, struct v4l2_control *); |
| 175 | int (*set_control)(struct soc_camera_device *, struct v4l2_control *); | 175 | int (*set_control)(struct soc_camera_device *, struct v4l2_control *); |
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index 43dbb659f1f5..9aaf652b20ef 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | v4l2 chip identifiers header | 2 | v4l2 chip identifiers header |
| 3 | 3 | ||
| 4 | This header provides a list of chip identifiers that can be returned | 4 | This header provides a list of chip identifiers that can be returned |
| 5 | through the VIDIOC_G_CHIP_IDENT ioctl. | 5 | through the VIDIOC_DBG_G_CHIP_IDENT ioctl. |
| 6 | 6 | ||
| 7 | Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> | 7 | Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 8 | 8 | ||
| @@ -24,7 +24,7 @@ | |||
| 24 | #ifndef V4L2_CHIP_IDENT_H_ | 24 | #ifndef V4L2_CHIP_IDENT_H_ |
| 25 | #define V4L2_CHIP_IDENT_H_ | 25 | #define V4L2_CHIP_IDENT_H_ |
| 26 | 26 | ||
| 27 | /* VIDIOC_G_CHIP_IDENT: identifies the actual chip installed on the board */ | 27 | /* VIDIOC_DBG_G_CHIP_IDENT: identifies the actual chip installed on the board */ |
| 28 | enum { | 28 | enum { |
| 29 | /* general idents: reserved range 0-49 */ | 29 | /* general idents: reserved range 0-49 */ |
| 30 | V4L2_IDENT_NONE = 0, /* No chip matched */ | 30 | V4L2_IDENT_NONE = 0, /* No chip matched */ |
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index f99c866d8c37..95e74f1874e1 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h | |||
| @@ -114,10 +114,10 @@ u32 v4l2_ctrl_next(const u32 * const *ctrl_classes, u32 id); | |||
| 114 | /* Register/chip ident helper function */ | 114 | /* Register/chip ident helper function */ |
| 115 | 115 | ||
| 116 | struct i2c_client; /* forward reference */ | 116 | struct i2c_client; /* forward reference */ |
| 117 | int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 id_type, u32 chip_id); | 117 | int v4l2_chip_match_i2c_client(struct i2c_client *c, const struct v4l2_dbg_match *match); |
| 118 | int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chip, | 118 | int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_dbg_chip_ident *chip, |
| 119 | u32 ident, u32 revision); | 119 | u32 ident, u32 revision); |
| 120 | int v4l2_chip_match_host(u32 id_type, u32 chip_id); | 120 | int v4l2_chip_match_host(const struct v4l2_dbg_match *match); |
| 121 | 121 | ||
| 122 | /* ------------------------------------------------------------------------- */ | 122 | /* ------------------------------------------------------------------------- */ |
| 123 | 123 | ||
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 0a88d1d17d30..e36faab8459b 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #define VFL_TYPE_MAX 4 | 25 | #define VFL_TYPE_MAX 4 |
| 26 | 26 | ||
| 27 | struct v4l2_ioctl_callbacks; | 27 | struct v4l2_ioctl_callbacks; |
| 28 | struct video_device; | ||
| 28 | struct v4l2_device; | 29 | struct v4l2_device; |
| 29 | 30 | ||
| 30 | /* Flag to mark the video_device struct as unregistered. | 31 | /* Flag to mark the video_device struct as unregistered. |
| @@ -32,6 +33,18 @@ struct v4l2_device; | |||
| 32 | device access. It is set by video_unregister_device. */ | 33 | device access. It is set by video_unregister_device. */ |
| 33 | #define V4L2_FL_UNREGISTERED (0) | 34 | #define V4L2_FL_UNREGISTERED (0) |
| 34 | 35 | ||
| 36 | struct v4l2_file_operations { | ||
| 37 | struct module *owner; | ||
| 38 | ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); | ||
| 39 | ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); | ||
| 40 | unsigned int (*poll) (struct file *, struct poll_table_struct *); | ||
| 41 | long (*ioctl) (struct file *, unsigned int, unsigned long); | ||
| 42 | long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); | ||
| 43 | int (*mmap) (struct file *, struct vm_area_struct *); | ||
| 44 | int (*open) (struct file *); | ||
| 45 | int (*release) (struct file *); | ||
| 46 | }; | ||
| 47 | |||
| 35 | /* | 48 | /* |
| 36 | * Newer version of video_device, handled by videodev2.c | 49 | * Newer version of video_device, handled by videodev2.c |
| 37 | * This version moves redundant code from video device code to | 50 | * This version moves redundant code from video device code to |
| @@ -41,7 +54,7 @@ struct v4l2_device; | |||
| 41 | struct video_device | 54 | struct video_device |
| 42 | { | 55 | { |
| 43 | /* device ops */ | 56 | /* device ops */ |
| 44 | const struct file_operations *fops; | 57 | const struct v4l2_file_operations *fops; |
| 45 | 58 | ||
| 46 | /* sysfs */ | 59 | /* sysfs */ |
| 47 | struct device dev; /* v4l device */ | 60 | struct device dev; /* v4l device */ |
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h index 97b283a04289..9bf4ccc93dbf 100644 --- a/include/media/v4l2-device.h +++ b/include/media/v4l2-device.h | |||
| @@ -80,7 +80,7 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd); | |||
| 80 | #define __v4l2_device_call_subdevs_until_err(dev, cond, o, f, args...) \ | 80 | #define __v4l2_device_call_subdevs_until_err(dev, cond, o, f, args...) \ |
| 81 | ({ \ | 81 | ({ \ |
| 82 | struct v4l2_subdev *sd; \ | 82 | struct v4l2_subdev *sd; \ |
| 83 | int err = 0; \ | 83 | long err = 0; \ |
| 84 | \ | 84 | \ |
| 85 | list_for_each_entry(sd, &(dev)->subdevs, list) { \ | 85 | list_for_each_entry(sd, &(dev)->subdevs, list) { \ |
| 86 | if ((cond) && sd->ops->o && sd->ops->o->f) \ | 86 | if ((cond) && sd->ops->o && sd->ops->o->f) \ |
diff --git a/include/media/v4l2-int-device.h b/include/media/v4l2-int-device.h index ecda3c725837..fbf585561570 100644 --- a/include/media/v4l2-int-device.h +++ b/include/media/v4l2-int-device.h | |||
| @@ -219,7 +219,7 @@ enum v4l2_int_ioctl_num { | |||
| 219 | vidioc_int_reset_num, | 219 | vidioc_int_reset_num, |
| 220 | /* VIDIOC_INT_INIT */ | 220 | /* VIDIOC_INT_INIT */ |
| 221 | vidioc_int_init_num, | 221 | vidioc_int_init_num, |
| 222 | /* VIDIOC_INT_G_CHIP_IDENT */ | 222 | /* VIDIOC_DBG_G_CHIP_IDENT */ |
| 223 | vidioc_int_g_chip_ident_num, | 223 | vidioc_int_g_chip_ident_num, |
| 224 | 224 | ||
| 225 | /* | 225 | /* |
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index fcdb58c4ce07..b01c044868d0 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h | |||
| @@ -225,12 +225,12 @@ struct v4l2_ioctl_ops { | |||
| 225 | /* Debugging ioctls */ | 225 | /* Debugging ioctls */ |
| 226 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 226 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 227 | int (*vidioc_g_register) (struct file *file, void *fh, | 227 | int (*vidioc_g_register) (struct file *file, void *fh, |
| 228 | struct v4l2_register *reg); | 228 | struct v4l2_dbg_register *reg); |
| 229 | int (*vidioc_s_register) (struct file *file, void *fh, | 229 | int (*vidioc_s_register) (struct file *file, void *fh, |
| 230 | struct v4l2_register *reg); | 230 | struct v4l2_dbg_register *reg); |
| 231 | #endif | 231 | #endif |
| 232 | int (*vidioc_g_chip_ident) (struct file *file, void *fh, | 232 | int (*vidioc_g_chip_ident) (struct file *file, void *fh, |
| 233 | struct v4l2_chip_ident *chip); | 233 | struct v4l2_dbg_chip_ident *chip); |
| 234 | 234 | ||
| 235 | int (*vidioc_enum_framesizes) (struct file *file, void *fh, | 235 | int (*vidioc_enum_framesizes) (struct file *file, void *fh, |
| 236 | struct v4l2_frmsizeenum *fsize); | 236 | struct v4l2_frmsizeenum *fsize); |
| @@ -239,7 +239,7 @@ struct v4l2_ioctl_ops { | |||
| 239 | struct v4l2_frmivalenum *fival); | 239 | struct v4l2_frmivalenum *fival); |
| 240 | 240 | ||
| 241 | /* For other private ioctls */ | 241 | /* For other private ioctls */ |
| 242 | int (*vidioc_default) (struct file *file, void *fh, | 242 | long (*vidioc_default) (struct file *file, void *fh, |
| 243 | int cmd, void *arg); | 243 | int cmd, void *arg); |
| 244 | }; | 244 | }; |
| 245 | 245 | ||
| @@ -277,36 +277,27 @@ extern const char *v4l2_field_names[]; | |||
| 277 | extern const char *v4l2_type_names[]; | 277 | extern const char *v4l2_type_names[]; |
| 278 | 278 | ||
| 279 | /* Compatibility layer interface -- v4l1-compat module */ | 279 | /* Compatibility layer interface -- v4l1-compat module */ |
| 280 | typedef int (*v4l2_kioctl)(struct file *file, | 280 | typedef long (*v4l2_kioctl)(struct file *file, |
| 281 | unsigned int cmd, void *arg); | 281 | unsigned int cmd, void *arg); |
| 282 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 282 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
| 283 | int v4l_compat_translate_ioctl(struct file *file, | 283 | long v4l_compat_translate_ioctl(struct file *file, |
| 284 | int cmd, void *arg, v4l2_kioctl driver_ioctl); | 284 | int cmd, void *arg, v4l2_kioctl driver_ioctl); |
| 285 | #else | 285 | #else |
| 286 | #define v4l_compat_translate_ioctl(file, cmd, arg, ioctl) (-EINVAL) | 286 | #define v4l_compat_translate_ioctl(file, cmd, arg, ioctl) (-EINVAL) |
| 287 | #endif | 287 | #endif |
| 288 | 288 | ||
| 289 | #ifdef CONFIG_COMPAT | ||
| 289 | /* 32 Bits compatibility layer for 64 bits processors */ | 290 | /* 32 Bits compatibility layer for 64 bits processors */ |
| 290 | extern long v4l_compat_ioctl32(struct file *file, unsigned int cmd, | 291 | extern long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, |
| 291 | unsigned long arg); | 292 | unsigned long arg); |
| 293 | #endif | ||
| 292 | 294 | ||
| 293 | /* Include support for obsoleted stuff */ | 295 | /* Include support for obsoleted stuff */ |
| 294 | extern int video_usercopy(struct file *file, unsigned int cmd, | 296 | extern long video_usercopy(struct file *file, unsigned int cmd, |
| 295 | unsigned long arg, v4l2_kioctl func); | 297 | unsigned long arg, v4l2_kioctl func); |
| 296 | 298 | ||
| 297 | /* Standard handlers for V4L ioctl's */ | 299 | /* Standard handlers for V4L ioctl's */ |
| 298 | 300 | extern long video_ioctl2(struct file *file, | |
| 299 | /* This prototype is used on fops.unlocked_ioctl */ | ||
| 300 | extern long __video_ioctl2(struct file *file, | ||
| 301 | unsigned int cmd, unsigned long arg); | ||
| 302 | |||
| 303 | /* This prototype is used on fops.ioctl | ||
| 304 | * Since fops.ioctl enables Kernel Big Lock, it is preferred | ||
| 305 | * to use __video_ioctl2 instead. | ||
| 306 | * It should be noticed that there's no lock code inside | ||
| 307 | * video_ioctl2(). | ||
| 308 | */ | ||
| 309 | extern int video_ioctl2(struct inode *inode, struct file *file, | ||
| 310 | unsigned int cmd, unsigned long arg); | 301 | unsigned int cmd, unsigned long arg); |
| 311 | 302 | ||
| 312 | #endif /* _V4L2_IOCTL_H */ | 303 | #endif /* _V4L2_IOCTL_H */ |
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index ceef016bb0b7..37b09e56e943 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h | |||
| @@ -69,7 +69,7 @@ struct tuner_setup; | |||
| 69 | not yet implemented) since ops provide proper type-checking. | 69 | not yet implemented) since ops provide proper type-checking. |
| 70 | */ | 70 | */ |
| 71 | struct v4l2_subdev_core_ops { | 71 | struct v4l2_subdev_core_ops { |
| 72 | int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip); | 72 | int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip); |
| 73 | int (*log_status)(struct v4l2_subdev *sd); | 73 | int (*log_status)(struct v4l2_subdev *sd); |
| 74 | int (*init)(struct v4l2_subdev *sd, u32 val); | 74 | int (*init)(struct v4l2_subdev *sd, u32 val); |
| 75 | int (*s_standby)(struct v4l2_subdev *sd, u32 standby); | 75 | int (*s_standby)(struct v4l2_subdev *sd, u32 standby); |
| @@ -79,10 +79,10 @@ struct v4l2_subdev_core_ops { | |||
| 79 | int (*g_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl); | 79 | int (*g_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl); |
| 80 | int (*s_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl); | 80 | int (*s_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl); |
| 81 | int (*querymenu)(struct v4l2_subdev *sd, struct v4l2_querymenu *qm); | 81 | int (*querymenu)(struct v4l2_subdev *sd, struct v4l2_querymenu *qm); |
| 82 | int (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg); | 82 | long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg); |
| 83 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 83 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 84 | int (*g_register)(struct v4l2_subdev *sd, struct v4l2_register *reg); | 84 | int (*g_register)(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg); |
| 85 | int (*s_register)(struct v4l2_subdev *sd, struct v4l2_register *reg); | 85 | int (*s_register)(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg); |
| 86 | #endif | 86 | #endif |
| 87 | }; | 87 | }; |
| 88 | 88 | ||
diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h index b6870cbaf2b3..426899e529c5 100644 --- a/include/sound/tea575x-tuner.h +++ b/include/sound/tea575x-tuner.h | |||
| @@ -36,7 +36,7 @@ struct snd_tea575x_ops { | |||
| 36 | struct snd_tea575x { | 36 | struct snd_tea575x { |
| 37 | struct snd_card *card; | 37 | struct snd_card *card; |
| 38 | struct video_device vd; /* video device */ | 38 | struct video_device vd; /* video device */ |
| 39 | struct file_operations fops; | 39 | struct v4l2_file_operations fops; |
| 40 | int dev_nr; /* requested device number + 1 */ | 40 | int dev_nr; /* requested device number + 1 */ |
| 41 | int vd_registered; /* video device is registered */ | 41 | int vd_registered; /* video device is registered */ |
| 42 | int tea5759; /* 5759 chip is present */ | 42 | int tea5759; /* 5759 chip is present */ |
diff --git a/init/main.c b/init/main.c index ad8f9f53f8d1..cd168ebc5924 100644 --- a/init/main.c +++ b/init/main.c | |||
| @@ -371,12 +371,7 @@ EXPORT_SYMBOL(nr_cpu_ids); | |||
| 371 | /* An arch may set nr_cpu_ids earlier if needed, so this would be redundant */ | 371 | /* An arch may set nr_cpu_ids earlier if needed, so this would be redundant */ |
| 372 | static void __init setup_nr_cpu_ids(void) | 372 | static void __init setup_nr_cpu_ids(void) |
| 373 | { | 373 | { |
| 374 | int cpu, highest_cpu = 0; | 374 | nr_cpu_ids = find_last_bit(cpumask_bits(cpu_possible_mask),NR_CPUS) + 1; |
| 375 | |||
| 376 | for_each_possible_cpu(cpu) | ||
| 377 | highest_cpu = cpu; | ||
| 378 | |||
| 379 | nr_cpu_ids = highest_cpu + 1; | ||
| 380 | } | 375 | } |
| 381 | 376 | ||
| 382 | #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA | 377 | #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA |
| @@ -518,9 +513,9 @@ static void __init boot_cpu_init(void) | |||
| 518 | { | 513 | { |
| 519 | int cpu = smp_processor_id(); | 514 | int cpu = smp_processor_id(); |
| 520 | /* Mark the boot cpu "present", "online" etc for SMP and UP case */ | 515 | /* Mark the boot cpu "present", "online" etc for SMP and UP case */ |
| 521 | cpu_set(cpu, cpu_online_map); | 516 | set_cpu_online(cpu, true); |
| 522 | cpu_set(cpu, cpu_present_map); | 517 | set_cpu_present(cpu, true); |
| 523 | cpu_set(cpu, cpu_possible_map); | 518 | set_cpu_possible(cpu, true); |
| 524 | } | 519 | } |
| 525 | 520 | ||
| 526 | void __init __weak smp_setup_processor_id(void) | 521 | void __init __weak smp_setup_processor_id(void) |
diff --git a/kernel/compat.c b/kernel/compat.c index 8eafe3eb50d9..d52e2ec1deb5 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
| @@ -454,16 +454,16 @@ asmlinkage long compat_sys_waitid(int which, compat_pid_t pid, | |||
| 454 | } | 454 | } |
| 455 | 455 | ||
| 456 | static int compat_get_user_cpu_mask(compat_ulong_t __user *user_mask_ptr, | 456 | static int compat_get_user_cpu_mask(compat_ulong_t __user *user_mask_ptr, |
| 457 | unsigned len, cpumask_t *new_mask) | 457 | unsigned len, struct cpumask *new_mask) |
| 458 | { | 458 | { |
| 459 | unsigned long *k; | 459 | unsigned long *k; |
| 460 | 460 | ||
| 461 | if (len < sizeof(cpumask_t)) | 461 | if (len < cpumask_size()) |
| 462 | memset(new_mask, 0, sizeof(cpumask_t)); | 462 | memset(new_mask, 0, cpumask_size()); |
| 463 | else if (len > sizeof(cpumask_t)) | 463 | else if (len > cpumask_size()) |
| 464 | len = sizeof(cpumask_t); | 464 | len = cpumask_size(); |
| 465 | 465 | ||
| 466 | k = cpus_addr(*new_mask); | 466 | k = cpumask_bits(new_mask); |
| 467 | return compat_get_bitmap(k, user_mask_ptr, len * 8); | 467 | return compat_get_bitmap(k, user_mask_ptr, len * 8); |
| 468 | } | 468 | } |
| 469 | 469 | ||
| @@ -471,40 +471,51 @@ asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid, | |||
| 471 | unsigned int len, | 471 | unsigned int len, |
| 472 | compat_ulong_t __user *user_mask_ptr) | 472 | compat_ulong_t __user *user_mask_ptr) |
| 473 | { | 473 | { |
| 474 | cpumask_t new_mask; | 474 | cpumask_var_t new_mask; |
| 475 | int retval; | 475 | int retval; |
| 476 | 476 | ||
| 477 | retval = compat_get_user_cpu_mask(user_mask_ptr, len, &new_mask); | 477 | if (!alloc_cpumask_var(&new_mask, GFP_KERNEL)) |
| 478 | return -ENOMEM; | ||
| 479 | |||
| 480 | retval = compat_get_user_cpu_mask(user_mask_ptr, len, new_mask); | ||
| 478 | if (retval) | 481 | if (retval) |
| 479 | return retval; | 482 | goto out; |
| 480 | 483 | ||
| 481 | return sched_setaffinity(pid, &new_mask); | 484 | retval = sched_setaffinity(pid, new_mask); |
| 485 | out: | ||
| 486 | free_cpumask_var(new_mask); | ||
| 487 | return retval; | ||
| 482 | } | 488 | } |
| 483 | 489 | ||
| 484 | asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len, | 490 | asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len, |
| 485 | compat_ulong_t __user *user_mask_ptr) | 491 | compat_ulong_t __user *user_mask_ptr) |
| 486 | { | 492 | { |
| 487 | int ret; | 493 | int ret; |
| 488 | cpumask_t mask; | 494 | cpumask_var_t mask; |
| 489 | unsigned long *k; | 495 | unsigned long *k; |
| 490 | unsigned int min_length = sizeof(cpumask_t); | 496 | unsigned int min_length = cpumask_size(); |
| 491 | 497 | ||
| 492 | if (NR_CPUS <= BITS_PER_COMPAT_LONG) | 498 | if (nr_cpu_ids <= BITS_PER_COMPAT_LONG) |
| 493 | min_length = sizeof(compat_ulong_t); | 499 | min_length = sizeof(compat_ulong_t); |
| 494 | 500 | ||
| 495 | if (len < min_length) | 501 | if (len < min_length) |
| 496 | return -EINVAL; | 502 | return -EINVAL; |
| 497 | 503 | ||
| 498 | ret = sched_getaffinity(pid, &mask); | 504 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) |
| 505 | return -ENOMEM; | ||
| 506 | |||
| 507 | ret = sched_getaffinity(pid, mask); | ||
| 499 | if (ret < 0) | 508 | if (ret < 0) |
| 500 | return ret; | 509 | goto out; |
| 501 | 510 | ||
| 502 | k = cpus_addr(mask); | 511 | k = cpumask_bits(mask); |
| 503 | ret = compat_put_bitmap(user_mask_ptr, k, min_length * 8); | 512 | ret = compat_put_bitmap(user_mask_ptr, k, min_length * 8); |
| 504 | if (ret) | 513 | if (ret == 0) |
| 505 | return ret; | 514 | ret = min_length; |
| 506 | 515 | ||
| 507 | return min_length; | 516 | out: |
| 517 | free_cpumask_var(mask); | ||
| 518 | return ret; | ||
| 508 | } | 519 | } |
| 509 | 520 | ||
| 510 | int get_compat_itimerspec(struct itimerspec *dst, | 521 | int get_compat_itimerspec(struct itimerspec *dst, |
diff --git a/kernel/cpu.c b/kernel/cpu.c index bae131a1211b..47fff3b63cbf 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
| @@ -15,30 +15,8 @@ | |||
| 15 | #include <linux/stop_machine.h> | 15 | #include <linux/stop_machine.h> |
| 16 | #include <linux/mutex.h> | 16 | #include <linux/mutex.h> |
| 17 | 17 | ||
| 18 | /* | ||
| 19 | * Represents all cpu's present in the system | ||
| 20 | * In systems capable of hotplug, this map could dynamically grow | ||
| 21 | * as new cpu's are detected in the system via any platform specific | ||
| 22 | * method, such as ACPI for e.g. | ||
| 23 | */ | ||
| 24 | cpumask_t cpu_present_map __read_mostly; | ||
| 25 | EXPORT_SYMBOL(cpu_present_map); | ||
| 26 | |||
| 27 | /* | ||
| 28 | * Represents all cpu's that are currently online. | ||
| 29 | */ | ||
| 30 | cpumask_t cpu_online_map __read_mostly; | ||
| 31 | EXPORT_SYMBOL(cpu_online_map); | ||
| 32 | |||
| 33 | #ifdef CONFIG_INIT_ALL_POSSIBLE | ||
| 34 | cpumask_t cpu_possible_map __read_mostly = CPU_MASK_ALL; | ||
| 35 | #else | ||
| 36 | cpumask_t cpu_possible_map __read_mostly; | ||
| 37 | #endif | ||
| 38 | EXPORT_SYMBOL(cpu_possible_map); | ||
| 39 | |||
| 40 | #ifdef CONFIG_SMP | 18 | #ifdef CONFIG_SMP |
| 41 | /* Serializes the updates to cpu_online_map, cpu_present_map */ | 19 | /* Serializes the updates to cpu_online_mask, cpu_present_mask */ |
| 42 | static DEFINE_MUTEX(cpu_add_remove_lock); | 20 | static DEFINE_MUTEX(cpu_add_remove_lock); |
| 43 | 21 | ||
| 44 | static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain); | 22 | static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain); |
| @@ -65,8 +43,6 @@ void __init cpu_hotplug_init(void) | |||
| 65 | cpu_hotplug.refcount = 0; | 43 | cpu_hotplug.refcount = 0; |
| 66 | } | 44 | } |
| 67 | 45 | ||
| 68 | cpumask_t cpu_active_map; | ||
| 69 | |||
| 70 | #ifdef CONFIG_HOTPLUG_CPU | 46 | #ifdef CONFIG_HOTPLUG_CPU |
| 71 | 47 | ||
| 72 | void get_online_cpus(void) | 48 | void get_online_cpus(void) |
| @@ -97,7 +73,7 @@ EXPORT_SYMBOL_GPL(put_online_cpus); | |||
| 97 | 73 | ||
| 98 | /* | 74 | /* |
| 99 | * The following two API's must be used when attempting | 75 | * The following two API's must be used when attempting |
| 100 | * to serialize the updates to cpu_online_map, cpu_present_map. | 76 | * to serialize the updates to cpu_online_mask, cpu_present_mask. |
| 101 | */ | 77 | */ |
| 102 | void cpu_maps_update_begin(void) | 78 | void cpu_maps_update_begin(void) |
| 103 | { | 79 | { |
| @@ -218,7 +194,7 @@ static int __ref take_cpu_down(void *_param) | |||
| 218 | static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) | 194 | static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) |
| 219 | { | 195 | { |
| 220 | int err, nr_calls = 0; | 196 | int err, nr_calls = 0; |
| 221 | cpumask_t old_allowed, tmp; | 197 | cpumask_var_t old_allowed; |
| 222 | void *hcpu = (void *)(long)cpu; | 198 | void *hcpu = (void *)(long)cpu; |
| 223 | unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0; | 199 | unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0; |
| 224 | struct take_cpu_down_param tcd_param = { | 200 | struct take_cpu_down_param tcd_param = { |
| @@ -232,6 +208,9 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) | |||
| 232 | if (!cpu_online(cpu)) | 208 | if (!cpu_online(cpu)) |
| 233 | return -EINVAL; | 209 | return -EINVAL; |
| 234 | 210 | ||
| 211 | if (!alloc_cpumask_var(&old_allowed, GFP_KERNEL)) | ||
| 212 | return -ENOMEM; | ||
| 213 | |||
| 235 | cpu_hotplug_begin(); | 214 | cpu_hotplug_begin(); |
| 236 | err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod, | 215 | err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod, |
| 237 | hcpu, -1, &nr_calls); | 216 | hcpu, -1, &nr_calls); |
| @@ -246,13 +225,11 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) | |||
| 246 | } | 225 | } |
| 247 | 226 | ||
| 248 | /* Ensure that we are not runnable on dying cpu */ | 227 | /* Ensure that we are not runnable on dying cpu */ |
| 249 | old_allowed = current->cpus_allowed; | 228 | cpumask_copy(old_allowed, ¤t->cpus_allowed); |
| 250 | cpus_setall(tmp); | 229 | set_cpus_allowed_ptr(current, |
| 251 | cpu_clear(cpu, tmp); | 230 | cpumask_of(cpumask_any_but(cpu_online_mask, cpu))); |
| 252 | set_cpus_allowed_ptr(current, &tmp); | ||
| 253 | tmp = cpumask_of_cpu(cpu); | ||
| 254 | 231 | ||
| 255 | err = __stop_machine(take_cpu_down, &tcd_param, &tmp); | 232 | err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu)); |
| 256 | if (err) { | 233 | if (err) { |
| 257 | /* CPU didn't die: tell everyone. Can't complain. */ | 234 | /* CPU didn't die: tell everyone. Can't complain. */ |
| 258 | if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod, | 235 | if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod, |
| @@ -278,7 +255,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) | |||
| 278 | check_for_tasks(cpu); | 255 | check_for_tasks(cpu); |
| 279 | 256 | ||
| 280 | out_allowed: | 257 | out_allowed: |
| 281 | set_cpus_allowed_ptr(current, &old_allowed); | 258 | set_cpus_allowed_ptr(current, old_allowed); |
| 282 | out_release: | 259 | out_release: |
| 283 | cpu_hotplug_done(); | 260 | cpu_hotplug_done(); |
| 284 | if (!err) { | 261 | if (!err) { |
| @@ -286,6 +263,7 @@ out_release: | |||
| 286 | hcpu) == NOTIFY_BAD) | 263 | hcpu) == NOTIFY_BAD) |
| 287 | BUG(); | 264 | BUG(); |
| 288 | } | 265 | } |
| 266 | free_cpumask_var(old_allowed); | ||
| 289 | return err; | 267 | return err; |
| 290 | } | 268 | } |
| 291 | 269 | ||
| @@ -304,7 +282,7 @@ int __ref cpu_down(unsigned int cpu) | |||
| 304 | 282 | ||
| 305 | /* | 283 | /* |
| 306 | * Make sure the all cpus did the reschedule and are not | 284 | * Make sure the all cpus did the reschedule and are not |
| 307 | * using stale version of the cpu_active_map. | 285 | * using stale version of the cpu_active_mask. |
| 308 | * This is not strictly necessary becuase stop_machine() | 286 | * This is not strictly necessary becuase stop_machine() |
| 309 | * that we run down the line already provides the required | 287 | * that we run down the line already provides the required |
| 310 | * synchronization. But it's really a side effect and we do not | 288 | * synchronization. But it's really a side effect and we do not |
| @@ -368,7 +346,7 @@ out_notify: | |||
| 368 | int __cpuinit cpu_up(unsigned int cpu) | 346 | int __cpuinit cpu_up(unsigned int cpu) |
| 369 | { | 347 | { |
| 370 | int err = 0; | 348 | int err = 0; |
| 371 | if (!cpu_isset(cpu, cpu_possible_map)) { | 349 | if (!cpu_possible(cpu)) { |
| 372 | printk(KERN_ERR "can't online cpu %d because it is not " | 350 | printk(KERN_ERR "can't online cpu %d because it is not " |
| 373 | "configured as may-hotadd at boot time\n", cpu); | 351 | "configured as may-hotadd at boot time\n", cpu); |
| 374 | #if defined(CONFIG_IA64) || defined(CONFIG_X86_64) | 352 | #if defined(CONFIG_IA64) || defined(CONFIG_X86_64) |
| @@ -393,25 +371,25 @@ out: | |||
| 393 | } | 371 | } |
| 394 | 372 | ||
| 395 | #ifdef CONFIG_PM_SLEEP_SMP | 373 | #ifdef CONFIG_PM_SLEEP_SMP |
| 396 | static cpumask_t frozen_cpus; | 374 | static cpumask_var_t frozen_cpus; |
| 397 | 375 | ||
| 398 | int disable_nonboot_cpus(void) | 376 | int disable_nonboot_cpus(void) |
| 399 | { | 377 | { |
| 400 | int cpu, first_cpu, error = 0; | 378 | int cpu, first_cpu, error = 0; |
| 401 | 379 | ||
| 402 | cpu_maps_update_begin(); | 380 | cpu_maps_update_begin(); |
| 403 | first_cpu = first_cpu(cpu_online_map); | 381 | first_cpu = cpumask_first(cpu_online_mask); |
| 404 | /* We take down all of the non-boot CPUs in one shot to avoid races | 382 | /* We take down all of the non-boot CPUs in one shot to avoid races |
| 405 | * with the userspace trying to use the CPU hotplug at the same time | 383 | * with the userspace trying to use the CPU hotplug at the same time |
| 406 | */ | 384 | */ |
| 407 | cpus_clear(frozen_cpus); | 385 | cpumask_clear(frozen_cpus); |
| 408 | printk("Disabling non-boot CPUs ...\n"); | 386 | printk("Disabling non-boot CPUs ...\n"); |
| 409 | for_each_online_cpu(cpu) { | 387 | for_each_online_cpu(cpu) { |
| 410 | if (cpu == first_cpu) | 388 | if (cpu == first_cpu) |
| 411 | continue; | 389 | continue; |
| 412 | error = _cpu_down(cpu, 1); | 390 | error = _cpu_down(cpu, 1); |
| 413 | if (!error) { | 391 | if (!error) { |
| 414 | cpu_set(cpu, frozen_cpus); | 392 | cpumask_set_cpu(cpu, frozen_cpus); |
| 415 | printk("CPU%d is down\n", cpu); | 393 | printk("CPU%d is down\n", cpu); |
| 416 | } else { | 394 | } else { |
| 417 | printk(KERN_ERR "Error taking CPU%d down: %d\n", | 395 | printk(KERN_ERR "Error taking CPU%d down: %d\n", |
| @@ -437,11 +415,11 @@ void __ref enable_nonboot_cpus(void) | |||
| 437 | /* Allow everyone to use the CPU hotplug again */ | 415 | /* Allow everyone to use the CPU hotplug again */ |
| 438 | cpu_maps_update_begin(); | 416 | cpu_maps_update_begin(); |
| 439 | cpu_hotplug_disabled = 0; | 417 | cpu_hotplug_disabled = 0; |
| 440 | if (cpus_empty(frozen_cpus)) | 418 | if (cpumask_empty(frozen_cpus)) |
| 441 | goto out; | 419 | goto out; |
| 442 | 420 | ||
| 443 | printk("Enabling non-boot CPUs ...\n"); | 421 | printk("Enabling non-boot CPUs ...\n"); |
| 444 | for_each_cpu_mask_nr(cpu, frozen_cpus) { | 422 | for_each_cpu(cpu, frozen_cpus) { |
| 445 | error = _cpu_up(cpu, 1); | 423 | error = _cpu_up(cpu, 1); |
| 446 | if (!error) { | 424 | if (!error) { |
| 447 | printk("CPU%d is up\n", cpu); | 425 | printk("CPU%d is up\n", cpu); |
| @@ -449,10 +427,18 @@ void __ref enable_nonboot_cpus(void) | |||
| 449 | } | 427 | } |
| 450 | printk(KERN_WARNING "Error taking CPU%d up: %d\n", cpu, error); | 428 | printk(KERN_WARNING "Error taking CPU%d up: %d\n", cpu, error); |
| 451 | } | 429 | } |
| 452 | cpus_clear(frozen_cpus); | 430 | cpumask_clear(frozen_cpus); |
| 453 | out: | 431 | out: |
| 454 | cpu_maps_update_done(); | 432 | cpu_maps_update_done(); |
| 455 | } | 433 | } |
| 434 | |||
| 435 | static int alloc_frozen_cpus(void) | ||
| 436 | { | ||
| 437 | if (!alloc_cpumask_var(&frozen_cpus, GFP_KERNEL|__GFP_ZERO)) | ||
| 438 | return -ENOMEM; | ||
| 439 | return 0; | ||
| 440 | } | ||
| 441 | core_initcall(alloc_frozen_cpus); | ||
| 456 | #endif /* CONFIG_PM_SLEEP_SMP */ | 442 | #endif /* CONFIG_PM_SLEEP_SMP */ |
| 457 | 443 | ||
| 458 | /** | 444 | /** |
| @@ -468,7 +454,7 @@ void __cpuinit notify_cpu_starting(unsigned int cpu) | |||
| 468 | unsigned long val = CPU_STARTING; | 454 | unsigned long val = CPU_STARTING; |
| 469 | 455 | ||
| 470 | #ifdef CONFIG_PM_SLEEP_SMP | 456 | #ifdef CONFIG_PM_SLEEP_SMP |
| 471 | if (cpu_isset(cpu, frozen_cpus)) | 457 | if (frozen_cpus != NULL && cpumask_test_cpu(cpu, frozen_cpus)) |
| 472 | val = CPU_STARTING_FROZEN; | 458 | val = CPU_STARTING_FROZEN; |
| 473 | #endif /* CONFIG_PM_SLEEP_SMP */ | 459 | #endif /* CONFIG_PM_SLEEP_SMP */ |
| 474 | raw_notifier_call_chain(&cpu_chain, val, (void *)(long)cpu); | 460 | raw_notifier_call_chain(&cpu_chain, val, (void *)(long)cpu); |
| @@ -480,7 +466,7 @@ void __cpuinit notify_cpu_starting(unsigned int cpu) | |||
| 480 | * cpu_bit_bitmap[] is a special, "compressed" data structure that | 466 | * cpu_bit_bitmap[] is a special, "compressed" data structure that |
| 481 | * represents all NR_CPUS bits binary values of 1<<nr. | 467 | * represents all NR_CPUS bits binary values of 1<<nr. |
| 482 | * | 468 | * |
| 483 | * It is used by cpumask_of_cpu() to get a constant address to a CPU | 469 | * It is used by cpumask_of() to get a constant address to a CPU |
| 484 | * mask value that has a single bit set only. | 470 | * mask value that has a single bit set only. |
| 485 | */ | 471 | */ |
| 486 | 472 | ||
| @@ -503,3 +489,71 @@ EXPORT_SYMBOL_GPL(cpu_bit_bitmap); | |||
| 503 | 489 | ||
| 504 | const DECLARE_BITMAP(cpu_all_bits, NR_CPUS) = CPU_BITS_ALL; | 490 | const DECLARE_BITMAP(cpu_all_bits, NR_CPUS) = CPU_BITS_ALL; |
| 505 | EXPORT_SYMBOL(cpu_all_bits); | 491 | EXPORT_SYMBOL(cpu_all_bits); |
| 492 | |||
| 493 | #ifdef CONFIG_INIT_ALL_POSSIBLE | ||
| 494 | static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly | ||
| 495 | = CPU_BITS_ALL; | ||
| 496 | #else | ||
| 497 | static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly; | ||
| 498 | #endif | ||
| 499 | const struct cpumask *const cpu_possible_mask = to_cpumask(cpu_possible_bits); | ||
| 500 | EXPORT_SYMBOL(cpu_possible_mask); | ||
| 501 | |||
| 502 | static DECLARE_BITMAP(cpu_online_bits, CONFIG_NR_CPUS) __read_mostly; | ||
| 503 | const struct cpumask *const cpu_online_mask = to_cpumask(cpu_online_bits); | ||
| 504 | EXPORT_SYMBOL(cpu_online_mask); | ||
| 505 | |||
| 506 | static DECLARE_BITMAP(cpu_present_bits, CONFIG_NR_CPUS) __read_mostly; | ||
| 507 | const struct cpumask *const cpu_present_mask = to_cpumask(cpu_present_bits); | ||
| 508 | EXPORT_SYMBOL(cpu_present_mask); | ||
| 509 | |||
| 510 | static DECLARE_BITMAP(cpu_active_bits, CONFIG_NR_CPUS) __read_mostly; | ||
| 511 | const struct cpumask *const cpu_active_mask = to_cpumask(cpu_active_bits); | ||
| 512 | EXPORT_SYMBOL(cpu_active_mask); | ||
| 513 | |||
| 514 | void set_cpu_possible(unsigned int cpu, bool possible) | ||
| 515 | { | ||
| 516 | if (possible) | ||
| 517 | cpumask_set_cpu(cpu, to_cpumask(cpu_possible_bits)); | ||
| 518 | else | ||
| 519 | cpumask_clear_cpu(cpu, to_cpumask(cpu_possible_bits)); | ||
| 520 | } | ||
| 521 | |||
| 522 | void set_cpu_present(unsigned int cpu, bool present) | ||
| 523 | { | ||
| 524 | if (present) | ||
| 525 | cpumask_set_cpu(cpu, to_cpumask(cpu_present_bits)); | ||
| 526 | else | ||
| 527 | cpumask_clear_cpu(cpu, to_cpumask(cpu_present_bits)); | ||
| 528 | } | ||
| 529 | |||
| 530 | void set_cpu_online(unsigned int cpu, bool online) | ||
| 531 | { | ||
| 532 | if (online) | ||
| 533 | cpumask_set_cpu(cpu, to_cpumask(cpu_online_bits)); | ||
| 534 | else | ||
| 535 | cpumask_clear_cpu(cpu, to_cpumask(cpu_online_bits)); | ||
| 536 | } | ||
| 537 | |||
| 538 | void set_cpu_active(unsigned int cpu, bool active) | ||
| 539 | { | ||
| 540 | if (active) | ||
| 541 | cpumask_set_cpu(cpu, to_cpumask(cpu_active_bits)); | ||
| 542 | else | ||
| 543 | cpumask_clear_cpu(cpu, to_cpumask(cpu_active_bits)); | ||
| 544 | } | ||
| 545 | |||
| 546 | void init_cpu_present(const struct cpumask *src) | ||
| 547 | { | ||
| 548 | cpumask_copy(to_cpumask(cpu_present_bits), src); | ||
| 549 | } | ||
| 550 | |||
| 551 | void init_cpu_possible(const struct cpumask *src) | ||
| 552 | { | ||
| 553 | cpumask_copy(to_cpumask(cpu_possible_bits), src); | ||
| 554 | } | ||
| 555 | |||
| 556 | void init_cpu_online(const struct cpumask *src) | ||
| 557 | { | ||
| 558 | cpumask_copy(to_cpumask(cpu_online_bits), src); | ||
| 559 | } | ||
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 61c4a9b62165..cd0cd8dcb345 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
| @@ -16,8 +16,15 @@ | |||
| 16 | #include "internals.h" | 16 | #include "internals.h" |
| 17 | 17 | ||
| 18 | #ifdef CONFIG_SMP | 18 | #ifdef CONFIG_SMP |
| 19 | cpumask_var_t irq_default_affinity; | ||
| 19 | 20 | ||
| 20 | cpumask_t irq_default_affinity = CPU_MASK_ALL; | 21 | static int init_irq_default_affinity(void) |
| 22 | { | ||
| 23 | alloc_cpumask_var(&irq_default_affinity, GFP_KERNEL); | ||
| 24 | cpumask_setall(irq_default_affinity); | ||
| 25 | return 0; | ||
| 26 | } | ||
| 27 | core_initcall(init_irq_default_affinity); | ||
| 21 | 28 | ||
| 22 | /** | 29 | /** |
| 23 | * synchronize_irq - wait for pending IRQ handlers (on other CPUs) | 30 | * synchronize_irq - wait for pending IRQ handlers (on other CPUs) |
| @@ -127,7 +134,7 @@ int do_irq_select_affinity(unsigned int irq, struct irq_desc *desc) | |||
| 127 | desc->status &= ~IRQ_AFFINITY_SET; | 134 | desc->status &= ~IRQ_AFFINITY_SET; |
| 128 | } | 135 | } |
| 129 | 136 | ||
| 130 | cpumask_and(&desc->affinity, cpu_online_mask, &irq_default_affinity); | 137 | cpumask_and(&desc->affinity, cpu_online_mask, irq_default_affinity); |
| 131 | set_affinity: | 138 | set_affinity: |
| 132 | desc->chip->set_affinity(irq, &desc->affinity); | 139 | desc->chip->set_affinity(irq, &desc->affinity); |
| 133 | 140 | ||
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index d2c0e5ee53c5..aae3f742bcec 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c | |||
| @@ -20,7 +20,7 @@ static struct proc_dir_entry *root_irq_dir; | |||
| 20 | static int irq_affinity_proc_show(struct seq_file *m, void *v) | 20 | static int irq_affinity_proc_show(struct seq_file *m, void *v) |
| 21 | { | 21 | { |
| 22 | struct irq_desc *desc = irq_to_desc((long)m->private); | 22 | struct irq_desc *desc = irq_to_desc((long)m->private); |
| 23 | cpumask_t *mask = &desc->affinity; | 23 | const struct cpumask *mask = &desc->affinity; |
| 24 | 24 | ||
| 25 | #ifdef CONFIG_GENERIC_PENDING_IRQ | 25 | #ifdef CONFIG_GENERIC_PENDING_IRQ |
| 26 | if (desc->status & IRQ_MOVE_PENDING) | 26 | if (desc->status & IRQ_MOVE_PENDING) |
| @@ -54,7 +54,7 @@ static ssize_t irq_affinity_proc_write(struct file *file, | |||
| 54 | if (err) | 54 | if (err) |
| 55 | goto free_cpumask; | 55 | goto free_cpumask; |
| 56 | 56 | ||
| 57 | if (!is_affinity_mask_valid(*new_value)) { | 57 | if (!is_affinity_mask_valid(new_value)) { |
| 58 | err = -EINVAL; | 58 | err = -EINVAL; |
| 59 | goto free_cpumask; | 59 | goto free_cpumask; |
| 60 | } | 60 | } |
| @@ -93,7 +93,7 @@ static const struct file_operations irq_affinity_proc_fops = { | |||
| 93 | 93 | ||
| 94 | static int default_affinity_show(struct seq_file *m, void *v) | 94 | static int default_affinity_show(struct seq_file *m, void *v) |
| 95 | { | 95 | { |
| 96 | seq_cpumask(m, &irq_default_affinity); | 96 | seq_cpumask(m, irq_default_affinity); |
| 97 | seq_putc(m, '\n'); | 97 | seq_putc(m, '\n'); |
| 98 | return 0; | 98 | return 0; |
| 99 | } | 99 | } |
| @@ -101,27 +101,37 @@ static int default_affinity_show(struct seq_file *m, void *v) | |||
| 101 | static ssize_t default_affinity_write(struct file *file, | 101 | static ssize_t default_affinity_write(struct file *file, |
| 102 | const char __user *buffer, size_t count, loff_t *ppos) | 102 | const char __user *buffer, size_t count, loff_t *ppos) |
| 103 | { | 103 | { |
| 104 | cpumask_t new_value; | 104 | cpumask_var_t new_value; |
| 105 | int err; | 105 | int err; |
| 106 | 106 | ||
| 107 | err = cpumask_parse_user(buffer, count, &new_value); | 107 | if (!alloc_cpumask_var(&new_value, GFP_KERNEL)) |
| 108 | return -ENOMEM; | ||
| 109 | |||
| 110 | err = cpumask_parse_user(buffer, count, new_value); | ||
| 108 | if (err) | 111 | if (err) |
| 109 | return err; | 112 | goto out; |
| 110 | 113 | ||
| 111 | if (!is_affinity_mask_valid(new_value)) | 114 | if (!is_affinity_mask_valid(new_value)) { |
| 112 | return -EINVAL; | 115 | err = -EINVAL; |
| 116 | goto out; | ||
| 117 | } | ||
| 113 | 118 | ||
| 114 | /* | 119 | /* |
| 115 | * Do not allow disabling IRQs completely - it's a too easy | 120 | * Do not allow disabling IRQs completely - it's a too easy |
| 116 | * way to make the system unusable accidentally :-) At least | 121 | * way to make the system unusable accidentally :-) At least |
| 117 | * one online CPU still has to be targeted. | 122 | * one online CPU still has to be targeted. |
| 118 | */ | 123 | */ |
| 119 | if (!cpus_intersects(new_value, cpu_online_map)) | 124 | if (!cpumask_intersects(new_value, cpu_online_mask)) { |
| 120 | return -EINVAL; | 125 | err = -EINVAL; |
| 126 | goto out; | ||
| 127 | } | ||
| 121 | 128 | ||
| 122 | irq_default_affinity = new_value; | 129 | cpumask_copy(irq_default_affinity, new_value); |
| 130 | err = count; | ||
| 123 | 131 | ||
| 124 | return count; | 132 | out: |
| 133 | free_cpumask_var(new_value); | ||
| 134 | return err; | ||
| 125 | } | 135 | } |
| 126 | 136 | ||
| 127 | static int default_affinity_open(struct inode *inode, struct file *file) | 137 | static int default_affinity_open(struct inode *inode, struct file *file) |
diff --git a/kernel/kexec.c b/kernel/kexec.c index ac0fde7b54d0..3fb855ad6aa0 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
| @@ -1116,7 +1116,7 @@ void crash_save_cpu(struct pt_regs *regs, int cpu) | |||
| 1116 | struct elf_prstatus prstatus; | 1116 | struct elf_prstatus prstatus; |
| 1117 | u32 *buf; | 1117 | u32 *buf; |
| 1118 | 1118 | ||
| 1119 | if ((cpu < 0) || (cpu >= NR_CPUS)) | 1119 | if ((cpu < 0) || (cpu >= nr_cpu_ids)) |
| 1120 | return; | 1120 | return; |
| 1121 | 1121 | ||
| 1122 | /* Using ELF notes here is opportunistic. | 1122 | /* Using ELF notes here is opportunistic. |
diff --git a/kernel/power/poweroff.c b/kernel/power/poweroff.c index 72016f051477..97890831e1b5 100644 --- a/kernel/power/poweroff.c +++ b/kernel/power/poweroff.c | |||
| @@ -27,7 +27,7 @@ static DECLARE_WORK(poweroff_work, do_poweroff); | |||
| 27 | static void handle_poweroff(int key, struct tty_struct *tty) | 27 | static void handle_poweroff(int key, struct tty_struct *tty) |
| 28 | { | 28 | { |
| 29 | /* run sysrq poweroff on boot cpu */ | 29 | /* run sysrq poweroff on boot cpu */ |
| 30 | schedule_work_on(first_cpu(cpu_online_map), &poweroff_work); | 30 | schedule_work_on(cpumask_first(cpu_online_mask), &poweroff_work); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | static struct sysrq_key_op sysrq_poweroff_op = { | 33 | static struct sysrq_key_op sysrq_poweroff_op = { |
diff --git a/kernel/profile.c b/kernel/profile.c index 4cb7d68fed82..d18e2d2654f2 100644 --- a/kernel/profile.c +++ b/kernel/profile.c | |||
| @@ -45,7 +45,7 @@ static unsigned long prof_len, prof_shift; | |||
| 45 | int prof_on __read_mostly; | 45 | int prof_on __read_mostly; |
| 46 | EXPORT_SYMBOL_GPL(prof_on); | 46 | EXPORT_SYMBOL_GPL(prof_on); |
| 47 | 47 | ||
| 48 | static cpumask_t prof_cpu_mask = CPU_MASK_ALL; | 48 | static cpumask_var_t prof_cpu_mask; |
| 49 | #ifdef CONFIG_SMP | 49 | #ifdef CONFIG_SMP |
| 50 | static DEFINE_PER_CPU(struct profile_hit *[2], cpu_profile_hits); | 50 | static DEFINE_PER_CPU(struct profile_hit *[2], cpu_profile_hits); |
| 51 | static DEFINE_PER_CPU(int, cpu_profile_flip); | 51 | static DEFINE_PER_CPU(int, cpu_profile_flip); |
| @@ -113,9 +113,13 @@ int __ref profile_init(void) | |||
| 113 | buffer_bytes = prof_len*sizeof(atomic_t); | 113 | buffer_bytes = prof_len*sizeof(atomic_t); |
| 114 | if (!slab_is_available()) { | 114 | if (!slab_is_available()) { |
| 115 | prof_buffer = alloc_bootmem(buffer_bytes); | 115 | prof_buffer = alloc_bootmem(buffer_bytes); |
| 116 | alloc_bootmem_cpumask_var(&prof_cpu_mask); | ||
| 116 | return 0; | 117 | return 0; |
| 117 | } | 118 | } |
| 118 | 119 | ||
| 120 | if (!alloc_cpumask_var(&prof_cpu_mask, GFP_KERNEL)) | ||
| 121 | return -ENOMEM; | ||
| 122 | |||
| 119 | prof_buffer = kzalloc(buffer_bytes, GFP_KERNEL); | 123 | prof_buffer = kzalloc(buffer_bytes, GFP_KERNEL); |
| 120 | if (prof_buffer) | 124 | if (prof_buffer) |
| 121 | return 0; | 125 | return 0; |
| @@ -128,6 +132,7 @@ int __ref profile_init(void) | |||
| 128 | if (prof_buffer) | 132 | if (prof_buffer) |
| 129 | return 0; | 133 | return 0; |
| 130 | 134 | ||
| 135 | free_cpumask_var(prof_cpu_mask); | ||
| 131 | return -ENOMEM; | 136 | return -ENOMEM; |
| 132 | } | 137 | } |
| 133 | 138 | ||
| @@ -386,13 +391,15 @@ out_free: | |||
| 386 | return NOTIFY_BAD; | 391 | return NOTIFY_BAD; |
| 387 | case CPU_ONLINE: | 392 | case CPU_ONLINE: |
| 388 | case CPU_ONLINE_FROZEN: | 393 | case CPU_ONLINE_FROZEN: |
| 389 | cpu_set(cpu, prof_cpu_mask); | 394 | if (prof_cpu_mask != NULL) |
| 395 | cpumask_set_cpu(cpu, prof_cpu_mask); | ||
| 390 | break; | 396 | break; |
| 391 | case CPU_UP_CANCELED: | 397 | case CPU_UP_CANCELED: |
| 392 | case CPU_UP_CANCELED_FROZEN: | 398 | case CPU_UP_CANCELED_FROZEN: |
| 393 | case CPU_DEAD: | 399 | case CPU_DEAD: |
| 394 | case CPU_DEAD_FROZEN: | 400 | case CPU_DEAD_FROZEN: |
| 395 | cpu_clear(cpu, prof_cpu_mask); | 401 | if (prof_cpu_mask != NULL) |
| 402 | cpumask_clear_cpu(cpu, prof_cpu_mask); | ||
| 396 | if (per_cpu(cpu_profile_hits, cpu)[0]) { | 403 | if (per_cpu(cpu_profile_hits, cpu)[0]) { |
| 397 | page = virt_to_page(per_cpu(cpu_profile_hits, cpu)[0]); | 404 | page = virt_to_page(per_cpu(cpu_profile_hits, cpu)[0]); |
| 398 | per_cpu(cpu_profile_hits, cpu)[0] = NULL; | 405 | per_cpu(cpu_profile_hits, cpu)[0] = NULL; |
| @@ -430,7 +437,8 @@ void profile_tick(int type) | |||
| 430 | 437 | ||
| 431 | if (type == CPU_PROFILING && timer_hook) | 438 | if (type == CPU_PROFILING && timer_hook) |
| 432 | timer_hook(regs); | 439 | timer_hook(regs); |
| 433 | if (!user_mode(regs) && cpu_isset(smp_processor_id(), prof_cpu_mask)) | 440 | if (!user_mode(regs) && prof_cpu_mask != NULL && |
| 441 | cpumask_test_cpu(smp_processor_id(), prof_cpu_mask)) | ||
| 434 | profile_hit(type, (void *)profile_pc(regs)); | 442 | profile_hit(type, (void *)profile_pc(regs)); |
| 435 | } | 443 | } |
| 436 | 444 | ||
| @@ -442,7 +450,7 @@ void profile_tick(int type) | |||
| 442 | static int prof_cpu_mask_read_proc(char *page, char **start, off_t off, | 450 | static int prof_cpu_mask_read_proc(char *page, char **start, off_t off, |
| 443 | int count, int *eof, void *data) | 451 | int count, int *eof, void *data) |
| 444 | { | 452 | { |
| 445 | int len = cpumask_scnprintf(page, count, (cpumask_t *)data); | 453 | int len = cpumask_scnprintf(page, count, data); |
| 446 | if (count - len < 2) | 454 | if (count - len < 2) |
| 447 | return -EINVAL; | 455 | return -EINVAL; |
| 448 | len += sprintf(page + len, "\n"); | 456 | len += sprintf(page + len, "\n"); |
| @@ -452,16 +460,20 @@ static int prof_cpu_mask_read_proc(char *page, char **start, off_t off, | |||
| 452 | static int prof_cpu_mask_write_proc(struct file *file, | 460 | static int prof_cpu_mask_write_proc(struct file *file, |
| 453 | const char __user *buffer, unsigned long count, void *data) | 461 | const char __user *buffer, unsigned long count, void *data) |
| 454 | { | 462 | { |
| 455 | cpumask_t *mask = (cpumask_t *)data; | 463 | struct cpumask *mask = data; |
| 456 | unsigned long full_count = count, err; | 464 | unsigned long full_count = count, err; |
| 457 | cpumask_t new_value; | 465 | cpumask_var_t new_value; |
| 458 | 466 | ||
| 459 | err = cpumask_parse_user(buffer, count, &new_value); | 467 | if (!alloc_cpumask_var(&new_value, GFP_KERNEL)) |
| 460 | if (err) | 468 | return -ENOMEM; |
| 461 | return err; | ||
| 462 | 469 | ||
| 463 | *mask = new_value; | 470 | err = cpumask_parse_user(buffer, count, new_value); |
| 464 | return full_count; | 471 | if (!err) { |
| 472 | cpumask_copy(mask, new_value); | ||
| 473 | err = full_count; | ||
| 474 | } | ||
| 475 | free_cpumask_var(new_value); | ||
| 476 | return err; | ||
| 465 | } | 477 | } |
| 466 | 478 | ||
| 467 | void create_prof_cpu_mask(struct proc_dir_entry *root_irq_dir) | 479 | void create_prof_cpu_mask(struct proc_dir_entry *root_irq_dir) |
| @@ -472,7 +484,7 @@ void create_prof_cpu_mask(struct proc_dir_entry *root_irq_dir) | |||
| 472 | entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir); | 484 | entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir); |
| 473 | if (!entry) | 485 | if (!entry) |
| 474 | return; | 486 | return; |
| 475 | entry->data = (void *)&prof_cpu_mask; | 487 | entry->data = prof_cpu_mask; |
| 476 | entry->read_proc = prof_cpu_mask_read_proc; | 488 | entry->read_proc = prof_cpu_mask_read_proc; |
| 477 | entry->write_proc = prof_cpu_mask_write_proc; | 489 | entry->write_proc = prof_cpu_mask_write_proc; |
| 478 | } | 490 | } |
diff --git a/kernel/rcuclassic.c b/kernel/rcuclassic.c index c03ca3e61919..490934fc7ac3 100644 --- a/kernel/rcuclassic.c +++ b/kernel/rcuclassic.c | |||
| @@ -63,14 +63,14 @@ static struct rcu_ctrlblk rcu_ctrlblk = { | |||
| 63 | .completed = -300, | 63 | .completed = -300, |
| 64 | .pending = -300, | 64 | .pending = -300, |
| 65 | .lock = __SPIN_LOCK_UNLOCKED(&rcu_ctrlblk.lock), | 65 | .lock = __SPIN_LOCK_UNLOCKED(&rcu_ctrlblk.lock), |
| 66 | .cpumask = CPU_MASK_NONE, | 66 | .cpumask = CPU_BITS_NONE, |
| 67 | }; | 67 | }; |
| 68 | static struct rcu_ctrlblk rcu_bh_ctrlblk = { | 68 | static struct rcu_ctrlblk rcu_bh_ctrlblk = { |
| 69 | .cur = -300, | 69 | .cur = -300, |
| 70 | .completed = -300, | 70 | .completed = -300, |
| 71 | .pending = -300, | 71 | .pending = -300, |
| 72 | .lock = __SPIN_LOCK_UNLOCKED(&rcu_bh_ctrlblk.lock), | 72 | .lock = __SPIN_LOCK_UNLOCKED(&rcu_bh_ctrlblk.lock), |
| 73 | .cpumask = CPU_MASK_NONE, | 73 | .cpumask = CPU_BITS_NONE, |
| 74 | }; | 74 | }; |
| 75 | 75 | ||
| 76 | DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L }; | 76 | DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L }; |
| @@ -85,7 +85,6 @@ static void force_quiescent_state(struct rcu_data *rdp, | |||
| 85 | struct rcu_ctrlblk *rcp) | 85 | struct rcu_ctrlblk *rcp) |
| 86 | { | 86 | { |
| 87 | int cpu; | 87 | int cpu; |
| 88 | cpumask_t cpumask; | ||
| 89 | unsigned long flags; | 88 | unsigned long flags; |
| 90 | 89 | ||
| 91 | set_need_resched(); | 90 | set_need_resched(); |
| @@ -96,10 +95,10 @@ static void force_quiescent_state(struct rcu_data *rdp, | |||
| 96 | * Don't send IPI to itself. With irqs disabled, | 95 | * Don't send IPI to itself. With irqs disabled, |
| 97 | * rdp->cpu is the current cpu. | 96 | * rdp->cpu is the current cpu. |
| 98 | * | 97 | * |
| 99 | * cpu_online_map is updated by the _cpu_down() | 98 | * cpu_online_mask is updated by the _cpu_down() |
| 100 | * using __stop_machine(). Since we're in irqs disabled | 99 | * using __stop_machine(). Since we're in irqs disabled |
| 101 | * section, __stop_machine() is not exectuting, hence | 100 | * section, __stop_machine() is not exectuting, hence |
| 102 | * the cpu_online_map is stable. | 101 | * the cpu_online_mask is stable. |
| 103 | * | 102 | * |
| 104 | * However, a cpu might have been offlined _just_ before | 103 | * However, a cpu might have been offlined _just_ before |
| 105 | * we disabled irqs while entering here. | 104 | * we disabled irqs while entering here. |
| @@ -107,13 +106,14 @@ static void force_quiescent_state(struct rcu_data *rdp, | |||
| 107 | * notification, leading to the offlined cpu's bit | 106 | * notification, leading to the offlined cpu's bit |
| 108 | * being set in the rcp->cpumask. | 107 | * being set in the rcp->cpumask. |
| 109 | * | 108 | * |
| 110 | * Hence cpumask = (rcp->cpumask & cpu_online_map) to prevent | 109 | * Hence cpumask = (rcp->cpumask & cpu_online_mask) to prevent |
| 111 | * sending smp_reschedule() to an offlined CPU. | 110 | * sending smp_reschedule() to an offlined CPU. |
| 112 | */ | 111 | */ |
| 113 | cpus_and(cpumask, rcp->cpumask, cpu_online_map); | 112 | for_each_cpu_and(cpu, |
| 114 | cpu_clear(rdp->cpu, cpumask); | 113 | to_cpumask(rcp->cpumask), cpu_online_mask) { |
| 115 | for_each_cpu_mask_nr(cpu, cpumask) | 114 | if (cpu != rdp->cpu) |
| 116 | smp_send_reschedule(cpu); | 115 | smp_send_reschedule(cpu); |
| 116 | } | ||
| 117 | } | 117 | } |
| 118 | spin_unlock_irqrestore(&rcp->lock, flags); | 118 | spin_unlock_irqrestore(&rcp->lock, flags); |
| 119 | } | 119 | } |
| @@ -193,7 +193,7 @@ static void print_other_cpu_stall(struct rcu_ctrlblk *rcp) | |||
| 193 | 193 | ||
| 194 | printk(KERN_ERR "INFO: RCU detected CPU stalls:"); | 194 | printk(KERN_ERR "INFO: RCU detected CPU stalls:"); |
| 195 | for_each_possible_cpu(cpu) { | 195 | for_each_possible_cpu(cpu) { |
| 196 | if (cpu_isset(cpu, rcp->cpumask)) | 196 | if (cpumask_test_cpu(cpu, to_cpumask(rcp->cpumask))) |
| 197 | printk(" %d", cpu); | 197 | printk(" %d", cpu); |
| 198 | } | 198 | } |
| 199 | printk(" (detected by %d, t=%ld jiffies)\n", | 199 | printk(" (detected by %d, t=%ld jiffies)\n", |
| @@ -221,7 +221,8 @@ static void check_cpu_stall(struct rcu_ctrlblk *rcp) | |||
| 221 | long delta; | 221 | long delta; |
| 222 | 222 | ||
| 223 | delta = jiffies - rcp->jiffies_stall; | 223 | delta = jiffies - rcp->jiffies_stall; |
| 224 | if (cpu_isset(smp_processor_id(), rcp->cpumask) && delta >= 0) { | 224 | if (cpumask_test_cpu(smp_processor_id(), to_cpumask(rcp->cpumask)) && |
| 225 | delta >= 0) { | ||
| 225 | 226 | ||
| 226 | /* We haven't checked in, so go dump stack. */ | 227 | /* We haven't checked in, so go dump stack. */ |
| 227 | print_cpu_stall(rcp); | 228 | print_cpu_stall(rcp); |
| @@ -393,7 +394,8 @@ static void rcu_start_batch(struct rcu_ctrlblk *rcp) | |||
| 393 | * unnecessarily. | 394 | * unnecessarily. |
| 394 | */ | 395 | */ |
| 395 | smp_mb(); | 396 | smp_mb(); |
| 396 | cpumask_andnot(&rcp->cpumask, cpu_online_mask, nohz_cpu_mask); | 397 | cpumask_andnot(to_cpumask(rcp->cpumask), |
| 398 | cpu_online_mask, nohz_cpu_mask); | ||
| 397 | 399 | ||
| 398 | rcp->signaled = 0; | 400 | rcp->signaled = 0; |
| 399 | } | 401 | } |
| @@ -406,8 +408,8 @@ static void rcu_start_batch(struct rcu_ctrlblk *rcp) | |||
| 406 | */ | 408 | */ |
| 407 | static void cpu_quiet(int cpu, struct rcu_ctrlblk *rcp) | 409 | static void cpu_quiet(int cpu, struct rcu_ctrlblk *rcp) |
| 408 | { | 410 | { |
| 409 | cpu_clear(cpu, rcp->cpumask); | 411 | cpumask_clear_cpu(cpu, to_cpumask(rcp->cpumask)); |
| 410 | if (cpus_empty(rcp->cpumask)) { | 412 | if (cpumask_empty(to_cpumask(rcp->cpumask))) { |
| 411 | /* batch completed ! */ | 413 | /* batch completed ! */ |
| 412 | rcp->completed = rcp->cur; | 414 | rcp->completed = rcp->cur; |
| 413 | rcu_start_batch(rcp); | 415 | rcu_start_batch(rcp); |
diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c index 04982659875a..f9dc8f3720f6 100644 --- a/kernel/rcupreempt.c +++ b/kernel/rcupreempt.c | |||
| @@ -164,7 +164,8 @@ static char *rcu_try_flip_state_names[] = | |||
| 164 | { "idle", "waitack", "waitzero", "waitmb" }; | 164 | { "idle", "waitack", "waitzero", "waitmb" }; |
| 165 | #endif /* #ifdef CONFIG_RCU_TRACE */ | 165 | #endif /* #ifdef CONFIG_RCU_TRACE */ |
| 166 | 166 | ||
| 167 | static cpumask_t rcu_cpu_online_map __read_mostly = CPU_MASK_NONE; | 167 | static DECLARE_BITMAP(rcu_cpu_online_map, NR_CPUS) __read_mostly |
| 168 | = CPU_BITS_NONE; | ||
| 168 | 169 | ||
| 169 | /* | 170 | /* |
| 170 | * Enum and per-CPU flag to determine when each CPU has seen | 171 | * Enum and per-CPU flag to determine when each CPU has seen |
| @@ -758,7 +759,7 @@ rcu_try_flip_idle(void) | |||
| 758 | 759 | ||
| 759 | /* Now ask each CPU for acknowledgement of the flip. */ | 760 | /* Now ask each CPU for acknowledgement of the flip. */ |
| 760 | 761 | ||
| 761 | for_each_cpu_mask_nr(cpu, rcu_cpu_online_map) { | 762 | for_each_cpu(cpu, to_cpumask(rcu_cpu_online_map)) { |
| 762 | per_cpu(rcu_flip_flag, cpu) = rcu_flipped; | 763 | per_cpu(rcu_flip_flag, cpu) = rcu_flipped; |
| 763 | dyntick_save_progress_counter(cpu); | 764 | dyntick_save_progress_counter(cpu); |
| 764 | } | 765 | } |
| @@ -776,7 +777,7 @@ rcu_try_flip_waitack(void) | |||
| 776 | int cpu; | 777 | int cpu; |
| 777 | 778 | ||
| 778 | RCU_TRACE_ME(rcupreempt_trace_try_flip_a1); | 779 | RCU_TRACE_ME(rcupreempt_trace_try_flip_a1); |
| 779 | for_each_cpu_mask_nr(cpu, rcu_cpu_online_map) | 780 | for_each_cpu(cpu, to_cpumask(rcu_cpu_online_map)) |
| 780 | if (rcu_try_flip_waitack_needed(cpu) && | 781 | if (rcu_try_flip_waitack_needed(cpu) && |
| 781 | per_cpu(rcu_flip_flag, cpu) != rcu_flip_seen) { | 782 | per_cpu(rcu_flip_flag, cpu) != rcu_flip_seen) { |
| 782 | RCU_TRACE_ME(rcupreempt_trace_try_flip_ae1); | 783 | RCU_TRACE_ME(rcupreempt_trace_try_flip_ae1); |
| @@ -808,7 +809,7 @@ rcu_try_flip_waitzero(void) | |||
| 808 | /* Check to see if the sum of the "last" counters is zero. */ | 809 | /* Check to see if the sum of the "last" counters is zero. */ |
| 809 | 810 | ||
| 810 | RCU_TRACE_ME(rcupreempt_trace_try_flip_z1); | 811 | RCU_TRACE_ME(rcupreempt_trace_try_flip_z1); |
| 811 | for_each_cpu_mask_nr(cpu, rcu_cpu_online_map) | 812 | for_each_cpu(cpu, to_cpumask(rcu_cpu_online_map)) |
| 812 | sum += RCU_DATA_CPU(cpu)->rcu_flipctr[lastidx]; | 813 | sum += RCU_DATA_CPU(cpu)->rcu_flipctr[lastidx]; |
| 813 | if (sum != 0) { | 814 | if (sum != 0) { |
| 814 | RCU_TRACE_ME(rcupreempt_trace_try_flip_ze1); | 815 | RCU_TRACE_ME(rcupreempt_trace_try_flip_ze1); |
| @@ -823,7 +824,7 @@ rcu_try_flip_waitzero(void) | |||
| 823 | smp_mb(); /* ^^^^^^^^^^^^ */ | 824 | smp_mb(); /* ^^^^^^^^^^^^ */ |
| 824 | 825 | ||
| 825 | /* Call for a memory barrier from each CPU. */ | 826 | /* Call for a memory barrier from each CPU. */ |
| 826 | for_each_cpu_mask_nr(cpu, rcu_cpu_online_map) { | 827 | for_each_cpu(cpu, to_cpumask(rcu_cpu_online_map)) { |
| 827 | per_cpu(rcu_mb_flag, cpu) = rcu_mb_needed; | 828 | per_cpu(rcu_mb_flag, cpu) = rcu_mb_needed; |
| 828 | dyntick_save_progress_counter(cpu); | 829 | dyntick_save_progress_counter(cpu); |
| 829 | } | 830 | } |
| @@ -843,7 +844,7 @@ rcu_try_flip_waitmb(void) | |||
| 843 | int cpu; | 844 | int cpu; |
| 844 | 845 | ||
| 845 | RCU_TRACE_ME(rcupreempt_trace_try_flip_m1); | 846 | RCU_TRACE_ME(rcupreempt_trace_try_flip_m1); |
| 846 | for_each_cpu_mask_nr(cpu, rcu_cpu_online_map) | 847 | for_each_cpu(cpu, to_cpumask(rcu_cpu_online_map)) |
| 847 | if (rcu_try_flip_waitmb_needed(cpu) && | 848 | if (rcu_try_flip_waitmb_needed(cpu) && |
| 848 | per_cpu(rcu_mb_flag, cpu) != rcu_mb_done) { | 849 | per_cpu(rcu_mb_flag, cpu) != rcu_mb_done) { |
| 849 | RCU_TRACE_ME(rcupreempt_trace_try_flip_me1); | 850 | RCU_TRACE_ME(rcupreempt_trace_try_flip_me1); |
| @@ -1032,7 +1033,7 @@ void rcu_offline_cpu(int cpu) | |||
| 1032 | RCU_DATA_CPU(cpu)->rcu_flipctr[0] = 0; | 1033 | RCU_DATA_CPU(cpu)->rcu_flipctr[0] = 0; |
| 1033 | RCU_DATA_CPU(cpu)->rcu_flipctr[1] = 0; | 1034 | RCU_DATA_CPU(cpu)->rcu_flipctr[1] = 0; |
| 1034 | 1035 | ||
| 1035 | cpu_clear(cpu, rcu_cpu_online_map); | 1036 | cpumask_clear_cpu(cpu, to_cpumask(rcu_cpu_online_map)); |
| 1036 | 1037 | ||
| 1037 | spin_unlock_irqrestore(&rcu_ctrlblk.fliplock, flags); | 1038 | spin_unlock_irqrestore(&rcu_ctrlblk.fliplock, flags); |
| 1038 | 1039 | ||
| @@ -1072,7 +1073,7 @@ void __cpuinit rcu_online_cpu(int cpu) | |||
| 1072 | struct rcu_data *rdp; | 1073 | struct rcu_data *rdp; |
| 1073 | 1074 | ||
| 1074 | spin_lock_irqsave(&rcu_ctrlblk.fliplock, flags); | 1075 | spin_lock_irqsave(&rcu_ctrlblk.fliplock, flags); |
| 1075 | cpu_set(cpu, rcu_cpu_online_map); | 1076 | cpumask_set_cpu(cpu, to_cpumask(rcu_cpu_online_map)); |
| 1076 | spin_unlock_irqrestore(&rcu_ctrlblk.fliplock, flags); | 1077 | spin_unlock_irqrestore(&rcu_ctrlblk.fliplock, flags); |
| 1077 | 1078 | ||
| 1078 | /* | 1079 | /* |
| @@ -1430,7 +1431,7 @@ void __init __rcu_init(void) | |||
| 1430 | * We don't need protection against CPU-Hotplug here | 1431 | * We don't need protection against CPU-Hotplug here |
| 1431 | * since | 1432 | * since |
| 1432 | * a) If a CPU comes online while we are iterating over the | 1433 | * a) If a CPU comes online while we are iterating over the |
| 1433 | * cpu_online_map below, we would only end up making a | 1434 | * cpu_online_mask below, we would only end up making a |
| 1434 | * duplicate call to rcu_online_cpu() which sets the corresponding | 1435 | * duplicate call to rcu_online_cpu() which sets the corresponding |
| 1435 | * CPU's mask in the rcu_cpu_online_map. | 1436 | * CPU's mask in the rcu_cpu_online_map. |
| 1436 | * | 1437 | * |
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c index b31065522104..3245b40952c6 100644 --- a/kernel/rcutorture.c +++ b/kernel/rcutorture.c | |||
| @@ -868,49 +868,52 @@ static int rcu_idle_cpu; /* Force all torture tasks off this CPU */ | |||
| 868 | */ | 868 | */ |
| 869 | static void rcu_torture_shuffle_tasks(void) | 869 | static void rcu_torture_shuffle_tasks(void) |
| 870 | { | 870 | { |
| 871 | cpumask_t tmp_mask; | 871 | cpumask_var_t tmp_mask; |
| 872 | int i; | 872 | int i; |
| 873 | 873 | ||
| 874 | cpus_setall(tmp_mask); | 874 | if (!alloc_cpumask_var(&tmp_mask, GFP_KERNEL)) |
| 875 | BUG(); | ||
| 876 | |||
| 877 | cpumask_setall(tmp_mask); | ||
| 875 | get_online_cpus(); | 878 | get_online_cpus(); |
| 876 | 879 | ||
| 877 | /* No point in shuffling if there is only one online CPU (ex: UP) */ | 880 | /* No point in shuffling if there is only one online CPU (ex: UP) */ |
| 878 | if (num_online_cpus() == 1) { | 881 | if (num_online_cpus() == 1) |
| 879 | put_online_cpus(); | 882 | goto out; |
| 880 | return; | ||
| 881 | } | ||
| 882 | 883 | ||
| 883 | if (rcu_idle_cpu != -1) | 884 | if (rcu_idle_cpu != -1) |
| 884 | cpu_clear(rcu_idle_cpu, tmp_mask); | 885 | cpumask_clear_cpu(rcu_idle_cpu, tmp_mask); |
| 885 | 886 | ||
| 886 | set_cpus_allowed_ptr(current, &tmp_mask); | 887 | set_cpus_allowed_ptr(current, tmp_mask); |
| 887 | 888 | ||
| 888 | if (reader_tasks) { | 889 | if (reader_tasks) { |
| 889 | for (i = 0; i < nrealreaders; i++) | 890 | for (i = 0; i < nrealreaders; i++) |
| 890 | if (reader_tasks[i]) | 891 | if (reader_tasks[i]) |
| 891 | set_cpus_allowed_ptr(reader_tasks[i], | 892 | set_cpus_allowed_ptr(reader_tasks[i], |
| 892 | &tmp_mask); | 893 | tmp_mask); |
| 893 | } | 894 | } |
| 894 | 895 | ||
| 895 | if (fakewriter_tasks) { | 896 | if (fakewriter_tasks) { |
| 896 | for (i = 0; i < nfakewriters; i++) | 897 | for (i = 0; i < nfakewriters; i++) |
| 897 | if (fakewriter_tasks[i]) | 898 | if (fakewriter_tasks[i]) |
| 898 | set_cpus_allowed_ptr(fakewriter_tasks[i], | 899 | set_cpus_allowed_ptr(fakewriter_tasks[i], |
| 899 | &tmp_mask); | 900 | tmp_mask); |
| 900 | } | 901 | } |
| 901 | 902 | ||
| 902 | if (writer_task) | 903 | if (writer_task) |
| 903 | set_cpus_allowed_ptr(writer_task, &tmp_mask); | 904 | set_cpus_allowed_ptr(writer_task, tmp_mask); |
| 904 | 905 | ||
| 905 | if (stats_task) | 906 | if (stats_task) |
| 906 | set_cpus_allowed_ptr(stats_task, &tmp_mask); | 907 | set_cpus_allowed_ptr(stats_task, tmp_mask); |
| 907 | 908 | ||
| 908 | if (rcu_idle_cpu == -1) | 909 | if (rcu_idle_cpu == -1) |
| 909 | rcu_idle_cpu = num_online_cpus() - 1; | 910 | rcu_idle_cpu = num_online_cpus() - 1; |
| 910 | else | 911 | else |
| 911 | rcu_idle_cpu--; | 912 | rcu_idle_cpu--; |
| 912 | 913 | ||
| 914 | out: | ||
| 913 | put_online_cpus(); | 915 | put_online_cpus(); |
| 916 | free_cpumask_var(tmp_mask); | ||
| 914 | } | 917 | } |
| 915 | 918 | ||
| 916 | /* Shuffle tasks across CPUs, with the intent of allowing each CPU in the | 919 | /* Shuffle tasks across CPUs, with the intent of allowing each CPU in the |
diff --git a/kernel/sched.c b/kernel/sched.c index 27ba1d642f0f..545c6fccd1dc 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -3715,7 +3715,7 @@ redo: | |||
| 3715 | * don't kick the migration_thread, if the curr | 3715 | * don't kick the migration_thread, if the curr |
| 3716 | * task on busiest cpu can't be moved to this_cpu | 3716 | * task on busiest cpu can't be moved to this_cpu |
| 3717 | */ | 3717 | */ |
| 3718 | if (!cpu_isset(this_cpu, busiest->curr->cpus_allowed)) { | 3718 | if (!cpumask_test_cpu(this_cpu, &busiest->curr->cpus_allowed)) { |
| 3719 | double_unlock_balance(this_rq, busiest); | 3719 | double_unlock_balance(this_rq, busiest); |
| 3720 | all_pinned = 1; | 3720 | all_pinned = 1; |
| 3721 | return ld_moved; | 3721 | return ld_moved; |
| @@ -4150,13 +4150,17 @@ unsigned long long task_delta_exec(struct task_struct *p) | |||
| 4150 | * Account user cpu time to a process. | 4150 | * Account user cpu time to a process. |
| 4151 | * @p: the process that the cpu time gets accounted to | 4151 | * @p: the process that the cpu time gets accounted to |
| 4152 | * @cputime: the cpu time spent in user space since the last update | 4152 | * @cputime: the cpu time spent in user space since the last update |
| 4153 | * @cputime_scaled: cputime scaled by cpu frequency | ||
| 4153 | */ | 4154 | */ |
| 4154 | void account_user_time(struct task_struct *p, cputime_t cputime) | 4155 | void account_user_time(struct task_struct *p, cputime_t cputime, |
| 4156 | cputime_t cputime_scaled) | ||
| 4155 | { | 4157 | { |
| 4156 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; | 4158 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; |
| 4157 | cputime64_t tmp; | 4159 | cputime64_t tmp; |
| 4158 | 4160 | ||
| 4161 | /* Add user time to process. */ | ||
| 4159 | p->utime = cputime_add(p->utime, cputime); | 4162 | p->utime = cputime_add(p->utime, cputime); |
| 4163 | p->utimescaled = cputime_add(p->utimescaled, cputime_scaled); | ||
| 4160 | account_group_user_time(p, cputime); | 4164 | account_group_user_time(p, cputime); |
| 4161 | 4165 | ||
| 4162 | /* Add user time to cpustat. */ | 4166 | /* Add user time to cpustat. */ |
| @@ -4173,51 +4177,48 @@ void account_user_time(struct task_struct *p, cputime_t cputime) | |||
| 4173 | * Account guest cpu time to a process. | 4177 | * Account guest cpu time to a process. |
| 4174 | * @p: the process that the cpu time gets accounted to | 4178 | * @p: the process that the cpu time gets accounted to |
| 4175 | * @cputime: the cpu time spent in virtual machine since the last update | 4179 | * @cputime: the cpu time spent in virtual machine since the last update |
| 4180 | * @cputime_scaled: cputime scaled by cpu frequency | ||
| 4176 | */ | 4181 | */ |
| 4177 | static void account_guest_time(struct task_struct *p, cputime_t cputime) | 4182 | static void account_guest_time(struct task_struct *p, cputime_t cputime, |
| 4183 | cputime_t cputime_scaled) | ||
| 4178 | { | 4184 | { |
| 4179 | cputime64_t tmp; | 4185 | cputime64_t tmp; |
| 4180 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; | 4186 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; |
| 4181 | 4187 | ||
| 4182 | tmp = cputime_to_cputime64(cputime); | 4188 | tmp = cputime_to_cputime64(cputime); |
| 4183 | 4189 | ||
| 4190 | /* Add guest time to process. */ | ||
| 4184 | p->utime = cputime_add(p->utime, cputime); | 4191 | p->utime = cputime_add(p->utime, cputime); |
| 4192 | p->utimescaled = cputime_add(p->utimescaled, cputime_scaled); | ||
| 4185 | account_group_user_time(p, cputime); | 4193 | account_group_user_time(p, cputime); |
| 4186 | p->gtime = cputime_add(p->gtime, cputime); | 4194 | p->gtime = cputime_add(p->gtime, cputime); |
| 4187 | 4195 | ||
| 4196 | /* Add guest time to cpustat. */ | ||
| 4188 | cpustat->user = cputime64_add(cpustat->user, tmp); | 4197 | cpustat->user = cputime64_add(cpustat->user, tmp); |
| 4189 | cpustat->guest = cputime64_add(cpustat->guest, tmp); | 4198 | cpustat->guest = cputime64_add(cpustat->guest, tmp); |
| 4190 | } | 4199 | } |
| 4191 | 4200 | ||
| 4192 | /* | 4201 | /* |
| 4193 | * Account scaled user cpu time to a process. | ||
| 4194 | * @p: the process that the cpu time gets accounted to | ||
| 4195 | * @cputime: the cpu time spent in user space since the last update | ||
| 4196 | */ | ||
| 4197 | void account_user_time_scaled(struct task_struct *p, cputime_t cputime) | ||
| 4198 | { | ||
| 4199 | p->utimescaled = cputime_add(p->utimescaled, cputime); | ||
| 4200 | } | ||
| 4201 | |||
| 4202 | /* | ||
| 4203 | * Account system cpu time to a process. | 4202 | * Account system cpu time to a process. |
| 4204 | * @p: the process that the cpu time gets accounted to | 4203 | * @p: the process that the cpu time gets accounted to |
| 4205 | * @hardirq_offset: the offset to subtract from hardirq_count() | 4204 | * @hardirq_offset: the offset to subtract from hardirq_count() |
| 4206 | * @cputime: the cpu time spent in kernel space since the last update | 4205 | * @cputime: the cpu time spent in kernel space since the last update |
| 4206 | * @cputime_scaled: cputime scaled by cpu frequency | ||
| 4207 | */ | 4207 | */ |
| 4208 | void account_system_time(struct task_struct *p, int hardirq_offset, | 4208 | void account_system_time(struct task_struct *p, int hardirq_offset, |
| 4209 | cputime_t cputime) | 4209 | cputime_t cputime, cputime_t cputime_scaled) |
| 4210 | { | 4210 | { |
| 4211 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; | 4211 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; |
| 4212 | struct rq *rq = this_rq(); | ||
| 4213 | cputime64_t tmp; | 4212 | cputime64_t tmp; |
| 4214 | 4213 | ||
| 4215 | if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) { | 4214 | if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) { |
| 4216 | account_guest_time(p, cputime); | 4215 | account_guest_time(p, cputime, cputime_scaled); |
| 4217 | return; | 4216 | return; |
| 4218 | } | 4217 | } |
| 4219 | 4218 | ||
| 4219 | /* Add system time to process. */ | ||
| 4220 | p->stime = cputime_add(p->stime, cputime); | 4220 | p->stime = cputime_add(p->stime, cputime); |
| 4221 | p->stimescaled = cputime_add(p->stimescaled, cputime_scaled); | ||
| 4221 | account_group_system_time(p, cputime); | 4222 | account_group_system_time(p, cputime); |
| 4222 | 4223 | ||
| 4223 | /* Add system time to cpustat. */ | 4224 | /* Add system time to cpustat. */ |
| @@ -4226,49 +4227,85 @@ void account_system_time(struct task_struct *p, int hardirq_offset, | |||
| 4226 | cpustat->irq = cputime64_add(cpustat->irq, tmp); | 4227 | cpustat->irq = cputime64_add(cpustat->irq, tmp); |
| 4227 | else if (softirq_count()) | 4228 | else if (softirq_count()) |
| 4228 | cpustat->softirq = cputime64_add(cpustat->softirq, tmp); | 4229 | cpustat->softirq = cputime64_add(cpustat->softirq, tmp); |
| 4229 | else if (p != rq->idle) | ||
| 4230 | cpustat->system = cputime64_add(cpustat->system, tmp); | ||
| 4231 | else if (atomic_read(&rq->nr_iowait) > 0) | ||
| 4232 | cpustat->iowait = cputime64_add(cpustat->iowait, tmp); | ||
| 4233 | else | 4230 | else |
| 4234 | cpustat->idle = cputime64_add(cpustat->idle, tmp); | 4231 | cpustat->system = cputime64_add(cpustat->system, tmp); |
| 4232 | |||
| 4235 | /* Account for system time used */ | 4233 | /* Account for system time used */ |
| 4236 | acct_update_integrals(p); | 4234 | acct_update_integrals(p); |
| 4237 | } | 4235 | } |
| 4238 | 4236 | ||
| 4239 | /* | 4237 | /* |
| 4240 | * Account scaled system cpu time to a process. | 4238 | * Account for involuntary wait time. |
| 4241 | * @p: the process that the cpu time gets accounted to | 4239 | * @steal: the cpu time spent in involuntary wait |
| 4242 | * @hardirq_offset: the offset to subtract from hardirq_count() | ||
| 4243 | * @cputime: the cpu time spent in kernel space since the last update | ||
| 4244 | */ | 4240 | */ |
| 4245 | void account_system_time_scaled(struct task_struct *p, cputime_t cputime) | 4241 | void account_steal_time(cputime_t cputime) |
| 4246 | { | 4242 | { |
| 4247 | p->stimescaled = cputime_add(p->stimescaled, cputime); | 4243 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; |
| 4244 | cputime64_t cputime64 = cputime_to_cputime64(cputime); | ||
| 4245 | |||
| 4246 | cpustat->steal = cputime64_add(cpustat->steal, cputime64); | ||
| 4248 | } | 4247 | } |
| 4249 | 4248 | ||
| 4250 | /* | 4249 | /* |
| 4251 | * Account for involuntary wait time. | 4250 | * Account for idle time. |
| 4252 | * @p: the process from which the cpu time has been stolen | 4251 | * @cputime: the cpu time spent in idle wait |
| 4253 | * @steal: the cpu time spent in involuntary wait | ||
| 4254 | */ | 4252 | */ |
| 4255 | void account_steal_time(struct task_struct *p, cputime_t steal) | 4253 | void account_idle_time(cputime_t cputime) |
| 4256 | { | 4254 | { |
| 4257 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; | 4255 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; |
| 4258 | cputime64_t tmp = cputime_to_cputime64(steal); | 4256 | cputime64_t cputime64 = cputime_to_cputime64(cputime); |
| 4259 | struct rq *rq = this_rq(); | 4257 | struct rq *rq = this_rq(); |
| 4260 | 4258 | ||
| 4261 | if (p == rq->idle) { | 4259 | if (atomic_read(&rq->nr_iowait) > 0) |
| 4262 | p->stime = cputime_add(p->stime, steal); | 4260 | cpustat->iowait = cputime64_add(cpustat->iowait, cputime64); |
| 4263 | if (atomic_read(&rq->nr_iowait) > 0) | 4261 | else |
| 4264 | cpustat->iowait = cputime64_add(cpustat->iowait, tmp); | 4262 | cpustat->idle = cputime64_add(cpustat->idle, cputime64); |
| 4265 | else | 4263 | } |
| 4266 | cpustat->idle = cputime64_add(cpustat->idle, tmp); | 4264 | |
| 4267 | } else | 4265 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING |
| 4268 | cpustat->steal = cputime64_add(cpustat->steal, tmp); | 4266 | |
| 4267 | /* | ||
| 4268 | * Account a single tick of cpu time. | ||
| 4269 | * @p: the process that the cpu time gets accounted to | ||
| 4270 | * @user_tick: indicates if the tick is a user or a system tick | ||
| 4271 | */ | ||
| 4272 | void account_process_tick(struct task_struct *p, int user_tick) | ||
| 4273 | { | ||
| 4274 | cputime_t one_jiffy = jiffies_to_cputime(1); | ||
| 4275 | cputime_t one_jiffy_scaled = cputime_to_scaled(one_jiffy); | ||
| 4276 | struct rq *rq = this_rq(); | ||
| 4277 | |||
| 4278 | if (user_tick) | ||
| 4279 | account_user_time(p, one_jiffy, one_jiffy_scaled); | ||
| 4280 | else if (p != rq->idle) | ||
| 4281 | account_system_time(p, HARDIRQ_OFFSET, one_jiffy, | ||
| 4282 | one_jiffy_scaled); | ||
| 4283 | else | ||
| 4284 | account_idle_time(one_jiffy); | ||
| 4285 | } | ||
| 4286 | |||
| 4287 | /* | ||
| 4288 | * Account multiple ticks of steal time. | ||
| 4289 | * @p: the process from which the cpu time has been stolen | ||
| 4290 | * @ticks: number of stolen ticks | ||
| 4291 | */ | ||
| 4292 | void account_steal_ticks(unsigned long ticks) | ||
| 4293 | { | ||
| 4294 | account_steal_time(jiffies_to_cputime(ticks)); | ||
| 4269 | } | 4295 | } |
| 4270 | 4296 | ||
| 4271 | /* | 4297 | /* |
| 4298 | * Account multiple ticks of idle time. | ||
| 4299 | * @ticks: number of stolen ticks | ||
| 4300 | */ | ||
| 4301 | void account_idle_ticks(unsigned long ticks) | ||
| 4302 | { | ||
| 4303 | account_idle_time(jiffies_to_cputime(ticks)); | ||
| 4304 | } | ||
| 4305 | |||
| 4306 | #endif | ||
| 4307 | |||
| 4308 | /* | ||
| 4272 | * Use precise platform statistics if available: | 4309 | * Use precise platform statistics if available: |
| 4273 | */ | 4310 | */ |
| 4274 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 4311 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
| @@ -6220,9 +6257,7 @@ static int __migrate_task_irq(struct task_struct *p, int src_cpu, int dest_cpu) | |||
| 6220 | static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p) | 6257 | static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p) |
| 6221 | { | 6258 | { |
| 6222 | int dest_cpu; | 6259 | int dest_cpu; |
| 6223 | /* FIXME: Use cpumask_of_node here. */ | 6260 | const struct cpumask *nodemask = cpumask_of_node(cpu_to_node(dead_cpu)); |
| 6224 | cpumask_t _nodemask = node_to_cpumask(cpu_to_node(dead_cpu)); | ||
| 6225 | const struct cpumask *nodemask = &_nodemask; | ||
| 6226 | 6261 | ||
| 6227 | again: | 6262 | again: |
| 6228 | /* Look for allowed, online CPU in same node. */ | 6263 | /* Look for allowed, online CPU in same node. */ |
| @@ -7133,21 +7168,18 @@ static int find_next_best_node(int node, nodemask_t *used_nodes) | |||
| 7133 | static void sched_domain_node_span(int node, struct cpumask *span) | 7168 | static void sched_domain_node_span(int node, struct cpumask *span) |
| 7134 | { | 7169 | { |
| 7135 | nodemask_t used_nodes; | 7170 | nodemask_t used_nodes; |
| 7136 | /* FIXME: use cpumask_of_node() */ | ||
| 7137 | node_to_cpumask_ptr(nodemask, node); | ||
| 7138 | int i; | 7171 | int i; |
| 7139 | 7172 | ||
| 7140 | cpus_clear(*span); | 7173 | cpumask_clear(span); |
| 7141 | nodes_clear(used_nodes); | 7174 | nodes_clear(used_nodes); |
| 7142 | 7175 | ||
| 7143 | cpus_or(*span, *span, *nodemask); | 7176 | cpumask_or(span, span, cpumask_of_node(node)); |
| 7144 | node_set(node, used_nodes); | 7177 | node_set(node, used_nodes); |
| 7145 | 7178 | ||
| 7146 | for (i = 1; i < SD_NODES_PER_DOMAIN; i++) { | 7179 | for (i = 1; i < SD_NODES_PER_DOMAIN; i++) { |
| 7147 | int next_node = find_next_best_node(node, &used_nodes); | 7180 | int next_node = find_next_best_node(node, &used_nodes); |
| 7148 | 7181 | ||
| 7149 | node_to_cpumask_ptr_next(nodemask, next_node); | 7182 | cpumask_or(span, span, cpumask_of_node(next_node)); |
| 7150 | cpus_or(*span, *span, *nodemask); | ||
| 7151 | } | 7183 | } |
| 7152 | } | 7184 | } |
| 7153 | #endif /* CONFIG_NUMA */ | 7185 | #endif /* CONFIG_NUMA */ |
| @@ -7227,9 +7259,7 @@ cpu_to_phys_group(int cpu, const struct cpumask *cpu_map, | |||
| 7227 | { | 7259 | { |
| 7228 | int group; | 7260 | int group; |
| 7229 | #ifdef CONFIG_SCHED_MC | 7261 | #ifdef CONFIG_SCHED_MC |
| 7230 | /* FIXME: Use cpu_coregroup_mask. */ | 7262 | cpumask_and(mask, cpu_coregroup_mask(cpu), cpu_map); |
| 7231 | *mask = cpu_coregroup_map(cpu); | ||
| 7232 | cpus_and(*mask, *mask, *cpu_map); | ||
| 7233 | group = cpumask_first(mask); | 7263 | group = cpumask_first(mask); |
| 7234 | #elif defined(CONFIG_SCHED_SMT) | 7264 | #elif defined(CONFIG_SCHED_SMT) |
| 7235 | cpumask_and(mask, &per_cpu(cpu_sibling_map, cpu), cpu_map); | 7265 | cpumask_and(mask, &per_cpu(cpu_sibling_map, cpu), cpu_map); |
| @@ -7259,10 +7289,8 @@ static int cpu_to_allnodes_group(int cpu, const struct cpumask *cpu_map, | |||
| 7259 | struct cpumask *nodemask) | 7289 | struct cpumask *nodemask) |
| 7260 | { | 7290 | { |
| 7261 | int group; | 7291 | int group; |
| 7262 | /* FIXME: use cpumask_of_node */ | ||
| 7263 | node_to_cpumask_ptr(pnodemask, cpu_to_node(cpu)); | ||
| 7264 | 7292 | ||
| 7265 | cpumask_and(nodemask, pnodemask, cpu_map); | 7293 | cpumask_and(nodemask, cpumask_of_node(cpu_to_node(cpu)), cpu_map); |
| 7266 | group = cpumask_first(nodemask); | 7294 | group = cpumask_first(nodemask); |
| 7267 | 7295 | ||
| 7268 | if (sg) | 7296 | if (sg) |
| @@ -7313,10 +7341,8 @@ static void free_sched_groups(const struct cpumask *cpu_map, | |||
| 7313 | 7341 | ||
| 7314 | for (i = 0; i < nr_node_ids; i++) { | 7342 | for (i = 0; i < nr_node_ids; i++) { |
| 7315 | struct sched_group *oldsg, *sg = sched_group_nodes[i]; | 7343 | struct sched_group *oldsg, *sg = sched_group_nodes[i]; |
| 7316 | /* FIXME: Use cpumask_of_node */ | ||
| 7317 | node_to_cpumask_ptr(pnodemask, i); | ||
| 7318 | 7344 | ||
| 7319 | cpus_and(*nodemask, *pnodemask, *cpu_map); | 7345 | cpumask_and(nodemask, cpumask_of_node(i), cpu_map); |
| 7320 | if (cpumask_empty(nodemask)) | 7346 | if (cpumask_empty(nodemask)) |
| 7321 | continue; | 7347 | continue; |
| 7322 | 7348 | ||
| @@ -7525,9 +7551,7 @@ static int __build_sched_domains(const struct cpumask *cpu_map, | |||
| 7525 | for_each_cpu(i, cpu_map) { | 7551 | for_each_cpu(i, cpu_map) { |
| 7526 | struct sched_domain *sd = NULL, *p; | 7552 | struct sched_domain *sd = NULL, *p; |
| 7527 | 7553 | ||
| 7528 | /* FIXME: use cpumask_of_node */ | 7554 | cpumask_and(nodemask, cpumask_of_node(cpu_to_node(i)), cpu_map); |
| 7529 | *nodemask = node_to_cpumask(cpu_to_node(i)); | ||
| 7530 | cpus_and(*nodemask, *nodemask, *cpu_map); | ||
| 7531 | 7555 | ||
| 7532 | #ifdef CONFIG_NUMA | 7556 | #ifdef CONFIG_NUMA |
| 7533 | if (cpumask_weight(cpu_map) > | 7557 | if (cpumask_weight(cpu_map) > |
| @@ -7568,9 +7592,8 @@ static int __build_sched_domains(const struct cpumask *cpu_map, | |||
| 7568 | sd = &per_cpu(core_domains, i).sd; | 7592 | sd = &per_cpu(core_domains, i).sd; |
| 7569 | SD_INIT(sd, MC); | 7593 | SD_INIT(sd, MC); |
| 7570 | set_domain_attribute(sd, attr); | 7594 | set_domain_attribute(sd, attr); |
| 7571 | *sched_domain_span(sd) = cpu_coregroup_map(i); | 7595 | cpumask_and(sched_domain_span(sd), cpu_map, |
| 7572 | cpumask_and(sched_domain_span(sd), | 7596 | cpu_coregroup_mask(i)); |
| 7573 | sched_domain_span(sd), cpu_map); | ||
| 7574 | sd->parent = p; | 7597 | sd->parent = p; |
| 7575 | p->child = sd; | 7598 | p->child = sd; |
| 7576 | cpu_to_core_group(i, cpu_map, &sd->groups, tmpmask); | 7599 | cpu_to_core_group(i, cpu_map, &sd->groups, tmpmask); |
| @@ -7606,9 +7629,7 @@ static int __build_sched_domains(const struct cpumask *cpu_map, | |||
| 7606 | #ifdef CONFIG_SCHED_MC | 7629 | #ifdef CONFIG_SCHED_MC |
| 7607 | /* Set up multi-core groups */ | 7630 | /* Set up multi-core groups */ |
| 7608 | for_each_cpu(i, cpu_map) { | 7631 | for_each_cpu(i, cpu_map) { |
| 7609 | /* FIXME: Use cpu_coregroup_mask */ | 7632 | cpumask_and(this_core_map, cpu_coregroup_mask(i), cpu_map); |
| 7610 | *this_core_map = cpu_coregroup_map(i); | ||
| 7611 | cpus_and(*this_core_map, *this_core_map, *cpu_map); | ||
| 7612 | if (i != cpumask_first(this_core_map)) | 7633 | if (i != cpumask_first(this_core_map)) |
| 7613 | continue; | 7634 | continue; |
| 7614 | 7635 | ||
| @@ -7620,9 +7641,7 @@ static int __build_sched_domains(const struct cpumask *cpu_map, | |||
| 7620 | 7641 | ||
| 7621 | /* Set up physical groups */ | 7642 | /* Set up physical groups */ |
| 7622 | for (i = 0; i < nr_node_ids; i++) { | 7643 | for (i = 0; i < nr_node_ids; i++) { |
| 7623 | /* FIXME: Use cpumask_of_node */ | 7644 | cpumask_and(nodemask, cpumask_of_node(i), cpu_map); |
| 7624 | *nodemask = node_to_cpumask(i); | ||
| 7625 | cpus_and(*nodemask, *nodemask, *cpu_map); | ||
| 7626 | if (cpumask_empty(nodemask)) | 7645 | if (cpumask_empty(nodemask)) |
| 7627 | continue; | 7646 | continue; |
| 7628 | 7647 | ||
| @@ -7644,11 +7663,8 @@ static int __build_sched_domains(const struct cpumask *cpu_map, | |||
| 7644 | struct sched_group *sg, *prev; | 7663 | struct sched_group *sg, *prev; |
| 7645 | int j; | 7664 | int j; |
| 7646 | 7665 | ||
| 7647 | /* FIXME: Use cpumask_of_node */ | ||
| 7648 | *nodemask = node_to_cpumask(i); | ||
| 7649 | cpumask_clear(covered); | 7666 | cpumask_clear(covered); |
| 7650 | 7667 | cpumask_and(nodemask, cpumask_of_node(i), cpu_map); | |
| 7651 | cpus_and(*nodemask, *nodemask, *cpu_map); | ||
| 7652 | if (cpumask_empty(nodemask)) { | 7668 | if (cpumask_empty(nodemask)) { |
| 7653 | sched_group_nodes[i] = NULL; | 7669 | sched_group_nodes[i] = NULL; |
| 7654 | continue; | 7670 | continue; |
| @@ -7679,8 +7695,6 @@ static int __build_sched_domains(const struct cpumask *cpu_map, | |||
| 7679 | 7695 | ||
| 7680 | for (j = 0; j < nr_node_ids; j++) { | 7696 | for (j = 0; j < nr_node_ids; j++) { |
| 7681 | int n = (i + j) % nr_node_ids; | 7697 | int n = (i + j) % nr_node_ids; |
| 7682 | /* FIXME: Use cpumask_of_node */ | ||
| 7683 | node_to_cpumask_ptr(pnodemask, n); | ||
| 7684 | 7698 | ||
| 7685 | cpumask_complement(notcovered, covered); | 7699 | cpumask_complement(notcovered, covered); |
| 7686 | cpumask_and(tmpmask, notcovered, cpu_map); | 7700 | cpumask_and(tmpmask, notcovered, cpu_map); |
| @@ -7688,7 +7702,7 @@ static int __build_sched_domains(const struct cpumask *cpu_map, | |||
| 7688 | if (cpumask_empty(tmpmask)) | 7702 | if (cpumask_empty(tmpmask)) |
| 7689 | break; | 7703 | break; |
| 7690 | 7704 | ||
| 7691 | cpumask_and(tmpmask, tmpmask, pnodemask); | 7705 | cpumask_and(tmpmask, tmpmask, cpumask_of_node(n)); |
| 7692 | if (cpumask_empty(tmpmask)) | 7706 | if (cpumask_empty(tmpmask)) |
| 7693 | continue; | 7707 | continue; |
| 7694 | 7708 | ||
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index 833b6d44483c..954e1a81b796 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c | |||
| @@ -1383,7 +1383,8 @@ static inline void init_sched_rt_class(void) | |||
| 1383 | unsigned int i; | 1383 | unsigned int i; |
| 1384 | 1384 | ||
| 1385 | for_each_possible_cpu(i) | 1385 | for_each_possible_cpu(i) |
| 1386 | alloc_cpumask_var(&per_cpu(local_cpu_mask, i), GFP_KERNEL); | 1386 | alloc_cpumask_var_node(&per_cpu(local_cpu_mask, i), |
| 1387 | GFP_KERNEL, cpu_to_node(i)); | ||
| 1387 | } | 1388 | } |
| 1388 | #endif /* CONFIG_SMP */ | 1389 | #endif /* CONFIG_SMP */ |
| 1389 | 1390 | ||
diff --git a/kernel/smp.c b/kernel/smp.c index 75c8dde58c55..5cfa0e5e3e88 100644 --- a/kernel/smp.c +++ b/kernel/smp.c | |||
| @@ -24,8 +24,8 @@ struct call_function_data { | |||
| 24 | struct call_single_data csd; | 24 | struct call_single_data csd; |
| 25 | spinlock_t lock; | 25 | spinlock_t lock; |
| 26 | unsigned int refs; | 26 | unsigned int refs; |
| 27 | cpumask_t cpumask; | ||
| 28 | struct rcu_head rcu_head; | 27 | struct rcu_head rcu_head; |
| 28 | unsigned long cpumask_bits[]; | ||
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | struct call_single_queue { | 31 | struct call_single_queue { |
| @@ -110,13 +110,13 @@ void generic_smp_call_function_interrupt(void) | |||
| 110 | list_for_each_entry_rcu(data, &call_function_queue, csd.list) { | 110 | list_for_each_entry_rcu(data, &call_function_queue, csd.list) { |
| 111 | int refs; | 111 | int refs; |
| 112 | 112 | ||
| 113 | if (!cpu_isset(cpu, data->cpumask)) | 113 | if (!cpumask_test_cpu(cpu, to_cpumask(data->cpumask_bits))) |
| 114 | continue; | 114 | continue; |
| 115 | 115 | ||
| 116 | data->csd.func(data->csd.info); | 116 | data->csd.func(data->csd.info); |
| 117 | 117 | ||
| 118 | spin_lock(&data->lock); | 118 | spin_lock(&data->lock); |
| 119 | cpu_clear(cpu, data->cpumask); | 119 | cpumask_clear_cpu(cpu, to_cpumask(data->cpumask_bits)); |
| 120 | WARN_ON(data->refs == 0); | 120 | WARN_ON(data->refs == 0); |
| 121 | data->refs--; | 121 | data->refs--; |
| 122 | refs = data->refs; | 122 | refs = data->refs; |
| @@ -223,7 +223,7 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, | |||
| 223 | local_irq_save(flags); | 223 | local_irq_save(flags); |
| 224 | func(info); | 224 | func(info); |
| 225 | local_irq_restore(flags); | 225 | local_irq_restore(flags); |
| 226 | } else if ((unsigned)cpu < NR_CPUS && cpu_online(cpu)) { | 226 | } else if ((unsigned)cpu < nr_cpu_ids && cpu_online(cpu)) { |
| 227 | struct call_single_data *data = NULL; | 227 | struct call_single_data *data = NULL; |
| 228 | 228 | ||
| 229 | if (!wait) { | 229 | if (!wait) { |
| @@ -266,51 +266,19 @@ void __smp_call_function_single(int cpu, struct call_single_data *data) | |||
| 266 | generic_exec_single(cpu, data); | 266 | generic_exec_single(cpu, data); |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | /* Dummy function */ | 269 | /* FIXME: Shim for archs using old arch_send_call_function_ipi API. */ |
| 270 | static void quiesce_dummy(void *unused) | 270 | #ifndef arch_send_call_function_ipi_mask |
| 271 | { | 271 | #define arch_send_call_function_ipi_mask(maskp) \ |
| 272 | } | 272 | arch_send_call_function_ipi(*(maskp)) |
| 273 | 273 | #endif | |
| 274 | /* | ||
| 275 | * Ensure stack based data used in call function mask is safe to free. | ||
| 276 | * | ||
| 277 | * This is needed by smp_call_function_mask when using on-stack data, because | ||
| 278 | * a single call function queue is shared by all CPUs, and any CPU may pick up | ||
| 279 | * the data item on the queue at any time before it is deleted. So we need to | ||
| 280 | * ensure that all CPUs have transitioned through a quiescent state after | ||
| 281 | * this call. | ||
| 282 | * | ||
| 283 | * This is a very slow function, implemented by sending synchronous IPIs to | ||
| 284 | * all possible CPUs. For this reason, we have to alloc data rather than use | ||
| 285 | * stack based data even in the case of synchronous calls. The stack based | ||
| 286 | * data is then just used for deadlock/oom fallback which will be very rare. | ||
| 287 | * | ||
| 288 | * If a faster scheme can be made, we could go back to preferring stack based | ||
| 289 | * data -- the data allocation/free is non-zero cost. | ||
| 290 | */ | ||
| 291 | static void smp_call_function_mask_quiesce_stack(cpumask_t mask) | ||
| 292 | { | ||
| 293 | struct call_single_data data; | ||
| 294 | int cpu; | ||
| 295 | |||
| 296 | data.func = quiesce_dummy; | ||
| 297 | data.info = NULL; | ||
| 298 | |||
| 299 | for_each_cpu_mask(cpu, mask) { | ||
| 300 | data.flags = CSD_FLAG_WAIT; | ||
| 301 | generic_exec_single(cpu, &data); | ||
| 302 | } | ||
| 303 | } | ||
| 304 | 274 | ||
| 305 | /** | 275 | /** |
| 306 | * smp_call_function_mask(): Run a function on a set of other CPUs. | 276 | * smp_call_function_many(): Run a function on a set of other CPUs. |
| 307 | * @mask: The set of cpus to run on. | 277 | * @mask: The set of cpus to run on (only runs on online subset). |
| 308 | * @func: The function to run. This must be fast and non-blocking. | 278 | * @func: The function to run. This must be fast and non-blocking. |
| 309 | * @info: An arbitrary pointer to pass to the function. | 279 | * @info: An arbitrary pointer to pass to the function. |
| 310 | * @wait: If true, wait (atomically) until function has completed on other CPUs. | 280 | * @wait: If true, wait (atomically) until function has completed on other CPUs. |
| 311 | * | 281 | * |
| 312 | * Returns 0 on success, else a negative status code. | ||
| 313 | * | ||
| 314 | * If @wait is true, then returns once @func has returned. Note that @wait | 282 | * If @wait is true, then returns once @func has returned. Note that @wait |
| 315 | * will be implicitly turned on in case of allocation failures, since | 283 | * will be implicitly turned on in case of allocation failures, since |
| 316 | * we fall back to on-stack allocation. | 284 | * we fall back to on-stack allocation. |
| @@ -319,53 +287,57 @@ static void smp_call_function_mask_quiesce_stack(cpumask_t mask) | |||
| 319 | * hardware interrupt handler or from a bottom half handler. Preemption | 287 | * hardware interrupt handler or from a bottom half handler. Preemption |
| 320 | * must be disabled when calling this function. | 288 | * must be disabled when calling this function. |
| 321 | */ | 289 | */ |
| 322 | int smp_call_function_mask(cpumask_t mask, void (*func)(void *), void *info, | 290 | void smp_call_function_many(const struct cpumask *mask, |
| 323 | int wait) | 291 | void (*func)(void *), void *info, |
| 292 | bool wait) | ||
| 324 | { | 293 | { |
| 325 | struct call_function_data d; | 294 | struct call_function_data *data; |
| 326 | struct call_function_data *data = NULL; | ||
| 327 | cpumask_t allbutself; | ||
| 328 | unsigned long flags; | 295 | unsigned long flags; |
| 329 | int cpu, num_cpus; | 296 | int cpu, next_cpu; |
| 330 | int slowpath = 0; | ||
| 331 | 297 | ||
| 332 | /* Can deadlock when called with interrupts disabled */ | 298 | /* Can deadlock when called with interrupts disabled */ |
| 333 | WARN_ON(irqs_disabled()); | 299 | WARN_ON(irqs_disabled()); |
| 334 | 300 | ||
| 335 | cpu = smp_processor_id(); | 301 | /* So, what's a CPU they want? Ignoring this one. */ |
| 336 | allbutself = cpu_online_map; | 302 | cpu = cpumask_first_and(mask, cpu_online_mask); |
| 337 | cpu_clear(cpu, allbutself); | 303 | if (cpu == smp_processor_id()) |
| 338 | cpus_and(mask, mask, allbutself); | 304 | cpu = cpumask_next_and(cpu, mask, cpu_online_mask); |
| 339 | num_cpus = cpus_weight(mask); | 305 | /* No online cpus? We're done. */ |
| 340 | 306 | if (cpu >= nr_cpu_ids) | |
| 341 | /* | 307 | return; |
| 342 | * If zero CPUs, return. If just a single CPU, turn this request | 308 | |
| 343 | * into a targetted single call instead since it's faster. | 309 | /* Do we have another CPU which isn't us? */ |
| 344 | */ | 310 | next_cpu = cpumask_next_and(cpu, mask, cpu_online_mask); |
| 345 | if (!num_cpus) | 311 | if (next_cpu == smp_processor_id()) |
| 346 | return 0; | 312 | next_cpu = cpumask_next_and(next_cpu, mask, cpu_online_mask); |
| 347 | else if (num_cpus == 1) { | 313 | |
| 348 | cpu = first_cpu(mask); | 314 | /* Fastpath: do that cpu by itself. */ |
| 349 | return smp_call_function_single(cpu, func, info, wait); | 315 | if (next_cpu >= nr_cpu_ids) { |
| 316 | smp_call_function_single(cpu, func, info, wait); | ||
| 317 | return; | ||
| 350 | } | 318 | } |
| 351 | 319 | ||
| 352 | data = kmalloc(sizeof(*data), GFP_ATOMIC); | 320 | data = kmalloc(sizeof(*data) + cpumask_size(), GFP_ATOMIC); |
| 353 | if (data) { | 321 | if (unlikely(!data)) { |
| 354 | data->csd.flags = CSD_FLAG_ALLOC; | 322 | /* Slow path. */ |
| 355 | if (wait) | 323 | for_each_online_cpu(cpu) { |
| 356 | data->csd.flags |= CSD_FLAG_WAIT; | 324 | if (cpu == smp_processor_id()) |
| 357 | } else { | 325 | continue; |
| 358 | data = &d; | 326 | if (cpumask_test_cpu(cpu, mask)) |
| 359 | data->csd.flags = CSD_FLAG_WAIT; | 327 | smp_call_function_single(cpu, func, info, wait); |
| 360 | wait = 1; | 328 | } |
| 361 | slowpath = 1; | 329 | return; |
| 362 | } | 330 | } |
| 363 | 331 | ||
| 364 | spin_lock_init(&data->lock); | 332 | spin_lock_init(&data->lock); |
| 333 | data->csd.flags = CSD_FLAG_ALLOC; | ||
| 334 | if (wait) | ||
| 335 | data->csd.flags |= CSD_FLAG_WAIT; | ||
| 365 | data->csd.func = func; | 336 | data->csd.func = func; |
| 366 | data->csd.info = info; | 337 | data->csd.info = info; |
| 367 | data->refs = num_cpus; | 338 | cpumask_and(to_cpumask(data->cpumask_bits), mask, cpu_online_mask); |
| 368 | data->cpumask = mask; | 339 | cpumask_clear_cpu(smp_processor_id(), to_cpumask(data->cpumask_bits)); |
| 340 | data->refs = cpumask_weight(to_cpumask(data->cpumask_bits)); | ||
| 369 | 341 | ||
| 370 | spin_lock_irqsave(&call_function_lock, flags); | 342 | spin_lock_irqsave(&call_function_lock, flags); |
| 371 | list_add_tail_rcu(&data->csd.list, &call_function_queue); | 343 | list_add_tail_rcu(&data->csd.list, &call_function_queue); |
| @@ -377,18 +349,13 @@ int smp_call_function_mask(cpumask_t mask, void (*func)(void *), void *info, | |||
| 377 | smp_mb(); | 349 | smp_mb(); |
| 378 | 350 | ||
| 379 | /* Send a message to all CPUs in the map */ | 351 | /* Send a message to all CPUs in the map */ |
| 380 | arch_send_call_function_ipi(mask); | 352 | arch_send_call_function_ipi_mask(to_cpumask(data->cpumask_bits)); |
| 381 | 353 | ||
| 382 | /* optionally wait for the CPUs to complete */ | 354 | /* optionally wait for the CPUs to complete */ |
| 383 | if (wait) { | 355 | if (wait) |
| 384 | csd_flag_wait(&data->csd); | 356 | csd_flag_wait(&data->csd); |
| 385 | if (unlikely(slowpath)) | ||
| 386 | smp_call_function_mask_quiesce_stack(mask); | ||
| 387 | } | ||
| 388 | |||
| 389 | return 0; | ||
| 390 | } | 357 | } |
| 391 | EXPORT_SYMBOL(smp_call_function_mask); | 358 | EXPORT_SYMBOL(smp_call_function_many); |
| 392 | 359 | ||
| 393 | /** | 360 | /** |
| 394 | * smp_call_function(): Run a function on all other CPUs. | 361 | * smp_call_function(): Run a function on all other CPUs. |
| @@ -396,7 +363,7 @@ EXPORT_SYMBOL(smp_call_function_mask); | |||
| 396 | * @info: An arbitrary pointer to pass to the function. | 363 | * @info: An arbitrary pointer to pass to the function. |
| 397 | * @wait: If true, wait (atomically) until function has completed on other CPUs. | 364 | * @wait: If true, wait (atomically) until function has completed on other CPUs. |
| 398 | * | 365 | * |
| 399 | * Returns 0 on success, else a negative status code. | 366 | * Returns 0. |
| 400 | * | 367 | * |
| 401 | * If @wait is true, then returns once @func has returned; otherwise | 368 | * If @wait is true, then returns once @func has returned; otherwise |
| 402 | * it returns just before the target cpu calls @func. In case of allocation | 369 | * it returns just before the target cpu calls @func. In case of allocation |
| @@ -407,12 +374,10 @@ EXPORT_SYMBOL(smp_call_function_mask); | |||
| 407 | */ | 374 | */ |
| 408 | int smp_call_function(void (*func)(void *), void *info, int wait) | 375 | int smp_call_function(void (*func)(void *), void *info, int wait) |
| 409 | { | 376 | { |
| 410 | int ret; | ||
| 411 | |||
| 412 | preempt_disable(); | 377 | preempt_disable(); |
| 413 | ret = smp_call_function_mask(cpu_online_map, func, info, wait); | 378 | smp_call_function_many(cpu_online_mask, func, info, wait); |
| 414 | preempt_enable(); | 379 | preempt_enable(); |
| 415 | return ret; | 380 | return 0; |
| 416 | } | 381 | } |
| 417 | EXPORT_SYMBOL(smp_call_function); | 382 | EXPORT_SYMBOL(smp_call_function); |
| 418 | 383 | ||
diff --git a/kernel/softirq.c b/kernel/softirq.c index 670c1eca47ec..bdbe9de9cd8d 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
| @@ -733,7 +733,7 @@ static int __cpuinit cpu_callback(struct notifier_block *nfb, | |||
| 733 | break; | 733 | break; |
| 734 | /* Unbind so it can run. Fall thru. */ | 734 | /* Unbind so it can run. Fall thru. */ |
| 735 | kthread_bind(per_cpu(ksoftirqd, hotcpu), | 735 | kthread_bind(per_cpu(ksoftirqd, hotcpu), |
| 736 | any_online_cpu(cpu_online_map)); | 736 | cpumask_any(cpu_online_mask)); |
| 737 | case CPU_DEAD: | 737 | case CPU_DEAD: |
| 738 | case CPU_DEAD_FROZEN: { | 738 | case CPU_DEAD_FROZEN: { |
| 739 | struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; | 739 | struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; |
diff --git a/kernel/softlockup.c b/kernel/softlockup.c index 1ab790c67b17..d9188c66278a 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c | |||
| @@ -303,17 +303,15 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
| 303 | break; | 303 | break; |
| 304 | case CPU_ONLINE: | 304 | case CPU_ONLINE: |
| 305 | case CPU_ONLINE_FROZEN: | 305 | case CPU_ONLINE_FROZEN: |
| 306 | check_cpu = any_online_cpu(cpu_online_map); | 306 | check_cpu = cpumask_any(cpu_online_mask); |
| 307 | wake_up_process(per_cpu(watchdog_task, hotcpu)); | 307 | wake_up_process(per_cpu(watchdog_task, hotcpu)); |
| 308 | break; | 308 | break; |
| 309 | #ifdef CONFIG_HOTPLUG_CPU | 309 | #ifdef CONFIG_HOTPLUG_CPU |
| 310 | case CPU_DOWN_PREPARE: | 310 | case CPU_DOWN_PREPARE: |
| 311 | case CPU_DOWN_PREPARE_FROZEN: | 311 | case CPU_DOWN_PREPARE_FROZEN: |
| 312 | if (hotcpu == check_cpu) { | 312 | if (hotcpu == check_cpu) { |
| 313 | cpumask_t temp_cpu_online_map = cpu_online_map; | 313 | /* Pick any other online cpu. */ |
| 314 | 314 | check_cpu = cpumask_any_but(cpu_online_mask, hotcpu); | |
| 315 | cpu_clear(hotcpu, temp_cpu_online_map); | ||
| 316 | check_cpu = any_online_cpu(temp_cpu_online_map); | ||
| 317 | } | 315 | } |
| 318 | break; | 316 | break; |
| 319 | 317 | ||
| @@ -323,7 +321,7 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
| 323 | break; | 321 | break; |
| 324 | /* Unbind so it can run. Fall thru. */ | 322 | /* Unbind so it can run. Fall thru. */ |
| 325 | kthread_bind(per_cpu(watchdog_task, hotcpu), | 323 | kthread_bind(per_cpu(watchdog_task, hotcpu), |
| 326 | any_online_cpu(cpu_online_map)); | 324 | cpumask_any(cpu_online_mask)); |
| 327 | case CPU_DEAD: | 325 | case CPU_DEAD: |
| 328 | case CPU_DEAD_FROZEN: | 326 | case CPU_DEAD_FROZEN: |
| 329 | p = per_cpu(watchdog_task, hotcpu); | 327 | p = per_cpu(watchdog_task, hotcpu); |
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c index 24e8ceacc388..286c41722e8c 100644 --- a/kernel/stop_machine.c +++ b/kernel/stop_machine.c | |||
| @@ -69,10 +69,10 @@ static void stop_cpu(struct work_struct *unused) | |||
| 69 | int err; | 69 | int err; |
| 70 | 70 | ||
| 71 | if (!active_cpus) { | 71 | if (!active_cpus) { |
| 72 | if (cpu == first_cpu(cpu_online_map)) | 72 | if (cpu == cpumask_first(cpu_online_mask)) |
| 73 | smdata = &active; | 73 | smdata = &active; |
| 74 | } else { | 74 | } else { |
| 75 | if (cpu_isset(cpu, *active_cpus)) | 75 | if (cpumask_test_cpu(cpu, active_cpus)) |
| 76 | smdata = &active; | 76 | smdata = &active; |
| 77 | } | 77 | } |
| 78 | /* Simple state machine */ | 78 | /* Simple state machine */ |
| @@ -109,7 +109,7 @@ static int chill(void *unused) | |||
| 109 | return 0; | 109 | return 0; |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | int __stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus) | 112 | int __stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus) |
| 113 | { | 113 | { |
| 114 | struct work_struct *sm_work; | 114 | struct work_struct *sm_work; |
| 115 | int i, ret; | 115 | int i, ret; |
| @@ -142,7 +142,7 @@ int __stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus) | |||
| 142 | return ret; | 142 | return ret; |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | int stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus) | 145 | int stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus) |
| 146 | { | 146 | { |
| 147 | int ret; | 147 | int ret; |
| 148 | 148 | ||
diff --git a/kernel/taskstats.c b/kernel/taskstats.c index 6d7dc4ec4aa5..888adbcca30c 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c | |||
| @@ -290,18 +290,17 @@ ret: | |||
| 290 | return; | 290 | return; |
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | static int add_del_listener(pid_t pid, cpumask_t *maskp, int isadd) | 293 | static int add_del_listener(pid_t pid, const struct cpumask *mask, int isadd) |
| 294 | { | 294 | { |
| 295 | struct listener_list *listeners; | 295 | struct listener_list *listeners; |
| 296 | struct listener *s, *tmp; | 296 | struct listener *s, *tmp; |
| 297 | unsigned int cpu; | 297 | unsigned int cpu; |
| 298 | cpumask_t mask = *maskp; | ||
| 299 | 298 | ||
| 300 | if (!cpus_subset(mask, cpu_possible_map)) | 299 | if (!cpumask_subset(mask, cpu_possible_mask)) |
| 301 | return -EINVAL; | 300 | return -EINVAL; |
| 302 | 301 | ||
| 303 | if (isadd == REGISTER) { | 302 | if (isadd == REGISTER) { |
| 304 | for_each_cpu_mask_nr(cpu, mask) { | 303 | for_each_cpu(cpu, mask) { |
| 305 | s = kmalloc_node(sizeof(struct listener), GFP_KERNEL, | 304 | s = kmalloc_node(sizeof(struct listener), GFP_KERNEL, |
| 306 | cpu_to_node(cpu)); | 305 | cpu_to_node(cpu)); |
| 307 | if (!s) | 306 | if (!s) |
| @@ -320,7 +319,7 @@ static int add_del_listener(pid_t pid, cpumask_t *maskp, int isadd) | |||
| 320 | 319 | ||
| 321 | /* Deregister or cleanup */ | 320 | /* Deregister or cleanup */ |
| 322 | cleanup: | 321 | cleanup: |
| 323 | for_each_cpu_mask_nr(cpu, mask) { | 322 | for_each_cpu(cpu, mask) { |
| 324 | listeners = &per_cpu(listener_array, cpu); | 323 | listeners = &per_cpu(listener_array, cpu); |
| 325 | down_write(&listeners->sem); | 324 | down_write(&listeners->sem); |
| 326 | list_for_each_entry_safe(s, tmp, &listeners->list, list) { | 325 | list_for_each_entry_safe(s, tmp, &listeners->list, list) { |
| @@ -335,7 +334,7 @@ cleanup: | |||
| 335 | return 0; | 334 | return 0; |
| 336 | } | 335 | } |
| 337 | 336 | ||
| 338 | static int parse(struct nlattr *na, cpumask_t *mask) | 337 | static int parse(struct nlattr *na, struct cpumask *mask) |
| 339 | { | 338 | { |
| 340 | char *data; | 339 | char *data; |
| 341 | int len; | 340 | int len; |
| @@ -428,23 +427,33 @@ err: | |||
| 428 | 427 | ||
| 429 | static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) | 428 | static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) |
| 430 | { | 429 | { |
| 431 | int rc = 0; | 430 | int rc; |
| 432 | struct sk_buff *rep_skb; | 431 | struct sk_buff *rep_skb; |
| 433 | struct taskstats *stats; | 432 | struct taskstats *stats; |
| 434 | size_t size; | 433 | size_t size; |
| 435 | cpumask_t mask; | 434 | cpumask_var_t mask; |
| 435 | |||
| 436 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) | ||
| 437 | return -ENOMEM; | ||
| 436 | 438 | ||
| 437 | rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], &mask); | 439 | rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], mask); |
| 438 | if (rc < 0) | 440 | if (rc < 0) |
| 439 | return rc; | 441 | goto free_return_rc; |
| 440 | if (rc == 0) | 442 | if (rc == 0) { |
| 441 | return add_del_listener(info->snd_pid, &mask, REGISTER); | 443 | rc = add_del_listener(info->snd_pid, mask, REGISTER); |
| 444 | goto free_return_rc; | ||
| 445 | } | ||
| 442 | 446 | ||
| 443 | rc = parse(info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK], &mask); | 447 | rc = parse(info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK], mask); |
| 444 | if (rc < 0) | 448 | if (rc < 0) |
| 449 | goto free_return_rc; | ||
| 450 | if (rc == 0) { | ||
| 451 | rc = add_del_listener(info->snd_pid, mask, DEREGISTER); | ||
| 452 | free_return_rc: | ||
| 453 | free_cpumask_var(mask); | ||
| 445 | return rc; | 454 | return rc; |
| 446 | if (rc == 0) | 455 | } |
| 447 | return add_del_listener(info->snd_pid, &mask, DEREGISTER); | 456 | free_cpumask_var(mask); |
| 448 | 457 | ||
| 449 | /* | 458 | /* |
| 450 | * Size includes space for nested attributes | 459 | * Size includes space for nested attributes |
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 9ed2eec97526..ca89e1593f08 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
| @@ -145,10 +145,11 @@ static void clocksource_watchdog(unsigned long data) | |||
| 145 | * Cycle through CPUs to check if the CPUs stay | 145 | * Cycle through CPUs to check if the CPUs stay |
| 146 | * synchronized to each other. | 146 | * synchronized to each other. |
| 147 | */ | 147 | */ |
| 148 | int next_cpu = next_cpu_nr(raw_smp_processor_id(), cpu_online_map); | 148 | int next_cpu = cpumask_next(raw_smp_processor_id(), |
| 149 | cpu_online_mask); | ||
| 149 | 150 | ||
| 150 | if (next_cpu >= nr_cpu_ids) | 151 | if (next_cpu >= nr_cpu_ids) |
| 151 | next_cpu = first_cpu(cpu_online_map); | 152 | next_cpu = cpumask_first(cpu_online_mask); |
| 152 | watchdog_timer.expires += WATCHDOG_INTERVAL; | 153 | watchdog_timer.expires += WATCHDOG_INTERVAL; |
| 153 | add_timer_on(&watchdog_timer, next_cpu); | 154 | add_timer_on(&watchdog_timer, next_cpu); |
| 154 | } | 155 | } |
| @@ -173,7 +174,7 @@ static void clocksource_check_watchdog(struct clocksource *cs) | |||
| 173 | watchdog_last = watchdog->read(); | 174 | watchdog_last = watchdog->read(); |
| 174 | watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL; | 175 | watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL; |
| 175 | add_timer_on(&watchdog_timer, | 176 | add_timer_on(&watchdog_timer, |
| 176 | first_cpu(cpu_online_map)); | 177 | cpumask_first(cpu_online_mask)); |
| 177 | } | 178 | } |
| 178 | } else { | 179 | } else { |
| 179 | if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) | 180 | if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) |
| @@ -195,7 +196,7 @@ static void clocksource_check_watchdog(struct clocksource *cs) | |||
| 195 | watchdog_timer.expires = | 196 | watchdog_timer.expires = |
| 196 | jiffies + WATCHDOG_INTERVAL; | 197 | jiffies + WATCHDOG_INTERVAL; |
| 197 | add_timer_on(&watchdog_timer, | 198 | add_timer_on(&watchdog_timer, |
| 198 | first_cpu(cpu_online_map)); | 199 | cpumask_first(cpu_online_mask)); |
| 199 | } | 200 | } |
| 200 | } | 201 | } |
| 201 | } | 202 | } |
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 9590af2327be..118a3b3b3f9a 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
| @@ -28,7 +28,9 @@ | |||
| 28 | */ | 28 | */ |
| 29 | 29 | ||
| 30 | struct tick_device tick_broadcast_device; | 30 | struct tick_device tick_broadcast_device; |
| 31 | static cpumask_t tick_broadcast_mask; | 31 | /* FIXME: Use cpumask_var_t. */ |
| 32 | static DECLARE_BITMAP(tick_broadcast_mask, NR_CPUS); | ||
| 33 | static DECLARE_BITMAP(tmpmask, NR_CPUS); | ||
| 32 | static DEFINE_SPINLOCK(tick_broadcast_lock); | 34 | static DEFINE_SPINLOCK(tick_broadcast_lock); |
| 33 | static int tick_broadcast_force; | 35 | static int tick_broadcast_force; |
| 34 | 36 | ||
| @@ -46,9 +48,9 @@ struct tick_device *tick_get_broadcast_device(void) | |||
| 46 | return &tick_broadcast_device; | 48 | return &tick_broadcast_device; |
| 47 | } | 49 | } |
| 48 | 50 | ||
| 49 | cpumask_t *tick_get_broadcast_mask(void) | 51 | struct cpumask *tick_get_broadcast_mask(void) |
| 50 | { | 52 | { |
| 51 | return &tick_broadcast_mask; | 53 | return to_cpumask(tick_broadcast_mask); |
| 52 | } | 54 | } |
| 53 | 55 | ||
| 54 | /* | 56 | /* |
| @@ -72,7 +74,7 @@ int tick_check_broadcast_device(struct clock_event_device *dev) | |||
| 72 | 74 | ||
| 73 | clockevents_exchange_device(NULL, dev); | 75 | clockevents_exchange_device(NULL, dev); |
| 74 | tick_broadcast_device.evtdev = dev; | 76 | tick_broadcast_device.evtdev = dev; |
| 75 | if (!cpus_empty(tick_broadcast_mask)) | 77 | if (!cpumask_empty(tick_get_broadcast_mask())) |
| 76 | tick_broadcast_start_periodic(dev); | 78 | tick_broadcast_start_periodic(dev); |
| 77 | return 1; | 79 | return 1; |
| 78 | } | 80 | } |
| @@ -104,7 +106,7 @@ int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu) | |||
| 104 | */ | 106 | */ |
| 105 | if (!tick_device_is_functional(dev)) { | 107 | if (!tick_device_is_functional(dev)) { |
| 106 | dev->event_handler = tick_handle_periodic; | 108 | dev->event_handler = tick_handle_periodic; |
| 107 | cpu_set(cpu, tick_broadcast_mask); | 109 | cpumask_set_cpu(cpu, tick_get_broadcast_mask()); |
| 108 | tick_broadcast_start_periodic(tick_broadcast_device.evtdev); | 110 | tick_broadcast_start_periodic(tick_broadcast_device.evtdev); |
| 109 | ret = 1; | 111 | ret = 1; |
| 110 | } else { | 112 | } else { |
| @@ -116,7 +118,7 @@ int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu) | |||
| 116 | if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) { | 118 | if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) { |
| 117 | int cpu = smp_processor_id(); | 119 | int cpu = smp_processor_id(); |
| 118 | 120 | ||
| 119 | cpu_clear(cpu, tick_broadcast_mask); | 121 | cpumask_clear_cpu(cpu, tick_get_broadcast_mask()); |
| 120 | tick_broadcast_clear_oneshot(cpu); | 122 | tick_broadcast_clear_oneshot(cpu); |
| 121 | } | 123 | } |
| 122 | } | 124 | } |
| @@ -125,9 +127,9 @@ int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu) | |||
| 125 | } | 127 | } |
| 126 | 128 | ||
| 127 | /* | 129 | /* |
| 128 | * Broadcast the event to the cpus, which are set in the mask | 130 | * Broadcast the event to the cpus, which are set in the mask (mangled). |
| 129 | */ | 131 | */ |
| 130 | static void tick_do_broadcast(cpumask_t mask) | 132 | static void tick_do_broadcast(struct cpumask *mask) |
| 131 | { | 133 | { |
| 132 | int cpu = smp_processor_id(); | 134 | int cpu = smp_processor_id(); |
| 133 | struct tick_device *td; | 135 | struct tick_device *td; |
| @@ -135,22 +137,21 @@ static void tick_do_broadcast(cpumask_t mask) | |||
| 135 | /* | 137 | /* |
| 136 | * Check, if the current cpu is in the mask | 138 | * Check, if the current cpu is in the mask |
| 137 | */ | 139 | */ |
| 138 | if (cpu_isset(cpu, mask)) { | 140 | if (cpumask_test_cpu(cpu, mask)) { |
| 139 | cpu_clear(cpu, mask); | 141 | cpumask_clear_cpu(cpu, mask); |
| 140 | td = &per_cpu(tick_cpu_device, cpu); | 142 | td = &per_cpu(tick_cpu_device, cpu); |
| 141 | td->evtdev->event_handler(td->evtdev); | 143 | td->evtdev->event_handler(td->evtdev); |
| 142 | } | 144 | } |
| 143 | 145 | ||
| 144 | if (!cpus_empty(mask)) { | 146 | if (!cpumask_empty(mask)) { |
| 145 | /* | 147 | /* |
| 146 | * It might be necessary to actually check whether the devices | 148 | * It might be necessary to actually check whether the devices |
| 147 | * have different broadcast functions. For now, just use the | 149 | * have different broadcast functions. For now, just use the |
| 148 | * one of the first device. This works as long as we have this | 150 | * one of the first device. This works as long as we have this |
| 149 | * misfeature only on x86 (lapic) | 151 | * misfeature only on x86 (lapic) |
| 150 | */ | 152 | */ |
| 151 | cpu = first_cpu(mask); | 153 | td = &per_cpu(tick_cpu_device, cpumask_first(mask)); |
| 152 | td = &per_cpu(tick_cpu_device, cpu); | 154 | td->evtdev->broadcast(mask); |
| 153 | td->evtdev->broadcast(&mask); | ||
| 154 | } | 155 | } |
| 155 | } | 156 | } |
| 156 | 157 | ||
| @@ -160,12 +161,11 @@ static void tick_do_broadcast(cpumask_t mask) | |||
| 160 | */ | 161 | */ |
| 161 | static void tick_do_periodic_broadcast(void) | 162 | static void tick_do_periodic_broadcast(void) |
| 162 | { | 163 | { |
| 163 | cpumask_t mask; | ||
| 164 | |||
| 165 | spin_lock(&tick_broadcast_lock); | 164 | spin_lock(&tick_broadcast_lock); |
| 166 | 165 | ||
| 167 | cpus_and(mask, cpu_online_map, tick_broadcast_mask); | 166 | cpumask_and(to_cpumask(tmpmask), |
| 168 | tick_do_broadcast(mask); | 167 | cpu_online_mask, tick_get_broadcast_mask()); |
| 168 | tick_do_broadcast(to_cpumask(tmpmask)); | ||
| 169 | 169 | ||
| 170 | spin_unlock(&tick_broadcast_lock); | 170 | spin_unlock(&tick_broadcast_lock); |
| 171 | } | 171 | } |
| @@ -228,13 +228,13 @@ static void tick_do_broadcast_on_off(void *why) | |||
| 228 | if (!tick_device_is_functional(dev)) | 228 | if (!tick_device_is_functional(dev)) |
| 229 | goto out; | 229 | goto out; |
| 230 | 230 | ||
| 231 | bc_stopped = cpus_empty(tick_broadcast_mask); | 231 | bc_stopped = cpumask_empty(tick_get_broadcast_mask()); |
| 232 | 232 | ||
| 233 | switch (*reason) { | 233 | switch (*reason) { |
| 234 | case CLOCK_EVT_NOTIFY_BROADCAST_ON: | 234 | case CLOCK_EVT_NOTIFY_BROADCAST_ON: |
| 235 | case CLOCK_EVT_NOTIFY_BROADCAST_FORCE: | 235 | case CLOCK_EVT_NOTIFY_BROADCAST_FORCE: |
| 236 | if (!cpu_isset(cpu, tick_broadcast_mask)) { | 236 | if (!cpumask_test_cpu(cpu, tick_get_broadcast_mask())) { |
| 237 | cpu_set(cpu, tick_broadcast_mask); | 237 | cpumask_set_cpu(cpu, tick_get_broadcast_mask()); |
| 238 | if (tick_broadcast_device.mode == | 238 | if (tick_broadcast_device.mode == |
| 239 | TICKDEV_MODE_PERIODIC) | 239 | TICKDEV_MODE_PERIODIC) |
| 240 | clockevents_shutdown(dev); | 240 | clockevents_shutdown(dev); |
| @@ -244,8 +244,8 @@ static void tick_do_broadcast_on_off(void *why) | |||
| 244 | break; | 244 | break; |
| 245 | case CLOCK_EVT_NOTIFY_BROADCAST_OFF: | 245 | case CLOCK_EVT_NOTIFY_BROADCAST_OFF: |
| 246 | if (!tick_broadcast_force && | 246 | if (!tick_broadcast_force && |
| 247 | cpu_isset(cpu, tick_broadcast_mask)) { | 247 | cpumask_test_cpu(cpu, tick_get_broadcast_mask())) { |
| 248 | cpu_clear(cpu, tick_broadcast_mask); | 248 | cpumask_clear_cpu(cpu, tick_get_broadcast_mask()); |
| 249 | if (tick_broadcast_device.mode == | 249 | if (tick_broadcast_device.mode == |
| 250 | TICKDEV_MODE_PERIODIC) | 250 | TICKDEV_MODE_PERIODIC) |
| 251 | tick_setup_periodic(dev, 0); | 251 | tick_setup_periodic(dev, 0); |
| @@ -253,7 +253,7 @@ static void tick_do_broadcast_on_off(void *why) | |||
| 253 | break; | 253 | break; |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | if (cpus_empty(tick_broadcast_mask)) { | 256 | if (cpumask_empty(tick_get_broadcast_mask())) { |
| 257 | if (!bc_stopped) | 257 | if (!bc_stopped) |
| 258 | clockevents_shutdown(bc); | 258 | clockevents_shutdown(bc); |
| 259 | } else if (bc_stopped) { | 259 | } else if (bc_stopped) { |
| @@ -272,7 +272,7 @@ out: | |||
| 272 | */ | 272 | */ |
| 273 | void tick_broadcast_on_off(unsigned long reason, int *oncpu) | 273 | void tick_broadcast_on_off(unsigned long reason, int *oncpu) |
| 274 | { | 274 | { |
| 275 | if (!cpu_isset(*oncpu, cpu_online_map)) | 275 | if (!cpumask_test_cpu(*oncpu, cpu_online_mask)) |
| 276 | printk(KERN_ERR "tick-broadcast: ignoring broadcast for " | 276 | printk(KERN_ERR "tick-broadcast: ignoring broadcast for " |
| 277 | "offline CPU #%d\n", *oncpu); | 277 | "offline CPU #%d\n", *oncpu); |
| 278 | else | 278 | else |
| @@ -303,10 +303,10 @@ void tick_shutdown_broadcast(unsigned int *cpup) | |||
| 303 | spin_lock_irqsave(&tick_broadcast_lock, flags); | 303 | spin_lock_irqsave(&tick_broadcast_lock, flags); |
| 304 | 304 | ||
| 305 | bc = tick_broadcast_device.evtdev; | 305 | bc = tick_broadcast_device.evtdev; |
| 306 | cpu_clear(cpu, tick_broadcast_mask); | 306 | cpumask_clear_cpu(cpu, tick_get_broadcast_mask()); |
| 307 | 307 | ||
| 308 | if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) { | 308 | if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) { |
| 309 | if (bc && cpus_empty(tick_broadcast_mask)) | 309 | if (bc && cpumask_empty(tick_get_broadcast_mask())) |
| 310 | clockevents_shutdown(bc); | 310 | clockevents_shutdown(bc); |
| 311 | } | 311 | } |
| 312 | 312 | ||
| @@ -342,10 +342,10 @@ int tick_resume_broadcast(void) | |||
| 342 | 342 | ||
| 343 | switch (tick_broadcast_device.mode) { | 343 | switch (tick_broadcast_device.mode) { |
| 344 | case TICKDEV_MODE_PERIODIC: | 344 | case TICKDEV_MODE_PERIODIC: |
| 345 | if(!cpus_empty(tick_broadcast_mask)) | 345 | if (!cpumask_empty(tick_get_broadcast_mask())) |
| 346 | tick_broadcast_start_periodic(bc); | 346 | tick_broadcast_start_periodic(bc); |
| 347 | broadcast = cpu_isset(smp_processor_id(), | 347 | broadcast = cpumask_test_cpu(smp_processor_id(), |
| 348 | tick_broadcast_mask); | 348 | tick_get_broadcast_mask()); |
| 349 | break; | 349 | break; |
| 350 | case TICKDEV_MODE_ONESHOT: | 350 | case TICKDEV_MODE_ONESHOT: |
| 351 | broadcast = tick_resume_broadcast_oneshot(bc); | 351 | broadcast = tick_resume_broadcast_oneshot(bc); |
| @@ -360,14 +360,15 @@ int tick_resume_broadcast(void) | |||
| 360 | 360 | ||
| 361 | #ifdef CONFIG_TICK_ONESHOT | 361 | #ifdef CONFIG_TICK_ONESHOT |
| 362 | 362 | ||
| 363 | static cpumask_t tick_broadcast_oneshot_mask; | 363 | /* FIXME: use cpumask_var_t. */ |
| 364 | static DECLARE_BITMAP(tick_broadcast_oneshot_mask, NR_CPUS); | ||
| 364 | 365 | ||
| 365 | /* | 366 | /* |
| 366 | * Debugging: see timer_list.c | 367 | * Exposed for debugging: see timer_list.c |
| 367 | */ | 368 | */ |
| 368 | cpumask_t *tick_get_broadcast_oneshot_mask(void) | 369 | struct cpumask *tick_get_broadcast_oneshot_mask(void) |
| 369 | { | 370 | { |
| 370 | return &tick_broadcast_oneshot_mask; | 371 | return to_cpumask(tick_broadcast_oneshot_mask); |
| 371 | } | 372 | } |
| 372 | 373 | ||
| 373 | static int tick_broadcast_set_event(ktime_t expires, int force) | 374 | static int tick_broadcast_set_event(ktime_t expires, int force) |
| @@ -389,7 +390,7 @@ int tick_resume_broadcast_oneshot(struct clock_event_device *bc) | |||
| 389 | */ | 390 | */ |
| 390 | void tick_check_oneshot_broadcast(int cpu) | 391 | void tick_check_oneshot_broadcast(int cpu) |
| 391 | { | 392 | { |
| 392 | if (cpu_isset(cpu, tick_broadcast_oneshot_mask)) { | 393 | if (cpumask_test_cpu(cpu, to_cpumask(tick_broadcast_oneshot_mask))) { |
| 393 | struct tick_device *td = &per_cpu(tick_cpu_device, cpu); | 394 | struct tick_device *td = &per_cpu(tick_cpu_device, cpu); |
| 394 | 395 | ||
| 395 | clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_ONESHOT); | 396 | clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_ONESHOT); |
| @@ -402,7 +403,6 @@ void tick_check_oneshot_broadcast(int cpu) | |||
| 402 | static void tick_handle_oneshot_broadcast(struct clock_event_device *dev) | 403 | static void tick_handle_oneshot_broadcast(struct clock_event_device *dev) |
| 403 | { | 404 | { |
| 404 | struct tick_device *td; | 405 | struct tick_device *td; |
| 405 | cpumask_t mask; | ||
| 406 | ktime_t now, next_event; | 406 | ktime_t now, next_event; |
| 407 | int cpu; | 407 | int cpu; |
| 408 | 408 | ||
| @@ -410,13 +410,13 @@ static void tick_handle_oneshot_broadcast(struct clock_event_device *dev) | |||
| 410 | again: | 410 | again: |
| 411 | dev->next_event.tv64 = KTIME_MAX; | 411 | dev->next_event.tv64 = KTIME_MAX; |
| 412 | next_event.tv64 = KTIME_MAX; | 412 | next_event.tv64 = KTIME_MAX; |
| 413 | mask = CPU_MASK_NONE; | 413 | cpumask_clear(to_cpumask(tmpmask)); |
| 414 | now = ktime_get(); | 414 | now = ktime_get(); |
| 415 | /* Find all expired events */ | 415 | /* Find all expired events */ |
| 416 | for_each_cpu_mask_nr(cpu, tick_broadcast_oneshot_mask) { | 416 | for_each_cpu(cpu, tick_get_broadcast_oneshot_mask()) { |
| 417 | td = &per_cpu(tick_cpu_device, cpu); | 417 | td = &per_cpu(tick_cpu_device, cpu); |
| 418 | if (td->evtdev->next_event.tv64 <= now.tv64) | 418 | if (td->evtdev->next_event.tv64 <= now.tv64) |
| 419 | cpu_set(cpu, mask); | 419 | cpumask_set_cpu(cpu, to_cpumask(tmpmask)); |
| 420 | else if (td->evtdev->next_event.tv64 < next_event.tv64) | 420 | else if (td->evtdev->next_event.tv64 < next_event.tv64) |
| 421 | next_event.tv64 = td->evtdev->next_event.tv64; | 421 | next_event.tv64 = td->evtdev->next_event.tv64; |
| 422 | } | 422 | } |
| @@ -424,7 +424,7 @@ again: | |||
| 424 | /* | 424 | /* |
| 425 | * Wakeup the cpus which have an expired event. | 425 | * Wakeup the cpus which have an expired event. |
| 426 | */ | 426 | */ |
| 427 | tick_do_broadcast(mask); | 427 | tick_do_broadcast(to_cpumask(tmpmask)); |
| 428 | 428 | ||
| 429 | /* | 429 | /* |
| 430 | * Two reasons for reprogram: | 430 | * Two reasons for reprogram: |
| @@ -476,15 +476,16 @@ void tick_broadcast_oneshot_control(unsigned long reason) | |||
| 476 | goto out; | 476 | goto out; |
| 477 | 477 | ||
| 478 | if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) { | 478 | if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) { |
| 479 | if (!cpu_isset(cpu, tick_broadcast_oneshot_mask)) { | 479 | if (!cpumask_test_cpu(cpu, tick_get_broadcast_oneshot_mask())) { |
| 480 | cpu_set(cpu, tick_broadcast_oneshot_mask); | 480 | cpumask_set_cpu(cpu, tick_get_broadcast_oneshot_mask()); |
| 481 | clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN); | 481 | clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN); |
| 482 | if (dev->next_event.tv64 < bc->next_event.tv64) | 482 | if (dev->next_event.tv64 < bc->next_event.tv64) |
| 483 | tick_broadcast_set_event(dev->next_event, 1); | 483 | tick_broadcast_set_event(dev->next_event, 1); |
| 484 | } | 484 | } |
| 485 | } else { | 485 | } else { |
| 486 | if (cpu_isset(cpu, tick_broadcast_oneshot_mask)) { | 486 | if (cpumask_test_cpu(cpu, tick_get_broadcast_oneshot_mask())) { |
| 487 | cpu_clear(cpu, tick_broadcast_oneshot_mask); | 487 | cpumask_clear_cpu(cpu, |
| 488 | tick_get_broadcast_oneshot_mask()); | ||
| 488 | clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT); | 489 | clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT); |
| 489 | if (dev->next_event.tv64 != KTIME_MAX) | 490 | if (dev->next_event.tv64 != KTIME_MAX) |
| 490 | tick_program_event(dev->next_event, 1); | 491 | tick_program_event(dev->next_event, 1); |
| @@ -502,15 +503,16 @@ out: | |||
| 502 | */ | 503 | */ |
| 503 | static void tick_broadcast_clear_oneshot(int cpu) | 504 | static void tick_broadcast_clear_oneshot(int cpu) |
| 504 | { | 505 | { |
| 505 | cpu_clear(cpu, tick_broadcast_oneshot_mask); | 506 | cpumask_clear_cpu(cpu, tick_get_broadcast_oneshot_mask()); |
| 506 | } | 507 | } |
| 507 | 508 | ||
| 508 | static void tick_broadcast_init_next_event(cpumask_t *mask, ktime_t expires) | 509 | static void tick_broadcast_init_next_event(struct cpumask *mask, |
| 510 | ktime_t expires) | ||
| 509 | { | 511 | { |
| 510 | struct tick_device *td; | 512 | struct tick_device *td; |
| 511 | int cpu; | 513 | int cpu; |
| 512 | 514 | ||
| 513 | for_each_cpu_mask_nr(cpu, *mask) { | 515 | for_each_cpu(cpu, mask) { |
| 514 | td = &per_cpu(tick_cpu_device, cpu); | 516 | td = &per_cpu(tick_cpu_device, cpu); |
| 515 | if (td->evtdev) | 517 | if (td->evtdev) |
| 516 | td->evtdev->next_event = expires; | 518 | td->evtdev->next_event = expires; |
| @@ -526,7 +528,6 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc) | |||
| 526 | if (bc->event_handler != tick_handle_oneshot_broadcast) { | 528 | if (bc->event_handler != tick_handle_oneshot_broadcast) { |
| 527 | int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC; | 529 | int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC; |
| 528 | int cpu = smp_processor_id(); | 530 | int cpu = smp_processor_id(); |
| 529 | cpumask_t mask; | ||
| 530 | 531 | ||
| 531 | bc->event_handler = tick_handle_oneshot_broadcast; | 532 | bc->event_handler = tick_handle_oneshot_broadcast; |
| 532 | clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); | 533 | clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); |
| @@ -540,13 +541,15 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc) | |||
| 540 | * oneshot_mask bits for those and program the | 541 | * oneshot_mask bits for those and program the |
| 541 | * broadcast device to fire. | 542 | * broadcast device to fire. |
| 542 | */ | 543 | */ |
| 543 | mask = tick_broadcast_mask; | 544 | cpumask_copy(to_cpumask(tmpmask), tick_get_broadcast_mask()); |
| 544 | cpu_clear(cpu, mask); | 545 | cpumask_clear_cpu(cpu, to_cpumask(tmpmask)); |
| 545 | cpus_or(tick_broadcast_oneshot_mask, | 546 | cpumask_or(tick_get_broadcast_oneshot_mask(), |
| 546 | tick_broadcast_oneshot_mask, mask); | 547 | tick_get_broadcast_oneshot_mask(), |
| 547 | 548 | to_cpumask(tmpmask)); | |
| 548 | if (was_periodic && !cpus_empty(mask)) { | 549 | |
| 549 | tick_broadcast_init_next_event(&mask, tick_next_period); | 550 | if (was_periodic && !cpumask_empty(to_cpumask(tmpmask))) { |
| 551 | tick_broadcast_init_next_event(to_cpumask(tmpmask), | ||
| 552 | tick_next_period); | ||
| 550 | tick_broadcast_set_event(tick_next_period, 1); | 553 | tick_broadcast_set_event(tick_next_period, 1); |
| 551 | } else | 554 | } else |
| 552 | bc->next_event.tv64 = KTIME_MAX; | 555 | bc->next_event.tv64 = KTIME_MAX; |
| @@ -585,7 +588,7 @@ void tick_shutdown_broadcast_oneshot(unsigned int *cpup) | |||
| 585 | * Clear the broadcast mask flag for the dead cpu, but do not | 588 | * Clear the broadcast mask flag for the dead cpu, but do not |
| 586 | * stop the broadcast device! | 589 | * stop the broadcast device! |
| 587 | */ | 590 | */ |
| 588 | cpu_clear(cpu, tick_broadcast_oneshot_mask); | 591 | cpumask_clear_cpu(cpu, tick_get_broadcast_oneshot_mask()); |
| 589 | 592 | ||
| 590 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); | 593 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); |
| 591 | } | 594 | } |
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index f8372be74122..63e05d423a09 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c | |||
| @@ -254,7 +254,7 @@ static int tick_check_new_device(struct clock_event_device *newdev) | |||
| 254 | curdev = NULL; | 254 | curdev = NULL; |
| 255 | } | 255 | } |
| 256 | clockevents_exchange_device(curdev, newdev); | 256 | clockevents_exchange_device(curdev, newdev); |
| 257 | tick_setup_device(td, newdev, cpu, &cpumask_of_cpu(cpu)); | 257 | tick_setup_device(td, newdev, cpu, cpumask_of(cpu)); |
| 258 | if (newdev->features & CLOCK_EVT_FEAT_ONESHOT) | 258 | if (newdev->features & CLOCK_EVT_FEAT_ONESHOT) |
| 259 | tick_oneshot_notify(); | 259 | tick_oneshot_notify(); |
| 260 | 260 | ||
| @@ -299,9 +299,9 @@ static void tick_shutdown(unsigned int *cpup) | |||
| 299 | } | 299 | } |
| 300 | /* Transfer the do_timer job away from this cpu */ | 300 | /* Transfer the do_timer job away from this cpu */ |
| 301 | if (*cpup == tick_do_timer_cpu) { | 301 | if (*cpup == tick_do_timer_cpu) { |
| 302 | int cpu = first_cpu(cpu_online_map); | 302 | int cpu = cpumask_first(cpu_online_mask); |
| 303 | 303 | ||
| 304 | tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu : | 304 | tick_do_timer_cpu = (cpu < nr_cpu_ids) ? cpu : |
| 305 | TICK_DO_TIMER_NONE; | 305 | TICK_DO_TIMER_NONE; |
| 306 | } | 306 | } |
| 307 | spin_unlock_irqrestore(&tick_device_lock, flags); | 307 | spin_unlock_irqrestore(&tick_device_lock, flags); |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 76a574bbef97..1b6c05bd0d0a 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
| @@ -419,7 +419,9 @@ void tick_nohz_restart_sched_tick(void) | |||
| 419 | { | 419 | { |
| 420 | int cpu = smp_processor_id(); | 420 | int cpu = smp_processor_id(); |
| 421 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); | 421 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); |
| 422 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | ||
| 422 | unsigned long ticks; | 423 | unsigned long ticks; |
| 424 | #endif | ||
| 423 | ktime_t now; | 425 | ktime_t now; |
| 424 | 426 | ||
| 425 | local_irq_disable(); | 427 | local_irq_disable(); |
| @@ -441,6 +443,7 @@ void tick_nohz_restart_sched_tick(void) | |||
| 441 | tick_do_update_jiffies64(now); | 443 | tick_do_update_jiffies64(now); |
| 442 | cpumask_clear_cpu(cpu, nohz_cpu_mask); | 444 | cpumask_clear_cpu(cpu, nohz_cpu_mask); |
| 443 | 445 | ||
| 446 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | ||
| 444 | /* | 447 | /* |
| 445 | * We stopped the tick in idle. Update process times would miss the | 448 | * We stopped the tick in idle. Update process times would miss the |
| 446 | * time we slept as update_process_times does only a 1 tick | 449 | * time we slept as update_process_times does only a 1 tick |
| @@ -450,12 +453,9 @@ void tick_nohz_restart_sched_tick(void) | |||
| 450 | /* | 453 | /* |
| 451 | * We might be one off. Do not randomly account a huge number of ticks! | 454 | * We might be one off. Do not randomly account a huge number of ticks! |
| 452 | */ | 455 | */ |
| 453 | if (ticks && ticks < LONG_MAX) { | 456 | if (ticks && ticks < LONG_MAX) |
| 454 | add_preempt_count(HARDIRQ_OFFSET); | 457 | account_idle_ticks(ticks); |
| 455 | account_system_time(current, HARDIRQ_OFFSET, | 458 | #endif |
| 456 | jiffies_to_cputime(ticks)); | ||
| 457 | sub_preempt_count(HARDIRQ_OFFSET); | ||
| 458 | } | ||
| 459 | 459 | ||
| 460 | touch_softlockup_watchdog(); | 460 | touch_softlockup_watchdog(); |
| 461 | /* | 461 | /* |
diff --git a/kernel/timer.c b/kernel/timer.c index 566257d1dc10..dee3f641a7a7 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
| @@ -1018,21 +1018,6 @@ unsigned long get_next_timer_interrupt(unsigned long now) | |||
| 1018 | } | 1018 | } |
| 1019 | #endif | 1019 | #endif |
| 1020 | 1020 | ||
| 1021 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | ||
| 1022 | void account_process_tick(struct task_struct *p, int user_tick) | ||
| 1023 | { | ||
| 1024 | cputime_t one_jiffy = jiffies_to_cputime(1); | ||
| 1025 | |||
| 1026 | if (user_tick) { | ||
| 1027 | account_user_time(p, one_jiffy); | ||
| 1028 | account_user_time_scaled(p, cputime_to_scaled(one_jiffy)); | ||
| 1029 | } else { | ||
| 1030 | account_system_time(p, HARDIRQ_OFFSET, one_jiffy); | ||
| 1031 | account_system_time_scaled(p, cputime_to_scaled(one_jiffy)); | ||
| 1032 | } | ||
| 1033 | } | ||
| 1034 | #endif | ||
| 1035 | |||
| 1036 | /* | 1021 | /* |
| 1037 | * Called from the timer interrupt handler to charge one tick to the current | 1022 | * Called from the timer interrupt handler to charge one tick to the current |
| 1038 | * process. user_tick is 1 if the tick is user time, 0 for system. | 1023 | * process. user_tick is 1 if the tick is user time, 0 for system. |
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 1d601a7c4587..a9d9760dc7b6 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
| @@ -195,7 +195,7 @@ void *ring_buffer_event_data(struct ring_buffer_event *event) | |||
| 195 | EXPORT_SYMBOL_GPL(ring_buffer_event_data); | 195 | EXPORT_SYMBOL_GPL(ring_buffer_event_data); |
| 196 | 196 | ||
| 197 | #define for_each_buffer_cpu(buffer, cpu) \ | 197 | #define for_each_buffer_cpu(buffer, cpu) \ |
| 198 | for_each_cpu_mask(cpu, buffer->cpumask) | 198 | for_each_cpu(cpu, buffer->cpumask) |
| 199 | 199 | ||
| 200 | #define TS_SHIFT 27 | 200 | #define TS_SHIFT 27 |
| 201 | #define TS_MASK ((1ULL << TS_SHIFT) - 1) | 201 | #define TS_MASK ((1ULL << TS_SHIFT) - 1) |
| @@ -267,7 +267,7 @@ struct ring_buffer { | |||
| 267 | unsigned pages; | 267 | unsigned pages; |
| 268 | unsigned flags; | 268 | unsigned flags; |
| 269 | int cpus; | 269 | int cpus; |
| 270 | cpumask_t cpumask; | 270 | cpumask_var_t cpumask; |
| 271 | atomic_t record_disabled; | 271 | atomic_t record_disabled; |
| 272 | 272 | ||
| 273 | struct mutex mutex; | 273 | struct mutex mutex; |
| @@ -458,6 +458,9 @@ struct ring_buffer *ring_buffer_alloc(unsigned long size, unsigned flags) | |||
| 458 | if (!buffer) | 458 | if (!buffer) |
| 459 | return NULL; | 459 | return NULL; |
| 460 | 460 | ||
| 461 | if (!alloc_cpumask_var(&buffer->cpumask, GFP_KERNEL)) | ||
| 462 | goto fail_free_buffer; | ||
| 463 | |||
| 461 | buffer->pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE); | 464 | buffer->pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE); |
| 462 | buffer->flags = flags; | 465 | buffer->flags = flags; |
| 463 | 466 | ||
| @@ -465,14 +468,14 @@ struct ring_buffer *ring_buffer_alloc(unsigned long size, unsigned flags) | |||
| 465 | if (buffer->pages == 1) | 468 | if (buffer->pages == 1) |
| 466 | buffer->pages++; | 469 | buffer->pages++; |
| 467 | 470 | ||
| 468 | buffer->cpumask = cpu_possible_map; | 471 | cpumask_copy(buffer->cpumask, cpu_possible_mask); |
| 469 | buffer->cpus = nr_cpu_ids; | 472 | buffer->cpus = nr_cpu_ids; |
| 470 | 473 | ||
| 471 | bsize = sizeof(void *) * nr_cpu_ids; | 474 | bsize = sizeof(void *) * nr_cpu_ids; |
| 472 | buffer->buffers = kzalloc(ALIGN(bsize, cache_line_size()), | 475 | buffer->buffers = kzalloc(ALIGN(bsize, cache_line_size()), |
| 473 | GFP_KERNEL); | 476 | GFP_KERNEL); |
| 474 | if (!buffer->buffers) | 477 | if (!buffer->buffers) |
| 475 | goto fail_free_buffer; | 478 | goto fail_free_cpumask; |
| 476 | 479 | ||
| 477 | for_each_buffer_cpu(buffer, cpu) { | 480 | for_each_buffer_cpu(buffer, cpu) { |
| 478 | buffer->buffers[cpu] = | 481 | buffer->buffers[cpu] = |
| @@ -492,6 +495,9 @@ struct ring_buffer *ring_buffer_alloc(unsigned long size, unsigned flags) | |||
| 492 | } | 495 | } |
| 493 | kfree(buffer->buffers); | 496 | kfree(buffer->buffers); |
| 494 | 497 | ||
| 498 | fail_free_cpumask: | ||
| 499 | free_cpumask_var(buffer->cpumask); | ||
| 500 | |||
| 495 | fail_free_buffer: | 501 | fail_free_buffer: |
| 496 | kfree(buffer); | 502 | kfree(buffer); |
| 497 | return NULL; | 503 | return NULL; |
| @@ -510,6 +516,8 @@ ring_buffer_free(struct ring_buffer *buffer) | |||
| 510 | for_each_buffer_cpu(buffer, cpu) | 516 | for_each_buffer_cpu(buffer, cpu) |
| 511 | rb_free_cpu_buffer(buffer->buffers[cpu]); | 517 | rb_free_cpu_buffer(buffer->buffers[cpu]); |
| 512 | 518 | ||
| 519 | free_cpumask_var(buffer->cpumask); | ||
| 520 | |||
| 513 | kfree(buffer); | 521 | kfree(buffer); |
| 514 | } | 522 | } |
| 515 | EXPORT_SYMBOL_GPL(ring_buffer_free); | 523 | EXPORT_SYMBOL_GPL(ring_buffer_free); |
| @@ -1283,7 +1291,7 @@ ring_buffer_lock_reserve(struct ring_buffer *buffer, | |||
| 1283 | 1291 | ||
| 1284 | cpu = raw_smp_processor_id(); | 1292 | cpu = raw_smp_processor_id(); |
| 1285 | 1293 | ||
| 1286 | if (!cpu_isset(cpu, buffer->cpumask)) | 1294 | if (!cpumask_test_cpu(cpu, buffer->cpumask)) |
| 1287 | goto out; | 1295 | goto out; |
| 1288 | 1296 | ||
| 1289 | cpu_buffer = buffer->buffers[cpu]; | 1297 | cpu_buffer = buffer->buffers[cpu]; |
| @@ -1396,7 +1404,7 @@ int ring_buffer_write(struct ring_buffer *buffer, | |||
| 1396 | 1404 | ||
| 1397 | cpu = raw_smp_processor_id(); | 1405 | cpu = raw_smp_processor_id(); |
| 1398 | 1406 | ||
| 1399 | if (!cpu_isset(cpu, buffer->cpumask)) | 1407 | if (!cpumask_test_cpu(cpu, buffer->cpumask)) |
| 1400 | goto out; | 1408 | goto out; |
| 1401 | 1409 | ||
| 1402 | cpu_buffer = buffer->buffers[cpu]; | 1410 | cpu_buffer = buffer->buffers[cpu]; |
| @@ -1478,7 +1486,7 @@ void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu) | |||
| 1478 | { | 1486 | { |
| 1479 | struct ring_buffer_per_cpu *cpu_buffer; | 1487 | struct ring_buffer_per_cpu *cpu_buffer; |
| 1480 | 1488 | ||
| 1481 | if (!cpu_isset(cpu, buffer->cpumask)) | 1489 | if (!cpumask_test_cpu(cpu, buffer->cpumask)) |
| 1482 | return; | 1490 | return; |
| 1483 | 1491 | ||
| 1484 | cpu_buffer = buffer->buffers[cpu]; | 1492 | cpu_buffer = buffer->buffers[cpu]; |
| @@ -1498,7 +1506,7 @@ void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu) | |||
| 1498 | { | 1506 | { |
| 1499 | struct ring_buffer_per_cpu *cpu_buffer; | 1507 | struct ring_buffer_per_cpu *cpu_buffer; |
| 1500 | 1508 | ||
| 1501 | if (!cpu_isset(cpu, buffer->cpumask)) | 1509 | if (!cpumask_test_cpu(cpu, buffer->cpumask)) |
| 1502 | return; | 1510 | return; |
| 1503 | 1511 | ||
| 1504 | cpu_buffer = buffer->buffers[cpu]; | 1512 | cpu_buffer = buffer->buffers[cpu]; |
| @@ -1515,7 +1523,7 @@ unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu) | |||
| 1515 | { | 1523 | { |
| 1516 | struct ring_buffer_per_cpu *cpu_buffer; | 1524 | struct ring_buffer_per_cpu *cpu_buffer; |
| 1517 | 1525 | ||
| 1518 | if (!cpu_isset(cpu, buffer->cpumask)) | 1526 | if (!cpumask_test_cpu(cpu, buffer->cpumask)) |
| 1519 | return 0; | 1527 | return 0; |
| 1520 | 1528 | ||
| 1521 | cpu_buffer = buffer->buffers[cpu]; | 1529 | cpu_buffer = buffer->buffers[cpu]; |
| @@ -1532,7 +1540,7 @@ unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu) | |||
| 1532 | { | 1540 | { |
| 1533 | struct ring_buffer_per_cpu *cpu_buffer; | 1541 | struct ring_buffer_per_cpu *cpu_buffer; |
| 1534 | 1542 | ||
| 1535 | if (!cpu_isset(cpu, buffer->cpumask)) | 1543 | if (!cpumask_test_cpu(cpu, buffer->cpumask)) |
| 1536 | return 0; | 1544 | return 0; |
| 1537 | 1545 | ||
| 1538 | cpu_buffer = buffer->buffers[cpu]; | 1546 | cpu_buffer = buffer->buffers[cpu]; |
| @@ -1850,7 +1858,7 @@ rb_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts) | |||
| 1850 | struct buffer_page *reader; | 1858 | struct buffer_page *reader; |
| 1851 | int nr_loops = 0; | 1859 | int nr_loops = 0; |
| 1852 | 1860 | ||
| 1853 | if (!cpu_isset(cpu, buffer->cpumask)) | 1861 | if (!cpumask_test_cpu(cpu, buffer->cpumask)) |
| 1854 | return NULL; | 1862 | return NULL; |
| 1855 | 1863 | ||
| 1856 | cpu_buffer = buffer->buffers[cpu]; | 1864 | cpu_buffer = buffer->buffers[cpu]; |
| @@ -2025,7 +2033,7 @@ ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts) | |||
| 2025 | struct ring_buffer_event *event; | 2033 | struct ring_buffer_event *event; |
| 2026 | unsigned long flags; | 2034 | unsigned long flags; |
| 2027 | 2035 | ||
| 2028 | if (!cpu_isset(cpu, buffer->cpumask)) | 2036 | if (!cpumask_test_cpu(cpu, buffer->cpumask)) |
| 2029 | return NULL; | 2037 | return NULL; |
| 2030 | 2038 | ||
| 2031 | spin_lock_irqsave(&cpu_buffer->reader_lock, flags); | 2039 | spin_lock_irqsave(&cpu_buffer->reader_lock, flags); |
| @@ -2062,7 +2070,7 @@ ring_buffer_read_start(struct ring_buffer *buffer, int cpu) | |||
| 2062 | struct ring_buffer_iter *iter; | 2070 | struct ring_buffer_iter *iter; |
| 2063 | unsigned long flags; | 2071 | unsigned long flags; |
| 2064 | 2072 | ||
| 2065 | if (!cpu_isset(cpu, buffer->cpumask)) | 2073 | if (!cpumask_test_cpu(cpu, buffer->cpumask)) |
| 2066 | return NULL; | 2074 | return NULL; |
| 2067 | 2075 | ||
| 2068 | iter = kmalloc(sizeof(*iter), GFP_KERNEL); | 2076 | iter = kmalloc(sizeof(*iter), GFP_KERNEL); |
| @@ -2172,7 +2180,7 @@ void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu) | |||
| 2172 | struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu]; | 2180 | struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu]; |
| 2173 | unsigned long flags; | 2181 | unsigned long flags; |
| 2174 | 2182 | ||
| 2175 | if (!cpu_isset(cpu, buffer->cpumask)) | 2183 | if (!cpumask_test_cpu(cpu, buffer->cpumask)) |
| 2176 | return; | 2184 | return; |
| 2177 | 2185 | ||
| 2178 | spin_lock_irqsave(&cpu_buffer->reader_lock, flags); | 2186 | spin_lock_irqsave(&cpu_buffer->reader_lock, flags); |
| @@ -2228,7 +2236,7 @@ int ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu) | |||
| 2228 | { | 2236 | { |
| 2229 | struct ring_buffer_per_cpu *cpu_buffer; | 2237 | struct ring_buffer_per_cpu *cpu_buffer; |
| 2230 | 2238 | ||
| 2231 | if (!cpu_isset(cpu, buffer->cpumask)) | 2239 | if (!cpumask_test_cpu(cpu, buffer->cpumask)) |
| 2232 | return 1; | 2240 | return 1; |
| 2233 | 2241 | ||
| 2234 | cpu_buffer = buffer->buffers[cpu]; | 2242 | cpu_buffer = buffer->buffers[cpu]; |
| @@ -2252,8 +2260,8 @@ int ring_buffer_swap_cpu(struct ring_buffer *buffer_a, | |||
| 2252 | struct ring_buffer_per_cpu *cpu_buffer_a; | 2260 | struct ring_buffer_per_cpu *cpu_buffer_a; |
| 2253 | struct ring_buffer_per_cpu *cpu_buffer_b; | 2261 | struct ring_buffer_per_cpu *cpu_buffer_b; |
| 2254 | 2262 | ||
| 2255 | if (!cpu_isset(cpu, buffer_a->cpumask) || | 2263 | if (!cpumask_test_cpu(cpu, buffer_a->cpumask) || |
| 2256 | !cpu_isset(cpu, buffer_b->cpumask)) | 2264 | !cpumask_test_cpu(cpu, buffer_b->cpumask)) |
| 2257 | return -EINVAL; | 2265 | return -EINVAL; |
| 2258 | 2266 | ||
| 2259 | /* At least make sure the two buffers are somewhat the same */ | 2267 | /* At least make sure the two buffers are somewhat the same */ |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0e91f43b6baf..c580233add95 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -89,10 +89,10 @@ static inline void ftrace_enable_cpu(void) | |||
| 89 | preempt_enable(); | 89 | preempt_enable(); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | static cpumask_t __read_mostly tracing_buffer_mask; | 92 | static cpumask_var_t __read_mostly tracing_buffer_mask; |
| 93 | 93 | ||
| 94 | #define for_each_tracing_cpu(cpu) \ | 94 | #define for_each_tracing_cpu(cpu) \ |
| 95 | for_each_cpu_mask(cpu, tracing_buffer_mask) | 95 | for_each_cpu(cpu, tracing_buffer_mask) |
| 96 | 96 | ||
| 97 | /* | 97 | /* |
| 98 | * ftrace_dump_on_oops - variable to dump ftrace buffer on oops | 98 | * ftrace_dump_on_oops - variable to dump ftrace buffer on oops |
| @@ -1811,10 +1811,10 @@ static void test_cpu_buff_start(struct trace_iterator *iter) | |||
| 1811 | if (!(iter->iter_flags & TRACE_FILE_ANNOTATE)) | 1811 | if (!(iter->iter_flags & TRACE_FILE_ANNOTATE)) |
| 1812 | return; | 1812 | return; |
| 1813 | 1813 | ||
| 1814 | if (cpu_isset(iter->cpu, iter->started)) | 1814 | if (cpumask_test_cpu(iter->cpu, iter->started)) |
| 1815 | return; | 1815 | return; |
| 1816 | 1816 | ||
| 1817 | cpu_set(iter->cpu, iter->started); | 1817 | cpumask_set_cpu(iter->cpu, iter->started); |
| 1818 | trace_seq_printf(s, "##### CPU %u buffer started ####\n", iter->cpu); | 1818 | trace_seq_printf(s, "##### CPU %u buffer started ####\n", iter->cpu); |
| 1819 | } | 1819 | } |
| 1820 | 1820 | ||
| @@ -2646,13 +2646,7 @@ static struct file_operations show_traces_fops = { | |||
| 2646 | /* | 2646 | /* |
| 2647 | * Only trace on a CPU if the bitmask is set: | 2647 | * Only trace on a CPU if the bitmask is set: |
| 2648 | */ | 2648 | */ |
| 2649 | static cpumask_t tracing_cpumask = CPU_MASK_ALL; | 2649 | static cpumask_var_t tracing_cpumask; |
| 2650 | |||
| 2651 | /* | ||
| 2652 | * When tracing/tracing_cpu_mask is modified then this holds | ||
| 2653 | * the new bitmask we are about to install: | ||
| 2654 | */ | ||
| 2655 | static cpumask_t tracing_cpumask_new; | ||
| 2656 | 2650 | ||
| 2657 | /* | 2651 | /* |
| 2658 | * The tracer itself will not take this lock, but still we want | 2652 | * The tracer itself will not take this lock, but still we want |
| @@ -2674,7 +2668,7 @@ tracing_cpumask_read(struct file *filp, char __user *ubuf, | |||
| 2674 | 2668 | ||
| 2675 | mutex_lock(&tracing_cpumask_update_lock); | 2669 | mutex_lock(&tracing_cpumask_update_lock); |
| 2676 | 2670 | ||
| 2677 | len = cpumask_scnprintf(mask_str, count, &tracing_cpumask); | 2671 | len = cpumask_scnprintf(mask_str, count, tracing_cpumask); |
| 2678 | if (count - len < 2) { | 2672 | if (count - len < 2) { |
| 2679 | count = -EINVAL; | 2673 | count = -EINVAL; |
| 2680 | goto out_err; | 2674 | goto out_err; |
| @@ -2693,9 +2687,13 @@ tracing_cpumask_write(struct file *filp, const char __user *ubuf, | |||
| 2693 | size_t count, loff_t *ppos) | 2687 | size_t count, loff_t *ppos) |
| 2694 | { | 2688 | { |
| 2695 | int err, cpu; | 2689 | int err, cpu; |
| 2690 | cpumask_var_t tracing_cpumask_new; | ||
| 2691 | |||
| 2692 | if (!alloc_cpumask_var(&tracing_cpumask_new, GFP_KERNEL)) | ||
| 2693 | return -ENOMEM; | ||
| 2696 | 2694 | ||
| 2697 | mutex_lock(&tracing_cpumask_update_lock); | 2695 | mutex_lock(&tracing_cpumask_update_lock); |
| 2698 | err = cpumask_parse_user(ubuf, count, &tracing_cpumask_new); | 2696 | err = cpumask_parse_user(ubuf, count, tracing_cpumask_new); |
| 2699 | if (err) | 2697 | if (err) |
| 2700 | goto err_unlock; | 2698 | goto err_unlock; |
| 2701 | 2699 | ||
| @@ -2706,26 +2704,28 @@ tracing_cpumask_write(struct file *filp, const char __user *ubuf, | |||
| 2706 | * Increase/decrease the disabled counter if we are | 2704 | * Increase/decrease the disabled counter if we are |
| 2707 | * about to flip a bit in the cpumask: | 2705 | * about to flip a bit in the cpumask: |
| 2708 | */ | 2706 | */ |
| 2709 | if (cpu_isset(cpu, tracing_cpumask) && | 2707 | if (cpumask_test_cpu(cpu, tracing_cpumask) && |
| 2710 | !cpu_isset(cpu, tracing_cpumask_new)) { | 2708 | !cpumask_test_cpu(cpu, tracing_cpumask_new)) { |
| 2711 | atomic_inc(&global_trace.data[cpu]->disabled); | 2709 | atomic_inc(&global_trace.data[cpu]->disabled); |
| 2712 | } | 2710 | } |
| 2713 | if (!cpu_isset(cpu, tracing_cpumask) && | 2711 | if (!cpumask_test_cpu(cpu, tracing_cpumask) && |
| 2714 | cpu_isset(cpu, tracing_cpumask_new)) { | 2712 | cpumask_test_cpu(cpu, tracing_cpumask_new)) { |
| 2715 | atomic_dec(&global_trace.data[cpu]->disabled); | 2713 | atomic_dec(&global_trace.data[cpu]->disabled); |
| 2716 | } | 2714 | } |
| 2717 | } | 2715 | } |
| 2718 | __raw_spin_unlock(&ftrace_max_lock); | 2716 | __raw_spin_unlock(&ftrace_max_lock); |
| 2719 | local_irq_enable(); | 2717 | local_irq_enable(); |
| 2720 | 2718 | ||
| 2721 | tracing_cpumask = tracing_cpumask_new; | 2719 | cpumask_copy(tracing_cpumask, tracing_cpumask_new); |
| 2722 | 2720 | ||
| 2723 | mutex_unlock(&tracing_cpumask_update_lock); | 2721 | mutex_unlock(&tracing_cpumask_update_lock); |
| 2722 | free_cpumask_var(tracing_cpumask_new); | ||
| 2724 | 2723 | ||
| 2725 | return count; | 2724 | return count; |
| 2726 | 2725 | ||
| 2727 | err_unlock: | 2726 | err_unlock: |
| 2728 | mutex_unlock(&tracing_cpumask_update_lock); | 2727 | mutex_unlock(&tracing_cpumask_update_lock); |
| 2728 | free_cpumask_var(tracing_cpumask); | ||
| 2729 | 2729 | ||
| 2730 | return err; | 2730 | return err; |
| 2731 | } | 2731 | } |
| @@ -3114,10 +3114,15 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) | |||
| 3114 | if (!iter) | 3114 | if (!iter) |
| 3115 | return -ENOMEM; | 3115 | return -ENOMEM; |
| 3116 | 3116 | ||
| 3117 | if (!alloc_cpumask_var(&iter->started, GFP_KERNEL)) { | ||
| 3118 | kfree(iter); | ||
| 3119 | return -ENOMEM; | ||
| 3120 | } | ||
| 3121 | |||
| 3117 | mutex_lock(&trace_types_lock); | 3122 | mutex_lock(&trace_types_lock); |
| 3118 | 3123 | ||
| 3119 | /* trace pipe does not show start of buffer */ | 3124 | /* trace pipe does not show start of buffer */ |
| 3120 | cpus_setall(iter->started); | 3125 | cpumask_setall(iter->started); |
| 3121 | 3126 | ||
| 3122 | iter->tr = &global_trace; | 3127 | iter->tr = &global_trace; |
| 3123 | iter->trace = current_trace; | 3128 | iter->trace = current_trace; |
| @@ -3134,6 +3139,7 @@ static int tracing_release_pipe(struct inode *inode, struct file *file) | |||
| 3134 | { | 3139 | { |
| 3135 | struct trace_iterator *iter = file->private_data; | 3140 | struct trace_iterator *iter = file->private_data; |
| 3136 | 3141 | ||
| 3142 | free_cpumask_var(iter->started); | ||
| 3137 | kfree(iter); | 3143 | kfree(iter); |
| 3138 | atomic_dec(&tracing_reader); | 3144 | atomic_dec(&tracing_reader); |
| 3139 | 3145 | ||
| @@ -3752,7 +3758,6 @@ void ftrace_dump(void) | |||
| 3752 | static DEFINE_SPINLOCK(ftrace_dump_lock); | 3758 | static DEFINE_SPINLOCK(ftrace_dump_lock); |
| 3753 | /* use static because iter can be a bit big for the stack */ | 3759 | /* use static because iter can be a bit big for the stack */ |
| 3754 | static struct trace_iterator iter; | 3760 | static struct trace_iterator iter; |
| 3755 | static cpumask_t mask; | ||
| 3756 | static int dump_ran; | 3761 | static int dump_ran; |
| 3757 | unsigned long flags; | 3762 | unsigned long flags; |
| 3758 | int cnt = 0, cpu; | 3763 | int cnt = 0, cpu; |
| @@ -3786,8 +3791,6 @@ void ftrace_dump(void) | |||
| 3786 | * and then release the locks again. | 3791 | * and then release the locks again. |
| 3787 | */ | 3792 | */ |
| 3788 | 3793 | ||
| 3789 | cpus_clear(mask); | ||
| 3790 | |||
| 3791 | while (!trace_empty(&iter)) { | 3794 | while (!trace_empty(&iter)) { |
| 3792 | 3795 | ||
| 3793 | if (!cnt) | 3796 | if (!cnt) |
| @@ -3823,19 +3826,28 @@ __init static int tracer_alloc_buffers(void) | |||
| 3823 | { | 3826 | { |
| 3824 | struct trace_array_cpu *data; | 3827 | struct trace_array_cpu *data; |
| 3825 | int i; | 3828 | int i; |
| 3829 | int ret = -ENOMEM; | ||
| 3826 | 3830 | ||
| 3827 | /* TODO: make the number of buffers hot pluggable with CPUS */ | 3831 | if (!alloc_cpumask_var(&tracing_buffer_mask, GFP_KERNEL)) |
| 3828 | tracing_buffer_mask = cpu_possible_map; | 3832 | goto out; |
| 3833 | |||
| 3834 | if (!alloc_cpumask_var(&tracing_cpumask, GFP_KERNEL)) | ||
| 3835 | goto out_free_buffer_mask; | ||
| 3836 | |||
| 3837 | cpumask_copy(tracing_buffer_mask, cpu_possible_mask); | ||
| 3838 | cpumask_copy(tracing_cpumask, cpu_all_mask); | ||
| 3829 | 3839 | ||
| 3840 | /* TODO: make the number of buffers hot pluggable with CPUS */ | ||
| 3830 | global_trace.buffer = ring_buffer_alloc(trace_buf_size, | 3841 | global_trace.buffer = ring_buffer_alloc(trace_buf_size, |
| 3831 | TRACE_BUFFER_FLAGS); | 3842 | TRACE_BUFFER_FLAGS); |
| 3832 | if (!global_trace.buffer) { | 3843 | if (!global_trace.buffer) { |
| 3833 | printk(KERN_ERR "tracer: failed to allocate ring buffer!\n"); | 3844 | printk(KERN_ERR "tracer: failed to allocate ring buffer!\n"); |
| 3834 | WARN_ON(1); | 3845 | WARN_ON(1); |
| 3835 | return 0; | 3846 | goto out_free_cpumask; |
| 3836 | } | 3847 | } |
| 3837 | global_trace.entries = ring_buffer_size(global_trace.buffer); | 3848 | global_trace.entries = ring_buffer_size(global_trace.buffer); |
| 3838 | 3849 | ||
| 3850 | |||
| 3839 | #ifdef CONFIG_TRACER_MAX_TRACE | 3851 | #ifdef CONFIG_TRACER_MAX_TRACE |
| 3840 | max_tr.buffer = ring_buffer_alloc(trace_buf_size, | 3852 | max_tr.buffer = ring_buffer_alloc(trace_buf_size, |
| 3841 | TRACE_BUFFER_FLAGS); | 3853 | TRACE_BUFFER_FLAGS); |
| @@ -3843,7 +3855,7 @@ __init static int tracer_alloc_buffers(void) | |||
| 3843 | printk(KERN_ERR "tracer: failed to allocate max ring buffer!\n"); | 3855 | printk(KERN_ERR "tracer: failed to allocate max ring buffer!\n"); |
| 3844 | WARN_ON(1); | 3856 | WARN_ON(1); |
| 3845 | ring_buffer_free(global_trace.buffer); | 3857 | ring_buffer_free(global_trace.buffer); |
| 3846 | return 0; | 3858 | goto out_free_cpumask; |
| 3847 | } | 3859 | } |
| 3848 | max_tr.entries = ring_buffer_size(max_tr.buffer); | 3860 | max_tr.entries = ring_buffer_size(max_tr.buffer); |
| 3849 | WARN_ON(max_tr.entries != global_trace.entries); | 3861 | WARN_ON(max_tr.entries != global_trace.entries); |
| @@ -3873,8 +3885,14 @@ __init static int tracer_alloc_buffers(void) | |||
| 3873 | &trace_panic_notifier); | 3885 | &trace_panic_notifier); |
| 3874 | 3886 | ||
| 3875 | register_die_notifier(&trace_die_notifier); | 3887 | register_die_notifier(&trace_die_notifier); |
| 3888 | ret = 0; | ||
| 3876 | 3889 | ||
| 3877 | return 0; | 3890 | out_free_cpumask: |
| 3891 | free_cpumask_var(tracing_cpumask); | ||
| 3892 | out_free_buffer_mask: | ||
| 3893 | free_cpumask_var(tracing_buffer_mask); | ||
| 3894 | out: | ||
| 3895 | return ret; | ||
| 3878 | } | 3896 | } |
| 3879 | early_initcall(tracer_alloc_buffers); | 3897 | early_initcall(tracer_alloc_buffers); |
| 3880 | fs_initcall(tracer_init_debugfs); | 3898 | fs_initcall(tracer_init_debugfs); |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index cc7a4f864036..4d3d381bfd95 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
| @@ -368,7 +368,7 @@ struct trace_iterator { | |||
| 368 | loff_t pos; | 368 | loff_t pos; |
| 369 | long idx; | 369 | long idx; |
| 370 | 370 | ||
| 371 | cpumask_t started; | 371 | cpumask_var_t started; |
| 372 | }; | 372 | }; |
| 373 | 373 | ||
| 374 | int tracing_is_enabled(void); | 374 | int tracing_is_enabled(void); |
diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c index 3ccebde28482..366c8c333e13 100644 --- a/kernel/trace/trace_boot.c +++ b/kernel/trace/trace_boot.c | |||
| @@ -42,7 +42,7 @@ static int boot_trace_init(struct trace_array *tr) | |||
| 42 | int cpu; | 42 | int cpu; |
| 43 | boot_trace = tr; | 43 | boot_trace = tr; |
| 44 | 44 | ||
| 45 | for_each_cpu_mask(cpu, cpu_possible_map) | 45 | for_each_cpu(cpu, cpu_possible_mask) |
| 46 | tracing_reset(tr, cpu); | 46 | tracing_reset(tr, cpu); |
| 47 | 47 | ||
| 48 | tracing_sched_switch_assign_trace(tr); | 48 | tracing_sched_switch_assign_trace(tr); |
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 4bf39fcae97a..930c08e5b38e 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c | |||
| @@ -79,7 +79,7 @@ print_graph_cpu(struct trace_seq *s, int cpu) | |||
| 79 | int i; | 79 | int i; |
| 80 | int ret; | 80 | int ret; |
| 81 | int log10_this = log10_cpu(cpu); | 81 | int log10_this = log10_cpu(cpu); |
| 82 | int log10_all = log10_cpu(cpus_weight_nr(cpu_online_map)); | 82 | int log10_all = log10_cpu(cpumask_weight(cpu_online_mask)); |
| 83 | 83 | ||
| 84 | 84 | ||
| 85 | /* | 85 | /* |
diff --git a/kernel/trace/trace_hw_branches.c b/kernel/trace/trace_hw_branches.c index b6a3e20a49a9..649df22d435f 100644 --- a/kernel/trace/trace_hw_branches.c +++ b/kernel/trace/trace_hw_branches.c | |||
| @@ -46,7 +46,7 @@ static void bts_trace_start(struct trace_array *tr) | |||
| 46 | 46 | ||
| 47 | tracing_reset_online_cpus(tr); | 47 | tracing_reset_online_cpus(tr); |
| 48 | 48 | ||
| 49 | for_each_cpu_mask(cpu, cpu_possible_map) | 49 | for_each_cpu(cpu, cpu_possible_mask) |
| 50 | smp_call_function_single(cpu, bts_trace_start_cpu, NULL, 1); | 50 | smp_call_function_single(cpu, bts_trace_start_cpu, NULL, 1); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| @@ -62,7 +62,7 @@ static void bts_trace_stop(struct trace_array *tr) | |||
| 62 | { | 62 | { |
| 63 | int cpu; | 63 | int cpu; |
| 64 | 64 | ||
| 65 | for_each_cpu_mask(cpu, cpu_possible_map) | 65 | for_each_cpu(cpu, cpu_possible_mask) |
| 66 | smp_call_function_single(cpu, bts_trace_stop_cpu, NULL, 1); | 66 | smp_call_function_single(cpu, bts_trace_stop_cpu, NULL, 1); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| @@ -172,7 +172,7 @@ static void trace_bts_prepare(struct trace_iterator *iter) | |||
| 172 | { | 172 | { |
| 173 | int cpu; | 173 | int cpu; |
| 174 | 174 | ||
| 175 | for_each_cpu_mask(cpu, cpu_possible_map) | 175 | for_each_cpu(cpu, cpu_possible_mask) |
| 176 | smp_call_function_single(cpu, trace_bts_cpu, iter->tr, 1); | 176 | smp_call_function_single(cpu, trace_bts_cpu, iter->tr, 1); |
| 177 | } | 177 | } |
| 178 | 178 | ||
diff --git a/kernel/trace/trace_power.c b/kernel/trace/trace_power.c index a7172a352f62..7bda248daf55 100644 --- a/kernel/trace/trace_power.c +++ b/kernel/trace/trace_power.c | |||
| @@ -39,7 +39,7 @@ static int power_trace_init(struct trace_array *tr) | |||
| 39 | 39 | ||
| 40 | trace_power_enabled = 1; | 40 | trace_power_enabled = 1; |
| 41 | 41 | ||
| 42 | for_each_cpu_mask(cpu, cpu_possible_map) | 42 | for_each_cpu(cpu, cpu_possible_mask) |
| 43 | tracing_reset(tr, cpu); | 43 | tracing_reset(tr, cpu); |
| 44 | return 0; | 44 | return 0; |
| 45 | } | 45 | } |
diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index a5779bd975db..eaca5ad803ff 100644 --- a/kernel/trace/trace_sysprof.c +++ b/kernel/trace/trace_sysprof.c | |||
| @@ -196,9 +196,9 @@ static enum hrtimer_restart stack_trace_timer_fn(struct hrtimer *hrtimer) | |||
| 196 | return HRTIMER_RESTART; | 196 | return HRTIMER_RESTART; |
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | static void start_stack_timer(int cpu) | 199 | static void start_stack_timer(void *unused) |
| 200 | { | 200 | { |
| 201 | struct hrtimer *hrtimer = &per_cpu(stack_trace_hrtimer, cpu); | 201 | struct hrtimer *hrtimer = &__get_cpu_var(stack_trace_hrtimer); |
| 202 | 202 | ||
| 203 | hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 203 | hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
| 204 | hrtimer->function = stack_trace_timer_fn; | 204 | hrtimer->function = stack_trace_timer_fn; |
| @@ -208,14 +208,7 @@ static void start_stack_timer(int cpu) | |||
| 208 | 208 | ||
| 209 | static void start_stack_timers(void) | 209 | static void start_stack_timers(void) |
| 210 | { | 210 | { |
| 211 | cpumask_t saved_mask = current->cpus_allowed; | 211 | on_each_cpu(start_stack_timer, NULL, 1); |
| 212 | int cpu; | ||
| 213 | |||
| 214 | for_each_online_cpu(cpu) { | ||
| 215 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); | ||
| 216 | start_stack_timer(cpu); | ||
| 217 | } | ||
| 218 | set_cpus_allowed_ptr(current, &saved_mask); | ||
| 219 | } | 212 | } |
| 220 | 213 | ||
| 221 | static void stop_stack_timer(int cpu) | 214 | static void stop_stack_timer(int cpu) |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 4952322cba45..2f445833ae37 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
| @@ -73,7 +73,7 @@ static DEFINE_SPINLOCK(workqueue_lock); | |||
| 73 | static LIST_HEAD(workqueues); | 73 | static LIST_HEAD(workqueues); |
| 74 | 74 | ||
| 75 | static int singlethread_cpu __read_mostly; | 75 | static int singlethread_cpu __read_mostly; |
| 76 | static cpumask_t cpu_singlethread_map __read_mostly; | 76 | static const struct cpumask *cpu_singlethread_map __read_mostly; |
| 77 | /* | 77 | /* |
| 78 | * _cpu_down() first removes CPU from cpu_online_map, then CPU_DEAD | 78 | * _cpu_down() first removes CPU from cpu_online_map, then CPU_DEAD |
| 79 | * flushes cwq->worklist. This means that flush_workqueue/wait_on_work | 79 | * flushes cwq->worklist. This means that flush_workqueue/wait_on_work |
| @@ -81,7 +81,7 @@ static cpumask_t cpu_singlethread_map __read_mostly; | |||
| 81 | * use cpu_possible_map, the cpumask below is more a documentation | 81 | * use cpu_possible_map, the cpumask below is more a documentation |
| 82 | * than optimization. | 82 | * than optimization. |
| 83 | */ | 83 | */ |
| 84 | static cpumask_t cpu_populated_map __read_mostly; | 84 | static cpumask_var_t cpu_populated_map __read_mostly; |
| 85 | 85 | ||
| 86 | /* If it's single threaded, it isn't in the list of workqueues. */ | 86 | /* If it's single threaded, it isn't in the list of workqueues. */ |
| 87 | static inline int is_wq_single_threaded(struct workqueue_struct *wq) | 87 | static inline int is_wq_single_threaded(struct workqueue_struct *wq) |
| @@ -89,10 +89,10 @@ static inline int is_wq_single_threaded(struct workqueue_struct *wq) | |||
| 89 | return wq->singlethread; | 89 | return wq->singlethread; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | static const cpumask_t *wq_cpu_map(struct workqueue_struct *wq) | 92 | static const struct cpumask *wq_cpu_map(struct workqueue_struct *wq) |
| 93 | { | 93 | { |
| 94 | return is_wq_single_threaded(wq) | 94 | return is_wq_single_threaded(wq) |
| 95 | ? &cpu_singlethread_map : &cpu_populated_map; | 95 | ? cpu_singlethread_map : cpu_populated_map; |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | static | 98 | static |
| @@ -410,7 +410,7 @@ static int flush_cpu_workqueue(struct cpu_workqueue_struct *cwq) | |||
| 410 | */ | 410 | */ |
| 411 | void flush_workqueue(struct workqueue_struct *wq) | 411 | void flush_workqueue(struct workqueue_struct *wq) |
| 412 | { | 412 | { |
| 413 | const cpumask_t *cpu_map = wq_cpu_map(wq); | 413 | const struct cpumask *cpu_map = wq_cpu_map(wq); |
| 414 | int cpu; | 414 | int cpu; |
| 415 | 415 | ||
| 416 | might_sleep(); | 416 | might_sleep(); |
| @@ -532,7 +532,7 @@ static void wait_on_work(struct work_struct *work) | |||
| 532 | { | 532 | { |
| 533 | struct cpu_workqueue_struct *cwq; | 533 | struct cpu_workqueue_struct *cwq; |
| 534 | struct workqueue_struct *wq; | 534 | struct workqueue_struct *wq; |
| 535 | const cpumask_t *cpu_map; | 535 | const struct cpumask *cpu_map; |
| 536 | int cpu; | 536 | int cpu; |
| 537 | 537 | ||
| 538 | might_sleep(); | 538 | might_sleep(); |
| @@ -903,7 +903,7 @@ static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq) | |||
| 903 | */ | 903 | */ |
| 904 | void destroy_workqueue(struct workqueue_struct *wq) | 904 | void destroy_workqueue(struct workqueue_struct *wq) |
| 905 | { | 905 | { |
| 906 | const cpumask_t *cpu_map = wq_cpu_map(wq); | 906 | const struct cpumask *cpu_map = wq_cpu_map(wq); |
| 907 | int cpu; | 907 | int cpu; |
| 908 | 908 | ||
| 909 | cpu_maps_update_begin(); | 909 | cpu_maps_update_begin(); |
| @@ -933,7 +933,7 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, | |||
| 933 | 933 | ||
| 934 | switch (action) { | 934 | switch (action) { |
| 935 | case CPU_UP_PREPARE: | 935 | case CPU_UP_PREPARE: |
| 936 | cpu_set(cpu, cpu_populated_map); | 936 | cpumask_set_cpu(cpu, cpu_populated_map); |
| 937 | } | 937 | } |
| 938 | undo: | 938 | undo: |
| 939 | list_for_each_entry(wq, &workqueues, list) { | 939 | list_for_each_entry(wq, &workqueues, list) { |
| @@ -964,7 +964,7 @@ undo: | |||
| 964 | switch (action) { | 964 | switch (action) { |
| 965 | case CPU_UP_CANCELED: | 965 | case CPU_UP_CANCELED: |
| 966 | case CPU_POST_DEAD: | 966 | case CPU_POST_DEAD: |
| 967 | cpu_clear(cpu, cpu_populated_map); | 967 | cpumask_clear_cpu(cpu, cpu_populated_map); |
| 968 | } | 968 | } |
| 969 | 969 | ||
| 970 | return ret; | 970 | return ret; |
| @@ -1017,9 +1017,11 @@ EXPORT_SYMBOL_GPL(work_on_cpu); | |||
| 1017 | 1017 | ||
| 1018 | void __init init_workqueues(void) | 1018 | void __init init_workqueues(void) |
| 1019 | { | 1019 | { |
| 1020 | cpu_populated_map = cpu_online_map; | 1020 | alloc_cpumask_var(&cpu_populated_map, GFP_KERNEL); |
| 1021 | singlethread_cpu = first_cpu(cpu_possible_map); | 1021 | |
| 1022 | cpu_singlethread_map = cpumask_of_cpu(singlethread_cpu); | 1022 | cpumask_copy(cpu_populated_map, cpu_online_mask); |
| 1023 | singlethread_cpu = cpumask_first(cpu_possible_mask); | ||
| 1024 | cpu_singlethread_map = cpumask_of(singlethread_cpu); | ||
| 1023 | hotcpu_notifier(workqueue_cpu_callback, 0); | 1025 | hotcpu_notifier(workqueue_cpu_callback, 0); |
| 1024 | keventd_wq = create_workqueue("events"); | 1026 | keventd_wq = create_workqueue("events"); |
| 1025 | BUG_ON(!keventd_wq); | 1027 | BUG_ON(!keventd_wq); |
diff --git a/lib/Kconfig b/lib/Kconfig index 2ba43c4a5b07..03c2c24b9083 100644 --- a/lib/Kconfig +++ b/lib/Kconfig | |||
| @@ -13,6 +13,10 @@ config GENERIC_FIND_FIRST_BIT | |||
| 13 | config GENERIC_FIND_NEXT_BIT | 13 | config GENERIC_FIND_NEXT_BIT |
| 14 | bool | 14 | bool |
| 15 | 15 | ||
| 16 | config GENERIC_FIND_LAST_BIT | ||
| 17 | bool | ||
| 18 | default y | ||
| 19 | |||
| 16 | config CRC_CCITT | 20 | config CRC_CCITT |
| 17 | tristate "CRC-CCITT functions" | 21 | tristate "CRC-CCITT functions" |
| 18 | help | 22 | help |
| @@ -166,4 +170,8 @@ config CPUMASK_OFFSTACK | |||
| 166 | them on the stack. This is a bit more expensive, but avoids | 170 | them on the stack. This is a bit more expensive, but avoids |
| 167 | stack overflow. | 171 | stack overflow. |
| 168 | 172 | ||
| 173 | config DISABLE_OBSOLETE_CPUMASK_FUNCTIONS | ||
| 174 | bool "Disable obsolete cpumask functions" if DEBUG_PER_CPU_MAPS | ||
| 175 | depends on EXPERIMENTAL && BROKEN | ||
| 176 | |||
| 169 | endmenu | 177 | endmenu |
diff --git a/lib/Makefile b/lib/Makefile index 80fe8a3ec12a..32b0e64ded27 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
| @@ -37,6 +37,7 @@ lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o | |||
| 37 | lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o | 37 | lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o |
| 38 | lib-$(CONFIG_GENERIC_FIND_FIRST_BIT) += find_next_bit.o | 38 | lib-$(CONFIG_GENERIC_FIND_FIRST_BIT) += find_next_bit.o |
| 39 | lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o | 39 | lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o |
| 40 | lib-$(CONFIG_GENERIC_FIND_LAST_BIT) += find_last_bit.o | ||
| 40 | obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o | 41 | obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o |
| 41 | obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o | 42 | obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o |
| 42 | obj-$(CONFIG_PLIST) += plist.o | 43 | obj-$(CONFIG_PLIST) += plist.o |
diff --git a/lib/cpumask.c b/lib/cpumask.c index 8d03f22c6ced..3389e2440da0 100644 --- a/lib/cpumask.c +++ b/lib/cpumask.c | |||
| @@ -76,15 +76,28 @@ int cpumask_any_but(const struct cpumask *mask, unsigned int cpu) | |||
| 76 | 76 | ||
| 77 | /* These are not inline because of header tangles. */ | 77 | /* These are not inline because of header tangles. */ |
| 78 | #ifdef CONFIG_CPUMASK_OFFSTACK | 78 | #ifdef CONFIG_CPUMASK_OFFSTACK |
| 79 | bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags) | 79 | /** |
| 80 | * alloc_cpumask_var_node - allocate a struct cpumask on a given node | ||
| 81 | * @mask: pointer to cpumask_var_t where the cpumask is returned | ||
| 82 | * @flags: GFP_ flags | ||
| 83 | * | ||
| 84 | * Only defined when CONFIG_CPUMASK_OFFSTACK=y, otherwise is | ||
| 85 | * a nop returning a constant 1 (in <linux/cpumask.h>) | ||
| 86 | * Returns TRUE if memory allocation succeeded, FALSE otherwise. | ||
| 87 | * | ||
| 88 | * In addition, mask will be NULL if this fails. Note that gcc is | ||
| 89 | * usually smart enough to know that mask can never be NULL if | ||
| 90 | * CONFIG_CPUMASK_OFFSTACK=n, so does code elimination in that case | ||
| 91 | * too. | ||
| 92 | */ | ||
| 93 | bool alloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, int node) | ||
| 80 | { | 94 | { |
| 81 | if (likely(slab_is_available())) | 95 | if (likely(slab_is_available())) |
| 82 | *mask = kmalloc(cpumask_size(), flags); | 96 | *mask = kmalloc_node(cpumask_size(), flags, node); |
| 83 | else { | 97 | else { |
| 84 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS | 98 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS |
| 85 | printk(KERN_ERR | 99 | printk(KERN_ERR |
| 86 | "=> alloc_cpumask_var: kmalloc not available!\n"); | 100 | "=> alloc_cpumask_var: kmalloc not available!\n"); |
| 87 | dump_stack(); | ||
| 88 | #endif | 101 | #endif |
| 89 | *mask = NULL; | 102 | *mask = NULL; |
| 90 | } | 103 | } |
| @@ -94,21 +107,64 @@ bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags) | |||
| 94 | dump_stack(); | 107 | dump_stack(); |
| 95 | } | 108 | } |
| 96 | #endif | 109 | #endif |
| 110 | /* FIXME: Bandaid to save us from old primitives which go to NR_CPUS. */ | ||
| 111 | if (*mask) { | ||
| 112 | unsigned int tail; | ||
| 113 | tail = BITS_TO_LONGS(NR_CPUS - nr_cpumask_bits) * sizeof(long); | ||
| 114 | memset(cpumask_bits(*mask) + cpumask_size() - tail, | ||
| 115 | 0, tail); | ||
| 116 | } | ||
| 117 | |||
| 97 | return *mask != NULL; | 118 | return *mask != NULL; |
| 98 | } | 119 | } |
| 120 | EXPORT_SYMBOL(alloc_cpumask_var_node); | ||
| 121 | |||
| 122 | /** | ||
| 123 | * alloc_cpumask_var - allocate a struct cpumask | ||
| 124 | * @mask: pointer to cpumask_var_t where the cpumask is returned | ||
| 125 | * @flags: GFP_ flags | ||
| 126 | * | ||
| 127 | * Only defined when CONFIG_CPUMASK_OFFSTACK=y, otherwise is | ||
| 128 | * a nop returning a constant 1 (in <linux/cpumask.h>). | ||
| 129 | * | ||
| 130 | * See alloc_cpumask_var_node. | ||
| 131 | */ | ||
| 132 | bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags) | ||
| 133 | { | ||
| 134 | return alloc_cpumask_var_node(mask, flags, numa_node_id()); | ||
| 135 | } | ||
| 99 | EXPORT_SYMBOL(alloc_cpumask_var); | 136 | EXPORT_SYMBOL(alloc_cpumask_var); |
| 100 | 137 | ||
| 138 | /** | ||
| 139 | * alloc_bootmem_cpumask_var - allocate a struct cpumask from the bootmem arena. | ||
| 140 | * @mask: pointer to cpumask_var_t where the cpumask is returned | ||
| 141 | * | ||
| 142 | * Only defined when CONFIG_CPUMASK_OFFSTACK=y, otherwise is | ||
| 143 | * a nop (in <linux/cpumask.h>). | ||
| 144 | * Either returns an allocated (zero-filled) cpumask, or causes the | ||
| 145 | * system to panic. | ||
| 146 | */ | ||
| 101 | void __init alloc_bootmem_cpumask_var(cpumask_var_t *mask) | 147 | void __init alloc_bootmem_cpumask_var(cpumask_var_t *mask) |
| 102 | { | 148 | { |
| 103 | *mask = alloc_bootmem(cpumask_size()); | 149 | *mask = alloc_bootmem(cpumask_size()); |
| 104 | } | 150 | } |
| 105 | 151 | ||
| 152 | /** | ||
| 153 | * free_cpumask_var - frees memory allocated for a struct cpumask. | ||
| 154 | * @mask: cpumask to free | ||
| 155 | * | ||
| 156 | * This is safe on a NULL mask. | ||
| 157 | */ | ||
| 106 | void free_cpumask_var(cpumask_var_t mask) | 158 | void free_cpumask_var(cpumask_var_t mask) |
| 107 | { | 159 | { |
| 108 | kfree(mask); | 160 | kfree(mask); |
| 109 | } | 161 | } |
| 110 | EXPORT_SYMBOL(free_cpumask_var); | 162 | EXPORT_SYMBOL(free_cpumask_var); |
| 111 | 163 | ||
| 164 | /** | ||
| 165 | * free_bootmem_cpumask_var - frees result of alloc_bootmem_cpumask_var | ||
| 166 | * @mask: cpumask to free | ||
| 167 | */ | ||
| 112 | void __init free_bootmem_cpumask_var(cpumask_var_t mask) | 168 | void __init free_bootmem_cpumask_var(cpumask_var_t mask) |
| 113 | { | 169 | { |
| 114 | free_bootmem((unsigned long)mask, cpumask_size()); | 170 | free_bootmem((unsigned long)mask, cpumask_size()); |
diff --git a/lib/find_last_bit.c b/lib/find_last_bit.c new file mode 100644 index 000000000000..5d202e36bdd8 --- /dev/null +++ b/lib/find_last_bit.c | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | /* find_last_bit.c: fallback find next bit implementation | ||
| 2 | * | ||
| 3 | * Copyright (C) 2008 IBM Corporation | ||
| 4 | * Written by Rusty Russell <rusty@rustcorp.com.au> | ||
| 5 | * (Inspired by David Howell's find_next_bit implementation) | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version | ||
| 10 | * 2 of the License, or (at your option) any later version. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/bitops.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <asm/types.h> | ||
| 16 | #include <asm/byteorder.h> | ||
| 17 | |||
| 18 | unsigned long find_last_bit(const unsigned long *addr, unsigned long size) | ||
| 19 | { | ||
| 20 | unsigned long words; | ||
| 21 | unsigned long tmp; | ||
| 22 | |||
| 23 | /* Start at final word. */ | ||
| 24 | words = size / BITS_PER_LONG; | ||
| 25 | |||
| 26 | /* Partial final word? */ | ||
| 27 | if (size & (BITS_PER_LONG-1)) { | ||
| 28 | tmp = (addr[words] & (~0UL >> (BITS_PER_LONG | ||
| 29 | - (size & (BITS_PER_LONG-1))))); | ||
| 30 | if (tmp) | ||
| 31 | goto found; | ||
| 32 | } | ||
| 33 | |||
| 34 | while (words) { | ||
| 35 | tmp = addr[--words]; | ||
| 36 | if (tmp) { | ||
| 37 | found: | ||
| 38 | return words * BITS_PER_LONG + __fls(tmp); | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | /* Not found */ | ||
| 43 | return size; | ||
| 44 | } | ||
| 45 | EXPORT_SYMBOL(find_last_bit); | ||
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 3b777025d876..98d632277ca8 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
| @@ -661,6 +661,9 @@ static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width, | |||
| 661 | */ | 661 | */ |
| 662 | static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field_width, int precision, int flags) | 662 | static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field_width, int precision, int flags) |
| 663 | { | 663 | { |
| 664 | if (!ptr) | ||
| 665 | return string(buf, end, "(null)", field_width, precision, flags); | ||
| 666 | |||
| 664 | switch (*fmt) { | 667 | switch (*fmt) { |
| 665 | case 'F': | 668 | case 'F': |
| 666 | ptr = dereference_function_descriptor(ptr); | 669 | ptr = dereference_function_descriptor(ptr); |
diff --git a/mm/pdflush.c b/mm/pdflush.c index a0a14c4d5072..15de509b68fd 100644 --- a/mm/pdflush.c +++ b/mm/pdflush.c | |||
| @@ -172,7 +172,16 @@ static int __pdflush(struct pdflush_work *my_work) | |||
| 172 | static int pdflush(void *dummy) | 172 | static int pdflush(void *dummy) |
| 173 | { | 173 | { |
| 174 | struct pdflush_work my_work; | 174 | struct pdflush_work my_work; |
| 175 | cpumask_t cpus_allowed; | 175 | cpumask_var_t cpus_allowed; |
| 176 | |||
| 177 | /* | ||
| 178 | * Since the caller doesn't even check kthread_run() worked, let's not | ||
| 179 | * freak out too much if this fails. | ||
| 180 | */ | ||
| 181 | if (!alloc_cpumask_var(&cpus_allowed, GFP_KERNEL)) { | ||
| 182 | printk(KERN_WARNING "pdflush failed to allocate cpumask\n"); | ||
| 183 | return 0; | ||
| 184 | } | ||
| 176 | 185 | ||
| 177 | /* | 186 | /* |
| 178 | * pdflush can spend a lot of time doing encryption via dm-crypt. We | 187 | * pdflush can spend a lot of time doing encryption via dm-crypt. We |
| @@ -187,8 +196,9 @@ static int pdflush(void *dummy) | |||
| 187 | * This is needed as pdflush's are dynamically created and destroyed. | 196 | * This is needed as pdflush's are dynamically created and destroyed. |
| 188 | * The boottime pdflush's are easily placed w/o these 2 lines. | 197 | * The boottime pdflush's are easily placed w/o these 2 lines. |
| 189 | */ | 198 | */ |
| 190 | cpuset_cpus_allowed(current, &cpus_allowed); | 199 | cpuset_cpus_allowed(current, cpus_allowed); |
| 191 | set_cpus_allowed_ptr(current, &cpus_allowed); | 200 | set_cpus_allowed_ptr(current, cpus_allowed); |
| 201 | free_cpumask_var(cpus_allowed); | ||
| 192 | 202 | ||
| 193 | return __pdflush(&my_work); | 203 | return __pdflush(&my_work); |
| 194 | } | 204 | } |
| @@ -2157,7 +2157,7 @@ kmem_cache_create (const char *name, size_t size, size_t align, | |||
| 2157 | 2157 | ||
| 2158 | /* | 2158 | /* |
| 2159 | * We use cache_chain_mutex to ensure a consistent view of | 2159 | * We use cache_chain_mutex to ensure a consistent view of |
| 2160 | * cpu_online_map as well. Please see cpuup_callback | 2160 | * cpu_online_mask as well. Please see cpuup_callback |
| 2161 | */ | 2161 | */ |
| 2162 | get_online_cpus(); | 2162 | get_online_cpus(); |
| 2163 | mutex_lock(&cache_chain_mutex); | 2163 | mutex_lock(&cache_chain_mutex); |
| @@ -1970,7 +1970,7 @@ static DEFINE_PER_CPU(struct kmem_cache_cpu, | |||
| 1970 | kmem_cache_cpu)[NR_KMEM_CACHE_CPU]; | 1970 | kmem_cache_cpu)[NR_KMEM_CACHE_CPU]; |
| 1971 | 1971 | ||
| 1972 | static DEFINE_PER_CPU(struct kmem_cache_cpu *, kmem_cache_cpu_free); | 1972 | static DEFINE_PER_CPU(struct kmem_cache_cpu *, kmem_cache_cpu_free); |
| 1973 | static cpumask_t kmem_cach_cpu_free_init_once = CPU_MASK_NONE; | 1973 | static DECLARE_BITMAP(kmem_cach_cpu_free_init_once, CONFIG_NR_CPUS); |
| 1974 | 1974 | ||
| 1975 | static struct kmem_cache_cpu *alloc_kmem_cache_cpu(struct kmem_cache *s, | 1975 | static struct kmem_cache_cpu *alloc_kmem_cache_cpu(struct kmem_cache *s, |
| 1976 | int cpu, gfp_t flags) | 1976 | int cpu, gfp_t flags) |
| @@ -2045,13 +2045,13 @@ static void init_alloc_cpu_cpu(int cpu) | |||
| 2045 | { | 2045 | { |
| 2046 | int i; | 2046 | int i; |
| 2047 | 2047 | ||
| 2048 | if (cpu_isset(cpu, kmem_cach_cpu_free_init_once)) | 2048 | if (cpumask_test_cpu(cpu, to_cpumask(kmem_cach_cpu_free_init_once))) |
| 2049 | return; | 2049 | return; |
| 2050 | 2050 | ||
| 2051 | for (i = NR_KMEM_CACHE_CPU - 1; i >= 0; i--) | 2051 | for (i = NR_KMEM_CACHE_CPU - 1; i >= 0; i--) |
| 2052 | free_kmem_cache_cpu(&per_cpu(kmem_cache_cpu, cpu)[i], cpu); | 2052 | free_kmem_cache_cpu(&per_cpu(kmem_cache_cpu, cpu)[i], cpu); |
| 2053 | 2053 | ||
| 2054 | cpu_set(cpu, kmem_cach_cpu_free_init_once); | 2054 | cpumask_set_cpu(cpu, to_cpumask(kmem_cach_cpu_free_init_once)); |
| 2055 | } | 2055 | } |
| 2056 | 2056 | ||
| 2057 | static void __init init_alloc_cpu(void) | 2057 | static void __init init_alloc_cpu(void) |
| @@ -3451,7 +3451,7 @@ struct location { | |||
| 3451 | long max_time; | 3451 | long max_time; |
| 3452 | long min_pid; | 3452 | long min_pid; |
| 3453 | long max_pid; | 3453 | long max_pid; |
| 3454 | cpumask_t cpus; | 3454 | DECLARE_BITMAP(cpus, NR_CPUS); |
| 3455 | nodemask_t nodes; | 3455 | nodemask_t nodes; |
| 3456 | }; | 3456 | }; |
| 3457 | 3457 | ||
| @@ -3526,7 +3526,8 @@ static int add_location(struct loc_track *t, struct kmem_cache *s, | |||
| 3526 | if (track->pid > l->max_pid) | 3526 | if (track->pid > l->max_pid) |
| 3527 | l->max_pid = track->pid; | 3527 | l->max_pid = track->pid; |
| 3528 | 3528 | ||
| 3529 | cpu_set(track->cpu, l->cpus); | 3529 | cpumask_set_cpu(track->cpu, |
| 3530 | to_cpumask(l->cpus)); | ||
| 3530 | } | 3531 | } |
| 3531 | node_set(page_to_nid(virt_to_page(track)), l->nodes); | 3532 | node_set(page_to_nid(virt_to_page(track)), l->nodes); |
| 3532 | return 1; | 3533 | return 1; |
| @@ -3556,8 +3557,8 @@ static int add_location(struct loc_track *t, struct kmem_cache *s, | |||
| 3556 | l->max_time = age; | 3557 | l->max_time = age; |
| 3557 | l->min_pid = track->pid; | 3558 | l->min_pid = track->pid; |
| 3558 | l->max_pid = track->pid; | 3559 | l->max_pid = track->pid; |
| 3559 | cpus_clear(l->cpus); | 3560 | cpumask_clear(to_cpumask(l->cpus)); |
| 3560 | cpu_set(track->cpu, l->cpus); | 3561 | cpumask_set_cpu(track->cpu, to_cpumask(l->cpus)); |
| 3561 | nodes_clear(l->nodes); | 3562 | nodes_clear(l->nodes); |
| 3562 | node_set(page_to_nid(virt_to_page(track)), l->nodes); | 3563 | node_set(page_to_nid(virt_to_page(track)), l->nodes); |
| 3563 | return 1; | 3564 | return 1; |
| @@ -3638,11 +3639,12 @@ static int list_locations(struct kmem_cache *s, char *buf, | |||
| 3638 | len += sprintf(buf + len, " pid=%ld", | 3639 | len += sprintf(buf + len, " pid=%ld", |
| 3639 | l->min_pid); | 3640 | l->min_pid); |
| 3640 | 3641 | ||
| 3641 | if (num_online_cpus() > 1 && !cpus_empty(l->cpus) && | 3642 | if (num_online_cpus() > 1 && |
| 3643 | !cpumask_empty(to_cpumask(l->cpus)) && | ||
| 3642 | len < PAGE_SIZE - 60) { | 3644 | len < PAGE_SIZE - 60) { |
| 3643 | len += sprintf(buf + len, " cpus="); | 3645 | len += sprintf(buf + len, " cpus="); |
| 3644 | len += cpulist_scnprintf(buf + len, PAGE_SIZE - len - 50, | 3646 | len += cpulist_scnprintf(buf + len, PAGE_SIZE - len - 50, |
| 3645 | &l->cpus); | 3647 | to_cpumask(l->cpus)); |
| 3646 | } | 3648 | } |
| 3647 | 3649 | ||
| 3648 | if (num_online_nodes() > 1 && !nodes_empty(l->nodes) && | 3650 | if (num_online_nodes() > 1 && !nodes_empty(l->nodes) && |
diff --git a/mm/vmscan.c b/mm/vmscan.c index 62e7f62fb559..d196f46c8808 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
| @@ -1902,7 +1902,7 @@ static int kswapd(void *p) | |||
| 1902 | }; | 1902 | }; |
| 1903 | node_to_cpumask_ptr(cpumask, pgdat->node_id); | 1903 | node_to_cpumask_ptr(cpumask, pgdat->node_id); |
| 1904 | 1904 | ||
| 1905 | if (!cpus_empty(*cpumask)) | 1905 | if (!cpumask_empty(cpumask)) |
| 1906 | set_cpus_allowed_ptr(tsk, cpumask); | 1906 | set_cpus_allowed_ptr(tsk, cpumask); |
| 1907 | current->reclaim_state = &reclaim_state; | 1907 | current->reclaim_state = &reclaim_state; |
| 1908 | 1908 | ||
| @@ -2141,7 +2141,7 @@ static int __devinit cpu_callback(struct notifier_block *nfb, | |||
| 2141 | pg_data_t *pgdat = NODE_DATA(nid); | 2141 | pg_data_t *pgdat = NODE_DATA(nid); |
| 2142 | node_to_cpumask_ptr(mask, pgdat->node_id); | 2142 | node_to_cpumask_ptr(mask, pgdat->node_id); |
| 2143 | 2143 | ||
| 2144 | if (any_online_cpu(*mask) < nr_cpu_ids) | 2144 | if (cpumask_any_and(cpu_online_mask, mask) < nr_cpu_ids) |
| 2145 | /* One of our CPUs online: restore mask */ | 2145 | /* One of our CPUs online: restore mask */ |
| 2146 | set_cpus_allowed_ptr(pgdat->kswapd, mask); | 2146 | set_cpus_allowed_ptr(pgdat->kswapd, mask); |
| 2147 | } | 2147 | } |
diff --git a/mm/vmstat.c b/mm/vmstat.c index c3ccfda23adc..91149746bb8d 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | DEFINE_PER_CPU(struct vm_event_state, vm_event_states) = {{0}}; | 20 | DEFINE_PER_CPU(struct vm_event_state, vm_event_states) = {{0}}; |
| 21 | EXPORT_PER_CPU_SYMBOL(vm_event_states); | 21 | EXPORT_PER_CPU_SYMBOL(vm_event_states); |
| 22 | 22 | ||
| 23 | static void sum_vm_events(unsigned long *ret, cpumask_t *cpumask) | 23 | static void sum_vm_events(unsigned long *ret, const struct cpumask *cpumask) |
| 24 | { | 24 | { |
| 25 | int cpu; | 25 | int cpu; |
| 26 | int i; | 26 | int i; |
| @@ -43,7 +43,7 @@ static void sum_vm_events(unsigned long *ret, cpumask_t *cpumask) | |||
| 43 | void all_vm_events(unsigned long *ret) | 43 | void all_vm_events(unsigned long *ret) |
| 44 | { | 44 | { |
| 45 | get_online_cpus(); | 45 | get_online_cpus(); |
| 46 | sum_vm_events(ret, &cpu_online_map); | 46 | sum_vm_events(ret, cpu_online_mask); |
| 47 | put_online_cpus(); | 47 | put_online_cpus(); |
| 48 | } | 48 | } |
| 49 | EXPORT_SYMBOL_GPL(all_vm_events); | 49 | EXPORT_SYMBOL_GPL(all_vm_events); |
diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl index 488a3b1f760f..db30fac3083e 100644 --- a/scripts/headers_check.pl +++ b/scripts/headers_check.pl | |||
| @@ -14,7 +14,9 @@ | |||
| 14 | # Only include files located in asm* and linux* are checked. | 14 | # Only include files located in asm* and linux* are checked. |
| 15 | # The rest are assumed to be system include files. | 15 | # The rest are assumed to be system include files. |
| 16 | # | 16 | # |
| 17 | # 2) TODO: check for leaked CONFIG_ symbols | 17 | # 2) It is checked that prototypes does not use "extern" |
| 18 | # | ||
| 19 | # 3) Check for leaked CONFIG_ symbols | ||
| 18 | 20 | ||
| 19 | use strict; | 21 | use strict; |
| 20 | 22 | ||
| @@ -32,7 +34,11 @@ foreach my $file (@files) { | |||
| 32 | $lineno = 0; | 34 | $lineno = 0; |
| 33 | while ($line = <FH>) { | 35 | while ($line = <FH>) { |
| 34 | $lineno++; | 36 | $lineno++; |
| 35 | check_include(); | 37 | &check_include(); |
| 38 | &check_asm_types(); | ||
| 39 | &check_sizetypes(); | ||
| 40 | &check_prototypes(); | ||
| 41 | &check_config(); | ||
| 36 | } | 42 | } |
| 37 | close FH; | 43 | close FH; |
| 38 | } | 44 | } |
| @@ -54,3 +60,63 @@ sub check_include | |||
| 54 | } | 60 | } |
| 55 | } | 61 | } |
| 56 | } | 62 | } |
| 63 | |||
| 64 | sub check_prototypes | ||
| 65 | { | ||
| 66 | if ($line =~ m/^\s*extern\b/) { | ||
| 67 | printf STDERR "$filename:$lineno: extern's make no sense in userspace\n"; | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | sub check_config | ||
| 72 | { | ||
| 73 | if ($line =~ m/[^a-zA-Z0-9_]+CONFIG_([a-zA-Z0-9]+)[^a-zA-Z0-9]/) { | ||
| 74 | printf STDERR "$filename:$lineno: leaks CONFIG_$1 to userspace where it is not valid\n"; | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | my $linux_asm_types; | ||
| 79 | sub check_asm_types() | ||
| 80 | { | ||
| 81 | if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) { | ||
| 82 | return; | ||
| 83 | } | ||
| 84 | if ($lineno == 1) { | ||
| 85 | $linux_asm_types = 0; | ||
| 86 | } elsif ($linux_asm_types >= 1) { | ||
| 87 | return; | ||
| 88 | } | ||
| 89 | if ($line =~ m/^\s*#\s*include\s+<asm\/types.h>/) { | ||
| 90 | $linux_asm_types = 1; | ||
| 91 | printf STDERR "$filename:$lineno: " . | ||
| 92 | "include of <linux/types.h> is preferred over <asm/types.h>\n" | ||
| 93 | # Warn until headers are all fixed | ||
| 94 | #$ret = 1; | ||
| 95 | } | ||
| 96 | } | ||
| 97 | |||
| 98 | my $linux_types; | ||
| 99 | sub check_sizetypes | ||
| 100 | { | ||
| 101 | if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) { | ||
| 102 | return; | ||
| 103 | } | ||
| 104 | if ($lineno == 1) { | ||
| 105 | $linux_types = 0; | ||
| 106 | } elsif ($linux_types >= 1) { | ||
| 107 | return; | ||
| 108 | } | ||
| 109 | if ($line =~ m/^\s*#\s*include\s+<linux\/types.h>/) { | ||
| 110 | $linux_types = 1; | ||
| 111 | return; | ||
| 112 | } | ||
| 113 | if ($line =~ m/__[us](8|16|32|64)\b/) { | ||
| 114 | printf STDERR "$filename:$lineno: " . | ||
| 115 | "found __[us]{8,16,32,64} type " . | ||
| 116 | "without #include <linux/types.h>\n"; | ||
| 117 | $linux_types = 2; | ||
| 118 | # Warn until headers are all fixed | ||
| 119 | #$ret = 1; | ||
| 120 | } | ||
| 121 | } | ||
| 122 | |||
diff --git a/scripts/headers_install.pl b/scripts/headers_install.pl index 7d2b4146e02f..c6ae4052ab43 100644 --- a/scripts/headers_install.pl +++ b/scripts/headers_install.pl | |||
| @@ -36,6 +36,9 @@ foreach my $file (@files) { | |||
| 36 | $line =~ s/\s__attribute_const__\s/ /g; | 36 | $line =~ s/\s__attribute_const__\s/ /g; |
| 37 | $line =~ s/\s__attribute_const__$//g; | 37 | $line =~ s/\s__attribute_const__$//g; |
| 38 | $line =~ s/^#include <linux\/compiler.h>//; | 38 | $line =~ s/^#include <linux\/compiler.h>//; |
| 39 | $line =~ s/(^|\s)(inline)\b/$1__$2__/g; | ||
| 40 | $line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g; | ||
| 41 | $line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g; | ||
| 39 | printf OUTFILE "%s", $line; | 42 | printf OUTFILE "%s", $line; |
| 40 | } | 43 | } |
| 41 | close OUTFILE; | 44 | close OUTFILE; |
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 9d4cba1c001d..6408fefae083 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h | |||
| @@ -65,9 +65,13 @@ enum symbol_type { | |||
| 65 | S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER | 65 | S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER |
| 66 | }; | 66 | }; |
| 67 | 67 | ||
| 68 | /* enum values are used as index to symbol.def[] */ | ||
| 68 | enum { | 69 | enum { |
| 69 | S_DEF_USER, /* main user value */ | 70 | S_DEF_USER, /* main user value */ |
| 70 | S_DEF_AUTO, | 71 | S_DEF_AUTO, /* values read from auto.conf */ |
| 72 | S_DEF_DEF3, /* Reserved for UI usage */ | ||
| 73 | S_DEF_DEF4, /* Reserved for UI usage */ | ||
| 74 | S_DEF_COUNT | ||
| 71 | }; | 75 | }; |
| 72 | 76 | ||
| 73 | struct symbol { | 77 | struct symbol { |
| @@ -75,7 +79,7 @@ struct symbol { | |||
| 75 | char *name; | 79 | char *name; |
| 76 | enum symbol_type type; | 80 | enum symbol_type type; |
| 77 | struct symbol_value curr; | 81 | struct symbol_value curr; |
| 78 | struct symbol_value def[4]; | 82 | struct symbol_value def[S_DEF_COUNT]; |
| 79 | tristate visible; | 83 | tristate visible; |
| 80 | int flags; | 84 | int flags; |
| 81 | struct property *prop; | 85 | struct property *prop; |
| @@ -84,42 +88,64 @@ struct symbol { | |||
| 84 | 88 | ||
| 85 | #define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) | 89 | #define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) |
| 86 | 90 | ||
| 87 | #define SYMBOL_CONST 0x0001 | 91 | #define SYMBOL_CONST 0x0001 /* symbol is const */ |
| 88 | #define SYMBOL_CHECK 0x0008 | 92 | #define SYMBOL_CHECK 0x0008 /* used during dependency checking */ |
| 89 | #define SYMBOL_CHOICE 0x0010 | 93 | #define SYMBOL_CHOICE 0x0010 /* start of a choice block (null name) */ |
| 90 | #define SYMBOL_CHOICEVAL 0x0020 | 94 | #define SYMBOL_CHOICEVAL 0x0020 /* used as a value in a choice block */ |
| 91 | #define SYMBOL_VALID 0x0080 | 95 | #define SYMBOL_VALID 0x0080 /* set when symbol.curr is calculated */ |
| 92 | #define SYMBOL_OPTIONAL 0x0100 | 96 | #define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */ |
| 93 | #define SYMBOL_WRITE 0x0200 | 97 | #define SYMBOL_WRITE 0x0200 /* ? */ |
| 94 | #define SYMBOL_CHANGED 0x0400 | 98 | #define SYMBOL_CHANGED 0x0400 /* ? */ |
| 95 | #define SYMBOL_AUTO 0x1000 | 99 | #define SYMBOL_AUTO 0x1000 /* value from environment variable */ |
| 96 | #define SYMBOL_CHECKED 0x2000 | 100 | #define SYMBOL_CHECKED 0x2000 /* used during dependency checking */ |
| 97 | #define SYMBOL_WARNED 0x8000 | 101 | #define SYMBOL_WARNED 0x8000 /* warning has been issued */ |
| 98 | #define SYMBOL_DEF 0x10000 | 102 | |
| 99 | #define SYMBOL_DEF_USER 0x10000 | 103 | /* Set when symbol.def[] is used */ |
| 100 | #define SYMBOL_DEF_AUTO 0x20000 | 104 | #define SYMBOL_DEF 0x10000 /* First bit of SYMBOL_DEF */ |
| 101 | #define SYMBOL_DEF3 0x40000 | 105 | #define SYMBOL_DEF_USER 0x10000 /* symbol.def[S_DEF_USER] is valid */ |
| 102 | #define SYMBOL_DEF4 0x80000 | 106 | #define SYMBOL_DEF_AUTO 0x20000 /* symbol.def[S_DEF_AUTO] is valid */ |
| 107 | #define SYMBOL_DEF3 0x40000 /* symbol.def[S_DEF_3] is valid */ | ||
| 108 | #define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */ | ||
| 103 | 109 | ||
| 104 | #define SYMBOL_MAXLENGTH 256 | 110 | #define SYMBOL_MAXLENGTH 256 |
| 105 | #define SYMBOL_HASHSIZE 257 | 111 | #define SYMBOL_HASHSIZE 257 |
| 106 | #define SYMBOL_HASHMASK 0xff | 112 | #define SYMBOL_HASHMASK 0xff |
| 107 | 113 | ||
| 114 | /* A property represent the config options that can be associated | ||
| 115 | * with a config "symbol". | ||
| 116 | * Sample: | ||
| 117 | * config FOO | ||
| 118 | * default y | ||
| 119 | * prompt "foo prompt" | ||
| 120 | * select BAR | ||
| 121 | * config BAZ | ||
| 122 | * int "BAZ Value" | ||
| 123 | * range 1..255 | ||
| 124 | */ | ||
| 108 | enum prop_type { | 125 | enum prop_type { |
| 109 | P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, | 126 | P_UNKNOWN, |
| 110 | P_SELECT, P_RANGE, P_ENV | 127 | P_PROMPT, /* prompt "foo prompt" or "BAZ Value" */ |
| 128 | P_COMMENT, /* text associated with a comment */ | ||
| 129 | P_MENU, /* prompt associated with a menuconfig option */ | ||
| 130 | P_DEFAULT, /* default y */ | ||
| 131 | P_CHOICE, /* choice value */ | ||
| 132 | P_SELECT, /* select BAR */ | ||
| 133 | P_RANGE, /* range 7..100 (for a symbol) */ | ||
| 134 | P_ENV, /* value from environment variable */ | ||
| 111 | }; | 135 | }; |
| 112 | 136 | ||
| 113 | struct property { | 137 | struct property { |
| 114 | struct property *next; | 138 | struct property *next; /* next property - null if last */ |
| 115 | struct symbol *sym; | 139 | struct symbol *sym; /* the symbol for which the property is associated */ |
| 116 | enum prop_type type; | 140 | enum prop_type type; /* type of property */ |
| 117 | const char *text; | 141 | const char *text; /* the prompt value - P_PROMPT, P_MENU, P_COMMENT */ |
| 118 | struct expr_value visible; | 142 | struct expr_value visible; |
| 119 | struct expr *expr; | 143 | struct expr *expr; /* the optional conditional part of the property */ |
| 120 | struct menu *menu; | 144 | struct menu *menu; /* the menu the property are associated with |
| 121 | struct file *file; | 145 | * valid for: P_SELECT, P_RANGE, P_CHOICE, |
| 122 | int lineno; | 146 | * P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */ |
| 147 | struct file *file; /* what file was this property defined */ | ||
| 148 | int lineno; /* what lineno was this property defined */ | ||
| 123 | }; | 149 | }; |
| 124 | 150 | ||
| 125 | #define for_all_properties(sym, st, tok) \ | 151 | #define for_all_properties(sym, st, tok) \ |
diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped index 7342ce0a7780..dc3e81807d13 100644 --- a/scripts/kconfig/lex.zconf.c_shipped +++ b/scripts/kconfig/lex.zconf.c_shipped | |||
| @@ -2370,11 +2370,14 @@ void zconf_nextfile(const char *name) | |||
| 2370 | current_buf = buf; | 2370 | current_buf = buf; |
| 2371 | 2371 | ||
| 2372 | if (file->flags & FILE_BUSY) { | 2372 | if (file->flags & FILE_BUSY) { |
| 2373 | printf("recursive scan (%s)?\n", name); | 2373 | printf("%s:%d: do not source '%s' from itself\n", |
| 2374 | zconf_curname(), zconf_lineno(), name); | ||
| 2374 | exit(1); | 2375 | exit(1); |
| 2375 | } | 2376 | } |
| 2376 | if (file->flags & FILE_SCANNED) { | 2377 | if (file->flags & FILE_SCANNED) { |
| 2377 | printf("file %s already scanned?\n", name); | 2378 | printf("%s:%d: file '%s' is already sourced from '%s'\n", |
| 2379 | zconf_curname(), zconf_lineno(), name, | ||
| 2380 | file->parent->name); | ||
| 2378 | exit(1); | 2381 | exit(1); |
| 2379 | } | 2382 | } |
| 2380 | file->flags |= FILE_BUSY; | 2383 | file->flags |= FILE_BUSY; |
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l index 5164ef7ce499..21ff69c9ad4e 100644 --- a/scripts/kconfig/zconf.l +++ b/scripts/kconfig/zconf.l | |||
| @@ -314,11 +314,14 @@ void zconf_nextfile(const char *name) | |||
| 314 | current_buf = buf; | 314 | current_buf = buf; |
| 315 | 315 | ||
| 316 | if (file->flags & FILE_BUSY) { | 316 | if (file->flags & FILE_BUSY) { |
| 317 | printf("recursive scan (%s)?\n", name); | 317 | printf("%s:%d: do not source '%s' from itself\n", |
| 318 | zconf_curname(), zconf_lineno(), name); | ||
| 318 | exit(1); | 319 | exit(1); |
| 319 | } | 320 | } |
| 320 | if (file->flags & FILE_SCANNED) { | 321 | if (file->flags & FILE_SCANNED) { |
| 321 | printf("file %s already scanned?\n", name); | 322 | printf("%s:%d: file '%s' is already sourced from '%s'\n", |
| 323 | zconf_curname(), zconf_lineno(), name, | ||
| 324 | file->parent->name); | ||
| 322 | exit(1); | 325 | exit(1); |
| 323 | } | 326 | } |
| 324 | file->flags |= FILE_BUSY; | 327 | file->flags |= FILE_BUSY; |
diff --git a/scripts/tags.sh b/scripts/tags.sh index 4e7547209852..9e3451d2c3a1 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh | |||
| @@ -84,7 +84,6 @@ docscope() | |||
| 84 | 84 | ||
| 85 | exuberant() | 85 | exuberant() |
| 86 | { | 86 | { |
| 87 | all_sources > all | ||
| 88 | all_sources | xargs $1 -a \ | 87 | all_sources | xargs $1 -a \ |
| 89 | -I __initdata,__exitdata,__acquires,__releases \ | 88 | -I __initdata,__exitdata,__acquires,__releases \ |
| 90 | -I __read_mostly,____cacheline_aligned \ | 89 | -I __read_mostly,____cacheline_aligned \ |
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index c86303638235..e5520996a75b 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
| @@ -1211,7 +1211,7 @@ static struct avc_cache_stats *sel_avc_get_stat_idx(loff_t *idx) | |||
| 1211 | { | 1211 | { |
| 1212 | int cpu; | 1212 | int cpu; |
| 1213 | 1213 | ||
| 1214 | for (cpu = *idx; cpu < NR_CPUS; ++cpu) { | 1214 | for (cpu = *idx; cpu < nr_cpu_ids; ++cpu) { |
| 1215 | if (!cpu_possible(cpu)) | 1215 | if (!cpu_possible(cpu)) |
| 1216 | continue; | 1216 | continue; |
| 1217 | *idx = cpu + 1; | 1217 | *idx = cpu + 1; |
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index 549b4eba1496..9d98a6658ac9 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c | |||
| @@ -84,7 +84,7 @@ static void snd_tea575x_set_freq(struct snd_tea575x *tea) | |||
| 84 | * Linux Video interface | 84 | * Linux Video interface |
| 85 | */ | 85 | */ |
| 86 | 86 | ||
| 87 | static int snd_tea575x_ioctl(struct inode *inode, struct file *file, | 87 | static long snd_tea575x_ioctl(struct file *file, |
| 88 | unsigned int cmd, unsigned long data) | 88 | unsigned int cmd, unsigned long data) |
| 89 | { | 89 | { |
| 90 | struct snd_tea575x *tea = video_drvdata(file); | 90 | struct snd_tea575x *tea = video_drvdata(file); |
| @@ -174,14 +174,14 @@ static void snd_tea575x_release(struct video_device *vfd) | |||
| 174 | { | 174 | { |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | static int snd_tea575x_exclusive_open(struct inode *inode, struct file *file) | 177 | static int snd_tea575x_exclusive_open(struct file *file) |
| 178 | { | 178 | { |
| 179 | struct snd_tea575x *tea = video_drvdata(file); | 179 | struct snd_tea575x *tea = video_drvdata(file); |
| 180 | 180 | ||
| 181 | return test_and_set_bit(0, &tea->in_use) ? -EBUSY : 0; | 181 | return test_and_set_bit(0, &tea->in_use) ? -EBUSY : 0; |
| 182 | } | 182 | } |
| 183 | 183 | ||
| 184 | static int snd_tea575x_exclusive_release(struct inode *inode, struct file *file) | 184 | static int snd_tea575x_exclusive_release(struct file *file) |
| 185 | { | 185 | { |
| 186 | struct snd_tea575x *tea = video_drvdata(file); | 186 | struct snd_tea575x *tea = video_drvdata(file); |
| 187 | 187 | ||
diff --git a/virt/kvm/vtd.c b/virt/kvm/iommu.c index a770874f3a3a..e9693a29d00e 100644 --- a/virt/kvm/vtd.c +++ b/virt/kvm/iommu.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/kvm_host.h> | 25 | #include <linux/kvm_host.h> |
| 26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
| 27 | #include <linux/dmar.h> | 27 | #include <linux/dmar.h> |
| 28 | #include <linux/iommu.h> | ||
| 28 | #include <linux/intel-iommu.h> | 29 | #include <linux/intel-iommu.h> |
| 29 | 30 | ||
| 30 | static int kvm_iommu_unmap_memslots(struct kvm *kvm); | 31 | static int kvm_iommu_unmap_memslots(struct kvm *kvm); |
| @@ -37,7 +38,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, | |||
| 37 | gfn_t gfn = base_gfn; | 38 | gfn_t gfn = base_gfn; |
| 38 | pfn_t pfn; | 39 | pfn_t pfn; |
| 39 | int i, r = 0; | 40 | int i, r = 0; |
| 40 | struct dmar_domain *domain = kvm->arch.intel_iommu_domain; | 41 | struct iommu_domain *domain = kvm->arch.iommu_domain; |
| 41 | 42 | ||
| 42 | /* check if iommu exists and in use */ | 43 | /* check if iommu exists and in use */ |
| 43 | if (!domain) | 44 | if (!domain) |
| @@ -45,20 +46,17 @@ int kvm_iommu_map_pages(struct kvm *kvm, | |||
| 45 | 46 | ||
| 46 | for (i = 0; i < npages; i++) { | 47 | for (i = 0; i < npages; i++) { |
| 47 | /* check if already mapped */ | 48 | /* check if already mapped */ |
| 48 | pfn = (pfn_t)intel_iommu_iova_to_pfn(domain, | 49 | if (iommu_iova_to_phys(domain, gfn_to_gpa(gfn))) |
| 49 | gfn_to_gpa(gfn)); | ||
| 50 | if (pfn) | ||
| 51 | continue; | 50 | continue; |
| 52 | 51 | ||
| 53 | pfn = gfn_to_pfn(kvm, gfn); | 52 | pfn = gfn_to_pfn(kvm, gfn); |
| 54 | r = intel_iommu_page_mapping(domain, | 53 | r = iommu_map_range(domain, |
| 55 | gfn_to_gpa(gfn), | 54 | gfn_to_gpa(gfn), |
| 56 | pfn_to_hpa(pfn), | 55 | pfn_to_hpa(pfn), |
| 57 | PAGE_SIZE, | 56 | PAGE_SIZE, |
| 58 | DMA_PTE_READ | | 57 | IOMMU_READ | IOMMU_WRITE); |
| 59 | DMA_PTE_WRITE); | ||
| 60 | if (r) { | 58 | if (r) { |
| 61 | printk(KERN_ERR "kvm_iommu_map_pages:" | 59 | printk(KERN_ERR "kvm_iommu_map_address:" |
| 62 | "iommu failed to map pfn=%lx\n", pfn); | 60 | "iommu failed to map pfn=%lx\n", pfn); |
| 63 | goto unmap_pages; | 61 | goto unmap_pages; |
| 64 | } | 62 | } |
| @@ -73,7 +71,7 @@ unmap_pages: | |||
| 73 | 71 | ||
| 74 | static int kvm_iommu_map_memslots(struct kvm *kvm) | 72 | static int kvm_iommu_map_memslots(struct kvm *kvm) |
| 75 | { | 73 | { |
| 76 | int i, r; | 74 | int i, r = 0; |
| 77 | 75 | ||
| 78 | down_read(&kvm->slots_lock); | 76 | down_read(&kvm->slots_lock); |
| 79 | for (i = 0; i < kvm->nmemslots; i++) { | 77 | for (i = 0; i < kvm->nmemslots; i++) { |
| @@ -86,50 +84,79 @@ static int kvm_iommu_map_memslots(struct kvm *kvm) | |||
| 86 | return r; | 84 | return r; |
| 87 | } | 85 | } |
| 88 | 86 | ||
| 89 | int kvm_iommu_map_guest(struct kvm *kvm, | 87 | int kvm_assign_device(struct kvm *kvm, |
| 90 | struct kvm_assigned_dev_kernel *assigned_dev) | 88 | struct kvm_assigned_dev_kernel *assigned_dev) |
| 91 | { | 89 | { |
| 92 | struct pci_dev *pdev = NULL; | 90 | struct pci_dev *pdev = NULL; |
| 91 | struct iommu_domain *domain = kvm->arch.iommu_domain; | ||
| 93 | int r; | 92 | int r; |
| 94 | 93 | ||
| 95 | if (!intel_iommu_found()) { | 94 | /* check if iommu exists and in use */ |
| 96 | printk(KERN_ERR "%s: intel iommu not found\n", __func__); | 95 | if (!domain) |
| 96 | return 0; | ||
| 97 | |||
| 98 | pdev = assigned_dev->dev; | ||
| 99 | if (pdev == NULL) | ||
| 97 | return -ENODEV; | 100 | return -ENODEV; |
| 101 | |||
| 102 | r = iommu_attach_device(domain, &pdev->dev); | ||
| 103 | if (r) { | ||
| 104 | printk(KERN_ERR "assign device %x:%x.%x failed", | ||
| 105 | pdev->bus->number, | ||
| 106 | PCI_SLOT(pdev->devfn), | ||
| 107 | PCI_FUNC(pdev->devfn)); | ||
| 108 | return r; | ||
| 98 | } | 109 | } |
| 99 | 110 | ||
| 100 | printk(KERN_DEBUG "VT-d direct map: host bdf = %x:%x:%x\n", | 111 | printk(KERN_DEBUG "assign device: host bdf = %x:%x:%x\n", |
| 101 | assigned_dev->host_busnr, | 112 | assigned_dev->host_busnr, |
| 102 | PCI_SLOT(assigned_dev->host_devfn), | 113 | PCI_SLOT(assigned_dev->host_devfn), |
| 103 | PCI_FUNC(assigned_dev->host_devfn)); | 114 | PCI_FUNC(assigned_dev->host_devfn)); |
| 115 | |||
| 116 | return 0; | ||
| 117 | } | ||
| 118 | |||
| 119 | int kvm_deassign_device(struct kvm *kvm, | ||
| 120 | struct kvm_assigned_dev_kernel *assigned_dev) | ||
| 121 | { | ||
| 122 | struct iommu_domain *domain = kvm->arch.iommu_domain; | ||
| 123 | struct pci_dev *pdev = NULL; | ||
| 124 | |||
| 125 | /* check if iommu exists and in use */ | ||
| 126 | if (!domain) | ||
| 127 | return 0; | ||
| 104 | 128 | ||
| 105 | pdev = assigned_dev->dev; | 129 | pdev = assigned_dev->dev; |
| 130 | if (pdev == NULL) | ||
| 131 | return -ENODEV; | ||
| 106 | 132 | ||
| 107 | if (pdev == NULL) { | 133 | iommu_detach_device(domain, &pdev->dev); |
| 108 | if (kvm->arch.intel_iommu_domain) { | 134 | |
| 109 | intel_iommu_domain_exit(kvm->arch.intel_iommu_domain); | 135 | printk(KERN_DEBUG "deassign device: host bdf = %x:%x:%x\n", |
| 110 | kvm->arch.intel_iommu_domain = NULL; | 136 | assigned_dev->host_busnr, |
| 111 | } | 137 | PCI_SLOT(assigned_dev->host_devfn), |
| 138 | PCI_FUNC(assigned_dev->host_devfn)); | ||
| 139 | |||
| 140 | return 0; | ||
| 141 | } | ||
| 142 | |||
| 143 | int kvm_iommu_map_guest(struct kvm *kvm) | ||
| 144 | { | ||
| 145 | int r; | ||
| 146 | |||
| 147 | if (!iommu_found()) { | ||
| 148 | printk(KERN_ERR "%s: iommu not found\n", __func__); | ||
| 112 | return -ENODEV; | 149 | return -ENODEV; |
| 113 | } | 150 | } |
| 114 | 151 | ||
| 115 | kvm->arch.intel_iommu_domain = intel_iommu_domain_alloc(pdev); | 152 | kvm->arch.iommu_domain = iommu_domain_alloc(); |
| 116 | if (!kvm->arch.intel_iommu_domain) | 153 | if (!kvm->arch.iommu_domain) |
| 117 | return -ENODEV; | 154 | return -ENOMEM; |
| 118 | 155 | ||
| 119 | r = kvm_iommu_map_memslots(kvm); | 156 | r = kvm_iommu_map_memslots(kvm); |
| 120 | if (r) | 157 | if (r) |
| 121 | goto out_unmap; | 158 | goto out_unmap; |
| 122 | 159 | ||
| 123 | intel_iommu_detach_dev(kvm->arch.intel_iommu_domain, | ||
| 124 | pdev->bus->number, pdev->devfn); | ||
| 125 | |||
| 126 | r = intel_iommu_context_mapping(kvm->arch.intel_iommu_domain, | ||
| 127 | pdev); | ||
| 128 | if (r) { | ||
| 129 | printk(KERN_ERR "Domain context map for %s failed", | ||
| 130 | pci_name(pdev)); | ||
| 131 | goto out_unmap; | ||
| 132 | } | ||
| 133 | return 0; | 160 | return 0; |
| 134 | 161 | ||
| 135 | out_unmap: | 162 | out_unmap: |
| @@ -138,19 +165,26 @@ out_unmap: | |||
| 138 | } | 165 | } |
| 139 | 166 | ||
| 140 | static void kvm_iommu_put_pages(struct kvm *kvm, | 167 | static void kvm_iommu_put_pages(struct kvm *kvm, |
| 141 | gfn_t base_gfn, unsigned long npages) | 168 | gfn_t base_gfn, unsigned long npages) |
| 142 | { | 169 | { |
| 143 | gfn_t gfn = base_gfn; | 170 | gfn_t gfn = base_gfn; |
| 144 | pfn_t pfn; | 171 | pfn_t pfn; |
| 145 | struct dmar_domain *domain = kvm->arch.intel_iommu_domain; | 172 | struct iommu_domain *domain = kvm->arch.iommu_domain; |
| 146 | int i; | 173 | unsigned long i; |
| 174 | u64 phys; | ||
| 175 | |||
| 176 | /* check if iommu exists and in use */ | ||
| 177 | if (!domain) | ||
| 178 | return; | ||
| 147 | 179 | ||
| 148 | for (i = 0; i < npages; i++) { | 180 | for (i = 0; i < npages; i++) { |
| 149 | pfn = (pfn_t)intel_iommu_iova_to_pfn(domain, | 181 | phys = iommu_iova_to_phys(domain, gfn_to_gpa(gfn)); |
| 150 | gfn_to_gpa(gfn)); | 182 | pfn = phys >> PAGE_SHIFT; |
| 151 | kvm_release_pfn_clean(pfn); | 183 | kvm_release_pfn_clean(pfn); |
| 152 | gfn++; | 184 | gfn++; |
| 153 | } | 185 | } |
| 186 | |||
| 187 | iommu_unmap_range(domain, gfn_to_gpa(base_gfn), PAGE_SIZE * npages); | ||
| 154 | } | 188 | } |
| 155 | 189 | ||
| 156 | static int kvm_iommu_unmap_memslots(struct kvm *kvm) | 190 | static int kvm_iommu_unmap_memslots(struct kvm *kvm) |
| @@ -168,24 +202,13 @@ static int kvm_iommu_unmap_memslots(struct kvm *kvm) | |||
| 168 | 202 | ||
| 169 | int kvm_iommu_unmap_guest(struct kvm *kvm) | 203 | int kvm_iommu_unmap_guest(struct kvm *kvm) |
| 170 | { | 204 | { |
| 171 | struct kvm_assigned_dev_kernel *entry; | 205 | struct iommu_domain *domain = kvm->arch.iommu_domain; |
| 172 | struct dmar_domain *domain = kvm->arch.intel_iommu_domain; | ||
| 173 | 206 | ||
| 174 | /* check if iommu exists and in use */ | 207 | /* check if iommu exists and in use */ |
| 175 | if (!domain) | 208 | if (!domain) |
| 176 | return 0; | 209 | return 0; |
| 177 | 210 | ||
| 178 | list_for_each_entry(entry, &kvm->arch.assigned_dev_head, list) { | ||
| 179 | printk(KERN_DEBUG "VT-d unmap: host bdf = %x:%x:%x\n", | ||
| 180 | entry->host_busnr, | ||
| 181 | PCI_SLOT(entry->host_devfn), | ||
| 182 | PCI_FUNC(entry->host_devfn)); | ||
| 183 | |||
| 184 | /* detach kvm dmar domain */ | ||
| 185 | intel_iommu_detach_dev(domain, entry->host_busnr, | ||
| 186 | entry->host_devfn); | ||
| 187 | } | ||
| 188 | kvm_iommu_unmap_memslots(kvm); | 211 | kvm_iommu_unmap_memslots(kvm); |
| 189 | intel_iommu_domain_exit(domain); | 212 | iommu_domain_free(domain); |
| 190 | return 0; | 213 | return 0; |
| 191 | } | 214 | } |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index fc6127cbea1f..3a5a08298aab 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
| @@ -496,6 +496,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, | |||
| 496 | match->assigned_dev_id = assigned_dev->assigned_dev_id; | 496 | match->assigned_dev_id = assigned_dev->assigned_dev_id; |
| 497 | match->host_busnr = assigned_dev->busnr; | 497 | match->host_busnr = assigned_dev->busnr; |
| 498 | match->host_devfn = assigned_dev->devfn; | 498 | match->host_devfn = assigned_dev->devfn; |
| 499 | match->flags = assigned_dev->flags; | ||
| 499 | match->dev = dev; | 500 | match->dev = dev; |
| 500 | match->irq_source_id = -1; | 501 | match->irq_source_id = -1; |
| 501 | match->kvm = kvm; | 502 | match->kvm = kvm; |
| @@ -503,7 +504,12 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, | |||
| 503 | list_add(&match->list, &kvm->arch.assigned_dev_head); | 504 | list_add(&match->list, &kvm->arch.assigned_dev_head); |
| 504 | 505 | ||
| 505 | if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) { | 506 | if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) { |
| 506 | r = kvm_iommu_map_guest(kvm, match); | 507 | if (!kvm->arch.iommu_domain) { |
| 508 | r = kvm_iommu_map_guest(kvm); | ||
| 509 | if (r) | ||
| 510 | goto out_list_del; | ||
| 511 | } | ||
| 512 | r = kvm_assign_device(kvm, match); | ||
| 507 | if (r) | 513 | if (r) |
| 508 | goto out_list_del; | 514 | goto out_list_del; |
| 509 | } | 515 | } |
| @@ -525,6 +531,35 @@ out_free: | |||
| 525 | } | 531 | } |
| 526 | #endif | 532 | #endif |
| 527 | 533 | ||
| 534 | #ifdef KVM_CAP_DEVICE_DEASSIGNMENT | ||
| 535 | static int kvm_vm_ioctl_deassign_device(struct kvm *kvm, | ||
| 536 | struct kvm_assigned_pci_dev *assigned_dev) | ||
| 537 | { | ||
| 538 | int r = 0; | ||
| 539 | struct kvm_assigned_dev_kernel *match; | ||
| 540 | |||
| 541 | mutex_lock(&kvm->lock); | ||
| 542 | |||
| 543 | match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head, | ||
| 544 | assigned_dev->assigned_dev_id); | ||
| 545 | if (!match) { | ||
| 546 | printk(KERN_INFO "%s: device hasn't been assigned before, " | ||
| 547 | "so cannot be deassigned\n", __func__); | ||
| 548 | r = -EINVAL; | ||
| 549 | goto out; | ||
| 550 | } | ||
| 551 | |||
| 552 | if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) | ||
| 553 | kvm_deassign_device(kvm, match); | ||
| 554 | |||
| 555 | kvm_free_assigned_device(kvm, match); | ||
| 556 | |||
| 557 | out: | ||
| 558 | mutex_unlock(&kvm->lock); | ||
| 559 | return r; | ||
| 560 | } | ||
| 561 | #endif | ||
| 562 | |||
| 528 | static inline int valid_vcpu(int n) | 563 | static inline int valid_vcpu(int n) |
| 529 | { | 564 | { |
| 530 | return likely(n >= 0 && n < KVM_MAX_VCPUS); | 565 | return likely(n >= 0 && n < KVM_MAX_VCPUS); |
| @@ -1858,6 +1893,19 @@ static long kvm_vm_ioctl(struct file *filp, | |||
| 1858 | break; | 1893 | break; |
| 1859 | } | 1894 | } |
| 1860 | #endif | 1895 | #endif |
| 1896 | #ifdef KVM_CAP_DEVICE_DEASSIGNMENT | ||
| 1897 | case KVM_DEASSIGN_PCI_DEVICE: { | ||
| 1898 | struct kvm_assigned_pci_dev assigned_dev; | ||
| 1899 | |||
| 1900 | r = -EFAULT; | ||
| 1901 | if (copy_from_user(&assigned_dev, argp, sizeof assigned_dev)) | ||
| 1902 | goto out; | ||
| 1903 | r = kvm_vm_ioctl_deassign_device(kvm, &assigned_dev); | ||
| 1904 | if (r) | ||
| 1905 | goto out; | ||
| 1906 | break; | ||
| 1907 | } | ||
| 1908 | #endif | ||
| 1861 | default: | 1909 | default: |
| 1862 | r = kvm_arch_vm_ioctl(filp, ioctl, arg); | 1910 | r = kvm_arch_vm_ioctl(filp, ioctl, arg); |
| 1863 | } | 1911 | } |
