diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-27 17:11:53 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-27 17:11:53 -0400 |
commit | eb703027ac4ed563823e4d7824f68afed637d89a (patch) | |
tree | de35552440e7d2c7b74d0020c6a3cc1a8ed8b060 | |
parent | 429e90893c9ad2c266d541c94d6ca69a34a7701d (diff) | |
parent | 837b41b5de356aa67abb2cadb5eef3efc7776f91 (diff) |
Merge ../linux-2.6
174 files changed, 5263 insertions, 1829 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 72aff61e7315..6f6d117ac7e2 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |||
@@ -1024,6 +1024,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
1024 | intel-mac-v3 Intel Mac Type 3 | 1024 | intel-mac-v3 Intel Mac Type 3 |
1025 | intel-mac-v4 Intel Mac Type 4 | 1025 | intel-mac-v4 Intel Mac Type 4 |
1026 | intel-mac-v5 Intel Mac Type 5 | 1026 | intel-mac-v5 Intel Mac Type 5 |
1027 | intel-mac-auto Intel Mac (detect type according to subsystem id) | ||
1027 | macmini Intel Mac Mini (equivalent with type 3) | 1028 | macmini Intel Mac Mini (equivalent with type 3) |
1028 | macbook Intel Mac Book (eq. type 5) | 1029 | macbook Intel Mac Book (eq. type 5) |
1029 | macbook-pro-v1 Intel Mac Book Pro 1st generation (eq. type 3) | 1030 | macbook-pro-v1 Intel Mac Book Pro 1st generation (eq. type 3) |
diff --git a/Documentation/sparse.txt b/Documentation/sparse.txt index 1a3bdc27d95e..42f43fa59f24 100644 --- a/Documentation/sparse.txt +++ b/Documentation/sparse.txt | |||
@@ -73,10 +73,10 @@ recompiled, or use "make C=2" to run sparse on the files whether they need to | |||
73 | be recompiled or not. The latter is a fast way to check the whole tree if you | 73 | be recompiled or not. The latter is a fast way to check the whole tree if you |
74 | have already built it. | 74 | have already built it. |
75 | 75 | ||
76 | The optional make variable CHECKFLAGS can be used to pass arguments to sparse. | 76 | The optional make variable CF can be used to pass arguments to sparse. The |
77 | The build system passes -Wbitwise to sparse automatically. To perform | 77 | build system passes -Wbitwise to sparse automatically. To perform endianness |
78 | endianness checks, you may define __CHECK_ENDIAN__: | 78 | checks, you may define __CHECK_ENDIAN__: |
79 | 79 | ||
80 | make C=2 CHECKFLAGS="-D__CHECK_ENDIAN__" | 80 | make C=2 CF="-D__CHECK_ENDIAN__" |
81 | 81 | ||
82 | These checks are disabled by default as they generate a host of warnings. | 82 | These checks are disabled by default as they generate a host of warnings. |
@@ -43,7 +43,7 @@ $(obj)/$(bounds-file): kernel/bounds.s Kbuild | |||
43 | # 2) Generate asm-offsets.h | 43 | # 2) Generate asm-offsets.h |
44 | # | 44 | # |
45 | 45 | ||
46 | offsets-file := include/asm-$(SRCARCH)/asm-offsets.h | 46 | offsets-file := include/asm/asm-offsets.h |
47 | 47 | ||
48 | always += $(offsets-file) | 48 | always += $(offsets-file) |
49 | targets += $(offsets-file) | 49 | targets += $(offsets-file) |
@@ -81,7 +81,6 @@ arch/$(SRCARCH)/kernel/asm-offsets.s: arch/$(SRCARCH)/kernel/asm-offsets.c \ | |||
81 | $(call if_changed_dep,cc_s_c) | 81 | $(call if_changed_dep,cc_s_c) |
82 | 82 | ||
83 | $(obj)/$(offsets-file): arch/$(SRCARCH)/kernel/asm-offsets.s Kbuild | 83 | $(obj)/$(offsets-file): arch/$(SRCARCH)/kernel/asm-offsets.s Kbuild |
84 | $(Q)mkdir -p $(dir $@) | ||
85 | $(call cmd,offsets) | 84 | $(call cmd,offsets) |
86 | 85 | ||
87 | ##### | 86 | ##### |
@@ -205,6 +205,9 @@ ifeq ($(ARCH),x86_64) | |||
205 | SRCARCH := x86 | 205 | SRCARCH := x86 |
206 | endif | 206 | endif |
207 | 207 | ||
208 | # Where to locate arch specific headers | ||
209 | hdr-arch := $(SRCARCH) | ||
210 | |||
208 | KCONFIG_CONFIG ?= .config | 211 | KCONFIG_CONFIG ?= .config |
209 | 212 | ||
210 | # SHELL used by kbuild | 213 | # SHELL used by kbuild |
@@ -326,7 +329,8 @@ AFLAGS_KERNEL = | |||
326 | # Needed to be compatible with the O= option | 329 | # Needed to be compatible with the O= option |
327 | LINUXINCLUDE := -Iinclude \ | 330 | LINUXINCLUDE := -Iinclude \ |
328 | $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \ | 331 | $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \ |
329 | -include include/linux/autoconf.h | 332 | -I$(srctree)/arch/$(hdr-arch)/include \ |
333 | -include include/linux/autoconf.h | ||
330 | 334 | ||
331 | KBUILD_CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE) | 335 | KBUILD_CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE) |
332 | 336 | ||
@@ -922,7 +926,9 @@ ifneq ($(KBUILD_SRC),) | |||
922 | /bin/false; \ | 926 | /bin/false; \ |
923 | fi; | 927 | fi; |
924 | $(Q)if [ ! -d include2 ]; then mkdir -p include2; fi; | 928 | $(Q)if [ ! -d include2 ]; then mkdir -p include2; fi; |
925 | $(Q)ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm | 929 | $(Q)if [ -e $(srctree)/include/asm-$(SRCARCH)/system.h ]; then \ |
930 | ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm; \ | ||
931 | fi | ||
926 | endif | 932 | endif |
927 | 933 | ||
928 | # prepare2 creates a makefile if using a separate output directory | 934 | # prepare2 creates a makefile if using a separate output directory |
@@ -948,22 +954,34 @@ export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH) | |||
948 | 954 | ||
949 | # The asm symlink changes when $(ARCH) changes. | 955 | # The asm symlink changes when $(ARCH) changes. |
950 | # Detect this and ask user to run make mrproper | 956 | # Detect this and ask user to run make mrproper |
951 | 957 | define check-symlink | |
952 | include/asm: FORCE | 958 | set -e; \ |
953 | $(Q)set -e; asmlink=`readlink include/asm | cut -d '-' -f 2`; \ | 959 | if [ -L include/asm ]; then \ |
954 | if [ -L include/asm ]; then \ | 960 | asmlink=`readlink include/asm | cut -d '-' -f 2`; \ |
955 | if [ "$$asmlink" != "$(SRCARCH)" ]; then \ | 961 | if [ "$$asmlink" != "$(SRCARCH)" ]; then \ |
956 | echo "ERROR: the symlink $@ points to asm-$$asmlink but asm-$(SRCARCH) was expected"; \ | 962 | echo "ERROR: the symlink $@ points to asm-$$asmlink but asm-$(SRCARCH) was expected"; \ |
957 | echo " set ARCH or save .config and run 'make mrproper' to fix it"; \ | 963 | echo " set ARCH or save .config and run 'make mrproper' to fix it"; \ |
958 | exit 1; \ | 964 | exit 1; \ |
959 | fi; \ | 965 | fi; \ |
960 | else \ | ||
961 | echo ' SYMLINK $@ -> include/asm-$(SRCARCH)'; \ | ||
962 | if [ ! -d include ]; then \ | ||
963 | mkdir -p include; \ | ||
964 | fi; \ | ||
965 | ln -fsn asm-$(SRCARCH) $@; \ | ||
966 | fi | 966 | fi |
967 | endef | ||
968 | |||
969 | # We create the target directory of the symlink if it does | ||
970 | # not exist so the test in chack-symlink works and we have a | ||
971 | # directory for generated filesas used by some architectures. | ||
972 | define create-symlink | ||
973 | if [ ! -L include/asm ]; then \ | ||
974 | echo ' SYMLINK $@ -> include/asm-$(SRCARCH)'; \ | ||
975 | if [ ! -d include/asm-$(SRCARCH) ]; then \ | ||
976 | mkdir -p include/asm-$(SRCARCH); \ | ||
977 | fi; \ | ||
978 | ln -fsn asm-$(SRCARCH) $@; \ | ||
979 | fi | ||
980 | endef | ||
981 | |||
982 | include/asm: FORCE | ||
983 | $(Q)$(check-symlink) | ||
984 | $(Q)$(create-symlink) | ||
967 | 985 | ||
968 | # Generate some files | 986 | # Generate some files |
969 | # --------------------------------------------------------------------------- | 987 | # --------------------------------------------------------------------------- |
@@ -1010,36 +1028,43 @@ firmware_install: FORCE | |||
1010 | 1028 | ||
1011 | # --------------------------------------------------------------------------- | 1029 | # --------------------------------------------------------------------------- |
1012 | # Kernel headers | 1030 | # Kernel headers |
1013 | INSTALL_HDR_PATH=$(objtree)/usr | ||
1014 | export INSTALL_HDR_PATH | ||
1015 | 1031 | ||
1016 | HDRFILTER=generic i386 x86_64 | 1032 | #Default location for installed headers |
1017 | HDRARCHES=$(filter-out $(HDRFILTER),$(patsubst $(srctree)/include/asm-%/Kbuild,%,$(wildcard $(srctree)/include/asm-*/Kbuild))) | 1033 | export INSTALL_HDR_PATH = $(objtree)/usr |
1018 | 1034 | ||
1019 | PHONY += headers_install_all | 1035 | hdr-inst := -rR -f $(srctree)/scripts/Makefile.headersinst obj |
1020 | headers_install_all: include/linux/version.h scripts_basic FORCE | 1036 | # Find out where the Kbuild file is located to support |
1037 | # arch/$(ARCH)/include/asm | ||
1038 | hdr-dir = $(strip \ | ||
1039 | $(if $(wildcard $(srctree)/arch/$(hdr-arch)/include/asm/Kbuild), \ | ||
1040 | arch/$(hdr-arch)/include/asm, include/asm-$(hdr-arch))) | ||
1041 | |||
1042 | # If we do an all arch process set dst to asm-$(hdr-arch) | ||
1043 | hdr-dst = $(if $(KBUILD_HEADERS), dst=include/asm-$(hdr-arch), dst=include/asm) | ||
1044 | |||
1045 | PHONY += __headers | ||
1046 | __headers: include/linux/version.h scripts_basic FORCE | ||
1021 | $(Q)$(MAKE) $(build)=scripts scripts/unifdef | 1047 | $(Q)$(MAKE) $(build)=scripts scripts/unifdef |
1022 | $(Q)for arch in $(HDRARCHES); do \ | 1048 | |
1023 | $(MAKE) ARCH=$$arch -f $(srctree)/scripts/Makefile.headersinst obj=include BIASMDIR=-bi-$$arch ;\ | 1049 | PHONY += headers_install_all |
1024 | done | 1050 | headers_install_all: |
1051 | $(Q)$(CONFIG_SHELL) $(srctree)/scripts/headers.sh install | ||
1025 | 1052 | ||
1026 | PHONY += headers_install | 1053 | PHONY += headers_install |
1027 | headers_install: include/linux/version.h scripts_basic FORCE | 1054 | headers_install: __headers |
1028 | @if [ ! -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \ | 1055 | $(if $(wildcard $(srctree)/$(hdr-dir)/Kbuild),, \ |
1029 | echo '*** Error: Headers not exportable for this architecture ($(SRCARCH))'; \ | 1056 | $(error Headers not exportable for the $(SRCARCH) architecture)) |
1030 | exit 1 ; fi | 1057 | $(Q)$(MAKE) $(hdr-inst)=include |
1031 | $(Q)$(MAKE) $(build)=scripts scripts/unifdef | 1058 | $(Q)$(MAKE) $(hdr-inst)=$(hdr-dir) $(hdr-dst) |
1032 | $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst ARCH=$(SRCARCH) obj=include | ||
1033 | 1059 | ||
1034 | PHONY += headers_check_all | 1060 | PHONY += headers_check_all |
1035 | headers_check_all: headers_install_all | 1061 | headers_check_all: headers_install_all |
1036 | $(Q)for arch in $(HDRARCHES); do \ | 1062 | $(Q)$(CONFIG_SHELL) $(srctree)/scripts/headers.sh check |
1037 | $(MAKE) ARCH=$$arch -f $(srctree)/scripts/Makefile.headersinst obj=include BIASMDIR=-bi-$$arch HDRCHECK=1 ;\ | ||
1038 | done | ||
1039 | 1063 | ||
1040 | PHONY += headers_check | 1064 | PHONY += headers_check |
1041 | headers_check: headers_install | 1065 | headers_check: headers_install |
1042 | $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst ARCH=$(SRCARCH) obj=include HDRCHECK=1 | 1066 | $(Q)$(MAKE) $(hdr-inst)=include HDRCHECK=1 |
1067 | $(Q)$(MAKE) $(hdr-inst)=$(hdr-dir) $(hdr-dst) HDRCHECK=1 | ||
1043 | 1068 | ||
1044 | # --------------------------------------------------------------------------- | 1069 | # --------------------------------------------------------------------------- |
1045 | # Modules | 1070 | # Modules |
@@ -1131,7 +1156,7 @@ MRPROPER_FILES += .config .config.old include/asm .version .old_version \ | |||
1131 | include/linux/autoconf.h include/linux/version.h \ | 1156 | include/linux/autoconf.h include/linux/version.h \ |
1132 | include/linux/utsrelease.h \ | 1157 | include/linux/utsrelease.h \ |
1133 | include/linux/bounds.h include/asm*/asm-offsets.h \ | 1158 | include/linux/bounds.h include/asm*/asm-offsets.h \ |
1134 | Module.symvers tags TAGS cscope* | 1159 | Module.symvers Module.markers tags TAGS cscope* |
1135 | 1160 | ||
1136 | # clean - Delete most, but leave enough to build external modules | 1161 | # clean - Delete most, but leave enough to build external modules |
1137 | # | 1162 | # |
@@ -1150,7 +1175,7 @@ clean: archclean $(clean-dirs) | |||
1150 | \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ | 1175 | \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ |
1151 | -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ | 1176 | -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ |
1152 | -o -name '*.symtypes' -o -name 'modules.order' \ | 1177 | -o -name '*.symtypes' -o -name 'modules.order' \ |
1153 | -o -name 'Module.markers' \) \ | 1178 | -o -name 'Module.markers' -o -name '.tmp_*.o.*' \) \ |
1154 | -type f -print | xargs rm -f | 1179 | -type f -print | xargs rm -f |
1155 | 1180 | ||
1156 | # mrproper - Delete all generated files, including .config | 1181 | # mrproper - Delete all generated files, including .config |
@@ -1224,21 +1249,17 @@ help: | |||
1224 | @echo ' cscope - Generate cscope index' | 1249 | @echo ' cscope - Generate cscope index' |
1225 | @echo ' kernelrelease - Output the release version string' | 1250 | @echo ' kernelrelease - Output the release version string' |
1226 | @echo ' kernelversion - Output the version stored in Makefile' | 1251 | @echo ' kernelversion - Output the version stored in Makefile' |
1227 | @if [ -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \ | 1252 | @echo ' headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'; \ |
1228 | echo ' headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'; \ | ||
1229 | echo ' (default: $(INSTALL_HDR_PATH))'; \ | 1253 | echo ' (default: $(INSTALL_HDR_PATH))'; \ |
1230 | fi | 1254 | echo '' |
1231 | @echo '' | ||
1232 | @echo 'Static analysers' | 1255 | @echo 'Static analysers' |
1233 | @echo ' checkstack - Generate a list of stack hogs' | 1256 | @echo ' checkstack - Generate a list of stack hogs' |
1234 | @echo ' namespacecheck - Name space analysis on compiled kernel' | 1257 | @echo ' namespacecheck - Name space analysis on compiled kernel' |
1235 | @echo ' versioncheck - Sanity check on version.h usage' | 1258 | @echo ' versioncheck - Sanity check on version.h usage' |
1236 | @echo ' includecheck - Check for duplicate included header files' | 1259 | @echo ' includecheck - Check for duplicate included header files' |
1237 | @echo ' export_report - List the usages of all exported symbols' | 1260 | @echo ' export_report - List the usages of all exported symbols' |
1238 | @if [ -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \ | 1261 | @echo ' headers_check - Sanity check on exported headers'; \ |
1239 | echo ' headers_check - Sanity check on exported headers'; \ | 1262 | echo '' |
1240 | fi | ||
1241 | @echo '' | ||
1242 | @echo 'Kernel packaging:' | 1263 | @echo 'Kernel packaging:' |
1243 | @$(MAKE) $(build)=$(package-dir) help | 1264 | @$(MAKE) $(build)=$(package-dir) help |
1244 | @echo '' | 1265 | @echo '' |
@@ -1411,7 +1432,11 @@ define find-sources | |||
1411 | \( -name config -o -name 'asm-*' \) -prune \ | 1432 | \( -name config -o -name 'asm-*' \) -prune \ |
1412 | -o -name $1 -print; \ | 1433 | -o -name $1 -print; \ |
1413 | for arch in $(ALLINCLUDE_ARCHS) ; do \ | 1434 | for arch in $(ALLINCLUDE_ARCHS) ; do \ |
1414 | find $(__srctree)include/asm-$${arch} $(RCS_FIND_IGNORE) \ | 1435 | test -e $(__srctree)include/asm-$${arch} && \ |
1436 | find $(__srctree)include/asm-$${arch} $(RCS_FIND_IGNORE) \ | ||
1437 | -name $1 -print; \ | ||
1438 | test -e $(__srctree)arch/$${arch}/include/asm && \ | ||
1439 | find $(__srctree)arch/$${arch}/include/asm $(RCS_FIND_IGNORE) \ | ||
1415 | -name $1 -print; \ | 1440 | -name $1 -print; \ |
1416 | done ; \ | 1441 | done ; \ |
1417 | find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \ | 1442 | find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \ |
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c index 14dc5a143695..8538ba75ef92 100644 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ b/arch/avr32/boards/atstk1000/atstk1002.c | |||
@@ -21,6 +21,8 @@ | |||
21 | 21 | ||
22 | #include <asm/io.h> | 22 | #include <asm/io.h> |
23 | #include <asm/setup.h> | 23 | #include <asm/setup.h> |
24 | #include <asm/atmel-mci.h> | ||
25 | |||
24 | #include <asm/arch/at32ap700x.h> | 26 | #include <asm/arch/at32ap700x.h> |
25 | #include <asm/arch/board.h> | 27 | #include <asm/arch/board.h> |
26 | #include <asm/arch/init.h> | 28 | #include <asm/arch/init.h> |
@@ -260,6 +262,21 @@ void __init setup_board(void) | |||
260 | at32_setup_serial_console(0); | 262 | at32_setup_serial_console(0); |
261 | } | 263 | } |
262 | 264 | ||
265 | #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM | ||
266 | |||
267 | /* MMC card detect requires MACB0 *NOT* be used */ | ||
268 | #ifdef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM | ||
269 | static struct mci_platform_data __initdata mci0_data = { | ||
270 | .detect_pin = GPIO_PIN_PC(14), /* gpio30/sdcd */ | ||
271 | .wp_pin = GPIO_PIN_PC(15), /* gpio31/sdwp */ | ||
272 | }; | ||
273 | #define MCI_PDATA &mci0_data | ||
274 | #else | ||
275 | #define MCI_PDATA NULL | ||
276 | #endif /* SW6 for sd{cd,wp} routing */ | ||
277 | |||
278 | #endif /* SW2 for MMC signal routing */ | ||
279 | |||
263 | static int __init atstk1002_init(void) | 280 | static int __init atstk1002_init(void) |
264 | { | 281 | { |
265 | /* | 282 | /* |
@@ -309,7 +326,7 @@ static int __init atstk1002_init(void) | |||
309 | at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); | 326 | at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); |
310 | #endif | 327 | #endif |
311 | #ifndef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM | 328 | #ifndef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM |
312 | at32_add_device_mci(0, NULL); | 329 | at32_add_device_mci(0, MCI_PDATA); |
313 | #endif | 330 | #endif |
314 | #ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM | 331 | #ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM |
315 | set_hw_addr(at32_add_device_eth(1, ð_data[1])); | 332 | set_hw_addr(at32_add_device_eth(1, ð_data[1])); |
diff --git a/arch/avr32/boards/atstk1000/atstk1003.c b/arch/avr32/boards/atstk1000/atstk1003.c index ea109f435a83..591fc73b554a 100644 --- a/arch/avr32/boards/atstk1000/atstk1003.c +++ b/arch/avr32/boards/atstk1000/atstk1003.c | |||
@@ -154,7 +154,7 @@ static int __init atstk1003_init(void) | |||
154 | at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); | 154 | at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); |
155 | #endif | 155 | #endif |
156 | #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM | 156 | #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM |
157 | at32_add_device_mci(0); | 157 | at32_add_device_mci(0, NULL); |
158 | #endif | 158 | #endif |
159 | at32_add_device_usba(0, NULL); | 159 | at32_add_device_usba(0, NULL); |
160 | #ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM | 160 | #ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM |
diff --git a/arch/avr32/boards/atstk1000/atstk1004.c b/arch/avr32/boards/atstk1000/atstk1004.c index c7236df74d74..d9c5e0a21256 100644 --- a/arch/avr32/boards/atstk1000/atstk1004.c +++ b/arch/avr32/boards/atstk1000/atstk1004.c | |||
@@ -137,7 +137,7 @@ static int __init atstk1004_init(void) | |||
137 | at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); | 137 | at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); |
138 | #endif | 138 | #endif |
139 | #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM | 139 | #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM |
140 | at32_add_device_mci(0); | 140 | at32_add_device_mci(0, NULL); |
141 | #endif | 141 | #endif |
142 | at32_add_device_lcdc(0, &atstk1000_lcdc_data, | 142 | at32_add_device_lcdc(0, &atstk1000_lcdc_data, |
143 | fbmem_start, fbmem_size, 0); | 143 | fbmem_start, fbmem_size, 0); |
diff --git a/arch/avr32/kernel/time.c b/arch/avr32/kernel/time.c index abd954fb7ba0..7e7f32771ae1 100644 --- a/arch/avr32/kernel/time.c +++ b/arch/avr32/kernel/time.c | |||
@@ -43,6 +43,9 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) | |||
43 | { | 43 | { |
44 | struct clock_event_device *evdev = dev_id; | 44 | struct clock_event_device *evdev = dev_id; |
45 | 45 | ||
46 | if (unlikely(!(intc_get_pending(0) & 1))) | ||
47 | return IRQ_NONE; | ||
48 | |||
46 | /* | 49 | /* |
47 | * Disable the interrupt until the clockevent subsystem | 50 | * Disable the interrupt until the clockevent subsystem |
48 | * reprograms it. | 51 | * reprograms it. |
@@ -55,7 +58,8 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) | |||
55 | 58 | ||
56 | static struct irqaction timer_irqaction = { | 59 | static struct irqaction timer_irqaction = { |
57 | .handler = timer_interrupt, | 60 | .handler = timer_interrupt, |
58 | .flags = IRQF_TIMER | IRQF_DISABLED, | 61 | /* Oprofile uses the same irq as the timer, so allow it to be shared */ |
62 | .flags = IRQF_TIMER | IRQF_DISABLED | IRQF_SHARED, | ||
59 | .name = "avr32_comparator", | 63 | .name = "avr32_comparator", |
60 | }; | 64 | }; |
61 | 65 | ||
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index 351e1b42f937..1617048c86c5 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/dma-mapping.h> | 14 | #include <linux/dma-mapping.h> |
15 | #include <linux/gpio.h> | ||
15 | #include <linux/spi/spi.h> | 16 | #include <linux/spi/spi.h> |
16 | #include <linux/usb/atmel_usba_udc.h> | 17 | #include <linux/usb/atmel_usba_udc.h> |
17 | 18 | ||
@@ -1285,7 +1286,6 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data) | |||
1285 | { | 1286 | { |
1286 | struct mci_platform_data _data; | 1287 | struct mci_platform_data _data; |
1287 | struct platform_device *pdev; | 1288 | struct platform_device *pdev; |
1288 | struct dw_dma_slave *dws; | ||
1289 | 1289 | ||
1290 | if (id != 0) | 1290 | if (id != 0) |
1291 | return NULL; | 1291 | return NULL; |
@@ -1300,7 +1300,9 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data) | |||
1300 | 1300 | ||
1301 | if (!data) { | 1301 | if (!data) { |
1302 | data = &_data; | 1302 | data = &_data; |
1303 | memset(data, 0, sizeof(struct mci_platform_data)); | 1303 | memset(data, -1, sizeof(struct mci_platform_data)); |
1304 | data->detect_pin = GPIO_PIN_NONE; | ||
1305 | data->wp_pin = GPIO_PIN_NONE; | ||
1304 | } | 1306 | } |
1305 | 1307 | ||
1306 | if (platform_device_add_data(pdev, data, | 1308 | if (platform_device_add_data(pdev, data, |
@@ -1314,12 +1316,10 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data) | |||
1314 | select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */ | 1316 | select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */ |
1315 | select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */ | 1317 | select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */ |
1316 | 1318 | ||
1317 | if (data) { | 1319 | if (gpio_is_valid(data->detect_pin)) |
1318 | if (data->detect_pin != GPIO_PIN_NONE) | 1320 | at32_select_gpio(data->detect_pin, 0); |
1319 | at32_select_gpio(data->detect_pin, 0); | 1321 | if (gpio_is_valid(data->wp_pin)) |
1320 | if (data->wp_pin != GPIO_PIN_NONE) | 1322 | at32_select_gpio(data->wp_pin, 0); |
1321 | at32_select_gpio(data->wp_pin, 0); | ||
1322 | } | ||
1323 | 1323 | ||
1324 | atmel_mci0_pclk.dev = &pdev->dev; | 1324 | atmel_mci0_pclk.dev = &pdev->dev; |
1325 | 1325 | ||
@@ -1853,11 +1853,11 @@ at32_add_device_cf(unsigned int id, unsigned int extint, | |||
1853 | if (at32_init_ide_or_cf(pdev, data->cs, extint)) | 1853 | if (at32_init_ide_or_cf(pdev, data->cs, extint)) |
1854 | goto fail; | 1854 | goto fail; |
1855 | 1855 | ||
1856 | if (data->detect_pin != GPIO_PIN_NONE) | 1856 | if (gpio_is_valid(data->detect_pin)) |
1857 | at32_select_gpio(data->detect_pin, AT32_GPIOF_DEGLITCH); | 1857 | at32_select_gpio(data->detect_pin, AT32_GPIOF_DEGLITCH); |
1858 | if (data->reset_pin != GPIO_PIN_NONE) | 1858 | if (gpio_is_valid(data->reset_pin)) |
1859 | at32_select_gpio(data->reset_pin, 0); | 1859 | at32_select_gpio(data->reset_pin, 0); |
1860 | if (data->vcc_pin != GPIO_PIN_NONE) | 1860 | if (gpio_is_valid(data->vcc_pin)) |
1861 | at32_select_gpio(data->vcc_pin, 0); | 1861 | at32_select_gpio(data->vcc_pin, 0); |
1862 | /* READY is used as extint, so we can't select it as gpio */ | 1862 | /* READY is used as extint, so we can't select it as gpio */ |
1863 | 1863 | ||
@@ -1937,9 +1937,11 @@ static struct clk atmel_ac97c0_pclk = { | |||
1937 | .index = 10, | 1937 | .index = 10, |
1938 | }; | 1938 | }; |
1939 | 1939 | ||
1940 | struct platform_device *__init at32_add_device_ac97c(unsigned int id) | 1940 | struct platform_device *__init |
1941 | at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data) | ||
1941 | { | 1942 | { |
1942 | struct platform_device *pdev; | 1943 | struct platform_device *pdev; |
1944 | struct ac97c_platform_data _data; | ||
1943 | 1945 | ||
1944 | if (id != 0) | 1946 | if (id != 0) |
1945 | return NULL; | 1947 | return NULL; |
@@ -1950,19 +1952,37 @@ struct platform_device *__init at32_add_device_ac97c(unsigned int id) | |||
1950 | 1952 | ||
1951 | if (platform_device_add_resources(pdev, atmel_ac97c0_resource, | 1953 | if (platform_device_add_resources(pdev, atmel_ac97c0_resource, |
1952 | ARRAY_SIZE(atmel_ac97c0_resource))) | 1954 | ARRAY_SIZE(atmel_ac97c0_resource))) |
1953 | goto err_add_resources; | 1955 | goto fail; |
1956 | |||
1957 | if (!data) { | ||
1958 | data = &_data; | ||
1959 | memset(data, 0, sizeof(struct ac97c_platform_data)); | ||
1960 | data->reset_pin = GPIO_PIN_NONE; | ||
1961 | } | ||
1954 | 1962 | ||
1955 | select_peripheral(PB(20), PERIPH_B, 0); /* SYNC */ | 1963 | data->dma_rx_periph_id = 3; |
1956 | select_peripheral(PB(21), PERIPH_B, 0); /* SDO */ | 1964 | data->dma_tx_periph_id = 4; |
1957 | select_peripheral(PB(22), PERIPH_B, 0); /* SDI */ | 1965 | data->dma_controller_id = 0; |
1958 | select_peripheral(PB(23), PERIPH_B, 0); /* SCLK */ | 1966 | |
1967 | if (platform_device_add_data(pdev, data, | ||
1968 | sizeof(struct ac97c_platform_data))) | ||
1969 | goto fail; | ||
1970 | |||
1971 | select_peripheral(PB(20), PERIPH_B, 0); /* SDO */ | ||
1972 | select_peripheral(PB(21), PERIPH_B, 0); /* SYNC */ | ||
1973 | select_peripheral(PB(22), PERIPH_B, 0); /* SCLK */ | ||
1974 | select_peripheral(PB(23), PERIPH_B, 0); /* SDI */ | ||
1975 | |||
1976 | /* TODO: gpio_is_valid(data->reset_pin) with kernel 2.6.26. */ | ||
1977 | if (data->reset_pin != GPIO_PIN_NONE) | ||
1978 | at32_select_gpio(data->reset_pin, 0); | ||
1959 | 1979 | ||
1960 | atmel_ac97c0_pclk.dev = &pdev->dev; | 1980 | atmel_ac97c0_pclk.dev = &pdev->dev; |
1961 | 1981 | ||
1962 | platform_device_add(pdev); | 1982 | platform_device_add(pdev); |
1963 | return pdev; | 1983 | return pdev; |
1964 | 1984 | ||
1965 | err_add_resources: | 1985 | fail: |
1966 | platform_device_put(pdev); | 1986 | platform_device_put(pdev); |
1967 | return NULL; | 1987 | return NULL; |
1968 | } | 1988 | } |
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 2672f4d278ac..7a37d06376be 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
@@ -125,9 +125,9 @@ void kvm_arch_hardware_enable(void *garbage) | |||
125 | PAGE_KERNEL)); | 125 | PAGE_KERNEL)); |
126 | local_irq_save(saved_psr); | 126 | local_irq_save(saved_psr); |
127 | slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT); | 127 | slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT); |
128 | local_irq_restore(saved_psr); | ||
128 | if (slot < 0) | 129 | if (slot < 0) |
129 | return; | 130 | return; |
130 | local_irq_restore(saved_psr); | ||
131 | 131 | ||
132 | spin_lock(&vp_lock); | 132 | spin_lock(&vp_lock); |
133 | status = ia64_pal_vp_init_env(kvm_vsa_base ? | 133 | status = ia64_pal_vp_init_env(kvm_vsa_base ? |
@@ -160,9 +160,9 @@ void kvm_arch_hardware_disable(void *garbage) | |||
160 | 160 | ||
161 | local_irq_save(saved_psr); | 161 | local_irq_save(saved_psr); |
162 | slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT); | 162 | slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT); |
163 | local_irq_restore(saved_psr); | ||
163 | if (slot < 0) | 164 | if (slot < 0) |
164 | return; | 165 | return; |
165 | local_irq_restore(saved_psr); | ||
166 | 166 | ||
167 | status = ia64_pal_vp_exit_env(host_iva); | 167 | status = ia64_pal_vp_exit_env(host_iva); |
168 | if (status) | 168 | if (status) |
@@ -1253,6 +1253,7 @@ static int vti_vcpu_setup(struct kvm_vcpu *vcpu, int id) | |||
1253 | uninit: | 1253 | uninit: |
1254 | kvm_vcpu_uninit(vcpu); | 1254 | kvm_vcpu_uninit(vcpu); |
1255 | fail: | 1255 | fail: |
1256 | local_irq_restore(psr); | ||
1256 | return r; | 1257 | return r; |
1257 | } | 1258 | } |
1258 | 1259 | ||
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c index 75dff7cfa814..5a5602da5091 100644 --- a/arch/powerpc/kvm/44x_tlb.c +++ b/arch/powerpc/kvm/44x_tlb.c | |||
@@ -177,7 +177,8 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid, | |||
177 | vcpu->arch.msr & MSR_PR); | 177 | vcpu->arch.msr & MSR_PR); |
178 | } | 178 | } |
179 | 179 | ||
180 | void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid) | 180 | void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr, |
181 | gva_t eend, u32 asid) | ||
181 | { | 182 | { |
182 | unsigned int pid = asid & 0xff; | 183 | unsigned int pid = asid & 0xff; |
183 | int i; | 184 | int i; |
@@ -191,7 +192,7 @@ void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid) | |||
191 | if (!get_tlb_v(stlbe)) | 192 | if (!get_tlb_v(stlbe)) |
192 | continue; | 193 | continue; |
193 | 194 | ||
194 | if (eaddr < get_tlb_eaddr(stlbe)) | 195 | if (eend < get_tlb_eaddr(stlbe)) |
195 | continue; | 196 | continue; |
196 | 197 | ||
197 | if (eaddr > get_tlb_end(stlbe)) | 198 | if (eaddr > get_tlb_end(stlbe)) |
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index 000097461283..8c605d0a5488 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c | |||
@@ -137,7 +137,7 @@ static int kvmppc_emul_tlbwe(struct kvm_vcpu *vcpu, u32 inst) | |||
137 | if (tlbe->word0 & PPC44x_TLB_VALID) { | 137 | if (tlbe->word0 & PPC44x_TLB_VALID) { |
138 | eaddr = get_tlb_eaddr(tlbe); | 138 | eaddr = get_tlb_eaddr(tlbe); |
139 | asid = (tlbe->word0 & PPC44x_TLB_TS) | tlbe->tid; | 139 | asid = (tlbe->word0 & PPC44x_TLB_TS) | tlbe->tid; |
140 | kvmppc_mmu_invalidate(vcpu, eaddr, asid); | 140 | kvmppc_mmu_invalidate(vcpu, eaddr, get_tlb_end(tlbe), asid); |
141 | } | 141 | } |
142 | 142 | ||
143 | switch (ws) { | 143 | switch (ws) { |
diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h index 4e0633c413f3..ed60f3a74a85 100644 --- a/arch/s390/kvm/gaccess.h +++ b/arch/s390/kvm/gaccess.h | |||
@@ -18,11 +18,11 @@ | |||
18 | #include <asm/uaccess.h> | 18 | #include <asm/uaccess.h> |
19 | 19 | ||
20 | static inline void __user *__guestaddr_to_user(struct kvm_vcpu *vcpu, | 20 | static inline void __user *__guestaddr_to_user(struct kvm_vcpu *vcpu, |
21 | u64 guestaddr) | 21 | unsigned long guestaddr) |
22 | { | 22 | { |
23 | u64 prefix = vcpu->arch.sie_block->prefix; | 23 | unsigned long prefix = vcpu->arch.sie_block->prefix; |
24 | u64 origin = vcpu->kvm->arch.guest_origin; | 24 | unsigned long origin = vcpu->kvm->arch.guest_origin; |
25 | u64 memsize = vcpu->kvm->arch.guest_memsize; | 25 | unsigned long memsize = vcpu->kvm->arch.guest_memsize; |
26 | 26 | ||
27 | if (guestaddr < 2 * PAGE_SIZE) | 27 | if (guestaddr < 2 * PAGE_SIZE) |
28 | guestaddr += prefix; | 28 | guestaddr += prefix; |
@@ -37,7 +37,7 @@ static inline void __user *__guestaddr_to_user(struct kvm_vcpu *vcpu, | |||
37 | return (void __user *) guestaddr; | 37 | return (void __user *) guestaddr; |
38 | } | 38 | } |
39 | 39 | ||
40 | static inline int get_guest_u64(struct kvm_vcpu *vcpu, u64 guestaddr, | 40 | static inline int get_guest_u64(struct kvm_vcpu *vcpu, unsigned long guestaddr, |
41 | u64 *result) | 41 | u64 *result) |
42 | { | 42 | { |
43 | void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); | 43 | void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); |
@@ -47,10 +47,10 @@ static inline int get_guest_u64(struct kvm_vcpu *vcpu, u64 guestaddr, | |||
47 | if (IS_ERR((void __force *) uptr)) | 47 | if (IS_ERR((void __force *) uptr)) |
48 | return PTR_ERR((void __force *) uptr); | 48 | return PTR_ERR((void __force *) uptr); |
49 | 49 | ||
50 | return get_user(*result, (u64 __user *) uptr); | 50 | return get_user(*result, (unsigned long __user *) uptr); |
51 | } | 51 | } |
52 | 52 | ||
53 | static inline int get_guest_u32(struct kvm_vcpu *vcpu, u64 guestaddr, | 53 | static inline int get_guest_u32(struct kvm_vcpu *vcpu, unsigned long guestaddr, |
54 | u32 *result) | 54 | u32 *result) |
55 | { | 55 | { |
56 | void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); | 56 | void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); |
@@ -63,7 +63,7 @@ static inline int get_guest_u32(struct kvm_vcpu *vcpu, u64 guestaddr, | |||
63 | return get_user(*result, (u32 __user *) uptr); | 63 | return get_user(*result, (u32 __user *) uptr); |
64 | } | 64 | } |
65 | 65 | ||
66 | static inline int get_guest_u16(struct kvm_vcpu *vcpu, u64 guestaddr, | 66 | static inline int get_guest_u16(struct kvm_vcpu *vcpu, unsigned long guestaddr, |
67 | u16 *result) | 67 | u16 *result) |
68 | { | 68 | { |
69 | void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); | 69 | void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); |
@@ -76,7 +76,7 @@ static inline int get_guest_u16(struct kvm_vcpu *vcpu, u64 guestaddr, | |||
76 | return get_user(*result, (u16 __user *) uptr); | 76 | return get_user(*result, (u16 __user *) uptr); |
77 | } | 77 | } |
78 | 78 | ||
79 | static inline int get_guest_u8(struct kvm_vcpu *vcpu, u64 guestaddr, | 79 | static inline int get_guest_u8(struct kvm_vcpu *vcpu, unsigned long guestaddr, |
80 | u8 *result) | 80 | u8 *result) |
81 | { | 81 | { |
82 | void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); | 82 | void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); |
@@ -87,7 +87,7 @@ static inline int get_guest_u8(struct kvm_vcpu *vcpu, u64 guestaddr, | |||
87 | return get_user(*result, (u8 __user *) uptr); | 87 | return get_user(*result, (u8 __user *) uptr); |
88 | } | 88 | } |
89 | 89 | ||
90 | static inline int put_guest_u64(struct kvm_vcpu *vcpu, u64 guestaddr, | 90 | static inline int put_guest_u64(struct kvm_vcpu *vcpu, unsigned long guestaddr, |
91 | u64 value) | 91 | u64 value) |
92 | { | 92 | { |
93 | void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); | 93 | void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); |
@@ -100,7 +100,7 @@ static inline int put_guest_u64(struct kvm_vcpu *vcpu, u64 guestaddr, | |||
100 | return put_user(value, (u64 __user *) uptr); | 100 | return put_user(value, (u64 __user *) uptr); |
101 | } | 101 | } |
102 | 102 | ||
103 | static inline int put_guest_u32(struct kvm_vcpu *vcpu, u64 guestaddr, | 103 | static inline int put_guest_u32(struct kvm_vcpu *vcpu, unsigned long guestaddr, |
104 | u32 value) | 104 | u32 value) |
105 | { | 105 | { |
106 | void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); | 106 | void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); |
@@ -113,7 +113,7 @@ static inline int put_guest_u32(struct kvm_vcpu *vcpu, u64 guestaddr, | |||
113 | return put_user(value, (u32 __user *) uptr); | 113 | return put_user(value, (u32 __user *) uptr); |
114 | } | 114 | } |
115 | 115 | ||
116 | static inline int put_guest_u16(struct kvm_vcpu *vcpu, u64 guestaddr, | 116 | static inline int put_guest_u16(struct kvm_vcpu *vcpu, unsigned long guestaddr, |
117 | u16 value) | 117 | u16 value) |
118 | { | 118 | { |
119 | void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); | 119 | void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); |
@@ -126,7 +126,7 @@ static inline int put_guest_u16(struct kvm_vcpu *vcpu, u64 guestaddr, | |||
126 | return put_user(value, (u16 __user *) uptr); | 126 | return put_user(value, (u16 __user *) uptr); |
127 | } | 127 | } |
128 | 128 | ||
129 | static inline int put_guest_u8(struct kvm_vcpu *vcpu, u64 guestaddr, | 129 | static inline int put_guest_u8(struct kvm_vcpu *vcpu, unsigned long guestaddr, |
130 | u8 value) | 130 | u8 value) |
131 | { | 131 | { |
132 | void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); | 132 | void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); |
@@ -138,7 +138,8 @@ static inline int put_guest_u8(struct kvm_vcpu *vcpu, u64 guestaddr, | |||
138 | } | 138 | } |
139 | 139 | ||
140 | 140 | ||
141 | static inline int __copy_to_guest_slow(struct kvm_vcpu *vcpu, u64 guestdest, | 141 | static inline int __copy_to_guest_slow(struct kvm_vcpu *vcpu, |
142 | unsigned long guestdest, | ||
142 | const void *from, unsigned long n) | 143 | const void *from, unsigned long n) |
143 | { | 144 | { |
144 | int rc; | 145 | int rc; |
@@ -153,12 +154,12 @@ static inline int __copy_to_guest_slow(struct kvm_vcpu *vcpu, u64 guestdest, | |||
153 | return 0; | 154 | return 0; |
154 | } | 155 | } |
155 | 156 | ||
156 | static inline int copy_to_guest(struct kvm_vcpu *vcpu, u64 guestdest, | 157 | static inline int copy_to_guest(struct kvm_vcpu *vcpu, unsigned long guestdest, |
157 | const void *from, unsigned long n) | 158 | const void *from, unsigned long n) |
158 | { | 159 | { |
159 | u64 prefix = vcpu->arch.sie_block->prefix; | 160 | unsigned long prefix = vcpu->arch.sie_block->prefix; |
160 | u64 origin = vcpu->kvm->arch.guest_origin; | 161 | unsigned long origin = vcpu->kvm->arch.guest_origin; |
161 | u64 memsize = vcpu->kvm->arch.guest_memsize; | 162 | unsigned long memsize = vcpu->kvm->arch.guest_memsize; |
162 | 163 | ||
163 | if ((guestdest < 2 * PAGE_SIZE) && (guestdest + n > 2 * PAGE_SIZE)) | 164 | if ((guestdest < 2 * PAGE_SIZE) && (guestdest + n > 2 * PAGE_SIZE)) |
164 | goto slowpath; | 165 | goto slowpath; |
@@ -189,7 +190,8 @@ slowpath: | |||
189 | } | 190 | } |
190 | 191 | ||
191 | static inline int __copy_from_guest_slow(struct kvm_vcpu *vcpu, void *to, | 192 | static inline int __copy_from_guest_slow(struct kvm_vcpu *vcpu, void *to, |
192 | u64 guestsrc, unsigned long n) | 193 | unsigned long guestsrc, |
194 | unsigned long n) | ||
193 | { | 195 | { |
194 | int rc; | 196 | int rc; |
195 | unsigned long i; | 197 | unsigned long i; |
@@ -204,11 +206,11 @@ static inline int __copy_from_guest_slow(struct kvm_vcpu *vcpu, void *to, | |||
204 | } | 206 | } |
205 | 207 | ||
206 | static inline int copy_from_guest(struct kvm_vcpu *vcpu, void *to, | 208 | static inline int copy_from_guest(struct kvm_vcpu *vcpu, void *to, |
207 | u64 guestsrc, unsigned long n) | 209 | unsigned long guestsrc, unsigned long n) |
208 | { | 210 | { |
209 | u64 prefix = vcpu->arch.sie_block->prefix; | 211 | unsigned long prefix = vcpu->arch.sie_block->prefix; |
210 | u64 origin = vcpu->kvm->arch.guest_origin; | 212 | unsigned long origin = vcpu->kvm->arch.guest_origin; |
211 | u64 memsize = vcpu->kvm->arch.guest_memsize; | 213 | unsigned long memsize = vcpu->kvm->arch.guest_memsize; |
212 | 214 | ||
213 | if ((guestsrc < 2 * PAGE_SIZE) && (guestsrc + n > 2 * PAGE_SIZE)) | 215 | if ((guestsrc < 2 * PAGE_SIZE) && (guestsrc + n > 2 * PAGE_SIZE)) |
214 | goto slowpath; | 216 | goto slowpath; |
@@ -238,11 +240,12 @@ slowpath: | |||
238 | return __copy_from_guest_slow(vcpu, to, guestsrc, n); | 240 | return __copy_from_guest_slow(vcpu, to, guestsrc, n); |
239 | } | 241 | } |
240 | 242 | ||
241 | static inline int copy_to_guest_absolute(struct kvm_vcpu *vcpu, u64 guestdest, | 243 | static inline int copy_to_guest_absolute(struct kvm_vcpu *vcpu, |
244 | unsigned long guestdest, | ||
242 | const void *from, unsigned long n) | 245 | const void *from, unsigned long n) |
243 | { | 246 | { |
244 | u64 origin = vcpu->kvm->arch.guest_origin; | 247 | unsigned long origin = vcpu->kvm->arch.guest_origin; |
245 | u64 memsize = vcpu->kvm->arch.guest_memsize; | 248 | unsigned long memsize = vcpu->kvm->arch.guest_memsize; |
246 | 249 | ||
247 | if (guestdest + n > memsize) | 250 | if (guestdest + n > memsize) |
248 | return -EFAULT; | 251 | return -EFAULT; |
@@ -256,10 +259,11 @@ static inline int copy_to_guest_absolute(struct kvm_vcpu *vcpu, u64 guestdest, | |||
256 | } | 259 | } |
257 | 260 | ||
258 | static inline int copy_from_guest_absolute(struct kvm_vcpu *vcpu, void *to, | 261 | static inline int copy_from_guest_absolute(struct kvm_vcpu *vcpu, void *to, |
259 | u64 guestsrc, unsigned long n) | 262 | unsigned long guestsrc, |
263 | unsigned long n) | ||
260 | { | 264 | { |
261 | u64 origin = vcpu->kvm->arch.guest_origin; | 265 | unsigned long origin = vcpu->kvm->arch.guest_origin; |
262 | u64 memsize = vcpu->kvm->arch.guest_memsize; | 266 | unsigned long memsize = vcpu->kvm->arch.guest_memsize; |
263 | 267 | ||
264 | if (guestsrc + n > memsize) | 268 | if (guestsrc + n > memsize) |
265 | return -EFAULT; | 269 | return -EFAULT; |
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index 47a0b642174c..61236102203e 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include "kvm-s390.h" | 20 | #include "kvm-s390.h" |
21 | #include "gaccess.h" | 21 | #include "gaccess.h" |
22 | 22 | ||
23 | static int handle_lctg(struct kvm_vcpu *vcpu) | 23 | static int handle_lctlg(struct kvm_vcpu *vcpu) |
24 | { | 24 | { |
25 | int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; | 25 | int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; |
26 | int reg3 = vcpu->arch.sie_block->ipa & 0x000f; | 26 | int reg3 = vcpu->arch.sie_block->ipa & 0x000f; |
@@ -30,7 +30,7 @@ static int handle_lctg(struct kvm_vcpu *vcpu) | |||
30 | u64 useraddr; | 30 | u64 useraddr; |
31 | int reg, rc; | 31 | int reg, rc; |
32 | 32 | ||
33 | vcpu->stat.instruction_lctg++; | 33 | vcpu->stat.instruction_lctlg++; |
34 | if ((vcpu->arch.sie_block->ipb & 0xff) != 0x2f) | 34 | if ((vcpu->arch.sie_block->ipb & 0xff) != 0x2f) |
35 | return -ENOTSUPP; | 35 | return -ENOTSUPP; |
36 | 36 | ||
@@ -38,9 +38,12 @@ static int handle_lctg(struct kvm_vcpu *vcpu) | |||
38 | if (base2) | 38 | if (base2) |
39 | useraddr += vcpu->arch.guest_gprs[base2]; | 39 | useraddr += vcpu->arch.guest_gprs[base2]; |
40 | 40 | ||
41 | if (useraddr & 7) | ||
42 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | ||
43 | |||
41 | reg = reg1; | 44 | reg = reg1; |
42 | 45 | ||
43 | VCPU_EVENT(vcpu, 5, "lctg r1:%x, r3:%x,b2:%x,d2:%x", reg1, reg3, base2, | 46 | VCPU_EVENT(vcpu, 5, "lctlg r1:%x, r3:%x,b2:%x,d2:%x", reg1, reg3, base2, |
44 | disp2); | 47 | disp2); |
45 | 48 | ||
46 | do { | 49 | do { |
@@ -74,6 +77,9 @@ static int handle_lctl(struct kvm_vcpu *vcpu) | |||
74 | if (base2) | 77 | if (base2) |
75 | useraddr += vcpu->arch.guest_gprs[base2]; | 78 | useraddr += vcpu->arch.guest_gprs[base2]; |
76 | 79 | ||
80 | if (useraddr & 3) | ||
81 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | ||
82 | |||
77 | VCPU_EVENT(vcpu, 5, "lctl r1:%x, r3:%x,b2:%x,d2:%x", reg1, reg3, base2, | 83 | VCPU_EVENT(vcpu, 5, "lctl r1:%x, r3:%x,b2:%x,d2:%x", reg1, reg3, base2, |
78 | disp2); | 84 | disp2); |
79 | 85 | ||
@@ -99,7 +105,7 @@ static intercept_handler_t instruction_handlers[256] = { | |||
99 | [0xae] = kvm_s390_handle_sigp, | 105 | [0xae] = kvm_s390_handle_sigp, |
100 | [0xb2] = kvm_s390_handle_priv, | 106 | [0xb2] = kvm_s390_handle_priv, |
101 | [0xb7] = handle_lctl, | 107 | [0xb7] = handle_lctl, |
102 | [0xeb] = handle_lctg, | 108 | [0xeb] = handle_lctlg, |
103 | }; | 109 | }; |
104 | 110 | ||
105 | static int handle_noop(struct kvm_vcpu *vcpu) | 111 | static int handle_noop(struct kvm_vcpu *vcpu) |
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 11230b0db957..2960702b4824 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <asm/lowcore.h> | 13 | #include <asm/lowcore.h> |
14 | #include <asm/uaccess.h> | 14 | #include <asm/uaccess.h> |
15 | #include <linux/kvm_host.h> | 15 | #include <linux/kvm_host.h> |
16 | #include <linux/signal.h> | ||
16 | #include "kvm-s390.h" | 17 | #include "kvm-s390.h" |
17 | #include "gaccess.h" | 18 | #include "gaccess.h" |
18 | 19 | ||
@@ -246,15 +247,10 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu, | |||
246 | default: | 247 | default: |
247 | BUG(); | 248 | BUG(); |
248 | } | 249 | } |
249 | |||
250 | if (exception) { | 250 | if (exception) { |
251 | VCPU_EVENT(vcpu, 1, "%s", "program exception while delivering" | 251 | printk("kvm: The guest lowcore is not mapped during interrupt " |
252 | " interrupt"); | 252 | "delivery, killing userspace\n"); |
253 | kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); | 253 | do_exit(SIGKILL); |
254 | if (inti->type == KVM_S390_PROGRAM_INT) { | ||
255 | printk(KERN_WARNING "kvm: recursive program check\n"); | ||
256 | BUG(); | ||
257 | } | ||
258 | } | 254 | } |
259 | } | 255 | } |
260 | 256 | ||
@@ -277,14 +273,11 @@ static int __try_deliver_ckc_interrupt(struct kvm_vcpu *vcpu) | |||
277 | __LC_EXT_NEW_PSW, sizeof(psw_t)); | 273 | __LC_EXT_NEW_PSW, sizeof(psw_t)); |
278 | if (rc == -EFAULT) | 274 | if (rc == -EFAULT) |
279 | exception = 1; | 275 | exception = 1; |
280 | |||
281 | if (exception) { | 276 | if (exception) { |
282 | VCPU_EVENT(vcpu, 1, "%s", "program exception while delivering" \ | 277 | printk("kvm: The guest lowcore is not mapped during interrupt " |
283 | " ckc interrupt"); | 278 | "delivery, killing userspace\n"); |
284 | kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); | 279 | do_exit(SIGKILL); |
285 | return 0; | ||
286 | } | 280 | } |
287 | |||
288 | return 1; | 281 | return 1; |
289 | } | 282 | } |
290 | 283 | ||
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 1782cbcd2829..8b00eb2ddf57 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -39,7 +39,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
39 | { "exit_instruction", VCPU_STAT(exit_instruction) }, | 39 | { "exit_instruction", VCPU_STAT(exit_instruction) }, |
40 | { "exit_program_interruption", VCPU_STAT(exit_program_interruption) }, | 40 | { "exit_program_interruption", VCPU_STAT(exit_program_interruption) }, |
41 | { "exit_instr_and_program_int", VCPU_STAT(exit_instr_and_program) }, | 41 | { "exit_instr_and_program_int", VCPU_STAT(exit_instr_and_program) }, |
42 | { "instruction_lctg", VCPU_STAT(instruction_lctg) }, | 42 | { "instruction_lctlg", VCPU_STAT(instruction_lctlg) }, |
43 | { "instruction_lctl", VCPU_STAT(instruction_lctl) }, | 43 | { "instruction_lctl", VCPU_STAT(instruction_lctl) }, |
44 | { "deliver_emergency_signal", VCPU_STAT(deliver_emergency_signal) }, | 44 | { "deliver_emergency_signal", VCPU_STAT(deliver_emergency_signal) }, |
45 | { "deliver_service_signal", VCPU_STAT(deliver_service_signal) }, | 45 | { "deliver_service_signal", VCPU_STAT(deliver_service_signal) }, |
@@ -112,7 +112,12 @@ long kvm_arch_dev_ioctl(struct file *filp, | |||
112 | 112 | ||
113 | int kvm_dev_ioctl_check_extension(long ext) | 113 | int kvm_dev_ioctl_check_extension(long ext) |
114 | { | 114 | { |
115 | return 0; | 115 | switch (ext) { |
116 | case KVM_CAP_USER_MEMORY: | ||
117 | return 1; | ||
118 | default: | ||
119 | return 0; | ||
120 | } | ||
116 | } | 121 | } |
117 | 122 | ||
118 | /* Section: vm related */ | 123 | /* Section: vm related */ |
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 5a556114eaa5..170392687ce0 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c | |||
@@ -43,7 +43,8 @@ | |||
43 | #define SIGP_STAT_RECEIVER_CHECK 0x00000001UL | 43 | #define SIGP_STAT_RECEIVER_CHECK 0x00000001UL |
44 | 44 | ||
45 | 45 | ||
46 | static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr, u64 *reg) | 46 | static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr, |
47 | unsigned long *reg) | ||
47 | { | 48 | { |
48 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; | 49 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; |
49 | int rc; | 50 | int rc; |
@@ -167,7 +168,7 @@ static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter) | |||
167 | } | 168 | } |
168 | 169 | ||
169 | static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, | 170 | static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, |
170 | u64 *reg) | 171 | unsigned long *reg) |
171 | { | 172 | { |
172 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; | 173 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; |
173 | struct kvm_s390_local_interrupt *li; | 174 | struct kvm_s390_local_interrupt *li; |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index b0e4ddca6c18..2fa231923cf7 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -1814,6 +1814,7 @@ int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva) | |||
1814 | spin_unlock(&vcpu->kvm->mmu_lock); | 1814 | spin_unlock(&vcpu->kvm->mmu_lock); |
1815 | return r; | 1815 | return r; |
1816 | } | 1816 | } |
1817 | EXPORT_SYMBOL_GPL(kvm_mmu_unprotect_page_virt); | ||
1817 | 1818 | ||
1818 | void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) | 1819 | void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) |
1819 | { | 1820 | { |
@@ -1870,6 +1871,12 @@ void kvm_enable_tdp(void) | |||
1870 | } | 1871 | } |
1871 | EXPORT_SYMBOL_GPL(kvm_enable_tdp); | 1872 | EXPORT_SYMBOL_GPL(kvm_enable_tdp); |
1872 | 1873 | ||
1874 | void kvm_disable_tdp(void) | ||
1875 | { | ||
1876 | tdp_enabled = false; | ||
1877 | } | ||
1878 | EXPORT_SYMBOL_GPL(kvm_disable_tdp); | ||
1879 | |||
1873 | static void free_mmu_pages(struct kvm_vcpu *vcpu) | 1880 | static void free_mmu_pages(struct kvm_vcpu *vcpu) |
1874 | { | 1881 | { |
1875 | struct kvm_mmu_page *sp; | 1882 | struct kvm_mmu_page *sp; |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index b756e876dce3..e2ee264740c7 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -453,7 +453,8 @@ static __init int svm_hardware_setup(void) | |||
453 | if (npt_enabled) { | 453 | if (npt_enabled) { |
454 | printk(KERN_INFO "kvm: Nested Paging enabled\n"); | 454 | printk(KERN_INFO "kvm: Nested Paging enabled\n"); |
455 | kvm_enable_tdp(); | 455 | kvm_enable_tdp(); |
456 | } | 456 | } else |
457 | kvm_disable_tdp(); | ||
457 | 458 | ||
458 | return 0; | 459 | return 0; |
459 | 460 | ||
@@ -1007,10 +1008,13 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | |||
1007 | struct kvm *kvm = svm->vcpu.kvm; | 1008 | struct kvm *kvm = svm->vcpu.kvm; |
1008 | u64 fault_address; | 1009 | u64 fault_address; |
1009 | u32 error_code; | 1010 | u32 error_code; |
1011 | bool event_injection = false; | ||
1010 | 1012 | ||
1011 | if (!irqchip_in_kernel(kvm) && | 1013 | if (!irqchip_in_kernel(kvm) && |
1012 | is_external_interrupt(exit_int_info)) | 1014 | is_external_interrupt(exit_int_info)) { |
1015 | event_injection = true; | ||
1013 | push_irq(&svm->vcpu, exit_int_info & SVM_EVTINJ_VEC_MASK); | 1016 | push_irq(&svm->vcpu, exit_int_info & SVM_EVTINJ_VEC_MASK); |
1017 | } | ||
1014 | 1018 | ||
1015 | fault_address = svm->vmcb->control.exit_info_2; | 1019 | fault_address = svm->vmcb->control.exit_info_2; |
1016 | error_code = svm->vmcb->control.exit_info_1; | 1020 | error_code = svm->vmcb->control.exit_info_1; |
@@ -1024,6 +1028,8 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | |||
1024 | (u32)fault_address, (u32)(fault_address >> 32), | 1028 | (u32)fault_address, (u32)(fault_address >> 32), |
1025 | handler); | 1029 | handler); |
1026 | 1030 | ||
1031 | if (event_injection) | ||
1032 | kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address); | ||
1027 | return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code); | 1033 | return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code); |
1028 | } | 1034 | } |
1029 | 1035 | ||
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 0cac63701719..2a69773e3b26 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -2298,6 +2298,8 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
2298 | cr2 = vmcs_readl(EXIT_QUALIFICATION); | 2298 | cr2 = vmcs_readl(EXIT_QUALIFICATION); |
2299 | KVMTRACE_3D(PAGE_FAULT, vcpu, error_code, (u32)cr2, | 2299 | KVMTRACE_3D(PAGE_FAULT, vcpu, error_code, (u32)cr2, |
2300 | (u32)((u64)cr2 >> 32), handler); | 2300 | (u32)((u64)cr2 >> 32), handler); |
2301 | if (vect_info & VECTORING_INFO_VALID_MASK) | ||
2302 | kvm_mmu_unprotect_page_virt(vcpu, cr2); | ||
2301 | return kvm_mmu_page_fault(vcpu, cr2, error_code); | 2303 | return kvm_mmu_page_fault(vcpu, cr2, error_code); |
2302 | } | 2304 | } |
2303 | 2305 | ||
@@ -3116,15 +3118,6 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) | |||
3116 | return ERR_PTR(-ENOMEM); | 3118 | return ERR_PTR(-ENOMEM); |
3117 | 3119 | ||
3118 | allocate_vpid(vmx); | 3120 | allocate_vpid(vmx); |
3119 | if (id == 0 && vm_need_ept()) { | ||
3120 | kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK | | ||
3121 | VMX_EPT_WRITABLE_MASK | | ||
3122 | VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT); | ||
3123 | kvm_mmu_set_mask_ptes(0ull, VMX_EPT_FAKE_ACCESSED_MASK, | ||
3124 | VMX_EPT_FAKE_DIRTY_MASK, 0ull, | ||
3125 | VMX_EPT_EXECUTABLE_MASK); | ||
3126 | kvm_enable_tdp(); | ||
3127 | } | ||
3128 | 3121 | ||
3129 | err = kvm_vcpu_init(&vmx->vcpu, kvm, id); | 3122 | err = kvm_vcpu_init(&vmx->vcpu, kvm, id); |
3130 | if (err) | 3123 | if (err) |
@@ -3303,8 +3296,17 @@ static int __init vmx_init(void) | |||
3303 | vmx_disable_intercept_for_msr(vmx_msr_bitmap, MSR_IA32_SYSENTER_ESP); | 3296 | vmx_disable_intercept_for_msr(vmx_msr_bitmap, MSR_IA32_SYSENTER_ESP); |
3304 | vmx_disable_intercept_for_msr(vmx_msr_bitmap, MSR_IA32_SYSENTER_EIP); | 3297 | vmx_disable_intercept_for_msr(vmx_msr_bitmap, MSR_IA32_SYSENTER_EIP); |
3305 | 3298 | ||
3306 | if (cpu_has_vmx_ept()) | 3299 | if (vm_need_ept()) { |
3307 | bypass_guest_pf = 0; | 3300 | bypass_guest_pf = 0; |
3301 | kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK | | ||
3302 | VMX_EPT_WRITABLE_MASK | | ||
3303 | VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT); | ||
3304 | kvm_mmu_set_mask_ptes(0ull, VMX_EPT_FAKE_ACCESSED_MASK, | ||
3305 | VMX_EPT_FAKE_DIRTY_MASK, 0ull, | ||
3306 | VMX_EPT_EXECUTABLE_MASK); | ||
3307 | kvm_enable_tdp(); | ||
3308 | } else | ||
3309 | kvm_disable_tdp(); | ||
3308 | 3310 | ||
3309 | if (bypass_guest_pf) | 3311 | if (bypass_guest_pf) |
3310 | kvm_mmu_set_nonpresent_ptes(~0xffeull, 0ull); | 3312 | kvm_mmu_set_nonpresent_ptes(~0xffeull, 0ull); |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 9f1cdb011cff..5916191420c7 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -3184,6 +3184,10 @@ static void seg_desct_to_kvm_desct(struct desc_struct *seg_desc, u16 selector, | |||
3184 | kvm_desct->base |= seg_desc->base2 << 24; | 3184 | kvm_desct->base |= seg_desc->base2 << 24; |
3185 | kvm_desct->limit = seg_desc->limit0; | 3185 | kvm_desct->limit = seg_desc->limit0; |
3186 | kvm_desct->limit |= seg_desc->limit << 16; | 3186 | kvm_desct->limit |= seg_desc->limit << 16; |
3187 | if (seg_desc->g) { | ||
3188 | kvm_desct->limit <<= 12; | ||
3189 | kvm_desct->limit |= 0xfff; | ||
3190 | } | ||
3187 | kvm_desct->selector = selector; | 3191 | kvm_desct->selector = selector; |
3188 | kvm_desct->type = seg_desc->type; | 3192 | kvm_desct->type = seg_desc->type; |
3189 | kvm_desct->present = seg_desc->p; | 3193 | kvm_desct->present = seg_desc->p; |
@@ -3223,6 +3227,7 @@ static void get_segment_descritptor_dtable(struct kvm_vcpu *vcpu, | |||
3223 | static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, | 3227 | static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, |
3224 | struct desc_struct *seg_desc) | 3228 | struct desc_struct *seg_desc) |
3225 | { | 3229 | { |
3230 | gpa_t gpa; | ||
3226 | struct descriptor_table dtable; | 3231 | struct descriptor_table dtable; |
3227 | u16 index = selector >> 3; | 3232 | u16 index = selector >> 3; |
3228 | 3233 | ||
@@ -3232,13 +3237,16 @@ static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, | |||
3232 | kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc); | 3237 | kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc); |
3233 | return 1; | 3238 | return 1; |
3234 | } | 3239 | } |
3235 | return kvm_read_guest(vcpu->kvm, dtable.base + index * 8, seg_desc, 8); | 3240 | gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base); |
3241 | gpa += index * 8; | ||
3242 | return kvm_read_guest(vcpu->kvm, gpa, seg_desc, 8); | ||
3236 | } | 3243 | } |
3237 | 3244 | ||
3238 | /* allowed just for 8 bytes segments */ | 3245 | /* allowed just for 8 bytes segments */ |
3239 | static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, | 3246 | static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, |
3240 | struct desc_struct *seg_desc) | 3247 | struct desc_struct *seg_desc) |
3241 | { | 3248 | { |
3249 | gpa_t gpa; | ||
3242 | struct descriptor_table dtable; | 3250 | struct descriptor_table dtable; |
3243 | u16 index = selector >> 3; | 3251 | u16 index = selector >> 3; |
3244 | 3252 | ||
@@ -3246,7 +3254,9 @@ static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, | |||
3246 | 3254 | ||
3247 | if (dtable.limit < index * 8 + 7) | 3255 | if (dtable.limit < index * 8 + 7) |
3248 | return 1; | 3256 | return 1; |
3249 | return kvm_write_guest(vcpu->kvm, dtable.base + index * 8, seg_desc, 8); | 3257 | gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base); |
3258 | gpa += index * 8; | ||
3259 | return kvm_write_guest(vcpu->kvm, gpa, seg_desc, 8); | ||
3250 | } | 3260 | } |
3251 | 3261 | ||
3252 | static u32 get_tss_base_addr(struct kvm_vcpu *vcpu, | 3262 | static u32 get_tss_base_addr(struct kvm_vcpu *vcpu, |
@@ -3258,55 +3268,7 @@ static u32 get_tss_base_addr(struct kvm_vcpu *vcpu, | |||
3258 | base_addr |= (seg_desc->base1 << 16); | 3268 | base_addr |= (seg_desc->base1 << 16); |
3259 | base_addr |= (seg_desc->base2 << 24); | 3269 | base_addr |= (seg_desc->base2 << 24); |
3260 | 3270 | ||
3261 | return base_addr; | 3271 | return vcpu->arch.mmu.gva_to_gpa(vcpu, base_addr); |
3262 | } | ||
3263 | |||
3264 | static int load_tss_segment32(struct kvm_vcpu *vcpu, | ||
3265 | struct desc_struct *seg_desc, | ||
3266 | struct tss_segment_32 *tss) | ||
3267 | { | ||
3268 | u32 base_addr; | ||
3269 | |||
3270 | base_addr = get_tss_base_addr(vcpu, seg_desc); | ||
3271 | |||
3272 | return kvm_read_guest(vcpu->kvm, base_addr, tss, | ||
3273 | sizeof(struct tss_segment_32)); | ||
3274 | } | ||
3275 | |||
3276 | static int save_tss_segment32(struct kvm_vcpu *vcpu, | ||
3277 | struct desc_struct *seg_desc, | ||
3278 | struct tss_segment_32 *tss) | ||
3279 | { | ||
3280 | u32 base_addr; | ||
3281 | |||
3282 | base_addr = get_tss_base_addr(vcpu, seg_desc); | ||
3283 | |||
3284 | return kvm_write_guest(vcpu->kvm, base_addr, tss, | ||
3285 | sizeof(struct tss_segment_32)); | ||
3286 | } | ||
3287 | |||
3288 | static int load_tss_segment16(struct kvm_vcpu *vcpu, | ||
3289 | struct desc_struct *seg_desc, | ||
3290 | struct tss_segment_16 *tss) | ||
3291 | { | ||
3292 | u32 base_addr; | ||
3293 | |||
3294 | base_addr = get_tss_base_addr(vcpu, seg_desc); | ||
3295 | |||
3296 | return kvm_read_guest(vcpu->kvm, base_addr, tss, | ||
3297 | sizeof(struct tss_segment_16)); | ||
3298 | } | ||
3299 | |||
3300 | static int save_tss_segment16(struct kvm_vcpu *vcpu, | ||
3301 | struct desc_struct *seg_desc, | ||
3302 | struct tss_segment_16 *tss) | ||
3303 | { | ||
3304 | u32 base_addr; | ||
3305 | |||
3306 | base_addr = get_tss_base_addr(vcpu, seg_desc); | ||
3307 | |||
3308 | return kvm_write_guest(vcpu->kvm, base_addr, tss, | ||
3309 | sizeof(struct tss_segment_16)); | ||
3310 | } | 3272 | } |
3311 | 3273 | ||
3312 | static u16 get_segment_selector(struct kvm_vcpu *vcpu, int seg) | 3274 | static u16 get_segment_selector(struct kvm_vcpu *vcpu, int seg) |
@@ -3466,20 +3428,26 @@ static int load_state_from_tss16(struct kvm_vcpu *vcpu, | |||
3466 | } | 3428 | } |
3467 | 3429 | ||
3468 | static int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector, | 3430 | static int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector, |
3469 | struct desc_struct *cseg_desc, | 3431 | u32 old_tss_base, |
3470 | struct desc_struct *nseg_desc) | 3432 | struct desc_struct *nseg_desc) |
3471 | { | 3433 | { |
3472 | struct tss_segment_16 tss_segment_16; | 3434 | struct tss_segment_16 tss_segment_16; |
3473 | int ret = 0; | 3435 | int ret = 0; |
3474 | 3436 | ||
3475 | if (load_tss_segment16(vcpu, cseg_desc, &tss_segment_16)) | 3437 | if (kvm_read_guest(vcpu->kvm, old_tss_base, &tss_segment_16, |
3438 | sizeof tss_segment_16)) | ||
3476 | goto out; | 3439 | goto out; |
3477 | 3440 | ||
3478 | save_state_to_tss16(vcpu, &tss_segment_16); | 3441 | save_state_to_tss16(vcpu, &tss_segment_16); |
3479 | save_tss_segment16(vcpu, cseg_desc, &tss_segment_16); | ||
3480 | 3442 | ||
3481 | if (load_tss_segment16(vcpu, nseg_desc, &tss_segment_16)) | 3443 | if (kvm_write_guest(vcpu->kvm, old_tss_base, &tss_segment_16, |
3444 | sizeof tss_segment_16)) | ||
3482 | goto out; | 3445 | goto out; |
3446 | |||
3447 | if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc), | ||
3448 | &tss_segment_16, sizeof tss_segment_16)) | ||
3449 | goto out; | ||
3450 | |||
3483 | if (load_state_from_tss16(vcpu, &tss_segment_16)) | 3451 | if (load_state_from_tss16(vcpu, &tss_segment_16)) |
3484 | goto out; | 3452 | goto out; |
3485 | 3453 | ||
@@ -3489,20 +3457,26 @@ out: | |||
3489 | } | 3457 | } |
3490 | 3458 | ||
3491 | static int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector, | 3459 | static int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector, |
3492 | struct desc_struct *cseg_desc, | 3460 | u32 old_tss_base, |
3493 | struct desc_struct *nseg_desc) | 3461 | struct desc_struct *nseg_desc) |
3494 | { | 3462 | { |
3495 | struct tss_segment_32 tss_segment_32; | 3463 | struct tss_segment_32 tss_segment_32; |
3496 | int ret = 0; | 3464 | int ret = 0; |
3497 | 3465 | ||
3498 | if (load_tss_segment32(vcpu, cseg_desc, &tss_segment_32)) | 3466 | if (kvm_read_guest(vcpu->kvm, old_tss_base, &tss_segment_32, |
3467 | sizeof tss_segment_32)) | ||
3499 | goto out; | 3468 | goto out; |
3500 | 3469 | ||
3501 | save_state_to_tss32(vcpu, &tss_segment_32); | 3470 | save_state_to_tss32(vcpu, &tss_segment_32); |
3502 | save_tss_segment32(vcpu, cseg_desc, &tss_segment_32); | ||
3503 | 3471 | ||
3504 | if (load_tss_segment32(vcpu, nseg_desc, &tss_segment_32)) | 3472 | if (kvm_write_guest(vcpu->kvm, old_tss_base, &tss_segment_32, |
3473 | sizeof tss_segment_32)) | ||
3474 | goto out; | ||
3475 | |||
3476 | if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc), | ||
3477 | &tss_segment_32, sizeof tss_segment_32)) | ||
3505 | goto out; | 3478 | goto out; |
3479 | |||
3506 | if (load_state_from_tss32(vcpu, &tss_segment_32)) | 3480 | if (load_state_from_tss32(vcpu, &tss_segment_32)) |
3507 | goto out; | 3481 | goto out; |
3508 | 3482 | ||
@@ -3517,16 +3491,20 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason) | |||
3517 | struct desc_struct cseg_desc; | 3491 | struct desc_struct cseg_desc; |
3518 | struct desc_struct nseg_desc; | 3492 | struct desc_struct nseg_desc; |
3519 | int ret = 0; | 3493 | int ret = 0; |
3494 | u32 old_tss_base = get_segment_base(vcpu, VCPU_SREG_TR); | ||
3495 | u16 old_tss_sel = get_segment_selector(vcpu, VCPU_SREG_TR); | ||
3520 | 3496 | ||
3521 | kvm_get_segment(vcpu, &tr_seg, VCPU_SREG_TR); | 3497 | old_tss_base = vcpu->arch.mmu.gva_to_gpa(vcpu, old_tss_base); |
3522 | 3498 | ||
3499 | /* FIXME: Handle errors. Failure to read either TSS or their | ||
3500 | * descriptors should generate a pagefault. | ||
3501 | */ | ||
3523 | if (load_guest_segment_descriptor(vcpu, tss_selector, &nseg_desc)) | 3502 | if (load_guest_segment_descriptor(vcpu, tss_selector, &nseg_desc)) |
3524 | goto out; | 3503 | goto out; |
3525 | 3504 | ||
3526 | if (load_guest_segment_descriptor(vcpu, tr_seg.selector, &cseg_desc)) | 3505 | if (load_guest_segment_descriptor(vcpu, old_tss_sel, &cseg_desc)) |
3527 | goto out; | 3506 | goto out; |
3528 | 3507 | ||
3529 | |||
3530 | if (reason != TASK_SWITCH_IRET) { | 3508 | if (reason != TASK_SWITCH_IRET) { |
3531 | int cpl; | 3509 | int cpl; |
3532 | 3510 | ||
@@ -3544,8 +3522,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason) | |||
3544 | 3522 | ||
3545 | if (reason == TASK_SWITCH_IRET || reason == TASK_SWITCH_JMP) { | 3523 | if (reason == TASK_SWITCH_IRET || reason == TASK_SWITCH_JMP) { |
3546 | cseg_desc.type &= ~(1 << 1); //clear the B flag | 3524 | cseg_desc.type &= ~(1 << 1); //clear the B flag |
3547 | save_guest_segment_descriptor(vcpu, tr_seg.selector, | 3525 | save_guest_segment_descriptor(vcpu, old_tss_sel, &cseg_desc); |
3548 | &cseg_desc); | ||
3549 | } | 3526 | } |
3550 | 3527 | ||
3551 | if (reason == TASK_SWITCH_IRET) { | 3528 | if (reason == TASK_SWITCH_IRET) { |
@@ -3557,10 +3534,10 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason) | |||
3557 | kvm_x86_ops->cache_regs(vcpu); | 3534 | kvm_x86_ops->cache_regs(vcpu); |
3558 | 3535 | ||
3559 | if (nseg_desc.type & 8) | 3536 | if (nseg_desc.type & 8) |
3560 | ret = kvm_task_switch_32(vcpu, tss_selector, &cseg_desc, | 3537 | ret = kvm_task_switch_32(vcpu, tss_selector, old_tss_base, |
3561 | &nseg_desc); | 3538 | &nseg_desc); |
3562 | else | 3539 | else |
3563 | ret = kvm_task_switch_16(vcpu, tss_selector, &cseg_desc, | 3540 | ret = kvm_task_switch_16(vcpu, tss_selector, old_tss_base, |
3564 | &nseg_desc); | 3541 | &nseg_desc); |
3565 | 3542 | ||
3566 | if (reason == TASK_SWITCH_CALL || reason == TASK_SWITCH_GATE) { | 3543 | if (reason == TASK_SWITCH_CALL || reason == TASK_SWITCH_GATE) { |
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index b11943dadefd..681c15f42083 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c | |||
@@ -99,6 +99,9 @@ struct talitos_private { | |||
99 | /* next channel to be assigned next incoming descriptor */ | 99 | /* next channel to be assigned next incoming descriptor */ |
100 | atomic_t last_chan; | 100 | atomic_t last_chan; |
101 | 101 | ||
102 | /* per-channel number of requests pending in channel h/w fifo */ | ||
103 | atomic_t *submit_count; | ||
104 | |||
102 | /* per-channel request fifo */ | 105 | /* per-channel request fifo */ |
103 | struct talitos_request **fifo; | 106 | struct talitos_request **fifo; |
104 | 107 | ||
@@ -263,15 +266,15 @@ static int talitos_submit(struct device *dev, struct talitos_desc *desc, | |||
263 | 266 | ||
264 | spin_lock_irqsave(&priv->head_lock[ch], flags); | 267 | spin_lock_irqsave(&priv->head_lock[ch], flags); |
265 | 268 | ||
266 | head = priv->head[ch]; | 269 | if (!atomic_inc_not_zero(&priv->submit_count[ch])) { |
267 | request = &priv->fifo[ch][head]; | 270 | /* h/w fifo is full */ |
268 | |||
269 | if (request->desc) { | ||
270 | /* request queue is full */ | ||
271 | spin_unlock_irqrestore(&priv->head_lock[ch], flags); | 271 | spin_unlock_irqrestore(&priv->head_lock[ch], flags); |
272 | return -EAGAIN; | 272 | return -EAGAIN; |
273 | } | 273 | } |
274 | 274 | ||
275 | head = priv->head[ch]; | ||
276 | request = &priv->fifo[ch][head]; | ||
277 | |||
275 | /* map descriptor and save caller data */ | 278 | /* map descriptor and save caller data */ |
276 | request->dma_desc = dma_map_single(dev, desc, sizeof(*desc), | 279 | request->dma_desc = dma_map_single(dev, desc, sizeof(*desc), |
277 | DMA_BIDIRECTIONAL); | 280 | DMA_BIDIRECTIONAL); |
@@ -335,6 +338,9 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch) | |||
335 | priv->tail[ch] = (tail + 1) & (priv->fifo_len - 1); | 338 | priv->tail[ch] = (tail + 1) & (priv->fifo_len - 1); |
336 | 339 | ||
337 | spin_unlock_irqrestore(&priv->tail_lock[ch], flags); | 340 | spin_unlock_irqrestore(&priv->tail_lock[ch], flags); |
341 | |||
342 | atomic_dec(&priv->submit_count[ch]); | ||
343 | |||
338 | saved_req.callback(dev, saved_req.desc, saved_req.context, | 344 | saved_req.callback(dev, saved_req.desc, saved_req.context, |
339 | status); | 345 | status); |
340 | /* channel may resume processing in single desc error case */ | 346 | /* channel may resume processing in single desc error case */ |
@@ -842,7 +848,7 @@ static int sg_to_link_tbl(struct scatterlist *sg, int sg_count, | |||
842 | 848 | ||
843 | /* adjust (decrease) last one (or two) entry's len to cryptlen */ | 849 | /* adjust (decrease) last one (or two) entry's len to cryptlen */ |
844 | link_tbl_ptr--; | 850 | link_tbl_ptr--; |
845 | while (link_tbl_ptr->len <= (-cryptlen)) { | 851 | while (be16_to_cpu(link_tbl_ptr->len) <= (-cryptlen)) { |
846 | /* Empty this entry, and move to previous one */ | 852 | /* Empty this entry, and move to previous one */ |
847 | cryptlen += be16_to_cpu(link_tbl_ptr->len); | 853 | cryptlen += be16_to_cpu(link_tbl_ptr->len); |
848 | link_tbl_ptr->len = 0; | 854 | link_tbl_ptr->len = 0; |
@@ -874,7 +880,7 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq, | |||
874 | unsigned int cryptlen = areq->cryptlen; | 880 | unsigned int cryptlen = areq->cryptlen; |
875 | unsigned int authsize = ctx->authsize; | 881 | unsigned int authsize = ctx->authsize; |
876 | unsigned int ivsize; | 882 | unsigned int ivsize; |
877 | int sg_count; | 883 | int sg_count, ret; |
878 | 884 | ||
879 | /* hmac key */ | 885 | /* hmac key */ |
880 | map_single_talitos_ptr(dev, &desc->ptr[0], ctx->authkeylen, &ctx->key, | 886 | map_single_talitos_ptr(dev, &desc->ptr[0], ctx->authkeylen, &ctx->key, |
@@ -978,7 +984,12 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq, | |||
978 | map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv, 0, | 984 | map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv, 0, |
979 | DMA_FROM_DEVICE); | 985 | DMA_FROM_DEVICE); |
980 | 986 | ||
981 | return talitos_submit(dev, desc, callback, areq); | 987 | ret = talitos_submit(dev, desc, callback, areq); |
988 | if (ret != -EINPROGRESS) { | ||
989 | ipsec_esp_unmap(dev, edesc, areq); | ||
990 | kfree(edesc); | ||
991 | } | ||
992 | return ret; | ||
982 | } | 993 | } |
983 | 994 | ||
984 | 995 | ||
@@ -1009,6 +1020,8 @@ static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq, | |||
1009 | struct talitos_ctx *ctx = crypto_aead_ctx(authenc); | 1020 | struct talitos_ctx *ctx = crypto_aead_ctx(authenc); |
1010 | struct ipsec_esp_edesc *edesc; | 1021 | struct ipsec_esp_edesc *edesc; |
1011 | int src_nents, dst_nents, alloc_len, dma_len; | 1022 | int src_nents, dst_nents, alloc_len, dma_len; |
1023 | gfp_t flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : | ||
1024 | GFP_ATOMIC; | ||
1012 | 1025 | ||
1013 | if (areq->cryptlen + ctx->authsize > TALITOS_MAX_DATA_LEN) { | 1026 | if (areq->cryptlen + ctx->authsize > TALITOS_MAX_DATA_LEN) { |
1014 | dev_err(ctx->dev, "cryptlen exceeds h/w max limit\n"); | 1027 | dev_err(ctx->dev, "cryptlen exceeds h/w max limit\n"); |
@@ -1022,7 +1035,7 @@ static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq, | |||
1022 | dst_nents = src_nents; | 1035 | dst_nents = src_nents; |
1023 | } else { | 1036 | } else { |
1024 | dst_nents = sg_count(areq->dst, areq->cryptlen + ctx->authsize); | 1037 | dst_nents = sg_count(areq->dst, areq->cryptlen + ctx->authsize); |
1025 | dst_nents = (dst_nents == 1) ? 0 : src_nents; | 1038 | dst_nents = (dst_nents == 1) ? 0 : dst_nents; |
1026 | } | 1039 | } |
1027 | 1040 | ||
1028 | /* | 1041 | /* |
@@ -1040,7 +1053,7 @@ static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq, | |||
1040 | alloc_len += icv_stashing ? ctx->authsize : 0; | 1053 | alloc_len += icv_stashing ? ctx->authsize : 0; |
1041 | } | 1054 | } |
1042 | 1055 | ||
1043 | edesc = kmalloc(alloc_len, GFP_DMA); | 1056 | edesc = kmalloc(alloc_len, GFP_DMA | flags); |
1044 | if (!edesc) { | 1057 | if (!edesc) { |
1045 | dev_err(ctx->dev, "could not allocate edescriptor\n"); | 1058 | dev_err(ctx->dev, "could not allocate edescriptor\n"); |
1046 | return ERR_PTR(-ENOMEM); | 1059 | return ERR_PTR(-ENOMEM); |
@@ -1337,6 +1350,7 @@ static int __devexit talitos_remove(struct of_device *ofdev) | |||
1337 | if (hw_supports(dev, DESC_HDR_SEL0_RNG)) | 1350 | if (hw_supports(dev, DESC_HDR_SEL0_RNG)) |
1338 | talitos_unregister_rng(dev); | 1351 | talitos_unregister_rng(dev); |
1339 | 1352 | ||
1353 | kfree(priv->submit_count); | ||
1340 | kfree(priv->tail); | 1354 | kfree(priv->tail); |
1341 | kfree(priv->head); | 1355 | kfree(priv->head); |
1342 | 1356 | ||
@@ -1466,9 +1480,6 @@ static int talitos_probe(struct of_device *ofdev, | |||
1466 | goto err_out; | 1480 | goto err_out; |
1467 | } | 1481 | } |
1468 | 1482 | ||
1469 | of_node_put(np); | ||
1470 | np = NULL; | ||
1471 | |||
1472 | priv->head_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels, | 1483 | priv->head_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels, |
1473 | GFP_KERNEL); | 1484 | GFP_KERNEL); |
1474 | priv->tail_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels, | 1485 | priv->tail_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels, |
@@ -1504,6 +1515,16 @@ static int talitos_probe(struct of_device *ofdev, | |||
1504 | } | 1515 | } |
1505 | } | 1516 | } |
1506 | 1517 | ||
1518 | priv->submit_count = kmalloc(sizeof(atomic_t) * priv->num_channels, | ||
1519 | GFP_KERNEL); | ||
1520 | if (!priv->submit_count) { | ||
1521 | dev_err(dev, "failed to allocate fifo submit count space\n"); | ||
1522 | err = -ENOMEM; | ||
1523 | goto err_out; | ||
1524 | } | ||
1525 | for (i = 0; i < priv->num_channels; i++) | ||
1526 | atomic_set(&priv->submit_count[i], -priv->chfifo_len); | ||
1527 | |||
1507 | priv->head = kzalloc(sizeof(int) * priv->num_channels, GFP_KERNEL); | 1528 | priv->head = kzalloc(sizeof(int) * priv->num_channels, GFP_KERNEL); |
1508 | priv->tail = kzalloc(sizeof(int) * priv->num_channels, GFP_KERNEL); | 1529 | priv->tail = kzalloc(sizeof(int) * priv->num_channels, GFP_KERNEL); |
1509 | if (!priv->head || !priv->tail) { | 1530 | if (!priv->head || !priv->tail) { |
@@ -1559,8 +1580,6 @@ static int talitos_probe(struct of_device *ofdev, | |||
1559 | 1580 | ||
1560 | err_out: | 1581 | err_out: |
1561 | talitos_remove(ofdev); | 1582 | talitos_remove(ofdev); |
1562 | if (np) | ||
1563 | of_node_put(np); | ||
1564 | 1583 | ||
1565 | return err; | 1584 | return err; |
1566 | } | 1585 | } |
diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig index 76f26710fc16..fa6d6abefd4d 100644 --- a/drivers/firewire/Kconfig +++ b/drivers/firewire/Kconfig | |||
@@ -16,8 +16,13 @@ config FIREWIRE | |||
16 | enable the new stack. | 16 | enable the new stack. |
17 | 17 | ||
18 | To compile this driver as a module, say M here: the module will be | 18 | To compile this driver as a module, say M here: the module will be |
19 | called firewire-core. It functionally replaces ieee1394, raw1394, | 19 | called firewire-core. |
20 | and video1394. | 20 | |
21 | This module functionally replaces ieee1394, raw1394, and video1394. | ||
22 | To access it from application programs, you generally need at least | ||
23 | libraw1394 version 2. IIDC/DCAM applications also need libdc1394 | ||
24 | version 2. No libraries are required to access storage devices | ||
25 | through the firewire-sbp2 driver. | ||
21 | 26 | ||
22 | config FIREWIRE_OHCI | 27 | config FIREWIRE_OHCI |
23 | tristate "OHCI-1394 controllers" | 28 | tristate "OHCI-1394 controllers" |
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index da873d795aad..bbd73a406e53 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c | |||
@@ -539,7 +539,7 @@ fw_core_remove_card(struct fw_card *card) | |||
539 | wait_for_completion(&card->done); | 539 | wait_for_completion(&card->done); |
540 | 540 | ||
541 | cancel_delayed_work_sync(&card->work); | 541 | cancel_delayed_work_sync(&card->work); |
542 | fw_flush_transactions(card); | 542 | WARN_ON(!list_empty(&card->transaction_list)); |
543 | del_timer_sync(&card->flush_timer); | 543 | del_timer_sync(&card->flush_timer); |
544 | } | 544 | } |
545 | EXPORT_SYMBOL(fw_core_remove_card); | 545 | EXPORT_SYMBOL(fw_core_remove_card); |
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index c639915fc3cb..bc81d6fcd2fd 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/fw-cdev.c | |||
@@ -382,9 +382,9 @@ complete_transaction(struct fw_card *card, int rcode, | |||
382 | 382 | ||
383 | response->response.type = FW_CDEV_EVENT_RESPONSE; | 383 | response->response.type = FW_CDEV_EVENT_RESPONSE; |
384 | response->response.rcode = rcode; | 384 | response->response.rcode = rcode; |
385 | queue_event(client, &response->event, | 385 | queue_event(client, &response->event, &response->response, |
386 | &response->response, sizeof(response->response), | 386 | sizeof(response->response) + response->response.length, |
387 | response->response.data, response->response.length); | 387 | NULL, 0); |
388 | } | 388 | } |
389 | 389 | ||
390 | static int ioctl_send_request(struct client *client, void *buffer) | 390 | static int ioctl_send_request(struct client *client, void *buffer) |
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 566672e0bcff..251416f2148f 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c | |||
@@ -171,7 +171,6 @@ struct iso_context { | |||
171 | struct fw_ohci { | 171 | struct fw_ohci { |
172 | struct fw_card card; | 172 | struct fw_card card; |
173 | 173 | ||
174 | u32 version; | ||
175 | __iomem char *registers; | 174 | __iomem char *registers; |
176 | dma_addr_t self_id_bus; | 175 | dma_addr_t self_id_bus; |
177 | __le32 *self_id_cpu; | 176 | __le32 *self_id_cpu; |
@@ -180,6 +179,8 @@ struct fw_ohci { | |||
180 | int generation; | 179 | int generation; |
181 | int request_generation; /* for timestamping incoming requests */ | 180 | int request_generation; /* for timestamping incoming requests */ |
182 | u32 bus_seconds; | 181 | u32 bus_seconds; |
182 | |||
183 | bool use_dualbuffer; | ||
183 | bool old_uninorth; | 184 | bool old_uninorth; |
184 | bool bus_reset_packet_quirk; | 185 | bool bus_reset_packet_quirk; |
185 | 186 | ||
@@ -1885,7 +1886,7 @@ ohci_allocate_iso_context(struct fw_card *card, int type, size_t header_size) | |||
1885 | } else { | 1886 | } else { |
1886 | mask = &ohci->ir_context_mask; | 1887 | mask = &ohci->ir_context_mask; |
1887 | list = ohci->ir_context_list; | 1888 | list = ohci->ir_context_list; |
1888 | if (ohci->version >= OHCI_VERSION_1_1) | 1889 | if (ohci->use_dualbuffer) |
1889 | callback = handle_ir_dualbuffer_packet; | 1890 | callback = handle_ir_dualbuffer_packet; |
1890 | else | 1891 | else |
1891 | callback = handle_ir_packet_per_buffer; | 1892 | callback = handle_ir_packet_per_buffer; |
@@ -1949,7 +1950,7 @@ static int ohci_start_iso(struct fw_iso_context *base, | |||
1949 | } else { | 1950 | } else { |
1950 | index = ctx - ohci->ir_context_list; | 1951 | index = ctx - ohci->ir_context_list; |
1951 | control = IR_CONTEXT_ISOCH_HEADER; | 1952 | control = IR_CONTEXT_ISOCH_HEADER; |
1952 | if (ohci->version >= OHCI_VERSION_1_1) | 1953 | if (ohci->use_dualbuffer) |
1953 | control |= IR_CONTEXT_DUAL_BUFFER_MODE; | 1954 | control |= IR_CONTEXT_DUAL_BUFFER_MODE; |
1954 | match = (tags << 28) | (sync << 8) | ctx->base.channel; | 1955 | match = (tags << 28) | (sync << 8) | ctx->base.channel; |
1955 | if (cycle >= 0) { | 1956 | if (cycle >= 0) { |
@@ -2279,7 +2280,7 @@ ohci_queue_iso(struct fw_iso_context *base, | |||
2279 | spin_lock_irqsave(&ctx->context.ohci->lock, flags); | 2280 | spin_lock_irqsave(&ctx->context.ohci->lock, flags); |
2280 | if (base->type == FW_ISO_CONTEXT_TRANSMIT) | 2281 | if (base->type == FW_ISO_CONTEXT_TRANSMIT) |
2281 | retval = ohci_queue_iso_transmit(base, packet, buffer, payload); | 2282 | retval = ohci_queue_iso_transmit(base, packet, buffer, payload); |
2282 | else if (ctx->context.ohci->version >= OHCI_VERSION_1_1) | 2283 | else if (ctx->context.ohci->use_dualbuffer) |
2283 | retval = ohci_queue_iso_receive_dualbuffer(base, packet, | 2284 | retval = ohci_queue_iso_receive_dualbuffer(base, packet, |
2284 | buffer, payload); | 2285 | buffer, payload); |
2285 | else | 2286 | else |
@@ -2341,7 +2342,7 @@ static int __devinit | |||
2341 | pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | 2342 | pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) |
2342 | { | 2343 | { |
2343 | struct fw_ohci *ohci; | 2344 | struct fw_ohci *ohci; |
2344 | u32 bus_options, max_receive, link_speed; | 2345 | u32 bus_options, max_receive, link_speed, version; |
2345 | u64 guid; | 2346 | u64 guid; |
2346 | int err; | 2347 | int err; |
2347 | size_t size; | 2348 | size_t size; |
@@ -2366,12 +2367,6 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
2366 | pci_write_config_dword(dev, OHCI1394_PCI_HCI_Control, 0); | 2367 | pci_write_config_dword(dev, OHCI1394_PCI_HCI_Control, 0); |
2367 | pci_set_drvdata(dev, ohci); | 2368 | pci_set_drvdata(dev, ohci); |
2368 | 2369 | ||
2369 | #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) | ||
2370 | ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE && | ||
2371 | dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW; | ||
2372 | #endif | ||
2373 | ohci->bus_reset_packet_quirk = dev->vendor == PCI_VENDOR_ID_TI; | ||
2374 | |||
2375 | spin_lock_init(&ohci->lock); | 2370 | spin_lock_init(&ohci->lock); |
2376 | 2371 | ||
2377 | tasklet_init(&ohci->bus_reset_tasklet, | 2372 | tasklet_init(&ohci->bus_reset_tasklet, |
@@ -2390,6 +2385,23 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
2390 | goto fail_iomem; | 2385 | goto fail_iomem; |
2391 | } | 2386 | } |
2392 | 2387 | ||
2388 | version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; | ||
2389 | ohci->use_dualbuffer = version >= OHCI_VERSION_1_1; | ||
2390 | |||
2391 | /* x86-32 currently doesn't use highmem for dma_alloc_coherent */ | ||
2392 | #if !defined(CONFIG_X86_32) | ||
2393 | /* dual-buffer mode is broken with descriptor addresses above 2G */ | ||
2394 | if (dev->vendor == PCI_VENDOR_ID_TI && | ||
2395 | dev->device == PCI_DEVICE_ID_TI_TSB43AB22) | ||
2396 | ohci->use_dualbuffer = false; | ||
2397 | #endif | ||
2398 | |||
2399 | #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) | ||
2400 | ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE && | ||
2401 | dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW; | ||
2402 | #endif | ||
2403 | ohci->bus_reset_packet_quirk = dev->vendor == PCI_VENDOR_ID_TI; | ||
2404 | |||
2393 | ar_context_init(&ohci->ar_request_ctx, ohci, | 2405 | ar_context_init(&ohci->ar_request_ctx, ohci, |
2394 | OHCI1394_AsReqRcvContextControlSet); | 2406 | OHCI1394_AsReqRcvContextControlSet); |
2395 | 2407 | ||
@@ -2441,9 +2453,8 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
2441 | if (err < 0) | 2453 | if (err < 0) |
2442 | goto fail_self_id; | 2454 | goto fail_self_id; |
2443 | 2455 | ||
2444 | ohci->version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; | ||
2445 | fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n", | 2456 | fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n", |
2446 | dev->dev.bus_id, ohci->version >> 16, ohci->version & 0xff); | 2457 | dev->dev.bus_id, version >> 16, version & 0xff); |
2447 | return 0; | 2458 | return 0; |
2448 | 2459 | ||
2449 | fail_self_id: | 2460 | fail_self_id: |
diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c index 213b0ff8f3d6..c1b81077c4a8 100644 --- a/drivers/firewire/fw-topology.c +++ b/drivers/firewire/fw-topology.c | |||
@@ -510,8 +510,6 @@ fw_core_handle_bus_reset(struct fw_card *card, | |||
510 | struct fw_node *local_node; | 510 | struct fw_node *local_node; |
511 | unsigned long flags; | 511 | unsigned long flags; |
512 | 512 | ||
513 | fw_flush_transactions(card); | ||
514 | |||
515 | spin_lock_irqsave(&card->lock, flags); | 513 | spin_lock_irqsave(&card->lock, flags); |
516 | 514 | ||
517 | /* | 515 | /* |
diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c index 40db80752272..e5d1a0b64fcf 100644 --- a/drivers/firewire/fw-transaction.c +++ b/drivers/firewire/fw-transaction.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/kref.h> | 23 | #include <linux/kref.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/mutex.h> | ||
25 | #include <linux/init.h> | 26 | #include <linux/init.h> |
26 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
27 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
@@ -151,7 +152,7 @@ transmit_complete_callback(struct fw_packet *packet, | |||
151 | 152 | ||
152 | static void | 153 | static void |
153 | fw_fill_request(struct fw_packet *packet, int tcode, int tlabel, | 154 | fw_fill_request(struct fw_packet *packet, int tcode, int tlabel, |
154 | int node_id, int source_id, int generation, int speed, | 155 | int destination_id, int source_id, int generation, int speed, |
155 | unsigned long long offset, void *payload, size_t length) | 156 | unsigned long long offset, void *payload, size_t length) |
156 | { | 157 | { |
157 | int ext_tcode; | 158 | int ext_tcode; |
@@ -166,7 +167,7 @@ fw_fill_request(struct fw_packet *packet, int tcode, int tlabel, | |||
166 | HEADER_RETRY(RETRY_X) | | 167 | HEADER_RETRY(RETRY_X) | |
167 | HEADER_TLABEL(tlabel) | | 168 | HEADER_TLABEL(tlabel) | |
168 | HEADER_TCODE(tcode) | | 169 | HEADER_TCODE(tcode) | |
169 | HEADER_DESTINATION(node_id); | 170 | HEADER_DESTINATION(destination_id); |
170 | packet->header[1] = | 171 | packet->header[1] = |
171 | HEADER_OFFSET_HIGH(offset >> 32) | HEADER_SOURCE(source_id); | 172 | HEADER_OFFSET_HIGH(offset >> 32) | HEADER_SOURCE(source_id); |
172 | packet->header[2] = | 173 | packet->header[2] = |
@@ -252,7 +253,7 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t, | |||
252 | fw_transaction_callback_t callback, void *callback_data) | 253 | fw_transaction_callback_t callback, void *callback_data) |
253 | { | 254 | { |
254 | unsigned long flags; | 255 | unsigned long flags; |
255 | int tlabel, source; | 256 | int tlabel; |
256 | 257 | ||
257 | /* | 258 | /* |
258 | * Bump the flush timer up 100ms first of all so we | 259 | * Bump the flush timer up 100ms first of all so we |
@@ -268,7 +269,6 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t, | |||
268 | 269 | ||
269 | spin_lock_irqsave(&card->lock, flags); | 270 | spin_lock_irqsave(&card->lock, flags); |
270 | 271 | ||
271 | source = card->node_id; | ||
272 | tlabel = card->current_tlabel; | 272 | tlabel = card->current_tlabel; |
273 | if (card->tlabel_mask & (1 << tlabel)) { | 273 | if (card->tlabel_mask & (1 << tlabel)) { |
274 | spin_unlock_irqrestore(&card->lock, flags); | 274 | spin_unlock_irqrestore(&card->lock, flags); |
@@ -279,77 +279,58 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t, | |||
279 | card->current_tlabel = (card->current_tlabel + 1) & 0x1f; | 279 | card->current_tlabel = (card->current_tlabel + 1) & 0x1f; |
280 | card->tlabel_mask |= (1 << tlabel); | 280 | card->tlabel_mask |= (1 << tlabel); |
281 | 281 | ||
282 | list_add_tail(&t->link, &card->transaction_list); | ||
283 | |||
284 | spin_unlock_irqrestore(&card->lock, flags); | ||
285 | |||
286 | /* Initialize rest of transaction, fill out packet and send it. */ | ||
287 | t->node_id = node_id; | 282 | t->node_id = node_id; |
288 | t->tlabel = tlabel; | 283 | t->tlabel = tlabel; |
289 | t->callback = callback; | 284 | t->callback = callback; |
290 | t->callback_data = callback_data; | 285 | t->callback_data = callback_data; |
291 | 286 | ||
292 | fw_fill_request(&t->packet, tcode, t->tlabel, | 287 | fw_fill_request(&t->packet, tcode, t->tlabel, node_id, card->node_id, |
293 | node_id, source, generation, | 288 | generation, speed, offset, payload, length); |
294 | speed, offset, payload, length); | ||
295 | t->packet.callback = transmit_complete_callback; | 289 | t->packet.callback = transmit_complete_callback; |
296 | 290 | ||
291 | list_add_tail(&t->link, &card->transaction_list); | ||
292 | |||
293 | spin_unlock_irqrestore(&card->lock, flags); | ||
294 | |||
297 | card->driver->send_request(card, &t->packet); | 295 | card->driver->send_request(card, &t->packet); |
298 | } | 296 | } |
299 | EXPORT_SYMBOL(fw_send_request); | 297 | EXPORT_SYMBOL(fw_send_request); |
300 | 298 | ||
301 | struct fw_phy_packet { | 299 | static DEFINE_MUTEX(phy_config_mutex); |
302 | struct fw_packet packet; | 300 | static DECLARE_COMPLETION(phy_config_done); |
303 | struct completion done; | ||
304 | struct kref kref; | ||
305 | }; | ||
306 | |||
307 | static void phy_packet_release(struct kref *kref) | ||
308 | { | ||
309 | struct fw_phy_packet *p = | ||
310 | container_of(kref, struct fw_phy_packet, kref); | ||
311 | kfree(p); | ||
312 | } | ||
313 | 301 | ||
314 | static void transmit_phy_packet_callback(struct fw_packet *packet, | 302 | static void transmit_phy_packet_callback(struct fw_packet *packet, |
315 | struct fw_card *card, int status) | 303 | struct fw_card *card, int status) |
316 | { | 304 | { |
317 | struct fw_phy_packet *p = | 305 | complete(&phy_config_done); |
318 | container_of(packet, struct fw_phy_packet, packet); | ||
319 | |||
320 | complete(&p->done); | ||
321 | kref_put(&p->kref, phy_packet_release); | ||
322 | } | 306 | } |
323 | 307 | ||
308 | static struct fw_packet phy_config_packet = { | ||
309 | .header_length = 8, | ||
310 | .payload_length = 0, | ||
311 | .speed = SCODE_100, | ||
312 | .callback = transmit_phy_packet_callback, | ||
313 | }; | ||
314 | |||
324 | void fw_send_phy_config(struct fw_card *card, | 315 | void fw_send_phy_config(struct fw_card *card, |
325 | int node_id, int generation, int gap_count) | 316 | int node_id, int generation, int gap_count) |
326 | { | 317 | { |
327 | struct fw_phy_packet *p; | ||
328 | long timeout = DIV_ROUND_UP(HZ, 10); | 318 | long timeout = DIV_ROUND_UP(HZ, 10); |
329 | u32 data = PHY_IDENTIFIER(PHY_PACKET_CONFIG) | | 319 | u32 data = PHY_IDENTIFIER(PHY_PACKET_CONFIG) | |
330 | PHY_CONFIG_ROOT_ID(node_id) | | 320 | PHY_CONFIG_ROOT_ID(node_id) | |
331 | PHY_CONFIG_GAP_COUNT(gap_count); | 321 | PHY_CONFIG_GAP_COUNT(gap_count); |
332 | 322 | ||
333 | p = kmalloc(sizeof(*p), GFP_KERNEL); | 323 | mutex_lock(&phy_config_mutex); |
334 | if (p == NULL) | 324 | |
335 | return; | 325 | phy_config_packet.header[0] = data; |
326 | phy_config_packet.header[1] = ~data; | ||
327 | phy_config_packet.generation = generation; | ||
328 | INIT_COMPLETION(phy_config_done); | ||
329 | |||
330 | card->driver->send_request(card, &phy_config_packet); | ||
331 | wait_for_completion_timeout(&phy_config_done, timeout); | ||
336 | 332 | ||
337 | p->packet.header[0] = data; | 333 | mutex_unlock(&phy_config_mutex); |
338 | p->packet.header[1] = ~data; | ||
339 | p->packet.header_length = 8; | ||
340 | p->packet.payload_length = 0; | ||
341 | p->packet.speed = SCODE_100; | ||
342 | p->packet.generation = generation; | ||
343 | p->packet.callback = transmit_phy_packet_callback; | ||
344 | init_completion(&p->done); | ||
345 | kref_set(&p->kref, 2); | ||
346 | |||
347 | card->driver->send_request(card, &p->packet); | ||
348 | timeout = wait_for_completion_timeout(&p->done, timeout); | ||
349 | kref_put(&p->kref, phy_packet_release); | ||
350 | |||
351 | /* will leak p if the callback is never executed */ | ||
352 | WARN_ON(timeout == 0); | ||
353 | } | 334 | } |
354 | 335 | ||
355 | void fw_flush_transactions(struct fw_card *card) | 336 | void fw_flush_transactions(struct fw_card *card) |
diff --git a/drivers/isdn/hardware/mISDN/Kconfig b/drivers/isdn/hardware/mISDN/Kconfig index 14793480c453..9cd5f5f62280 100644 --- a/drivers/isdn/hardware/mISDN/Kconfig +++ b/drivers/isdn/hardware/mISDN/Kconfig | |||
@@ -7,6 +7,7 @@ config MISDN_HFCPCI | |||
7 | tristate "Support for HFC PCI cards" | 7 | tristate "Support for HFC PCI cards" |
8 | depends on MISDN | 8 | depends on MISDN |
9 | depends on PCI | 9 | depends on PCI |
10 | depends on VIRT_TO_BUS | ||
10 | help | 11 | help |
11 | Enable support for cards with Cologne Chip AG's | 12 | Enable support for cards with Cologne Chip AG's |
12 | HFC PCI chip. | 13 | HFC PCI chip. |
diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c index f5ad888ee71e..a7915a156c04 100644 --- a/drivers/isdn/mISDN/layer2.c +++ b/drivers/isdn/mISDN/layer2.c | |||
@@ -2030,7 +2030,7 @@ release_l2(struct layer2 *l2) | |||
2030 | skb_queue_purge(&l2->down_queue); | 2030 | skb_queue_purge(&l2->down_queue); |
2031 | ReleaseWin(l2); | 2031 | ReleaseWin(l2); |
2032 | if (test_bit(FLG_LAPD, &l2->flag)) { | 2032 | if (test_bit(FLG_LAPD, &l2->flag)) { |
2033 | release_tei(l2); | 2033 | TEIrelease(l2); |
2034 | if (l2->ch.st) | 2034 | if (l2->ch.st) |
2035 | l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D, | 2035 | l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D, |
2036 | CLOSE_CHANNEL, NULL); | 2036 | CLOSE_CHANNEL, NULL); |
diff --git a/drivers/isdn/mISDN/layer2.h b/drivers/isdn/mISDN/layer2.h index de2dd02056a3..6293f80dc2d3 100644 --- a/drivers/isdn/mISDN/layer2.h +++ b/drivers/isdn/mISDN/layer2.h | |||
@@ -96,7 +96,7 @@ extern int tei_l2(struct layer2 *, u_int, u_long arg); | |||
96 | 96 | ||
97 | /* from tei.c */ | 97 | /* from tei.c */ |
98 | extern int l2_tei(struct layer2 *, u_int, u_long arg); | 98 | extern int l2_tei(struct layer2 *, u_int, u_long arg); |
99 | extern void release_tei(struct layer2 *); | 99 | extern void TEIrelease(struct layer2 *); |
100 | extern int TEIInit(u_int *); | 100 | extern int TEIInit(u_int *); |
101 | extern void TEIFree(void); | 101 | extern void TEIFree(void); |
102 | 102 | ||
diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c index 56a76a0ffddd..6fbae42127bf 100644 --- a/drivers/isdn/mISDN/tei.c +++ b/drivers/isdn/mISDN/tei.c | |||
@@ -945,7 +945,7 @@ l2_tei(struct layer2 *l2, u_int cmd, u_long arg) | |||
945 | } | 945 | } |
946 | 946 | ||
947 | void | 947 | void |
948 | release_tei(struct layer2 *l2) | 948 | TEIrelease(struct layer2 *l2) |
949 | { | 949 | { |
950 | struct teimgr *tm = l2->tm; | 950 | struct teimgr *tm = l2->tm; |
951 | u_long flags; | 951 | u_long flags; |
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index fea966d66f98..71dd65aa31b6 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -147,9 +147,12 @@ static struct priority_group *alloc_priority_group(void) | |||
147 | static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti) | 147 | static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti) |
148 | { | 148 | { |
149 | struct pgpath *pgpath, *tmp; | 149 | struct pgpath *pgpath, *tmp; |
150 | struct multipath *m = ti->private; | ||
150 | 151 | ||
151 | list_for_each_entry_safe(pgpath, tmp, pgpaths, list) { | 152 | list_for_each_entry_safe(pgpath, tmp, pgpaths, list) { |
152 | list_del(&pgpath->list); | 153 | list_del(&pgpath->list); |
154 | if (m->hw_handler_name) | ||
155 | scsi_dh_detach(bdev_get_queue(pgpath->path.dev->bdev)); | ||
153 | dm_put_device(ti, pgpath->path.dev); | 156 | dm_put_device(ti, pgpath->path.dev); |
154 | free_pgpath(pgpath); | 157 | free_pgpath(pgpath); |
155 | } | 158 | } |
@@ -548,6 +551,7 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps, | |||
548 | { | 551 | { |
549 | int r; | 552 | int r; |
550 | struct pgpath *p; | 553 | struct pgpath *p; |
554 | struct multipath *m = ti->private; | ||
551 | 555 | ||
552 | /* we need at least a path arg */ | 556 | /* we need at least a path arg */ |
553 | if (as->argc < 1) { | 557 | if (as->argc < 1) { |
@@ -566,6 +570,15 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps, | |||
566 | goto bad; | 570 | goto bad; |
567 | } | 571 | } |
568 | 572 | ||
573 | if (m->hw_handler_name) { | ||
574 | r = scsi_dh_attach(bdev_get_queue(p->path.dev->bdev), | ||
575 | m->hw_handler_name); | ||
576 | if (r < 0) { | ||
577 | dm_put_device(ti, p->path.dev); | ||
578 | goto bad; | ||
579 | } | ||
580 | } | ||
581 | |||
569 | r = ps->type->add_path(ps, &p->path, as->argc, as->argv, &ti->error); | 582 | r = ps->type->add_path(ps, &p->path, as->argc, as->argv, &ti->error); |
570 | if (r) { | 583 | if (r) { |
571 | dm_put_device(ti, p->path.dev); | 584 | dm_put_device(ti, p->path.dev); |
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 34402c47027e..d6a0074b9dc3 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -273,12 +273,12 @@ mpt_fault_reset_work(struct work_struct *work) | |||
273 | ioc_raw_state = mpt_GetIocState(ioc, 0); | 273 | ioc_raw_state = mpt_GetIocState(ioc, 0); |
274 | if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) { | 274 | if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) { |
275 | printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n", | 275 | printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n", |
276 | ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK); | 276 | ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK); |
277 | printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n", | 277 | printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n", |
278 | ioc->name, __FUNCTION__); | 278 | ioc->name, __func__); |
279 | rc = mpt_HardResetHandler(ioc, CAN_SLEEP); | 279 | rc = mpt_HardResetHandler(ioc, CAN_SLEEP); |
280 | printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name, | 280 | printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name, |
281 | __FUNCTION__, (rc == 0) ? "success" : "failed"); | 281 | __func__, (rc == 0) ? "success" : "failed"); |
282 | ioc_raw_state = mpt_GetIocState(ioc, 0); | 282 | ioc_raw_state = mpt_GetIocState(ioc, 0); |
283 | if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) | 283 | if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) |
284 | printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after " | 284 | printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after " |
@@ -356,7 +356,7 @@ mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa) | |||
356 | if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || | 356 | if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || |
357 | MptCallbacks[cb_idx] == NULL) { | 357 | MptCallbacks[cb_idx] == NULL) { |
358 | printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", | 358 | printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", |
359 | __FUNCTION__, ioc->name, cb_idx); | 359 | __func__, ioc->name, cb_idx); |
360 | goto out; | 360 | goto out; |
361 | } | 361 | } |
362 | 362 | ||
@@ -420,7 +420,7 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa) | |||
420 | if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || | 420 | if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || |
421 | MptCallbacks[cb_idx] == NULL) { | 421 | MptCallbacks[cb_idx] == NULL) { |
422 | printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", | 422 | printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", |
423 | __FUNCTION__, ioc->name, cb_idx); | 423 | __func__, ioc->name, cb_idx); |
424 | freeme = 0; | 424 | freeme = 0; |
425 | goto out; | 425 | goto out; |
426 | } | 426 | } |
@@ -2434,7 +2434,7 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) | |||
2434 | 2434 | ||
2435 | if (ioc->cached_fw != NULL) { | 2435 | if (ioc->cached_fw != NULL) { |
2436 | ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto " | 2436 | ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto " |
2437 | "adapter\n", __FUNCTION__, ioc->name)); | 2437 | "adapter\n", __func__, ioc->name)); |
2438 | if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *) | 2438 | if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *) |
2439 | ioc->cached_fw, CAN_SLEEP)) < 0) { | 2439 | ioc->cached_fw, CAN_SLEEP)) < 0) { |
2440 | printk(MYIOC_s_WARN_FMT | 2440 | printk(MYIOC_s_WARN_FMT |
@@ -3693,7 +3693,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) | |||
3693 | 3693 | ||
3694 | if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { | 3694 | if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { |
3695 | drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset " | 3695 | drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset " |
3696 | "address=%p\n", ioc->name, __FUNCTION__, | 3696 | "address=%p\n", ioc->name, __func__, |
3697 | &ioc->chip->Doorbell, &ioc->chip->Reset_1078)); | 3697 | &ioc->chip->Doorbell, &ioc->chip->Reset_1078)); |
3698 | CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07); | 3698 | CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07); |
3699 | if (sleepFlag == CAN_SLEEP) | 3699 | if (sleepFlag == CAN_SLEEP) |
@@ -4742,12 +4742,12 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode) | |||
4742 | break; | 4742 | break; |
4743 | } | 4743 | } |
4744 | 4744 | ||
4745 | printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode); | 4745 | printk("%s: persist_opcode=%x\n",__func__, persist_opcode); |
4746 | 4746 | ||
4747 | /* Get a MF for this command. | 4747 | /* Get a MF for this command. |
4748 | */ | 4748 | */ |
4749 | if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { | 4749 | if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { |
4750 | printk("%s: no msg frames!\n",__FUNCTION__); | 4750 | printk("%s: no msg frames!\n",__func__); |
4751 | return -1; | 4751 | return -1; |
4752 | } | 4752 | } |
4753 | 4753 | ||
@@ -4771,13 +4771,13 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode) | |||
4771 | (SasIoUnitControlReply_t *)ioc->persist_reply_frame; | 4771 | (SasIoUnitControlReply_t *)ioc->persist_reply_frame; |
4772 | if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) { | 4772 | if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) { |
4773 | printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", | 4773 | printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", |
4774 | __FUNCTION__, | 4774 | __func__, |
4775 | sasIoUnitCntrReply->IOCStatus, | 4775 | sasIoUnitCntrReply->IOCStatus, |
4776 | sasIoUnitCntrReply->IOCLogInfo); | 4776 | sasIoUnitCntrReply->IOCLogInfo); |
4777 | return -1; | 4777 | return -1; |
4778 | } | 4778 | } |
4779 | 4779 | ||
4780 | printk("%s: success\n",__FUNCTION__); | 4780 | printk("%s: success\n",__func__); |
4781 | return 0; | 4781 | return 0; |
4782 | } | 4782 | } |
4783 | 4783 | ||
@@ -5784,7 +5784,7 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp) | |||
5784 | 5784 | ||
5785 | if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { | 5785 | if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { |
5786 | dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n", | 5786 | dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n", |
5787 | ioc->name,__FUNCTION__)); | 5787 | ioc->name,__func__)); |
5788 | return -1; | 5788 | return -1; |
5789 | } | 5789 | } |
5790 | 5790 | ||
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index a5920423e2b2..f5233f3d9eff 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c | |||
@@ -505,7 +505,7 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | |||
505 | event = le32_to_cpu(pEvReply->Event) & 0xFF; | 505 | event = le32_to_cpu(pEvReply->Event) & 0xFF; |
506 | 506 | ||
507 | dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s() called\n", | 507 | dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s() called\n", |
508 | ioc->name, __FUNCTION__)); | 508 | ioc->name, __func__)); |
509 | if(async_queue == NULL) | 509 | if(async_queue == NULL) |
510 | return 1; | 510 | return 1; |
511 | 511 | ||
@@ -2482,7 +2482,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) | |||
2482 | */ | 2482 | */ |
2483 | if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) { | 2483 | if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) { |
2484 | dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n", | 2484 | dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n", |
2485 | ioc->name,__FUNCTION__)); | 2485 | ioc->name,__func__)); |
2486 | goto out; | 2486 | goto out; |
2487 | } | 2487 | } |
2488 | 2488 | ||
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index b36cae9ec6db..c3c24fdf9fb6 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
@@ -231,28 +231,28 @@ static int | |||
231 | mptfc_abort(struct scsi_cmnd *SCpnt) | 231 | mptfc_abort(struct scsi_cmnd *SCpnt) |
232 | { | 232 | { |
233 | return | 233 | return |
234 | mptfc_block_error_handler(SCpnt, mptscsih_abort, __FUNCTION__); | 234 | mptfc_block_error_handler(SCpnt, mptscsih_abort, __func__); |
235 | } | 235 | } |
236 | 236 | ||
237 | static int | 237 | static int |
238 | mptfc_dev_reset(struct scsi_cmnd *SCpnt) | 238 | mptfc_dev_reset(struct scsi_cmnd *SCpnt) |
239 | { | 239 | { |
240 | return | 240 | return |
241 | mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __FUNCTION__); | 241 | mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __func__); |
242 | } | 242 | } |
243 | 243 | ||
244 | static int | 244 | static int |
245 | mptfc_bus_reset(struct scsi_cmnd *SCpnt) | 245 | mptfc_bus_reset(struct scsi_cmnd *SCpnt) |
246 | { | 246 | { |
247 | return | 247 | return |
248 | mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __FUNCTION__); | 248 | mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __func__); |
249 | } | 249 | } |
250 | 250 | ||
251 | static int | 251 | static int |
252 | mptfc_host_reset(struct scsi_cmnd *SCpnt) | 252 | mptfc_host_reset(struct scsi_cmnd *SCpnt) |
253 | { | 253 | { |
254 | return | 254 | return |
255 | mptfc_block_error_handler(SCpnt, mptscsih_host_reset, __FUNCTION__); | 255 | mptfc_block_error_handler(SCpnt, mptscsih_host_reset, __func__); |
256 | } | 256 | } |
257 | 257 | ||
258 | static void | 258 | static void |
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index d709d92b7b30..a1abf95cf751 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c | |||
@@ -610,7 +610,7 @@ mpt_lan_send_turbo(struct net_device *dev, u32 tmsg) | |||
610 | 610 | ||
611 | dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, skb %p sent.\n", | 611 | dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, skb %p sent.\n", |
612 | IOC_AND_NETDEV_NAMES_s_s(dev), | 612 | IOC_AND_NETDEV_NAMES_s_s(dev), |
613 | __FUNCTION__, sent)); | 613 | __func__, sent)); |
614 | 614 | ||
615 | priv->SendCtl[ctx].skb = NULL; | 615 | priv->SendCtl[ctx].skb = NULL; |
616 | pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[ctx].dma, | 616 | pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[ctx].dma, |
@@ -676,7 +676,7 @@ mpt_lan_send_reply(struct net_device *dev, LANSendReply_t *pSendRep) | |||
676 | 676 | ||
677 | dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, skb %p sent.\n", | 677 | dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, skb %p sent.\n", |
678 | IOC_AND_NETDEV_NAMES_s_s(dev), | 678 | IOC_AND_NETDEV_NAMES_s_s(dev), |
679 | __FUNCTION__, sent)); | 679 | __func__, sent)); |
680 | 680 | ||
681 | priv->SendCtl[ctx].skb = NULL; | 681 | priv->SendCtl[ctx].skb = NULL; |
682 | pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[ctx].dma, | 682 | pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[ctx].dma, |
@@ -715,7 +715,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) | |||
715 | u16 cur_naa = 0x1000; | 715 | u16 cur_naa = 0x1000; |
716 | 716 | ||
717 | dioprintk((KERN_INFO MYNAM ": %s called, skb_addr = %p\n", | 717 | dioprintk((KERN_INFO MYNAM ": %s called, skb_addr = %p\n", |
718 | __FUNCTION__, skb)); | 718 | __func__, skb)); |
719 | 719 | ||
720 | spin_lock_irqsave(&priv->txfidx_lock, flags); | 720 | spin_lock_irqsave(&priv->txfidx_lock, flags); |
721 | if (priv->mpt_txfidx_tail < 0) { | 721 | if (priv->mpt_txfidx_tail < 0) { |
@@ -723,7 +723,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) | |||
723 | spin_unlock_irqrestore(&priv->txfidx_lock, flags); | 723 | spin_unlock_irqrestore(&priv->txfidx_lock, flags); |
724 | 724 | ||
725 | printk (KERN_ERR "%s: no tx context available: %u\n", | 725 | printk (KERN_ERR "%s: no tx context available: %u\n", |
726 | __FUNCTION__, priv->mpt_txfidx_tail); | 726 | __func__, priv->mpt_txfidx_tail); |
727 | return 1; | 727 | return 1; |
728 | } | 728 | } |
729 | 729 | ||
@@ -733,7 +733,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) | |||
733 | spin_unlock_irqrestore(&priv->txfidx_lock, flags); | 733 | spin_unlock_irqrestore(&priv->txfidx_lock, flags); |
734 | 734 | ||
735 | printk (KERN_ERR "%s: Unable to alloc request frame\n", | 735 | printk (KERN_ERR "%s: Unable to alloc request frame\n", |
736 | __FUNCTION__); | 736 | __func__); |
737 | return 1; | 737 | return 1; |
738 | } | 738 | } |
739 | 739 | ||
@@ -1208,7 +1208,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) | |||
1208 | 1208 | ||
1209 | dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, Start_buckets = %u, buckets_out = %u\n", | 1209 | dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, Start_buckets = %u, buckets_out = %u\n", |
1210 | IOC_AND_NETDEV_NAMES_s_s(dev), | 1210 | IOC_AND_NETDEV_NAMES_s_s(dev), |
1211 | __FUNCTION__, buckets, curr)); | 1211 | __func__, buckets, curr)); |
1212 | 1212 | ||
1213 | max = (mpt_dev->req_sz - MPT_LAN_RECEIVE_POST_REQUEST_SIZE) / | 1213 | max = (mpt_dev->req_sz - MPT_LAN_RECEIVE_POST_REQUEST_SIZE) / |
1214 | (MPT_LAN_TRANSACTION32_SIZE + sizeof(SGESimple64_t)); | 1214 | (MPT_LAN_TRANSACTION32_SIZE + sizeof(SGESimple64_t)); |
@@ -1217,9 +1217,9 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) | |||
1217 | mf = mpt_get_msg_frame(LanCtx, mpt_dev); | 1217 | mf = mpt_get_msg_frame(LanCtx, mpt_dev); |
1218 | if (mf == NULL) { | 1218 | if (mf == NULL) { |
1219 | printk (KERN_ERR "%s: Unable to alloc request frame\n", | 1219 | printk (KERN_ERR "%s: Unable to alloc request frame\n", |
1220 | __FUNCTION__); | 1220 | __func__); |
1221 | dioprintk((KERN_ERR "%s: %u buckets remaining\n", | 1221 | dioprintk((KERN_ERR "%s: %u buckets remaining\n", |
1222 | __FUNCTION__, buckets)); | 1222 | __func__, buckets)); |
1223 | goto out; | 1223 | goto out; |
1224 | } | 1224 | } |
1225 | pRecvReq = (LANReceivePostRequest_t *) mf; | 1225 | pRecvReq = (LANReceivePostRequest_t *) mf; |
@@ -1244,7 +1244,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) | |||
1244 | spin_lock_irqsave(&priv->rxfidx_lock, flags); | 1244 | spin_lock_irqsave(&priv->rxfidx_lock, flags); |
1245 | if (priv->mpt_rxfidx_tail < 0) { | 1245 | if (priv->mpt_rxfidx_tail < 0) { |
1246 | printk (KERN_ERR "%s: Can't alloc context\n", | 1246 | printk (KERN_ERR "%s: Can't alloc context\n", |
1247 | __FUNCTION__); | 1247 | __func__); |
1248 | spin_unlock_irqrestore(&priv->rxfidx_lock, | 1248 | spin_unlock_irqrestore(&priv->rxfidx_lock, |
1249 | flags); | 1249 | flags); |
1250 | break; | 1250 | break; |
@@ -1267,7 +1267,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) | |||
1267 | if (skb == NULL) { | 1267 | if (skb == NULL) { |
1268 | printk (KERN_WARNING | 1268 | printk (KERN_WARNING |
1269 | MYNAM "/%s: Can't alloc skb\n", | 1269 | MYNAM "/%s: Can't alloc skb\n", |
1270 | __FUNCTION__); | 1270 | __func__); |
1271 | priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx; | 1271 | priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx; |
1272 | spin_unlock_irqrestore(&priv->rxfidx_lock, flags); | 1272 | spin_unlock_irqrestore(&priv->rxfidx_lock, flags); |
1273 | break; | 1273 | break; |
@@ -1305,7 +1305,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) | |||
1305 | 1305 | ||
1306 | if (pSimple == NULL) { | 1306 | if (pSimple == NULL) { |
1307 | /**/ printk (KERN_WARNING MYNAM "/%s: No buckets posted\n", | 1307 | /**/ printk (KERN_WARNING MYNAM "/%s: No buckets posted\n", |
1308 | /**/ __FUNCTION__); | 1308 | /**/ __func__); |
1309 | mpt_free_msg_frame(mpt_dev, mf); | 1309 | mpt_free_msg_frame(mpt_dev, mf); |
1310 | goto out; | 1310 | goto out; |
1311 | } | 1311 | } |
@@ -1329,9 +1329,9 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) | |||
1329 | 1329 | ||
1330 | out: | 1330 | out: |
1331 | dioprintk((KERN_INFO MYNAM "/%s: End_buckets = %u, priv->buckets_out = %u\n", | 1331 | dioprintk((KERN_INFO MYNAM "/%s: End_buckets = %u, priv->buckets_out = %u\n", |
1332 | __FUNCTION__, buckets, atomic_read(&priv->buckets_out))); | 1332 | __func__, buckets, atomic_read(&priv->buckets_out))); |
1333 | dioprintk((KERN_INFO MYNAM "/%s: Posted %u buckets and received %u back\n", | 1333 | dioprintk((KERN_INFO MYNAM "/%s: Posted %u buckets and received %u back\n", |
1334 | __FUNCTION__, priv->total_posted, priv->total_received)); | 1334 | __func__, priv->total_posted, priv->total_received)); |
1335 | 1335 | ||
1336 | clear_bit(0, &priv->post_buckets_active); | 1336 | clear_bit(0, &priv->post_buckets_active); |
1337 | } | 1337 | } |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index b1147aa7afde..12b732512e57 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -300,7 +300,7 @@ mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_detai | |||
300 | phy_info = port_info->phy_info; | 300 | phy_info = port_info->phy_info; |
301 | 301 | ||
302 | dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d " | 302 | dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d " |
303 | "bitmask=0x%016llX\n", ioc->name, __FUNCTION__, port_details, | 303 | "bitmask=0x%016llX\n", ioc->name, __func__, port_details, |
304 | port_details->num_phys, (unsigned long long) | 304 | port_details->num_phys, (unsigned long long) |
305 | port_details->phy_bitmask)); | 305 | port_details->phy_bitmask)); |
306 | 306 | ||
@@ -411,7 +411,7 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) | |||
411 | */ | 411 | */ |
412 | dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT | 412 | dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT |
413 | "%s: [%p]: deleting phy = %d\n", | 413 | "%s: [%p]: deleting phy = %d\n", |
414 | ioc->name, __FUNCTION__, port_details, i)); | 414 | ioc->name, __func__, port_details, i)); |
415 | port_details->num_phys--; | 415 | port_details->num_phys--; |
416 | port_details->phy_bitmask &= ~ (1 << phy_info->phy_id); | 416 | port_details->phy_bitmask &= ~ (1 << phy_info->phy_id); |
417 | memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); | 417 | memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); |
@@ -497,7 +497,7 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) | |||
497 | continue; | 497 | continue; |
498 | dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT | 498 | dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT |
499 | "%s: [%p]: phy_id=%02d num_phys=%02d " | 499 | "%s: [%p]: phy_id=%02d num_phys=%02d " |
500 | "bitmask=0x%016llX\n", ioc->name, __FUNCTION__, | 500 | "bitmask=0x%016llX\n", ioc->name, __func__, |
501 | port_details, i, port_details->num_phys, | 501 | port_details, i, port_details->num_phys, |
502 | (unsigned long long)port_details->phy_bitmask)); | 502 | (unsigned long long)port_details->phy_bitmask)); |
503 | dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n", | 503 | dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n", |
@@ -553,7 +553,7 @@ mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id) | |||
553 | 553 | ||
554 | if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) { | 554 | if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) { |
555 | dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames @%d!!\n", | 555 | dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames @%d!!\n", |
556 | ioc->name,__FUNCTION__, __LINE__)); | 556 | ioc->name,__func__, __LINE__)); |
557 | return 0; | 557 | return 0; |
558 | } | 558 | } |
559 | 559 | ||
@@ -606,7 +606,7 @@ mptsas_target_reset_queue(MPT_ADAPTER *ioc, | |||
606 | GFP_ATOMIC); | 606 | GFP_ATOMIC); |
607 | if (!target_reset_list) { | 607 | if (!target_reset_list) { |
608 | dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n", | 608 | dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n", |
609 | ioc->name,__FUNCTION__, __LINE__)); | 609 | ioc->name,__func__, __LINE__)); |
610 | return; | 610 | return; |
611 | } | 611 | } |
612 | 612 | ||
@@ -673,7 +673,7 @@ mptsas_dev_reset_complete(MPT_ADAPTER *ioc) | |||
673 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); | 673 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); |
674 | if (!ev) { | 674 | if (!ev) { |
675 | dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n", | 675 | dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n", |
676 | ioc->name,__FUNCTION__, __LINE__)); | 676 | ioc->name,__func__, __LINE__)); |
677 | return; | 677 | return; |
678 | } | 678 | } |
679 | 679 | ||
@@ -1183,7 +1183,7 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset) | |||
1183 | reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply; | 1183 | reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply; |
1184 | if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) { | 1184 | if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) { |
1185 | printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", | 1185 | printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", |
1186 | ioc->name, __FUNCTION__, reply->IOCStatus, reply->IOCLogInfo); | 1186 | ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo); |
1187 | error = -ENXIO; | 1187 | error = -ENXIO; |
1188 | goto out_unlock; | 1188 | goto out_unlock; |
1189 | } | 1189 | } |
@@ -1270,14 +1270,14 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, | |||
1270 | 1270 | ||
1271 | if (!rsp) { | 1271 | if (!rsp) { |
1272 | printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n", | 1272 | printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n", |
1273 | ioc->name, __FUNCTION__); | 1273 | ioc->name, __func__); |
1274 | return -EINVAL; | 1274 | return -EINVAL; |
1275 | } | 1275 | } |
1276 | 1276 | ||
1277 | /* do we need to support multiple segments? */ | 1277 | /* do we need to support multiple segments? */ |
1278 | if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) { | 1278 | if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) { |
1279 | printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n", | 1279 | printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n", |
1280 | ioc->name, __FUNCTION__, req->bio->bi_vcnt, req->data_len, | 1280 | ioc->name, __func__, req->bio->bi_vcnt, req->data_len, |
1281 | rsp->bio->bi_vcnt, rsp->data_len); | 1281 | rsp->bio->bi_vcnt, rsp->data_len); |
1282 | return -EINVAL; | 1282 | return -EINVAL; |
1283 | } | 1283 | } |
@@ -1343,7 +1343,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, | |||
1343 | 1343 | ||
1344 | timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ); | 1344 | timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ); |
1345 | if (!timeleft) { | 1345 | if (!timeleft) { |
1346 | printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __FUNCTION__); | 1346 | printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __func__); |
1347 | /* On timeout reset the board */ | 1347 | /* On timeout reset the board */ |
1348 | mpt_HardResetHandler(ioc, CAN_SLEEP); | 1348 | mpt_HardResetHandler(ioc, CAN_SLEEP); |
1349 | ret = -ETIMEDOUT; | 1349 | ret = -ETIMEDOUT; |
@@ -1361,7 +1361,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, | |||
1361 | rsp->data_len -= smprep->ResponseDataLength; | 1361 | rsp->data_len -= smprep->ResponseDataLength; |
1362 | } else { | 1362 | } else { |
1363 | printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n", | 1363 | printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n", |
1364 | ioc->name, __FUNCTION__); | 1364 | ioc->name, __func__); |
1365 | ret = -ENXIO; | 1365 | ret = -ENXIO; |
1366 | } | 1366 | } |
1367 | unmap: | 1367 | unmap: |
@@ -2006,7 +2006,7 @@ static int mptsas_probe_one_phy(struct device *dev, | |||
2006 | if (error) { | 2006 | if (error) { |
2007 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | 2007 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT |
2008 | "%s: exit at line=%d\n", ioc->name, | 2008 | "%s: exit at line=%d\n", ioc->name, |
2009 | __FUNCTION__, __LINE__)); | 2009 | __func__, __LINE__)); |
2010 | goto out; | 2010 | goto out; |
2011 | } | 2011 | } |
2012 | mptsas_set_port(ioc, phy_info, port); | 2012 | mptsas_set_port(ioc, phy_info, port); |
@@ -2076,7 +2076,7 @@ static int mptsas_probe_one_phy(struct device *dev, | |||
2076 | if (!rphy) { | 2076 | if (!rphy) { |
2077 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | 2077 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT |
2078 | "%s: exit at line=%d\n", ioc->name, | 2078 | "%s: exit at line=%d\n", ioc->name, |
2079 | __FUNCTION__, __LINE__)); | 2079 | __func__, __LINE__)); |
2080 | goto out; | 2080 | goto out; |
2081 | } | 2081 | } |
2082 | 2082 | ||
@@ -2085,7 +2085,7 @@ static int mptsas_probe_one_phy(struct device *dev, | |||
2085 | if (error) { | 2085 | if (error) { |
2086 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | 2086 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT |
2087 | "%s: exit at line=%d\n", ioc->name, | 2087 | "%s: exit at line=%d\n", ioc->name, |
2088 | __FUNCTION__, __LINE__)); | 2088 | __func__, __LINE__)); |
2089 | sas_rphy_free(rphy); | 2089 | sas_rphy_free(rphy); |
2090 | goto out; | 2090 | goto out; |
2091 | } | 2091 | } |
@@ -2613,7 +2613,7 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2613 | (ev->channel << 8) + ev->id)) { | 2613 | (ev->channel << 8) + ev->id)) { |
2614 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | 2614 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT |
2615 | "%s: exit at line=%d\n", ioc->name, | 2615 | "%s: exit at line=%d\n", ioc->name, |
2616 | __FUNCTION__, __LINE__)); | 2616 | __func__, __LINE__)); |
2617 | break; | 2617 | break; |
2618 | } | 2618 | } |
2619 | phy_info = mptsas_find_phyinfo_by_sas_address( | 2619 | phy_info = mptsas_find_phyinfo_by_sas_address( |
@@ -2633,20 +2633,20 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2633 | if (!phy_info){ | 2633 | if (!phy_info){ |
2634 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | 2634 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT |
2635 | "%s: exit at line=%d\n", ioc->name, | 2635 | "%s: exit at line=%d\n", ioc->name, |
2636 | __FUNCTION__, __LINE__)); | 2636 | __func__, __LINE__)); |
2637 | break; | 2637 | break; |
2638 | } | 2638 | } |
2639 | if (!phy_info->port_details) { | 2639 | if (!phy_info->port_details) { |
2640 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | 2640 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT |
2641 | "%s: exit at line=%d\n", ioc->name, | 2641 | "%s: exit at line=%d\n", ioc->name, |
2642 | __FUNCTION__, __LINE__)); | 2642 | __func__, __LINE__)); |
2643 | break; | 2643 | break; |
2644 | } | 2644 | } |
2645 | rphy = mptsas_get_rphy(phy_info); | 2645 | rphy = mptsas_get_rphy(phy_info); |
2646 | if (!rphy) { | 2646 | if (!rphy) { |
2647 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | 2647 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT |
2648 | "%s: exit at line=%d\n", ioc->name, | 2648 | "%s: exit at line=%d\n", ioc->name, |
2649 | __FUNCTION__, __LINE__)); | 2649 | __func__, __LINE__)); |
2650 | break; | 2650 | break; |
2651 | } | 2651 | } |
2652 | 2652 | ||
@@ -2654,7 +2654,7 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2654 | if (!port) { | 2654 | if (!port) { |
2655 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | 2655 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT |
2656 | "%s: exit at line=%d\n", ioc->name, | 2656 | "%s: exit at line=%d\n", ioc->name, |
2657 | __FUNCTION__, __LINE__)); | 2657 | __func__, __LINE__)); |
2658 | break; | 2658 | break; |
2659 | } | 2659 | } |
2660 | 2660 | ||
@@ -2665,7 +2665,7 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2665 | if (!vtarget) { | 2665 | if (!vtarget) { |
2666 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | 2666 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT |
2667 | "%s: exit at line=%d\n", ioc->name, | 2667 | "%s: exit at line=%d\n", ioc->name, |
2668 | __FUNCTION__, __LINE__)); | 2668 | __func__, __LINE__)); |
2669 | break; | 2669 | break; |
2670 | } | 2670 | } |
2671 | 2671 | ||
@@ -2720,7 +2720,7 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2720 | (ev->channel << 8) + ev->id)) { | 2720 | (ev->channel << 8) + ev->id)) { |
2721 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | 2721 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT |
2722 | "%s: exit at line=%d\n", ioc->name, | 2722 | "%s: exit at line=%d\n", ioc->name, |
2723 | __FUNCTION__, __LINE__)); | 2723 | __func__, __LINE__)); |
2724 | break; | 2724 | break; |
2725 | } | 2725 | } |
2726 | 2726 | ||
@@ -2732,7 +2732,7 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2732 | if (!phy_info || !phy_info->port_details) { | 2732 | if (!phy_info || !phy_info->port_details) { |
2733 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | 2733 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT |
2734 | "%s: exit at line=%d\n", ioc->name, | 2734 | "%s: exit at line=%d\n", ioc->name, |
2735 | __FUNCTION__, __LINE__)); | 2735 | __func__, __LINE__)); |
2736 | break; | 2736 | break; |
2737 | } | 2737 | } |
2738 | 2738 | ||
@@ -2744,7 +2744,7 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2744 | if (!vtarget) { | 2744 | if (!vtarget) { |
2745 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | 2745 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT |
2746 | "%s: exit at line=%d\n", ioc->name, | 2746 | "%s: exit at line=%d\n", ioc->name, |
2747 | __FUNCTION__, __LINE__)); | 2747 | __func__, __LINE__)); |
2748 | break; | 2748 | break; |
2749 | } | 2749 | } |
2750 | /* | 2750 | /* |
@@ -2767,7 +2767,7 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2767 | if (mptsas_get_rphy(phy_info)) { | 2767 | if (mptsas_get_rphy(phy_info)) { |
2768 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | 2768 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT |
2769 | "%s: exit at line=%d\n", ioc->name, | 2769 | "%s: exit at line=%d\n", ioc->name, |
2770 | __FUNCTION__, __LINE__)); | 2770 | __func__, __LINE__)); |
2771 | if (ev->channel) printk("%d\n", __LINE__); | 2771 | if (ev->channel) printk("%d\n", __LINE__); |
2772 | break; | 2772 | break; |
2773 | } | 2773 | } |
@@ -2776,7 +2776,7 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2776 | if (!port) { | 2776 | if (!port) { |
2777 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | 2777 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT |
2778 | "%s: exit at line=%d\n", ioc->name, | 2778 | "%s: exit at line=%d\n", ioc->name, |
2779 | __FUNCTION__, __LINE__)); | 2779 | __func__, __LINE__)); |
2780 | break; | 2780 | break; |
2781 | } | 2781 | } |
2782 | memcpy(&phy_info->attached, &sas_device, | 2782 | memcpy(&phy_info->attached, &sas_device, |
@@ -2801,7 +2801,7 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2801 | if (!rphy) { | 2801 | if (!rphy) { |
2802 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | 2802 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT |
2803 | "%s: exit at line=%d\n", ioc->name, | 2803 | "%s: exit at line=%d\n", ioc->name, |
2804 | __FUNCTION__, __LINE__)); | 2804 | __func__, __LINE__)); |
2805 | break; /* non-fatal: an rphy can be added later */ | 2805 | break; /* non-fatal: an rphy can be added later */ |
2806 | } | 2806 | } |
2807 | 2807 | ||
@@ -2809,7 +2809,7 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2809 | if (sas_rphy_add(rphy)) { | 2809 | if (sas_rphy_add(rphy)) { |
2810 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | 2810 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT |
2811 | "%s: exit at line=%d\n", ioc->name, | 2811 | "%s: exit at line=%d\n", ioc->name, |
2812 | __FUNCTION__, __LINE__)); | 2812 | __func__, __LINE__)); |
2813 | sas_rphy_free(rphy); | 2813 | sas_rphy_free(rphy); |
2814 | break; | 2814 | break; |
2815 | } | 2815 | } |
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index d142b6b4b976..9f9354fd3516 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -461,7 +461,7 @@ mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget, | |||
461 | 461 | ||
462 | if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) { | 462 | if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) { |
463 | dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: no msg frames!!\n", | 463 | dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: no msg frames!!\n", |
464 | ioc->name,__FUNCTION__)); | 464 | ioc->name,__func__)); |
465 | return; | 465 | return; |
466 | } | 466 | } |
467 | 467 | ||
@@ -2187,7 +2187,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m | |||
2187 | (ioc->debug_level & MPT_DEBUG_TM )) | 2187 | (ioc->debug_level & MPT_DEBUG_TM )) |
2188 | printk("%s: ha=%d [%d:%d:0] task_type=0x%02X " | 2188 | printk("%s: ha=%d [%d:%d:0] task_type=0x%02X " |
2189 | "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X " | 2189 | "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X " |
2190 | "term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus, | 2190 | "term_cmnds=%d\n", __func__, ioc->id, pScsiTmReply->Bus, |
2191 | pScsiTmReply->TargetID, pScsiTmReq->TaskType, | 2191 | pScsiTmReply->TargetID, pScsiTmReq->TaskType, |
2192 | le16_to_cpu(pScsiTmReply->IOCStatus), | 2192 | le16_to_cpu(pScsiTmReply->IOCStatus), |
2193 | le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode, | 2193 | le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode, |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 321eb9134635..f5ade1904aad 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -360,7 +360,7 @@ config THINKPAD_ACPI_VIDEO | |||
360 | If you are not sure, say Y here. | 360 | If you are not sure, say Y here. |
361 | 361 | ||
362 | config THINKPAD_ACPI_HOTKEY_POLL | 362 | config THINKPAD_ACPI_HOTKEY_POLL |
363 | bool "Suport NVRAM polling for hot keys" | 363 | bool "Support NVRAM polling for hot keys" |
364 | depends on THINKPAD_ACPI | 364 | depends on THINKPAD_ACPI |
365 | default y | 365 | default y |
366 | ---help--- | 366 | ---help--- |
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c index e171650766ce..bf5e4d065436 100644 --- a/drivers/misc/atmel-ssc.c +++ b/drivers/misc/atmel-ssc.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/clk.h> | 13 | #include <linux/clk.h> |
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | #include <linux/list.h> | ||
17 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
18 | #include <linux/atmel-ssc.h> | 17 | #include <linux/atmel-ssc.h> |
19 | 18 | ||
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index b68381f7bfdd..992b4beb757c 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
@@ -11,6 +11,8 @@ | |||
11 | #include <linux/clk.h> | 11 | #include <linux/clk.h> |
12 | #include <linux/debugfs.h> | 12 | #include <linux/debugfs.h> |
13 | #include <linux/device.h> | 13 | #include <linux/device.h> |
14 | #include <linux/err.h> | ||
15 | #include <linux/gpio.h> | ||
14 | #include <linux/init.h> | 16 | #include <linux/init.h> |
15 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
16 | #include <linux/ioport.h> | 18 | #include <linux/ioport.h> |
@@ -27,7 +29,6 @@ | |||
27 | #include <asm/unaligned.h> | 29 | #include <asm/unaligned.h> |
28 | 30 | ||
29 | #include <asm/arch/board.h> | 31 | #include <asm/arch/board.h> |
30 | #include <asm/arch/gpio.h> | ||
31 | 32 | ||
32 | #include "atmel-mci-regs.h" | 33 | #include "atmel-mci-regs.h" |
33 | 34 | ||
@@ -573,7 +574,7 @@ static int atmci_get_ro(struct mmc_host *mmc) | |||
573 | int read_only = 0; | 574 | int read_only = 0; |
574 | struct atmel_mci *host = mmc_priv(mmc); | 575 | struct atmel_mci *host = mmc_priv(mmc); |
575 | 576 | ||
576 | if (host->wp_pin >= 0) { | 577 | if (gpio_is_valid(host->wp_pin)) { |
577 | read_only = gpio_get_value(host->wp_pin); | 578 | read_only = gpio_get_value(host->wp_pin); |
578 | dev_dbg(&mmc->class_dev, "card is %s\n", | 579 | dev_dbg(&mmc->class_dev, "card is %s\n", |
579 | read_only ? "read-only" : "read-write"); | 580 | read_only ? "read-only" : "read-write"); |
@@ -635,7 +636,7 @@ static void atmci_detect_change(unsigned long data) | |||
635 | * been freed. | 636 | * been freed. |
636 | */ | 637 | */ |
637 | smp_rmb(); | 638 | smp_rmb(); |
638 | if (host->detect_pin < 0) | 639 | if (!gpio_is_valid(host->detect_pin)) |
639 | return; | 640 | return; |
640 | 641 | ||
641 | enable_irq(gpio_to_irq(host->detect_pin)); | 642 | enable_irq(gpio_to_irq(host->detect_pin)); |
@@ -1050,7 +1051,7 @@ static int __init atmci_probe(struct platform_device *pdev) | |||
1050 | 1051 | ||
1051 | /* Assume card is present if we don't have a detect pin */ | 1052 | /* Assume card is present if we don't have a detect pin */ |
1052 | host->present = 1; | 1053 | host->present = 1; |
1053 | if (host->detect_pin >= 0) { | 1054 | if (gpio_is_valid(host->detect_pin)) { |
1054 | if (gpio_request(host->detect_pin, "mmc_detect")) { | 1055 | if (gpio_request(host->detect_pin, "mmc_detect")) { |
1055 | dev_dbg(&mmc->class_dev, "no detect pin available\n"); | 1056 | dev_dbg(&mmc->class_dev, "no detect pin available\n"); |
1056 | host->detect_pin = -1; | 1057 | host->detect_pin = -1; |
@@ -1058,7 +1059,7 @@ static int __init atmci_probe(struct platform_device *pdev) | |||
1058 | host->present = !gpio_get_value(host->detect_pin); | 1059 | host->present = !gpio_get_value(host->detect_pin); |
1059 | } | 1060 | } |
1060 | } | 1061 | } |
1061 | if (host->wp_pin >= 0) { | 1062 | if (gpio_is_valid(host->wp_pin)) { |
1062 | if (gpio_request(host->wp_pin, "mmc_wp")) { | 1063 | if (gpio_request(host->wp_pin, "mmc_wp")) { |
1063 | dev_dbg(&mmc->class_dev, "no WP pin available\n"); | 1064 | dev_dbg(&mmc->class_dev, "no WP pin available\n"); |
1064 | host->wp_pin = -1; | 1065 | host->wp_pin = -1; |
@@ -1069,7 +1070,7 @@ static int __init atmci_probe(struct platform_device *pdev) | |||
1069 | 1070 | ||
1070 | mmc_add_host(mmc); | 1071 | mmc_add_host(mmc); |
1071 | 1072 | ||
1072 | if (host->detect_pin >= 0) { | 1073 | if (gpio_is_valid(host->detect_pin)) { |
1073 | setup_timer(&host->detect_timer, atmci_detect_change, | 1074 | setup_timer(&host->detect_timer, atmci_detect_change, |
1074 | (unsigned long)host); | 1075 | (unsigned long)host); |
1075 | 1076 | ||
@@ -1112,7 +1113,7 @@ static int __exit atmci_remove(struct platform_device *pdev) | |||
1112 | if (host) { | 1113 | if (host) { |
1113 | /* Debugfs stuff is cleaned up by mmc core */ | 1114 | /* Debugfs stuff is cleaned up by mmc core */ |
1114 | 1115 | ||
1115 | if (host->detect_pin >= 0) { | 1116 | if (gpio_is_valid(host->detect_pin)) { |
1116 | int pin = host->detect_pin; | 1117 | int pin = host->detect_pin; |
1117 | 1118 | ||
1118 | /* Make sure the timer doesn't enable the interrupt */ | 1119 | /* Make sure the timer doesn't enable the interrupt */ |
@@ -1132,7 +1133,7 @@ static int __exit atmci_remove(struct platform_device *pdev) | |||
1132 | mci_readl(host, SR); | 1133 | mci_readl(host, SR); |
1133 | clk_disable(host->mck); | 1134 | clk_disable(host->mck); |
1134 | 1135 | ||
1135 | if (host->wp_pin >= 0) | 1136 | if (gpio_is_valid(host->wp_pin)) |
1136 | gpio_free(host->wp_pin); | 1137 | gpio_free(host->wp_pin); |
1137 | 1138 | ||
1138 | free_irq(platform_get_irq(pdev, 0), host->mmc); | 1139 | free_irq(platform_get_irq(pdev, 0), host->mmc); |
diff --git a/drivers/s390/kvm/Makefile b/drivers/s390/kvm/Makefile index 4a5ec39f9ca6..0815690ac1e0 100644 --- a/drivers/s390/kvm/Makefile +++ b/drivers/s390/kvm/Makefile | |||
@@ -6,4 +6,4 @@ | |||
6 | # it under the terms of the GNU General Public License (version 2 only) | 6 | # it under the terms of the GNU General Public License (version 2 only) |
7 | # as published by the Free Software Foundation. | 7 | # as published by the Free Software Foundation. |
8 | 8 | ||
9 | obj-$(CONFIG_VIRTIO) += kvm_virtio.o | 9 | obj-$(CONFIG_S390_GUEST) += kvm_virtio.o |
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 7045511f9ad2..b92c19bb6876 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c | |||
@@ -4,7 +4,7 @@ | |||
4 | Written By: Adam Radford <linuxraid@amcc.com> | 4 | Written By: Adam Radford <linuxraid@amcc.com> |
5 | Modifications By: Tom Couch <linuxraid@amcc.com> | 5 | Modifications By: Tom Couch <linuxraid@amcc.com> |
6 | 6 | ||
7 | Copyright (C) 2004-2007 Applied Micro Circuits Corporation. | 7 | Copyright (C) 2004-2008 Applied Micro Circuits Corporation. |
8 | 8 | ||
9 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
10 | it under the terms of the GNU General Public License as published by | 10 | it under the terms of the GNU General Public License as published by |
@@ -71,6 +71,10 @@ | |||
71 | Add support for 9650SE controllers. | 71 | Add support for 9650SE controllers. |
72 | 2.26.02.009 - Fix dma mask setting to fallback to 32-bit if 64-bit fails. | 72 | 2.26.02.009 - Fix dma mask setting to fallback to 32-bit if 64-bit fails. |
73 | 2.26.02.010 - Add support for 9690SA controllers. | 73 | 2.26.02.010 - Add support for 9690SA controllers. |
74 | 2.26.02.011 - Increase max AENs drained to 256. | ||
75 | Add MSI support and "use_msi" module parameter. | ||
76 | Fix bug in twa_get_param() on 4GB+. | ||
77 | Use pci_resource_len() for ioremap(). | ||
74 | */ | 78 | */ |
75 | 79 | ||
76 | #include <linux/module.h> | 80 | #include <linux/module.h> |
@@ -95,7 +99,7 @@ | |||
95 | #include "3w-9xxx.h" | 99 | #include "3w-9xxx.h" |
96 | 100 | ||
97 | /* Globals */ | 101 | /* Globals */ |
98 | #define TW_DRIVER_VERSION "2.26.02.010" | 102 | #define TW_DRIVER_VERSION "2.26.02.011" |
99 | static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; | 103 | static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; |
100 | static unsigned int twa_device_extension_count; | 104 | static unsigned int twa_device_extension_count; |
101 | static int twa_major = -1; | 105 | static int twa_major = -1; |
@@ -107,6 +111,10 @@ MODULE_DESCRIPTION ("3ware 9000 Storage Controller Linux Driver"); | |||
107 | MODULE_LICENSE("GPL"); | 111 | MODULE_LICENSE("GPL"); |
108 | MODULE_VERSION(TW_DRIVER_VERSION); | 112 | MODULE_VERSION(TW_DRIVER_VERSION); |
109 | 113 | ||
114 | static int use_msi = 0; | ||
115 | module_param(use_msi, int, S_IRUGO); | ||
116 | MODULE_PARM_DESC(use_msi, "Use Message Signaled Interrupts. Default: 0"); | ||
117 | |||
110 | /* Function prototypes */ | 118 | /* Function prototypes */ |
111 | static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header); | 119 | static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header); |
112 | static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id); | 120 | static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id); |
@@ -1038,7 +1046,6 @@ static void *twa_get_param(TW_Device_Extension *tw_dev, int request_id, int tabl | |||
1038 | TW_Command_Full *full_command_packet; | 1046 | TW_Command_Full *full_command_packet; |
1039 | TW_Command *command_packet; | 1047 | TW_Command *command_packet; |
1040 | TW_Param_Apache *param; | 1048 | TW_Param_Apache *param; |
1041 | unsigned long param_value; | ||
1042 | void *retval = NULL; | 1049 | void *retval = NULL; |
1043 | 1050 | ||
1044 | /* Setup the command packet */ | 1051 | /* Setup the command packet */ |
@@ -1057,9 +1064,8 @@ static void *twa_get_param(TW_Device_Extension *tw_dev, int request_id, int tabl | |||
1057 | param->table_id = cpu_to_le16(table_id | 0x8000); | 1064 | param->table_id = cpu_to_le16(table_id | 0x8000); |
1058 | param->parameter_id = cpu_to_le16(parameter_id); | 1065 | param->parameter_id = cpu_to_le16(parameter_id); |
1059 | param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes); | 1066 | param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes); |
1060 | param_value = tw_dev->generic_buffer_phys[request_id]; | ||
1061 | 1067 | ||
1062 | command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(param_value); | 1068 | command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]); |
1063 | command_packet->byte8_offset.param.sgl[0].length = cpu_to_le32(TW_SECTOR_SIZE); | 1069 | command_packet->byte8_offset.param.sgl[0].length = cpu_to_le32(TW_SECTOR_SIZE); |
1064 | 1070 | ||
1065 | /* Post the command packet to the board */ | 1071 | /* Post the command packet to the board */ |
@@ -2000,7 +2006,7 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id | |||
2000 | { | 2006 | { |
2001 | struct Scsi_Host *host = NULL; | 2007 | struct Scsi_Host *host = NULL; |
2002 | TW_Device_Extension *tw_dev; | 2008 | TW_Device_Extension *tw_dev; |
2003 | u32 mem_addr; | 2009 | unsigned long mem_addr, mem_len; |
2004 | int retval = -ENODEV; | 2010 | int retval = -ENODEV; |
2005 | 2011 | ||
2006 | retval = pci_enable_device(pdev); | 2012 | retval = pci_enable_device(pdev); |
@@ -2045,13 +2051,16 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id | |||
2045 | goto out_free_device_extension; | 2051 | goto out_free_device_extension; |
2046 | } | 2052 | } |
2047 | 2053 | ||
2048 | if (pdev->device == PCI_DEVICE_ID_3WARE_9000) | 2054 | if (pdev->device == PCI_DEVICE_ID_3WARE_9000) { |
2049 | mem_addr = pci_resource_start(pdev, 1); | 2055 | mem_addr = pci_resource_start(pdev, 1); |
2050 | else | 2056 | mem_len = pci_resource_len(pdev, 1); |
2057 | } else { | ||
2051 | mem_addr = pci_resource_start(pdev, 2); | 2058 | mem_addr = pci_resource_start(pdev, 2); |
2059 | mem_len = pci_resource_len(pdev, 2); | ||
2060 | } | ||
2052 | 2061 | ||
2053 | /* Save base address */ | 2062 | /* Save base address */ |
2054 | tw_dev->base_addr = ioremap(mem_addr, PAGE_SIZE); | 2063 | tw_dev->base_addr = ioremap(mem_addr, mem_len); |
2055 | if (!tw_dev->base_addr) { | 2064 | if (!tw_dev->base_addr) { |
2056 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x35, "Failed to ioremap"); | 2065 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x35, "Failed to ioremap"); |
2057 | goto out_release_mem_region; | 2066 | goto out_release_mem_region; |
@@ -2086,7 +2095,7 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id | |||
2086 | 2095 | ||
2087 | pci_set_drvdata(pdev, host); | 2096 | pci_set_drvdata(pdev, host); |
2088 | 2097 | ||
2089 | printk(KERN_WARNING "3w-9xxx: scsi%d: Found a 3ware 9000 Storage Controller at 0x%x, IRQ: %d.\n", | 2098 | printk(KERN_WARNING "3w-9xxx: scsi%d: Found a 3ware 9000 Storage Controller at 0x%lx, IRQ: %d.\n", |
2090 | host->host_no, mem_addr, pdev->irq); | 2099 | host->host_no, mem_addr, pdev->irq); |
2091 | printk(KERN_WARNING "3w-9xxx: scsi%d: Firmware %s, BIOS %s, Ports: %d.\n", | 2100 | printk(KERN_WARNING "3w-9xxx: scsi%d: Firmware %s, BIOS %s, Ports: %d.\n", |
2092 | host->host_no, | 2101 | host->host_no, |
@@ -2097,6 +2106,11 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id | |||
2097 | le32_to_cpu(*(int *)twa_get_param(tw_dev, 2, TW_INFORMATION_TABLE, | 2106 | le32_to_cpu(*(int *)twa_get_param(tw_dev, 2, TW_INFORMATION_TABLE, |
2098 | TW_PARAM_PORTCOUNT, TW_PARAM_PORTCOUNT_LENGTH))); | 2107 | TW_PARAM_PORTCOUNT, TW_PARAM_PORTCOUNT_LENGTH))); |
2099 | 2108 | ||
2109 | /* Try to enable MSI */ | ||
2110 | if (use_msi && (pdev->device != PCI_DEVICE_ID_3WARE_9000) && | ||
2111 | !pci_enable_msi(pdev)) | ||
2112 | set_bit(TW_USING_MSI, &tw_dev->flags); | ||
2113 | |||
2100 | /* Now setup the interrupt handler */ | 2114 | /* Now setup the interrupt handler */ |
2101 | retval = request_irq(pdev->irq, twa_interrupt, IRQF_SHARED, "3w-9xxx", tw_dev); | 2115 | retval = request_irq(pdev->irq, twa_interrupt, IRQF_SHARED, "3w-9xxx", tw_dev); |
2102 | if (retval) { | 2116 | if (retval) { |
@@ -2120,6 +2134,8 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id | |||
2120 | return 0; | 2134 | return 0; |
2121 | 2135 | ||
2122 | out_remove_host: | 2136 | out_remove_host: |
2137 | if (test_bit(TW_USING_MSI, &tw_dev->flags)) | ||
2138 | pci_disable_msi(pdev); | ||
2123 | scsi_remove_host(host); | 2139 | scsi_remove_host(host); |
2124 | out_iounmap: | 2140 | out_iounmap: |
2125 | iounmap(tw_dev->base_addr); | 2141 | iounmap(tw_dev->base_addr); |
@@ -2151,6 +2167,10 @@ static void twa_remove(struct pci_dev *pdev) | |||
2151 | /* Shutdown the card */ | 2167 | /* Shutdown the card */ |
2152 | __twa_shutdown(tw_dev); | 2168 | __twa_shutdown(tw_dev); |
2153 | 2169 | ||
2170 | /* Disable MSI if enabled */ | ||
2171 | if (test_bit(TW_USING_MSI, &tw_dev->flags)) | ||
2172 | pci_disable_msi(pdev); | ||
2173 | |||
2154 | /* Free IO remapping */ | 2174 | /* Free IO remapping */ |
2155 | iounmap(tw_dev->base_addr); | 2175 | iounmap(tw_dev->base_addr); |
2156 | 2176 | ||
diff --git a/drivers/scsi/3w-9xxx.h b/drivers/scsi/3w-9xxx.h index d14a9479e389..1729a8785fea 100644 --- a/drivers/scsi/3w-9xxx.h +++ b/drivers/scsi/3w-9xxx.h | |||
@@ -4,7 +4,7 @@ | |||
4 | Written By: Adam Radford <linuxraid@amcc.com> | 4 | Written By: Adam Radford <linuxraid@amcc.com> |
5 | Modifications By: Tom Couch <linuxraid@amcc.com> | 5 | Modifications By: Tom Couch <linuxraid@amcc.com> |
6 | 6 | ||
7 | Copyright (C) 2004-2007 Applied Micro Circuits Corporation. | 7 | Copyright (C) 2004-2008 Applied Micro Circuits Corporation. |
8 | 8 | ||
9 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
10 | it under the terms of the GNU General Public License as published by | 10 | it under the terms of the GNU General Public License as published by |
@@ -319,8 +319,8 @@ static twa_message_type twa_error_table[] = { | |||
319 | 319 | ||
320 | /* Compatibility defines */ | 320 | /* Compatibility defines */ |
321 | #define TW_9000_ARCH_ID 0x5 | 321 | #define TW_9000_ARCH_ID 0x5 |
322 | #define TW_CURRENT_DRIVER_SRL 30 | 322 | #define TW_CURRENT_DRIVER_SRL 35 |
323 | #define TW_CURRENT_DRIVER_BUILD 80 | 323 | #define TW_CURRENT_DRIVER_BUILD 0 |
324 | #define TW_CURRENT_DRIVER_BRANCH 0 | 324 | #define TW_CURRENT_DRIVER_BRANCH 0 |
325 | 325 | ||
326 | /* Phase defines */ | 326 | /* Phase defines */ |
@@ -352,8 +352,9 @@ static twa_message_type twa_error_table[] = { | |||
352 | #define TW_MAX_RESET_TRIES 2 | 352 | #define TW_MAX_RESET_TRIES 2 |
353 | #define TW_MAX_CMDS_PER_LUN 254 | 353 | #define TW_MAX_CMDS_PER_LUN 254 |
354 | #define TW_MAX_RESPONSE_DRAIN 256 | 354 | #define TW_MAX_RESPONSE_DRAIN 256 |
355 | #define TW_MAX_AEN_DRAIN 40 | 355 | #define TW_MAX_AEN_DRAIN 255 |
356 | #define TW_IN_RESET 2 | 356 | #define TW_IN_RESET 2 |
357 | #define TW_USING_MSI 3 | ||
357 | #define TW_IN_ATTENTION_LOOP 4 | 358 | #define TW_IN_ATTENTION_LOOP 4 |
358 | #define TW_MAX_SECTORS 256 | 359 | #define TW_MAX_SECTORS 256 |
359 | #define TW_AEN_WAIT_TIME 1000 | 360 | #define TW_AEN_WAIT_TIME 1000 |
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 26be540d1dd3..c7f06298bd3c 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -63,6 +63,7 @@ comment "SCSI support type (disk, tape, CD-ROM)" | |||
63 | config BLK_DEV_SD | 63 | config BLK_DEV_SD |
64 | tristate "SCSI disk support" | 64 | tristate "SCSI disk support" |
65 | depends on SCSI | 65 | depends on SCSI |
66 | select CRC_T10DIF | ||
66 | ---help--- | 67 | ---help--- |
67 | If you want to use SCSI hard disks, Fibre Channel disks, | 68 | If you want to use SCSI hard disks, Fibre Channel disks, |
68 | Serial ATA (SATA) or Parallel ATA (PATA) hard disks, | 69 | Serial ATA (SATA) or Parallel ATA (PATA) hard disks, |
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index a8149677de23..72fd5043cfa1 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile | |||
@@ -151,6 +151,8 @@ scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o | |||
151 | scsi_tgt-y += scsi_tgt_lib.o scsi_tgt_if.o | 151 | scsi_tgt-y += scsi_tgt_lib.o scsi_tgt_if.o |
152 | 152 | ||
153 | sd_mod-objs := sd.o | 153 | sd_mod-objs := sd.o |
154 | sd_mod-$(CONFIG_BLK_DEV_INTEGRITY) += sd_dif.o | ||
155 | |||
154 | sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o | 156 | sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o |
155 | ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \ | 157 | ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \ |
156 | := -DCONFIG_NCR53C8XX_PREFETCH -DSCSI_NCR_BIG_ENDIAN \ | 158 | := -DCONFIG_NCR53C8XX_PREFETCH -DSCSI_NCR_BIG_ENDIAN \ |
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 8591585e5cc5..218777bfc143 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c | |||
@@ -2278,7 +2278,7 @@ do { \ | |||
2278 | #define ASC_DBG(lvl, format, arg...) { \ | 2278 | #define ASC_DBG(lvl, format, arg...) { \ |
2279 | if (asc_dbglvl >= (lvl)) \ | 2279 | if (asc_dbglvl >= (lvl)) \ |
2280 | printk(KERN_DEBUG "%s: %s: " format, DRV_NAME, \ | 2280 | printk(KERN_DEBUG "%s: %s: " format, DRV_NAME, \ |
2281 | __FUNCTION__ , ## arg); \ | 2281 | __func__ , ## arg); \ |
2282 | } | 2282 | } |
2283 | 2283 | ||
2284 | #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \ | 2284 | #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \ |
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index 0899cb61e3dd..b5a868d85eb4 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c | |||
@@ -288,20 +288,20 @@ static LIST_HEAD(aha152x_host_list); | |||
288 | #define DO_LOCK(flags) \ | 288 | #define DO_LOCK(flags) \ |
289 | do { \ | 289 | do { \ |
290 | if(spin_is_locked(&QLOCK)) { \ | 290 | if(spin_is_locked(&QLOCK)) { \ |
291 | DPRINTK(debug_intr, DEBUG_LEAD "(%s:%d) already locked at %s:%d\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__, QLOCKER, QLOCKERL); \ | 291 | DPRINTK(debug_intr, DEBUG_LEAD "(%s:%d) already locked at %s:%d\n", CMDINFO(CURRENT_SC), __func__, __LINE__, QLOCKER, QLOCKERL); \ |
292 | } \ | 292 | } \ |
293 | DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) locking\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \ | 293 | DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) locking\n", CMDINFO(CURRENT_SC), __func__, __LINE__); \ |
294 | spin_lock_irqsave(&QLOCK,flags); \ | 294 | spin_lock_irqsave(&QLOCK,flags); \ |
295 | DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) locked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \ | 295 | DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) locked\n", CMDINFO(CURRENT_SC), __func__, __LINE__); \ |
296 | QLOCKER=__FUNCTION__; \ | 296 | QLOCKER=__func__; \ |
297 | QLOCKERL=__LINE__; \ | 297 | QLOCKERL=__LINE__; \ |
298 | } while(0) | 298 | } while(0) |
299 | 299 | ||
300 | #define DO_UNLOCK(flags) \ | 300 | #define DO_UNLOCK(flags) \ |
301 | do { \ | 301 | do { \ |
302 | DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) unlocking (locked at %s:%d)\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__, QLOCKER, QLOCKERL); \ | 302 | DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) unlocking (locked at %s:%d)\n", CMDINFO(CURRENT_SC), __func__, __LINE__, QLOCKER, QLOCKERL); \ |
303 | spin_unlock_irqrestore(&QLOCK,flags); \ | 303 | spin_unlock_irqrestore(&QLOCK,flags); \ |
304 | DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) unlocked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \ | 304 | DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) unlocked\n", CMDINFO(CURRENT_SC), __func__, __LINE__); \ |
305 | QLOCKER="(not locked)"; \ | 305 | QLOCKER="(not locked)"; \ |
306 | QLOCKERL=0; \ | 306 | QLOCKERL=0; \ |
307 | } while(0) | 307 | } while(0) |
diff --git a/drivers/scsi/aic94xx/aic94xx.h b/drivers/scsi/aic94xx/aic94xx.h index 2ef459e9cda1..2863a9d22851 100644 --- a/drivers/scsi/aic94xx/aic94xx.h +++ b/drivers/scsi/aic94xx/aic94xx.h | |||
@@ -39,9 +39,9 @@ | |||
39 | 39 | ||
40 | #ifdef ASD_ENTER_EXIT | 40 | #ifdef ASD_ENTER_EXIT |
41 | #define ENTER printk(KERN_NOTICE "%s: ENTER %s\n", ASD_DRIVER_NAME, \ | 41 | #define ENTER printk(KERN_NOTICE "%s: ENTER %s\n", ASD_DRIVER_NAME, \ |
42 | __FUNCTION__) | 42 | __func__) |
43 | #define EXIT printk(KERN_NOTICE "%s: --EXIT %s\n", ASD_DRIVER_NAME, \ | 43 | #define EXIT printk(KERN_NOTICE "%s: --EXIT %s\n", ASD_DRIVER_NAME, \ |
44 | __FUNCTION__) | 44 | __func__) |
45 | #else | 45 | #else |
46 | #define ENTER | 46 | #define ENTER |
47 | #define EXIT | 47 | #define EXIT |
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c index 83a78222896d..eb9dc3195fdf 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.c +++ b/drivers/scsi/aic94xx/aic94xx_hwi.c | |||
@@ -1359,7 +1359,7 @@ int asd_enable_phys(struct asd_ha_struct *asd_ha, const u8 phy_mask) | |||
1359 | struct asd_ascb *ascb_list; | 1359 | struct asd_ascb *ascb_list; |
1360 | 1360 | ||
1361 | if (!phy_mask) { | 1361 | if (!phy_mask) { |
1362 | asd_printk("%s called with phy_mask of 0!?\n", __FUNCTION__); | 1362 | asd_printk("%s called with phy_mask of 0!?\n", __func__); |
1363 | return 0; | 1363 | return 0; |
1364 | } | 1364 | } |
1365 | 1365 | ||
diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c index 46643319c520..ca55013b6ae5 100644 --- a/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/drivers/scsi/aic94xx/aic94xx_scb.c | |||
@@ -211,7 +211,7 @@ static void asd_form_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy) | |||
211 | phy->asd_port = port; | 211 | phy->asd_port = port; |
212 | } | 212 | } |
213 | ASD_DPRINTK("%s: updating phy_mask 0x%x for phy%d\n", | 213 | ASD_DPRINTK("%s: updating phy_mask 0x%x for phy%d\n", |
214 | __FUNCTION__, phy->asd_port->phy_mask, sas_phy->id); | 214 | __func__, phy->asd_port->phy_mask, sas_phy->id); |
215 | asd_update_port_links(asd_ha, phy); | 215 | asd_update_port_links(asd_ha, phy); |
216 | spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags); | 216 | spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags); |
217 | } | 217 | } |
@@ -294,7 +294,7 @@ static void asd_link_reset_err_tasklet(struct asd_ascb *ascb, | |||
294 | struct asd_ascb *cp = asd_ascb_alloc_list(ascb->ha, &num, | 294 | struct asd_ascb *cp = asd_ascb_alloc_list(ascb->ha, &num, |
295 | GFP_ATOMIC); | 295 | GFP_ATOMIC); |
296 | if (!cp) { | 296 | if (!cp) { |
297 | asd_printk("%s: out of memory\n", __FUNCTION__); | 297 | asd_printk("%s: out of memory\n", __func__); |
298 | goto out; | 298 | goto out; |
299 | } | 299 | } |
300 | ASD_DPRINTK("phy%d: retries:0 performing link reset seq\n", | 300 | ASD_DPRINTK("phy%d: retries:0 performing link reset seq\n", |
@@ -446,7 +446,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, | |||
446 | struct domain_device *failed_dev = NULL; | 446 | struct domain_device *failed_dev = NULL; |
447 | 447 | ||
448 | ASD_DPRINTK("%s: REQ_TASK_ABORT, reason=0x%X\n", | 448 | ASD_DPRINTK("%s: REQ_TASK_ABORT, reason=0x%X\n", |
449 | __FUNCTION__, dl->status_block[3]); | 449 | __func__, dl->status_block[3]); |
450 | 450 | ||
451 | /* | 451 | /* |
452 | * Find the task that caused the abort and abort it first. | 452 | * Find the task that caused the abort and abort it first. |
@@ -474,7 +474,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, | |||
474 | 474 | ||
475 | if (!failed_dev) { | 475 | if (!failed_dev) { |
476 | ASD_DPRINTK("%s: Can't find task (tc=%d) to abort!\n", | 476 | ASD_DPRINTK("%s: Can't find task (tc=%d) to abort!\n", |
477 | __FUNCTION__, tc_abort); | 477 | __func__, tc_abort); |
478 | goto out; | 478 | goto out; |
479 | } | 479 | } |
480 | 480 | ||
@@ -502,7 +502,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, | |||
502 | conn_handle = *((u16*)(&dl->status_block[1])); | 502 | conn_handle = *((u16*)(&dl->status_block[1])); |
503 | conn_handle = le16_to_cpu(conn_handle); | 503 | conn_handle = le16_to_cpu(conn_handle); |
504 | 504 | ||
505 | ASD_DPRINTK("%s: REQ_DEVICE_RESET, reason=0x%X\n", __FUNCTION__, | 505 | ASD_DPRINTK("%s: REQ_DEVICE_RESET, reason=0x%X\n", __func__, |
506 | dl->status_block[3]); | 506 | dl->status_block[3]); |
507 | 507 | ||
508 | /* Find the last pending task for the device... */ | 508 | /* Find the last pending task for the device... */ |
@@ -522,7 +522,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, | |||
522 | 522 | ||
523 | if (!last_dev_task) { | 523 | if (!last_dev_task) { |
524 | ASD_DPRINTK("%s: Device reset for idle device %d?\n", | 524 | ASD_DPRINTK("%s: Device reset for idle device %d?\n", |
525 | __FUNCTION__, conn_handle); | 525 | __func__, conn_handle); |
526 | goto out; | 526 | goto out; |
527 | } | 527 | } |
528 | 528 | ||
@@ -549,10 +549,10 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, | |||
549 | goto out; | 549 | goto out; |
550 | } | 550 | } |
551 | case SIGNAL_NCQ_ERROR: | 551 | case SIGNAL_NCQ_ERROR: |
552 | ASD_DPRINTK("%s: SIGNAL_NCQ_ERROR\n", __FUNCTION__); | 552 | ASD_DPRINTK("%s: SIGNAL_NCQ_ERROR\n", __func__); |
553 | goto out; | 553 | goto out; |
554 | case CLEAR_NCQ_ERROR: | 554 | case CLEAR_NCQ_ERROR: |
555 | ASD_DPRINTK("%s: CLEAR_NCQ_ERROR\n", __FUNCTION__); | 555 | ASD_DPRINTK("%s: CLEAR_NCQ_ERROR\n", __func__); |
556 | goto out; | 556 | goto out; |
557 | } | 557 | } |
558 | 558 | ||
@@ -560,26 +560,26 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, | |||
560 | 560 | ||
561 | switch (sb_opcode) { | 561 | switch (sb_opcode) { |
562 | case BYTES_DMAED: | 562 | case BYTES_DMAED: |
563 | ASD_DPRINTK("%s: phy%d: BYTES_DMAED\n", __FUNCTION__, phy_id); | 563 | ASD_DPRINTK("%s: phy%d: BYTES_DMAED\n", __func__, phy_id); |
564 | asd_bytes_dmaed_tasklet(ascb, dl, edb, phy_id); | 564 | asd_bytes_dmaed_tasklet(ascb, dl, edb, phy_id); |
565 | break; | 565 | break; |
566 | case PRIMITIVE_RECVD: | 566 | case PRIMITIVE_RECVD: |
567 | ASD_DPRINTK("%s: phy%d: PRIMITIVE_RECVD\n", __FUNCTION__, | 567 | ASD_DPRINTK("%s: phy%d: PRIMITIVE_RECVD\n", __func__, |
568 | phy_id); | 568 | phy_id); |
569 | asd_primitive_rcvd_tasklet(ascb, dl, phy_id); | 569 | asd_primitive_rcvd_tasklet(ascb, dl, phy_id); |
570 | break; | 570 | break; |
571 | case PHY_EVENT: | 571 | case PHY_EVENT: |
572 | ASD_DPRINTK("%s: phy%d: PHY_EVENT\n", __FUNCTION__, phy_id); | 572 | ASD_DPRINTK("%s: phy%d: PHY_EVENT\n", __func__, phy_id); |
573 | asd_phy_event_tasklet(ascb, dl); | 573 | asd_phy_event_tasklet(ascb, dl); |
574 | break; | 574 | break; |
575 | case LINK_RESET_ERROR: | 575 | case LINK_RESET_ERROR: |
576 | ASD_DPRINTK("%s: phy%d: LINK_RESET_ERROR\n", __FUNCTION__, | 576 | ASD_DPRINTK("%s: phy%d: LINK_RESET_ERROR\n", __func__, |
577 | phy_id); | 577 | phy_id); |
578 | asd_link_reset_err_tasklet(ascb, dl, phy_id); | 578 | asd_link_reset_err_tasklet(ascb, dl, phy_id); |
579 | break; | 579 | break; |
580 | case TIMER_EVENT: | 580 | case TIMER_EVENT: |
581 | ASD_DPRINTK("%s: phy%d: TIMER_EVENT, lost dw sync\n", | 581 | ASD_DPRINTK("%s: phy%d: TIMER_EVENT, lost dw sync\n", |
582 | __FUNCTION__, phy_id); | 582 | __func__, phy_id); |
583 | asd_turn_led(asd_ha, phy_id, 0); | 583 | asd_turn_led(asd_ha, phy_id, 0); |
584 | /* the device is gone */ | 584 | /* the device is gone */ |
585 | sas_phy_disconnected(sas_phy); | 585 | sas_phy_disconnected(sas_phy); |
@@ -587,7 +587,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, | |||
587 | sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT); | 587 | sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT); |
588 | break; | 588 | break; |
589 | default: | 589 | default: |
590 | ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __FUNCTION__, | 590 | ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __func__, |
591 | phy_id, sb_opcode); | 591 | phy_id, sb_opcode); |
592 | ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n", | 592 | ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n", |
593 | edb, dl->opcode); | 593 | edb, dl->opcode); |
@@ -654,7 +654,7 @@ static void control_phy_tasklet_complete(struct asd_ascb *ascb, | |||
654 | 654 | ||
655 | if (status != 0) { | 655 | if (status != 0) { |
656 | ASD_DPRINTK("%s: phy%d status block opcode:0x%x\n", | 656 | ASD_DPRINTK("%s: phy%d status block opcode:0x%x\n", |
657 | __FUNCTION__, phy_id, status); | 657 | __func__, phy_id, status); |
658 | goto out; | 658 | goto out; |
659 | } | 659 | } |
660 | 660 | ||
@@ -663,7 +663,7 @@ static void control_phy_tasklet_complete(struct asd_ascb *ascb, | |||
663 | asd_ha->hw_prof.enabled_phys &= ~(1 << phy_id); | 663 | asd_ha->hw_prof.enabled_phys &= ~(1 << phy_id); |
664 | asd_turn_led(asd_ha, phy_id, 0); | 664 | asd_turn_led(asd_ha, phy_id, 0); |
665 | asd_control_led(asd_ha, phy_id, 0); | 665 | asd_control_led(asd_ha, phy_id, 0); |
666 | ASD_DPRINTK("%s: disable phy%d\n", __FUNCTION__, phy_id); | 666 | ASD_DPRINTK("%s: disable phy%d\n", __func__, phy_id); |
667 | break; | 667 | break; |
668 | 668 | ||
669 | case ENABLE_PHY: | 669 | case ENABLE_PHY: |
@@ -673,40 +673,40 @@ static void control_phy_tasklet_complete(struct asd_ascb *ascb, | |||
673 | get_lrate_mode(phy, oob_mode); | 673 | get_lrate_mode(phy, oob_mode); |
674 | asd_turn_led(asd_ha, phy_id, 1); | 674 | asd_turn_led(asd_ha, phy_id, 1); |
675 | ASD_DPRINTK("%s: phy%d, lrate:0x%x, proto:0x%x\n", | 675 | ASD_DPRINTK("%s: phy%d, lrate:0x%x, proto:0x%x\n", |
676 | __FUNCTION__, phy_id,phy->sas_phy.linkrate, | 676 | __func__, phy_id,phy->sas_phy.linkrate, |
677 | phy->sas_phy.iproto); | 677 | phy->sas_phy.iproto); |
678 | } else if (oob_status & CURRENT_SPINUP_HOLD) { | 678 | } else if (oob_status & CURRENT_SPINUP_HOLD) { |
679 | asd_ha->hw_prof.enabled_phys |= (1 << phy_id); | 679 | asd_ha->hw_prof.enabled_phys |= (1 << phy_id); |
680 | asd_turn_led(asd_ha, phy_id, 1); | 680 | asd_turn_led(asd_ha, phy_id, 1); |
681 | ASD_DPRINTK("%s: phy%d, spinup hold\n", __FUNCTION__, | 681 | ASD_DPRINTK("%s: phy%d, spinup hold\n", __func__, |
682 | phy_id); | 682 | phy_id); |
683 | } else if (oob_status & CURRENT_ERR_MASK) { | 683 | } else if (oob_status & CURRENT_ERR_MASK) { |
684 | asd_turn_led(asd_ha, phy_id, 0); | 684 | asd_turn_led(asd_ha, phy_id, 0); |
685 | ASD_DPRINTK("%s: phy%d: error: oob status:0x%02x\n", | 685 | ASD_DPRINTK("%s: phy%d: error: oob status:0x%02x\n", |
686 | __FUNCTION__, phy_id, oob_status); | 686 | __func__, phy_id, oob_status); |
687 | } else if (oob_status & (CURRENT_HOT_PLUG_CNCT | 687 | } else if (oob_status & (CURRENT_HOT_PLUG_CNCT |
688 | | CURRENT_DEVICE_PRESENT)) { | 688 | | CURRENT_DEVICE_PRESENT)) { |
689 | asd_ha->hw_prof.enabled_phys |= (1 << phy_id); | 689 | asd_ha->hw_prof.enabled_phys |= (1 << phy_id); |
690 | asd_turn_led(asd_ha, phy_id, 1); | 690 | asd_turn_led(asd_ha, phy_id, 1); |
691 | ASD_DPRINTK("%s: phy%d: hot plug or device present\n", | 691 | ASD_DPRINTK("%s: phy%d: hot plug or device present\n", |
692 | __FUNCTION__, phy_id); | 692 | __func__, phy_id); |
693 | } else { | 693 | } else { |
694 | asd_ha->hw_prof.enabled_phys |= (1 << phy_id); | 694 | asd_ha->hw_prof.enabled_phys |= (1 << phy_id); |
695 | asd_turn_led(asd_ha, phy_id, 0); | 695 | asd_turn_led(asd_ha, phy_id, 0); |
696 | ASD_DPRINTK("%s: phy%d: no device present: " | 696 | ASD_DPRINTK("%s: phy%d: no device present: " |
697 | "oob_status:0x%x\n", | 697 | "oob_status:0x%x\n", |
698 | __FUNCTION__, phy_id, oob_status); | 698 | __func__, phy_id, oob_status); |
699 | } | 699 | } |
700 | break; | 700 | break; |
701 | case RELEASE_SPINUP_HOLD: | 701 | case RELEASE_SPINUP_HOLD: |
702 | case PHY_NO_OP: | 702 | case PHY_NO_OP: |
703 | case EXECUTE_HARD_RESET: | 703 | case EXECUTE_HARD_RESET: |
704 | ASD_DPRINTK("%s: phy%d: sub_func:0x%x\n", __FUNCTION__, | 704 | ASD_DPRINTK("%s: phy%d: sub_func:0x%x\n", __func__, |
705 | phy_id, control_phy->sub_func); | 705 | phy_id, control_phy->sub_func); |
706 | /* XXX finish */ | 706 | /* XXX finish */ |
707 | break; | 707 | break; |
708 | default: | 708 | default: |
709 | ASD_DPRINTK("%s: phy%d: sub_func:0x%x?\n", __FUNCTION__, | 709 | ASD_DPRINTK("%s: phy%d: sub_func:0x%x?\n", __func__, |
710 | phy_id, control_phy->sub_func); | 710 | phy_id, control_phy->sub_func); |
711 | break; | 711 | break; |
712 | } | 712 | } |
diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c index 326765c9caf8..75d20f72501f 100644 --- a/drivers/scsi/aic94xx/aic94xx_task.c +++ b/drivers/scsi/aic94xx/aic94xx_task.c | |||
@@ -320,7 +320,7 @@ Again: | |||
320 | case TC_RESUME: | 320 | case TC_RESUME: |
321 | case TC_PARTIAL_SG_LIST: | 321 | case TC_PARTIAL_SG_LIST: |
322 | default: | 322 | default: |
323 | ASD_DPRINTK("%s: dl opcode: 0x%x?\n", __FUNCTION__, opcode); | 323 | ASD_DPRINTK("%s: dl opcode: 0x%x?\n", __func__, opcode); |
324 | break; | 324 | break; |
325 | } | 325 | } |
326 | 326 | ||
diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c index 633ff40c736a..d4640ef6d44f 100644 --- a/drivers/scsi/aic94xx/aic94xx_tmf.c +++ b/drivers/scsi/aic94xx/aic94xx_tmf.c | |||
@@ -75,12 +75,12 @@ static void asd_clear_nexus_tasklet_complete(struct asd_ascb *ascb, | |||
75 | struct done_list_struct *dl) | 75 | struct done_list_struct *dl) |
76 | { | 76 | { |
77 | struct tasklet_completion_status *tcs = ascb->uldd_task; | 77 | struct tasklet_completion_status *tcs = ascb->uldd_task; |
78 | ASD_DPRINTK("%s: here\n", __FUNCTION__); | 78 | ASD_DPRINTK("%s: here\n", __func__); |
79 | if (!del_timer(&ascb->timer)) { | 79 | if (!del_timer(&ascb->timer)) { |
80 | ASD_DPRINTK("%s: couldn't delete timer\n", __FUNCTION__); | 80 | ASD_DPRINTK("%s: couldn't delete timer\n", __func__); |
81 | return; | 81 | return; |
82 | } | 82 | } |
83 | ASD_DPRINTK("%s: opcode: 0x%x\n", __FUNCTION__, dl->opcode); | 83 | ASD_DPRINTK("%s: opcode: 0x%x\n", __func__, dl->opcode); |
84 | tcs->dl_opcode = dl->opcode; | 84 | tcs->dl_opcode = dl->opcode; |
85 | complete(ascb->completion); | 85 | complete(ascb->completion); |
86 | asd_ascb_free(ascb); | 86 | asd_ascb_free(ascb); |
@@ -91,7 +91,7 @@ static void asd_clear_nexus_timedout(unsigned long data) | |||
91 | struct asd_ascb *ascb = (void *)data; | 91 | struct asd_ascb *ascb = (void *)data; |
92 | struct tasklet_completion_status *tcs = ascb->uldd_task; | 92 | struct tasklet_completion_status *tcs = ascb->uldd_task; |
93 | 93 | ||
94 | ASD_DPRINTK("%s: here\n", __FUNCTION__); | 94 | ASD_DPRINTK("%s: here\n", __func__); |
95 | tcs->dl_opcode = TMF_RESP_FUNC_FAILED; | 95 | tcs->dl_opcode = TMF_RESP_FUNC_FAILED; |
96 | complete(ascb->completion); | 96 | complete(ascb->completion); |
97 | } | 97 | } |
@@ -103,7 +103,7 @@ static void asd_clear_nexus_timedout(unsigned long data) | |||
103 | DECLARE_COMPLETION_ONSTACK(completion); \ | 103 | DECLARE_COMPLETION_ONSTACK(completion); \ |
104 | DECLARE_TCS(tcs); \ | 104 | DECLARE_TCS(tcs); \ |
105 | \ | 105 | \ |
106 | ASD_DPRINTK("%s: PRE\n", __FUNCTION__); \ | 106 | ASD_DPRINTK("%s: PRE\n", __func__); \ |
107 | res = 1; \ | 107 | res = 1; \ |
108 | ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL); \ | 108 | ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL); \ |
109 | if (!ascb) \ | 109 | if (!ascb) \ |
@@ -115,12 +115,12 @@ static void asd_clear_nexus_timedout(unsigned long data) | |||
115 | scb->header.opcode = CLEAR_NEXUS | 115 | scb->header.opcode = CLEAR_NEXUS |
116 | 116 | ||
117 | #define CLEAR_NEXUS_POST \ | 117 | #define CLEAR_NEXUS_POST \ |
118 | ASD_DPRINTK("%s: POST\n", __FUNCTION__); \ | 118 | ASD_DPRINTK("%s: POST\n", __func__); \ |
119 | res = asd_enqueue_internal(ascb, asd_clear_nexus_tasklet_complete, \ | 119 | res = asd_enqueue_internal(ascb, asd_clear_nexus_tasklet_complete, \ |
120 | asd_clear_nexus_timedout); \ | 120 | asd_clear_nexus_timedout); \ |
121 | if (res) \ | 121 | if (res) \ |
122 | goto out_err; \ | 122 | goto out_err; \ |
123 | ASD_DPRINTK("%s: clear nexus posted, waiting...\n", __FUNCTION__); \ | 123 | ASD_DPRINTK("%s: clear nexus posted, waiting...\n", __func__); \ |
124 | wait_for_completion(&completion); \ | 124 | wait_for_completion(&completion); \ |
125 | res = tcs.dl_opcode; \ | 125 | res = tcs.dl_opcode; \ |
126 | if (res == TC_NO_ERROR) \ | 126 | if (res == TC_NO_ERROR) \ |
@@ -417,7 +417,7 @@ int asd_abort_task(struct sas_task *task) | |||
417 | if (task->task_state_flags & SAS_TASK_STATE_DONE) { | 417 | if (task->task_state_flags & SAS_TASK_STATE_DONE) { |
418 | spin_unlock_irqrestore(&task->task_state_lock, flags); | 418 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
419 | res = TMF_RESP_FUNC_COMPLETE; | 419 | res = TMF_RESP_FUNC_COMPLETE; |
420 | ASD_DPRINTK("%s: task 0x%p done\n", __FUNCTION__, task); | 420 | ASD_DPRINTK("%s: task 0x%p done\n", __func__, task); |
421 | goto out_done; | 421 | goto out_done; |
422 | } | 422 | } |
423 | spin_unlock_irqrestore(&task->task_state_lock, flags); | 423 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
@@ -481,7 +481,7 @@ int asd_abort_task(struct sas_task *task) | |||
481 | if (task->task_state_flags & SAS_TASK_STATE_DONE) { | 481 | if (task->task_state_flags & SAS_TASK_STATE_DONE) { |
482 | spin_unlock_irqrestore(&task->task_state_lock, flags); | 482 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
483 | res = TMF_RESP_FUNC_COMPLETE; | 483 | res = TMF_RESP_FUNC_COMPLETE; |
484 | ASD_DPRINTK("%s: task 0x%p done\n", __FUNCTION__, task); | 484 | ASD_DPRINTK("%s: task 0x%p done\n", __func__, task); |
485 | goto out_done; | 485 | goto out_done; |
486 | } | 486 | } |
487 | spin_unlock_irqrestore(&task->task_state_lock, flags); | 487 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index a715632e19d4..477542602284 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c | |||
@@ -240,7 +240,7 @@ static void __fas216_checkmagic(FAS216_Info *info, const char *func) | |||
240 | panic("scsi memory space corrupted in %s", func); | 240 | panic("scsi memory space corrupted in %s", func); |
241 | } | 241 | } |
242 | } | 242 | } |
243 | #define fas216_checkmagic(info) __fas216_checkmagic((info), __FUNCTION__) | 243 | #define fas216_checkmagic(info) __fas216_checkmagic((info), __func__) |
244 | #else | 244 | #else |
245 | #define fas216_checkmagic(info) | 245 | #define fas216_checkmagic(info) |
246 | #endif | 246 | #endif |
@@ -2658,7 +2658,7 @@ int fas216_eh_host_reset(struct scsi_cmnd *SCpnt) | |||
2658 | fas216_checkmagic(info); | 2658 | fas216_checkmagic(info); |
2659 | 2659 | ||
2660 | printk("scsi%d.%c: %s: resetting host\n", | 2660 | printk("scsi%d.%c: %s: resetting host\n", |
2661 | info->host->host_no, '0' + SCpnt->device->id, __FUNCTION__); | 2661 | info->host->host_no, '0' + SCpnt->device->id, __func__); |
2662 | 2662 | ||
2663 | /* | 2663 | /* |
2664 | * Reset the SCSI chip. | 2664 | * Reset the SCSI chip. |
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index aa2011b64683..3c257fe0893e 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c | |||
@@ -930,6 +930,7 @@ static int ch_probe(struct device *dev) | |||
930 | if (init) | 930 | if (init) |
931 | ch_init_elem(ch); | 931 | ch_init_elem(ch); |
932 | 932 | ||
933 | dev_set_drvdata(dev, ch); | ||
933 | sdev_printk(KERN_INFO, sd, "Attached scsi changer %s\n", ch->name); | 934 | sdev_printk(KERN_INFO, sd, "Attached scsi changer %s\n", ch->name); |
934 | 935 | ||
935 | return 0; | 936 | return 0; |
diff --git a/drivers/scsi/device_handler/Kconfig b/drivers/scsi/device_handler/Kconfig index 2adc0f666b68..67070257919f 100644 --- a/drivers/scsi/device_handler/Kconfig +++ b/drivers/scsi/device_handler/Kconfig | |||
@@ -30,3 +30,11 @@ config SCSI_DH_EMC | |||
30 | depends on SCSI_DH | 30 | depends on SCSI_DH |
31 | help | 31 | help |
32 | If you have a EMC CLARiiON select y. Otherwise, say N. | 32 | If you have a EMC CLARiiON select y. Otherwise, say N. |
33 | |||
34 | config SCSI_DH_ALUA | ||
35 | tristate "SPC-3 ALUA Device Handler (EXPERIMENTAL)" | ||
36 | depends on SCSI_DH && EXPERIMENTAL | ||
37 | help | ||
38 | SCSI Device handler for generic SPC-3 Asymmetric Logical Unit | ||
39 | Access (ALUA). | ||
40 | |||
diff --git a/drivers/scsi/device_handler/Makefile b/drivers/scsi/device_handler/Makefile index 35272e93b1c8..e1d2ea083e15 100644 --- a/drivers/scsi/device_handler/Makefile +++ b/drivers/scsi/device_handler/Makefile | |||
@@ -5,3 +5,4 @@ obj-$(CONFIG_SCSI_DH) += scsi_dh.o | |||
5 | obj-$(CONFIG_SCSI_DH_RDAC) += scsi_dh_rdac.o | 5 | obj-$(CONFIG_SCSI_DH_RDAC) += scsi_dh_rdac.o |
6 | obj-$(CONFIG_SCSI_DH_HP_SW) += scsi_dh_hp_sw.o | 6 | obj-$(CONFIG_SCSI_DH_HP_SW) += scsi_dh_hp_sw.o |
7 | obj-$(CONFIG_SCSI_DH_EMC) += scsi_dh_emc.o | 7 | obj-$(CONFIG_SCSI_DH_EMC) += scsi_dh_emc.o |
8 | obj-$(CONFIG_SCSI_DH_ALUA) += scsi_dh_alua.o | ||
diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c index ab6c21cd9689..a518f2eff19a 100644 --- a/drivers/scsi/device_handler/scsi_dh.c +++ b/drivers/scsi/device_handler/scsi_dh.c | |||
@@ -24,8 +24,16 @@ | |||
24 | #include <scsi/scsi_dh.h> | 24 | #include <scsi/scsi_dh.h> |
25 | #include "../scsi_priv.h" | 25 | #include "../scsi_priv.h" |
26 | 26 | ||
27 | struct scsi_dh_devinfo_list { | ||
28 | struct list_head node; | ||
29 | char vendor[9]; | ||
30 | char model[17]; | ||
31 | struct scsi_device_handler *handler; | ||
32 | }; | ||
33 | |||
27 | static DEFINE_SPINLOCK(list_lock); | 34 | static DEFINE_SPINLOCK(list_lock); |
28 | static LIST_HEAD(scsi_dh_list); | 35 | static LIST_HEAD(scsi_dh_list); |
36 | static LIST_HEAD(scsi_dh_dev_list); | ||
29 | 37 | ||
30 | static struct scsi_device_handler *get_device_handler(const char *name) | 38 | static struct scsi_device_handler *get_device_handler(const char *name) |
31 | { | 39 | { |
@@ -33,7 +41,7 @@ static struct scsi_device_handler *get_device_handler(const char *name) | |||
33 | 41 | ||
34 | spin_lock(&list_lock); | 42 | spin_lock(&list_lock); |
35 | list_for_each_entry(tmp, &scsi_dh_list, list) { | 43 | list_for_each_entry(tmp, &scsi_dh_list, list) { |
36 | if (!strcmp(tmp->name, name)) { | 44 | if (!strncmp(tmp->name, name, strlen(tmp->name))) { |
37 | found = tmp; | 45 | found = tmp; |
38 | break; | 46 | break; |
39 | } | 47 | } |
@@ -42,11 +50,307 @@ static struct scsi_device_handler *get_device_handler(const char *name) | |||
42 | return found; | 50 | return found; |
43 | } | 51 | } |
44 | 52 | ||
53 | |||
54 | static struct scsi_device_handler * | ||
55 | scsi_dh_cache_lookup(struct scsi_device *sdev) | ||
56 | { | ||
57 | struct scsi_dh_devinfo_list *tmp; | ||
58 | struct scsi_device_handler *found_dh = NULL; | ||
59 | |||
60 | spin_lock(&list_lock); | ||
61 | list_for_each_entry(tmp, &scsi_dh_dev_list, node) { | ||
62 | if (!strncmp(sdev->vendor, tmp->vendor, strlen(tmp->vendor)) && | ||
63 | !strncmp(sdev->model, tmp->model, strlen(tmp->model))) { | ||
64 | found_dh = tmp->handler; | ||
65 | break; | ||
66 | } | ||
67 | } | ||
68 | spin_unlock(&list_lock); | ||
69 | |||
70 | return found_dh; | ||
71 | } | ||
72 | |||
73 | static int scsi_dh_handler_lookup(struct scsi_device_handler *scsi_dh, | ||
74 | struct scsi_device *sdev) | ||
75 | { | ||
76 | int i, found = 0; | ||
77 | |||
78 | for(i = 0; scsi_dh->devlist[i].vendor; i++) { | ||
79 | if (!strncmp(sdev->vendor, scsi_dh->devlist[i].vendor, | ||
80 | strlen(scsi_dh->devlist[i].vendor)) && | ||
81 | !strncmp(sdev->model, scsi_dh->devlist[i].model, | ||
82 | strlen(scsi_dh->devlist[i].model))) { | ||
83 | found = 1; | ||
84 | break; | ||
85 | } | ||
86 | } | ||
87 | return found; | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * device_handler_match - Attach a device handler to a device | ||
92 | * @scsi_dh - The device handler to match against or NULL | ||
93 | * @sdev - SCSI device to be tested against @scsi_dh | ||
94 | * | ||
95 | * Tests @sdev against the device handler @scsi_dh or against | ||
96 | * all registered device_handler if @scsi_dh == NULL. | ||
97 | * Returns the found device handler or NULL if not found. | ||
98 | */ | ||
99 | static struct scsi_device_handler * | ||
100 | device_handler_match(struct scsi_device_handler *scsi_dh, | ||
101 | struct scsi_device *sdev) | ||
102 | { | ||
103 | struct scsi_device_handler *found_dh = NULL; | ||
104 | struct scsi_dh_devinfo_list *tmp; | ||
105 | |||
106 | found_dh = scsi_dh_cache_lookup(sdev); | ||
107 | if (found_dh) | ||
108 | return found_dh; | ||
109 | |||
110 | if (scsi_dh) { | ||
111 | if (scsi_dh_handler_lookup(scsi_dh, sdev)) | ||
112 | found_dh = scsi_dh; | ||
113 | } else { | ||
114 | struct scsi_device_handler *tmp_dh; | ||
115 | |||
116 | spin_lock(&list_lock); | ||
117 | list_for_each_entry(tmp_dh, &scsi_dh_list, list) { | ||
118 | if (scsi_dh_handler_lookup(tmp_dh, sdev)) | ||
119 | found_dh = tmp_dh; | ||
120 | } | ||
121 | spin_unlock(&list_lock); | ||
122 | } | ||
123 | |||
124 | if (found_dh) { /* If device is found, add it to the cache */ | ||
125 | tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); | ||
126 | if (tmp) { | ||
127 | strncpy(tmp->vendor, sdev->vendor, 8); | ||
128 | strncpy(tmp->model, sdev->model, 16); | ||
129 | tmp->vendor[8] = '\0'; | ||
130 | tmp->model[16] = '\0'; | ||
131 | tmp->handler = found_dh; | ||
132 | spin_lock(&list_lock); | ||
133 | list_add(&tmp->node, &scsi_dh_dev_list); | ||
134 | spin_unlock(&list_lock); | ||
135 | } else { | ||
136 | found_dh = NULL; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | return found_dh; | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * scsi_dh_handler_attach - Attach a device handler to a device | ||
145 | * @sdev - SCSI device the device handler should attach to | ||
146 | * @scsi_dh - The device handler to attach | ||
147 | */ | ||
148 | static int scsi_dh_handler_attach(struct scsi_device *sdev, | ||
149 | struct scsi_device_handler *scsi_dh) | ||
150 | { | ||
151 | int err = 0; | ||
152 | |||
153 | if (sdev->scsi_dh_data) { | ||
154 | if (sdev->scsi_dh_data->scsi_dh != scsi_dh) | ||
155 | err = -EBUSY; | ||
156 | } else if (scsi_dh->attach) | ||
157 | err = scsi_dh->attach(sdev); | ||
158 | |||
159 | return err; | ||
160 | } | ||
161 | |||
162 | /* | ||
163 | * scsi_dh_handler_detach - Detach a device handler from a device | ||
164 | * @sdev - SCSI device the device handler should be detached from | ||
165 | * @scsi_dh - Device handler to be detached | ||
166 | * | ||
167 | * Detach from a device handler. If a device handler is specified, | ||
168 | * only detach if the currently attached handler matches @scsi_dh. | ||
169 | */ | ||
170 | static void scsi_dh_handler_detach(struct scsi_device *sdev, | ||
171 | struct scsi_device_handler *scsi_dh) | ||
172 | { | ||
173 | if (!sdev->scsi_dh_data) | ||
174 | return; | ||
175 | |||
176 | if (scsi_dh && scsi_dh != sdev->scsi_dh_data->scsi_dh) | ||
177 | return; | ||
178 | |||
179 | if (!scsi_dh) | ||
180 | scsi_dh = sdev->scsi_dh_data->scsi_dh; | ||
181 | |||
182 | if (scsi_dh && scsi_dh->detach) | ||
183 | scsi_dh->detach(sdev); | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * Functions for sysfs attribute 'dh_state' | ||
188 | */ | ||
189 | static ssize_t | ||
190 | store_dh_state(struct device *dev, struct device_attribute *attr, | ||
191 | const char *buf, size_t count) | ||
192 | { | ||
193 | struct scsi_device *sdev = to_scsi_device(dev); | ||
194 | struct scsi_device_handler *scsi_dh; | ||
195 | int err = -EINVAL; | ||
196 | |||
197 | if (!sdev->scsi_dh_data) { | ||
198 | /* | ||
199 | * Attach to a device handler | ||
200 | */ | ||
201 | if (!(scsi_dh = get_device_handler(buf))) | ||
202 | return err; | ||
203 | err = scsi_dh_handler_attach(sdev, scsi_dh); | ||
204 | } else { | ||
205 | scsi_dh = sdev->scsi_dh_data->scsi_dh; | ||
206 | if (!strncmp(buf, "detach", 6)) { | ||
207 | /* | ||
208 | * Detach from a device handler | ||
209 | */ | ||
210 | scsi_dh_handler_detach(sdev, scsi_dh); | ||
211 | err = 0; | ||
212 | } else if (!strncmp(buf, "activate", 8)) { | ||
213 | /* | ||
214 | * Activate a device handler | ||
215 | */ | ||
216 | if (scsi_dh->activate) | ||
217 | err = scsi_dh->activate(sdev); | ||
218 | else | ||
219 | err = 0; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | return err<0?err:count; | ||
224 | } | ||
225 | |||
226 | static ssize_t | ||
227 | show_dh_state(struct device *dev, struct device_attribute *attr, char *buf) | ||
228 | { | ||
229 | struct scsi_device *sdev = to_scsi_device(dev); | ||
230 | |||
231 | if (!sdev->scsi_dh_data) | ||
232 | return snprintf(buf, 20, "detached\n"); | ||
233 | |||
234 | return snprintf(buf, 20, "%s\n", sdev->scsi_dh_data->scsi_dh->name); | ||
235 | } | ||
236 | |||
237 | static struct device_attribute scsi_dh_state_attr = | ||
238 | __ATTR(dh_state, S_IRUGO | S_IWUSR, show_dh_state, | ||
239 | store_dh_state); | ||
240 | |||
241 | /* | ||
242 | * scsi_dh_sysfs_attr_add - Callback for scsi_init_dh | ||
243 | */ | ||
244 | static int scsi_dh_sysfs_attr_add(struct device *dev, void *data) | ||
245 | { | ||
246 | struct scsi_device *sdev; | ||
247 | int err; | ||
248 | |||
249 | if (!scsi_is_sdev_device(dev)) | ||
250 | return 0; | ||
251 | |||
252 | sdev = to_scsi_device(dev); | ||
253 | |||
254 | err = device_create_file(&sdev->sdev_gendev, | ||
255 | &scsi_dh_state_attr); | ||
256 | |||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | /* | ||
261 | * scsi_dh_sysfs_attr_remove - Callback for scsi_exit_dh | ||
262 | */ | ||
263 | static int scsi_dh_sysfs_attr_remove(struct device *dev, void *data) | ||
264 | { | ||
265 | struct scsi_device *sdev; | ||
266 | |||
267 | if (!scsi_is_sdev_device(dev)) | ||
268 | return 0; | ||
269 | |||
270 | sdev = to_scsi_device(dev); | ||
271 | |||
272 | device_remove_file(&sdev->sdev_gendev, | ||
273 | &scsi_dh_state_attr); | ||
274 | |||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | /* | ||
279 | * scsi_dh_notifier - notifier chain callback | ||
280 | */ | ||
281 | static int scsi_dh_notifier(struct notifier_block *nb, | ||
282 | unsigned long action, void *data) | ||
283 | { | ||
284 | struct device *dev = data; | ||
285 | struct scsi_device *sdev; | ||
286 | int err = 0; | ||
287 | struct scsi_device_handler *devinfo = NULL; | ||
288 | |||
289 | if (!scsi_is_sdev_device(dev)) | ||
290 | return 0; | ||
291 | |||
292 | sdev = to_scsi_device(dev); | ||
293 | |||
294 | if (action == BUS_NOTIFY_ADD_DEVICE) { | ||
295 | devinfo = device_handler_match(NULL, sdev); | ||
296 | if (!devinfo) | ||
297 | goto out; | ||
298 | |||
299 | err = scsi_dh_handler_attach(sdev, devinfo); | ||
300 | if (!err) | ||
301 | err = device_create_file(dev, &scsi_dh_state_attr); | ||
302 | } else if (action == BUS_NOTIFY_DEL_DEVICE) { | ||
303 | device_remove_file(dev, &scsi_dh_state_attr); | ||
304 | scsi_dh_handler_detach(sdev, NULL); | ||
305 | } | ||
306 | out: | ||
307 | return err; | ||
308 | } | ||
309 | |||
310 | /* | ||
311 | * scsi_dh_notifier_add - Callback for scsi_register_device_handler | ||
312 | */ | ||
45 | static int scsi_dh_notifier_add(struct device *dev, void *data) | 313 | static int scsi_dh_notifier_add(struct device *dev, void *data) |
46 | { | 314 | { |
47 | struct scsi_device_handler *scsi_dh = data; | 315 | struct scsi_device_handler *scsi_dh = data; |
316 | struct scsi_device *sdev; | ||
317 | |||
318 | if (!scsi_is_sdev_device(dev)) | ||
319 | return 0; | ||
320 | |||
321 | if (!get_device(dev)) | ||
322 | return 0; | ||
323 | |||
324 | sdev = to_scsi_device(dev); | ||
325 | |||
326 | if (device_handler_match(scsi_dh, sdev)) | ||
327 | scsi_dh_handler_attach(sdev, scsi_dh); | ||
328 | |||
329 | put_device(dev); | ||
330 | |||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | /* | ||
335 | * scsi_dh_notifier_remove - Callback for scsi_unregister_device_handler | ||
336 | */ | ||
337 | static int scsi_dh_notifier_remove(struct device *dev, void *data) | ||
338 | { | ||
339 | struct scsi_device_handler *scsi_dh = data; | ||
340 | struct scsi_device *sdev; | ||
341 | |||
342 | if (!scsi_is_sdev_device(dev)) | ||
343 | return 0; | ||
344 | |||
345 | if (!get_device(dev)) | ||
346 | return 0; | ||
347 | |||
348 | sdev = to_scsi_device(dev); | ||
349 | |||
350 | scsi_dh_handler_detach(sdev, scsi_dh); | ||
351 | |||
352 | put_device(dev); | ||
48 | 353 | ||
49 | scsi_dh->nb.notifier_call(&scsi_dh->nb, BUS_NOTIFY_ADD_DEVICE, dev); | ||
50 | return 0; | 354 | return 0; |
51 | } | 355 | } |
52 | 356 | ||
@@ -59,33 +363,19 @@ static int scsi_dh_notifier_add(struct device *dev, void *data) | |||
59 | */ | 363 | */ |
60 | int scsi_register_device_handler(struct scsi_device_handler *scsi_dh) | 364 | int scsi_register_device_handler(struct scsi_device_handler *scsi_dh) |
61 | { | 365 | { |
62 | int ret = -EBUSY; | 366 | if (get_device_handler(scsi_dh->name)) |
63 | struct scsi_device_handler *tmp; | 367 | return -EBUSY; |
64 | 368 | ||
65 | tmp = get_device_handler(scsi_dh->name); | ||
66 | if (tmp) | ||
67 | goto done; | ||
68 | |||
69 | ret = bus_register_notifier(&scsi_bus_type, &scsi_dh->nb); | ||
70 | |||
71 | bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, scsi_dh_notifier_add); | ||
72 | spin_lock(&list_lock); | 369 | spin_lock(&list_lock); |
73 | list_add(&scsi_dh->list, &scsi_dh_list); | 370 | list_add(&scsi_dh->list, &scsi_dh_list); |
74 | spin_unlock(&list_lock); | 371 | spin_unlock(&list_lock); |
372 | bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, scsi_dh_notifier_add); | ||
373 | printk(KERN_INFO "%s: device handler registered\n", scsi_dh->name); | ||
75 | 374 | ||
76 | done: | 375 | return SCSI_DH_OK; |
77 | return ret; | ||
78 | } | 376 | } |
79 | EXPORT_SYMBOL_GPL(scsi_register_device_handler); | 377 | EXPORT_SYMBOL_GPL(scsi_register_device_handler); |
80 | 378 | ||
81 | static int scsi_dh_notifier_remove(struct device *dev, void *data) | ||
82 | { | ||
83 | struct scsi_device_handler *scsi_dh = data; | ||
84 | |||
85 | scsi_dh->nb.notifier_call(&scsi_dh->nb, BUS_NOTIFY_DEL_DEVICE, dev); | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | /* | 379 | /* |
90 | * scsi_unregister_device_handler - register a device handler personality | 380 | * scsi_unregister_device_handler - register a device handler personality |
91 | * module. | 381 | * module. |
@@ -95,23 +385,26 @@ static int scsi_dh_notifier_remove(struct device *dev, void *data) | |||
95 | */ | 385 | */ |
96 | int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh) | 386 | int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh) |
97 | { | 387 | { |
98 | int ret = -ENODEV; | 388 | struct scsi_dh_devinfo_list *tmp, *pos; |
99 | struct scsi_device_handler *tmp; | ||
100 | |||
101 | tmp = get_device_handler(scsi_dh->name); | ||
102 | if (!tmp) | ||
103 | goto done; | ||
104 | 389 | ||
105 | ret = bus_unregister_notifier(&scsi_bus_type, &scsi_dh->nb); | 390 | if (!get_device_handler(scsi_dh->name)) |
391 | return -ENODEV; | ||
106 | 392 | ||
107 | bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, | 393 | bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, |
108 | scsi_dh_notifier_remove); | 394 | scsi_dh_notifier_remove); |
395 | |||
109 | spin_lock(&list_lock); | 396 | spin_lock(&list_lock); |
110 | list_del(&scsi_dh->list); | 397 | list_del(&scsi_dh->list); |
398 | list_for_each_entry_safe(pos, tmp, &scsi_dh_dev_list, node) { | ||
399 | if (pos->handler == scsi_dh) { | ||
400 | list_del(&pos->node); | ||
401 | kfree(pos); | ||
402 | } | ||
403 | } | ||
111 | spin_unlock(&list_lock); | 404 | spin_unlock(&list_lock); |
405 | printk(KERN_INFO "%s: device handler unregistered\n", scsi_dh->name); | ||
112 | 406 | ||
113 | done: | 407 | return SCSI_DH_OK; |
114 | return ret; | ||
115 | } | 408 | } |
116 | EXPORT_SYMBOL_GPL(scsi_unregister_device_handler); | 409 | EXPORT_SYMBOL_GPL(scsi_unregister_device_handler); |
117 | 410 | ||
@@ -157,6 +450,97 @@ int scsi_dh_handler_exist(const char *name) | |||
157 | } | 450 | } |
158 | EXPORT_SYMBOL_GPL(scsi_dh_handler_exist); | 451 | EXPORT_SYMBOL_GPL(scsi_dh_handler_exist); |
159 | 452 | ||
453 | /* | ||
454 | * scsi_dh_handler_attach - Attach device handler | ||
455 | * @sdev - sdev the handler should be attached to | ||
456 | * @name - name of the handler to attach | ||
457 | */ | ||
458 | int scsi_dh_attach(struct request_queue *q, const char *name) | ||
459 | { | ||
460 | unsigned long flags; | ||
461 | struct scsi_device *sdev; | ||
462 | struct scsi_device_handler *scsi_dh; | ||
463 | int err = 0; | ||
464 | |||
465 | scsi_dh = get_device_handler(name); | ||
466 | if (!scsi_dh) | ||
467 | return -EINVAL; | ||
468 | |||
469 | spin_lock_irqsave(q->queue_lock, flags); | ||
470 | sdev = q->queuedata; | ||
471 | if (!sdev || !get_device(&sdev->sdev_gendev)) | ||
472 | err = -ENODEV; | ||
473 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
474 | |||
475 | if (!err) { | ||
476 | err = scsi_dh_handler_attach(sdev, scsi_dh); | ||
477 | |||
478 | put_device(&sdev->sdev_gendev); | ||
479 | } | ||
480 | return err; | ||
481 | } | ||
482 | EXPORT_SYMBOL_GPL(scsi_dh_attach); | ||
483 | |||
484 | /* | ||
485 | * scsi_dh_handler_detach - Detach device handler | ||
486 | * @sdev - sdev the handler should be detached from | ||
487 | * | ||
488 | * This function will detach the device handler only | ||
489 | * if the sdev is not part of the internal list, ie | ||
490 | * if it has been attached manually. | ||
491 | */ | ||
492 | void scsi_dh_detach(struct request_queue *q) | ||
493 | { | ||
494 | unsigned long flags; | ||
495 | struct scsi_device *sdev; | ||
496 | struct scsi_device_handler *scsi_dh = NULL; | ||
497 | |||
498 | spin_lock_irqsave(q->queue_lock, flags); | ||
499 | sdev = q->queuedata; | ||
500 | if (!sdev || !get_device(&sdev->sdev_gendev)) | ||
501 | sdev = NULL; | ||
502 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
503 | |||
504 | if (!sdev) | ||
505 | return; | ||
506 | |||
507 | if (sdev->scsi_dh_data) { | ||
508 | /* if sdev is not on internal list, detach */ | ||
509 | scsi_dh = sdev->scsi_dh_data->scsi_dh; | ||
510 | if (!device_handler_match(scsi_dh, sdev)) | ||
511 | scsi_dh_handler_detach(sdev, scsi_dh); | ||
512 | } | ||
513 | put_device(&sdev->sdev_gendev); | ||
514 | } | ||
515 | EXPORT_SYMBOL_GPL(scsi_dh_detach); | ||
516 | |||
517 | static struct notifier_block scsi_dh_nb = { | ||
518 | .notifier_call = scsi_dh_notifier | ||
519 | }; | ||
520 | |||
521 | static int __init scsi_dh_init(void) | ||
522 | { | ||
523 | int r; | ||
524 | |||
525 | r = bus_register_notifier(&scsi_bus_type, &scsi_dh_nb); | ||
526 | |||
527 | if (!r) | ||
528 | bus_for_each_dev(&scsi_bus_type, NULL, NULL, | ||
529 | scsi_dh_sysfs_attr_add); | ||
530 | |||
531 | return r; | ||
532 | } | ||
533 | |||
534 | static void __exit scsi_dh_exit(void) | ||
535 | { | ||
536 | bus_for_each_dev(&scsi_bus_type, NULL, NULL, | ||
537 | scsi_dh_sysfs_attr_remove); | ||
538 | bus_unregister_notifier(&scsi_bus_type, &scsi_dh_nb); | ||
539 | } | ||
540 | |||
541 | module_init(scsi_dh_init); | ||
542 | module_exit(scsi_dh_exit); | ||
543 | |||
160 | MODULE_DESCRIPTION("SCSI device handler"); | 544 | MODULE_DESCRIPTION("SCSI device handler"); |
161 | MODULE_AUTHOR("Chandra Seetharaman <sekharan@us.ibm.com>"); | 545 | MODULE_AUTHOR("Chandra Seetharaman <sekharan@us.ibm.com>"); |
162 | MODULE_LICENSE("GPL"); | 546 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c new file mode 100644 index 000000000000..fcdd73f25625 --- /dev/null +++ b/drivers/scsi/device_handler/scsi_dh_alua.c | |||
@@ -0,0 +1,802 @@ | |||
1 | /* | ||
2 | * Generic SCSI-3 ALUA SCSI Device Handler | ||
3 | * | ||
4 | * Copyright (C) 2007, 2008 Hannes Reinecke, SUSE Linux Products GmbH. | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | * | ||
21 | */ | ||
22 | #include <scsi/scsi.h> | ||
23 | #include <scsi/scsi_eh.h> | ||
24 | #include <scsi/scsi_dh.h> | ||
25 | |||
26 | #define ALUA_DH_NAME "alua" | ||
27 | #define ALUA_DH_VER "1.2" | ||
28 | |||
29 | #define TPGS_STATE_OPTIMIZED 0x0 | ||
30 | #define TPGS_STATE_NONOPTIMIZED 0x1 | ||
31 | #define TPGS_STATE_STANDBY 0x2 | ||
32 | #define TPGS_STATE_UNAVAILABLE 0x3 | ||
33 | #define TPGS_STATE_OFFLINE 0xe | ||
34 | #define TPGS_STATE_TRANSITIONING 0xf | ||
35 | |||
36 | #define TPGS_SUPPORT_NONE 0x00 | ||
37 | #define TPGS_SUPPORT_OPTIMIZED 0x01 | ||
38 | #define TPGS_SUPPORT_NONOPTIMIZED 0x02 | ||
39 | #define TPGS_SUPPORT_STANDBY 0x04 | ||
40 | #define TPGS_SUPPORT_UNAVAILABLE 0x08 | ||
41 | #define TPGS_SUPPORT_OFFLINE 0x40 | ||
42 | #define TPGS_SUPPORT_TRANSITION 0x80 | ||
43 | |||
44 | #define TPGS_MODE_UNINITIALIZED -1 | ||
45 | #define TPGS_MODE_NONE 0x0 | ||
46 | #define TPGS_MODE_IMPLICIT 0x1 | ||
47 | #define TPGS_MODE_EXPLICIT 0x2 | ||
48 | |||
49 | #define ALUA_INQUIRY_SIZE 36 | ||
50 | #define ALUA_FAILOVER_TIMEOUT (60 * HZ) | ||
51 | #define ALUA_FAILOVER_RETRIES 5 | ||
52 | |||
53 | struct alua_dh_data { | ||
54 | int group_id; | ||
55 | int rel_port; | ||
56 | int tpgs; | ||
57 | int state; | ||
58 | unsigned char inq[ALUA_INQUIRY_SIZE]; | ||
59 | unsigned char *buff; | ||
60 | int bufflen; | ||
61 | unsigned char sense[SCSI_SENSE_BUFFERSIZE]; | ||
62 | int senselen; | ||
63 | }; | ||
64 | |||
65 | #define ALUA_POLICY_SWITCH_CURRENT 0 | ||
66 | #define ALUA_POLICY_SWITCH_ALL 1 | ||
67 | |||
68 | static inline struct alua_dh_data *get_alua_data(struct scsi_device *sdev) | ||
69 | { | ||
70 | struct scsi_dh_data *scsi_dh_data = sdev->scsi_dh_data; | ||
71 | BUG_ON(scsi_dh_data == NULL); | ||
72 | return ((struct alua_dh_data *) scsi_dh_data->buf); | ||
73 | } | ||
74 | |||
75 | static int realloc_buffer(struct alua_dh_data *h, unsigned len) | ||
76 | { | ||
77 | if (h->buff && h->buff != h->inq) | ||
78 | kfree(h->buff); | ||
79 | |||
80 | h->buff = kmalloc(len, GFP_NOIO); | ||
81 | if (!h->buff) { | ||
82 | h->buff = h->inq; | ||
83 | h->bufflen = ALUA_INQUIRY_SIZE; | ||
84 | return 1; | ||
85 | } | ||
86 | h->bufflen = len; | ||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static struct request *get_alua_req(struct scsi_device *sdev, | ||
91 | void *buffer, unsigned buflen, int rw) | ||
92 | { | ||
93 | struct request *rq; | ||
94 | struct request_queue *q = sdev->request_queue; | ||
95 | |||
96 | rq = blk_get_request(q, rw, GFP_NOIO); | ||
97 | |||
98 | if (!rq) { | ||
99 | sdev_printk(KERN_INFO, sdev, | ||
100 | "%s: blk_get_request failed\n", __func__); | ||
101 | return NULL; | ||
102 | } | ||
103 | |||
104 | if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) { | ||
105 | blk_put_request(rq); | ||
106 | sdev_printk(KERN_INFO, sdev, | ||
107 | "%s: blk_rq_map_kern failed\n", __func__); | ||
108 | return NULL; | ||
109 | } | ||
110 | |||
111 | rq->cmd_type = REQ_TYPE_BLOCK_PC; | ||
112 | rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE; | ||
113 | rq->retries = ALUA_FAILOVER_RETRIES; | ||
114 | rq->timeout = ALUA_FAILOVER_TIMEOUT; | ||
115 | |||
116 | return rq; | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * submit_std_inquiry - Issue a standard INQUIRY command | ||
121 | * @sdev: sdev the command should be send to | ||
122 | */ | ||
123 | static int submit_std_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) | ||
124 | { | ||
125 | struct request *rq; | ||
126 | int err = SCSI_DH_RES_TEMP_UNAVAIL; | ||
127 | |||
128 | rq = get_alua_req(sdev, h->inq, ALUA_INQUIRY_SIZE, READ); | ||
129 | if (!rq) | ||
130 | goto done; | ||
131 | |||
132 | /* Prepare the command. */ | ||
133 | rq->cmd[0] = INQUIRY; | ||
134 | rq->cmd[1] = 0; | ||
135 | rq->cmd[2] = 0; | ||
136 | rq->cmd[4] = ALUA_INQUIRY_SIZE; | ||
137 | rq->cmd_len = COMMAND_SIZE(INQUIRY); | ||
138 | |||
139 | rq->sense = h->sense; | ||
140 | memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); | ||
141 | rq->sense_len = h->senselen = 0; | ||
142 | |||
143 | err = blk_execute_rq(rq->q, NULL, rq, 1); | ||
144 | if (err == -EIO) { | ||
145 | sdev_printk(KERN_INFO, sdev, | ||
146 | "%s: std inquiry failed with %x\n", | ||
147 | ALUA_DH_NAME, rq->errors); | ||
148 | h->senselen = rq->sense_len; | ||
149 | err = SCSI_DH_IO; | ||
150 | } | ||
151 | blk_put_request(rq); | ||
152 | done: | ||
153 | return err; | ||
154 | } | ||
155 | |||
156 | /* | ||
157 | * submit_vpd_inquiry - Issue an INQUIRY VPD page 0x83 command | ||
158 | * @sdev: sdev the command should be sent to | ||
159 | */ | ||
160 | static int submit_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) | ||
161 | { | ||
162 | struct request *rq; | ||
163 | int err = SCSI_DH_RES_TEMP_UNAVAIL; | ||
164 | |||
165 | rq = get_alua_req(sdev, h->buff, h->bufflen, READ); | ||
166 | if (!rq) | ||
167 | goto done; | ||
168 | |||
169 | /* Prepare the command. */ | ||
170 | rq->cmd[0] = INQUIRY; | ||
171 | rq->cmd[1] = 1; | ||
172 | rq->cmd[2] = 0x83; | ||
173 | rq->cmd[4] = h->bufflen; | ||
174 | rq->cmd_len = COMMAND_SIZE(INQUIRY); | ||
175 | |||
176 | rq->sense = h->sense; | ||
177 | memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); | ||
178 | rq->sense_len = h->senselen = 0; | ||
179 | |||
180 | err = blk_execute_rq(rq->q, NULL, rq, 1); | ||
181 | if (err == -EIO) { | ||
182 | sdev_printk(KERN_INFO, sdev, | ||
183 | "%s: evpd inquiry failed with %x\n", | ||
184 | ALUA_DH_NAME, rq->errors); | ||
185 | h->senselen = rq->sense_len; | ||
186 | err = SCSI_DH_IO; | ||
187 | } | ||
188 | blk_put_request(rq); | ||
189 | done: | ||
190 | return err; | ||
191 | } | ||
192 | |||
193 | /* | ||
194 | * submit_rtpg - Issue a REPORT TARGET GROUP STATES command | ||
195 | * @sdev: sdev the command should be sent to | ||
196 | */ | ||
197 | static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) | ||
198 | { | ||
199 | struct request *rq; | ||
200 | int err = SCSI_DH_RES_TEMP_UNAVAIL; | ||
201 | |||
202 | rq = get_alua_req(sdev, h->buff, h->bufflen, READ); | ||
203 | if (!rq) | ||
204 | goto done; | ||
205 | |||
206 | /* Prepare the command. */ | ||
207 | rq->cmd[0] = MAINTENANCE_IN; | ||
208 | rq->cmd[1] = MI_REPORT_TARGET_PGS; | ||
209 | rq->cmd[6] = (h->bufflen >> 24) & 0xff; | ||
210 | rq->cmd[7] = (h->bufflen >> 16) & 0xff; | ||
211 | rq->cmd[8] = (h->bufflen >> 8) & 0xff; | ||
212 | rq->cmd[9] = h->bufflen & 0xff; | ||
213 | rq->cmd_len = COMMAND_SIZE(MAINTENANCE_IN); | ||
214 | |||
215 | rq->sense = h->sense; | ||
216 | memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); | ||
217 | rq->sense_len = h->senselen = 0; | ||
218 | |||
219 | err = blk_execute_rq(rq->q, NULL, rq, 1); | ||
220 | if (err == -EIO) { | ||
221 | sdev_printk(KERN_INFO, sdev, | ||
222 | "%s: rtpg failed with %x\n", | ||
223 | ALUA_DH_NAME, rq->errors); | ||
224 | h->senselen = rq->sense_len; | ||
225 | err = SCSI_DH_IO; | ||
226 | } | ||
227 | blk_put_request(rq); | ||
228 | done: | ||
229 | return err; | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * submit_stpg - Issue a SET TARGET GROUP STATES command | ||
234 | * @sdev: sdev the command should be sent to | ||
235 | * | ||
236 | * Currently we're only setting the current target port group state | ||
237 | * to 'active/optimized' and let the array firmware figure out | ||
238 | * the states of the remaining groups. | ||
239 | */ | ||
240 | static unsigned submit_stpg(struct scsi_device *sdev, struct alua_dh_data *h) | ||
241 | { | ||
242 | struct request *rq; | ||
243 | int err = SCSI_DH_RES_TEMP_UNAVAIL; | ||
244 | int stpg_len = 8; | ||
245 | |||
246 | /* Prepare the data buffer */ | ||
247 | memset(h->buff, 0, stpg_len); | ||
248 | h->buff[4] = TPGS_STATE_OPTIMIZED & 0x0f; | ||
249 | h->buff[6] = (h->group_id >> 8) & 0x0f; | ||
250 | h->buff[7] = h->group_id & 0x0f; | ||
251 | |||
252 | rq = get_alua_req(sdev, h->buff, stpg_len, WRITE); | ||
253 | if (!rq) | ||
254 | goto done; | ||
255 | |||
256 | /* Prepare the command. */ | ||
257 | rq->cmd[0] = MAINTENANCE_OUT; | ||
258 | rq->cmd[1] = MO_SET_TARGET_PGS; | ||
259 | rq->cmd[6] = (stpg_len >> 24) & 0xff; | ||
260 | rq->cmd[7] = (stpg_len >> 16) & 0xff; | ||
261 | rq->cmd[8] = (stpg_len >> 8) & 0xff; | ||
262 | rq->cmd[9] = stpg_len & 0xff; | ||
263 | rq->cmd_len = COMMAND_SIZE(MAINTENANCE_OUT); | ||
264 | |||
265 | rq->sense = h->sense; | ||
266 | memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); | ||
267 | rq->sense_len = h->senselen = 0; | ||
268 | |||
269 | err = blk_execute_rq(rq->q, NULL, rq, 1); | ||
270 | if (err == -EIO) { | ||
271 | sdev_printk(KERN_INFO, sdev, | ||
272 | "%s: stpg failed with %x\n", | ||
273 | ALUA_DH_NAME, rq->errors); | ||
274 | h->senselen = rq->sense_len; | ||
275 | err = SCSI_DH_IO; | ||
276 | } | ||
277 | blk_put_request(rq); | ||
278 | done: | ||
279 | return err; | ||
280 | } | ||
281 | |||
282 | /* | ||
283 | * alua_std_inquiry - Evaluate standard INQUIRY command | ||
284 | * @sdev: device to be checked | ||
285 | * | ||
286 | * Just extract the TPGS setting to find out if ALUA | ||
287 | * is supported. | ||
288 | */ | ||
289 | static int alua_std_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) | ||
290 | { | ||
291 | int err; | ||
292 | |||
293 | err = submit_std_inquiry(sdev, h); | ||
294 | |||
295 | if (err != SCSI_DH_OK) | ||
296 | return err; | ||
297 | |||
298 | /* Check TPGS setting */ | ||
299 | h->tpgs = (h->inq[5] >> 4) & 0x3; | ||
300 | switch (h->tpgs) { | ||
301 | case TPGS_MODE_EXPLICIT|TPGS_MODE_IMPLICIT: | ||
302 | sdev_printk(KERN_INFO, sdev, | ||
303 | "%s: supports implicit and explicit TPGS\n", | ||
304 | ALUA_DH_NAME); | ||
305 | break; | ||
306 | case TPGS_MODE_EXPLICIT: | ||
307 | sdev_printk(KERN_INFO, sdev, "%s: supports explicit TPGS\n", | ||
308 | ALUA_DH_NAME); | ||
309 | break; | ||
310 | case TPGS_MODE_IMPLICIT: | ||
311 | sdev_printk(KERN_INFO, sdev, "%s: supports implicit TPGS\n", | ||
312 | ALUA_DH_NAME); | ||
313 | break; | ||
314 | default: | ||
315 | h->tpgs = TPGS_MODE_NONE; | ||
316 | sdev_printk(KERN_INFO, sdev, "%s: not supported\n", | ||
317 | ALUA_DH_NAME); | ||
318 | err = SCSI_DH_DEV_UNSUPP; | ||
319 | break; | ||
320 | } | ||
321 | |||
322 | return err; | ||
323 | } | ||
324 | |||
325 | /* | ||
326 | * alua_vpd_inquiry - Evaluate INQUIRY vpd page 0x83 | ||
327 | * @sdev: device to be checked | ||
328 | * | ||
329 | * Extract the relative target port and the target port group | ||
330 | * descriptor from the list of identificators. | ||
331 | */ | ||
332 | static int alua_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) | ||
333 | { | ||
334 | int len; | ||
335 | unsigned err; | ||
336 | unsigned char *d; | ||
337 | |||
338 | retry: | ||
339 | err = submit_vpd_inquiry(sdev, h); | ||
340 | |||
341 | if (err != SCSI_DH_OK) | ||
342 | return err; | ||
343 | |||
344 | /* Check if vpd page exceeds initial buffer */ | ||
345 | len = (h->buff[2] << 8) + h->buff[3] + 4; | ||
346 | if (len > h->bufflen) { | ||
347 | /* Resubmit with the correct length */ | ||
348 | if (realloc_buffer(h, len)) { | ||
349 | sdev_printk(KERN_WARNING, sdev, | ||
350 | "%s: kmalloc buffer failed\n", | ||
351 | ALUA_DH_NAME); | ||
352 | /* Temporary failure, bypass */ | ||
353 | return SCSI_DH_DEV_TEMP_BUSY; | ||
354 | } | ||
355 | goto retry; | ||
356 | } | ||
357 | |||
358 | /* | ||
359 | * Now look for the correct descriptor. | ||
360 | */ | ||
361 | d = h->buff + 4; | ||
362 | while (d < h->buff + len) { | ||
363 | switch (d[1] & 0xf) { | ||
364 | case 0x4: | ||
365 | /* Relative target port */ | ||
366 | h->rel_port = (d[6] << 8) + d[7]; | ||
367 | break; | ||
368 | case 0x5: | ||
369 | /* Target port group */ | ||
370 | h->group_id = (d[6] << 8) + d[7]; | ||
371 | break; | ||
372 | default: | ||
373 | break; | ||
374 | } | ||
375 | d += d[3] + 4; | ||
376 | } | ||
377 | |||
378 | if (h->group_id == -1) { | ||
379 | /* | ||
380 | * Internal error; TPGS supported but required | ||
381 | * VPD identification descriptors not present. | ||
382 | * Disable ALUA support | ||
383 | */ | ||
384 | sdev_printk(KERN_INFO, sdev, | ||
385 | "%s: No target port descriptors found\n", | ||
386 | ALUA_DH_NAME); | ||
387 | h->state = TPGS_STATE_OPTIMIZED; | ||
388 | h->tpgs = TPGS_MODE_NONE; | ||
389 | err = SCSI_DH_DEV_UNSUPP; | ||
390 | } else { | ||
391 | sdev_printk(KERN_INFO, sdev, | ||
392 | "%s: port group %02x rel port %02x\n", | ||
393 | ALUA_DH_NAME, h->group_id, h->rel_port); | ||
394 | } | ||
395 | |||
396 | return err; | ||
397 | } | ||
398 | |||
399 | static char print_alua_state(int state) | ||
400 | { | ||
401 | switch (state) { | ||
402 | case TPGS_STATE_OPTIMIZED: | ||
403 | return 'A'; | ||
404 | case TPGS_STATE_NONOPTIMIZED: | ||
405 | return 'N'; | ||
406 | case TPGS_STATE_STANDBY: | ||
407 | return 'S'; | ||
408 | case TPGS_STATE_UNAVAILABLE: | ||
409 | return 'U'; | ||
410 | case TPGS_STATE_OFFLINE: | ||
411 | return 'O'; | ||
412 | case TPGS_STATE_TRANSITIONING: | ||
413 | return 'T'; | ||
414 | default: | ||
415 | return 'X'; | ||
416 | } | ||
417 | } | ||
418 | |||
419 | static int alua_check_sense(struct scsi_device *sdev, | ||
420 | struct scsi_sense_hdr *sense_hdr) | ||
421 | { | ||
422 | switch (sense_hdr->sense_key) { | ||
423 | case NOT_READY: | ||
424 | if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0a) | ||
425 | /* | ||
426 | * LUN Not Accessible - ALUA state transition | ||
427 | */ | ||
428 | return NEEDS_RETRY; | ||
429 | if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0b) | ||
430 | /* | ||
431 | * LUN Not Accessible -- Target port in standby state | ||
432 | */ | ||
433 | return SUCCESS; | ||
434 | if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0c) | ||
435 | /* | ||
436 | * LUN Not Accessible -- Target port in unavailable state | ||
437 | */ | ||
438 | return SUCCESS; | ||
439 | if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x12) | ||
440 | /* | ||
441 | * LUN Not Ready -- Offline | ||
442 | */ | ||
443 | return SUCCESS; | ||
444 | break; | ||
445 | case UNIT_ATTENTION: | ||
446 | if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00) | ||
447 | /* | ||
448 | * Power On, Reset, or Bus Device Reset, just retry. | ||
449 | */ | ||
450 | return NEEDS_RETRY; | ||
451 | if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06) { | ||
452 | /* | ||
453 | * ALUA state changed | ||
454 | */ | ||
455 | return NEEDS_RETRY; | ||
456 | } | ||
457 | if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07) { | ||
458 | /* | ||
459 | * Implicit ALUA state transition failed | ||
460 | */ | ||
461 | return NEEDS_RETRY; | ||
462 | } | ||
463 | break; | ||
464 | } | ||
465 | |||
466 | return SCSI_RETURN_NOT_HANDLED; | ||
467 | } | ||
468 | |||
469 | /* | ||
470 | * alua_stpg - Evaluate SET TARGET GROUP STATES | ||
471 | * @sdev: the device to be evaluated | ||
472 | * @state: the new target group state | ||
473 | * | ||
474 | * Send a SET TARGET GROUP STATES command to the device. | ||
475 | * We only have to test here if we should resubmit the command; | ||
476 | * any other error is assumed as a failure. | ||
477 | */ | ||
478 | static int alua_stpg(struct scsi_device *sdev, int state, | ||
479 | struct alua_dh_data *h) | ||
480 | { | ||
481 | struct scsi_sense_hdr sense_hdr; | ||
482 | unsigned err; | ||
483 | int retry = ALUA_FAILOVER_RETRIES; | ||
484 | |||
485 | retry: | ||
486 | err = submit_stpg(sdev, h); | ||
487 | if (err == SCSI_DH_IO && h->senselen > 0) { | ||
488 | err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, | ||
489 | &sense_hdr); | ||
490 | if (!err) | ||
491 | return SCSI_DH_IO; | ||
492 | err = alua_check_sense(sdev, &sense_hdr); | ||
493 | if (retry > 0 && err == NEEDS_RETRY) { | ||
494 | retry--; | ||
495 | goto retry; | ||
496 | } | ||
497 | sdev_printk(KERN_INFO, sdev, | ||
498 | "%s: stpg sense code: %02x/%02x/%02x\n", | ||
499 | ALUA_DH_NAME, sense_hdr.sense_key, | ||
500 | sense_hdr.asc, sense_hdr.ascq); | ||
501 | err = SCSI_DH_IO; | ||
502 | } | ||
503 | if (err == SCSI_DH_OK) { | ||
504 | h->state = state; | ||
505 | sdev_printk(KERN_INFO, sdev, | ||
506 | "%s: port group %02x switched to state %c\n", | ||
507 | ALUA_DH_NAME, h->group_id, | ||
508 | print_alua_state(h->state) ); | ||
509 | } | ||
510 | return err; | ||
511 | } | ||
512 | |||
513 | /* | ||
514 | * alua_rtpg - Evaluate REPORT TARGET GROUP STATES | ||
515 | * @sdev: the device to be evaluated. | ||
516 | * | ||
517 | * Evaluate the Target Port Group State. | ||
518 | * Returns SCSI_DH_DEV_OFFLINED if the path is | ||
519 | * found to be unuseable. | ||
520 | */ | ||
521 | static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) | ||
522 | { | ||
523 | struct scsi_sense_hdr sense_hdr; | ||
524 | int len, k, off, valid_states = 0; | ||
525 | char *ucp; | ||
526 | unsigned err; | ||
527 | |||
528 | retry: | ||
529 | err = submit_rtpg(sdev, h); | ||
530 | |||
531 | if (err == SCSI_DH_IO && h->senselen > 0) { | ||
532 | err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, | ||
533 | &sense_hdr); | ||
534 | if (!err) | ||
535 | return SCSI_DH_IO; | ||
536 | |||
537 | err = alua_check_sense(sdev, &sense_hdr); | ||
538 | if (err == NEEDS_RETRY) | ||
539 | goto retry; | ||
540 | sdev_printk(KERN_INFO, sdev, | ||
541 | "%s: rtpg sense code %02x/%02x/%02x\n", | ||
542 | ALUA_DH_NAME, sense_hdr.sense_key, | ||
543 | sense_hdr.asc, sense_hdr.ascq); | ||
544 | err = SCSI_DH_IO; | ||
545 | } | ||
546 | if (err != SCSI_DH_OK) | ||
547 | return err; | ||
548 | |||
549 | len = (h->buff[0] << 24) + (h->buff[1] << 16) + | ||
550 | (h->buff[2] << 8) + h->buff[3] + 4; | ||
551 | |||
552 | if (len > h->bufflen) { | ||
553 | /* Resubmit with the correct length */ | ||
554 | if (realloc_buffer(h, len)) { | ||
555 | sdev_printk(KERN_WARNING, sdev, | ||
556 | "%s: kmalloc buffer failed\n",__func__); | ||
557 | /* Temporary failure, bypass */ | ||
558 | return SCSI_DH_DEV_TEMP_BUSY; | ||
559 | } | ||
560 | goto retry; | ||
561 | } | ||
562 | |||
563 | for (k = 4, ucp = h->buff + 4; k < len; k += off, ucp += off) { | ||
564 | if (h->group_id == (ucp[2] << 8) + ucp[3]) { | ||
565 | h->state = ucp[0] & 0x0f; | ||
566 | valid_states = ucp[1]; | ||
567 | } | ||
568 | off = 8 + (ucp[7] * 4); | ||
569 | } | ||
570 | |||
571 | sdev_printk(KERN_INFO, sdev, | ||
572 | "%s: port group %02x state %c supports %c%c%c%c%c%c\n", | ||
573 | ALUA_DH_NAME, h->group_id, print_alua_state(h->state), | ||
574 | valid_states&TPGS_SUPPORT_TRANSITION?'T':'t', | ||
575 | valid_states&TPGS_SUPPORT_OFFLINE?'O':'o', | ||
576 | valid_states&TPGS_SUPPORT_UNAVAILABLE?'U':'u', | ||
577 | valid_states&TPGS_SUPPORT_STANDBY?'S':'s', | ||
578 | valid_states&TPGS_SUPPORT_NONOPTIMIZED?'N':'n', | ||
579 | valid_states&TPGS_SUPPORT_OPTIMIZED?'A':'a'); | ||
580 | |||
581 | if (h->tpgs & TPGS_MODE_EXPLICIT) { | ||
582 | switch (h->state) { | ||
583 | case TPGS_STATE_TRANSITIONING: | ||
584 | /* State transition, retry */ | ||
585 | goto retry; | ||
586 | break; | ||
587 | case TPGS_STATE_OFFLINE: | ||
588 | /* Path is offline, fail */ | ||
589 | err = SCSI_DH_DEV_OFFLINED; | ||
590 | break; | ||
591 | default: | ||
592 | break; | ||
593 | } | ||
594 | } else { | ||
595 | /* Only Implicit ALUA support */ | ||
596 | if (h->state == TPGS_STATE_OPTIMIZED || | ||
597 | h->state == TPGS_STATE_NONOPTIMIZED || | ||
598 | h->state == TPGS_STATE_STANDBY) | ||
599 | /* Useable path if active */ | ||
600 | err = SCSI_DH_OK; | ||
601 | else | ||
602 | /* Path unuseable for unavailable/offline */ | ||
603 | err = SCSI_DH_DEV_OFFLINED; | ||
604 | } | ||
605 | return err; | ||
606 | } | ||
607 | |||
608 | /* | ||
609 | * alua_initialize - Initialize ALUA state | ||
610 | * @sdev: the device to be initialized | ||
611 | * | ||
612 | * For the prep_fn to work correctly we have | ||
613 | * to initialize the ALUA state for the device. | ||
614 | */ | ||
615 | static int alua_initialize(struct scsi_device *sdev, struct alua_dh_data *h) | ||
616 | { | ||
617 | int err; | ||
618 | |||
619 | err = alua_std_inquiry(sdev, h); | ||
620 | if (err != SCSI_DH_OK) | ||
621 | goto out; | ||
622 | |||
623 | err = alua_vpd_inquiry(sdev, h); | ||
624 | if (err != SCSI_DH_OK) | ||
625 | goto out; | ||
626 | |||
627 | err = alua_rtpg(sdev, h); | ||
628 | if (err != SCSI_DH_OK) | ||
629 | goto out; | ||
630 | |||
631 | out: | ||
632 | return err; | ||
633 | } | ||
634 | |||
635 | /* | ||
636 | * alua_activate - activate a path | ||
637 | * @sdev: device on the path to be activated | ||
638 | * | ||
639 | * We're currently switching the port group to be activated only and | ||
640 | * let the array figure out the rest. | ||
641 | * There may be other arrays which require us to switch all port groups | ||
642 | * based on a certain policy. But until we actually encounter them it | ||
643 | * should be okay. | ||
644 | */ | ||
645 | static int alua_activate(struct scsi_device *sdev) | ||
646 | { | ||
647 | struct alua_dh_data *h = get_alua_data(sdev); | ||
648 | int err = SCSI_DH_OK; | ||
649 | |||
650 | if (h->group_id != -1) { | ||
651 | err = alua_rtpg(sdev, h); | ||
652 | if (err != SCSI_DH_OK) | ||
653 | goto out; | ||
654 | } | ||
655 | |||
656 | if (h->tpgs == TPGS_MODE_EXPLICIT && h->state != TPGS_STATE_OPTIMIZED) | ||
657 | err = alua_stpg(sdev, TPGS_STATE_OPTIMIZED, h); | ||
658 | |||
659 | out: | ||
660 | return err; | ||
661 | } | ||
662 | |||
663 | /* | ||
664 | * alua_prep_fn - request callback | ||
665 | * | ||
666 | * Fail I/O to all paths not in state | ||
667 | * active/optimized or active/non-optimized. | ||
668 | */ | ||
669 | static int alua_prep_fn(struct scsi_device *sdev, struct request *req) | ||
670 | { | ||
671 | struct alua_dh_data *h = get_alua_data(sdev); | ||
672 | int ret = BLKPREP_OK; | ||
673 | |||
674 | if (h->state != TPGS_STATE_OPTIMIZED && | ||
675 | h->state != TPGS_STATE_NONOPTIMIZED) { | ||
676 | ret = BLKPREP_KILL; | ||
677 | req->cmd_flags |= REQ_QUIET; | ||
678 | } | ||
679 | return ret; | ||
680 | |||
681 | } | ||
682 | |||
683 | const struct scsi_dh_devlist alua_dev_list[] = { | ||
684 | {"HP", "MSA VOLUME" }, | ||
685 | {"HP", "HSV101" }, | ||
686 | {"HP", "HSV111" }, | ||
687 | {"HP", "HSV200" }, | ||
688 | {"HP", "HSV210" }, | ||
689 | {"HP", "HSV300" }, | ||
690 | {"IBM", "2107900" }, | ||
691 | {"IBM", "2145" }, | ||
692 | {"Pillar", "Axiom" }, | ||
693 | {NULL, NULL} | ||
694 | }; | ||
695 | |||
696 | static int alua_bus_attach(struct scsi_device *sdev); | ||
697 | static void alua_bus_detach(struct scsi_device *sdev); | ||
698 | |||
699 | static struct scsi_device_handler alua_dh = { | ||
700 | .name = ALUA_DH_NAME, | ||
701 | .module = THIS_MODULE, | ||
702 | .devlist = alua_dev_list, | ||
703 | .attach = alua_bus_attach, | ||
704 | .detach = alua_bus_detach, | ||
705 | .prep_fn = alua_prep_fn, | ||
706 | .check_sense = alua_check_sense, | ||
707 | .activate = alua_activate, | ||
708 | }; | ||
709 | |||
710 | /* | ||
711 | * alua_bus_attach - Attach device handler | ||
712 | * @sdev: device to be attached to | ||
713 | */ | ||
714 | static int alua_bus_attach(struct scsi_device *sdev) | ||
715 | { | ||
716 | struct scsi_dh_data *scsi_dh_data; | ||
717 | struct alua_dh_data *h; | ||
718 | unsigned long flags; | ||
719 | int err = SCSI_DH_OK; | ||
720 | |||
721 | scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) | ||
722 | + sizeof(*h) , GFP_KERNEL); | ||
723 | if (!scsi_dh_data) { | ||
724 | sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n", | ||
725 | ALUA_DH_NAME); | ||
726 | return -ENOMEM; | ||
727 | } | ||
728 | |||
729 | scsi_dh_data->scsi_dh = &alua_dh; | ||
730 | h = (struct alua_dh_data *) scsi_dh_data->buf; | ||
731 | h->tpgs = TPGS_MODE_UNINITIALIZED; | ||
732 | h->state = TPGS_STATE_OPTIMIZED; | ||
733 | h->group_id = -1; | ||
734 | h->rel_port = -1; | ||
735 | h->buff = h->inq; | ||
736 | h->bufflen = ALUA_INQUIRY_SIZE; | ||
737 | |||
738 | err = alua_initialize(sdev, h); | ||
739 | if (err != SCSI_DH_OK) | ||
740 | goto failed; | ||
741 | |||
742 | if (!try_module_get(THIS_MODULE)) | ||
743 | goto failed; | ||
744 | |||
745 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | ||
746 | sdev->scsi_dh_data = scsi_dh_data; | ||
747 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
748 | |||
749 | return 0; | ||
750 | |||
751 | failed: | ||
752 | kfree(scsi_dh_data); | ||
753 | sdev_printk(KERN_ERR, sdev, "%s: not attached\n", ALUA_DH_NAME); | ||
754 | return -EINVAL; | ||
755 | } | ||
756 | |||
757 | /* | ||
758 | * alua_bus_detach - Detach device handler | ||
759 | * @sdev: device to be detached from | ||
760 | */ | ||
761 | static void alua_bus_detach(struct scsi_device *sdev) | ||
762 | { | ||
763 | struct scsi_dh_data *scsi_dh_data; | ||
764 | struct alua_dh_data *h; | ||
765 | unsigned long flags; | ||
766 | |||
767 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | ||
768 | scsi_dh_data = sdev->scsi_dh_data; | ||
769 | sdev->scsi_dh_data = NULL; | ||
770 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
771 | |||
772 | h = (struct alua_dh_data *) scsi_dh_data->buf; | ||
773 | if (h->buff && h->inq != h->buff) | ||
774 | kfree(h->buff); | ||
775 | kfree(scsi_dh_data); | ||
776 | module_put(THIS_MODULE); | ||
777 | sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", ALUA_DH_NAME); | ||
778 | } | ||
779 | |||
780 | static int __init alua_init(void) | ||
781 | { | ||
782 | int r; | ||
783 | |||
784 | r = scsi_register_device_handler(&alua_dh); | ||
785 | if (r != 0) | ||
786 | printk(KERN_ERR "%s: Failed to register scsi device handler", | ||
787 | ALUA_DH_NAME); | ||
788 | return r; | ||
789 | } | ||
790 | |||
791 | static void __exit alua_exit(void) | ||
792 | { | ||
793 | scsi_unregister_device_handler(&alua_dh); | ||
794 | } | ||
795 | |||
796 | module_init(alua_init); | ||
797 | module_exit(alua_exit); | ||
798 | |||
799 | MODULE_DESCRIPTION("DM Multipath ALUA support"); | ||
800 | MODULE_AUTHOR("Hannes Reinecke <hare@suse.de>"); | ||
801 | MODULE_LICENSE("GPL"); | ||
802 | MODULE_VERSION(ALUA_DH_VER); | ||
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index f2467e936e55..aa46b131b20e 100644 --- a/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/drivers/scsi/device_handler/scsi_dh_emc.c | |||
@@ -25,28 +25,31 @@ | |||
25 | #include <scsi/scsi_dh.h> | 25 | #include <scsi/scsi_dh.h> |
26 | #include <scsi/scsi_device.h> | 26 | #include <scsi/scsi_device.h> |
27 | 27 | ||
28 | #define CLARIION_NAME "emc_clariion" | 28 | #define CLARIION_NAME "emc" |
29 | 29 | ||
30 | #define CLARIION_TRESPASS_PAGE 0x22 | 30 | #define CLARIION_TRESPASS_PAGE 0x22 |
31 | #define CLARIION_BUFFER_SIZE 0x80 | 31 | #define CLARIION_BUFFER_SIZE 0xFC |
32 | #define CLARIION_TIMEOUT (60 * HZ) | 32 | #define CLARIION_TIMEOUT (60 * HZ) |
33 | #define CLARIION_RETRIES 3 | 33 | #define CLARIION_RETRIES 3 |
34 | #define CLARIION_UNBOUND_LU -1 | 34 | #define CLARIION_UNBOUND_LU -1 |
35 | #define CLARIION_SP_A 0 | ||
36 | #define CLARIION_SP_B 1 | ||
35 | 37 | ||
36 | static unsigned char long_trespass[] = { | 38 | /* Flags */ |
37 | 0, 0, 0, 0, | 39 | #define CLARIION_SHORT_TRESPASS 1 |
38 | CLARIION_TRESPASS_PAGE, /* Page code */ | 40 | #define CLARIION_HONOR_RESERVATIONS 2 |
39 | 0x09, /* Page length - 2 */ | ||
40 | 0x81, /* Trespass code + Honor reservation bit */ | ||
41 | 0xff, 0xff, /* Trespass target */ | ||
42 | 0, 0, 0, 0, 0, 0 /* Reserved bytes / unknown */ | ||
43 | }; | ||
44 | 41 | ||
45 | static unsigned char long_trespass_hr[] = { | 42 | /* LUN states */ |
46 | 0, 0, 0, 0, | 43 | #define CLARIION_LUN_UNINITIALIZED -1 |
44 | #define CLARIION_LUN_UNBOUND 0 | ||
45 | #define CLARIION_LUN_BOUND 1 | ||
46 | #define CLARIION_LUN_OWNED 2 | ||
47 | |||
48 | static unsigned char long_trespass[] = { | ||
49 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
47 | CLARIION_TRESPASS_PAGE, /* Page code */ | 50 | CLARIION_TRESPASS_PAGE, /* Page code */ |
48 | 0x09, /* Page length - 2 */ | 51 | 0x09, /* Page length - 2 */ |
49 | 0x01, /* Trespass code + Honor reservation bit */ | 52 | 0x01, /* Trespass code */ |
50 | 0xff, 0xff, /* Trespass target */ | 53 | 0xff, 0xff, /* Trespass target */ |
51 | 0, 0, 0, 0, 0, 0 /* Reserved bytes / unknown */ | 54 | 0, 0, 0, 0, 0, 0 /* Reserved bytes / unknown */ |
52 | }; | 55 | }; |
@@ -55,39 +58,56 @@ static unsigned char short_trespass[] = { | |||
55 | 0, 0, 0, 0, | 58 | 0, 0, 0, 0, |
56 | CLARIION_TRESPASS_PAGE, /* Page code */ | 59 | CLARIION_TRESPASS_PAGE, /* Page code */ |
57 | 0x02, /* Page length - 2 */ | 60 | 0x02, /* Page length - 2 */ |
58 | 0x81, /* Trespass code + Honor reservation bit */ | 61 | 0x01, /* Trespass code */ |
59 | 0xff, /* Trespass target */ | 62 | 0xff, /* Trespass target */ |
60 | }; | 63 | }; |
61 | 64 | ||
62 | static unsigned char short_trespass_hr[] = { | 65 | static const char * lun_state[] = |
63 | 0, 0, 0, 0, | 66 | { |
64 | CLARIION_TRESPASS_PAGE, /* Page code */ | 67 | "not bound", |
65 | 0x02, /* Page length - 2 */ | 68 | "bound", |
66 | 0x01, /* Trespass code + Honor reservation bit */ | 69 | "owned", |
67 | 0xff, /* Trespass target */ | ||
68 | }; | 70 | }; |
69 | 71 | ||
70 | struct clariion_dh_data { | 72 | struct clariion_dh_data { |
71 | /* | 73 | /* |
74 | * Flags: | ||
75 | * CLARIION_SHORT_TRESPASS | ||
72 | * Use short trespass command (FC-series) or the long version | 76 | * Use short trespass command (FC-series) or the long version |
73 | * (default for AX/CX CLARiiON arrays). | 77 | * (default for AX/CX CLARiiON arrays). |
74 | */ | 78 | * |
75 | unsigned short_trespass; | 79 | * CLARIION_HONOR_RESERVATIONS |
76 | /* | ||
77 | * Whether or not (default) to honor SCSI reservations when | 80 | * Whether or not (default) to honor SCSI reservations when |
78 | * initiating a switch-over. | 81 | * initiating a switch-over. |
79 | */ | 82 | */ |
80 | unsigned hr; | 83 | unsigned flags; |
81 | /* I/O buffer for both MODE_SELECT and INQUIRY commands. */ | 84 | /* |
85 | * I/O buffer for both MODE_SELECT and INQUIRY commands. | ||
86 | */ | ||
82 | char buffer[CLARIION_BUFFER_SIZE]; | 87 | char buffer[CLARIION_BUFFER_SIZE]; |
83 | /* | 88 | /* |
84 | * SCSI sense buffer for commands -- assumes serial issuance | 89 | * SCSI sense buffer for commands -- assumes serial issuance |
85 | * and completion sequence of all commands for same multipath. | 90 | * and completion sequence of all commands for same multipath. |
86 | */ | 91 | */ |
87 | unsigned char sense[SCSI_SENSE_BUFFERSIZE]; | 92 | unsigned char sense[SCSI_SENSE_BUFFERSIZE]; |
88 | /* which SP (A=0,B=1,UNBOUND=-1) is dflt SP for path's mapped dev */ | 93 | unsigned int senselen; |
94 | /* | ||
95 | * LUN state | ||
96 | */ | ||
97 | int lun_state; | ||
98 | /* | ||
99 | * SP Port number | ||
100 | */ | ||
101 | int port; | ||
102 | /* | ||
103 | * which SP (A=0,B=1,UNBOUND=-1) is the default SP for this | ||
104 | * path's mapped LUN | ||
105 | */ | ||
89 | int default_sp; | 106 | int default_sp; |
90 | /* which SP (A=0,B=1,UNBOUND=-1) is active for path's mapped dev */ | 107 | /* |
108 | * which SP (A=0,B=1,UNBOUND=-1) is the active SP for this | ||
109 | * path's mapped LUN | ||
110 | */ | ||
91 | int current_sp; | 111 | int current_sp; |
92 | }; | 112 | }; |
93 | 113 | ||
@@ -102,19 +122,16 @@ static inline struct clariion_dh_data | |||
102 | /* | 122 | /* |
103 | * Parse MODE_SELECT cmd reply. | 123 | * Parse MODE_SELECT cmd reply. |
104 | */ | 124 | */ |
105 | static int trespass_endio(struct scsi_device *sdev, int result) | 125 | static int trespass_endio(struct scsi_device *sdev, char *sense) |
106 | { | 126 | { |
107 | int err = SCSI_DH_OK; | 127 | int err = SCSI_DH_IO; |
108 | struct scsi_sense_hdr sshdr; | 128 | struct scsi_sense_hdr sshdr; |
109 | struct clariion_dh_data *csdev = get_clariion_data(sdev); | ||
110 | char *sense = csdev->sense; | ||
111 | 129 | ||
112 | if (status_byte(result) == CHECK_CONDITION && | 130 | if (!scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr)) { |
113 | scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr)) { | 131 | sdev_printk(KERN_ERR, sdev, "%s: Found valid sense data 0x%2x, " |
114 | sdev_printk(KERN_ERR, sdev, "Found valid sense data 0x%2x, " | ||
115 | "0x%2x, 0x%2x while sending CLARiiON trespass " | 132 | "0x%2x, 0x%2x while sending CLARiiON trespass " |
116 | "command.\n", sshdr.sense_key, sshdr.asc, | 133 | "command.\n", CLARIION_NAME, sshdr.sense_key, |
117 | sshdr.ascq); | 134 | sshdr.asc, sshdr.ascq); |
118 | 135 | ||
119 | if ((sshdr.sense_key == 0x05) && (sshdr.asc == 0x04) && | 136 | if ((sshdr.sense_key == 0x05) && (sshdr.asc == 0x04) && |
120 | (sshdr.ascq == 0x00)) { | 137 | (sshdr.ascq == 0x00)) { |
@@ -122,9 +139,9 @@ static int trespass_endio(struct scsi_device *sdev, int result) | |||
122 | * Array based copy in progress -- do not send | 139 | * Array based copy in progress -- do not send |
123 | * mode_select or copy will be aborted mid-stream. | 140 | * mode_select or copy will be aborted mid-stream. |
124 | */ | 141 | */ |
125 | sdev_printk(KERN_INFO, sdev, "Array Based Copy in " | 142 | sdev_printk(KERN_INFO, sdev, "%s: Array Based Copy in " |
126 | "progress while sending CLARiiON trespass " | 143 | "progress while sending CLARiiON trespass " |
127 | "command.\n"); | 144 | "command.\n", CLARIION_NAME); |
128 | err = SCSI_DH_DEV_TEMP_BUSY; | 145 | err = SCSI_DH_DEV_TEMP_BUSY; |
129 | } else if ((sshdr.sense_key == 0x02) && (sshdr.asc == 0x04) && | 146 | } else if ((sshdr.sense_key == 0x02) && (sshdr.asc == 0x04) && |
130 | (sshdr.ascq == 0x03)) { | 147 | (sshdr.ascq == 0x03)) { |
@@ -132,160 +149,153 @@ static int trespass_endio(struct scsi_device *sdev, int result) | |||
132 | * LUN Not Ready - Manual Intervention Required | 149 | * LUN Not Ready - Manual Intervention Required |
133 | * indicates in-progress ucode upgrade (NDU). | 150 | * indicates in-progress ucode upgrade (NDU). |
134 | */ | 151 | */ |
135 | sdev_printk(KERN_INFO, sdev, "Detected in-progress " | 152 | sdev_printk(KERN_INFO, sdev, "%s: Detected in-progress " |
136 | "ucode upgrade NDU operation while sending " | 153 | "ucode upgrade NDU operation while sending " |
137 | "CLARiiON trespass command.\n"); | 154 | "CLARiiON trespass command.\n", CLARIION_NAME); |
138 | err = SCSI_DH_DEV_TEMP_BUSY; | 155 | err = SCSI_DH_DEV_TEMP_BUSY; |
139 | } else | 156 | } else |
140 | err = SCSI_DH_DEV_FAILED; | 157 | err = SCSI_DH_DEV_FAILED; |
141 | } else if (result) { | 158 | } else { |
142 | sdev_printk(KERN_ERR, sdev, "Error 0x%x while sending " | 159 | sdev_printk(KERN_INFO, sdev, |
143 | "CLARiiON trespass command.\n", result); | 160 | "%s: failed to send MODE SELECT, no sense available\n", |
144 | err = SCSI_DH_IO; | 161 | CLARIION_NAME); |
145 | } | 162 | } |
146 | |||
147 | return err; | 163 | return err; |
148 | } | 164 | } |
149 | 165 | ||
150 | static int parse_sp_info_reply(struct scsi_device *sdev, int result, | 166 | static int parse_sp_info_reply(struct scsi_device *sdev, |
151 | int *default_sp, int *current_sp, int *new_current_sp) | 167 | struct clariion_dh_data *csdev) |
152 | { | 168 | { |
153 | int err = SCSI_DH_OK; | 169 | int err = SCSI_DH_OK; |
154 | struct clariion_dh_data *csdev = get_clariion_data(sdev); | ||
155 | 170 | ||
156 | if (result == 0) { | 171 | /* check for in-progress ucode upgrade (NDU) */ |
157 | /* check for in-progress ucode upgrade (NDU) */ | 172 | if (csdev->buffer[48] != 0) { |
158 | if (csdev->buffer[48] != 0) { | 173 | sdev_printk(KERN_NOTICE, sdev, "%s: Detected in-progress " |
159 | sdev_printk(KERN_NOTICE, sdev, "Detected in-progress " | 174 | "ucode upgrade NDU operation while finding " |
160 | "ucode upgrade NDU operation while finding " | 175 | "current active SP.", CLARIION_NAME); |
161 | "current active SP."); | 176 | err = SCSI_DH_DEV_TEMP_BUSY; |
162 | err = SCSI_DH_DEV_TEMP_BUSY; | 177 | goto out; |
163 | } else { | 178 | } |
164 | *default_sp = csdev->buffer[5]; | 179 | if (csdev->buffer[4] < 0 || csdev->buffer[4] > 2) { |
165 | 180 | /* Invalid buffer format */ | |
166 | if (csdev->buffer[4] == 2) | 181 | sdev_printk(KERN_NOTICE, sdev, |
167 | /* SP for path is current */ | 182 | "%s: invalid VPD page 0xC0 format\n", |
168 | *current_sp = csdev->buffer[8]; | 183 | CLARIION_NAME); |
169 | else { | 184 | err = SCSI_DH_NOSYS; |
170 | if (csdev->buffer[4] == 1) | 185 | goto out; |
171 | /* SP for this path is NOT current */ | 186 | } |
172 | if (csdev->buffer[8] == 0) | 187 | switch (csdev->buffer[28] & 0x0f) { |
173 | *current_sp = 1; | 188 | case 6: |
174 | else | 189 | sdev_printk(KERN_NOTICE, sdev, |
175 | *current_sp = 0; | 190 | "%s: ALUA failover mode detected\n", |
176 | else | 191 | CLARIION_NAME); |
177 | /* unbound LU or LUNZ */ | 192 | break; |
178 | *current_sp = CLARIION_UNBOUND_LU; | 193 | case 4: |
179 | } | 194 | /* Linux failover */ |
180 | *new_current_sp = csdev->buffer[8]; | 195 | break; |
181 | } | 196 | default: |
182 | } else { | 197 | sdev_printk(KERN_WARNING, sdev, |
183 | struct scsi_sense_hdr sshdr; | 198 | "%s: Invalid failover mode %d\n", |
184 | 199 | CLARIION_NAME, csdev->buffer[28] & 0x0f); | |
185 | err = SCSI_DH_IO; | 200 | err = SCSI_DH_NOSYS; |
186 | 201 | goto out; | |
187 | if (scsi_normalize_sense(csdev->sense, SCSI_SENSE_BUFFERSIZE, | ||
188 | &sshdr)) | ||
189 | sdev_printk(KERN_ERR, sdev, "Found valid sense data " | ||
190 | "0x%2x, 0x%2x, 0x%2x while finding current " | ||
191 | "active SP.", sshdr.sense_key, sshdr.asc, | ||
192 | sshdr.ascq); | ||
193 | else | ||
194 | sdev_printk(KERN_ERR, sdev, "Error 0x%x finding " | ||
195 | "current active SP.", result); | ||
196 | } | 202 | } |
197 | 203 | ||
204 | csdev->default_sp = csdev->buffer[5]; | ||
205 | csdev->lun_state = csdev->buffer[4]; | ||
206 | csdev->current_sp = csdev->buffer[8]; | ||
207 | csdev->port = csdev->buffer[7]; | ||
208 | |||
209 | out: | ||
198 | return err; | 210 | return err; |
199 | } | 211 | } |
200 | 212 | ||
201 | static int sp_info_endio(struct scsi_device *sdev, int result, | 213 | #define emc_default_str "FC (Legacy)" |
202 | int mode_select_sent, int *done) | 214 | |
215 | static char * parse_sp_model(struct scsi_device *sdev, unsigned char *buffer) | ||
203 | { | 216 | { |
204 | struct clariion_dh_data *csdev = get_clariion_data(sdev); | 217 | unsigned char len = buffer[4] + 5; |
205 | int err_flags, default_sp, current_sp, new_current_sp; | 218 | char *sp_model = NULL; |
219 | unsigned char sp_len, serial_len; | ||
220 | |||
221 | if (len < 160) { | ||
222 | sdev_printk(KERN_WARNING, sdev, | ||
223 | "%s: Invalid information section length %d\n", | ||
224 | CLARIION_NAME, len); | ||
225 | /* Check for old FC arrays */ | ||
226 | if (!strncmp(buffer + 8, "DGC", 3)) { | ||
227 | /* Old FC array, not supporting extended information */ | ||
228 | sp_model = emc_default_str; | ||
229 | } | ||
230 | goto out; | ||
231 | } | ||
206 | 232 | ||
207 | err_flags = parse_sp_info_reply(sdev, result, &default_sp, | 233 | /* |
208 | ¤t_sp, &new_current_sp); | 234 | * Parse extended information for SP model number |
235 | */ | ||
236 | serial_len = buffer[160]; | ||
237 | if (serial_len == 0 || serial_len + 161 > len) { | ||
238 | sdev_printk(KERN_WARNING, sdev, | ||
239 | "%s: Invalid array serial number length %d\n", | ||
240 | CLARIION_NAME, serial_len); | ||
241 | goto out; | ||
242 | } | ||
243 | sp_len = buffer[99]; | ||
244 | if (sp_len == 0 || serial_len + sp_len + 161 > len) { | ||
245 | sdev_printk(KERN_WARNING, sdev, | ||
246 | "%s: Invalid model number length %d\n", | ||
247 | CLARIION_NAME, sp_len); | ||
248 | goto out; | ||
249 | } | ||
250 | sp_model = &buffer[serial_len + 161]; | ||
251 | /* Strip whitespace at the end */ | ||
252 | while (sp_len > 1 && sp_model[sp_len - 1] == ' ') | ||
253 | sp_len--; | ||
209 | 254 | ||
210 | if (err_flags != SCSI_DH_OK) | 255 | sp_model[sp_len] = '\0'; |
211 | goto done; | ||
212 | 256 | ||
213 | if (mode_select_sent) { | 257 | out: |
214 | csdev->default_sp = default_sp; | 258 | return sp_model; |
215 | csdev->current_sp = current_sp; | ||
216 | } else { | ||
217 | /* | ||
218 | * Issue the actual module_selec request IFF either | ||
219 | * (1) we do not know the identity of the current SP OR | ||
220 | * (2) what we think we know is actually correct. | ||
221 | */ | ||
222 | if ((current_sp != CLARIION_UNBOUND_LU) && | ||
223 | (new_current_sp != current_sp)) { | ||
224 | |||
225 | csdev->default_sp = default_sp; | ||
226 | csdev->current_sp = current_sp; | ||
227 | |||
228 | sdev_printk(KERN_INFO, sdev, "Ignoring path group " | ||
229 | "switch-over command for CLARiiON SP%s since " | ||
230 | " mapped device is already initialized.", | ||
231 | current_sp ? "B" : "A"); | ||
232 | if (done) | ||
233 | *done = 1; /* as good as doing it */ | ||
234 | } | ||
235 | } | ||
236 | done: | ||
237 | return err_flags; | ||
238 | } | 259 | } |
239 | 260 | ||
240 | /* | 261 | /* |
241 | * Get block request for REQ_BLOCK_PC command issued to path. Currently | 262 | * Get block request for REQ_BLOCK_PC command issued to path. Currently |
242 | * limited to MODE_SELECT (trespass) and INQUIRY (VPD page 0xC0) commands. | 263 | * limited to MODE_SELECT (trespass) and INQUIRY (VPD page 0xC0) commands. |
243 | * | 264 | * |
244 | * Uses data and sense buffers in hardware handler context structure and | 265 | * Uses data and sense buffers in hardware handler context structure and |
245 | * assumes serial servicing of commands, both issuance and completion. | 266 | * assumes serial servicing of commands, both issuance and completion. |
246 | */ | 267 | */ |
247 | static struct request *get_req(struct scsi_device *sdev, int cmd) | 268 | static struct request *get_req(struct scsi_device *sdev, int cmd, |
269 | unsigned char *buffer) | ||
248 | { | 270 | { |
249 | struct clariion_dh_data *csdev = get_clariion_data(sdev); | ||
250 | struct request *rq; | 271 | struct request *rq; |
251 | unsigned char *page22; | ||
252 | int len = 0; | 272 | int len = 0; |
253 | 273 | ||
254 | rq = blk_get_request(sdev->request_queue, | 274 | rq = blk_get_request(sdev->request_queue, |
255 | (cmd == MODE_SELECT) ? WRITE : READ, GFP_ATOMIC); | 275 | (cmd == MODE_SELECT) ? WRITE : READ, GFP_NOIO); |
256 | if (!rq) { | 276 | if (!rq) { |
257 | sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed"); | 277 | sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed"); |
258 | return NULL; | 278 | return NULL; |
259 | } | 279 | } |
260 | 280 | ||
261 | memset(&rq->cmd, 0, BLK_MAX_CDB); | 281 | memset(rq->cmd, 0, BLK_MAX_CDB); |
282 | rq->cmd_len = COMMAND_SIZE(cmd); | ||
262 | rq->cmd[0] = cmd; | 283 | rq->cmd[0] = cmd; |
263 | rq->cmd_len = COMMAND_SIZE(rq->cmd[0]); | ||
264 | 284 | ||
265 | switch (cmd) { | 285 | switch (cmd) { |
266 | case MODE_SELECT: | 286 | case MODE_SELECT: |
267 | if (csdev->short_trespass) { | 287 | len = sizeof(short_trespass); |
268 | page22 = csdev->hr ? short_trespass_hr : short_trespass; | 288 | rq->cmd_flags |= REQ_RW; |
269 | len = sizeof(short_trespass); | 289 | rq->cmd[1] = 0x10; |
270 | } else { | 290 | break; |
271 | page22 = csdev->hr ? long_trespass_hr : long_trespass; | 291 | case MODE_SELECT_10: |
272 | len = sizeof(long_trespass); | 292 | len = sizeof(long_trespass); |
273 | } | ||
274 | /* | ||
275 | * Can't DMA from kernel BSS -- must copy selected trespass | ||
276 | * command mode page contents to context buffer which is | ||
277 | * allocated by kmalloc. | ||
278 | */ | ||
279 | BUG_ON((len > CLARIION_BUFFER_SIZE)); | ||
280 | memcpy(csdev->buffer, page22, len); | ||
281 | rq->cmd_flags |= REQ_RW; | 293 | rq->cmd_flags |= REQ_RW; |
282 | rq->cmd[1] = 0x10; | 294 | rq->cmd[1] = 0x10; |
283 | break; | 295 | break; |
284 | case INQUIRY: | 296 | case INQUIRY: |
285 | rq->cmd[1] = 0x1; | ||
286 | rq->cmd[2] = 0xC0; | ||
287 | len = CLARIION_BUFFER_SIZE; | 297 | len = CLARIION_BUFFER_SIZE; |
288 | memset(csdev->buffer, 0, CLARIION_BUFFER_SIZE); | 298 | memset(buffer, 0, len); |
289 | break; | 299 | break; |
290 | default: | 300 | default: |
291 | BUG_ON(1); | 301 | BUG_ON(1); |
@@ -298,47 +308,94 @@ static struct request *get_req(struct scsi_device *sdev, int cmd) | |||
298 | rq->timeout = CLARIION_TIMEOUT; | 308 | rq->timeout = CLARIION_TIMEOUT; |
299 | rq->retries = CLARIION_RETRIES; | 309 | rq->retries = CLARIION_RETRIES; |
300 | 310 | ||
301 | rq->sense = csdev->sense; | 311 | if (blk_rq_map_kern(rq->q, rq, buffer, len, GFP_NOIO)) { |
302 | memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); | 312 | blk_put_request(rq); |
303 | rq->sense_len = 0; | ||
304 | |||
305 | if (blk_rq_map_kern(sdev->request_queue, rq, csdev->buffer, | ||
306 | len, GFP_ATOMIC)) { | ||
307 | __blk_put_request(rq->q, rq); | ||
308 | return NULL; | 313 | return NULL; |
309 | } | 314 | } |
310 | 315 | ||
311 | return rq; | 316 | return rq; |
312 | } | 317 | } |
313 | 318 | ||
314 | static int send_cmd(struct scsi_device *sdev, int cmd) | 319 | static int send_inquiry_cmd(struct scsi_device *sdev, int page, |
320 | struct clariion_dh_data *csdev) | ||
315 | { | 321 | { |
316 | struct request *rq = get_req(sdev, cmd); | 322 | struct request *rq = get_req(sdev, INQUIRY, csdev->buffer); |
323 | int err; | ||
317 | 324 | ||
318 | if (!rq) | 325 | if (!rq) |
319 | return SCSI_DH_RES_TEMP_UNAVAIL; | 326 | return SCSI_DH_RES_TEMP_UNAVAIL; |
320 | 327 | ||
321 | return blk_execute_rq(sdev->request_queue, NULL, rq, 1); | 328 | rq->sense = csdev->sense; |
329 | memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); | ||
330 | rq->sense_len = csdev->senselen = 0; | ||
331 | |||
332 | rq->cmd[0] = INQUIRY; | ||
333 | if (page != 0) { | ||
334 | rq->cmd[1] = 1; | ||
335 | rq->cmd[2] = page; | ||
336 | } | ||
337 | err = blk_execute_rq(sdev->request_queue, NULL, rq, 1); | ||
338 | if (err == -EIO) { | ||
339 | sdev_printk(KERN_INFO, sdev, | ||
340 | "%s: failed to send %s INQUIRY: %x\n", | ||
341 | CLARIION_NAME, page?"EVPD":"standard", | ||
342 | rq->errors); | ||
343 | csdev->senselen = rq->sense_len; | ||
344 | err = SCSI_DH_IO; | ||
345 | } | ||
346 | |||
347 | blk_put_request(rq); | ||
348 | |||
349 | return err; | ||
322 | } | 350 | } |
323 | 351 | ||
324 | static int clariion_activate(struct scsi_device *sdev) | 352 | static int send_trespass_cmd(struct scsi_device *sdev, |
353 | struct clariion_dh_data *csdev) | ||
325 | { | 354 | { |
326 | int result, done = 0; | 355 | struct request *rq; |
356 | unsigned char *page22; | ||
357 | int err, len, cmd; | ||
358 | |||
359 | if (csdev->flags & CLARIION_SHORT_TRESPASS) { | ||
360 | page22 = short_trespass; | ||
361 | if (!(csdev->flags & CLARIION_HONOR_RESERVATIONS)) | ||
362 | /* Set Honor Reservations bit */ | ||
363 | page22[6] |= 0x80; | ||
364 | len = sizeof(short_trespass); | ||
365 | cmd = MODE_SELECT; | ||
366 | } else { | ||
367 | page22 = long_trespass; | ||
368 | if (!(csdev->flags & CLARIION_HONOR_RESERVATIONS)) | ||
369 | /* Set Honor Reservations bit */ | ||
370 | page22[10] |= 0x80; | ||
371 | len = sizeof(long_trespass); | ||
372 | cmd = MODE_SELECT_10; | ||
373 | } | ||
374 | BUG_ON((len > CLARIION_BUFFER_SIZE)); | ||
375 | memcpy(csdev->buffer, page22, len); | ||
327 | 376 | ||
328 | result = send_cmd(sdev, INQUIRY); | 377 | rq = get_req(sdev, cmd, csdev->buffer); |
329 | result = sp_info_endio(sdev, result, 0, &done); | 378 | if (!rq) |
330 | if (result || done) | 379 | return SCSI_DH_RES_TEMP_UNAVAIL; |
331 | goto done; | ||
332 | 380 | ||
333 | result = send_cmd(sdev, MODE_SELECT); | 381 | rq->sense = csdev->sense; |
334 | result = trespass_endio(sdev, result); | 382 | memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); |
335 | if (result) | 383 | rq->sense_len = csdev->senselen = 0; |
336 | goto done; | ||
337 | 384 | ||
338 | result = send_cmd(sdev, INQUIRY); | 385 | err = blk_execute_rq(sdev->request_queue, NULL, rq, 1); |
339 | result = sp_info_endio(sdev, result, 1, NULL); | 386 | if (err == -EIO) { |
340 | done: | 387 | if (rq->sense_len) { |
341 | return result; | 388 | err = trespass_endio(sdev, csdev->sense); |
389 | } else { | ||
390 | sdev_printk(KERN_INFO, sdev, | ||
391 | "%s: failed to send MODE SELECT: %x\n", | ||
392 | CLARIION_NAME, rq->errors); | ||
393 | } | ||
394 | } | ||
395 | |||
396 | blk_put_request(rq); | ||
397 | |||
398 | return err; | ||
342 | } | 399 | } |
343 | 400 | ||
344 | static int clariion_check_sense(struct scsi_device *sdev, | 401 | static int clariion_check_sense(struct scsi_device *sdev, |
@@ -386,99 +443,215 @@ static int clariion_check_sense(struct scsi_device *sdev, | |||
386 | break; | 443 | break; |
387 | } | 444 | } |
388 | 445 | ||
389 | /* success just means we do not care what scsi-ml does */ | 446 | return SCSI_RETURN_NOT_HANDLED; |
390 | return SUCCESS; | 447 | } |
448 | |||
449 | static int clariion_prep_fn(struct scsi_device *sdev, struct request *req) | ||
450 | { | ||
451 | struct clariion_dh_data *h = get_clariion_data(sdev); | ||
452 | int ret = BLKPREP_OK; | ||
453 | |||
454 | if (h->lun_state != CLARIION_LUN_OWNED) { | ||
455 | ret = BLKPREP_KILL; | ||
456 | req->cmd_flags |= REQ_QUIET; | ||
457 | } | ||
458 | return ret; | ||
459 | |||
460 | } | ||
461 | |||
462 | static int clariion_std_inquiry(struct scsi_device *sdev, | ||
463 | struct clariion_dh_data *csdev) | ||
464 | { | ||
465 | int err; | ||
466 | char *sp_model; | ||
467 | |||
468 | err = send_inquiry_cmd(sdev, 0, csdev); | ||
469 | if (err != SCSI_DH_OK && csdev->senselen) { | ||
470 | struct scsi_sense_hdr sshdr; | ||
471 | |||
472 | if (scsi_normalize_sense(csdev->sense, SCSI_SENSE_BUFFERSIZE, | ||
473 | &sshdr)) { | ||
474 | sdev_printk(KERN_ERR, sdev, "%s: INQUIRY sense code " | ||
475 | "%02x/%02x/%02x\n", CLARIION_NAME, | ||
476 | sshdr.sense_key, sshdr.asc, sshdr.ascq); | ||
477 | } | ||
478 | err = SCSI_DH_IO; | ||
479 | goto out; | ||
480 | } | ||
481 | |||
482 | sp_model = parse_sp_model(sdev, csdev->buffer); | ||
483 | if (!sp_model) { | ||
484 | err = SCSI_DH_DEV_UNSUPP; | ||
485 | goto out; | ||
486 | } | ||
487 | |||
488 | /* | ||
489 | * FC Series arrays do not support long trespass | ||
490 | */ | ||
491 | if (!strlen(sp_model) || !strncmp(sp_model, "FC",2)) | ||
492 | csdev->flags |= CLARIION_SHORT_TRESPASS; | ||
493 | |||
494 | sdev_printk(KERN_INFO, sdev, | ||
495 | "%s: detected Clariion %s, flags %x\n", | ||
496 | CLARIION_NAME, sp_model, csdev->flags); | ||
497 | out: | ||
498 | return err; | ||
391 | } | 499 | } |
392 | 500 | ||
393 | static const struct { | 501 | static int clariion_send_inquiry(struct scsi_device *sdev, |
394 | char *vendor; | 502 | struct clariion_dh_data *csdev) |
395 | char *model; | 503 | { |
396 | } clariion_dev_list[] = { | 504 | int err, retry = CLARIION_RETRIES; |
505 | |||
506 | retry: | ||
507 | err = send_inquiry_cmd(sdev, 0xC0, csdev); | ||
508 | if (err != SCSI_DH_OK && csdev->senselen) { | ||
509 | struct scsi_sense_hdr sshdr; | ||
510 | |||
511 | err = scsi_normalize_sense(csdev->sense, SCSI_SENSE_BUFFERSIZE, | ||
512 | &sshdr); | ||
513 | if (!err) | ||
514 | return SCSI_DH_IO; | ||
515 | |||
516 | err = clariion_check_sense(sdev, &sshdr); | ||
517 | if (retry > 0 && err == NEEDS_RETRY) { | ||
518 | retry--; | ||
519 | goto retry; | ||
520 | } | ||
521 | sdev_printk(KERN_ERR, sdev, "%s: INQUIRY sense code " | ||
522 | "%02x/%02x/%02x\n", CLARIION_NAME, | ||
523 | sshdr.sense_key, sshdr.asc, sshdr.ascq); | ||
524 | err = SCSI_DH_IO; | ||
525 | } else { | ||
526 | err = parse_sp_info_reply(sdev, csdev); | ||
527 | } | ||
528 | return err; | ||
529 | } | ||
530 | |||
531 | static int clariion_activate(struct scsi_device *sdev) | ||
532 | { | ||
533 | struct clariion_dh_data *csdev = get_clariion_data(sdev); | ||
534 | int result; | ||
535 | |||
536 | result = clariion_send_inquiry(sdev, csdev); | ||
537 | if (result != SCSI_DH_OK) | ||
538 | goto done; | ||
539 | |||
540 | if (csdev->lun_state == CLARIION_LUN_OWNED) | ||
541 | goto done; | ||
542 | |||
543 | result = send_trespass_cmd(sdev, csdev); | ||
544 | if (result != SCSI_DH_OK) | ||
545 | goto done; | ||
546 | sdev_printk(KERN_INFO, sdev,"%s: %s trespass command sent\n", | ||
547 | CLARIION_NAME, | ||
548 | csdev->flags&CLARIION_SHORT_TRESPASS?"short":"long" ); | ||
549 | |||
550 | /* Update status */ | ||
551 | result = clariion_send_inquiry(sdev, csdev); | ||
552 | if (result != SCSI_DH_OK) | ||
553 | goto done; | ||
554 | |||
555 | done: | ||
556 | sdev_printk(KERN_INFO, sdev, | ||
557 | "%s: at SP %c Port %d (%s, default SP %c)\n", | ||
558 | CLARIION_NAME, csdev->current_sp + 'A', | ||
559 | csdev->port, lun_state[csdev->lun_state], | ||
560 | csdev->default_sp + 'A'); | ||
561 | |||
562 | return result; | ||
563 | } | ||
564 | |||
565 | const struct scsi_dh_devlist clariion_dev_list[] = { | ||
397 | {"DGC", "RAID"}, | 566 | {"DGC", "RAID"}, |
398 | {"DGC", "DISK"}, | 567 | {"DGC", "DISK"}, |
568 | {"DGC", "VRAID"}, | ||
399 | {NULL, NULL}, | 569 | {NULL, NULL}, |
400 | }; | 570 | }; |
401 | 571 | ||
402 | static int clariion_bus_notify(struct notifier_block *, unsigned long, void *); | 572 | static int clariion_bus_attach(struct scsi_device *sdev); |
573 | static void clariion_bus_detach(struct scsi_device *sdev); | ||
403 | 574 | ||
404 | static struct scsi_device_handler clariion_dh = { | 575 | static struct scsi_device_handler clariion_dh = { |
405 | .name = CLARIION_NAME, | 576 | .name = CLARIION_NAME, |
406 | .module = THIS_MODULE, | 577 | .module = THIS_MODULE, |
407 | .nb.notifier_call = clariion_bus_notify, | 578 | .devlist = clariion_dev_list, |
579 | .attach = clariion_bus_attach, | ||
580 | .detach = clariion_bus_detach, | ||
408 | .check_sense = clariion_check_sense, | 581 | .check_sense = clariion_check_sense, |
409 | .activate = clariion_activate, | 582 | .activate = clariion_activate, |
583 | .prep_fn = clariion_prep_fn, | ||
410 | }; | 584 | }; |
411 | 585 | ||
412 | /* | 586 | /* |
413 | * TODO: need some interface so we can set trespass values | 587 | * TODO: need some interface so we can set trespass values |
414 | */ | 588 | */ |
415 | static int clariion_bus_notify(struct notifier_block *nb, | 589 | static int clariion_bus_attach(struct scsi_device *sdev) |
416 | unsigned long action, void *data) | ||
417 | { | 590 | { |
418 | struct device *dev = data; | ||
419 | struct scsi_device *sdev; | ||
420 | struct scsi_dh_data *scsi_dh_data; | 591 | struct scsi_dh_data *scsi_dh_data; |
421 | struct clariion_dh_data *h; | 592 | struct clariion_dh_data *h; |
422 | int i, found = 0; | ||
423 | unsigned long flags; | 593 | unsigned long flags; |
594 | int err; | ||
424 | 595 | ||
425 | if (!scsi_is_sdev_device(dev)) | 596 | scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) |
426 | return 0; | 597 | + sizeof(*h) , GFP_KERNEL); |
598 | if (!scsi_dh_data) { | ||
599 | sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n", | ||
600 | CLARIION_NAME); | ||
601 | return -ENOMEM; | ||
602 | } | ||
427 | 603 | ||
428 | sdev = to_scsi_device(dev); | 604 | scsi_dh_data->scsi_dh = &clariion_dh; |
605 | h = (struct clariion_dh_data *) scsi_dh_data->buf; | ||
606 | h->lun_state = CLARIION_LUN_UNINITIALIZED; | ||
607 | h->default_sp = CLARIION_UNBOUND_LU; | ||
608 | h->current_sp = CLARIION_UNBOUND_LU; | ||
429 | 609 | ||
430 | if (action == BUS_NOTIFY_ADD_DEVICE) { | 610 | err = clariion_std_inquiry(sdev, h); |
431 | for (i = 0; clariion_dev_list[i].vendor; i++) { | 611 | if (err != SCSI_DH_OK) |
432 | if (!strncmp(sdev->vendor, clariion_dev_list[i].vendor, | 612 | goto failed; |
433 | strlen(clariion_dev_list[i].vendor)) && | ||
434 | !strncmp(sdev->model, clariion_dev_list[i].model, | ||
435 | strlen(clariion_dev_list[i].model))) { | ||
436 | found = 1; | ||
437 | break; | ||
438 | } | ||
439 | } | ||
440 | if (!found) | ||
441 | goto out; | ||
442 | |||
443 | scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) | ||
444 | + sizeof(*h) , GFP_KERNEL); | ||
445 | if (!scsi_dh_data) { | ||
446 | sdev_printk(KERN_ERR, sdev, "Attach failed %s.\n", | ||
447 | CLARIION_NAME); | ||
448 | goto out; | ||
449 | } | ||
450 | 613 | ||
451 | scsi_dh_data->scsi_dh = &clariion_dh; | 614 | err = clariion_send_inquiry(sdev, h); |
452 | h = (struct clariion_dh_data *) scsi_dh_data->buf; | 615 | if (err != SCSI_DH_OK) |
453 | h->default_sp = CLARIION_UNBOUND_LU; | 616 | goto failed; |
454 | h->current_sp = CLARIION_UNBOUND_LU; | ||
455 | 617 | ||
456 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | 618 | if (!try_module_get(THIS_MODULE)) |
457 | sdev->scsi_dh_data = scsi_dh_data; | 619 | goto failed; |
458 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
459 | 620 | ||
460 | sdev_printk(KERN_NOTICE, sdev, "Attached %s.\n", CLARIION_NAME); | 621 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); |
461 | try_module_get(THIS_MODULE); | 622 | sdev->scsi_dh_data = scsi_dh_data; |
623 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
462 | 624 | ||
463 | } else if (action == BUS_NOTIFY_DEL_DEVICE) { | 625 | sdev_printk(KERN_INFO, sdev, |
464 | if (sdev->scsi_dh_data == NULL || | 626 | "%s: connected to SP %c Port %d (%s, default SP %c)\n", |
465 | sdev->scsi_dh_data->scsi_dh != &clariion_dh) | 627 | CLARIION_NAME, h->current_sp + 'A', |
466 | goto out; | 628 | h->port, lun_state[h->lun_state], |
629 | h->default_sp + 'A'); | ||
467 | 630 | ||
468 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | 631 | return 0; |
469 | scsi_dh_data = sdev->scsi_dh_data; | ||
470 | sdev->scsi_dh_data = NULL; | ||
471 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
472 | 632 | ||
473 | sdev_printk(KERN_NOTICE, sdev, "Dettached %s.\n", | 633 | failed: |
474 | CLARIION_NAME); | 634 | kfree(scsi_dh_data); |
635 | sdev_printk(KERN_ERR, sdev, "%s: not attached\n", | ||
636 | CLARIION_NAME); | ||
637 | return -EINVAL; | ||
638 | } | ||
475 | 639 | ||
476 | kfree(scsi_dh_data); | 640 | static void clariion_bus_detach(struct scsi_device *sdev) |
477 | module_put(THIS_MODULE); | 641 | { |
478 | } | 642 | struct scsi_dh_data *scsi_dh_data; |
643 | unsigned long flags; | ||
479 | 644 | ||
480 | out: | 645 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); |
481 | return 0; | 646 | scsi_dh_data = sdev->scsi_dh_data; |
647 | sdev->scsi_dh_data = NULL; | ||
648 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
649 | |||
650 | sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", | ||
651 | CLARIION_NAME); | ||
652 | |||
653 | kfree(scsi_dh_data); | ||
654 | module_put(THIS_MODULE); | ||
482 | } | 655 | } |
483 | 656 | ||
484 | static int __init clariion_init(void) | 657 | static int __init clariion_init(void) |
@@ -487,7 +660,8 @@ static int __init clariion_init(void) | |||
487 | 660 | ||
488 | r = scsi_register_device_handler(&clariion_dh); | 661 | r = scsi_register_device_handler(&clariion_dh); |
489 | if (r != 0) | 662 | if (r != 0) |
490 | printk(KERN_ERR "Failed to register scsi device handler."); | 663 | printk(KERN_ERR "%s: Failed to register scsi device handler.", |
664 | CLARIION_NAME); | ||
491 | return r; | 665 | return r; |
492 | } | 666 | } |
493 | 667 | ||
diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c index ae6be87d6a83..9c7a1f8ebb72 100644 --- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c +++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * | 4 | * |
5 | * Copyright (C) 2006 Red Hat, Inc. All rights reserved. | 5 | * Copyright (C) 2006 Red Hat, Inc. All rights reserved. |
6 | * Copyright (C) 2006 Mike Christie | 6 | * Copyright (C) 2006 Mike Christie |
7 | * Copyright (C) 2008 Hannes Reinecke <hare@suse.de> | ||
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
@@ -25,13 +26,18 @@ | |||
25 | #include <scsi/scsi_eh.h> | 26 | #include <scsi/scsi_eh.h> |
26 | #include <scsi/scsi_dh.h> | 27 | #include <scsi/scsi_dh.h> |
27 | 28 | ||
28 | #define HP_SW_NAME "hp_sw" | 29 | #define HP_SW_NAME "hp_sw" |
29 | 30 | ||
30 | #define HP_SW_TIMEOUT (60 * HZ) | 31 | #define HP_SW_TIMEOUT (60 * HZ) |
31 | #define HP_SW_RETRIES 3 | 32 | #define HP_SW_RETRIES 3 |
33 | |||
34 | #define HP_SW_PATH_UNINITIALIZED -1 | ||
35 | #define HP_SW_PATH_ACTIVE 0 | ||
36 | #define HP_SW_PATH_PASSIVE 1 | ||
32 | 37 | ||
33 | struct hp_sw_dh_data { | 38 | struct hp_sw_dh_data { |
34 | unsigned char sense[SCSI_SENSE_BUFFERSIZE]; | 39 | unsigned char sense[SCSI_SENSE_BUFFERSIZE]; |
40 | int path_state; | ||
35 | int retries; | 41 | int retries; |
36 | }; | 42 | }; |
37 | 43 | ||
@@ -42,51 +48,161 @@ static inline struct hp_sw_dh_data *get_hp_sw_data(struct scsi_device *sdev) | |||
42 | return ((struct hp_sw_dh_data *) scsi_dh_data->buf); | 48 | return ((struct hp_sw_dh_data *) scsi_dh_data->buf); |
43 | } | 49 | } |
44 | 50 | ||
45 | static int hp_sw_done(struct scsi_device *sdev) | 51 | /* |
52 | * tur_done - Handle TEST UNIT READY return status | ||
53 | * @sdev: sdev the command has been sent to | ||
54 | * @errors: blk error code | ||
55 | * | ||
56 | * Returns SCSI_DH_DEV_OFFLINED if the sdev is on the passive path | ||
57 | */ | ||
58 | static int tur_done(struct scsi_device *sdev, unsigned char *sense) | ||
46 | { | 59 | { |
47 | struct hp_sw_dh_data *h = get_hp_sw_data(sdev); | ||
48 | struct scsi_sense_hdr sshdr; | 60 | struct scsi_sense_hdr sshdr; |
49 | int rc; | 61 | int ret; |
50 | |||
51 | sdev_printk(KERN_INFO, sdev, "hp_sw_done\n"); | ||
52 | 62 | ||
53 | rc = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, &sshdr); | 63 | ret = scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr); |
54 | if (!rc) | 64 | if (!ret) { |
65 | sdev_printk(KERN_WARNING, sdev, | ||
66 | "%s: sending tur failed, no sense available\n", | ||
67 | HP_SW_NAME); | ||
68 | ret = SCSI_DH_IO; | ||
55 | goto done; | 69 | goto done; |
70 | } | ||
56 | switch (sshdr.sense_key) { | 71 | switch (sshdr.sense_key) { |
72 | case UNIT_ATTENTION: | ||
73 | ret = SCSI_DH_IMM_RETRY; | ||
74 | break; | ||
57 | case NOT_READY: | 75 | case NOT_READY: |
58 | if ((sshdr.asc == 0x04) && (sshdr.ascq == 3)) { | 76 | if ((sshdr.asc == 0x04) && (sshdr.ascq == 2)) { |
59 | rc = SCSI_DH_RETRY; | 77 | /* |
60 | h->retries++; | 78 | * LUN not ready - Initialization command required |
79 | * | ||
80 | * This is the passive path | ||
81 | */ | ||
82 | ret = SCSI_DH_DEV_OFFLINED; | ||
61 | break; | 83 | break; |
62 | } | 84 | } |
63 | /* fall through */ | 85 | /* Fallthrough */ |
64 | default: | 86 | default: |
65 | h->retries++; | 87 | sdev_printk(KERN_WARNING, sdev, |
66 | rc = SCSI_DH_IMM_RETRY; | 88 | "%s: sending tur failed, sense %x/%x/%x\n", |
89 | HP_SW_NAME, sshdr.sense_key, sshdr.asc, | ||
90 | sshdr.ascq); | ||
91 | break; | ||
67 | } | 92 | } |
68 | 93 | ||
69 | done: | 94 | done: |
70 | if (rc == SCSI_DH_OK || rc == SCSI_DH_IO) | 95 | return ret; |
71 | h->retries = 0; | 96 | } |
72 | else if (h->retries > HP_SW_RETRIES) { | 97 | |
73 | h->retries = 0; | 98 | /* |
99 | * hp_sw_tur - Send TEST UNIT READY | ||
100 | * @sdev: sdev command should be sent to | ||
101 | * | ||
102 | * Use the TEST UNIT READY command to determine | ||
103 | * the path state. | ||
104 | */ | ||
105 | static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h) | ||
106 | { | ||
107 | struct request *req; | ||
108 | int ret; | ||
109 | |||
110 | req = blk_get_request(sdev->request_queue, WRITE, GFP_NOIO); | ||
111 | if (!req) | ||
112 | return SCSI_DH_RES_TEMP_UNAVAIL; | ||
113 | |||
114 | req->cmd_type = REQ_TYPE_BLOCK_PC; | ||
115 | req->cmd_flags |= REQ_FAILFAST; | ||
116 | req->cmd_len = COMMAND_SIZE(TEST_UNIT_READY); | ||
117 | memset(req->cmd, 0, MAX_COMMAND_SIZE); | ||
118 | req->cmd[0] = TEST_UNIT_READY; | ||
119 | req->timeout = HP_SW_TIMEOUT; | ||
120 | req->sense = h->sense; | ||
121 | memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE); | ||
122 | req->sense_len = 0; | ||
123 | |||
124 | retry: | ||
125 | ret = blk_execute_rq(req->q, NULL, req, 1); | ||
126 | if (ret == -EIO) { | ||
127 | if (req->sense_len > 0) { | ||
128 | ret = tur_done(sdev, h->sense); | ||
129 | } else { | ||
130 | sdev_printk(KERN_WARNING, sdev, | ||
131 | "%s: sending tur failed with %x\n", | ||
132 | HP_SW_NAME, req->errors); | ||
133 | ret = SCSI_DH_IO; | ||
134 | } | ||
135 | } else { | ||
136 | h->path_state = HP_SW_PATH_ACTIVE; | ||
137 | ret = SCSI_DH_OK; | ||
138 | } | ||
139 | if (ret == SCSI_DH_IMM_RETRY) | ||
140 | goto retry; | ||
141 | if (ret == SCSI_DH_DEV_OFFLINED) { | ||
142 | h->path_state = HP_SW_PATH_PASSIVE; | ||
143 | ret = SCSI_DH_OK; | ||
144 | } | ||
145 | |||
146 | blk_put_request(req); | ||
147 | |||
148 | return ret; | ||
149 | } | ||
150 | |||
151 | /* | ||
152 | * start_done - Handle START STOP UNIT return status | ||
153 | * @sdev: sdev the command has been sent to | ||
154 | * @errors: blk error code | ||
155 | */ | ||
156 | static int start_done(struct scsi_device *sdev, unsigned char *sense) | ||
157 | { | ||
158 | struct scsi_sense_hdr sshdr; | ||
159 | int rc; | ||
160 | |||
161 | rc = scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr); | ||
162 | if (!rc) { | ||
163 | sdev_printk(KERN_WARNING, sdev, | ||
164 | "%s: sending start_stop_unit failed, " | ||
165 | "no sense available\n", | ||
166 | HP_SW_NAME); | ||
167 | return SCSI_DH_IO; | ||
168 | } | ||
169 | switch (sshdr.sense_key) { | ||
170 | case NOT_READY: | ||
171 | if ((sshdr.asc == 0x04) && (sshdr.ascq == 3)) { | ||
172 | /* | ||
173 | * LUN not ready - manual intervention required | ||
174 | * | ||
175 | * Switch-over in progress, retry. | ||
176 | */ | ||
177 | rc = SCSI_DH_RETRY; | ||
178 | break; | ||
179 | } | ||
180 | /* fall through */ | ||
181 | default: | ||
182 | sdev_printk(KERN_WARNING, sdev, | ||
183 | "%s: sending start_stop_unit failed, sense %x/%x/%x\n", | ||
184 | HP_SW_NAME, sshdr.sense_key, sshdr.asc, | ||
185 | sshdr.ascq); | ||
74 | rc = SCSI_DH_IO; | 186 | rc = SCSI_DH_IO; |
75 | } | 187 | } |
188 | |||
76 | return rc; | 189 | return rc; |
77 | } | 190 | } |
78 | 191 | ||
79 | static int hp_sw_activate(struct scsi_device *sdev) | 192 | /* |
193 | * hp_sw_start_stop - Send START STOP UNIT command | ||
194 | * @sdev: sdev command should be sent to | ||
195 | * | ||
196 | * Sending START STOP UNIT activates the SP. | ||
197 | */ | ||
198 | static int hp_sw_start_stop(struct scsi_device *sdev, struct hp_sw_dh_data *h) | ||
80 | { | 199 | { |
81 | struct hp_sw_dh_data *h = get_hp_sw_data(sdev); | ||
82 | struct request *req; | 200 | struct request *req; |
83 | int ret = SCSI_DH_RES_TEMP_UNAVAIL; | 201 | int ret, retry; |
84 | 202 | ||
85 | req = blk_get_request(sdev->request_queue, WRITE, GFP_ATOMIC); | 203 | req = blk_get_request(sdev->request_queue, WRITE, GFP_NOIO); |
86 | if (!req) | 204 | if (!req) |
87 | goto done; | 205 | return SCSI_DH_RES_TEMP_UNAVAIL; |
88 | |||
89 | sdev_printk(KERN_INFO, sdev, "sending START_STOP."); | ||
90 | 206 | ||
91 | req->cmd_type = REQ_TYPE_BLOCK_PC; | 207 | req->cmd_type = REQ_TYPE_BLOCK_PC; |
92 | req->cmd_flags |= REQ_FAILFAST; | 208 | req->cmd_flags |= REQ_FAILFAST; |
@@ -98,95 +214,153 @@ static int hp_sw_activate(struct scsi_device *sdev) | |||
98 | req->sense = h->sense; | 214 | req->sense = h->sense; |
99 | memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE); | 215 | memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE); |
100 | req->sense_len = 0; | 216 | req->sense_len = 0; |
217 | retry = h->retries; | ||
101 | 218 | ||
219 | retry: | ||
102 | ret = blk_execute_rq(req->q, NULL, req, 1); | 220 | ret = blk_execute_rq(req->q, NULL, req, 1); |
103 | if (!ret) /* SUCCESS */ | 221 | if (ret == -EIO) { |
104 | ret = hp_sw_done(sdev); | 222 | if (req->sense_len > 0) { |
105 | else | 223 | ret = start_done(sdev, h->sense); |
224 | } else { | ||
225 | sdev_printk(KERN_WARNING, sdev, | ||
226 | "%s: sending start_stop_unit failed with %x\n", | ||
227 | HP_SW_NAME, req->errors); | ||
228 | ret = SCSI_DH_IO; | ||
229 | } | ||
230 | } else | ||
231 | ret = SCSI_DH_OK; | ||
232 | |||
233 | if (ret == SCSI_DH_RETRY) { | ||
234 | if (--retry) | ||
235 | goto retry; | ||
106 | ret = SCSI_DH_IO; | 236 | ret = SCSI_DH_IO; |
107 | done: | 237 | } |
238 | |||
239 | blk_put_request(req); | ||
240 | |||
241 | return ret; | ||
242 | } | ||
243 | |||
244 | static int hp_sw_prep_fn(struct scsi_device *sdev, struct request *req) | ||
245 | { | ||
246 | struct hp_sw_dh_data *h = get_hp_sw_data(sdev); | ||
247 | int ret = BLKPREP_OK; | ||
248 | |||
249 | if (h->path_state != HP_SW_PATH_ACTIVE) { | ||
250 | ret = BLKPREP_KILL; | ||
251 | req->cmd_flags |= REQ_QUIET; | ||
252 | } | ||
253 | return ret; | ||
254 | |||
255 | } | ||
256 | |||
257 | /* | ||
258 | * hp_sw_activate - Activate a path | ||
259 | * @sdev: sdev on the path to be activated | ||
260 | * | ||
261 | * The HP Active/Passive firmware is pretty simple; | ||
262 | * the passive path reports NOT READY with sense codes | ||
263 | * 0x04/0x02; a START STOP UNIT command will then | ||
264 | * activate the passive path (and deactivate the | ||
265 | * previously active one). | ||
266 | */ | ||
267 | static int hp_sw_activate(struct scsi_device *sdev) | ||
268 | { | ||
269 | int ret = SCSI_DH_OK; | ||
270 | struct hp_sw_dh_data *h = get_hp_sw_data(sdev); | ||
271 | |||
272 | ret = hp_sw_tur(sdev, h); | ||
273 | |||
274 | if (ret == SCSI_DH_OK && h->path_state == HP_SW_PATH_PASSIVE) { | ||
275 | ret = hp_sw_start_stop(sdev, h); | ||
276 | if (ret == SCSI_DH_OK) | ||
277 | sdev_printk(KERN_INFO, sdev, | ||
278 | "%s: activated path\n", | ||
279 | HP_SW_NAME); | ||
280 | } | ||
281 | |||
108 | return ret; | 282 | return ret; |
109 | } | 283 | } |
110 | 284 | ||
111 | static const struct { | 285 | const struct scsi_dh_devlist hp_sw_dh_data_list[] = { |
112 | char *vendor; | 286 | {"COMPAQ", "MSA1000 VOLUME"}, |
113 | char *model; | 287 | {"COMPAQ", "HSV110"}, |
114 | } hp_sw_dh_data_list[] = { | 288 | {"HP", "HSV100"}, |
115 | {"COMPAQ", "MSA"}, | ||
116 | {"HP", "HSV"}, | ||
117 | {"DEC", "HSG80"}, | 289 | {"DEC", "HSG80"}, |
118 | {NULL, NULL}, | 290 | {NULL, NULL}, |
119 | }; | 291 | }; |
120 | 292 | ||
121 | static int hp_sw_bus_notify(struct notifier_block *, unsigned long, void *); | 293 | static int hp_sw_bus_attach(struct scsi_device *sdev); |
294 | static void hp_sw_bus_detach(struct scsi_device *sdev); | ||
122 | 295 | ||
123 | static struct scsi_device_handler hp_sw_dh = { | 296 | static struct scsi_device_handler hp_sw_dh = { |
124 | .name = HP_SW_NAME, | 297 | .name = HP_SW_NAME, |
125 | .module = THIS_MODULE, | 298 | .module = THIS_MODULE, |
126 | .nb.notifier_call = hp_sw_bus_notify, | 299 | .devlist = hp_sw_dh_data_list, |
300 | .attach = hp_sw_bus_attach, | ||
301 | .detach = hp_sw_bus_detach, | ||
127 | .activate = hp_sw_activate, | 302 | .activate = hp_sw_activate, |
303 | .prep_fn = hp_sw_prep_fn, | ||
128 | }; | 304 | }; |
129 | 305 | ||
130 | static int hp_sw_bus_notify(struct notifier_block *nb, | 306 | static int hp_sw_bus_attach(struct scsi_device *sdev) |
131 | unsigned long action, void *data) | ||
132 | { | 307 | { |
133 | struct device *dev = data; | ||
134 | struct scsi_device *sdev; | ||
135 | struct scsi_dh_data *scsi_dh_data; | 308 | struct scsi_dh_data *scsi_dh_data; |
136 | int i, found = 0; | 309 | struct hp_sw_dh_data *h; |
137 | unsigned long flags; | 310 | unsigned long flags; |
311 | int ret; | ||
138 | 312 | ||
139 | if (!scsi_is_sdev_device(dev)) | 313 | scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) |
314 | + sizeof(struct hp_sw_dh_data) , GFP_KERNEL); | ||
315 | if (!scsi_dh_data) { | ||
316 | sdev_printk(KERN_ERR, sdev, "%s: Attach Failed\n", | ||
317 | HP_SW_NAME); | ||
140 | return 0; | 318 | return 0; |
319 | } | ||
141 | 320 | ||
142 | sdev = to_scsi_device(dev); | 321 | scsi_dh_data->scsi_dh = &hp_sw_dh; |
143 | 322 | h = (struct hp_sw_dh_data *) scsi_dh_data->buf; | |
144 | if (action == BUS_NOTIFY_ADD_DEVICE) { | 323 | h->path_state = HP_SW_PATH_UNINITIALIZED; |
145 | for (i = 0; hp_sw_dh_data_list[i].vendor; i++) { | 324 | h->retries = HP_SW_RETRIES; |
146 | if (!strncmp(sdev->vendor, hp_sw_dh_data_list[i].vendor, | ||
147 | strlen(hp_sw_dh_data_list[i].vendor)) && | ||
148 | !strncmp(sdev->model, hp_sw_dh_data_list[i].model, | ||
149 | strlen(hp_sw_dh_data_list[i].model))) { | ||
150 | found = 1; | ||
151 | break; | ||
152 | } | ||
153 | } | ||
154 | if (!found) | ||
155 | goto out; | ||
156 | 325 | ||
157 | scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) | 326 | ret = hp_sw_tur(sdev, h); |
158 | + sizeof(struct hp_sw_dh_data) , GFP_KERNEL); | 327 | if (ret != SCSI_DH_OK || h->path_state == HP_SW_PATH_UNINITIALIZED) |
159 | if (!scsi_dh_data) { | 328 | goto failed; |
160 | sdev_printk(KERN_ERR, sdev, "Attach Failed %s.\n", | ||
161 | HP_SW_NAME); | ||
162 | goto out; | ||
163 | } | ||
164 | 329 | ||
165 | scsi_dh_data->scsi_dh = &hp_sw_dh; | 330 | if (!try_module_get(THIS_MODULE)) |
166 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | 331 | goto failed; |
167 | sdev->scsi_dh_data = scsi_dh_data; | ||
168 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
169 | try_module_get(THIS_MODULE); | ||
170 | 332 | ||
171 | sdev_printk(KERN_NOTICE, sdev, "Attached %s.\n", HP_SW_NAME); | 333 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); |
172 | } else if (action == BUS_NOTIFY_DEL_DEVICE) { | 334 | sdev->scsi_dh_data = scsi_dh_data; |
173 | if (sdev->scsi_dh_data == NULL || | 335 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); |
174 | sdev->scsi_dh_data->scsi_dh != &hp_sw_dh) | ||
175 | goto out; | ||
176 | 336 | ||
177 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | 337 | sdev_printk(KERN_INFO, sdev, "%s: attached to %s path\n", |
178 | scsi_dh_data = sdev->scsi_dh_data; | 338 | HP_SW_NAME, h->path_state == HP_SW_PATH_ACTIVE? |
179 | sdev->scsi_dh_data = NULL; | 339 | "active":"passive"); |
180 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
181 | module_put(THIS_MODULE); | ||
182 | 340 | ||
183 | sdev_printk(KERN_NOTICE, sdev, "Dettached %s.\n", HP_SW_NAME); | 341 | return 0; |
184 | 342 | ||
185 | kfree(scsi_dh_data); | 343 | failed: |
186 | } | 344 | kfree(scsi_dh_data); |
345 | sdev_printk(KERN_ERR, sdev, "%s: not attached\n", | ||
346 | HP_SW_NAME); | ||
347 | return -EINVAL; | ||
348 | } | ||
187 | 349 | ||
188 | out: | 350 | static void hp_sw_bus_detach( struct scsi_device *sdev ) |
189 | return 0; | 351 | { |
352 | struct scsi_dh_data *scsi_dh_data; | ||
353 | unsigned long flags; | ||
354 | |||
355 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | ||
356 | scsi_dh_data = sdev->scsi_dh_data; | ||
357 | sdev->scsi_dh_data = NULL; | ||
358 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
359 | module_put(THIS_MODULE); | ||
360 | |||
361 | sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", HP_SW_NAME); | ||
362 | |||
363 | kfree(scsi_dh_data); | ||
190 | } | 364 | } |
191 | 365 | ||
192 | static int __init hp_sw_init(void) | 366 | static int __init hp_sw_init(void) |
@@ -202,6 +376,6 @@ static void __exit hp_sw_exit(void) | |||
202 | module_init(hp_sw_init); | 376 | module_init(hp_sw_init); |
203 | module_exit(hp_sw_exit); | 377 | module_exit(hp_sw_exit); |
204 | 378 | ||
205 | MODULE_DESCRIPTION("HP MSA 1000"); | 379 | MODULE_DESCRIPTION("HP Active/Passive driver"); |
206 | MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu"); | 380 | MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu"); |
207 | MODULE_LICENSE("GPL"); | 381 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index fdf34b0ec6e1..b093a501f8ae 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c | |||
@@ -173,6 +173,11 @@ struct rdac_dh_data { | |||
173 | #define RDAC_STATE_ACTIVE 0 | 173 | #define RDAC_STATE_ACTIVE 0 |
174 | #define RDAC_STATE_PASSIVE 1 | 174 | #define RDAC_STATE_PASSIVE 1 |
175 | unsigned char state; | 175 | unsigned char state; |
176 | |||
177 | #define RDAC_LUN_UNOWNED 0 | ||
178 | #define RDAC_LUN_OWNED 1 | ||
179 | #define RDAC_LUN_AVT 2 | ||
180 | char lun_state; | ||
176 | unsigned char sense[SCSI_SENSE_BUFFERSIZE]; | 181 | unsigned char sense[SCSI_SENSE_BUFFERSIZE]; |
177 | union { | 182 | union { |
178 | struct c2_inquiry c2; | 183 | struct c2_inquiry c2; |
@@ -182,6 +187,13 @@ struct rdac_dh_data { | |||
182 | } inq; | 187 | } inq; |
183 | }; | 188 | }; |
184 | 189 | ||
190 | static const char *lun_state[] = | ||
191 | { | ||
192 | "unowned", | ||
193 | "owned", | ||
194 | "owned (AVT mode)", | ||
195 | }; | ||
196 | |||
185 | static LIST_HEAD(ctlr_list); | 197 | static LIST_HEAD(ctlr_list); |
186 | static DEFINE_SPINLOCK(list_lock); | 198 | static DEFINE_SPINLOCK(list_lock); |
187 | 199 | ||
@@ -197,9 +209,8 @@ static struct request *get_rdac_req(struct scsi_device *sdev, | |||
197 | { | 209 | { |
198 | struct request *rq; | 210 | struct request *rq; |
199 | struct request_queue *q = sdev->request_queue; | 211 | struct request_queue *q = sdev->request_queue; |
200 | struct rdac_dh_data *h = get_rdac_data(sdev); | ||
201 | 212 | ||
202 | rq = blk_get_request(q, rw, GFP_KERNEL); | 213 | rq = blk_get_request(q, rw, GFP_NOIO); |
203 | 214 | ||
204 | if (!rq) { | 215 | if (!rq) { |
205 | sdev_printk(KERN_INFO, sdev, | 216 | sdev_printk(KERN_INFO, sdev, |
@@ -207,17 +218,14 @@ static struct request *get_rdac_req(struct scsi_device *sdev, | |||
207 | return NULL; | 218 | return NULL; |
208 | } | 219 | } |
209 | 220 | ||
210 | if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_KERNEL)) { | 221 | if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) { |
211 | blk_put_request(rq); | 222 | blk_put_request(rq); |
212 | sdev_printk(KERN_INFO, sdev, | 223 | sdev_printk(KERN_INFO, sdev, |
213 | "get_rdac_req: blk_rq_map_kern failed.\n"); | 224 | "get_rdac_req: blk_rq_map_kern failed.\n"); |
214 | return NULL; | 225 | return NULL; |
215 | } | 226 | } |
216 | 227 | ||
217 | memset(&rq->cmd, 0, BLK_MAX_CDB); | 228 | memset(rq->cmd, 0, BLK_MAX_CDB); |
218 | rq->sense = h->sense; | ||
219 | memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); | ||
220 | rq->sense_len = 0; | ||
221 | 229 | ||
222 | rq->cmd_type = REQ_TYPE_BLOCK_PC; | 230 | rq->cmd_type = REQ_TYPE_BLOCK_PC; |
223 | rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE; | 231 | rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE; |
@@ -227,12 +235,12 @@ static struct request *get_rdac_req(struct scsi_device *sdev, | |||
227 | return rq; | 235 | return rq; |
228 | } | 236 | } |
229 | 237 | ||
230 | static struct request *rdac_failover_get(struct scsi_device *sdev) | 238 | static struct request *rdac_failover_get(struct scsi_device *sdev, |
239 | struct rdac_dh_data *h) | ||
231 | { | 240 | { |
232 | struct request *rq; | 241 | struct request *rq; |
233 | struct rdac_mode_common *common; | 242 | struct rdac_mode_common *common; |
234 | unsigned data_size; | 243 | unsigned data_size; |
235 | struct rdac_dh_data *h = get_rdac_data(sdev); | ||
236 | 244 | ||
237 | if (h->ctlr->use_ms10) { | 245 | if (h->ctlr->use_ms10) { |
238 | struct rdac_pg_expanded *rdac_pg; | 246 | struct rdac_pg_expanded *rdac_pg; |
@@ -277,6 +285,10 @@ static struct request *rdac_failover_get(struct scsi_device *sdev) | |||
277 | } | 285 | } |
278 | rq->cmd_len = COMMAND_SIZE(rq->cmd[0]); | 286 | rq->cmd_len = COMMAND_SIZE(rq->cmd[0]); |
279 | 287 | ||
288 | rq->sense = h->sense; | ||
289 | memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); | ||
290 | rq->sense_len = 0; | ||
291 | |||
280 | return rq; | 292 | return rq; |
281 | } | 293 | } |
282 | 294 | ||
@@ -321,11 +333,10 @@ done: | |||
321 | } | 333 | } |
322 | 334 | ||
323 | static int submit_inquiry(struct scsi_device *sdev, int page_code, | 335 | static int submit_inquiry(struct scsi_device *sdev, int page_code, |
324 | unsigned int len) | 336 | unsigned int len, struct rdac_dh_data *h) |
325 | { | 337 | { |
326 | struct request *rq; | 338 | struct request *rq; |
327 | struct request_queue *q = sdev->request_queue; | 339 | struct request_queue *q = sdev->request_queue; |
328 | struct rdac_dh_data *h = get_rdac_data(sdev); | ||
329 | int err = SCSI_DH_RES_TEMP_UNAVAIL; | 340 | int err = SCSI_DH_RES_TEMP_UNAVAIL; |
330 | 341 | ||
331 | rq = get_rdac_req(sdev, &h->inq, len, READ); | 342 | rq = get_rdac_req(sdev, &h->inq, len, READ); |
@@ -338,59 +349,68 @@ static int submit_inquiry(struct scsi_device *sdev, int page_code, | |||
338 | rq->cmd[2] = page_code; | 349 | rq->cmd[2] = page_code; |
339 | rq->cmd[4] = len; | 350 | rq->cmd[4] = len; |
340 | rq->cmd_len = COMMAND_SIZE(INQUIRY); | 351 | rq->cmd_len = COMMAND_SIZE(INQUIRY); |
352 | |||
353 | rq->sense = h->sense; | ||
354 | memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); | ||
355 | rq->sense_len = 0; | ||
356 | |||
341 | err = blk_execute_rq(q, NULL, rq, 1); | 357 | err = blk_execute_rq(q, NULL, rq, 1); |
342 | if (err == -EIO) | 358 | if (err == -EIO) |
343 | err = SCSI_DH_IO; | 359 | err = SCSI_DH_IO; |
360 | |||
361 | blk_put_request(rq); | ||
344 | done: | 362 | done: |
345 | return err; | 363 | return err; |
346 | } | 364 | } |
347 | 365 | ||
348 | static int get_lun(struct scsi_device *sdev) | 366 | static int get_lun(struct scsi_device *sdev, struct rdac_dh_data *h) |
349 | { | 367 | { |
350 | int err; | 368 | int err; |
351 | struct c8_inquiry *inqp; | 369 | struct c8_inquiry *inqp; |
352 | struct rdac_dh_data *h = get_rdac_data(sdev); | ||
353 | 370 | ||
354 | err = submit_inquiry(sdev, 0xC8, sizeof(struct c8_inquiry)); | 371 | err = submit_inquiry(sdev, 0xC8, sizeof(struct c8_inquiry), h); |
355 | if (err == SCSI_DH_OK) { | 372 | if (err == SCSI_DH_OK) { |
356 | inqp = &h->inq.c8; | 373 | inqp = &h->inq.c8; |
357 | h->lun = inqp->lun[7]; /* currently it uses only one byte */ | 374 | if (inqp->page_code != 0xc8) |
375 | return SCSI_DH_NOSYS; | ||
376 | if (inqp->page_id[0] != 'e' || inqp->page_id[1] != 'd' || | ||
377 | inqp->page_id[2] != 'i' || inqp->page_id[3] != 'd') | ||
378 | return SCSI_DH_NOSYS; | ||
379 | h->lun = scsilun_to_int((struct scsi_lun *)inqp->lun); | ||
358 | } | 380 | } |
359 | return err; | 381 | return err; |
360 | } | 382 | } |
361 | 383 | ||
362 | #define RDAC_OWNED 0 | 384 | static int check_ownership(struct scsi_device *sdev, struct rdac_dh_data *h) |
363 | #define RDAC_UNOWNED 1 | ||
364 | #define RDAC_FAILED 2 | ||
365 | static int check_ownership(struct scsi_device *sdev) | ||
366 | { | 385 | { |
367 | int err; | 386 | int err; |
368 | struct c9_inquiry *inqp; | 387 | struct c9_inquiry *inqp; |
369 | struct rdac_dh_data *h = get_rdac_data(sdev); | ||
370 | 388 | ||
371 | err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry)); | 389 | err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry), h); |
372 | if (err == SCSI_DH_OK) { | 390 | if (err == SCSI_DH_OK) { |
373 | err = RDAC_UNOWNED; | ||
374 | inqp = &h->inq.c9; | 391 | inqp = &h->inq.c9; |
375 | /* | 392 | if ((inqp->avte_cvp >> 7) == 0x1) { |
376 | * If in AVT mode or if the path already owns the LUN, | 393 | /* LUN in AVT mode */ |
377 | * return RDAC_OWNED; | 394 | sdev_printk(KERN_NOTICE, sdev, |
378 | */ | 395 | "%s: AVT mode detected\n", |
379 | if (((inqp->avte_cvp >> 7) == 0x1) || | 396 | RDAC_NAME); |
380 | ((inqp->avte_cvp & 0x1) != 0)) | 397 | h->lun_state = RDAC_LUN_AVT; |
381 | err = RDAC_OWNED; | 398 | } else if ((inqp->avte_cvp & 0x1) != 0) { |
382 | } else | 399 | /* LUN was owned by the controller */ |
383 | err = RDAC_FAILED; | 400 | h->lun_state = RDAC_LUN_OWNED; |
401 | } | ||
402 | } | ||
403 | |||
384 | return err; | 404 | return err; |
385 | } | 405 | } |
386 | 406 | ||
387 | static int initialize_controller(struct scsi_device *sdev) | 407 | static int initialize_controller(struct scsi_device *sdev, |
408 | struct rdac_dh_data *h) | ||
388 | { | 409 | { |
389 | int err; | 410 | int err; |
390 | struct c4_inquiry *inqp; | 411 | struct c4_inquiry *inqp; |
391 | struct rdac_dh_data *h = get_rdac_data(sdev); | ||
392 | 412 | ||
393 | err = submit_inquiry(sdev, 0xC4, sizeof(struct c4_inquiry)); | 413 | err = submit_inquiry(sdev, 0xC4, sizeof(struct c4_inquiry), h); |
394 | if (err == SCSI_DH_OK) { | 414 | if (err == SCSI_DH_OK) { |
395 | inqp = &h->inq.c4; | 415 | inqp = &h->inq.c4; |
396 | h->ctlr = get_controller(inqp->subsys_id, inqp->slot_id); | 416 | h->ctlr = get_controller(inqp->subsys_id, inqp->slot_id); |
@@ -400,13 +420,12 @@ static int initialize_controller(struct scsi_device *sdev) | |||
400 | return err; | 420 | return err; |
401 | } | 421 | } |
402 | 422 | ||
403 | static int set_mode_select(struct scsi_device *sdev) | 423 | static int set_mode_select(struct scsi_device *sdev, struct rdac_dh_data *h) |
404 | { | 424 | { |
405 | int err; | 425 | int err; |
406 | struct c2_inquiry *inqp; | 426 | struct c2_inquiry *inqp; |
407 | struct rdac_dh_data *h = get_rdac_data(sdev); | ||
408 | 427 | ||
409 | err = submit_inquiry(sdev, 0xC2, sizeof(struct c2_inquiry)); | 428 | err = submit_inquiry(sdev, 0xC2, sizeof(struct c2_inquiry), h); |
410 | if (err == SCSI_DH_OK) { | 429 | if (err == SCSI_DH_OK) { |
411 | inqp = &h->inq.c2; | 430 | inqp = &h->inq.c2; |
412 | /* | 431 | /* |
@@ -421,13 +440,13 @@ static int set_mode_select(struct scsi_device *sdev) | |||
421 | return err; | 440 | return err; |
422 | } | 441 | } |
423 | 442 | ||
424 | static int mode_select_handle_sense(struct scsi_device *sdev) | 443 | static int mode_select_handle_sense(struct scsi_device *sdev, |
444 | unsigned char *sensebuf) | ||
425 | { | 445 | { |
426 | struct scsi_sense_hdr sense_hdr; | 446 | struct scsi_sense_hdr sense_hdr; |
427 | struct rdac_dh_data *h = get_rdac_data(sdev); | ||
428 | int sense, err = SCSI_DH_IO, ret; | 447 | int sense, err = SCSI_DH_IO, ret; |
429 | 448 | ||
430 | ret = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, &sense_hdr); | 449 | ret = scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sense_hdr); |
431 | if (!ret) | 450 | if (!ret) |
432 | goto done; | 451 | goto done; |
433 | 452 | ||
@@ -451,14 +470,13 @@ done: | |||
451 | return err; | 470 | return err; |
452 | } | 471 | } |
453 | 472 | ||
454 | static int send_mode_select(struct scsi_device *sdev) | 473 | static int send_mode_select(struct scsi_device *sdev, struct rdac_dh_data *h) |
455 | { | 474 | { |
456 | struct request *rq; | 475 | struct request *rq; |
457 | struct request_queue *q = sdev->request_queue; | 476 | struct request_queue *q = sdev->request_queue; |
458 | struct rdac_dh_data *h = get_rdac_data(sdev); | ||
459 | int err = SCSI_DH_RES_TEMP_UNAVAIL; | 477 | int err = SCSI_DH_RES_TEMP_UNAVAIL; |
460 | 478 | ||
461 | rq = rdac_failover_get(sdev); | 479 | rq = rdac_failover_get(sdev, h); |
462 | if (!rq) | 480 | if (!rq) |
463 | goto done; | 481 | goto done; |
464 | 482 | ||
@@ -466,9 +484,11 @@ static int send_mode_select(struct scsi_device *sdev) | |||
466 | 484 | ||
467 | err = blk_execute_rq(q, NULL, rq, 1); | 485 | err = blk_execute_rq(q, NULL, rq, 1); |
468 | if (err != SCSI_DH_OK) | 486 | if (err != SCSI_DH_OK) |
469 | err = mode_select_handle_sense(sdev); | 487 | err = mode_select_handle_sense(sdev, h->sense); |
470 | if (err == SCSI_DH_OK) | 488 | if (err == SCSI_DH_OK) |
471 | h->state = RDAC_STATE_ACTIVE; | 489 | h->state = RDAC_STATE_ACTIVE; |
490 | |||
491 | blk_put_request(rq); | ||
472 | done: | 492 | done: |
473 | return err; | 493 | return err; |
474 | } | 494 | } |
@@ -478,38 +498,23 @@ static int rdac_activate(struct scsi_device *sdev) | |||
478 | struct rdac_dh_data *h = get_rdac_data(sdev); | 498 | struct rdac_dh_data *h = get_rdac_data(sdev); |
479 | int err = SCSI_DH_OK; | 499 | int err = SCSI_DH_OK; |
480 | 500 | ||
481 | if (h->lun == UNINITIALIZED_LUN) { | 501 | err = check_ownership(sdev, h); |
482 | err = get_lun(sdev); | 502 | if (err != SCSI_DH_OK) |
483 | if (err != SCSI_DH_OK) | ||
484 | goto done; | ||
485 | } | ||
486 | |||
487 | err = check_ownership(sdev); | ||
488 | switch (err) { | ||
489 | case RDAC_UNOWNED: | ||
490 | break; | ||
491 | case RDAC_OWNED: | ||
492 | err = SCSI_DH_OK; | ||
493 | goto done; | ||
494 | case RDAC_FAILED: | ||
495 | default: | ||
496 | err = SCSI_DH_IO; | ||
497 | goto done; | 503 | goto done; |
498 | } | ||
499 | 504 | ||
500 | if (!h->ctlr) { | 505 | if (!h->ctlr) { |
501 | err = initialize_controller(sdev); | 506 | err = initialize_controller(sdev, h); |
502 | if (err != SCSI_DH_OK) | 507 | if (err != SCSI_DH_OK) |
503 | goto done; | 508 | goto done; |
504 | } | 509 | } |
505 | 510 | ||
506 | if (h->ctlr->use_ms10 == -1) { | 511 | if (h->ctlr->use_ms10 == -1) { |
507 | err = set_mode_select(sdev); | 512 | err = set_mode_select(sdev, h); |
508 | if (err != SCSI_DH_OK) | 513 | if (err != SCSI_DH_OK) |
509 | goto done; | 514 | goto done; |
510 | } | 515 | } |
511 | 516 | if (h->lun_state == RDAC_LUN_UNOWNED) | |
512 | err = send_mode_select(sdev); | 517 | err = send_mode_select(sdev, h); |
513 | done: | 518 | done: |
514 | return err; | 519 | return err; |
515 | } | 520 | } |
@@ -569,10 +574,7 @@ static int rdac_check_sense(struct scsi_device *sdev, | |||
569 | return SCSI_RETURN_NOT_HANDLED; | 574 | return SCSI_RETURN_NOT_HANDLED; |
570 | } | 575 | } |
571 | 576 | ||
572 | static const struct { | 577 | const struct scsi_dh_devlist rdac_dev_list[] = { |
573 | char *vendor; | ||
574 | char *model; | ||
575 | } rdac_dev_list[] = { | ||
576 | {"IBM", "1722"}, | 578 | {"IBM", "1722"}, |
577 | {"IBM", "1724"}, | 579 | {"IBM", "1724"}, |
578 | {"IBM", "1726"}, | 580 | {"IBM", "1726"}, |
@@ -590,89 +592,89 @@ static const struct { | |||
590 | {NULL, NULL}, | 592 | {NULL, NULL}, |
591 | }; | 593 | }; |
592 | 594 | ||
593 | static int rdac_bus_notify(struct notifier_block *, unsigned long, void *); | 595 | static int rdac_bus_attach(struct scsi_device *sdev); |
596 | static void rdac_bus_detach(struct scsi_device *sdev); | ||
594 | 597 | ||
595 | static struct scsi_device_handler rdac_dh = { | 598 | static struct scsi_device_handler rdac_dh = { |
596 | .name = RDAC_NAME, | 599 | .name = RDAC_NAME, |
597 | .module = THIS_MODULE, | 600 | .module = THIS_MODULE, |
598 | .nb.notifier_call = rdac_bus_notify, | 601 | .devlist = rdac_dev_list, |
599 | .prep_fn = rdac_prep_fn, | 602 | .prep_fn = rdac_prep_fn, |
600 | .check_sense = rdac_check_sense, | 603 | .check_sense = rdac_check_sense, |
604 | .attach = rdac_bus_attach, | ||
605 | .detach = rdac_bus_detach, | ||
601 | .activate = rdac_activate, | 606 | .activate = rdac_activate, |
602 | }; | 607 | }; |
603 | 608 | ||
604 | /* | 609 | static int rdac_bus_attach(struct scsi_device *sdev) |
605 | * TODO: need some interface so we can set trespass values | ||
606 | */ | ||
607 | static int rdac_bus_notify(struct notifier_block *nb, | ||
608 | unsigned long action, void *data) | ||
609 | { | 610 | { |
610 | struct device *dev = data; | ||
611 | struct scsi_device *sdev; | ||
612 | struct scsi_dh_data *scsi_dh_data; | 611 | struct scsi_dh_data *scsi_dh_data; |
613 | struct rdac_dh_data *h; | 612 | struct rdac_dh_data *h; |
614 | int i, found = 0; | ||
615 | unsigned long flags; | 613 | unsigned long flags; |
614 | int err; | ||
616 | 615 | ||
617 | if (!scsi_is_sdev_device(dev)) | 616 | scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) |
617 | + sizeof(*h) , GFP_KERNEL); | ||
618 | if (!scsi_dh_data) { | ||
619 | sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n", | ||
620 | RDAC_NAME); | ||
618 | return 0; | 621 | return 0; |
622 | } | ||
619 | 623 | ||
620 | sdev = to_scsi_device(dev); | 624 | scsi_dh_data->scsi_dh = &rdac_dh; |
621 | 625 | h = (struct rdac_dh_data *) scsi_dh_data->buf; | |
622 | if (action == BUS_NOTIFY_ADD_DEVICE) { | 626 | h->lun = UNINITIALIZED_LUN; |
623 | for (i = 0; rdac_dev_list[i].vendor; i++) { | 627 | h->state = RDAC_STATE_ACTIVE; |
624 | if (!strncmp(sdev->vendor, rdac_dev_list[i].vendor, | ||
625 | strlen(rdac_dev_list[i].vendor)) && | ||
626 | !strncmp(sdev->model, rdac_dev_list[i].model, | ||
627 | strlen(rdac_dev_list[i].model))) { | ||
628 | found = 1; | ||
629 | break; | ||
630 | } | ||
631 | } | ||
632 | if (!found) | ||
633 | goto out; | ||
634 | 628 | ||
635 | scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) | 629 | err = get_lun(sdev, h); |
636 | + sizeof(*h) , GFP_KERNEL); | 630 | if (err != SCSI_DH_OK) |
637 | if (!scsi_dh_data) { | 631 | goto failed; |
638 | sdev_printk(KERN_ERR, sdev, "Attach failed %s.\n", | ||
639 | RDAC_NAME); | ||
640 | goto out; | ||
641 | } | ||
642 | 632 | ||
643 | scsi_dh_data->scsi_dh = &rdac_dh; | 633 | err = check_ownership(sdev, h); |
644 | h = (struct rdac_dh_data *) scsi_dh_data->buf; | 634 | if (err != SCSI_DH_OK) |
645 | h->lun = UNINITIALIZED_LUN; | 635 | goto failed; |
646 | h->state = RDAC_STATE_ACTIVE; | 636 | |
647 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | 637 | if (!try_module_get(THIS_MODULE)) |
648 | sdev->scsi_dh_data = scsi_dh_data; | 638 | goto failed; |
649 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | 639 | |
650 | try_module_get(THIS_MODULE); | 640 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); |
651 | 641 | sdev->scsi_dh_data = scsi_dh_data; | |
652 | sdev_printk(KERN_NOTICE, sdev, "Attached %s.\n", RDAC_NAME); | 642 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); |
653 | 643 | ||
654 | } else if (action == BUS_NOTIFY_DEL_DEVICE) { | 644 | sdev_printk(KERN_NOTICE, sdev, |
655 | if (sdev->scsi_dh_data == NULL || | 645 | "%s: LUN %d (%s)\n", |
656 | sdev->scsi_dh_data->scsi_dh != &rdac_dh) | 646 | RDAC_NAME, h->lun, lun_state[(int)h->lun_state]); |
657 | goto out; | ||
658 | |||
659 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | ||
660 | scsi_dh_data = sdev->scsi_dh_data; | ||
661 | sdev->scsi_dh_data = NULL; | ||
662 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
663 | |||
664 | h = (struct rdac_dh_data *) scsi_dh_data->buf; | ||
665 | if (h->ctlr) | ||
666 | kref_put(&h->ctlr->kref, release_controller); | ||
667 | kfree(scsi_dh_data); | ||
668 | module_put(THIS_MODULE); | ||
669 | sdev_printk(KERN_NOTICE, sdev, "Dettached %s.\n", RDAC_NAME); | ||
670 | } | ||
671 | 647 | ||
672 | out: | ||
673 | return 0; | 648 | return 0; |
649 | |||
650 | failed: | ||
651 | kfree(scsi_dh_data); | ||
652 | sdev_printk(KERN_ERR, sdev, "%s: not attached\n", | ||
653 | RDAC_NAME); | ||
654 | return -EINVAL; | ||
655 | } | ||
656 | |||
657 | static void rdac_bus_detach( struct scsi_device *sdev ) | ||
658 | { | ||
659 | struct scsi_dh_data *scsi_dh_data; | ||
660 | struct rdac_dh_data *h; | ||
661 | unsigned long flags; | ||
662 | |||
663 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | ||
664 | scsi_dh_data = sdev->scsi_dh_data; | ||
665 | sdev->scsi_dh_data = NULL; | ||
666 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
667 | |||
668 | h = (struct rdac_dh_data *) scsi_dh_data->buf; | ||
669 | if (h->ctlr) | ||
670 | kref_put(&h->ctlr->kref, release_controller); | ||
671 | kfree(scsi_dh_data); | ||
672 | module_put(THIS_MODULE); | ||
673 | sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", RDAC_NAME); | ||
674 | } | 674 | } |
675 | 675 | ||
676 | |||
677 | |||
676 | static int __init rdac_init(void) | 678 | static int __init rdac_init(void) |
677 | { | 679 | { |
678 | int r; | 680 | int r; |
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 61f8fdea2d96..ae560bc04f9d 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c | |||
@@ -521,9 +521,10 @@ static void ibmvfc_set_host_action(struct ibmvfc_host *vhost, | |||
521 | static void ibmvfc_reinit_host(struct ibmvfc_host *vhost) | 521 | static void ibmvfc_reinit_host(struct ibmvfc_host *vhost) |
522 | { | 522 | { |
523 | if (vhost->action == IBMVFC_HOST_ACTION_NONE) { | 523 | if (vhost->action == IBMVFC_HOST_ACTION_NONE) { |
524 | scsi_block_requests(vhost->host); | 524 | if (!ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING)) { |
525 | ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING); | 525 | scsi_block_requests(vhost->host); |
526 | ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY); | 526 | ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY); |
527 | } | ||
527 | } else | 528 | } else |
528 | vhost->reinit = 1; | 529 | vhost->reinit = 1; |
529 | 530 | ||
@@ -854,39 +855,41 @@ static void ibmvfc_retry_host_init(struct ibmvfc_host *vhost) | |||
854 | } | 855 | } |
855 | 856 | ||
856 | /** | 857 | /** |
857 | * __ibmvfc_find_target - Find the specified scsi_target (no locking) | 858 | * __ibmvfc_get_target - Find the specified scsi_target (no locking) |
858 | * @starget: scsi target struct | 859 | * @starget: scsi target struct |
859 | * | 860 | * |
860 | * Return value: | 861 | * Return value: |
861 | * ibmvfc_target struct / NULL if not found | 862 | * ibmvfc_target struct / NULL if not found |
862 | **/ | 863 | **/ |
863 | static struct ibmvfc_target *__ibmvfc_find_target(struct scsi_target *starget) | 864 | static struct ibmvfc_target *__ibmvfc_get_target(struct scsi_target *starget) |
864 | { | 865 | { |
865 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 866 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
866 | struct ibmvfc_host *vhost = shost_priv(shost); | 867 | struct ibmvfc_host *vhost = shost_priv(shost); |
867 | struct ibmvfc_target *tgt; | 868 | struct ibmvfc_target *tgt; |
868 | 869 | ||
869 | list_for_each_entry(tgt, &vhost->targets, queue) | 870 | list_for_each_entry(tgt, &vhost->targets, queue) |
870 | if (tgt->target_id == starget->id) | 871 | if (tgt->target_id == starget->id) { |
872 | kref_get(&tgt->kref); | ||
871 | return tgt; | 873 | return tgt; |
874 | } | ||
872 | return NULL; | 875 | return NULL; |
873 | } | 876 | } |
874 | 877 | ||
875 | /** | 878 | /** |
876 | * ibmvfc_find_target - Find the specified scsi_target | 879 | * ibmvfc_get_target - Find the specified scsi_target |
877 | * @starget: scsi target struct | 880 | * @starget: scsi target struct |
878 | * | 881 | * |
879 | * Return value: | 882 | * Return value: |
880 | * ibmvfc_target struct / NULL if not found | 883 | * ibmvfc_target struct / NULL if not found |
881 | **/ | 884 | **/ |
882 | static struct ibmvfc_target *ibmvfc_find_target(struct scsi_target *starget) | 885 | static struct ibmvfc_target *ibmvfc_get_target(struct scsi_target *starget) |
883 | { | 886 | { |
884 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 887 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
885 | struct ibmvfc_target *tgt; | 888 | struct ibmvfc_target *tgt; |
886 | unsigned long flags; | 889 | unsigned long flags; |
887 | 890 | ||
888 | spin_lock_irqsave(shost->host_lock, flags); | 891 | spin_lock_irqsave(shost->host_lock, flags); |
889 | tgt = __ibmvfc_find_target(starget); | 892 | tgt = __ibmvfc_get_target(starget); |
890 | spin_unlock_irqrestore(shost->host_lock, flags); | 893 | spin_unlock_irqrestore(shost->host_lock, flags); |
891 | return tgt; | 894 | return tgt; |
892 | } | 895 | } |
@@ -963,6 +966,9 @@ static void ibmvfc_get_host_port_state(struct Scsi_Host *shost) | |||
963 | case IBMVFC_HALTED: | 966 | case IBMVFC_HALTED: |
964 | fc_host_port_state(shost) = FC_PORTSTATE_BLOCKED; | 967 | fc_host_port_state(shost) = FC_PORTSTATE_BLOCKED; |
965 | break; | 968 | break; |
969 | case IBMVFC_NO_CRQ: | ||
970 | fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; | ||
971 | break; | ||
966 | default: | 972 | default: |
967 | ibmvfc_log(vhost, 3, "Unknown port state: %d\n", vhost->state); | 973 | ibmvfc_log(vhost, 3, "Unknown port state: %d\n", vhost->state); |
968 | fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; | 974 | fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; |
@@ -988,6 +994,17 @@ static void ibmvfc_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout) | |||
988 | } | 994 | } |
989 | 995 | ||
990 | /** | 996 | /** |
997 | * ibmvfc_release_tgt - Free memory allocated for a target | ||
998 | * @kref: kref struct | ||
999 | * | ||
1000 | **/ | ||
1001 | static void ibmvfc_release_tgt(struct kref *kref) | ||
1002 | { | ||
1003 | struct ibmvfc_target *tgt = container_of(kref, struct ibmvfc_target, kref); | ||
1004 | kfree(tgt); | ||
1005 | } | ||
1006 | |||
1007 | /** | ||
991 | * ibmvfc_get_starget_node_name - Get SCSI target's node name | 1008 | * ibmvfc_get_starget_node_name - Get SCSI target's node name |
992 | * @starget: scsi target struct | 1009 | * @starget: scsi target struct |
993 | * | 1010 | * |
@@ -996,8 +1013,10 @@ static void ibmvfc_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout) | |||
996 | **/ | 1013 | **/ |
997 | static void ibmvfc_get_starget_node_name(struct scsi_target *starget) | 1014 | static void ibmvfc_get_starget_node_name(struct scsi_target *starget) |
998 | { | 1015 | { |
999 | struct ibmvfc_target *tgt = ibmvfc_find_target(starget); | 1016 | struct ibmvfc_target *tgt = ibmvfc_get_target(starget); |
1000 | fc_starget_port_name(starget) = tgt ? tgt->ids.node_name : 0; | 1017 | fc_starget_port_name(starget) = tgt ? tgt->ids.node_name : 0; |
1018 | if (tgt) | ||
1019 | kref_put(&tgt->kref, ibmvfc_release_tgt); | ||
1001 | } | 1020 | } |
1002 | 1021 | ||
1003 | /** | 1022 | /** |
@@ -1009,8 +1028,10 @@ static void ibmvfc_get_starget_node_name(struct scsi_target *starget) | |||
1009 | **/ | 1028 | **/ |
1010 | static void ibmvfc_get_starget_port_name(struct scsi_target *starget) | 1029 | static void ibmvfc_get_starget_port_name(struct scsi_target *starget) |
1011 | { | 1030 | { |
1012 | struct ibmvfc_target *tgt = ibmvfc_find_target(starget); | 1031 | struct ibmvfc_target *tgt = ibmvfc_get_target(starget); |
1013 | fc_starget_port_name(starget) = tgt ? tgt->ids.port_name : 0; | 1032 | fc_starget_port_name(starget) = tgt ? tgt->ids.port_name : 0; |
1033 | if (tgt) | ||
1034 | kref_put(&tgt->kref, ibmvfc_release_tgt); | ||
1014 | } | 1035 | } |
1015 | 1036 | ||
1016 | /** | 1037 | /** |
@@ -1022,8 +1043,10 @@ static void ibmvfc_get_starget_port_name(struct scsi_target *starget) | |||
1022 | **/ | 1043 | **/ |
1023 | static void ibmvfc_get_starget_port_id(struct scsi_target *starget) | 1044 | static void ibmvfc_get_starget_port_id(struct scsi_target *starget) |
1024 | { | 1045 | { |
1025 | struct ibmvfc_target *tgt = ibmvfc_find_target(starget); | 1046 | struct ibmvfc_target *tgt = ibmvfc_get_target(starget); |
1026 | fc_starget_port_id(starget) = tgt ? tgt->scsi_id : -1; | 1047 | fc_starget_port_id(starget) = tgt ? tgt->scsi_id : -1; |
1048 | if (tgt) | ||
1049 | kref_put(&tgt->kref, ibmvfc_release_tgt); | ||
1027 | } | 1050 | } |
1028 | 1051 | ||
1029 | /** | 1052 | /** |
@@ -1113,7 +1136,7 @@ static void ibmvfc_set_login_info(struct ibmvfc_host *vhost) | |||
1113 | login_info->max_cmds = max_requests + IBMVFC_NUM_INTERNAL_REQ; | 1136 | login_info->max_cmds = max_requests + IBMVFC_NUM_INTERNAL_REQ; |
1114 | login_info->capabilities = IBMVFC_CAN_MIGRATE; | 1137 | login_info->capabilities = IBMVFC_CAN_MIGRATE; |
1115 | login_info->async.va = vhost->async_crq.msg_token; | 1138 | login_info->async.va = vhost->async_crq.msg_token; |
1116 | login_info->async.len = vhost->async_crq.size; | 1139 | login_info->async.len = vhost->async_crq.size * sizeof(*vhost->async_crq.msgs); |
1117 | strncpy(login_info->partition_name, vhost->partition_name, IBMVFC_MAX_NAME); | 1140 | strncpy(login_info->partition_name, vhost->partition_name, IBMVFC_MAX_NAME); |
1118 | strncpy(login_info->device_name, | 1141 | strncpy(login_info->device_name, |
1119 | vhost->host->shost_gendev.bus_id, IBMVFC_MAX_NAME); | 1142 | vhost->host->shost_gendev.bus_id, IBMVFC_MAX_NAME); |
@@ -1404,7 +1427,7 @@ static void ibmvfc_log_error(struct ibmvfc_event *evt) | |||
1404 | err = cmd_status[index].name; | 1427 | err = cmd_status[index].name; |
1405 | } | 1428 | } |
1406 | 1429 | ||
1407 | if (!logerr && (vhost->log_level <= IBMVFC_DEFAULT_LOG_LEVEL)) | 1430 | if (!logerr && (vhost->log_level <= (IBMVFC_DEFAULT_LOG_LEVEL + 1))) |
1408 | return; | 1431 | return; |
1409 | 1432 | ||
1410 | if (rsp->flags & FCP_RSP_LEN_VALID) | 1433 | if (rsp->flags & FCP_RSP_LEN_VALID) |
@@ -2054,7 +2077,7 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, | |||
2054 | { | 2077 | { |
2055 | const char *desc = ibmvfc_get_ae_desc(crq->event); | 2078 | const char *desc = ibmvfc_get_ae_desc(crq->event); |
2056 | 2079 | ||
2057 | ibmvfc_log(vhost, 2, "%s event received\n", desc); | 2080 | ibmvfc_log(vhost, 3, "%s event received\n", desc); |
2058 | 2081 | ||
2059 | switch (crq->event) { | 2082 | switch (crq->event) { |
2060 | case IBMVFC_AE_LINK_UP: | 2083 | case IBMVFC_AE_LINK_UP: |
@@ -2648,17 +2671,6 @@ static void ibmvfc_retry_tgt_init(struct ibmvfc_target *tgt, | |||
2648 | } | 2671 | } |
2649 | 2672 | ||
2650 | /** | 2673 | /** |
2651 | * ibmvfc_release_tgt - Free memory allocated for a target | ||
2652 | * @kref: kref struct | ||
2653 | * | ||
2654 | **/ | ||
2655 | static void ibmvfc_release_tgt(struct kref *kref) | ||
2656 | { | ||
2657 | struct ibmvfc_target *tgt = container_of(kref, struct ibmvfc_target, kref); | ||
2658 | kfree(tgt); | ||
2659 | } | ||
2660 | |||
2661 | /** | ||
2662 | * ibmvfc_tgt_prli_done - Completion handler for Process Login | 2674 | * ibmvfc_tgt_prli_done - Completion handler for Process Login |
2663 | * @evt: ibmvfc event struct | 2675 | * @evt: ibmvfc event struct |
2664 | * | 2676 | * |
@@ -2902,6 +2914,139 @@ static void ibmvfc_tgt_implicit_logout(struct ibmvfc_target *tgt) | |||
2902 | } | 2914 | } |
2903 | 2915 | ||
2904 | /** | 2916 | /** |
2917 | * ibmvfc_adisc_needs_plogi - Does device need PLOGI? | ||
2918 | * @mad: ibmvfc passthru mad struct | ||
2919 | * @tgt: ibmvfc target struct | ||
2920 | * | ||
2921 | * Returns: | ||
2922 | * 1 if PLOGI needed / 0 if PLOGI not needed | ||
2923 | **/ | ||
2924 | static int ibmvfc_adisc_needs_plogi(struct ibmvfc_passthru_mad *mad, | ||
2925 | struct ibmvfc_target *tgt) | ||
2926 | { | ||
2927 | if (memcmp(&mad->fc_iu.response[2], &tgt->ids.port_name, | ||
2928 | sizeof(tgt->ids.port_name))) | ||
2929 | return 1; | ||
2930 | if (memcmp(&mad->fc_iu.response[4], &tgt->ids.node_name, | ||
2931 | sizeof(tgt->ids.node_name))) | ||
2932 | return 1; | ||
2933 | if (mad->fc_iu.response[6] != tgt->scsi_id) | ||
2934 | return 1; | ||
2935 | return 0; | ||
2936 | } | ||
2937 | |||
2938 | /** | ||
2939 | * ibmvfc_tgt_adisc_done - Completion handler for ADISC | ||
2940 | * @evt: ibmvfc event struct | ||
2941 | * | ||
2942 | **/ | ||
2943 | static void ibmvfc_tgt_adisc_done(struct ibmvfc_event *evt) | ||
2944 | { | ||
2945 | struct ibmvfc_target *tgt = evt->tgt; | ||
2946 | struct ibmvfc_host *vhost = evt->vhost; | ||
2947 | struct ibmvfc_passthru_mad *mad = &evt->xfer_iu->passthru; | ||
2948 | u32 status = mad->common.status; | ||
2949 | u8 fc_reason, fc_explain; | ||
2950 | |||
2951 | vhost->discovery_threads--; | ||
2952 | ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); | ||
2953 | |||
2954 | switch (status) { | ||
2955 | case IBMVFC_MAD_SUCCESS: | ||
2956 | tgt_dbg(tgt, "ADISC succeeded\n"); | ||
2957 | if (ibmvfc_adisc_needs_plogi(mad, tgt)) | ||
2958 | tgt->need_login = 1; | ||
2959 | break; | ||
2960 | case IBMVFC_MAD_DRIVER_FAILED: | ||
2961 | break; | ||
2962 | case IBMVFC_MAD_FAILED: | ||
2963 | default: | ||
2964 | tgt->need_login = 1; | ||
2965 | fc_reason = (mad->fc_iu.response[1] & 0x00ff0000) >> 16; | ||
2966 | fc_explain = (mad->fc_iu.response[1] & 0x0000ff00) >> 8; | ||
2967 | tgt_info(tgt, "ADISC failed: %s (%x:%x) %s (%x) %s (%x) rc=0x%02X\n", | ||
2968 | ibmvfc_get_cmd_error(mad->iu.status, mad->iu.error), | ||
2969 | mad->iu.status, mad->iu.error, | ||
2970 | ibmvfc_get_fc_type(fc_reason), fc_reason, | ||
2971 | ibmvfc_get_ls_explain(fc_explain), fc_explain, status); | ||
2972 | break; | ||
2973 | }; | ||
2974 | |||
2975 | kref_put(&tgt->kref, ibmvfc_release_tgt); | ||
2976 | ibmvfc_free_event(evt); | ||
2977 | wake_up(&vhost->work_wait_q); | ||
2978 | } | ||
2979 | |||
2980 | /** | ||
2981 | * ibmvfc_init_passthru - Initialize an event struct for FC passthru | ||
2982 | * @evt: ibmvfc event struct | ||
2983 | * | ||
2984 | **/ | ||
2985 | static void ibmvfc_init_passthru(struct ibmvfc_event *evt) | ||
2986 | { | ||
2987 | struct ibmvfc_passthru_mad *mad = &evt->iu.passthru; | ||
2988 | |||
2989 | memset(mad, 0, sizeof(*mad)); | ||
2990 | mad->common.version = 1; | ||
2991 | mad->common.opcode = IBMVFC_PASSTHRU; | ||
2992 | mad->common.length = sizeof(*mad) - sizeof(mad->fc_iu) - sizeof(mad->iu); | ||
2993 | mad->cmd_ioba.va = (u64)evt->crq.ioba + | ||
2994 | offsetof(struct ibmvfc_passthru_mad, iu); | ||
2995 | mad->cmd_ioba.len = sizeof(mad->iu); | ||
2996 | mad->iu.cmd_len = sizeof(mad->fc_iu.payload); | ||
2997 | mad->iu.rsp_len = sizeof(mad->fc_iu.response); | ||
2998 | mad->iu.cmd.va = (u64)evt->crq.ioba + | ||
2999 | offsetof(struct ibmvfc_passthru_mad, fc_iu) + | ||
3000 | offsetof(struct ibmvfc_passthru_fc_iu, payload); | ||
3001 | mad->iu.cmd.len = sizeof(mad->fc_iu.payload); | ||
3002 | mad->iu.rsp.va = (u64)evt->crq.ioba + | ||
3003 | offsetof(struct ibmvfc_passthru_mad, fc_iu) + | ||
3004 | offsetof(struct ibmvfc_passthru_fc_iu, response); | ||
3005 | mad->iu.rsp.len = sizeof(mad->fc_iu.response); | ||
3006 | } | ||
3007 | |||
3008 | /** | ||
3009 | * ibmvfc_tgt_adisc - Initiate an ADISC for specified target | ||
3010 | * @tgt: ibmvfc target struct | ||
3011 | * | ||
3012 | **/ | ||
3013 | static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt) | ||
3014 | { | ||
3015 | struct ibmvfc_passthru_mad *mad; | ||
3016 | struct ibmvfc_host *vhost = tgt->vhost; | ||
3017 | struct ibmvfc_event *evt; | ||
3018 | |||
3019 | if (vhost->discovery_threads >= disc_threads) | ||
3020 | return; | ||
3021 | |||
3022 | kref_get(&tgt->kref); | ||
3023 | evt = ibmvfc_get_event(vhost); | ||
3024 | vhost->discovery_threads++; | ||
3025 | ibmvfc_init_event(evt, ibmvfc_tgt_adisc_done, IBMVFC_MAD_FORMAT); | ||
3026 | evt->tgt = tgt; | ||
3027 | |||
3028 | ibmvfc_init_passthru(evt); | ||
3029 | mad = &evt->iu.passthru; | ||
3030 | mad->iu.flags = IBMVFC_FC_ELS; | ||
3031 | mad->iu.scsi_id = tgt->scsi_id; | ||
3032 | |||
3033 | mad->fc_iu.payload[0] = IBMVFC_ADISC; | ||
3034 | memcpy(&mad->fc_iu.payload[2], &vhost->login_buf->resp.port_name, | ||
3035 | sizeof(vhost->login_buf->resp.port_name)); | ||
3036 | memcpy(&mad->fc_iu.payload[4], &vhost->login_buf->resp.node_name, | ||
3037 | sizeof(vhost->login_buf->resp.node_name)); | ||
3038 | mad->fc_iu.payload[6] = vhost->login_buf->resp.scsi_id & 0x00ffffff; | ||
3039 | |||
3040 | ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); | ||
3041 | if (ibmvfc_send_event(evt, vhost, default_timeout)) { | ||
3042 | vhost->discovery_threads--; | ||
3043 | ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); | ||
3044 | kref_put(&tgt->kref, ibmvfc_release_tgt); | ||
3045 | } else | ||
3046 | tgt_dbg(tgt, "Sent ADISC\n"); | ||
3047 | } | ||
3048 | |||
3049 | /** | ||
2905 | * ibmvfc_tgt_query_target_done - Completion handler for Query Target MAD | 3050 | * ibmvfc_tgt_query_target_done - Completion handler for Query Target MAD |
2906 | * @evt: ibmvfc event struct | 3051 | * @evt: ibmvfc event struct |
2907 | * | 3052 | * |
@@ -2921,6 +3066,8 @@ static void ibmvfc_tgt_query_target_done(struct ibmvfc_event *evt) | |||
2921 | tgt->new_scsi_id = rsp->scsi_id; | 3066 | tgt->new_scsi_id = rsp->scsi_id; |
2922 | if (rsp->scsi_id != tgt->scsi_id) | 3067 | if (rsp->scsi_id != tgt->scsi_id) |
2923 | ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout); | 3068 | ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout); |
3069 | else | ||
3070 | ibmvfc_init_tgt(tgt, ibmvfc_tgt_adisc); | ||
2924 | break; | 3071 | break; |
2925 | case IBMVFC_MAD_DRIVER_FAILED: | 3072 | case IBMVFC_MAD_DRIVER_FAILED: |
2926 | break; | 3073 | break; |
@@ -3336,6 +3483,7 @@ static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt) | |||
3336 | tgt_dbg(tgt, "rport add succeeded\n"); | 3483 | tgt_dbg(tgt, "rport add succeeded\n"); |
3337 | rport->maxframe_size = tgt->service_parms.common.bb_rcv_sz & 0x0fff; | 3484 | rport->maxframe_size = tgt->service_parms.common.bb_rcv_sz & 0x0fff; |
3338 | rport->supported_classes = 0; | 3485 | rport->supported_classes = 0; |
3486 | tgt->target_id = rport->scsi_target_id; | ||
3339 | if (tgt->service_parms.class1_parms[0] & 0x80000000) | 3487 | if (tgt->service_parms.class1_parms[0] & 0x80000000) |
3340 | rport->supported_classes |= FC_COS_CLASS1; | 3488 | rport->supported_classes |= FC_COS_CLASS1; |
3341 | if (tgt->service_parms.class2_parms[0] & 0x80000000) | 3489 | if (tgt->service_parms.class2_parms[0] & 0x80000000) |
@@ -3800,10 +3948,12 @@ static int ibmvfc_remove(struct vio_dev *vdev) | |||
3800 | 3948 | ||
3801 | ENTER; | 3949 | ENTER; |
3802 | ibmvfc_remove_trace_file(&vhost->host->shost_dev.kobj, &ibmvfc_trace_attr); | 3950 | ibmvfc_remove_trace_file(&vhost->host->shost_dev.kobj, &ibmvfc_trace_attr); |
3951 | ibmvfc_link_down(vhost, IBMVFC_HOST_OFFLINE); | ||
3952 | ibmvfc_wait_while_resetting(vhost); | ||
3953 | ibmvfc_release_crq_queue(vhost); | ||
3803 | kthread_stop(vhost->work_thread); | 3954 | kthread_stop(vhost->work_thread); |
3804 | fc_remove_host(vhost->host); | 3955 | fc_remove_host(vhost->host); |
3805 | scsi_remove_host(vhost->host); | 3956 | scsi_remove_host(vhost->host); |
3806 | ibmvfc_release_crq_queue(vhost); | ||
3807 | 3957 | ||
3808 | spin_lock_irqsave(vhost->host->host_lock, flags); | 3958 | spin_lock_irqsave(vhost->host->host_lock, flags); |
3809 | ibmvfc_purge_requests(vhost, DID_ERROR); | 3959 | ibmvfc_purge_requests(vhost, DID_ERROR); |
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h index 057f3c01ed61..4bf6e374f076 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.h +++ b/drivers/scsi/ibmvscsi/ibmvfc.h | |||
@@ -29,8 +29,8 @@ | |||
29 | #include "viosrp.h" | 29 | #include "viosrp.h" |
30 | 30 | ||
31 | #define IBMVFC_NAME "ibmvfc" | 31 | #define IBMVFC_NAME "ibmvfc" |
32 | #define IBMVFC_DRIVER_VERSION "1.0.0" | 32 | #define IBMVFC_DRIVER_VERSION "1.0.1" |
33 | #define IBMVFC_DRIVER_DATE "(July 1, 2008)" | 33 | #define IBMVFC_DRIVER_DATE "(July 11, 2008)" |
34 | 34 | ||
35 | #define IBMVFC_DEFAULT_TIMEOUT 15 | 35 | #define IBMVFC_DEFAULT_TIMEOUT 15 |
36 | #define IBMVFC_INIT_TIMEOUT 30 | 36 | #define IBMVFC_INIT_TIMEOUT 30 |
@@ -119,6 +119,7 @@ enum ibmvfc_mad_types { | |||
119 | IBMVFC_PROCESS_LOGIN = 0x0008, | 119 | IBMVFC_PROCESS_LOGIN = 0x0008, |
120 | IBMVFC_QUERY_TARGET = 0x0010, | 120 | IBMVFC_QUERY_TARGET = 0x0010, |
121 | IBMVFC_IMPLICIT_LOGOUT = 0x0040, | 121 | IBMVFC_IMPLICIT_LOGOUT = 0x0040, |
122 | IBMVFC_PASSTHRU = 0x0200, | ||
122 | IBMVFC_TMF_MAD = 0x0100, | 123 | IBMVFC_TMF_MAD = 0x0100, |
123 | }; | 124 | }; |
124 | 125 | ||
@@ -439,6 +440,37 @@ struct ibmvfc_cmd { | |||
439 | struct ibmvfc_fcp_rsp rsp; | 440 | struct ibmvfc_fcp_rsp rsp; |
440 | }__attribute__((packed, aligned (8))); | 441 | }__attribute__((packed, aligned (8))); |
441 | 442 | ||
443 | struct ibmvfc_passthru_fc_iu { | ||
444 | u32 payload[7]; | ||
445 | #define IBMVFC_ADISC 0x52000000 | ||
446 | u32 response[7]; | ||
447 | }; | ||
448 | |||
449 | struct ibmvfc_passthru_iu { | ||
450 | u64 task_tag; | ||
451 | u32 cmd_len; | ||
452 | u32 rsp_len; | ||
453 | u16 status; | ||
454 | u16 error; | ||
455 | u32 flags; | ||
456 | #define IBMVFC_FC_ELS 0x01 | ||
457 | u32 cancel_key; | ||
458 | u32 reserved; | ||
459 | struct srp_direct_buf cmd; | ||
460 | struct srp_direct_buf rsp; | ||
461 | u64 correlation; | ||
462 | u64 scsi_id; | ||
463 | u64 tag; | ||
464 | u64 reserved2[2]; | ||
465 | }__attribute__((packed, aligned (8))); | ||
466 | |||
467 | struct ibmvfc_passthru_mad { | ||
468 | struct ibmvfc_mad_common common; | ||
469 | struct srp_direct_buf cmd_ioba; | ||
470 | struct ibmvfc_passthru_iu iu; | ||
471 | struct ibmvfc_passthru_fc_iu fc_iu; | ||
472 | }__attribute__((packed, aligned (8))); | ||
473 | |||
442 | struct ibmvfc_trace_start_entry { | 474 | struct ibmvfc_trace_start_entry { |
443 | u32 xfer_len; | 475 | u32 xfer_len; |
444 | }__attribute__((packed)); | 476 | }__attribute__((packed)); |
@@ -531,6 +563,7 @@ union ibmvfc_iu { | |||
531 | struct ibmvfc_implicit_logout implicit_logout; | 563 | struct ibmvfc_implicit_logout implicit_logout; |
532 | struct ibmvfc_tmf tmf; | 564 | struct ibmvfc_tmf tmf; |
533 | struct ibmvfc_cmd cmd; | 565 | struct ibmvfc_cmd cmd; |
566 | struct ibmvfc_passthru_mad passthru; | ||
534 | }__attribute__((packed, aligned (8))); | 567 | }__attribute__((packed, aligned (8))); |
535 | 568 | ||
536 | enum ibmvfc_target_action { | 569 | enum ibmvfc_target_action { |
@@ -656,6 +689,9 @@ struct ibmvfc_host { | |||
656 | #define tgt_dbg(t, fmt, ...) \ | 689 | #define tgt_dbg(t, fmt, ...) \ |
657 | DBG_CMD(dev_info((t)->vhost->dev, "%lX: " fmt, (t)->scsi_id, ##__VA_ARGS__)) | 690 | DBG_CMD(dev_info((t)->vhost->dev, "%lX: " fmt, (t)->scsi_id, ##__VA_ARGS__)) |
658 | 691 | ||
692 | #define tgt_info(t, fmt, ...) \ | ||
693 | dev_info((t)->vhost->dev, "%lX: " fmt, (t)->scsi_id, ##__VA_ARGS__) | ||
694 | |||
659 | #define tgt_err(t, fmt, ...) \ | 695 | #define tgt_err(t, fmt, ...) \ |
660 | dev_err((t)->vhost->dev, "%lX: " fmt, (t)->scsi_id, ##__VA_ARGS__) | 696 | dev_err((t)->vhost->dev, "%lX: " fmt, (t)->scsi_id, ##__VA_ARGS__) |
661 | 697 | ||
@@ -668,8 +704,8 @@ struct ibmvfc_host { | |||
668 | dev_err((vhost)->dev, ##__VA_ARGS__); \ | 704 | dev_err((vhost)->dev, ##__VA_ARGS__); \ |
669 | } while (0) | 705 | } while (0) |
670 | 706 | ||
671 | #define ENTER DBG_CMD(printk(KERN_INFO IBMVFC_NAME": Entering %s\n", __FUNCTION__)) | 707 | #define ENTER DBG_CMD(printk(KERN_INFO IBMVFC_NAME": Entering %s\n", __func__)) |
672 | #define LEAVE DBG_CMD(printk(KERN_INFO IBMVFC_NAME": Leaving %s\n", __FUNCTION__)) | 708 | #define LEAVE DBG_CMD(printk(KERN_INFO IBMVFC_NAME": Leaving %s\n", __func__)) |
673 | 709 | ||
674 | #ifdef CONFIG_SCSI_IBMVFC_TRACE | 710 | #ifdef CONFIG_SCSI_IBMVFC_TRACE |
675 | #define ibmvfc_create_trace_file(kobj, attr) sysfs_create_bin_file(kobj, attr) | 711 | #define ibmvfc_create_trace_file(kobj, attr) sysfs_create_bin_file(kobj, attr) |
diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index 2e13ec00172a..2a5b29d12172 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c | |||
@@ -55,7 +55,7 @@ | |||
55 | /* tmp - will replace with SCSI logging stuff */ | 55 | /* tmp - will replace with SCSI logging stuff */ |
56 | #define eprintk(fmt, args...) \ | 56 | #define eprintk(fmt, args...) \ |
57 | do { \ | 57 | do { \ |
58 | printk("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \ | 58 | printk("%s(%d) " fmt, __func__, __LINE__, ##args); \ |
59 | } while (0) | 59 | } while (0) |
60 | /* #define dprintk eprintk */ | 60 | /* #define dprintk eprintk */ |
61 | #define dprintk(fmt, args...) | 61 | #define dprintk(fmt, args...) |
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index f97d172844be..c2a9a13d788f 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c | |||
@@ -163,7 +163,7 @@ static int imm_proc_info(struct Scsi_Host *host, char *buffer, char **start, | |||
163 | 163 | ||
164 | #if IMM_DEBUG > 0 | 164 | #if IMM_DEBUG > 0 |
165 | #define imm_fail(x,y) printk("imm: imm_fail(%i) from %s at line %d\n",\ | 165 | #define imm_fail(x,y) printk("imm: imm_fail(%i) from %s at line %d\n",\ |
166 | y, __FUNCTION__, __LINE__); imm_fail_func(x,y); | 166 | y, __func__, __LINE__); imm_fail_func(x,y); |
167 | static inline void | 167 | static inline void |
168 | imm_fail_func(imm_struct *dev, int error_code) | 168 | imm_fail_func(imm_struct *dev, int error_code) |
169 | #else | 169 | #else |
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index d93156671e93..4871dd1f2582 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h | |||
@@ -1403,10 +1403,10 @@ struct ipr_ucode_image_header { | |||
1403 | } | 1403 | } |
1404 | 1404 | ||
1405 | #define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\ | 1405 | #define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\ |
1406 | __FILE__, __FUNCTION__, __LINE__) | 1406 | __FILE__, __func__, __LINE__) |
1407 | 1407 | ||
1408 | #define ENTER IPR_DBG_CMD(printk(KERN_INFO IPR_NAME": Entering %s\n", __FUNCTION__)) | 1408 | #define ENTER IPR_DBG_CMD(printk(KERN_INFO IPR_NAME": Entering %s\n", __func__)) |
1409 | #define LEAVE IPR_DBG_CMD(printk(KERN_INFO IPR_NAME": Leaving %s\n", __FUNCTION__)) | 1409 | #define LEAVE IPR_DBG_CMD(printk(KERN_INFO IPR_NAME": Leaving %s\n", __func__)) |
1410 | 1410 | ||
1411 | #define ipr_err_separator \ | 1411 | #define ipr_err_separator \ |
1412 | ipr_err("----------------------------------------------------------\n") | 1412 | ipr_err("----------------------------------------------------------\n") |
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 744f06d04a36..48ee8c7f5bdd 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c | |||
@@ -74,7 +74,7 @@ static enum ata_completion_errors sas_to_ata_err(struct task_status_struct *ts) | |||
74 | case SAS_OPEN_TO: | 74 | case SAS_OPEN_TO: |
75 | case SAS_OPEN_REJECT: | 75 | case SAS_OPEN_REJECT: |
76 | SAS_DPRINTK("%s: Saw error %d. What to do?\n", | 76 | SAS_DPRINTK("%s: Saw error %d. What to do?\n", |
77 | __FUNCTION__, ts->stat); | 77 | __func__, ts->stat); |
78 | return AC_ERR_OTHER; | 78 | return AC_ERR_OTHER; |
79 | 79 | ||
80 | case SAS_ABORTED_TASK: | 80 | case SAS_ABORTED_TASK: |
@@ -115,7 +115,7 @@ static void sas_ata_task_done(struct sas_task *task) | |||
115 | } else if (stat->stat != SAM_STAT_GOOD) { | 115 | } else if (stat->stat != SAM_STAT_GOOD) { |
116 | ac = sas_to_ata_err(stat); | 116 | ac = sas_to_ata_err(stat); |
117 | if (ac) { | 117 | if (ac) { |
118 | SAS_DPRINTK("%s: SAS error %x\n", __FUNCTION__, | 118 | SAS_DPRINTK("%s: SAS error %x\n", __func__, |
119 | stat->stat); | 119 | stat->stat); |
120 | /* We saw a SAS error. Send a vague error. */ | 120 | /* We saw a SAS error. Send a vague error. */ |
121 | qc->err_mask = ac; | 121 | qc->err_mask = ac; |
@@ -244,20 +244,20 @@ static void sas_ata_phy_reset(struct ata_port *ap) | |||
244 | res = i->dft->lldd_I_T_nexus_reset(dev); | 244 | res = i->dft->lldd_I_T_nexus_reset(dev); |
245 | 245 | ||
246 | if (res != TMF_RESP_FUNC_COMPLETE) | 246 | if (res != TMF_RESP_FUNC_COMPLETE) |
247 | SAS_DPRINTK("%s: Unable to reset I T nexus?\n", __FUNCTION__); | 247 | SAS_DPRINTK("%s: Unable to reset I T nexus?\n", __func__); |
248 | 248 | ||
249 | switch (dev->sata_dev.command_set) { | 249 | switch (dev->sata_dev.command_set) { |
250 | case ATA_COMMAND_SET: | 250 | case ATA_COMMAND_SET: |
251 | SAS_DPRINTK("%s: Found ATA device.\n", __FUNCTION__); | 251 | SAS_DPRINTK("%s: Found ATA device.\n", __func__); |
252 | ap->link.device[0].class = ATA_DEV_ATA; | 252 | ap->link.device[0].class = ATA_DEV_ATA; |
253 | break; | 253 | break; |
254 | case ATAPI_COMMAND_SET: | 254 | case ATAPI_COMMAND_SET: |
255 | SAS_DPRINTK("%s: Found ATAPI device.\n", __FUNCTION__); | 255 | SAS_DPRINTK("%s: Found ATAPI device.\n", __func__); |
256 | ap->link.device[0].class = ATA_DEV_ATAPI; | 256 | ap->link.device[0].class = ATA_DEV_ATAPI; |
257 | break; | 257 | break; |
258 | default: | 258 | default: |
259 | SAS_DPRINTK("%s: Unknown SATA command set: %d.\n", | 259 | SAS_DPRINTK("%s: Unknown SATA command set: %d.\n", |
260 | __FUNCTION__, | 260 | __func__, |
261 | dev->sata_dev.command_set); | 261 | dev->sata_dev.command_set); |
262 | ap->link.device[0].class = ATA_DEV_UNKNOWN; | 262 | ap->link.device[0].class = ATA_DEV_UNKNOWN; |
263 | break; | 263 | break; |
@@ -299,7 +299,7 @@ static int sas_ata_scr_write(struct ata_port *ap, unsigned int sc_reg_in, | |||
299 | { | 299 | { |
300 | struct domain_device *dev = ap->private_data; | 300 | struct domain_device *dev = ap->private_data; |
301 | 301 | ||
302 | SAS_DPRINTK("STUB %s\n", __FUNCTION__); | 302 | SAS_DPRINTK("STUB %s\n", __func__); |
303 | switch (sc_reg_in) { | 303 | switch (sc_reg_in) { |
304 | case SCR_STATUS: | 304 | case SCR_STATUS: |
305 | dev->sata_dev.sstatus = val; | 305 | dev->sata_dev.sstatus = val; |
@@ -324,7 +324,7 @@ static int sas_ata_scr_read(struct ata_port *ap, unsigned int sc_reg_in, | |||
324 | { | 324 | { |
325 | struct domain_device *dev = ap->private_data; | 325 | struct domain_device *dev = ap->private_data; |
326 | 326 | ||
327 | SAS_DPRINTK("STUB %s\n", __FUNCTION__); | 327 | SAS_DPRINTK("STUB %s\n", __func__); |
328 | switch (sc_reg_in) { | 328 | switch (sc_reg_in) { |
329 | case SCR_STATUS: | 329 | case SCR_STATUS: |
330 | *val = dev->sata_dev.sstatus; | 330 | *val = dev->sata_dev.sstatus; |
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index aefd865a5788..3da02e436788 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c | |||
@@ -121,7 +121,7 @@ static int smp_execute_task(struct domain_device *dev, void *req, int req_size, | |||
121 | break; | 121 | break; |
122 | } else { | 122 | } else { |
123 | SAS_DPRINTK("%s: task to dev %016llx response: 0x%x " | 123 | SAS_DPRINTK("%s: task to dev %016llx response: 0x%x " |
124 | "status 0x%x\n", __FUNCTION__, | 124 | "status 0x%x\n", __func__, |
125 | SAS_ADDR(dev->sas_addr), | 125 | SAS_ADDR(dev->sas_addr), |
126 | task->task_status.resp, | 126 | task->task_status.resp, |
127 | task->task_status.stat); | 127 | task->task_status.stat); |
@@ -1279,7 +1279,7 @@ static int sas_configure_present(struct domain_device *dev, int phy_id, | |||
1279 | goto out; | 1279 | goto out; |
1280 | } else if (res != SMP_RESP_FUNC_ACC) { | 1280 | } else if (res != SMP_RESP_FUNC_ACC) { |
1281 | SAS_DPRINTK("%s: dev %016llx phy 0x%x index 0x%x " | 1281 | SAS_DPRINTK("%s: dev %016llx phy 0x%x index 0x%x " |
1282 | "result 0x%x\n", __FUNCTION__, | 1282 | "result 0x%x\n", __func__, |
1283 | SAS_ADDR(dev->sas_addr), phy_id, i, res); | 1283 | SAS_ADDR(dev->sas_addr), phy_id, i, res); |
1284 | goto out; | 1284 | goto out; |
1285 | } | 1285 | } |
@@ -1901,7 +1901,7 @@ int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, | |||
1901 | 1901 | ||
1902 | if (!rsp) { | 1902 | if (!rsp) { |
1903 | printk("%s: space for a smp response is missing\n", | 1903 | printk("%s: space for a smp response is missing\n", |
1904 | __FUNCTION__); | 1904 | __func__); |
1905 | return -EINVAL; | 1905 | return -EINVAL; |
1906 | } | 1906 | } |
1907 | 1907 | ||
@@ -1914,20 +1914,20 @@ int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, | |||
1914 | if (type != SAS_EDGE_EXPANDER_DEVICE && | 1914 | if (type != SAS_EDGE_EXPANDER_DEVICE && |
1915 | type != SAS_FANOUT_EXPANDER_DEVICE) { | 1915 | type != SAS_FANOUT_EXPANDER_DEVICE) { |
1916 | printk("%s: can we send a smp request to a device?\n", | 1916 | printk("%s: can we send a smp request to a device?\n", |
1917 | __FUNCTION__); | 1917 | __func__); |
1918 | return -EINVAL; | 1918 | return -EINVAL; |
1919 | } | 1919 | } |
1920 | 1920 | ||
1921 | dev = sas_find_dev_by_rphy(rphy); | 1921 | dev = sas_find_dev_by_rphy(rphy); |
1922 | if (!dev) { | 1922 | if (!dev) { |
1923 | printk("%s: fail to find a domain_device?\n", __FUNCTION__); | 1923 | printk("%s: fail to find a domain_device?\n", __func__); |
1924 | return -EINVAL; | 1924 | return -EINVAL; |
1925 | } | 1925 | } |
1926 | 1926 | ||
1927 | /* do we need to support multiple segments? */ | 1927 | /* do we need to support multiple segments? */ |
1928 | if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) { | 1928 | if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) { |
1929 | printk("%s: multiple segments req %u %u, rsp %u %u\n", | 1929 | printk("%s: multiple segments req %u %u, rsp %u %u\n", |
1930 | __FUNCTION__, req->bio->bi_vcnt, req->data_len, | 1930 | __func__, req->bio->bi_vcnt, req->data_len, |
1931 | rsp->bio->bi_vcnt, rsp->data_len); | 1931 | rsp->bio->bi_vcnt, rsp->data_len); |
1932 | return -EINVAL; | 1932 | return -EINVAL; |
1933 | } | 1933 | } |
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c index 39ae68a3b0ef..139935a121b4 100644 --- a/drivers/scsi/libsas/sas_port.c +++ b/drivers/scsi/libsas/sas_port.c | |||
@@ -50,7 +50,7 @@ static void sas_form_port(struct asd_sas_phy *phy) | |||
50 | sas_deform_port(phy); | 50 | sas_deform_port(phy); |
51 | else { | 51 | else { |
52 | SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n", | 52 | SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n", |
53 | __FUNCTION__, phy->id, phy->port->id, | 53 | __func__, phy->id, phy->port->id, |
54 | phy->port->num_phys); | 54 | phy->port->num_phys); |
55 | return; | 55 | return; |
56 | } | 56 | } |
@@ -78,7 +78,7 @@ static void sas_form_port(struct asd_sas_phy *phy) | |||
78 | 78 | ||
79 | if (i >= sas_ha->num_phys) { | 79 | if (i >= sas_ha->num_phys) { |
80 | printk(KERN_NOTICE "%s: couldn't find a free port, bug?\n", | 80 | printk(KERN_NOTICE "%s: couldn't find a free port, bug?\n", |
81 | __FUNCTION__); | 81 | __func__); |
82 | spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags); | 82 | spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags); |
83 | return; | 83 | return; |
84 | } | 84 | } |
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 601ec5b6a7f6..a8e3ef309070 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c | |||
@@ -343,7 +343,7 @@ static enum task_disposition sas_scsi_find_task(struct sas_task *task) | |||
343 | flags); | 343 | flags); |
344 | SAS_DPRINTK("%s: task 0x%p aborted from " | 344 | SAS_DPRINTK("%s: task 0x%p aborted from " |
345 | "task_queue\n", | 345 | "task_queue\n", |
346 | __FUNCTION__, task); | 346 | __func__, task); |
347 | return TASK_IS_ABORTED; | 347 | return TASK_IS_ABORTED; |
348 | } | 348 | } |
349 | } | 349 | } |
@@ -351,13 +351,13 @@ static enum task_disposition sas_scsi_find_task(struct sas_task *task) | |||
351 | } | 351 | } |
352 | 352 | ||
353 | for (i = 0; i < 5; i++) { | 353 | for (i = 0; i < 5; i++) { |
354 | SAS_DPRINTK("%s: aborting task 0x%p\n", __FUNCTION__, task); | 354 | SAS_DPRINTK("%s: aborting task 0x%p\n", __func__, task); |
355 | res = si->dft->lldd_abort_task(task); | 355 | res = si->dft->lldd_abort_task(task); |
356 | 356 | ||
357 | spin_lock_irqsave(&task->task_state_lock, flags); | 357 | spin_lock_irqsave(&task->task_state_lock, flags); |
358 | if (task->task_state_flags & SAS_TASK_STATE_DONE) { | 358 | if (task->task_state_flags & SAS_TASK_STATE_DONE) { |
359 | spin_unlock_irqrestore(&task->task_state_lock, flags); | 359 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
360 | SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__, | 360 | SAS_DPRINTK("%s: task 0x%p is done\n", __func__, |
361 | task); | 361 | task); |
362 | return TASK_IS_DONE; | 362 | return TASK_IS_DONE; |
363 | } | 363 | } |
@@ -365,24 +365,24 @@ static enum task_disposition sas_scsi_find_task(struct sas_task *task) | |||
365 | 365 | ||
366 | if (res == TMF_RESP_FUNC_COMPLETE) { | 366 | if (res == TMF_RESP_FUNC_COMPLETE) { |
367 | SAS_DPRINTK("%s: task 0x%p is aborted\n", | 367 | SAS_DPRINTK("%s: task 0x%p is aborted\n", |
368 | __FUNCTION__, task); | 368 | __func__, task); |
369 | return TASK_IS_ABORTED; | 369 | return TASK_IS_ABORTED; |
370 | } else if (si->dft->lldd_query_task) { | 370 | } else if (si->dft->lldd_query_task) { |
371 | SAS_DPRINTK("%s: querying task 0x%p\n", | 371 | SAS_DPRINTK("%s: querying task 0x%p\n", |
372 | __FUNCTION__, task); | 372 | __func__, task); |
373 | res = si->dft->lldd_query_task(task); | 373 | res = si->dft->lldd_query_task(task); |
374 | switch (res) { | 374 | switch (res) { |
375 | case TMF_RESP_FUNC_SUCC: | 375 | case TMF_RESP_FUNC_SUCC: |
376 | SAS_DPRINTK("%s: task 0x%p at LU\n", | 376 | SAS_DPRINTK("%s: task 0x%p at LU\n", |
377 | __FUNCTION__, task); | 377 | __func__, task); |
378 | return TASK_IS_AT_LU; | 378 | return TASK_IS_AT_LU; |
379 | case TMF_RESP_FUNC_COMPLETE: | 379 | case TMF_RESP_FUNC_COMPLETE: |
380 | SAS_DPRINTK("%s: task 0x%p not at LU\n", | 380 | SAS_DPRINTK("%s: task 0x%p not at LU\n", |
381 | __FUNCTION__, task); | 381 | __func__, task); |
382 | return TASK_IS_NOT_AT_LU; | 382 | return TASK_IS_NOT_AT_LU; |
383 | case TMF_RESP_FUNC_FAILED: | 383 | case TMF_RESP_FUNC_FAILED: |
384 | SAS_DPRINTK("%s: task 0x%p failed to abort\n", | 384 | SAS_DPRINTK("%s: task 0x%p failed to abort\n", |
385 | __FUNCTION__, task); | 385 | __func__, task); |
386 | return TASK_ABORT_FAILED; | 386 | return TASK_ABORT_FAILED; |
387 | } | 387 | } |
388 | 388 | ||
@@ -545,7 +545,7 @@ Again: | |||
545 | 545 | ||
546 | if (need_reset) { | 546 | if (need_reset) { |
547 | SAS_DPRINTK("%s: task 0x%p requests reset\n", | 547 | SAS_DPRINTK("%s: task 0x%p requests reset\n", |
548 | __FUNCTION__, task); | 548 | __func__, task); |
549 | goto reset; | 549 | goto reset; |
550 | } | 550 | } |
551 | 551 | ||
@@ -556,13 +556,13 @@ Again: | |||
556 | 556 | ||
557 | switch (res) { | 557 | switch (res) { |
558 | case TASK_IS_DONE: | 558 | case TASK_IS_DONE: |
559 | SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__, | 559 | SAS_DPRINTK("%s: task 0x%p is done\n", __func__, |
560 | task); | 560 | task); |
561 | sas_eh_finish_cmd(cmd); | 561 | sas_eh_finish_cmd(cmd); |
562 | continue; | 562 | continue; |
563 | case TASK_IS_ABORTED: | 563 | case TASK_IS_ABORTED: |
564 | SAS_DPRINTK("%s: task 0x%p is aborted\n", | 564 | SAS_DPRINTK("%s: task 0x%p is aborted\n", |
565 | __FUNCTION__, task); | 565 | __func__, task); |
566 | sas_eh_finish_cmd(cmd); | 566 | sas_eh_finish_cmd(cmd); |
567 | continue; | 567 | continue; |
568 | case TASK_IS_AT_LU: | 568 | case TASK_IS_AT_LU: |
@@ -633,7 +633,7 @@ Again: | |||
633 | } | 633 | } |
634 | return list_empty(work_q); | 634 | return list_empty(work_q); |
635 | clear_q: | 635 | clear_q: |
636 | SAS_DPRINTK("--- Exit %s -- clear_q\n", __FUNCTION__); | 636 | SAS_DPRINTK("--- Exit %s -- clear_q\n", __func__); |
637 | list_for_each_entry_safe(cmd, n, work_q, eh_entry) | 637 | list_for_each_entry_safe(cmd, n, work_q, eh_entry) |
638 | sas_eh_finish_cmd(cmd); | 638 | sas_eh_finish_cmd(cmd); |
639 | 639 | ||
@@ -650,7 +650,7 @@ void sas_scsi_recover_host(struct Scsi_Host *shost) | |||
650 | list_splice_init(&shost->eh_cmd_q, &eh_work_q); | 650 | list_splice_init(&shost->eh_cmd_q, &eh_work_q); |
651 | spin_unlock_irqrestore(shost->host_lock, flags); | 651 | spin_unlock_irqrestore(shost->host_lock, flags); |
652 | 652 | ||
653 | SAS_DPRINTK("Enter %s\n", __FUNCTION__); | 653 | SAS_DPRINTK("Enter %s\n", __func__); |
654 | /* | 654 | /* |
655 | * Deal with commands that still have SAS tasks (i.e. they didn't | 655 | * Deal with commands that still have SAS tasks (i.e. they didn't |
656 | * complete via the normal sas_task completion mechanism) | 656 | * complete via the normal sas_task completion mechanism) |
@@ -669,7 +669,7 @@ void sas_scsi_recover_host(struct Scsi_Host *shost) | |||
669 | 669 | ||
670 | out: | 670 | out: |
671 | scsi_eh_flush_done_q(&ha->eh_done_q); | 671 | scsi_eh_flush_done_q(&ha->eh_done_q); |
672 | SAS_DPRINTK("--- Exit %s\n", __FUNCTION__); | 672 | SAS_DPRINTK("--- Exit %s\n", __func__); |
673 | return; | 673 | return; |
674 | } | 674 | } |
675 | 675 | ||
@@ -990,7 +990,7 @@ int __sas_task_abort(struct sas_task *task) | |||
990 | if (task->task_state_flags & SAS_TASK_STATE_ABORTED || | 990 | if (task->task_state_flags & SAS_TASK_STATE_ABORTED || |
991 | task->task_state_flags & SAS_TASK_STATE_DONE) { | 991 | task->task_state_flags & SAS_TASK_STATE_DONE) { |
992 | spin_unlock_irqrestore(&task->task_state_lock, flags); | 992 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
993 | SAS_DPRINTK("%s: Task %p already finished.\n", __FUNCTION__, | 993 | SAS_DPRINTK("%s: Task %p already finished.\n", __func__, |
994 | task); | 994 | task); |
995 | return 0; | 995 | return 0; |
996 | } | 996 | } |
diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index 6d6a76e65a6c..15e2d132e8b9 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c | |||
@@ -39,7 +39,7 @@ enum srp_task_attributes { | |||
39 | /* tmp - will replace with SCSI logging stuff */ | 39 | /* tmp - will replace with SCSI logging stuff */ |
40 | #define eprintk(fmt, args...) \ | 40 | #define eprintk(fmt, args...) \ |
41 | do { \ | 41 | do { \ |
42 | printk("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \ | 42 | printk("%s(%d) " fmt, __func__, __LINE__, ##args); \ |
43 | } while (0) | 43 | } while (0) |
44 | /* #define dprintk eprintk */ | 44 | /* #define dprintk eprintk */ |
45 | #define dprintk(fmt, args...) | 45 | #define dprintk(fmt, args...) |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 5b6e5395c8eb..d51a2a4b43eb 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -2083,7 +2083,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
2083 | if (iocbq_entry == NULL) { | 2083 | if (iocbq_entry == NULL) { |
2084 | printk(KERN_ERR "%s: only allocated %d iocbs of " | 2084 | printk(KERN_ERR "%s: only allocated %d iocbs of " |
2085 | "expected %d count. Unloading driver.\n", | 2085 | "expected %d count. Unloading driver.\n", |
2086 | __FUNCTION__, i, LPFC_IOCB_LIST_CNT); | 2086 | __func__, i, LPFC_IOCB_LIST_CNT); |
2087 | error = -ENOMEM; | 2087 | error = -ENOMEM; |
2088 | goto out_free_iocbq; | 2088 | goto out_free_iocbq; |
2089 | } | 2089 | } |
@@ -2093,7 +2093,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
2093 | kfree (iocbq_entry); | 2093 | kfree (iocbq_entry); |
2094 | printk(KERN_ERR "%s: failed to allocate IOTAG. " | 2094 | printk(KERN_ERR "%s: failed to allocate IOTAG. " |
2095 | "Unloading driver.\n", | 2095 | "Unloading driver.\n", |
2096 | __FUNCTION__); | 2096 | __func__); |
2097 | error = -ENOMEM; | 2097 | error = -ENOMEM; |
2098 | goto out_free_iocbq; | 2098 | goto out_free_iocbq; |
2099 | } | 2099 | } |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index c94da4f2b8a6..1bcebbd3dfac 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -341,7 +341,7 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
341 | if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) { | 341 | if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) { |
342 | printk(KERN_ERR "%s: Too many sg segments from " | 342 | printk(KERN_ERR "%s: Too many sg segments from " |
343 | "dma_map_sg. Config %d, seg_cnt %d", | 343 | "dma_map_sg. Config %d, seg_cnt %d", |
344 | __FUNCTION__, phba->cfg_sg_seg_cnt, | 344 | __func__, phba->cfg_sg_seg_cnt, |
345 | lpfc_cmd->seg_cnt); | 345 | lpfc_cmd->seg_cnt); |
346 | scsi_dma_unmap(scsi_cmnd); | 346 | scsi_dma_unmap(scsi_cmnd); |
347 | return 1; | 347 | return 1; |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index f40aa7b905f7..50fe07646738 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -219,7 +219,7 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd) | |||
219 | case CMD_IOCB_LOGENTRY_CN: | 219 | case CMD_IOCB_LOGENTRY_CN: |
220 | case CMD_IOCB_LOGENTRY_ASYNC_CN: | 220 | case CMD_IOCB_LOGENTRY_ASYNC_CN: |
221 | printk("%s - Unhandled SLI-3 Command x%x\n", | 221 | printk("%s - Unhandled SLI-3 Command x%x\n", |
222 | __FUNCTION__, iocb_cmnd); | 222 | __func__, iocb_cmnd); |
223 | type = LPFC_UNKNOWN_IOCB; | 223 | type = LPFC_UNKNOWN_IOCB; |
224 | break; | 224 | break; |
225 | default: | 225 | default: |
@@ -1715,7 +1715,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba, | |||
1715 | rspiocbp = __lpfc_sli_get_iocbq(phba); | 1715 | rspiocbp = __lpfc_sli_get_iocbq(phba); |
1716 | if (rspiocbp == NULL) { | 1716 | if (rspiocbp == NULL) { |
1717 | printk(KERN_ERR "%s: out of buffers! Failing " | 1717 | printk(KERN_ERR "%s: out of buffers! Failing " |
1718 | "completion.\n", __FUNCTION__); | 1718 | "completion.\n", __func__); |
1719 | break; | 1719 | break; |
1720 | } | 1720 | } |
1721 | 1721 | ||
@@ -3793,7 +3793,7 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport, | |||
3793 | break; | 3793 | break; |
3794 | default: | 3794 | default: |
3795 | printk(KERN_ERR "%s: Unknown context cmd type, value %d\n", | 3795 | printk(KERN_ERR "%s: Unknown context cmd type, value %d\n", |
3796 | __FUNCTION__, ctx_cmd); | 3796 | __func__, ctx_cmd); |
3797 | break; | 3797 | break; |
3798 | } | 3798 | } |
3799 | 3799 | ||
diff --git a/drivers/scsi/megaraid/mega_common.h b/drivers/scsi/megaraid/mega_common.h index f62ed468ada0..5ead1283a844 100644 --- a/drivers/scsi/megaraid/mega_common.h +++ b/drivers/scsi/megaraid/mega_common.h | |||
@@ -265,7 +265,7 @@ typedef struct { | |||
265 | #define ASSERT(expression) \ | 265 | #define ASSERT(expression) \ |
266 | if (!(expression)) { \ | 266 | if (!(expression)) { \ |
267 | ASSERT_ACTION("assertion failed:(%s), file: %s, line: %d:%s\n", \ | 267 | ASSERT_ACTION("assertion failed:(%s), file: %s, line: %d:%s\n", \ |
268 | #expression, __FILE__, __LINE__, __FUNCTION__); \ | 268 | #expression, __FILE__, __LINE__, __func__); \ |
269 | } | 269 | } |
270 | #else | 270 | #else |
271 | #define ASSERT(expression) | 271 | #define ASSERT(expression) |
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index 70a0f11f48b2..805bb61dde18 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c | |||
@@ -458,7 +458,7 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
458 | 458 | ||
459 | if (adapter == NULL) { | 459 | if (adapter == NULL) { |
460 | con_log(CL_ANN, (KERN_WARNING | 460 | con_log(CL_ANN, (KERN_WARNING |
461 | "megaraid: out of memory, %s %d.\n", __FUNCTION__, __LINE__)); | 461 | "megaraid: out of memory, %s %d.\n", __func__, __LINE__)); |
462 | 462 | ||
463 | goto out_probe_one; | 463 | goto out_probe_one; |
464 | } | 464 | } |
@@ -1002,7 +1002,7 @@ megaraid_alloc_cmd_packets(adapter_t *adapter) | |||
1002 | 1002 | ||
1003 | if (!raid_dev->una_mbox64) { | 1003 | if (!raid_dev->una_mbox64) { |
1004 | con_log(CL_ANN, (KERN_WARNING | 1004 | con_log(CL_ANN, (KERN_WARNING |
1005 | "megaraid: out of memory, %s %d\n", __FUNCTION__, | 1005 | "megaraid: out of memory, %s %d\n", __func__, |
1006 | __LINE__)); | 1006 | __LINE__)); |
1007 | return -1; | 1007 | return -1; |
1008 | } | 1008 | } |
@@ -1030,7 +1030,7 @@ megaraid_alloc_cmd_packets(adapter_t *adapter) | |||
1030 | if (!adapter->ibuf) { | 1030 | if (!adapter->ibuf) { |
1031 | 1031 | ||
1032 | con_log(CL_ANN, (KERN_WARNING | 1032 | con_log(CL_ANN, (KERN_WARNING |
1033 | "megaraid: out of memory, %s %d\n", __FUNCTION__, | 1033 | "megaraid: out of memory, %s %d\n", __func__, |
1034 | __LINE__)); | 1034 | __LINE__)); |
1035 | 1035 | ||
1036 | goto out_free_common_mbox; | 1036 | goto out_free_common_mbox; |
@@ -1052,7 +1052,7 @@ megaraid_alloc_cmd_packets(adapter_t *adapter) | |||
1052 | 1052 | ||
1053 | if (adapter->kscb_list == NULL) { | 1053 | if (adapter->kscb_list == NULL) { |
1054 | con_log(CL_ANN, (KERN_WARNING | 1054 | con_log(CL_ANN, (KERN_WARNING |
1055 | "megaraid: out of memory, %s %d\n", __FUNCTION__, | 1055 | "megaraid: out of memory, %s %d\n", __func__, |
1056 | __LINE__)); | 1056 | __LINE__)); |
1057 | goto out_free_ibuf; | 1057 | goto out_free_ibuf; |
1058 | } | 1058 | } |
@@ -1060,7 +1060,7 @@ megaraid_alloc_cmd_packets(adapter_t *adapter) | |||
1060 | // memory allocation for our command packets | 1060 | // memory allocation for our command packets |
1061 | if (megaraid_mbox_setup_dma_pools(adapter) != 0) { | 1061 | if (megaraid_mbox_setup_dma_pools(adapter) != 0) { |
1062 | con_log(CL_ANN, (KERN_WARNING | 1062 | con_log(CL_ANN, (KERN_WARNING |
1063 | "megaraid: out of memory, %s %d\n", __FUNCTION__, | 1063 | "megaraid: out of memory, %s %d\n", __func__, |
1064 | __LINE__)); | 1064 | __LINE__)); |
1065 | goto out_free_scb_list; | 1065 | goto out_free_scb_list; |
1066 | } | 1066 | } |
@@ -2981,7 +2981,7 @@ megaraid_mbox_product_info(adapter_t *adapter) | |||
2981 | 2981 | ||
2982 | if (pinfo == NULL) { | 2982 | if (pinfo == NULL) { |
2983 | con_log(CL_ANN, (KERN_WARNING | 2983 | con_log(CL_ANN, (KERN_WARNING |
2984 | "megaraid: out of memory, %s %d\n", __FUNCTION__, | 2984 | "megaraid: out of memory, %s %d\n", __func__, |
2985 | __LINE__)); | 2985 | __LINE__)); |
2986 | 2986 | ||
2987 | return -1; | 2987 | return -1; |
@@ -3508,7 +3508,7 @@ megaraid_cmm_register(adapter_t *adapter) | |||
3508 | 3508 | ||
3509 | if (adapter->uscb_list == NULL) { | 3509 | if (adapter->uscb_list == NULL) { |
3510 | con_log(CL_ANN, (KERN_WARNING | 3510 | con_log(CL_ANN, (KERN_WARNING |
3511 | "megaraid: out of memory, %s %d\n", __FUNCTION__, | 3511 | "megaraid: out of memory, %s %d\n", __func__, |
3512 | __LINE__)); | 3512 | __LINE__)); |
3513 | return -1; | 3513 | return -1; |
3514 | } | 3514 | } |
@@ -3879,7 +3879,7 @@ megaraid_sysfs_alloc_resources(adapter_t *adapter) | |||
3879 | !raid_dev->sysfs_buffer) { | 3879 | !raid_dev->sysfs_buffer) { |
3880 | 3880 | ||
3881 | con_log(CL_ANN, (KERN_WARNING | 3881 | con_log(CL_ANN, (KERN_WARNING |
3882 | "megaraid: out of memory, %s %d\n", __FUNCTION__, | 3882 | "megaraid: out of memory, %s %d\n", __func__, |
3883 | __LINE__)); | 3883 | __LINE__)); |
3884 | 3884 | ||
3885 | rval = -ENOMEM; | 3885 | rval = -ENOMEM; |
diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index ac3b280c2a72..f680561d2c6f 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c | |||
@@ -929,7 +929,7 @@ mraid_mm_register_adp(mraid_mmadp_t *lld_adp) | |||
929 | !adapter->pthru_dma_pool) { | 929 | !adapter->pthru_dma_pool) { |
930 | 930 | ||
931 | con_log(CL_ANN, (KERN_WARNING | 931 | con_log(CL_ANN, (KERN_WARNING |
932 | "megaraid cmm: out of memory, %s %d\n", __FUNCTION__, | 932 | "megaraid cmm: out of memory, %s %d\n", __func__, |
933 | __LINE__)); | 933 | __LINE__)); |
934 | 934 | ||
935 | rval = (-ENOMEM); | 935 | rval = (-ENOMEM); |
@@ -957,7 +957,7 @@ mraid_mm_register_adp(mraid_mmadp_t *lld_adp) | |||
957 | 957 | ||
958 | con_log(CL_ANN, (KERN_WARNING | 958 | con_log(CL_ANN, (KERN_WARNING |
959 | "megaraid cmm: out of memory, %s %d\n", | 959 | "megaraid cmm: out of memory, %s %d\n", |
960 | __FUNCTION__, __LINE__)); | 960 | __func__, __LINE__)); |
961 | 961 | ||
962 | rval = (-ENOMEM); | 962 | rval = (-ENOMEM); |
963 | 963 | ||
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index 7fed35372150..edf9fdb3cb3c 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c | |||
@@ -299,9 +299,9 @@ static struct scsi_host_template nsp32_template = { | |||
299 | #else | 299 | #else |
300 | # define NSP32_DEBUG_MASK 0xffffff | 300 | # define NSP32_DEBUG_MASK 0xffffff |
301 | # define nsp32_msg(type, args...) \ | 301 | # define nsp32_msg(type, args...) \ |
302 | nsp32_message (__FUNCTION__, __LINE__, (type), args) | 302 | nsp32_message (__func__, __LINE__, (type), args) |
303 | # define nsp32_dbg(mask, args...) \ | 303 | # define nsp32_dbg(mask, args...) \ |
304 | nsp32_dmessage(__FUNCTION__, __LINE__, (mask), args) | 304 | nsp32_dmessage(__func__, __LINE__, (mask), args) |
305 | #endif | 305 | #endif |
306 | 306 | ||
307 | #define NSP32_DEBUG_QUEUECOMMAND BIT(0) | 307 | #define NSP32_DEBUG_QUEUECOMMAND BIT(0) |
diff --git a/drivers/scsi/nsp32_debug.c b/drivers/scsi/nsp32_debug.c index ef3c59cbcff6..2fb3fb58858d 100644 --- a/drivers/scsi/nsp32_debug.c +++ b/drivers/scsi/nsp32_debug.c | |||
@@ -88,7 +88,7 @@ static void print_commandk (unsigned char *command) | |||
88 | int i,s; | 88 | int i,s; |
89 | // printk(KERN_DEBUG); | 89 | // printk(KERN_DEBUG); |
90 | print_opcodek(command[0]); | 90 | print_opcodek(command[0]); |
91 | /*printk(KERN_DEBUG "%s ", __FUNCTION__);*/ | 91 | /*printk(KERN_DEBUG "%s ", __func__);*/ |
92 | if ((command[0] >> 5) == 6 || | 92 | if ((command[0] >> 5) == 6 || |
93 | (command[0] >> 5) == 7 ) { | 93 | (command[0] >> 5) == 7 ) { |
94 | s = 12; /* vender specific */ | 94 | s = 12; /* vender specific */ |
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 5082ca3c6876..a221b6ef9fa9 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c | |||
@@ -107,9 +107,9 @@ static nsp_hw_data nsp_data_base; /* attach <-> detect glue */ | |||
107 | #else | 107 | #else |
108 | # define NSP_DEBUG_MASK 0xffffff | 108 | # define NSP_DEBUG_MASK 0xffffff |
109 | # define nsp_msg(type, args...) \ | 109 | # define nsp_msg(type, args...) \ |
110 | nsp_cs_message (__FUNCTION__, __LINE__, (type), args) | 110 | nsp_cs_message (__func__, __LINE__, (type), args) |
111 | # define nsp_dbg(mask, args...) \ | 111 | # define nsp_dbg(mask, args...) \ |
112 | nsp_cs_dmessage(__FUNCTION__, __LINE__, (mask), args) | 112 | nsp_cs_dmessage(__func__, __LINE__, (mask), args) |
113 | #endif | 113 | #endif |
114 | 114 | ||
115 | #define NSP_DEBUG_QUEUECOMMAND BIT(0) | 115 | #define NSP_DEBUG_QUEUECOMMAND BIT(0) |
diff --git a/drivers/scsi/pcmcia/nsp_debug.c b/drivers/scsi/pcmcia/nsp_debug.c index 2f75fe6e35a7..3c6ef64fcbff 100644 --- a/drivers/scsi/pcmcia/nsp_debug.c +++ b/drivers/scsi/pcmcia/nsp_debug.c | |||
@@ -90,7 +90,7 @@ static void print_commandk (unsigned char *command) | |||
90 | int i, s; | 90 | int i, s; |
91 | printk(KERN_DEBUG); | 91 | printk(KERN_DEBUG); |
92 | print_opcodek(command[0]); | 92 | print_opcodek(command[0]); |
93 | /*printk(KERN_DEBUG "%s ", __FUNCTION__);*/ | 93 | /*printk(KERN_DEBUG "%s ", __func__);*/ |
94 | if ((command[0] >> 5) == 6 || | 94 | if ((command[0] >> 5) == 6 || |
95 | (command[0] >> 5) == 7 ) { | 95 | (command[0] >> 5) == 7 ) { |
96 | s = 12; /* vender specific */ | 96 | s = 12; /* vender specific */ |
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index f655ae320b48..8aa0bd987e29 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c | |||
@@ -171,7 +171,7 @@ static int device_check(ppa_struct *dev); | |||
171 | 171 | ||
172 | #if PPA_DEBUG > 0 | 172 | #if PPA_DEBUG > 0 |
173 | #define ppa_fail(x,y) printk("ppa: ppa_fail(%i) from %s at line %d\n",\ | 173 | #define ppa_fail(x,y) printk("ppa: ppa_fail(%i) from %s at line %d\n",\ |
174 | y, __FUNCTION__, __LINE__); ppa_fail_func(x,y); | 174 | y, __func__, __LINE__); ppa_fail_func(x,y); |
175 | static inline void ppa_fail_func(ppa_struct *dev, int error_code) | 175 | static inline void ppa_fail_func(ppa_struct *dev, int error_code) |
176 | #else | 176 | #else |
177 | static inline void ppa_fail(ppa_struct *dev, int error_code) | 177 | static inline void ppa_fail(ppa_struct *dev, int error_code) |
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 3754ab87f89a..37f9ba0cd798 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c | |||
@@ -1695,7 +1695,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) | |||
1695 | risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen; | 1695 | risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen; |
1696 | 1696 | ||
1697 | dprintk(1, "%s: DMA RISC code (%i) words\n", | 1697 | dprintk(1, "%s: DMA RISC code (%i) words\n", |
1698 | __FUNCTION__, risc_code_size); | 1698 | __func__, risc_code_size); |
1699 | 1699 | ||
1700 | num = 0; | 1700 | num = 0; |
1701 | while (risc_code_size > 0) { | 1701 | while (risc_code_size > 0) { |
@@ -1721,7 +1721,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) | |||
1721 | mb[7] = pci_dma_hi32(ha->request_dma) & 0xffff; | 1721 | mb[7] = pci_dma_hi32(ha->request_dma) & 0xffff; |
1722 | mb[6] = pci_dma_hi32(ha->request_dma) >> 16; | 1722 | mb[6] = pci_dma_hi32(ha->request_dma) >> 16; |
1723 | dprintk(2, "%s: op=%d 0x%p = 0x%4x,0x%4x,0x%4x,0x%4x\n", | 1723 | dprintk(2, "%s: op=%d 0x%p = 0x%4x,0x%4x,0x%4x,0x%4x\n", |
1724 | __FUNCTION__, mb[0], | 1724 | __func__, mb[0], |
1725 | (void *)(long)ha->request_dma, | 1725 | (void *)(long)ha->request_dma, |
1726 | mb[6], mb[7], mb[2], mb[3]); | 1726 | mb[6], mb[7], mb[2], mb[3]); |
1727 | err = qla1280_mailbox_command(ha, BIT_4 | BIT_3 | BIT_2 | | 1727 | err = qla1280_mailbox_command(ha, BIT_4 | BIT_3 | BIT_2 | |
@@ -1753,10 +1753,10 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) | |||
1753 | if (tbuf[i] != sp[i] && warn++ < 10) { | 1753 | if (tbuf[i] != sp[i] && warn++ < 10) { |
1754 | printk(KERN_ERR "%s: FW compare error @ " | 1754 | printk(KERN_ERR "%s: FW compare error @ " |
1755 | "byte(0x%x) loop#=%x\n", | 1755 | "byte(0x%x) loop#=%x\n", |
1756 | __FUNCTION__, i, num); | 1756 | __func__, i, num); |
1757 | printk(KERN_ERR "%s: FWbyte=%x " | 1757 | printk(KERN_ERR "%s: FWbyte=%x " |
1758 | "FWfromChip=%x\n", | 1758 | "FWfromChip=%x\n", |
1759 | __FUNCTION__, sp[i], tbuf[i]); | 1759 | __func__, sp[i], tbuf[i]); |
1760 | /*break; */ | 1760 | /*break; */ |
1761 | } | 1761 | } |
1762 | } | 1762 | } |
@@ -1781,7 +1781,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha) | |||
1781 | int err; | 1781 | int err; |
1782 | 1782 | ||
1783 | dprintk(1, "%s: Verifying checksum of loaded RISC code.\n", | 1783 | dprintk(1, "%s: Verifying checksum of loaded RISC code.\n", |
1784 | __FUNCTION__); | 1784 | __func__); |
1785 | 1785 | ||
1786 | /* Verify checksum of loaded RISC code. */ | 1786 | /* Verify checksum of loaded RISC code. */ |
1787 | mb[0] = MBC_VERIFY_CHECKSUM; | 1787 | mb[0] = MBC_VERIFY_CHECKSUM; |
@@ -1794,7 +1794,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha) | |||
1794 | } | 1794 | } |
1795 | 1795 | ||
1796 | /* Start firmware execution. */ | 1796 | /* Start firmware execution. */ |
1797 | dprintk(1, "%s: start firmware running.\n", __FUNCTION__); | 1797 | dprintk(1, "%s: start firmware running.\n", __func__); |
1798 | mb[0] = MBC_EXECUTE_FIRMWARE; | 1798 | mb[0] = MBC_EXECUTE_FIRMWARE; |
1799 | mb[1] = *ql1280_board_tbl[ha->devnum].fwstart; | 1799 | mb[1] = *ql1280_board_tbl[ha->devnum].fwstart; |
1800 | err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); | 1800 | err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 8dd88fc1244a..7a4409ab30ea 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -20,18 +20,12 @@ qla2x00_sysfs_read_fw_dump(struct kobject *kobj, | |||
20 | { | 20 | { |
21 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 21 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
22 | struct device, kobj))); | 22 | struct device, kobj))); |
23 | char *rbuf = (char *)ha->fw_dump; | ||
24 | 23 | ||
25 | if (ha->fw_dump_reading == 0) | 24 | if (ha->fw_dump_reading == 0) |
26 | return 0; | 25 | return 0; |
27 | if (off > ha->fw_dump_len) | ||
28 | return 0; | ||
29 | if (off + count > ha->fw_dump_len) | ||
30 | count = ha->fw_dump_len - off; | ||
31 | 26 | ||
32 | memcpy(buf, &rbuf[off], count); | 27 | return memory_read_from_buffer(buf, count, &off, ha->fw_dump, |
33 | 28 | ha->fw_dump_len); | |
34 | return (count); | ||
35 | } | 29 | } |
36 | 30 | ||
37 | static ssize_t | 31 | static ssize_t |
@@ -94,20 +88,13 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj, | |||
94 | { | 88 | { |
95 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 89 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
96 | struct device, kobj))); | 90 | struct device, kobj))); |
97 | int size = ha->nvram_size; | ||
98 | char *nvram_cache = ha->nvram; | ||
99 | 91 | ||
100 | if (!capable(CAP_SYS_ADMIN) || off > size || count == 0) | 92 | if (!capable(CAP_SYS_ADMIN)) |
101 | return 0; | 93 | return 0; |
102 | if (off + count > size) { | ||
103 | size -= off; | ||
104 | count = size; | ||
105 | } | ||
106 | 94 | ||
107 | /* Read NVRAM data from cache. */ | 95 | /* Read NVRAM data from cache. */ |
108 | memcpy(buf, &nvram_cache[off], count); | 96 | return memory_read_from_buffer(buf, count, &off, ha->nvram, |
109 | 97 | ha->nvram_size); | |
110 | return count; | ||
111 | } | 98 | } |
112 | 99 | ||
113 | static ssize_t | 100 | static ssize_t |
@@ -175,14 +162,9 @@ qla2x00_sysfs_read_optrom(struct kobject *kobj, | |||
175 | 162 | ||
176 | if (ha->optrom_state != QLA_SREADING) | 163 | if (ha->optrom_state != QLA_SREADING) |
177 | return 0; | 164 | return 0; |
178 | if (off > ha->optrom_region_size) | ||
179 | return 0; | ||
180 | if (off + count > ha->optrom_region_size) | ||
181 | count = ha->optrom_region_size - off; | ||
182 | |||
183 | memcpy(buf, &ha->optrom_buffer[off], count); | ||
184 | 165 | ||
185 | return count; | 166 | return memory_read_from_buffer(buf, count, &off, ha->optrom_buffer, |
167 | ha->optrom_region_size); | ||
186 | } | 168 | } |
187 | 169 | ||
188 | static ssize_t | 170 | static ssize_t |
@@ -374,20 +356,12 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, | |||
374 | { | 356 | { |
375 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 357 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
376 | struct device, kobj))); | 358 | struct device, kobj))); |
377 | int size = ha->vpd_size; | ||
378 | char *vpd_cache = ha->vpd; | ||
379 | 359 | ||
380 | if (!capable(CAP_SYS_ADMIN) || off > size || count == 0) | 360 | if (!capable(CAP_SYS_ADMIN)) |
381 | return 0; | 361 | return 0; |
382 | if (off + count > size) { | ||
383 | size -= off; | ||
384 | count = size; | ||
385 | } | ||
386 | 362 | ||
387 | /* Read NVRAM data from cache. */ | 363 | /* Read NVRAM data from cache. */ |
388 | memcpy(buf, &vpd_cache[off], count); | 364 | return memory_read_from_buffer(buf, count, &off, ha->vpd, ha->vpd_size); |
389 | |||
390 | return count; | ||
391 | } | 365 | } |
392 | 366 | ||
393 | static ssize_t | 367 | static ssize_t |
@@ -557,8 +531,10 @@ qla2x00_serial_num_show(struct device *dev, struct device_attribute *attr, | |||
557 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 531 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); |
558 | uint32_t sn; | 532 | uint32_t sn; |
559 | 533 | ||
560 | if (IS_FWI2_CAPABLE(ha)) | 534 | if (IS_FWI2_CAPABLE(ha)) { |
561 | return snprintf(buf, PAGE_SIZE, "\n"); | 535 | qla2xxx_get_vpd_field(ha, "SN", buf, PAGE_SIZE); |
536 | return snprintf(buf, PAGE_SIZE, "%s\n", buf); | ||
537 | } | ||
562 | 538 | ||
563 | sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; | 539 | sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; |
564 | return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000, | 540 | return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000, |
@@ -809,6 +785,16 @@ qla2x00_optrom_fw_version_show(struct device *dev, | |||
809 | ha->fw_revision[3]); | 785 | ha->fw_revision[3]); |
810 | } | 786 | } |
811 | 787 | ||
788 | static ssize_t | ||
789 | qla2x00_total_isp_aborts_show(struct device *dev, | ||
790 | struct device_attribute *attr, char *buf) | ||
791 | { | ||
792 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | ||
793 | |||
794 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
795 | ha->qla_stats.total_isp_aborts); | ||
796 | } | ||
797 | |||
812 | static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL); | 798 | static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL); |
813 | static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); | 799 | static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); |
814 | static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL); | 800 | static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL); |
@@ -831,6 +817,8 @@ static DEVICE_ATTR(optrom_fcode_version, S_IRUGO, | |||
831 | qla2x00_optrom_fcode_version_show, NULL); | 817 | qla2x00_optrom_fcode_version_show, NULL); |
832 | static DEVICE_ATTR(optrom_fw_version, S_IRUGO, qla2x00_optrom_fw_version_show, | 818 | static DEVICE_ATTR(optrom_fw_version, S_IRUGO, qla2x00_optrom_fw_version_show, |
833 | NULL); | 819 | NULL); |
820 | static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show, | ||
821 | NULL); | ||
834 | 822 | ||
835 | struct device_attribute *qla2x00_host_attrs[] = { | 823 | struct device_attribute *qla2x00_host_attrs[] = { |
836 | &dev_attr_driver_version, | 824 | &dev_attr_driver_version, |
@@ -849,6 +837,7 @@ struct device_attribute *qla2x00_host_attrs[] = { | |||
849 | &dev_attr_optrom_efi_version, | 837 | &dev_attr_optrom_efi_version, |
850 | &dev_attr_optrom_fcode_version, | 838 | &dev_attr_optrom_fcode_version, |
851 | &dev_attr_optrom_fw_version, | 839 | &dev_attr_optrom_fw_version, |
840 | &dev_attr_total_isp_aborts, | ||
852 | NULL, | 841 | NULL, |
853 | }; | 842 | }; |
854 | 843 | ||
@@ -972,26 +961,39 @@ qla2x00_get_starget_port_id(struct scsi_target *starget) | |||
972 | } | 961 | } |
973 | 962 | ||
974 | static void | 963 | static void |
975 | qla2x00_get_rport_loss_tmo(struct fc_rport *rport) | 964 | qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) |
976 | { | 965 | { |
977 | struct Scsi_Host *host = rport_to_shost(rport); | 966 | if (timeout) |
978 | scsi_qla_host_t *ha = shost_priv(host); | 967 | rport->dev_loss_tmo = timeout; |
979 | 968 | else | |
980 | rport->dev_loss_tmo = ha->port_down_retry_count + 5; | 969 | rport->dev_loss_tmo = 1; |
981 | } | 970 | } |
982 | 971 | ||
983 | static void | 972 | static void |
984 | qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) | 973 | qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) |
985 | { | 974 | { |
986 | struct Scsi_Host *host = rport_to_shost(rport); | 975 | struct Scsi_Host *host = rport_to_shost(rport); |
987 | scsi_qla_host_t *ha = shost_priv(host); | 976 | fc_port_t *fcport = *(fc_port_t **)rport->dd_data; |
977 | |||
978 | qla2x00_abort_fcport_cmds(fcport); | ||
979 | |||
980 | /* | ||
981 | * Transport has effectively 'deleted' the rport, clear | ||
982 | * all local references. | ||
983 | */ | ||
984 | spin_lock_irq(host->host_lock); | ||
985 | fcport->rport = NULL; | ||
986 | *((fc_port_t **)rport->dd_data) = NULL; | ||
987 | spin_unlock_irq(host->host_lock); | ||
988 | } | ||
988 | 989 | ||
989 | if (timeout) | 990 | static void |
990 | ha->port_down_retry_count = timeout; | 991 | qla2x00_terminate_rport_io(struct fc_rport *rport) |
991 | else | 992 | { |
992 | ha->port_down_retry_count = 1; | 993 | fc_port_t *fcport = *(fc_port_t **)rport->dd_data; |
993 | 994 | ||
994 | rport->dev_loss_tmo = ha->port_down_retry_count + 5; | 995 | qla2x00_abort_fcport_cmds(fcport); |
996 | scsi_target_unblock(&rport->dev); | ||
995 | } | 997 | } |
996 | 998 | ||
997 | static int | 999 | static int |
@@ -1045,6 +1047,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) | |||
1045 | pfc_host_stat->invalid_tx_word_count = stats->inval_xmit_word_cnt; | 1047 | pfc_host_stat->invalid_tx_word_count = stats->inval_xmit_word_cnt; |
1046 | pfc_host_stat->invalid_crc_count = stats->inval_crc_cnt; | 1048 | pfc_host_stat->invalid_crc_count = stats->inval_crc_cnt; |
1047 | if (IS_FWI2_CAPABLE(ha)) { | 1049 | if (IS_FWI2_CAPABLE(ha)) { |
1050 | pfc_host_stat->lip_count = stats->lip_cnt; | ||
1048 | pfc_host_stat->tx_frames = stats->tx_frames; | 1051 | pfc_host_stat->tx_frames = stats->tx_frames; |
1049 | pfc_host_stat->rx_frames = stats->rx_frames; | 1052 | pfc_host_stat->rx_frames = stats->rx_frames; |
1050 | pfc_host_stat->dumped_frames = stats->dumped_frames; | 1053 | pfc_host_stat->dumped_frames = stats->dumped_frames; |
@@ -1173,17 +1176,16 @@ vport_create_failed_2: | |||
1173 | static int | 1176 | static int |
1174 | qla24xx_vport_delete(struct fc_vport *fc_vport) | 1177 | qla24xx_vport_delete(struct fc_vport *fc_vport) |
1175 | { | 1178 | { |
1176 | scsi_qla_host_t *ha = shost_priv(fc_vport->shost); | ||
1177 | scsi_qla_host_t *vha = fc_vport->dd_data; | 1179 | scsi_qla_host_t *vha = fc_vport->dd_data; |
1180 | scsi_qla_host_t *pha = to_qla_parent(vha); | ||
1181 | |||
1182 | while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) || | ||
1183 | test_bit(FCPORT_UPDATE_NEEDED, &pha->dpc_flags)) | ||
1184 | msleep(1000); | ||
1178 | 1185 | ||
1179 | qla24xx_disable_vp(vha); | 1186 | qla24xx_disable_vp(vha); |
1180 | qla24xx_deallocate_vp_id(vha); | 1187 | qla24xx_deallocate_vp_id(vha); |
1181 | 1188 | ||
1182 | mutex_lock(&ha->vport_lock); | ||
1183 | ha->cur_vport_count--; | ||
1184 | clear_bit(vha->vp_idx, ha->vp_idx_map); | ||
1185 | mutex_unlock(&ha->vport_lock); | ||
1186 | |||
1187 | kfree(vha->node_name); | 1189 | kfree(vha->node_name); |
1188 | kfree(vha->port_name); | 1190 | kfree(vha->port_name); |
1189 | 1191 | ||
@@ -1248,11 +1250,12 @@ struct fc_function_template qla2xxx_transport_functions = { | |||
1248 | .get_starget_port_id = qla2x00_get_starget_port_id, | 1250 | .get_starget_port_id = qla2x00_get_starget_port_id, |
1249 | .show_starget_port_id = 1, | 1251 | .show_starget_port_id = 1, |
1250 | 1252 | ||
1251 | .get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo, | ||
1252 | .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo, | 1253 | .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo, |
1253 | .show_rport_dev_loss_tmo = 1, | 1254 | .show_rport_dev_loss_tmo = 1, |
1254 | 1255 | ||
1255 | .issue_fc_host_lip = qla2x00_issue_lip, | 1256 | .issue_fc_host_lip = qla2x00_issue_lip, |
1257 | .dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk, | ||
1258 | .terminate_rport_io = qla2x00_terminate_rport_io, | ||
1256 | .get_fc_host_stats = qla2x00_get_fc_host_stats, | 1259 | .get_fc_host_stats = qla2x00_get_fc_host_stats, |
1257 | 1260 | ||
1258 | .vport_create = qla24xx_vport_create, | 1261 | .vport_create = qla24xx_vport_create, |
@@ -1291,11 +1294,12 @@ struct fc_function_template qla2xxx_transport_vport_functions = { | |||
1291 | .get_starget_port_id = qla2x00_get_starget_port_id, | 1294 | .get_starget_port_id = qla2x00_get_starget_port_id, |
1292 | .show_starget_port_id = 1, | 1295 | .show_starget_port_id = 1, |
1293 | 1296 | ||
1294 | .get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo, | ||
1295 | .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo, | 1297 | .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo, |
1296 | .show_rport_dev_loss_tmo = 1, | 1298 | .show_rport_dev_loss_tmo = 1, |
1297 | 1299 | ||
1298 | .issue_fc_host_lip = qla2x00_issue_lip, | 1300 | .issue_fc_host_lip = qla2x00_issue_lip, |
1301 | .dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk, | ||
1302 | .terminate_rport_io = qla2x00_terminate_rport_io, | ||
1299 | .get_fc_host_stats = qla2x00_get_fc_host_stats, | 1303 | .get_fc_host_stats = qla2x00_get_fc_host_stats, |
1300 | }; | 1304 | }; |
1301 | 1305 | ||
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index cbef785765cf..510ba64bc286 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -216,7 +216,7 @@ qla24xx_soft_reset(scsi_qla_host_t *ha) | |||
216 | 216 | ||
217 | static int | 217 | static int |
218 | qla2xxx_dump_ram(scsi_qla_host_t *ha, uint32_t addr, uint16_t *ram, | 218 | qla2xxx_dump_ram(scsi_qla_host_t *ha, uint32_t addr, uint16_t *ram, |
219 | uint16_t ram_words, void **nxt) | 219 | uint32_t ram_words, void **nxt) |
220 | { | 220 | { |
221 | int rval; | 221 | int rval; |
222 | uint32_t cnt, stat, timer, words, idx; | 222 | uint32_t cnt, stat, timer, words, idx; |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 8dd600013bd1..6da31ba94404 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -864,7 +864,8 @@ struct link_statistics { | |||
864 | uint32_t prim_seq_err_cnt; | 864 | uint32_t prim_seq_err_cnt; |
865 | uint32_t inval_xmit_word_cnt; | 865 | uint32_t inval_xmit_word_cnt; |
866 | uint32_t inval_crc_cnt; | 866 | uint32_t inval_crc_cnt; |
867 | uint32_t unused1[0x1b]; | 867 | uint32_t lip_cnt; |
868 | uint32_t unused1[0x1a]; | ||
868 | uint32_t tx_frames; | 869 | uint32_t tx_frames; |
869 | uint32_t rx_frames; | 870 | uint32_t rx_frames; |
870 | uint32_t dumped_frames; | 871 | uint32_t dumped_frames; |
@@ -1544,7 +1545,6 @@ typedef struct fc_port { | |||
1544 | int login_retry; | 1545 | int login_retry; |
1545 | atomic_t port_down_timer; | 1546 | atomic_t port_down_timer; |
1546 | 1547 | ||
1547 | spinlock_t rport_lock; | ||
1548 | struct fc_rport *rport, *drport; | 1548 | struct fc_rport *rport, *drport; |
1549 | u32 supported_classes; | 1549 | u32 supported_classes; |
1550 | 1550 | ||
@@ -2155,6 +2155,10 @@ struct qla_chip_state_84xx { | |||
2155 | uint32_t gold_fw_version; | 2155 | uint32_t gold_fw_version; |
2156 | }; | 2156 | }; |
2157 | 2157 | ||
2158 | struct qla_statistics { | ||
2159 | uint32_t total_isp_aborts; | ||
2160 | }; | ||
2161 | |||
2158 | /* | 2162 | /* |
2159 | * Linux Host Adapter structure | 2163 | * Linux Host Adapter structure |
2160 | */ | 2164 | */ |
@@ -2166,7 +2170,6 @@ typedef struct scsi_qla_host { | |||
2166 | struct pci_dev *pdev; | 2170 | struct pci_dev *pdev; |
2167 | 2171 | ||
2168 | unsigned long host_no; | 2172 | unsigned long host_no; |
2169 | unsigned long instance; | ||
2170 | 2173 | ||
2171 | volatile struct { | 2174 | volatile struct { |
2172 | uint32_t init_done :1; | 2175 | uint32_t init_done :1; |
@@ -2515,7 +2518,7 @@ typedef struct scsi_qla_host { | |||
2515 | 2518 | ||
2516 | uint8_t model_number[16+1]; | 2519 | uint8_t model_number[16+1]; |
2517 | #define BINZERO "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | 2520 | #define BINZERO "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" |
2518 | char *model_desc; | 2521 | char model_desc[80]; |
2519 | uint8_t adapter_id[16+1]; | 2522 | uint8_t adapter_id[16+1]; |
2520 | 2523 | ||
2521 | uint8_t *node_name; | 2524 | uint8_t *node_name; |
@@ -2596,6 +2599,7 @@ typedef struct scsi_qla_host { | |||
2596 | int cur_vport_count; | 2599 | int cur_vport_count; |
2597 | 2600 | ||
2598 | struct qla_chip_state_84xx *cs84xx; | 2601 | struct qla_chip_state_84xx *cs84xx; |
2602 | struct qla_statistics qla_stats; | ||
2599 | } scsi_qla_host_t; | 2603 | } scsi_qla_host_t; |
2600 | 2604 | ||
2601 | 2605 | ||
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 9b4bebee6879..0b156735e9a6 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -62,7 +62,7 @@ extern int ql2xfdmienable; | |||
62 | extern int ql2xallocfwdump; | 62 | extern int ql2xallocfwdump; |
63 | extern int ql2xextended_error_logging; | 63 | extern int ql2xextended_error_logging; |
64 | extern int ql2xqfullrampup; | 64 | extern int ql2xqfullrampup; |
65 | extern int num_hosts; | 65 | extern int ql2xiidmaenable; |
66 | 66 | ||
67 | extern int qla2x00_loop_reset(scsi_qla_host_t *); | 67 | extern int qla2x00_loop_reset(scsi_qla_host_t *); |
68 | extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); | 68 | extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); |
@@ -71,6 +71,8 @@ extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum | |||
71 | extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t, | 71 | extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t, |
72 | uint16_t, uint16_t); | 72 | uint16_t, uint16_t); |
73 | 73 | ||
74 | extern void qla2x00_abort_fcport_cmds(fc_port_t *); | ||
75 | |||
74 | /* | 76 | /* |
75 | * Global Functions in qla_mid.c source file. | 77 | * Global Functions in qla_mid.c source file. |
76 | */ | 78 | */ |
@@ -312,6 +314,7 @@ extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t, | |||
312 | uint16_t, uint16_t); | 314 | uint16_t, uint16_t); |
313 | 315 | ||
314 | extern void qla2xxx_get_flash_info(scsi_qla_host_t *); | 316 | extern void qla2xxx_get_flash_info(scsi_qla_host_t *); |
317 | extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t); | ||
315 | 318 | ||
316 | /* | 319 | /* |
317 | * Global Function Prototypes in qla_dbg.c source file. | 320 | * Global Function Prototypes in qla_dbg.c source file. |
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 4cb80b476c85..c2a4bfbcb05b 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c | |||
@@ -1661,6 +1661,12 @@ qla2x00_fdmi_register(scsi_qla_host_t *ha) | |||
1661 | { | 1661 | { |
1662 | int rval; | 1662 | int rval; |
1663 | 1663 | ||
1664 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { | ||
1665 | DEBUG2(printk("scsi(%ld): FDMI unsupported on " | ||
1666 | "ISP2100/ISP2200.\n", ha->host_no)); | ||
1667 | return QLA_SUCCESS; | ||
1668 | } | ||
1669 | |||
1664 | rval = qla2x00_mgmt_svr_login(ha); | 1670 | rval = qla2x00_mgmt_svr_login(ha); |
1665 | if (rval) | 1671 | if (rval) |
1666 | return rval; | 1672 | return rval; |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index bbbc5a632a1d..601a6b29750c 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -334,6 +334,8 @@ static int | |||
334 | qla2x00_isp_firmware(scsi_qla_host_t *ha) | 334 | qla2x00_isp_firmware(scsi_qla_host_t *ha) |
335 | { | 335 | { |
336 | int rval; | 336 | int rval; |
337 | uint16_t loop_id, topo, sw_cap; | ||
338 | uint8_t domain, area, al_pa; | ||
337 | 339 | ||
338 | /* Assume loading risc code */ | 340 | /* Assume loading risc code */ |
339 | rval = QLA_FUNCTION_FAILED; | 341 | rval = QLA_FUNCTION_FAILED; |
@@ -345,6 +347,11 @@ qla2x00_isp_firmware(scsi_qla_host_t *ha) | |||
345 | 347 | ||
346 | /* Verify checksum of loaded RISC code. */ | 348 | /* Verify checksum of loaded RISC code. */ |
347 | rval = qla2x00_verify_checksum(ha, ha->fw_srisc_address); | 349 | rval = qla2x00_verify_checksum(ha, ha->fw_srisc_address); |
350 | if (rval == QLA_SUCCESS) { | ||
351 | /* And, verify we are not in ROM code. */ | ||
352 | rval = qla2x00_get_adapter_id(ha, &loop_id, &al_pa, | ||
353 | &area, &domain, &topo, &sw_cap); | ||
354 | } | ||
348 | } | 355 | } |
349 | 356 | ||
350 | if (rval) { | 357 | if (rval) { |
@@ -722,7 +729,7 @@ qla24xx_chip_diag(scsi_qla_host_t *ha) | |||
722 | /* Perform RISC reset. */ | 729 | /* Perform RISC reset. */ |
723 | qla24xx_reset_risc(ha); | 730 | qla24xx_reset_risc(ha); |
724 | 731 | ||
725 | ha->fw_transfer_size = REQUEST_ENTRY_SIZE * 1024; | 732 | ha->fw_transfer_size = REQUEST_ENTRY_SIZE * ha->request_q_length; |
726 | 733 | ||
727 | rval = qla2x00_mbx_reg_test(ha); | 734 | rval = qla2x00_mbx_reg_test(ha); |
728 | if (rval) { | 735 | if (rval) { |
@@ -768,42 +775,16 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) | |||
768 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * | 775 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * |
769 | sizeof(uint32_t); | 776 | sizeof(uint32_t); |
770 | 777 | ||
771 | /* Allocate memory for Extended Trace Buffer. */ | ||
772 | tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma, | ||
773 | GFP_KERNEL); | ||
774 | if (!tc) { | ||
775 | qla_printk(KERN_WARNING, ha, "Unable to allocate " | ||
776 | "(%d KB) for EFT.\n", EFT_SIZE / 1024); | ||
777 | goto cont_alloc; | ||
778 | } | ||
779 | |||
780 | memset(tc, 0, EFT_SIZE); | ||
781 | rval = qla2x00_enable_eft_trace(ha, tc_dma, EFT_NUM_BUFFERS); | ||
782 | if (rval) { | ||
783 | qla_printk(KERN_WARNING, ha, "Unable to initialize " | ||
784 | "EFT (%d).\n", rval); | ||
785 | dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, | ||
786 | tc_dma); | ||
787 | goto cont_alloc; | ||
788 | } | ||
789 | |||
790 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for EFT...\n", | ||
791 | EFT_SIZE / 1024); | ||
792 | |||
793 | eft_size = EFT_SIZE; | ||
794 | ha->eft_dma = tc_dma; | ||
795 | ha->eft = tc; | ||
796 | |||
797 | /* Allocate memory for Fibre Channel Event Buffer. */ | 778 | /* Allocate memory for Fibre Channel Event Buffer. */ |
798 | if (!IS_QLA25XX(ha)) | 779 | if (!IS_QLA25XX(ha)) |
799 | goto cont_alloc; | 780 | goto try_eft; |
800 | 781 | ||
801 | tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma, | 782 | tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma, |
802 | GFP_KERNEL); | 783 | GFP_KERNEL); |
803 | if (!tc) { | 784 | if (!tc) { |
804 | qla_printk(KERN_WARNING, ha, "Unable to allocate " | 785 | qla_printk(KERN_WARNING, ha, "Unable to allocate " |
805 | "(%d KB) for FCE.\n", FCE_SIZE / 1024); | 786 | "(%d KB) for FCE.\n", FCE_SIZE / 1024); |
806 | goto cont_alloc; | 787 | goto try_eft; |
807 | } | 788 | } |
808 | 789 | ||
809 | memset(tc, 0, FCE_SIZE); | 790 | memset(tc, 0, FCE_SIZE); |
@@ -815,7 +796,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) | |||
815 | dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, | 796 | dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, |
816 | tc_dma); | 797 | tc_dma); |
817 | ha->flags.fce_enabled = 0; | 798 | ha->flags.fce_enabled = 0; |
818 | goto cont_alloc; | 799 | goto try_eft; |
819 | } | 800 | } |
820 | 801 | ||
821 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for FCE...\n", | 802 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for FCE...\n", |
@@ -825,6 +806,32 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) | |||
825 | ha->flags.fce_enabled = 1; | 806 | ha->flags.fce_enabled = 1; |
826 | ha->fce_dma = tc_dma; | 807 | ha->fce_dma = tc_dma; |
827 | ha->fce = tc; | 808 | ha->fce = tc; |
809 | try_eft: | ||
810 | /* Allocate memory for Extended Trace Buffer. */ | ||
811 | tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma, | ||
812 | GFP_KERNEL); | ||
813 | if (!tc) { | ||
814 | qla_printk(KERN_WARNING, ha, "Unable to allocate " | ||
815 | "(%d KB) for EFT.\n", EFT_SIZE / 1024); | ||
816 | goto cont_alloc; | ||
817 | } | ||
818 | |||
819 | memset(tc, 0, EFT_SIZE); | ||
820 | rval = qla2x00_enable_eft_trace(ha, tc_dma, EFT_NUM_BUFFERS); | ||
821 | if (rval) { | ||
822 | qla_printk(KERN_WARNING, ha, "Unable to initialize " | ||
823 | "EFT (%d).\n", rval); | ||
824 | dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, | ||
825 | tc_dma); | ||
826 | goto cont_alloc; | ||
827 | } | ||
828 | |||
829 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for EFT...\n", | ||
830 | EFT_SIZE / 1024); | ||
831 | |||
832 | eft_size = EFT_SIZE; | ||
833 | ha->eft_dma = tc_dma; | ||
834 | ha->eft = tc; | ||
828 | } | 835 | } |
829 | cont_alloc: | 836 | cont_alloc: |
830 | req_q_size = ha->request_q_length * sizeof(request_t); | 837 | req_q_size = ha->request_q_length * sizeof(request_t); |
@@ -1501,18 +1508,25 @@ qla2x00_set_model_info(scsi_qla_host_t *ha, uint8_t *model, size_t len, char *de | |||
1501 | index = (ha->pdev->subsystem_device & 0xff); | 1508 | index = (ha->pdev->subsystem_device & 0xff); |
1502 | if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && | 1509 | if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && |
1503 | index < QLA_MODEL_NAMES) | 1510 | index < QLA_MODEL_NAMES) |
1504 | ha->model_desc = qla2x00_model_name[index * 2 + 1]; | 1511 | strncpy(ha->model_desc, |
1512 | qla2x00_model_name[index * 2 + 1], | ||
1513 | sizeof(ha->model_desc) - 1); | ||
1505 | } else { | 1514 | } else { |
1506 | index = (ha->pdev->subsystem_device & 0xff); | 1515 | index = (ha->pdev->subsystem_device & 0xff); |
1507 | if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && | 1516 | if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && |
1508 | index < QLA_MODEL_NAMES) { | 1517 | index < QLA_MODEL_NAMES) { |
1509 | strcpy(ha->model_number, | 1518 | strcpy(ha->model_number, |
1510 | qla2x00_model_name[index * 2]); | 1519 | qla2x00_model_name[index * 2]); |
1511 | ha->model_desc = qla2x00_model_name[index * 2 + 1]; | 1520 | strncpy(ha->model_desc, |
1521 | qla2x00_model_name[index * 2 + 1], | ||
1522 | sizeof(ha->model_desc) - 1); | ||
1512 | } else { | 1523 | } else { |
1513 | strcpy(ha->model_number, def); | 1524 | strcpy(ha->model_number, def); |
1514 | } | 1525 | } |
1515 | } | 1526 | } |
1527 | if (IS_FWI2_CAPABLE(ha)) | ||
1528 | qla2xxx_get_vpd_field(ha, "\x82", ha->model_desc, | ||
1529 | sizeof(ha->model_desc)); | ||
1516 | } | 1530 | } |
1517 | 1531 | ||
1518 | /* On sparc systems, obtain port and node WWN from firmware | 1532 | /* On sparc systems, obtain port and node WWN from firmware |
@@ -1864,12 +1878,11 @@ qla2x00_rport_del(void *data) | |||
1864 | { | 1878 | { |
1865 | fc_port_t *fcport = data; | 1879 | fc_port_t *fcport = data; |
1866 | struct fc_rport *rport; | 1880 | struct fc_rport *rport; |
1867 | unsigned long flags; | ||
1868 | 1881 | ||
1869 | spin_lock_irqsave(&fcport->rport_lock, flags); | 1882 | spin_lock_irq(fcport->ha->host->host_lock); |
1870 | rport = fcport->drport; | 1883 | rport = fcport->drport; |
1871 | fcport->drport = NULL; | 1884 | fcport->drport = NULL; |
1872 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | 1885 | spin_unlock_irq(fcport->ha->host->host_lock); |
1873 | if (rport) | 1886 | if (rport) |
1874 | fc_remote_port_delete(rport); | 1887 | fc_remote_port_delete(rport); |
1875 | } | 1888 | } |
@@ -1898,7 +1911,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) | |||
1898 | atomic_set(&fcport->state, FCS_UNCONFIGURED); | 1911 | atomic_set(&fcport->state, FCS_UNCONFIGURED); |
1899 | fcport->flags = FCF_RLC_SUPPORT; | 1912 | fcport->flags = FCF_RLC_SUPPORT; |
1900 | fcport->supported_classes = FC_COS_UNSPECIFIED; | 1913 | fcport->supported_classes = FC_COS_UNSPECIFIED; |
1901 | spin_lock_init(&fcport->rport_lock); | ||
1902 | 1914 | ||
1903 | return fcport; | 1915 | return fcport; |
1904 | } | 1916 | } |
@@ -2007,8 +2019,10 @@ qla2x00_configure_loop(scsi_qla_host_t *ha) | |||
2007 | if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) { | 2019 | if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) { |
2008 | if (test_bit(LOCAL_LOOP_UPDATE, &save_flags)) | 2020 | if (test_bit(LOCAL_LOOP_UPDATE, &save_flags)) |
2009 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); | 2021 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); |
2010 | if (test_bit(RSCN_UPDATE, &save_flags)) | 2022 | if (test_bit(RSCN_UPDATE, &save_flags)) { |
2023 | ha->flags.rscn_queue_overflow = 1; | ||
2011 | set_bit(RSCN_UPDATE, &ha->dpc_flags); | 2024 | set_bit(RSCN_UPDATE, &ha->dpc_flags); |
2025 | } | ||
2012 | } | 2026 | } |
2013 | 2027 | ||
2014 | return (rval); | 2028 | return (rval); |
@@ -2243,28 +2257,24 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport) | |||
2243 | { | 2257 | { |
2244 | struct fc_rport_identifiers rport_ids; | 2258 | struct fc_rport_identifiers rport_ids; |
2245 | struct fc_rport *rport; | 2259 | struct fc_rport *rport; |
2246 | unsigned long flags; | ||
2247 | 2260 | ||
2248 | if (fcport->drport) | 2261 | if (fcport->drport) |
2249 | qla2x00_rport_del(fcport); | 2262 | qla2x00_rport_del(fcport); |
2250 | if (fcport->rport) | ||
2251 | return; | ||
2252 | 2263 | ||
2253 | rport_ids.node_name = wwn_to_u64(fcport->node_name); | 2264 | rport_ids.node_name = wwn_to_u64(fcport->node_name); |
2254 | rport_ids.port_name = wwn_to_u64(fcport->port_name); | 2265 | rport_ids.port_name = wwn_to_u64(fcport->port_name); |
2255 | rport_ids.port_id = fcport->d_id.b.domain << 16 | | 2266 | rport_ids.port_id = fcport->d_id.b.domain << 16 | |
2256 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; | 2267 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; |
2257 | rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; | 2268 | rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; |
2258 | rport = fc_remote_port_add(ha->host, 0, &rport_ids); | 2269 | fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids); |
2259 | if (!rport) { | 2270 | if (!rport) { |
2260 | qla_printk(KERN_WARNING, ha, | 2271 | qla_printk(KERN_WARNING, ha, |
2261 | "Unable to allocate fc remote port!\n"); | 2272 | "Unable to allocate fc remote port!\n"); |
2262 | return; | 2273 | return; |
2263 | } | 2274 | } |
2264 | spin_lock_irqsave(&fcport->rport_lock, flags); | 2275 | spin_lock_irq(fcport->ha->host->host_lock); |
2265 | fcport->rport = rport; | ||
2266 | *((fc_port_t **)rport->dd_data) = fcport; | 2276 | *((fc_port_t **)rport->dd_data) = fcport; |
2267 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | 2277 | spin_unlock_irq(fcport->ha->host->host_lock); |
2268 | 2278 | ||
2269 | rport->supported_classes = fcport->supported_classes; | 2279 | rport->supported_classes = fcport->supported_classes; |
2270 | 2280 | ||
@@ -2565,7 +2575,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) | |||
2565 | } else if (qla2x00_gnn_id(ha, swl) != QLA_SUCCESS) { | 2575 | } else if (qla2x00_gnn_id(ha, swl) != QLA_SUCCESS) { |
2566 | kfree(swl); | 2576 | kfree(swl); |
2567 | swl = NULL; | 2577 | swl = NULL; |
2568 | } else if (qla2x00_gfpn_id(ha, swl) == QLA_SUCCESS) { | 2578 | } else if (ql2xiidmaenable && |
2579 | qla2x00_gfpn_id(ha, swl) == QLA_SUCCESS) { | ||
2569 | qla2x00_gpsc(ha, swl); | 2580 | qla2x00_gpsc(ha, swl); |
2570 | } | 2581 | } |
2571 | } | 2582 | } |
@@ -3220,7 +3231,8 @@ qla2x00_update_fcports(scsi_qla_host_t *ha) | |||
3220 | 3231 | ||
3221 | /* Go with deferred removal of rport references. */ | 3232 | /* Go with deferred removal of rport references. */ |
3222 | list_for_each_entry(fcport, &ha->fcports, list) | 3233 | list_for_each_entry(fcport, &ha->fcports, list) |
3223 | if (fcport->drport) | 3234 | if (fcport->drport && |
3235 | atomic_read(&fcport->state) != FCS_UNCONFIGURED) | ||
3224 | qla2x00_rport_del(fcport); | 3236 | qla2x00_rport_del(fcport); |
3225 | } | 3237 | } |
3226 | 3238 | ||
@@ -3243,6 +3255,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3243 | if (ha->flags.online) { | 3255 | if (ha->flags.online) { |
3244 | ha->flags.online = 0; | 3256 | ha->flags.online = 0; |
3245 | clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 3257 | clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
3258 | ha->qla_stats.total_isp_aborts++; | ||
3246 | 3259 | ||
3247 | qla_printk(KERN_INFO, ha, | 3260 | qla_printk(KERN_INFO, ha, |
3248 | "Performing ISP error recovery - ha= %p.\n", ha); | 3261 | "Performing ISP error recovery - ha= %p.\n", ha); |
@@ -3283,17 +3296,6 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3283 | ha->isp_abort_cnt = 0; | 3296 | ha->isp_abort_cnt = 0; |
3284 | clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags); | 3297 | clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags); |
3285 | 3298 | ||
3286 | if (ha->eft) { | ||
3287 | memset(ha->eft, 0, EFT_SIZE); | ||
3288 | rval = qla2x00_enable_eft_trace(ha, | ||
3289 | ha->eft_dma, EFT_NUM_BUFFERS); | ||
3290 | if (rval) { | ||
3291 | qla_printk(KERN_WARNING, ha, | ||
3292 | "Unable to reinitialize EFT " | ||
3293 | "(%d).\n", rval); | ||
3294 | } | ||
3295 | } | ||
3296 | |||
3297 | if (ha->fce) { | 3299 | if (ha->fce) { |
3298 | ha->flags.fce_enabled = 1; | 3300 | ha->flags.fce_enabled = 1; |
3299 | memset(ha->fce, 0, | 3301 | memset(ha->fce, 0, |
@@ -3308,6 +3310,17 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3308 | ha->flags.fce_enabled = 0; | 3310 | ha->flags.fce_enabled = 0; |
3309 | } | 3311 | } |
3310 | } | 3312 | } |
3313 | |||
3314 | if (ha->eft) { | ||
3315 | memset(ha->eft, 0, EFT_SIZE); | ||
3316 | rval = qla2x00_enable_eft_trace(ha, | ||
3317 | ha->eft_dma, EFT_NUM_BUFFERS); | ||
3318 | if (rval) { | ||
3319 | qla_printk(KERN_WARNING, ha, | ||
3320 | "Unable to reinitialize EFT " | ||
3321 | "(%d).\n", rval); | ||
3322 | } | ||
3323 | } | ||
3311 | } else { /* failed the ISP abort */ | 3324 | } else { /* failed the ISP abort */ |
3312 | ha->flags.online = 1; | 3325 | ha->flags.online = 1; |
3313 | if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) { | 3326 | if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) { |
@@ -4026,8 +4039,8 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha) | |||
4026 | ret = qla2x00_stop_firmware(ha); | 4039 | ret = qla2x00_stop_firmware(ha); |
4027 | for (retries = 5; ret != QLA_SUCCESS && ret != QLA_FUNCTION_TIMEOUT && | 4040 | for (retries = 5; ret != QLA_SUCCESS && ret != QLA_FUNCTION_TIMEOUT && |
4028 | retries ; retries--) { | 4041 | retries ; retries--) { |
4029 | qla2x00_reset_chip(ha); | 4042 | ha->isp_ops->reset_chip(ha); |
4030 | if (qla2x00_chip_diag(ha) != QLA_SUCCESS) | 4043 | if (ha->isp_ops->chip_diag(ha) != QLA_SUCCESS) |
4031 | continue; | 4044 | continue; |
4032 | if (qla2x00_setup_chip(ha) != QLA_SUCCESS) | 4045 | if (qla2x00_setup_chip(ha) != QLA_SUCCESS) |
4033 | continue; | 4046 | continue; |
@@ -4049,7 +4062,7 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha) | |||
4049 | rval = qla2x00_fw_ready(ha->parent); | 4062 | rval = qla2x00_fw_ready(ha->parent); |
4050 | if (rval == QLA_SUCCESS) { | 4063 | if (rval == QLA_SUCCESS) { |
4051 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | 4064 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); |
4052 | qla2x00_marker(ha->parent, 0, 0, MK_SYNC_ALL); | 4065 | qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); |
4053 | } | 4066 | } |
4054 | 4067 | ||
4055 | ha->flags.management_server_logged_in = 0; | 4068 | ha->flags.management_server_logged_in = 0; |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 5489d5024673..d57669aa4615 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -454,10 +454,11 @@ qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun, | |||
454 | { | 454 | { |
455 | int ret; | 455 | int ret; |
456 | unsigned long flags = 0; | 456 | unsigned long flags = 0; |
457 | scsi_qla_host_t *pha = to_qla_parent(ha); | ||
457 | 458 | ||
458 | spin_lock_irqsave(&ha->hardware_lock, flags); | 459 | spin_lock_irqsave(&pha->hardware_lock, flags); |
459 | ret = __qla2x00_marker(ha, loop_id, lun, type); | 460 | ret = __qla2x00_marker(ha, loop_id, lun, type); |
460 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 461 | spin_unlock_irqrestore(&pha->hardware_lock, flags); |
461 | 462 | ||
462 | return (ret); | 463 | return (ret); |
463 | } | 464 | } |
@@ -672,7 +673,7 @@ qla24xx_start_scsi(srb_t *sp) | |||
672 | { | 673 | { |
673 | int ret, nseg; | 674 | int ret, nseg; |
674 | unsigned long flags; | 675 | unsigned long flags; |
675 | scsi_qla_host_t *ha; | 676 | scsi_qla_host_t *ha, *pha; |
676 | struct scsi_cmnd *cmd; | 677 | struct scsi_cmnd *cmd; |
677 | uint32_t *clr_ptr; | 678 | uint32_t *clr_ptr; |
678 | uint32_t index; | 679 | uint32_t index; |
@@ -686,6 +687,7 @@ qla24xx_start_scsi(srb_t *sp) | |||
686 | /* Setup device pointers. */ | 687 | /* Setup device pointers. */ |
687 | ret = 0; | 688 | ret = 0; |
688 | ha = sp->ha; | 689 | ha = sp->ha; |
690 | pha = to_qla_parent(ha); | ||
689 | reg = &ha->iobase->isp24; | 691 | reg = &ha->iobase->isp24; |
690 | cmd = sp->cmd; | 692 | cmd = sp->cmd; |
691 | /* So we know we haven't pci_map'ed anything yet */ | 693 | /* So we know we haven't pci_map'ed anything yet */ |
@@ -700,7 +702,7 @@ qla24xx_start_scsi(srb_t *sp) | |||
700 | } | 702 | } |
701 | 703 | ||
702 | /* Acquire ring specific lock */ | 704 | /* Acquire ring specific lock */ |
703 | spin_lock_irqsave(&ha->hardware_lock, flags); | 705 | spin_lock_irqsave(&pha->hardware_lock, flags); |
704 | 706 | ||
705 | /* Check for room in outstanding command list. */ | 707 | /* Check for room in outstanding command list. */ |
706 | handle = ha->current_outstanding_cmd; | 708 | handle = ha->current_outstanding_cmd; |
@@ -795,14 +797,14 @@ qla24xx_start_scsi(srb_t *sp) | |||
795 | ha->response_ring_ptr->signature != RESPONSE_PROCESSED) | 797 | ha->response_ring_ptr->signature != RESPONSE_PROCESSED) |
796 | qla24xx_process_response_queue(ha); | 798 | qla24xx_process_response_queue(ha); |
797 | 799 | ||
798 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 800 | spin_unlock_irqrestore(&pha->hardware_lock, flags); |
799 | return QLA_SUCCESS; | 801 | return QLA_SUCCESS; |
800 | 802 | ||
801 | queuing_error: | 803 | queuing_error: |
802 | if (tot_dsds) | 804 | if (tot_dsds) |
803 | scsi_dma_unmap(cmd); | 805 | scsi_dma_unmap(cmd); |
804 | 806 | ||
805 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 807 | spin_unlock_irqrestore(&pha->hardware_lock, flags); |
806 | 808 | ||
807 | return QLA_FUNCTION_FAILED; | 809 | return QLA_FUNCTION_FAILED; |
808 | } | 810 | } |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index ec63b79f900a..874d802edb7d 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -542,10 +542,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
542 | break; | 542 | break; |
543 | 543 | ||
544 | case MBA_PORT_UPDATE: /* Port database update */ | 544 | case MBA_PORT_UPDATE: /* Port database update */ |
545 | /* Only handle SCNs for our Vport index. */ | ||
546 | if (ha->parent && ha->vp_idx != (mb[3] & 0xff)) | ||
547 | break; | ||
548 | |||
549 | /* | 545 | /* |
550 | * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET | 546 | * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET |
551 | * event etc. earlier indicating loop is down) then process | 547 | * event etc. earlier indicating loop is down) then process |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 250d2f604397..bc90d6b8d0a0 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -918,6 +918,8 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa, | |||
918 | rval = qla2x00_mailbox_command(ha, mcp); | 918 | rval = qla2x00_mailbox_command(ha, mcp); |
919 | if (mcp->mb[0] == MBS_COMMAND_ERROR) | 919 | if (mcp->mb[0] == MBS_COMMAND_ERROR) |
920 | rval = QLA_COMMAND_ERROR; | 920 | rval = QLA_COMMAND_ERROR; |
921 | else if (mcp->mb[0] == MBS_INVALID_COMMAND) | ||
922 | rval = QLA_INVALID_COMMAND; | ||
921 | 923 | ||
922 | /* Return data. */ | 924 | /* Return data. */ |
923 | *id = mcp->mb[1]; | 925 | *id = mcp->mb[1]; |
@@ -2161,17 +2163,18 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
2161 | struct abort_entry_24xx *abt; | 2163 | struct abort_entry_24xx *abt; |
2162 | dma_addr_t abt_dma; | 2164 | dma_addr_t abt_dma; |
2163 | uint32_t handle; | 2165 | uint32_t handle; |
2166 | scsi_qla_host_t *pha = to_qla_parent(ha); | ||
2164 | 2167 | ||
2165 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | 2168 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
2166 | 2169 | ||
2167 | fcport = sp->fcport; | 2170 | fcport = sp->fcport; |
2168 | 2171 | ||
2169 | spin_lock_irqsave(&ha->hardware_lock, flags); | 2172 | spin_lock_irqsave(&pha->hardware_lock, flags); |
2170 | for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) { | 2173 | for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) { |
2171 | if (ha->outstanding_cmds[handle] == sp) | 2174 | if (pha->outstanding_cmds[handle] == sp) |
2172 | break; | 2175 | break; |
2173 | } | 2176 | } |
2174 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 2177 | spin_unlock_irqrestore(&pha->hardware_lock, flags); |
2175 | if (handle == MAX_OUTSTANDING_COMMANDS) { | 2178 | if (handle == MAX_OUTSTANDING_COMMANDS) { |
2176 | /* Command not found. */ | 2179 | /* Command not found. */ |
2177 | return QLA_FUNCTION_FAILED; | 2180 | return QLA_FUNCTION_FAILED; |
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 62a3ad6e8ecb..50baf6a1d67c 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -43,6 +43,7 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha) | |||
43 | 43 | ||
44 | set_bit(vp_id, ha->vp_idx_map); | 44 | set_bit(vp_id, ha->vp_idx_map); |
45 | ha->num_vhosts++; | 45 | ha->num_vhosts++; |
46 | ha->cur_vport_count++; | ||
46 | vha->vp_idx = vp_id; | 47 | vha->vp_idx = vp_id; |
47 | list_add_tail(&vha->vp_list, &ha->vp_list); | 48 | list_add_tail(&vha->vp_list, &ha->vp_list); |
48 | mutex_unlock(&ha->vport_lock); | 49 | mutex_unlock(&ha->vport_lock); |
@@ -58,6 +59,7 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha) | |||
58 | mutex_lock(&ha->vport_lock); | 59 | mutex_lock(&ha->vport_lock); |
59 | vp_id = vha->vp_idx; | 60 | vp_id = vha->vp_idx; |
60 | ha->num_vhosts--; | 61 | ha->num_vhosts--; |
62 | ha->cur_vport_count--; | ||
61 | clear_bit(vp_id, ha->vp_idx_map); | 63 | clear_bit(vp_id, ha->vp_idx_map); |
62 | list_del(&vha->vp_list); | 64 | list_del(&vha->vp_list); |
63 | mutex_unlock(&ha->vport_lock); | 65 | mutex_unlock(&ha->vport_lock); |
@@ -103,8 +105,8 @@ qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha) | |||
103 | "loop_id=0x%04x :%x\n", | 105 | "loop_id=0x%04x :%x\n", |
104 | vha->host_no, fcport->loop_id, fcport->vp_idx)); | 106 | vha->host_no, fcport->loop_id, fcport->vp_idx)); |
105 | 107 | ||
106 | atomic_set(&fcport->state, FCS_DEVICE_DEAD); | ||
107 | qla2x00_mark_device_lost(vha, fcport, 0, 0); | 108 | qla2x00_mark_device_lost(vha, fcport, 0, 0); |
109 | atomic_set(&fcport->state, FCS_UNCONFIGURED); | ||
108 | } | 110 | } |
109 | } | 111 | } |
110 | 112 | ||
@@ -276,7 +278,8 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha) | |||
276 | clear_bit(RESET_ACTIVE, &vha->dpc_flags); | 278 | clear_bit(RESET_ACTIVE, &vha->dpc_flags); |
277 | } | 279 | } |
278 | 280 | ||
279 | if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) { | 281 | if (atomic_read(&vha->vp_state) == VP_ACTIVE && |
282 | test_and_clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) { | ||
280 | if (!(test_and_set_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags))) { | 283 | if (!(test_and_set_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags))) { |
281 | qla2x00_loop_resync(vha); | 284 | qla2x00_loop_resync(vha); |
282 | clear_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags); | 285 | clear_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags); |
@@ -390,7 +393,6 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) | |||
390 | vha->parent = ha; | 393 | vha->parent = ha; |
391 | vha->fc_vport = fc_vport; | 394 | vha->fc_vport = fc_vport; |
392 | vha->device_flags = 0; | 395 | vha->device_flags = 0; |
393 | vha->instance = num_hosts; | ||
394 | vha->vp_idx = qla24xx_allocate_vp_id(vha); | 396 | vha->vp_idx = qla24xx_allocate_vp_id(vha); |
395 | if (vha->vp_idx > ha->max_npiv_vports) { | 397 | if (vha->vp_idx > ha->max_npiv_vports) { |
396 | DEBUG15(printk("scsi(%ld): Couldn't allocate vp_id.\n", | 398 | DEBUG15(printk("scsi(%ld): Couldn't allocate vp_id.\n", |
@@ -428,7 +430,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) | |||
428 | host->max_cmd_len = MAX_CMDSZ; | 430 | host->max_cmd_len = MAX_CMDSZ; |
429 | host->max_channel = MAX_BUSES - 1; | 431 | host->max_channel = MAX_BUSES - 1; |
430 | host->max_lun = MAX_LUNS; | 432 | host->max_lun = MAX_LUNS; |
431 | host->unique_id = vha->instance; | 433 | host->unique_id = host->host_no; |
432 | host->max_id = MAX_TARGETS_2200; | 434 | host->max_id = MAX_TARGETS_2200; |
433 | host->transportt = qla2xxx_transport_vport_template; | 435 | host->transportt = qla2xxx_transport_vport_template; |
434 | 436 | ||
@@ -436,12 +438,6 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) | |||
436 | vha->host_no, vha)); | 438 | vha->host_no, vha)); |
437 | 439 | ||
438 | vha->flags.init_done = 1; | 440 | vha->flags.init_done = 1; |
439 | num_hosts++; | ||
440 | |||
441 | mutex_lock(&ha->vport_lock); | ||
442 | set_bit(vha->vp_idx, ha->vp_idx_map); | ||
443 | ha->cur_vport_count++; | ||
444 | mutex_unlock(&ha->vport_lock); | ||
445 | 441 | ||
446 | return vha; | 442 | return vha; |
447 | 443 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 48eaa3bb5433..7c8af7ed2a5d 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -27,7 +27,6 @@ char qla2x00_version_str[40]; | |||
27 | */ | 27 | */ |
28 | static struct kmem_cache *srb_cachep; | 28 | static struct kmem_cache *srb_cachep; |
29 | 29 | ||
30 | int num_hosts; | ||
31 | int ql2xlogintimeout = 20; | 30 | int ql2xlogintimeout = 20; |
32 | module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR); | 31 | module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR); |
33 | MODULE_PARM_DESC(ql2xlogintimeout, | 32 | MODULE_PARM_DESC(ql2xlogintimeout, |
@@ -87,6 +86,13 @@ MODULE_PARM_DESC(ql2xqfullrampup, | |||
87 | "depth for a device after a queue-full condition has been " | 86 | "depth for a device after a queue-full condition has been " |
88 | "detected. Default is 120 seconds."); | 87 | "detected. Default is 120 seconds."); |
89 | 88 | ||
89 | int ql2xiidmaenable=1; | ||
90 | module_param(ql2xiidmaenable, int, S_IRUGO|S_IRUSR); | ||
91 | MODULE_PARM_DESC(ql2xiidmaenable, | ||
92 | "Enables iIDMA settings " | ||
93 | "Default is 1 - perform iIDMA. 0 - no iIDMA."); | ||
94 | |||
95 | |||
90 | /* | 96 | /* |
91 | * SCSI host template entry points | 97 | * SCSI host template entry points |
92 | */ | 98 | */ |
@@ -388,7 +394,7 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
388 | } | 394 | } |
389 | 395 | ||
390 | /* Close window on fcport/rport state-transitioning. */ | 396 | /* Close window on fcport/rport state-transitioning. */ |
391 | if (!*(fc_port_t **)rport->dd_data) { | 397 | if (fcport->drport) { |
392 | cmd->result = DID_IMM_RETRY << 16; | 398 | cmd->result = DID_IMM_RETRY << 16; |
393 | goto qc_fail_command; | 399 | goto qc_fail_command; |
394 | } | 400 | } |
@@ -443,7 +449,7 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
443 | int rval; | 449 | int rval; |
444 | scsi_qla_host_t *pha = to_qla_parent(ha); | 450 | scsi_qla_host_t *pha = to_qla_parent(ha); |
445 | 451 | ||
446 | if (unlikely(pci_channel_offline(ha->pdev))) { | 452 | if (unlikely(pci_channel_offline(pha->pdev))) { |
447 | cmd->result = DID_REQUEUE << 16; | 453 | cmd->result = DID_REQUEUE << 16; |
448 | goto qc24_fail_command; | 454 | goto qc24_fail_command; |
449 | } | 455 | } |
@@ -455,7 +461,7 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
455 | } | 461 | } |
456 | 462 | ||
457 | /* Close window on fcport/rport state-transitioning. */ | 463 | /* Close window on fcport/rport state-transitioning. */ |
458 | if (!*(fc_port_t **)rport->dd_data) { | 464 | if (fcport->drport) { |
459 | cmd->result = DID_IMM_RETRY << 16; | 465 | cmd->result = DID_IMM_RETRY << 16; |
460 | goto qc24_fail_command; | 466 | goto qc24_fail_command; |
461 | } | 467 | } |
@@ -617,6 +623,40 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha) | |||
617 | return (return_status); | 623 | return (return_status); |
618 | } | 624 | } |
619 | 625 | ||
626 | void | ||
627 | qla2x00_abort_fcport_cmds(fc_port_t *fcport) | ||
628 | { | ||
629 | int cnt; | ||
630 | unsigned long flags; | ||
631 | srb_t *sp; | ||
632 | scsi_qla_host_t *ha = fcport->ha; | ||
633 | scsi_qla_host_t *pha = to_qla_parent(ha); | ||
634 | |||
635 | spin_lock_irqsave(&pha->hardware_lock, flags); | ||
636 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | ||
637 | sp = pha->outstanding_cmds[cnt]; | ||
638 | if (!sp) | ||
639 | continue; | ||
640 | if (sp->fcport != fcport) | ||
641 | continue; | ||
642 | |||
643 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | ||
644 | if (ha->isp_ops->abort_command(ha, sp)) { | ||
645 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
646 | "Abort failed -- %lx\n", sp->cmd->serial_number)); | ||
647 | } else { | ||
648 | if (qla2x00_eh_wait_on_command(ha, sp->cmd) != | ||
649 | QLA_SUCCESS) | ||
650 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
651 | "Abort failed while waiting -- %lx\n", | ||
652 | sp->cmd->serial_number)); | ||
653 | |||
654 | } | ||
655 | spin_lock_irqsave(&pha->hardware_lock, flags); | ||
656 | } | ||
657 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | ||
658 | } | ||
659 | |||
620 | static void | 660 | static void |
621 | qla2x00_block_error_handler(struct scsi_cmnd *cmnd) | 661 | qla2x00_block_error_handler(struct scsi_cmnd *cmnd) |
622 | { | 662 | { |
@@ -1073,7 +1113,7 @@ qla2xxx_slave_configure(struct scsi_device *sdev) | |||
1073 | else | 1113 | else |
1074 | scsi_deactivate_tcq(sdev, ha->max_q_depth); | 1114 | scsi_deactivate_tcq(sdev, ha->max_q_depth); |
1075 | 1115 | ||
1076 | rport->dev_loss_tmo = ha->port_down_retry_count + 5; | 1116 | rport->dev_loss_tmo = ha->port_down_retry_count; |
1077 | 1117 | ||
1078 | return 0; | 1118 | return 0; |
1079 | } | 1119 | } |
@@ -1629,9 +1669,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1629 | } | 1669 | } |
1630 | host->can_queue = ha->request_q_length + 128; | 1670 | host->can_queue = ha->request_q_length + 128; |
1631 | 1671 | ||
1632 | /* load the F/W, read paramaters, and init the H/W */ | ||
1633 | ha->instance = num_hosts; | ||
1634 | |||
1635 | mutex_init(&ha->vport_lock); | 1672 | mutex_init(&ha->vport_lock); |
1636 | init_completion(&ha->mbx_cmd_comp); | 1673 | init_completion(&ha->mbx_cmd_comp); |
1637 | complete(&ha->mbx_cmd_comp); | 1674 | complete(&ha->mbx_cmd_comp); |
@@ -1679,7 +1716,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1679 | 1716 | ||
1680 | host->this_id = 255; | 1717 | host->this_id = 255; |
1681 | host->cmd_per_lun = 3; | 1718 | host->cmd_per_lun = 3; |
1682 | host->unique_id = ha->instance; | 1719 | host->unique_id = host->host_no; |
1683 | host->max_cmd_len = MAX_CMDSZ; | 1720 | host->max_cmd_len = MAX_CMDSZ; |
1684 | host->max_channel = MAX_BUSES - 1; | 1721 | host->max_channel = MAX_BUSES - 1; |
1685 | host->max_lun = MAX_LUNS; | 1722 | host->max_lun = MAX_LUNS; |
@@ -1700,8 +1737,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1700 | ha->flags.init_done = 1; | 1737 | ha->flags.init_done = 1; |
1701 | ha->flags.online = 1; | 1738 | ha->flags.online = 1; |
1702 | 1739 | ||
1703 | num_hosts++; | ||
1704 | |||
1705 | ret = scsi_add_host(host, &pdev->dev); | 1740 | ret = scsi_add_host(host, &pdev->dev); |
1706 | if (ret) | 1741 | if (ret) |
1707 | goto probe_failed; | 1742 | goto probe_failed; |
@@ -1813,27 +1848,21 @@ static inline void | |||
1813 | qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport, | 1848 | qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport, |
1814 | int defer) | 1849 | int defer) |
1815 | { | 1850 | { |
1816 | unsigned long flags; | ||
1817 | struct fc_rport *rport; | 1851 | struct fc_rport *rport; |
1852 | scsi_qla_host_t *pha = to_qla_parent(ha); | ||
1818 | 1853 | ||
1819 | if (!fcport->rport) | 1854 | if (!fcport->rport) |
1820 | return; | 1855 | return; |
1821 | 1856 | ||
1822 | rport = fcport->rport; | 1857 | rport = fcport->rport; |
1823 | if (defer) { | 1858 | if (defer) { |
1824 | spin_lock_irqsave(&fcport->rport_lock, flags); | 1859 | spin_lock_irq(ha->host->host_lock); |
1825 | fcport->drport = rport; | 1860 | fcport->drport = rport; |
1826 | fcport->rport = NULL; | 1861 | spin_unlock_irq(ha->host->host_lock); |
1827 | *(fc_port_t **)rport->dd_data = NULL; | 1862 | set_bit(FCPORT_UPDATE_NEEDED, &pha->dpc_flags); |
1828 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | 1863 | qla2xxx_wake_dpc(pha); |
1829 | set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags); | 1864 | } else |
1830 | } else { | ||
1831 | spin_lock_irqsave(&fcport->rport_lock, flags); | ||
1832 | fcport->rport = NULL; | ||
1833 | *(fc_port_t **)rport->dd_data = NULL; | ||
1834 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | ||
1835 | fc_remote_port_delete(rport); | 1865 | fc_remote_port_delete(rport); |
1836 | } | ||
1837 | } | 1866 | } |
1838 | 1867 | ||
1839 | /* | 1868 | /* |
@@ -1903,7 +1932,7 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer) | |||
1903 | scsi_qla_host_t *pha = to_qla_parent(ha); | 1932 | scsi_qla_host_t *pha = to_qla_parent(ha); |
1904 | 1933 | ||
1905 | list_for_each_entry(fcport, &pha->fcports, list) { | 1934 | list_for_each_entry(fcport, &pha->fcports, list) { |
1906 | if (ha->vp_idx != 0 && ha->vp_idx != fcport->vp_idx) | 1935 | if (ha->vp_idx != fcport->vp_idx) |
1907 | continue; | 1936 | continue; |
1908 | /* | 1937 | /* |
1909 | * No point in marking the device as lost, if the device is | 1938 | * No point in marking the device as lost, if the device is |
@@ -1911,17 +1940,10 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer) | |||
1911 | */ | 1940 | */ |
1912 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) | 1941 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) |
1913 | continue; | 1942 | continue; |
1914 | if (atomic_read(&fcport->state) == FCS_ONLINE) { | 1943 | if (atomic_read(&fcport->state) == FCS_ONLINE) |
1915 | if (defer) | 1944 | qla2x00_schedule_rport_del(ha, fcport, defer); |
1916 | qla2x00_schedule_rport_del(ha, fcport, defer); | ||
1917 | else if (ha->vp_idx == fcport->vp_idx) | ||
1918 | qla2x00_schedule_rport_del(ha, fcport, defer); | ||
1919 | } | ||
1920 | atomic_set(&fcport->state, FCS_DEVICE_LOST); | 1945 | atomic_set(&fcport->state, FCS_DEVICE_LOST); |
1921 | } | 1946 | } |
1922 | |||
1923 | if (defer) | ||
1924 | qla2xxx_wake_dpc(ha); | ||
1925 | } | 1947 | } |
1926 | 1948 | ||
1927 | /* | 1949 | /* |
@@ -2156,7 +2178,7 @@ qla2x00_alloc_work(struct scsi_qla_host *ha, enum qla_work_type type, | |||
2156 | static int | 2178 | static int |
2157 | qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked) | 2179 | qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked) |
2158 | { | 2180 | { |
2159 | unsigned long flags; | 2181 | unsigned long uninitialized_var(flags); |
2160 | scsi_qla_host_t *pha = to_qla_parent(ha); | 2182 | scsi_qla_host_t *pha = to_qla_parent(ha); |
2161 | 2183 | ||
2162 | if (!locked) | 2184 | if (!locked) |
@@ -2313,8 +2335,10 @@ qla2x00_do_dpc(void *data) | |||
2313 | ha->host_no)); | 2335 | ha->host_no)); |
2314 | } | 2336 | } |
2315 | 2337 | ||
2316 | if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) | 2338 | if (test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) { |
2317 | qla2x00_update_fcports(ha); | 2339 | qla2x00_update_fcports(ha); |
2340 | clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags); | ||
2341 | } | ||
2318 | 2342 | ||
2319 | if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) && | 2343 | if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) && |
2320 | (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) { | 2344 | (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) { |
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 1728ab3ccb20..1bca74474935 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -869,11 +869,9 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, | |||
869 | uint32_t i; | 869 | uint32_t i; |
870 | uint32_t *dwptr; | 870 | uint32_t *dwptr; |
871 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 871 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
872 | unsigned long flags; | ||
873 | 872 | ||
874 | ret = QLA_SUCCESS; | 873 | ret = QLA_SUCCESS; |
875 | 874 | ||
876 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
877 | /* Enable flash write. */ | 875 | /* Enable flash write. */ |
878 | WRT_REG_DWORD(®->ctrl_status, | 876 | WRT_REG_DWORD(®->ctrl_status, |
879 | RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); | 877 | RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); |
@@ -907,7 +905,6 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, | |||
907 | WRT_REG_DWORD(®->ctrl_status, | 905 | WRT_REG_DWORD(®->ctrl_status, |
908 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); | 906 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); |
909 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ | 907 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ |
910 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
911 | 908 | ||
912 | return ret; | 909 | return ret; |
913 | } | 910 | } |
@@ -2306,6 +2303,51 @@ qla24xx_get_flash_version(scsi_qla_host_t *ha, void *mbuf) | |||
2306 | } | 2303 | } |
2307 | 2304 | ||
2308 | static int | 2305 | static int |
2306 | qla2xxx_is_vpd_valid(uint8_t *pos, uint8_t *end) | ||
2307 | { | ||
2308 | if (pos >= end || *pos != 0x82) | ||
2309 | return 0; | ||
2310 | |||
2311 | pos += 3 + pos[1]; | ||
2312 | if (pos >= end || *pos != 0x90) | ||
2313 | return 0; | ||
2314 | |||
2315 | pos += 3 + pos[1]; | ||
2316 | if (pos >= end || *pos != 0x78) | ||
2317 | return 0; | ||
2318 | |||
2319 | return 1; | ||
2320 | } | ||
2321 | |||
2322 | int | ||
2323 | qla2xxx_get_vpd_field(scsi_qla_host_t *ha, char *key, char *str, size_t size) | ||
2324 | { | ||
2325 | uint8_t *pos = ha->vpd; | ||
2326 | uint8_t *end = pos + ha->vpd_size; | ||
2327 | int len = 0; | ||
2328 | |||
2329 | if (!IS_FWI2_CAPABLE(ha) || !qla2xxx_is_vpd_valid(pos, end)) | ||
2330 | return 0; | ||
2331 | |||
2332 | while (pos < end && *pos != 0x78) { | ||
2333 | len = (*pos == 0x82) ? pos[1] : pos[2]; | ||
2334 | |||
2335 | if (!strncmp(pos, key, strlen(key))) | ||
2336 | break; | ||
2337 | |||
2338 | if (*pos != 0x90 && *pos != 0x91) | ||
2339 | pos += len; | ||
2340 | |||
2341 | pos += 3; | ||
2342 | } | ||
2343 | |||
2344 | if (pos < end - len && *pos != 0x78) | ||
2345 | return snprintf(str, size, "%.*s", len, pos + 3); | ||
2346 | |||
2347 | return 0; | ||
2348 | } | ||
2349 | |||
2350 | static int | ||
2309 | qla2xxx_hw_event_store(scsi_qla_host_t *ha, uint32_t *fdata) | 2351 | qla2xxx_hw_event_store(scsi_qla_host_t *ha, uint32_t *fdata) |
2310 | { | 2352 | { |
2311 | uint32_t d[2], faddr; | 2353 | uint32_t d[2], faddr; |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index d058c8862b35..676c390db354 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,7 +7,7 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.02.01-k4" | 10 | #define QLA2XXX_VERSION "8.02.01-k6" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 2 | 13 | #define QLA_DRIVER_MINOR_VER 2 |
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 5822dd595826..88bebb13bc52 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -46,6 +46,8 @@ MODULE_PARM_DESC(ql4xextended_error_logging, | |||
46 | 46 | ||
47 | int ql4_mod_unload = 0; | 47 | int ql4_mod_unload = 0; |
48 | 48 | ||
49 | #define QL4_DEF_QDEPTH 32 | ||
50 | |||
49 | /* | 51 | /* |
50 | * SCSI host template entry points | 52 | * SCSI host template entry points |
51 | */ | 53 | */ |
@@ -1387,7 +1389,7 @@ static int qla4xxx_slave_alloc(struct scsi_device *sdev) | |||
1387 | 1389 | ||
1388 | sdev->hostdata = ddb; | 1390 | sdev->hostdata = ddb; |
1389 | sdev->tagged_supported = 1; | 1391 | sdev->tagged_supported = 1; |
1390 | scsi_activate_tcq(sdev, sdev->host->can_queue); | 1392 | scsi_activate_tcq(sdev, QL4_DEF_QDEPTH); |
1391 | return 0; | 1393 | return 0; |
1392 | } | 1394 | } |
1393 | 1395 | ||
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 36c92f961e15..ee6be596503d 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -197,11 +197,43 @@ static void | |||
197 | scsi_pool_free_command(struct scsi_host_cmd_pool *pool, | 197 | scsi_pool_free_command(struct scsi_host_cmd_pool *pool, |
198 | struct scsi_cmnd *cmd) | 198 | struct scsi_cmnd *cmd) |
199 | { | 199 | { |
200 | if (cmd->prot_sdb) | ||
201 | kmem_cache_free(scsi_sdb_cache, cmd->prot_sdb); | ||
202 | |||
200 | kmem_cache_free(pool->sense_slab, cmd->sense_buffer); | 203 | kmem_cache_free(pool->sense_slab, cmd->sense_buffer); |
201 | kmem_cache_free(pool->cmd_slab, cmd); | 204 | kmem_cache_free(pool->cmd_slab, cmd); |
202 | } | 205 | } |
203 | 206 | ||
204 | /** | 207 | /** |
208 | * scsi_host_alloc_command - internal function to allocate command | ||
209 | * @shost: SCSI host whose pool to allocate from | ||
210 | * @gfp_mask: mask for the allocation | ||
211 | * | ||
212 | * Returns a fully allocated command with sense buffer and protection | ||
213 | * data buffer (where applicable) or NULL on failure | ||
214 | */ | ||
215 | static struct scsi_cmnd * | ||
216 | scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask) | ||
217 | { | ||
218 | struct scsi_cmnd *cmd; | ||
219 | |||
220 | cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); | ||
221 | if (!cmd) | ||
222 | return NULL; | ||
223 | |||
224 | if (scsi_host_get_prot(shost) >= SHOST_DIX_TYPE0_PROTECTION) { | ||
225 | cmd->prot_sdb = kmem_cache_zalloc(scsi_sdb_cache, gfp_mask); | ||
226 | |||
227 | if (!cmd->prot_sdb) { | ||
228 | scsi_pool_free_command(shost->cmd_pool, cmd); | ||
229 | return NULL; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | return cmd; | ||
234 | } | ||
235 | |||
236 | /** | ||
205 | * __scsi_get_command - Allocate a struct scsi_cmnd | 237 | * __scsi_get_command - Allocate a struct scsi_cmnd |
206 | * @shost: host to transmit command | 238 | * @shost: host to transmit command |
207 | * @gfp_mask: allocation mask | 239 | * @gfp_mask: allocation mask |
@@ -214,7 +246,7 @@ struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask) | |||
214 | struct scsi_cmnd *cmd; | 246 | struct scsi_cmnd *cmd; |
215 | unsigned char *buf; | 247 | unsigned char *buf; |
216 | 248 | ||
217 | cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); | 249 | cmd = scsi_host_alloc_command(shost, gfp_mask); |
218 | 250 | ||
219 | if (unlikely(!cmd)) { | 251 | if (unlikely(!cmd)) { |
220 | unsigned long flags; | 252 | unsigned long flags; |
@@ -457,7 +489,7 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost) | |||
457 | /* | 489 | /* |
458 | * Get one backup command for this host. | 490 | * Get one backup command for this host. |
459 | */ | 491 | */ |
460 | cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); | 492 | cmd = scsi_host_alloc_command(shost, gfp_mask); |
461 | if (!cmd) { | 493 | if (!cmd) { |
462 | scsi_put_host_cmd_pool(gfp_mask); | 494 | scsi_put_host_cmd_pool(gfp_mask); |
463 | shost->cmd_pool = NULL; | 495 | shost->cmd_pool = NULL; |
@@ -902,11 +934,20 @@ void scsi_adjust_queue_depth(struct scsi_device *sdev, int tagged, int tags) | |||
902 | 934 | ||
903 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | 935 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); |
904 | 936 | ||
905 | /* Check to see if the queue is managed by the block layer. | 937 | /* |
906 | * If it is, and we fail to adjust the depth, exit. */ | 938 | * Check to see if the queue is managed by the block layer. |
907 | if (blk_queue_tagged(sdev->request_queue) && | 939 | * If it is, and we fail to adjust the depth, exit. |
908 | blk_queue_resize_tags(sdev->request_queue, tags) != 0) | 940 | * |
909 | goto out; | 941 | * Do not resize the tag map if it is a host wide share bqt, |
942 | * because the size should be the hosts's can_queue. If there | ||
943 | * is more IO than the LLD's can_queue (so there are not enuogh | ||
944 | * tags) request_fn's host queue ready check will handle it. | ||
945 | */ | ||
946 | if (!sdev->host->bqt) { | ||
947 | if (blk_queue_tagged(sdev->request_queue) && | ||
948 | blk_queue_resize_tags(sdev->request_queue, tags) != 0) | ||
949 | goto out; | ||
950 | } | ||
910 | 951 | ||
911 | sdev->queue_depth = tags; | 952 | sdev->queue_depth = tags; |
912 | switch (tagged) { | 953 | switch (tagged) { |
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 01d11a01ffbf..27c633f55794 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -1753,7 +1753,7 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev) | |||
1753 | open_devip = sdebug_device_create(sdbg_host, GFP_ATOMIC); | 1753 | open_devip = sdebug_device_create(sdbg_host, GFP_ATOMIC); |
1754 | if (!open_devip) { | 1754 | if (!open_devip) { |
1755 | printk(KERN_ERR "%s: out of memory at line %d\n", | 1755 | printk(KERN_ERR "%s: out of memory at line %d\n", |
1756 | __FUNCTION__, __LINE__); | 1756 | __func__, __LINE__); |
1757 | return NULL; | 1757 | return NULL; |
1758 | } | 1758 | } |
1759 | } | 1759 | } |
@@ -2656,7 +2656,7 @@ static int sdebug_add_adapter(void) | |||
2656 | sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL); | 2656 | sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL); |
2657 | if (NULL == sdbg_host) { | 2657 | if (NULL == sdbg_host) { |
2658 | printk(KERN_ERR "%s: out of memory at line %d\n", | 2658 | printk(KERN_ERR "%s: out of memory at line %d\n", |
2659 | __FUNCTION__, __LINE__); | 2659 | __func__, __LINE__); |
2660 | return -ENOMEM; | 2660 | return -ENOMEM; |
2661 | } | 2661 | } |
2662 | 2662 | ||
@@ -2667,7 +2667,7 @@ static int sdebug_add_adapter(void) | |||
2667 | sdbg_devinfo = sdebug_device_create(sdbg_host, GFP_KERNEL); | 2667 | sdbg_devinfo = sdebug_device_create(sdbg_host, GFP_KERNEL); |
2668 | if (!sdbg_devinfo) { | 2668 | if (!sdbg_devinfo) { |
2669 | printk(KERN_ERR "%s: out of memory at line %d\n", | 2669 | printk(KERN_ERR "%s: out of memory at line %d\n", |
2670 | __FUNCTION__, __LINE__); | 2670 | __func__, __LINE__); |
2671 | error = -ENOMEM; | 2671 | error = -ENOMEM; |
2672 | goto clean; | 2672 | goto clean; |
2673 | } | 2673 | } |
@@ -2987,7 +2987,7 @@ static int sdebug_driver_probe(struct device * dev) | |||
2987 | 2987 | ||
2988 | hpnt = scsi_host_alloc(&sdebug_driver_template, sizeof(sdbg_host)); | 2988 | hpnt = scsi_host_alloc(&sdebug_driver_template, sizeof(sdbg_host)); |
2989 | if (NULL == hpnt) { | 2989 | if (NULL == hpnt) { |
2990 | printk(KERN_ERR "%s: scsi_register failed\n", __FUNCTION__); | 2990 | printk(KERN_ERR "%s: scsi_register failed\n", __func__); |
2991 | error = -ENODEV; | 2991 | error = -ENODEV; |
2992 | return error; | 2992 | return error; |
2993 | } | 2993 | } |
@@ -3002,7 +3002,7 @@ static int sdebug_driver_probe(struct device * dev) | |||
3002 | 3002 | ||
3003 | error = scsi_add_host(hpnt, &sdbg_host->dev); | 3003 | error = scsi_add_host(hpnt, &sdbg_host->dev); |
3004 | if (error) { | 3004 | if (error) { |
3005 | printk(KERN_ERR "%s: scsi_add_host failed\n", __FUNCTION__); | 3005 | printk(KERN_ERR "%s: scsi_add_host failed\n", __func__); |
3006 | error = -ENODEV; | 3006 | error = -ENODEV; |
3007 | scsi_host_put(hpnt); | 3007 | scsi_host_put(hpnt); |
3008 | } else | 3008 | } else |
@@ -3021,7 +3021,7 @@ static int sdebug_driver_remove(struct device * dev) | |||
3021 | 3021 | ||
3022 | if (!sdbg_host) { | 3022 | if (!sdbg_host) { |
3023 | printk(KERN_ERR "%s: Unable to locate host info\n", | 3023 | printk(KERN_ERR "%s: Unable to locate host info\n", |
3024 | __FUNCTION__); | 3024 | __func__); |
3025 | return -ENODEV; | 3025 | return -ENODEV; |
3026 | } | 3026 | } |
3027 | 3027 | ||
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index a235802f2981..4969e4ec75ea 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c | |||
@@ -272,7 +272,7 @@ static void scsi_strcpy_devinfo(char *name, char *to, size_t to_length, | |||
272 | } | 272 | } |
273 | if (from_length > to_length) | 273 | if (from_length > to_length) |
274 | printk(KERN_WARNING "%s: %s string '%s' is too long\n", | 274 | printk(KERN_WARNING "%s: %s string '%s' is too long\n", |
275 | __FUNCTION__, name, from); | 275 | __func__, name, from); |
276 | } | 276 | } |
277 | 277 | ||
278 | /** | 278 | /** |
@@ -298,7 +298,7 @@ static int scsi_dev_info_list_add(int compatible, char *vendor, char *model, | |||
298 | 298 | ||
299 | devinfo = kmalloc(sizeof(*devinfo), GFP_KERNEL); | 299 | devinfo = kmalloc(sizeof(*devinfo), GFP_KERNEL); |
300 | if (!devinfo) { | 300 | if (!devinfo) { |
301 | printk(KERN_ERR "%s: no memory\n", __FUNCTION__); | 301 | printk(KERN_ERR "%s: no memory\n", __func__); |
302 | return -ENOMEM; | 302 | return -ENOMEM; |
303 | } | 303 | } |
304 | 304 | ||
@@ -363,7 +363,7 @@ static int scsi_dev_info_list_add_str(char *dev_list) | |||
363 | strflags = strsep(&next, next_check); | 363 | strflags = strsep(&next, next_check); |
364 | if (!model || !strflags) { | 364 | if (!model || !strflags) { |
365 | printk(KERN_ERR "%s: bad dev info string '%s' '%s'" | 365 | printk(KERN_ERR "%s: bad dev info string '%s' '%s'" |
366 | " '%s'\n", __FUNCTION__, vendor, model, | 366 | " '%s'\n", __func__, vendor, model, |
367 | strflags); | 367 | strflags); |
368 | res = -EINVAL; | 368 | res = -EINVAL; |
369 | } else | 369 | } else |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 006a95916f72..880051c89bde 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -139,7 +139,7 @@ void scsi_add_timer(struct scsi_cmnd *scmd, int timeout, | |||
139 | scmd->eh_timeout.function = (void (*)(unsigned long)) complete; | 139 | scmd->eh_timeout.function = (void (*)(unsigned long)) complete; |
140 | 140 | ||
141 | SCSI_LOG_ERROR_RECOVERY(5, printk("%s: scmd: %p, time:" | 141 | SCSI_LOG_ERROR_RECOVERY(5, printk("%s: scmd: %p, time:" |
142 | " %d, (%p)\n", __FUNCTION__, | 142 | " %d, (%p)\n", __func__, |
143 | scmd, timeout, complete)); | 143 | scmd, timeout, complete)); |
144 | 144 | ||
145 | add_timer(&scmd->eh_timeout); | 145 | add_timer(&scmd->eh_timeout); |
@@ -163,7 +163,7 @@ int scsi_delete_timer(struct scsi_cmnd *scmd) | |||
163 | rtn = del_timer(&scmd->eh_timeout); | 163 | rtn = del_timer(&scmd->eh_timeout); |
164 | 164 | ||
165 | SCSI_LOG_ERROR_RECOVERY(5, printk("%s: scmd: %p," | 165 | SCSI_LOG_ERROR_RECOVERY(5, printk("%s: scmd: %p," |
166 | " rtn: %d\n", __FUNCTION__, | 166 | " rtn: %d\n", __func__, |
167 | scmd, rtn)); | 167 | scmd, rtn)); |
168 | 168 | ||
169 | scmd->eh_timeout.data = (unsigned long)NULL; | 169 | scmd->eh_timeout.data = (unsigned long)NULL; |
@@ -233,7 +233,7 @@ int scsi_block_when_processing_errors(struct scsi_device *sdev) | |||
233 | 233 | ||
234 | online = scsi_device_online(sdev); | 234 | online = scsi_device_online(sdev); |
235 | 235 | ||
236 | SCSI_LOG_ERROR_RECOVERY(5, printk("%s: rtn: %d\n", __FUNCTION__, | 236 | SCSI_LOG_ERROR_RECOVERY(5, printk("%s: rtn: %d\n", __func__, |
237 | online)); | 237 | online)); |
238 | 238 | ||
239 | return online; | 239 | return online; |
@@ -271,7 +271,7 @@ static inline void scsi_eh_prt_fail_stats(struct Scsi_Host *shost, | |||
271 | SCSI_LOG_ERROR_RECOVERY(3, | 271 | SCSI_LOG_ERROR_RECOVERY(3, |
272 | sdev_printk(KERN_INFO, sdev, | 272 | sdev_printk(KERN_INFO, sdev, |
273 | "%s: cmds failed: %d, cancel: %d\n", | 273 | "%s: cmds failed: %d, cancel: %d\n", |
274 | __FUNCTION__, cmd_failed, | 274 | __func__, cmd_failed, |
275 | cmd_cancel)); | 275 | cmd_cancel)); |
276 | cmd_cancel = 0; | 276 | cmd_cancel = 0; |
277 | cmd_failed = 0; | 277 | cmd_failed = 0; |
@@ -344,6 +344,9 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) | |||
344 | return /* soft_error */ SUCCESS; | 344 | return /* soft_error */ SUCCESS; |
345 | 345 | ||
346 | case ABORTED_COMMAND: | 346 | case ABORTED_COMMAND: |
347 | if (sshdr.asc == 0x10) /* DIF */ | ||
348 | return SUCCESS; | ||
349 | |||
347 | return NEEDS_RETRY; | 350 | return NEEDS_RETRY; |
348 | case NOT_READY: | 351 | case NOT_READY: |
349 | case UNIT_ATTENTION: | 352 | case UNIT_ATTENTION: |
@@ -470,7 +473,7 @@ static void scsi_eh_done(struct scsi_cmnd *scmd) | |||
470 | 473 | ||
471 | SCSI_LOG_ERROR_RECOVERY(3, | 474 | SCSI_LOG_ERROR_RECOVERY(3, |
472 | printk("%s scmd: %p result: %x\n", | 475 | printk("%s scmd: %p result: %x\n", |
473 | __FUNCTION__, scmd, scmd->result)); | 476 | __func__, scmd, scmd->result)); |
474 | 477 | ||
475 | eh_action = scmd->device->host->eh_action; | 478 | eh_action = scmd->device->host->eh_action; |
476 | if (eh_action) | 479 | if (eh_action) |
@@ -487,7 +490,7 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd) | |||
487 | int rtn; | 490 | int rtn; |
488 | 491 | ||
489 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Host RST\n", | 492 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Host RST\n", |
490 | __FUNCTION__)); | 493 | __func__)); |
491 | 494 | ||
492 | if (!scmd->device->host->hostt->eh_host_reset_handler) | 495 | if (!scmd->device->host->hostt->eh_host_reset_handler) |
493 | return FAILED; | 496 | return FAILED; |
@@ -516,7 +519,7 @@ static int scsi_try_bus_reset(struct scsi_cmnd *scmd) | |||
516 | int rtn; | 519 | int rtn; |
517 | 520 | ||
518 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Bus RST\n", | 521 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Bus RST\n", |
519 | __FUNCTION__)); | 522 | __func__)); |
520 | 523 | ||
521 | if (!scmd->device->host->hostt->eh_bus_reset_handler) | 524 | if (!scmd->device->host->hostt->eh_bus_reset_handler) |
522 | return FAILED; | 525 | return FAILED; |
@@ -664,7 +667,10 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, | |||
664 | ses->sdb = scmd->sdb; | 667 | ses->sdb = scmd->sdb; |
665 | ses->next_rq = scmd->request->next_rq; | 668 | ses->next_rq = scmd->request->next_rq; |
666 | ses->result = scmd->result; | 669 | ses->result = scmd->result; |
670 | ses->underflow = scmd->underflow; | ||
671 | ses->prot_op = scmd->prot_op; | ||
667 | 672 | ||
673 | scmd->prot_op = SCSI_PROT_NORMAL; | ||
668 | scmd->cmnd = ses->eh_cmnd; | 674 | scmd->cmnd = ses->eh_cmnd; |
669 | memset(scmd->cmnd, 0, BLK_MAX_CDB); | 675 | memset(scmd->cmnd, 0, BLK_MAX_CDB); |
670 | memset(&scmd->sdb, 0, sizeof(scmd->sdb)); | 676 | memset(&scmd->sdb, 0, sizeof(scmd->sdb)); |
@@ -722,6 +728,8 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses) | |||
722 | scmd->sdb = ses->sdb; | 728 | scmd->sdb = ses->sdb; |
723 | scmd->request->next_rq = ses->next_rq; | 729 | scmd->request->next_rq = ses->next_rq; |
724 | scmd->result = ses->result; | 730 | scmd->result = ses->result; |
731 | scmd->underflow = ses->underflow; | ||
732 | scmd->prot_op = ses->prot_op; | ||
725 | } | 733 | } |
726 | EXPORT_SYMBOL(scsi_eh_restore_cmnd); | 734 | EXPORT_SYMBOL(scsi_eh_restore_cmnd); |
727 | 735 | ||
@@ -766,7 +774,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
766 | 774 | ||
767 | SCSI_LOG_ERROR_RECOVERY(3, | 775 | SCSI_LOG_ERROR_RECOVERY(3, |
768 | printk("%s: scmd: %p, timeleft: %ld\n", | 776 | printk("%s: scmd: %p, timeleft: %ld\n", |
769 | __FUNCTION__, scmd, timeleft)); | 777 | __func__, scmd, timeleft)); |
770 | 778 | ||
771 | /* | 779 | /* |
772 | * If there is time left scsi_eh_done got called, and we will | 780 | * If there is time left scsi_eh_done got called, and we will |
@@ -778,7 +786,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
778 | rtn = scsi_eh_completed_normally(scmd); | 786 | rtn = scsi_eh_completed_normally(scmd); |
779 | SCSI_LOG_ERROR_RECOVERY(3, | 787 | SCSI_LOG_ERROR_RECOVERY(3, |
780 | printk("%s: scsi_eh_completed_normally %x\n", | 788 | printk("%s: scsi_eh_completed_normally %x\n", |
781 | __FUNCTION__, rtn)); | 789 | __func__, rtn)); |
782 | 790 | ||
783 | switch (rtn) { | 791 | switch (rtn) { |
784 | case SUCCESS: | 792 | case SUCCESS: |
@@ -913,7 +921,7 @@ retry_tur: | |||
913 | rtn = scsi_send_eh_cmnd(scmd, tur_command, 6, SENSE_TIMEOUT, 0); | 921 | rtn = scsi_send_eh_cmnd(scmd, tur_command, 6, SENSE_TIMEOUT, 0); |
914 | 922 | ||
915 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n", | 923 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n", |
916 | __FUNCTION__, scmd, rtn)); | 924 | __func__, scmd, rtn)); |
917 | 925 | ||
918 | switch (rtn) { | 926 | switch (rtn) { |
919 | case NEEDS_RETRY: | 927 | case NEEDS_RETRY: |
@@ -1296,7 +1304,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) | |||
1296 | if (!scsi_device_online(scmd->device)) { | 1304 | if (!scsi_device_online(scmd->device)) { |
1297 | SCSI_LOG_ERROR_RECOVERY(5, printk("%s: device offline - report" | 1305 | SCSI_LOG_ERROR_RECOVERY(5, printk("%s: device offline - report" |
1298 | " as SUCCESS\n", | 1306 | " as SUCCESS\n", |
1299 | __FUNCTION__)); | 1307 | __func__)); |
1300 | return SUCCESS; | 1308 | return SUCCESS; |
1301 | } | 1309 | } |
1302 | 1310 | ||
@@ -1511,7 +1519,7 @@ static void scsi_restart_operations(struct Scsi_Host *shost) | |||
1511 | * ioctls to queued block devices. | 1519 | * ioctls to queued block devices. |
1512 | */ | 1520 | */ |
1513 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: waking up host to restart\n", | 1521 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: waking up host to restart\n", |
1514 | __FUNCTION__)); | 1522 | __func__)); |
1515 | 1523 | ||
1516 | spin_lock_irqsave(shost->host_lock, flags); | 1524 | spin_lock_irqsave(shost->host_lock, flags); |
1517 | if (scsi_host_set_state(shost, SHOST_RUNNING)) | 1525 | if (scsi_host_set_state(shost, SHOST_RUNNING)) |
@@ -1835,7 +1843,7 @@ scsi_reset_provider(struct scsi_device *dev, int flag) | |||
1835 | */ | 1843 | */ |
1836 | SCSI_LOG_ERROR_RECOVERY(3, | 1844 | SCSI_LOG_ERROR_RECOVERY(3, |
1837 | printk("%s: waking up host to restart after TMF\n", | 1845 | printk("%s: waking up host to restart after TMF\n", |
1838 | __FUNCTION__)); | 1846 | __func__)); |
1839 | 1847 | ||
1840 | wake_up(&shost->host_wait); | 1848 | wake_up(&shost->host_wait); |
1841 | 1849 | ||
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 88d1b5f44e59..ff5d56b3ee4d 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -65,7 +65,7 @@ static struct scsi_host_sg_pool scsi_sg_pools[] = { | |||
65 | }; | 65 | }; |
66 | #undef SP | 66 | #undef SP |
67 | 67 | ||
68 | static struct kmem_cache *scsi_sdb_cache; | 68 | struct kmem_cache *scsi_sdb_cache; |
69 | 69 | ||
70 | static void scsi_run_queue(struct request_queue *q); | 70 | static void scsi_run_queue(struct request_queue *q); |
71 | 71 | ||
@@ -787,6 +787,9 @@ void scsi_release_buffers(struct scsi_cmnd *cmd) | |||
787 | kmem_cache_free(scsi_sdb_cache, bidi_sdb); | 787 | kmem_cache_free(scsi_sdb_cache, bidi_sdb); |
788 | cmd->request->next_rq->special = NULL; | 788 | cmd->request->next_rq->special = NULL; |
789 | } | 789 | } |
790 | |||
791 | if (scsi_prot_sg_count(cmd)) | ||
792 | scsi_free_sgtable(cmd->prot_sdb); | ||
790 | } | 793 | } |
791 | EXPORT_SYMBOL(scsi_release_buffers); | 794 | EXPORT_SYMBOL(scsi_release_buffers); |
792 | 795 | ||
@@ -947,9 +950,14 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
947 | * 6-byte command. | 950 | * 6-byte command. |
948 | */ | 951 | */ |
949 | scsi_requeue_command(q, cmd); | 952 | scsi_requeue_command(q, cmd); |
950 | return; | 953 | } else if (sshdr.asc == 0x10) /* DIX */ |
951 | } else { | 954 | scsi_end_request(cmd, -EIO, this_count, 0); |
955 | else | ||
952 | scsi_end_request(cmd, -EIO, this_count, 1); | 956 | scsi_end_request(cmd, -EIO, this_count, 1); |
957 | return; | ||
958 | case ABORTED_COMMAND: | ||
959 | if (sshdr.asc == 0x10) { /* DIF */ | ||
960 | scsi_end_request(cmd, -EIO, this_count, 0); | ||
953 | return; | 961 | return; |
954 | } | 962 | } |
955 | break; | 963 | break; |
@@ -1072,6 +1080,26 @@ int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask) | |||
1072 | goto err_exit; | 1080 | goto err_exit; |
1073 | } | 1081 | } |
1074 | 1082 | ||
1083 | if (blk_integrity_rq(cmd->request)) { | ||
1084 | struct scsi_data_buffer *prot_sdb = cmd->prot_sdb; | ||
1085 | int ivecs, count; | ||
1086 | |||
1087 | BUG_ON(prot_sdb == NULL); | ||
1088 | ivecs = blk_rq_count_integrity_sg(cmd->request); | ||
1089 | |||
1090 | if (scsi_alloc_sgtable(prot_sdb, ivecs, gfp_mask)) { | ||
1091 | error = BLKPREP_DEFER; | ||
1092 | goto err_exit; | ||
1093 | } | ||
1094 | |||
1095 | count = blk_rq_map_integrity_sg(cmd->request, | ||
1096 | prot_sdb->table.sgl); | ||
1097 | BUG_ON(unlikely(count > ivecs)); | ||
1098 | |||
1099 | cmd->prot_sdb = prot_sdb; | ||
1100 | cmd->prot_sdb->table.nents = count; | ||
1101 | } | ||
1102 | |||
1075 | return BLKPREP_OK ; | 1103 | return BLKPREP_OK ; |
1076 | 1104 | ||
1077 | err_exit: | 1105 | err_exit: |
@@ -1367,7 +1395,7 @@ static void scsi_kill_request(struct request *req, struct request_queue *q) | |||
1367 | 1395 | ||
1368 | if (unlikely(cmd == NULL)) { | 1396 | if (unlikely(cmd == NULL)) { |
1369 | printk(KERN_CRIT "impossible request in %s.\n", | 1397 | printk(KERN_CRIT "impossible request in %s.\n", |
1370 | __FUNCTION__); | 1398 | __func__); |
1371 | BUG(); | 1399 | BUG(); |
1372 | } | 1400 | } |
1373 | 1401 | ||
@@ -1491,12 +1519,27 @@ static void scsi_request_fn(struct request_queue *q) | |||
1491 | printk(KERN_CRIT "impossible request in %s.\n" | 1519 | printk(KERN_CRIT "impossible request in %s.\n" |
1492 | "please mail a stack trace to " | 1520 | "please mail a stack trace to " |
1493 | "linux-scsi@vger.kernel.org\n", | 1521 | "linux-scsi@vger.kernel.org\n", |
1494 | __FUNCTION__); | 1522 | __func__); |
1495 | blk_dump_rq_flags(req, "foo"); | 1523 | blk_dump_rq_flags(req, "foo"); |
1496 | BUG(); | 1524 | BUG(); |
1497 | } | 1525 | } |
1498 | spin_lock(shost->host_lock); | 1526 | spin_lock(shost->host_lock); |
1499 | 1527 | ||
1528 | /* | ||
1529 | * We hit this when the driver is using a host wide | ||
1530 | * tag map. For device level tag maps the queue_depth check | ||
1531 | * in the device ready fn would prevent us from trying | ||
1532 | * to allocate a tag. Since the map is a shared host resource | ||
1533 | * we add the dev to the starved list so it eventually gets | ||
1534 | * a run when a tag is freed. | ||
1535 | */ | ||
1536 | if (blk_queue_tagged(q) && !blk_rq_tagged(req)) { | ||
1537 | if (list_empty(&sdev->starved_entry)) | ||
1538 | list_add_tail(&sdev->starved_entry, | ||
1539 | &shost->starved_list); | ||
1540 | goto not_ready; | ||
1541 | } | ||
1542 | |||
1500 | if (!scsi_host_queue_ready(q, shost, sdev)) | 1543 | if (!scsi_host_queue_ready(q, shost, sdev)) |
1501 | goto not_ready; | 1544 | goto not_ready; |
1502 | if (scsi_target(sdev)->single_lun) { | 1545 | if (scsi_target(sdev)->single_lun) { |
@@ -2486,7 +2529,7 @@ void *scsi_kmap_atomic_sg(struct scatterlist *sgl, int sg_count, | |||
2486 | if (unlikely(i == sg_count)) { | 2529 | if (unlikely(i == sg_count)) { |
2487 | printk(KERN_ERR "%s: Bytes in sg: %zu, requested offset %zu, " | 2530 | printk(KERN_ERR "%s: Bytes in sg: %zu, requested offset %zu, " |
2488 | "elements %d\n", | 2531 | "elements %d\n", |
2489 | __FUNCTION__, sg_len, *offset, sg_count); | 2532 | __func__, sg_len, *offset, sg_count); |
2490 | WARN_ON(1); | 2533 | WARN_ON(1); |
2491 | return NULL; | 2534 | return NULL; |
2492 | } | 2535 | } |
diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c index 370c78cc1cb5..ae7ed9a22662 100644 --- a/drivers/scsi/scsi_netlink.c +++ b/drivers/scsi/scsi_netlink.c | |||
@@ -55,7 +55,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb) | |||
55 | if ((nlh->nlmsg_len < (sizeof(*nlh) + sizeof(*hdr))) || | 55 | if ((nlh->nlmsg_len < (sizeof(*nlh) + sizeof(*hdr))) || |
56 | (skb->len < nlh->nlmsg_len)) { | 56 | (skb->len < nlh->nlmsg_len)) { |
57 | printk(KERN_WARNING "%s: discarding partial skb\n", | 57 | printk(KERN_WARNING "%s: discarding partial skb\n", |
58 | __FUNCTION__); | 58 | __func__); |
59 | return; | 59 | return; |
60 | } | 60 | } |
61 | 61 | ||
@@ -82,7 +82,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb) | |||
82 | 82 | ||
83 | if (nlh->nlmsg_len < (sizeof(*nlh) + hdr->msglen)) { | 83 | if (nlh->nlmsg_len < (sizeof(*nlh) + hdr->msglen)) { |
84 | printk(KERN_WARNING "%s: discarding partial message\n", | 84 | printk(KERN_WARNING "%s: discarding partial message\n", |
85 | __FUNCTION__); | 85 | __func__); |
86 | return; | 86 | return; |
87 | } | 87 | } |
88 | 88 | ||
@@ -139,7 +139,7 @@ scsi_netlink_init(void) | |||
139 | error = netlink_register_notifier(&scsi_netlink_notifier); | 139 | error = netlink_register_notifier(&scsi_netlink_notifier); |
140 | if (error) { | 140 | if (error) { |
141 | printk(KERN_ERR "%s: register of event handler failed - %d\n", | 141 | printk(KERN_ERR "%s: register of event handler failed - %d\n", |
142 | __FUNCTION__, error); | 142 | __func__, error); |
143 | return; | 143 | return; |
144 | } | 144 | } |
145 | 145 | ||
@@ -148,7 +148,7 @@ scsi_netlink_init(void) | |||
148 | THIS_MODULE); | 148 | THIS_MODULE); |
149 | if (!scsi_nl_sock) { | 149 | if (!scsi_nl_sock) { |
150 | printk(KERN_ERR "%s: register of recieve handler failed\n", | 150 | printk(KERN_ERR "%s: register of recieve handler failed\n", |
151 | __FUNCTION__); | 151 | __func__); |
152 | netlink_unregister_notifier(&scsi_netlink_notifier); | 152 | netlink_unregister_notifier(&scsi_netlink_notifier); |
153 | } | 153 | } |
154 | 154 | ||
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index b33e72516ef8..79f0f7511204 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h | |||
@@ -77,6 +77,7 @@ extern void scsi_exit_queue(void); | |||
77 | struct request_queue; | 77 | struct request_queue; |
78 | struct request; | 78 | struct request; |
79 | extern int scsi_prep_fn(struct request_queue *, struct request *); | 79 | extern int scsi_prep_fn(struct request_queue *, struct request *); |
80 | extern struct kmem_cache *scsi_sdb_cache; | ||
80 | 81 | ||
81 | /* scsi_proc.c */ | 82 | /* scsi_proc.c */ |
82 | #ifdef CONFIG_SCSI_PROC_FS | 83 | #ifdef CONFIG_SCSI_PROC_FS |
diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c index e4a0d2f9b357..c6a904a45bf9 100644 --- a/drivers/scsi/scsi_proc.c +++ b/drivers/scsi/scsi_proc.c | |||
@@ -114,7 +114,7 @@ void scsi_proc_hostdir_add(struct scsi_host_template *sht) | |||
114 | sht->proc_dir = proc_mkdir(sht->proc_name, proc_scsi); | 114 | sht->proc_dir = proc_mkdir(sht->proc_name, proc_scsi); |
115 | if (!sht->proc_dir) | 115 | if (!sht->proc_dir) |
116 | printk(KERN_ERR "%s: proc_mkdir failed for %s\n", | 116 | printk(KERN_ERR "%s: proc_mkdir failed for %s\n", |
117 | __FUNCTION__, sht->proc_name); | 117 | __func__, sht->proc_name); |
118 | else | 118 | else |
119 | sht->proc_dir->owner = sht->module; | 119 | sht->proc_dir->owner = sht->module; |
120 | } | 120 | } |
@@ -157,7 +157,7 @@ void scsi_proc_host_add(struct Scsi_Host *shost) | |||
157 | sht->proc_dir, proc_scsi_read, shost); | 157 | sht->proc_dir, proc_scsi_read, shost); |
158 | if (!p) { | 158 | if (!p) { |
159 | printk(KERN_ERR "%s: Failed to register host %d in" | 159 | printk(KERN_ERR "%s: Failed to register host %d in" |
160 | "%s\n", __FUNCTION__, shost->host_no, | 160 | "%s\n", __func__, shost->host_no, |
161 | sht->proc_name); | 161 | sht->proc_name); |
162 | return; | 162 | return; |
163 | } | 163 | } |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 196fe3af0d5e..84b4879cff11 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -318,7 +318,7 @@ out_device_destroy: | |||
318 | put_device(&sdev->sdev_gendev); | 318 | put_device(&sdev->sdev_gendev); |
319 | out: | 319 | out: |
320 | if (display_failure_msg) | 320 | if (display_failure_msg) |
321 | printk(ALLOC_FAILURE_MSG, __FUNCTION__); | 321 | printk(ALLOC_FAILURE_MSG, __func__); |
322 | return NULL; | 322 | return NULL; |
323 | } | 323 | } |
324 | 324 | ||
@@ -404,7 +404,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, | |||
404 | 404 | ||
405 | starget = kzalloc(size, GFP_KERNEL); | 405 | starget = kzalloc(size, GFP_KERNEL); |
406 | if (!starget) { | 406 | if (!starget) { |
407 | printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__); | 407 | printk(KERN_ERR "%s: allocation failure\n", __func__); |
408 | return NULL; | 408 | return NULL; |
409 | } | 409 | } |
410 | dev = &starget->dev; | 410 | dev = &starget->dev; |
@@ -1337,7 +1337,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, | |||
1337 | lun_data = kmalloc(length, GFP_ATOMIC | | 1337 | lun_data = kmalloc(length, GFP_ATOMIC | |
1338 | (sdev->host->unchecked_isa_dma ? __GFP_DMA : 0)); | 1338 | (sdev->host->unchecked_isa_dma ? __GFP_DMA : 0)); |
1339 | if (!lun_data) { | 1339 | if (!lun_data) { |
1340 | printk(ALLOC_FAILURE_MSG, __FUNCTION__); | 1340 | printk(ALLOC_FAILURE_MSG, __func__); |
1341 | goto out; | 1341 | goto out; |
1342 | } | 1342 | } |
1343 | 1343 | ||
@@ -1649,7 +1649,7 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, | |||
1649 | { | 1649 | { |
1650 | SCSI_LOG_SCAN_BUS(3, shost_printk (KERN_INFO, shost, | 1650 | SCSI_LOG_SCAN_BUS(3, shost_printk (KERN_INFO, shost, |
1651 | "%s: <%u:%u:%u>\n", | 1651 | "%s: <%u:%u:%u>\n", |
1652 | __FUNCTION__, channel, id, lun)); | 1652 | __func__, channel, id, lun)); |
1653 | 1653 | ||
1654 | if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || | 1654 | if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || |
1655 | ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) || | 1655 | ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) || |
@@ -1703,7 +1703,7 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) | |||
1703 | return NULL; | 1703 | return NULL; |
1704 | 1704 | ||
1705 | if (shost->async_scan) { | 1705 | if (shost->async_scan) { |
1706 | printk("%s called twice for host %d", __FUNCTION__, | 1706 | printk("%s called twice for host %d", __func__, |
1707 | shost->host_no); | 1707 | shost->host_no); |
1708 | dump_stack(); | 1708 | dump_stack(); |
1709 | return NULL; | 1709 | return NULL; |
@@ -1757,9 +1757,10 @@ static void scsi_finish_async_scan(struct async_scan_data *data) | |||
1757 | mutex_lock(&shost->scan_mutex); | 1757 | mutex_lock(&shost->scan_mutex); |
1758 | 1758 | ||
1759 | if (!shost->async_scan) { | 1759 | if (!shost->async_scan) { |
1760 | printk("%s called twice for host %d", __FUNCTION__, | 1760 | printk("%s called twice for host %d", __func__, |
1761 | shost->host_no); | 1761 | shost->host_no); |
1762 | dump_stack(); | 1762 | dump_stack(); |
1763 | mutex_unlock(&shost->scan_mutex); | ||
1763 | return; | 1764 | return; |
1764 | } | 1765 | } |
1765 | 1766 | ||
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index b6e561059779..ab3c71869be5 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -249,6 +249,8 @@ shost_rd_attr(cmd_per_lun, "%hd\n"); | |||
249 | shost_rd_attr(can_queue, "%hd\n"); | 249 | shost_rd_attr(can_queue, "%hd\n"); |
250 | shost_rd_attr(sg_tablesize, "%hu\n"); | 250 | shost_rd_attr(sg_tablesize, "%hu\n"); |
251 | shost_rd_attr(unchecked_isa_dma, "%d\n"); | 251 | shost_rd_attr(unchecked_isa_dma, "%d\n"); |
252 | shost_rd_attr(prot_capabilities, "%u\n"); | ||
253 | shost_rd_attr(prot_guard_type, "%hd\n"); | ||
252 | shost_rd_attr2(proc_name, hostt->proc_name, "%s\n"); | 254 | shost_rd_attr2(proc_name, hostt->proc_name, "%s\n"); |
253 | 255 | ||
254 | static struct attribute *scsi_sysfs_shost_attrs[] = { | 256 | static struct attribute *scsi_sysfs_shost_attrs[] = { |
@@ -263,6 +265,8 @@ static struct attribute *scsi_sysfs_shost_attrs[] = { | |||
263 | &dev_attr_hstate.attr, | 265 | &dev_attr_hstate.attr, |
264 | &dev_attr_supported_mode.attr, | 266 | &dev_attr_supported_mode.attr, |
265 | &dev_attr_active_mode.attr, | 267 | &dev_attr_active_mode.attr, |
268 | &dev_attr_prot_capabilities.attr, | ||
269 | &dev_attr_prot_guard_type.attr, | ||
266 | NULL | 270 | NULL |
267 | }; | 271 | }; |
268 | 272 | ||
diff --git a/drivers/scsi/scsi_tgt_priv.h b/drivers/scsi/scsi_tgt_priv.h index cb92888948f9..fe4c62177f78 100644 --- a/drivers/scsi/scsi_tgt_priv.h +++ b/drivers/scsi/scsi_tgt_priv.h | |||
@@ -6,7 +6,7 @@ struct task_struct; | |||
6 | /* tmp - will replace with SCSI logging stuff */ | 6 | /* tmp - will replace with SCSI logging stuff */ |
7 | #define eprintk(fmt, args...) \ | 7 | #define eprintk(fmt, args...) \ |
8 | do { \ | 8 | do { \ |
9 | printk("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \ | 9 | printk("%s(%d) " fmt, __func__, __LINE__, ##args); \ |
10 | } while (0) | 10 | } while (0) |
11 | 11 | ||
12 | #define dprintk(fmt, args...) | 12 | #define dprintk(fmt, args...) |
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index a272b9a2c869..56823fd1fb84 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -571,7 +571,7 @@ send_fail: | |||
571 | name = get_fc_host_event_code_name(event_code); | 571 | name = get_fc_host_event_code_name(event_code); |
572 | printk(KERN_WARNING | 572 | printk(KERN_WARNING |
573 | "%s: Dropped Event : host %d %s data 0x%08x - err %d\n", | 573 | "%s: Dropped Event : host %d %s data 0x%08x - err %d\n", |
574 | __FUNCTION__, shost->host_no, | 574 | __func__, shost->host_no, |
575 | (name) ? name : "<unknown>", event_data, err); | 575 | (name) ? name : "<unknown>", event_data, err); |
576 | return; | 576 | return; |
577 | } | 577 | } |
@@ -644,7 +644,7 @@ send_vendor_fail_skb: | |||
644 | send_vendor_fail: | 644 | send_vendor_fail: |
645 | printk(KERN_WARNING | 645 | printk(KERN_WARNING |
646 | "%s: Dropped Event : host %d vendor_unique - err %d\n", | 646 | "%s: Dropped Event : host %d vendor_unique - err %d\n", |
647 | __FUNCTION__, shost->host_no, err); | 647 | __func__, shost->host_no, err); |
648 | return; | 648 | return; |
649 | } | 649 | } |
650 | EXPORT_SYMBOL(fc_host_post_vendor_event); | 650 | EXPORT_SYMBOL(fc_host_post_vendor_event); |
@@ -2464,7 +2464,7 @@ fc_rport_create(struct Scsi_Host *shost, int channel, | |||
2464 | size = (sizeof(struct fc_rport) + fci->f->dd_fcrport_size); | 2464 | size = (sizeof(struct fc_rport) + fci->f->dd_fcrport_size); |
2465 | rport = kzalloc(size, GFP_KERNEL); | 2465 | rport = kzalloc(size, GFP_KERNEL); |
2466 | if (unlikely(!rport)) { | 2466 | if (unlikely(!rport)) { |
2467 | printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__); | 2467 | printk(KERN_ERR "%s: allocation failure\n", __func__); |
2468 | return NULL; | 2468 | return NULL; |
2469 | } | 2469 | } |
2470 | 2470 | ||
@@ -3137,7 +3137,7 @@ fc_vport_create(struct Scsi_Host *shost, int channel, struct device *pdev, | |||
3137 | size = (sizeof(struct fc_vport) + fci->f->dd_fcvport_size); | 3137 | size = (sizeof(struct fc_vport) + fci->f->dd_fcvport_size); |
3138 | vport = kzalloc(size, GFP_KERNEL); | 3138 | vport = kzalloc(size, GFP_KERNEL); |
3139 | if (unlikely(!vport)) { | 3139 | if (unlikely(!vport)) { |
3140 | printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__); | 3140 | printk(KERN_ERR "%s: allocation failure\n", __func__); |
3141 | return -ENOMEM; | 3141 | return -ENOMEM; |
3142 | } | 3142 | } |
3143 | 3143 | ||
@@ -3201,7 +3201,7 @@ fc_vport_create(struct Scsi_Host *shost, int channel, struct device *pdev, | |||
3201 | printk(KERN_ERR | 3201 | printk(KERN_ERR |
3202 | "%s: Cannot create vport symlinks for " | 3202 | "%s: Cannot create vport symlinks for " |
3203 | "%s, err=%d\n", | 3203 | "%s, err=%d\n", |
3204 | __FUNCTION__, dev->bus_id, error); | 3204 | __func__, dev->bus_id, error); |
3205 | } | 3205 | } |
3206 | spin_lock_irqsave(shost->host_lock, flags); | 3206 | spin_lock_irqsave(shost->host_lock, flags); |
3207 | vport->flags &= ~FC_VPORT_CREATING; | 3207 | vport->flags &= ~FC_VPORT_CREATING; |
@@ -3314,7 +3314,7 @@ fc_vport_sched_delete(struct work_struct *work) | |||
3314 | if (stat) | 3314 | if (stat) |
3315 | dev_printk(KERN_ERR, vport->dev.parent, | 3315 | dev_printk(KERN_ERR, vport->dev.parent, |
3316 | "%s: %s could not be deleted created via " | 3316 | "%s: %s could not be deleted created via " |
3317 | "shost%d channel %d - error %d\n", __FUNCTION__, | 3317 | "shost%d channel %d - error %d\n", __func__, |
3318 | vport->dev.bus_id, vport->shost->host_no, | 3318 | vport->dev.bus_id, vport->shost->host_no, |
3319 | vport->channel, stat); | 3319 | vport->channel, stat); |
3320 | } | 3320 | } |
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index f4461d35ffb9..366609386be1 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c | |||
@@ -779,7 +779,7 @@ static void sas_port_create_link(struct sas_port *port, | |||
779 | return; | 779 | return; |
780 | err: | 780 | err: |
781 | printk(KERN_ERR "%s: Cannot create port links, err=%d\n", | 781 | printk(KERN_ERR "%s: Cannot create port links, err=%d\n", |
782 | __FUNCTION__, res); | 782 | __func__, res); |
783 | } | 783 | } |
784 | 784 | ||
785 | static void sas_port_delete_link(struct sas_port *port, | 785 | static void sas_port_delete_link(struct sas_port *port, |
@@ -1029,7 +1029,7 @@ void sas_port_mark_backlink(struct sas_port *port) | |||
1029 | return; | 1029 | return; |
1030 | err: | 1030 | err: |
1031 | printk(KERN_ERR "%s: Cannot create port backlink, err=%d\n", | 1031 | printk(KERN_ERR "%s: Cannot create port backlink, err=%d\n", |
1032 | __FUNCTION__, res); | 1032 | __func__, res); |
1033 | 1033 | ||
1034 | } | 1034 | } |
1035 | EXPORT_SYMBOL(sas_port_mark_backlink); | 1035 | EXPORT_SYMBOL(sas_port_mark_backlink); |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 0c63947d8a9d..e5e7d7856454 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -99,8 +99,7 @@ static void scsi_disk_release(struct device *cdev); | |||
99 | static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); | 99 | static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); |
100 | static void sd_print_result(struct scsi_disk *, int); | 100 | static void sd_print_result(struct scsi_disk *, int); |
101 | 101 | ||
102 | static DEFINE_IDR(sd_index_idr); | 102 | static DEFINE_IDA(sd_index_ida); |
103 | static DEFINE_SPINLOCK(sd_index_lock); | ||
104 | 103 | ||
105 | /* This semaphore is used to mediate the 0->1 reference get in the | 104 | /* This semaphore is used to mediate the 0->1 reference get in the |
106 | * face of object destruction (i.e. we can't allow a get on an | 105 | * face of object destruction (i.e. we can't allow a get on an |
@@ -234,6 +233,24 @@ sd_show_allow_restart(struct device *dev, struct device_attribute *attr, | |||
234 | return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart); | 233 | return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart); |
235 | } | 234 | } |
236 | 235 | ||
236 | static ssize_t | ||
237 | sd_show_protection_type(struct device *dev, struct device_attribute *attr, | ||
238 | char *buf) | ||
239 | { | ||
240 | struct scsi_disk *sdkp = to_scsi_disk(dev); | ||
241 | |||
242 | return snprintf(buf, 20, "%u\n", sdkp->protection_type); | ||
243 | } | ||
244 | |||
245 | static ssize_t | ||
246 | sd_show_app_tag_own(struct device *dev, struct device_attribute *attr, | ||
247 | char *buf) | ||
248 | { | ||
249 | struct scsi_disk *sdkp = to_scsi_disk(dev); | ||
250 | |||
251 | return snprintf(buf, 20, "%u\n", sdkp->ATO); | ||
252 | } | ||
253 | |||
237 | static struct device_attribute sd_disk_attrs[] = { | 254 | static struct device_attribute sd_disk_attrs[] = { |
238 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, | 255 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, |
239 | sd_store_cache_type), | 256 | sd_store_cache_type), |
@@ -242,6 +259,8 @@ static struct device_attribute sd_disk_attrs[] = { | |||
242 | sd_store_allow_restart), | 259 | sd_store_allow_restart), |
243 | __ATTR(manage_start_stop, S_IRUGO|S_IWUSR, sd_show_manage_start_stop, | 260 | __ATTR(manage_start_stop, S_IRUGO|S_IWUSR, sd_show_manage_start_stop, |
244 | sd_store_manage_start_stop), | 261 | sd_store_manage_start_stop), |
262 | __ATTR(protection_type, S_IRUGO, sd_show_protection_type, NULL), | ||
263 | __ATTR(app_tag_own, S_IRUGO, sd_show_app_tag_own, NULL), | ||
245 | __ATTR_NULL, | 264 | __ATTR_NULL, |
246 | }; | 265 | }; |
247 | 266 | ||
@@ -354,7 +373,9 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
354 | struct scsi_cmnd *SCpnt; | 373 | struct scsi_cmnd *SCpnt; |
355 | struct scsi_device *sdp = q->queuedata; | 374 | struct scsi_device *sdp = q->queuedata; |
356 | struct gendisk *disk = rq->rq_disk; | 375 | struct gendisk *disk = rq->rq_disk; |
376 | struct scsi_disk *sdkp; | ||
357 | sector_t block = rq->sector; | 377 | sector_t block = rq->sector; |
378 | sector_t threshold; | ||
358 | unsigned int this_count = rq->nr_sectors; | 379 | unsigned int this_count = rq->nr_sectors; |
359 | unsigned int timeout = sdp->timeout; | 380 | unsigned int timeout = sdp->timeout; |
360 | int ret; | 381 | int ret; |
@@ -370,6 +391,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
370 | if (ret != BLKPREP_OK) | 391 | if (ret != BLKPREP_OK) |
371 | goto out; | 392 | goto out; |
372 | SCpnt = rq->special; | 393 | SCpnt = rq->special; |
394 | sdkp = scsi_disk(disk); | ||
373 | 395 | ||
374 | /* from here on until we're complete, any goto out | 396 | /* from here on until we're complete, any goto out |
375 | * is used for a killable error condition */ | 397 | * is used for a killable error condition */ |
@@ -401,13 +423,21 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
401 | } | 423 | } |
402 | 424 | ||
403 | /* | 425 | /* |
404 | * Some devices (some sdcards for one) don't like it if the | 426 | * Some SD card readers can't handle multi-sector accesses which touch |
405 | * last sector gets read in a larger then 1 sector read. | 427 | * the last one or two hardware sectors. Split accesses as needed. |
406 | */ | 428 | */ |
407 | if (unlikely(sdp->last_sector_bug && | 429 | threshold = get_capacity(disk) - SD_LAST_BUGGY_SECTORS * |
408 | rq->nr_sectors > sdp->sector_size / 512 && | 430 | (sdp->sector_size / 512); |
409 | block + this_count == get_capacity(disk))) | 431 | |
410 | this_count -= sdp->sector_size / 512; | 432 | if (unlikely(sdp->last_sector_bug && block + this_count > threshold)) { |
433 | if (block < threshold) { | ||
434 | /* Access up to the threshold but not beyond */ | ||
435 | this_count = threshold - block; | ||
436 | } else { | ||
437 | /* Access only a single hardware sector */ | ||
438 | this_count = sdp->sector_size / 512; | ||
439 | } | ||
440 | } | ||
411 | 441 | ||
412 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", | 442 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", |
413 | (unsigned long long)block)); | 443 | (unsigned long long)block)); |
@@ -459,6 +489,11 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
459 | } | 489 | } |
460 | SCpnt->cmnd[0] = WRITE_6; | 490 | SCpnt->cmnd[0] = WRITE_6; |
461 | SCpnt->sc_data_direction = DMA_TO_DEVICE; | 491 | SCpnt->sc_data_direction = DMA_TO_DEVICE; |
492 | |||
493 | if (blk_integrity_rq(rq) && | ||
494 | sd_dif_prepare(rq, block, sdp->sector_size) == -EIO) | ||
495 | goto out; | ||
496 | |||
462 | } else if (rq_data_dir(rq) == READ) { | 497 | } else if (rq_data_dir(rq) == READ) { |
463 | SCpnt->cmnd[0] = READ_6; | 498 | SCpnt->cmnd[0] = READ_6; |
464 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; | 499 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; |
@@ -473,8 +508,12 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
473 | "writing" : "reading", this_count, | 508 | "writing" : "reading", this_count, |
474 | rq->nr_sectors)); | 509 | rq->nr_sectors)); |
475 | 510 | ||
476 | SCpnt->cmnd[1] = 0; | 511 | /* Set RDPROTECT/WRPROTECT if disk is formatted with DIF */ |
477 | 512 | if (scsi_host_dif_capable(sdp->host, sdkp->protection_type)) | |
513 | SCpnt->cmnd[1] = 1 << 5; | ||
514 | else | ||
515 | SCpnt->cmnd[1] = 0; | ||
516 | |||
478 | if (block > 0xffffffff) { | 517 | if (block > 0xffffffff) { |
479 | SCpnt->cmnd[0] += READ_16 - READ_6; | 518 | SCpnt->cmnd[0] += READ_16 - READ_6; |
480 | SCpnt->cmnd[1] |= blk_fua_rq(rq) ? 0x8 : 0; | 519 | SCpnt->cmnd[1] |= blk_fua_rq(rq) ? 0x8 : 0; |
@@ -492,6 +531,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
492 | SCpnt->cmnd[13] = (unsigned char) this_count & 0xff; | 531 | SCpnt->cmnd[13] = (unsigned char) this_count & 0xff; |
493 | SCpnt->cmnd[14] = SCpnt->cmnd[15] = 0; | 532 | SCpnt->cmnd[14] = SCpnt->cmnd[15] = 0; |
494 | } else if ((this_count > 0xff) || (block > 0x1fffff) || | 533 | } else if ((this_count > 0xff) || (block > 0x1fffff) || |
534 | scsi_device_protection(SCpnt->device) || | ||
495 | SCpnt->device->use_10_for_rw) { | 535 | SCpnt->device->use_10_for_rw) { |
496 | if (this_count > 0xffff) | 536 | if (this_count > 0xffff) |
497 | this_count = 0xffff; | 537 | this_count = 0xffff; |
@@ -526,6 +566,10 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
526 | } | 566 | } |
527 | SCpnt->sdb.length = this_count * sdp->sector_size; | 567 | SCpnt->sdb.length = this_count * sdp->sector_size; |
528 | 568 | ||
569 | /* If DIF or DIX is enabled, tell HBA how to handle request */ | ||
570 | if (sdkp->protection_type || scsi_prot_sg_count(SCpnt)) | ||
571 | sd_dif_op(SCpnt, sdkp->protection_type, scsi_prot_sg_count(SCpnt)); | ||
572 | |||
529 | /* | 573 | /* |
530 | * We shouldn't disconnect in the middle of a sector, so with a dumb | 574 | * We shouldn't disconnect in the middle of a sector, so with a dumb |
531 | * host adapter, it's safe to assume that we can at least transfer | 575 | * host adapter, it's safe to assume that we can at least transfer |
@@ -920,6 +964,48 @@ static struct block_device_operations sd_fops = { | |||
920 | .revalidate_disk = sd_revalidate_disk, | 964 | .revalidate_disk = sd_revalidate_disk, |
921 | }; | 965 | }; |
922 | 966 | ||
967 | static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd) | ||
968 | { | ||
969 | u64 start_lba = scmd->request->sector; | ||
970 | u64 end_lba = scmd->request->sector + (scsi_bufflen(scmd) / 512); | ||
971 | u64 bad_lba; | ||
972 | int info_valid; | ||
973 | |||
974 | if (!blk_fs_request(scmd->request)) | ||
975 | return 0; | ||
976 | |||
977 | info_valid = scsi_get_sense_info_fld(scmd->sense_buffer, | ||
978 | SCSI_SENSE_BUFFERSIZE, | ||
979 | &bad_lba); | ||
980 | if (!info_valid) | ||
981 | return 0; | ||
982 | |||
983 | if (scsi_bufflen(scmd) <= scmd->device->sector_size) | ||
984 | return 0; | ||
985 | |||
986 | if (scmd->device->sector_size < 512) { | ||
987 | /* only legitimate sector_size here is 256 */ | ||
988 | start_lba <<= 1; | ||
989 | end_lba <<= 1; | ||
990 | } else { | ||
991 | /* be careful ... don't want any overflows */ | ||
992 | u64 factor = scmd->device->sector_size / 512; | ||
993 | do_div(start_lba, factor); | ||
994 | do_div(end_lba, factor); | ||
995 | } | ||
996 | |||
997 | /* The bad lba was reported incorrectly, we have no idea where | ||
998 | * the error is. | ||
999 | */ | ||
1000 | if (bad_lba < start_lba || bad_lba >= end_lba) | ||
1001 | return 0; | ||
1002 | |||
1003 | /* This computation should always be done in terms of | ||
1004 | * the resolution of the device's medium. | ||
1005 | */ | ||
1006 | return (bad_lba - start_lba) * scmd->device->sector_size; | ||
1007 | } | ||
1008 | |||
923 | /** | 1009 | /** |
924 | * sd_done - bottom half handler: called when the lower level | 1010 | * sd_done - bottom half handler: called when the lower level |
925 | * driver has completed (successfully or otherwise) a scsi command. | 1011 | * driver has completed (successfully or otherwise) a scsi command. |
@@ -930,15 +1016,10 @@ static struct block_device_operations sd_fops = { | |||
930 | static int sd_done(struct scsi_cmnd *SCpnt) | 1016 | static int sd_done(struct scsi_cmnd *SCpnt) |
931 | { | 1017 | { |
932 | int result = SCpnt->result; | 1018 | int result = SCpnt->result; |
933 | unsigned int xfer_size = scsi_bufflen(SCpnt); | 1019 | unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); |
934 | unsigned int good_bytes = result ? 0 : xfer_size; | ||
935 | u64 start_lba = SCpnt->request->sector; | ||
936 | u64 end_lba = SCpnt->request->sector + (xfer_size / 512); | ||
937 | u64 bad_lba; | ||
938 | struct scsi_sense_hdr sshdr; | 1020 | struct scsi_sense_hdr sshdr; |
939 | int sense_valid = 0; | 1021 | int sense_valid = 0; |
940 | int sense_deferred = 0; | 1022 | int sense_deferred = 0; |
941 | int info_valid; | ||
942 | 1023 | ||
943 | if (result) { | 1024 | if (result) { |
944 | sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr); | 1025 | sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr); |
@@ -963,36 +1044,7 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
963 | switch (sshdr.sense_key) { | 1044 | switch (sshdr.sense_key) { |
964 | case HARDWARE_ERROR: | 1045 | case HARDWARE_ERROR: |
965 | case MEDIUM_ERROR: | 1046 | case MEDIUM_ERROR: |
966 | if (!blk_fs_request(SCpnt->request)) | 1047 | good_bytes = sd_completed_bytes(SCpnt); |
967 | goto out; | ||
968 | info_valid = scsi_get_sense_info_fld(SCpnt->sense_buffer, | ||
969 | SCSI_SENSE_BUFFERSIZE, | ||
970 | &bad_lba); | ||
971 | if (!info_valid) | ||
972 | goto out; | ||
973 | if (xfer_size <= SCpnt->device->sector_size) | ||
974 | goto out; | ||
975 | if (SCpnt->device->sector_size < 512) { | ||
976 | /* only legitimate sector_size here is 256 */ | ||
977 | start_lba <<= 1; | ||
978 | end_lba <<= 1; | ||
979 | } else { | ||
980 | /* be careful ... don't want any overflows */ | ||
981 | u64 factor = SCpnt->device->sector_size / 512; | ||
982 | do_div(start_lba, factor); | ||
983 | do_div(end_lba, factor); | ||
984 | } | ||
985 | |||
986 | if (bad_lba < start_lba || bad_lba >= end_lba) | ||
987 | /* the bad lba was reported incorrectly, we have | ||
988 | * no idea where the error is | ||
989 | */ | ||
990 | goto out; | ||
991 | |||
992 | /* This computation should always be done in terms of | ||
993 | * the resolution of the device's medium. | ||
994 | */ | ||
995 | good_bytes = (bad_lba - start_lba)*SCpnt->device->sector_size; | ||
996 | break; | 1048 | break; |
997 | case RECOVERED_ERROR: | 1049 | case RECOVERED_ERROR: |
998 | case NO_SENSE: | 1050 | case NO_SENSE: |
@@ -1002,10 +1054,23 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
1002 | scsi_print_sense("sd", SCpnt); | 1054 | scsi_print_sense("sd", SCpnt); |
1003 | SCpnt->result = 0; | 1055 | SCpnt->result = 0; |
1004 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | 1056 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); |
1005 | good_bytes = xfer_size; | 1057 | good_bytes = scsi_bufflen(SCpnt); |
1058 | break; | ||
1059 | case ABORTED_COMMAND: | ||
1060 | if (sshdr.asc == 0x10) { /* DIF: Disk detected corruption */ | ||
1061 | scsi_print_result(SCpnt); | ||
1062 | scsi_print_sense("sd", SCpnt); | ||
1063 | good_bytes = sd_completed_bytes(SCpnt); | ||
1064 | } | ||
1006 | break; | 1065 | break; |
1007 | case ILLEGAL_REQUEST: | 1066 | case ILLEGAL_REQUEST: |
1008 | if (SCpnt->device->use_10_for_rw && | 1067 | if (sshdr.asc == 0x10) { /* DIX: HBA detected corruption */ |
1068 | scsi_print_result(SCpnt); | ||
1069 | scsi_print_sense("sd", SCpnt); | ||
1070 | good_bytes = sd_completed_bytes(SCpnt); | ||
1071 | } | ||
1072 | if (!scsi_device_protection(SCpnt->device) && | ||
1073 | SCpnt->device->use_10_for_rw && | ||
1009 | (SCpnt->cmnd[0] == READ_10 || | 1074 | (SCpnt->cmnd[0] == READ_10 || |
1010 | SCpnt->cmnd[0] == WRITE_10)) | 1075 | SCpnt->cmnd[0] == WRITE_10)) |
1011 | SCpnt->device->use_10_for_rw = 0; | 1076 | SCpnt->device->use_10_for_rw = 0; |
@@ -1018,6 +1083,9 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
1018 | break; | 1083 | break; |
1019 | } | 1084 | } |
1020 | out: | 1085 | out: |
1086 | if (rq_data_dir(SCpnt->request) == READ && scsi_prot_sg_count(SCpnt)) | ||
1087 | sd_dif_complete(SCpnt, good_bytes); | ||
1088 | |||
1021 | return good_bytes; | 1089 | return good_bytes; |
1022 | } | 1090 | } |
1023 | 1091 | ||
@@ -1165,6 +1233,49 @@ sd_spinup_disk(struct scsi_disk *sdkp) | |||
1165 | } | 1233 | } |
1166 | } | 1234 | } |
1167 | 1235 | ||
1236 | |||
1237 | /* | ||
1238 | * Determine whether disk supports Data Integrity Field. | ||
1239 | */ | ||
1240 | void sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer) | ||
1241 | { | ||
1242 | struct scsi_device *sdp = sdkp->device; | ||
1243 | u8 type; | ||
1244 | |||
1245 | if (scsi_device_protection(sdp) == 0 || (buffer[12] & 1) == 0) | ||
1246 | type = 0; | ||
1247 | else | ||
1248 | type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */ | ||
1249 | |||
1250 | switch (type) { | ||
1251 | case SD_DIF_TYPE0_PROTECTION: | ||
1252 | sdkp->protection_type = 0; | ||
1253 | break; | ||
1254 | |||
1255 | case SD_DIF_TYPE1_PROTECTION: | ||
1256 | case SD_DIF_TYPE3_PROTECTION: | ||
1257 | sdkp->protection_type = type; | ||
1258 | break; | ||
1259 | |||
1260 | case SD_DIF_TYPE2_PROTECTION: | ||
1261 | sd_printk(KERN_ERR, sdkp, "formatted with DIF Type 2 " \ | ||
1262 | "protection which is currently unsupported. " \ | ||
1263 | "Disabling disk!\n"); | ||
1264 | goto disable; | ||
1265 | |||
1266 | default: | ||
1267 | sd_printk(KERN_ERR, sdkp, "formatted with unknown " \ | ||
1268 | "protection type %d. Disabling disk!\n", type); | ||
1269 | goto disable; | ||
1270 | } | ||
1271 | |||
1272 | return; | ||
1273 | |||
1274 | disable: | ||
1275 | sdkp->protection_type = 0; | ||
1276 | sdkp->capacity = 0; | ||
1277 | } | ||
1278 | |||
1168 | /* | 1279 | /* |
1169 | * read disk capacity | 1280 | * read disk capacity |
1170 | */ | 1281 | */ |
@@ -1174,7 +1285,8 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) | |||
1174 | unsigned char cmd[16]; | 1285 | unsigned char cmd[16]; |
1175 | int the_result, retries; | 1286 | int the_result, retries; |
1176 | int sector_size = 0; | 1287 | int sector_size = 0; |
1177 | int longrc = 0; | 1288 | /* Force READ CAPACITY(16) when PROTECT=1 */ |
1289 | int longrc = scsi_device_protection(sdkp->device) ? 1 : 0; | ||
1178 | struct scsi_sense_hdr sshdr; | 1290 | struct scsi_sense_hdr sshdr; |
1179 | int sense_valid = 0; | 1291 | int sense_valid = 0; |
1180 | struct scsi_device *sdp = sdkp->device; | 1292 | struct scsi_device *sdp = sdkp->device; |
@@ -1186,8 +1298,8 @@ repeat: | |||
1186 | memset((void *) cmd, 0, 16); | 1298 | memset((void *) cmd, 0, 16); |
1187 | cmd[0] = SERVICE_ACTION_IN; | 1299 | cmd[0] = SERVICE_ACTION_IN; |
1188 | cmd[1] = SAI_READ_CAPACITY_16; | 1300 | cmd[1] = SAI_READ_CAPACITY_16; |
1189 | cmd[13] = 12; | 1301 | cmd[13] = 13; |
1190 | memset((void *) buffer, 0, 12); | 1302 | memset((void *) buffer, 0, 13); |
1191 | } else { | 1303 | } else { |
1192 | cmd[0] = READ_CAPACITY; | 1304 | cmd[0] = READ_CAPACITY; |
1193 | memset((void *) &cmd[1], 0, 9); | 1305 | memset((void *) &cmd[1], 0, 9); |
@@ -1195,7 +1307,7 @@ repeat: | |||
1195 | } | 1307 | } |
1196 | 1308 | ||
1197 | the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE, | 1309 | the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE, |
1198 | buffer, longrc ? 12 : 8, &sshdr, | 1310 | buffer, longrc ? 13 : 8, &sshdr, |
1199 | SD_TIMEOUT, SD_MAX_RETRIES); | 1311 | SD_TIMEOUT, SD_MAX_RETRIES); |
1200 | 1312 | ||
1201 | if (media_not_present(sdkp, &sshdr)) | 1313 | if (media_not_present(sdkp, &sshdr)) |
@@ -1270,6 +1382,8 @@ repeat: | |||
1270 | 1382 | ||
1271 | sector_size = (buffer[8] << 24) | | 1383 | sector_size = (buffer[8] << 24) | |
1272 | (buffer[9] << 16) | (buffer[10] << 8) | buffer[11]; | 1384 | (buffer[9] << 16) | (buffer[10] << 8) | buffer[11]; |
1385 | |||
1386 | sd_read_protection_type(sdkp, buffer); | ||
1273 | } | 1387 | } |
1274 | 1388 | ||
1275 | /* Some devices return the total number of sectors, not the | 1389 | /* Some devices return the total number of sectors, not the |
@@ -1531,6 +1645,52 @@ defaults: | |||
1531 | sdkp->DPOFUA = 0; | 1645 | sdkp->DPOFUA = 0; |
1532 | } | 1646 | } |
1533 | 1647 | ||
1648 | /* | ||
1649 | * The ATO bit indicates whether the DIF application tag is available | ||
1650 | * for use by the operating system. | ||
1651 | */ | ||
1652 | void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer) | ||
1653 | { | ||
1654 | int res, offset; | ||
1655 | struct scsi_device *sdp = sdkp->device; | ||
1656 | struct scsi_mode_data data; | ||
1657 | struct scsi_sense_hdr sshdr; | ||
1658 | |||
1659 | if (sdp->type != TYPE_DISK) | ||
1660 | return; | ||
1661 | |||
1662 | if (sdkp->protection_type == 0) | ||
1663 | return; | ||
1664 | |||
1665 | res = scsi_mode_sense(sdp, 1, 0x0a, buffer, 36, SD_TIMEOUT, | ||
1666 | SD_MAX_RETRIES, &data, &sshdr); | ||
1667 | |||
1668 | if (!scsi_status_is_good(res) || !data.header_length || | ||
1669 | data.length < 6) { | ||
1670 | sd_printk(KERN_WARNING, sdkp, | ||
1671 | "getting Control mode page failed, assume no ATO\n"); | ||
1672 | |||
1673 | if (scsi_sense_valid(&sshdr)) | ||
1674 | sd_print_sense_hdr(sdkp, &sshdr); | ||
1675 | |||
1676 | return; | ||
1677 | } | ||
1678 | |||
1679 | offset = data.header_length + data.block_descriptor_length; | ||
1680 | |||
1681 | if ((buffer[offset] & 0x3f) != 0x0a) { | ||
1682 | sd_printk(KERN_ERR, sdkp, "ATO Got wrong page\n"); | ||
1683 | return; | ||
1684 | } | ||
1685 | |||
1686 | if ((buffer[offset + 5] & 0x80) == 0) | ||
1687 | return; | ||
1688 | |||
1689 | sdkp->ATO = 1; | ||
1690 | |||
1691 | return; | ||
1692 | } | ||
1693 | |||
1534 | /** | 1694 | /** |
1535 | * sd_revalidate_disk - called the first time a new disk is seen, | 1695 | * sd_revalidate_disk - called the first time a new disk is seen, |
1536 | * performs disk spin up, read_capacity, etc. | 1696 | * performs disk spin up, read_capacity, etc. |
@@ -1567,6 +1727,7 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
1567 | sdkp->write_prot = 0; | 1727 | sdkp->write_prot = 0; |
1568 | sdkp->WCE = 0; | 1728 | sdkp->WCE = 0; |
1569 | sdkp->RCD = 0; | 1729 | sdkp->RCD = 0; |
1730 | sdkp->ATO = 0; | ||
1570 | 1731 | ||
1571 | sd_spinup_disk(sdkp); | 1732 | sd_spinup_disk(sdkp); |
1572 | 1733 | ||
@@ -1578,6 +1739,7 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
1578 | sd_read_capacity(sdkp, buffer); | 1739 | sd_read_capacity(sdkp, buffer); |
1579 | sd_read_write_protect_flag(sdkp, buffer); | 1740 | sd_read_write_protect_flag(sdkp, buffer); |
1580 | sd_read_cache_type(sdkp, buffer); | 1741 | sd_read_cache_type(sdkp, buffer); |
1742 | sd_read_app_tag_own(sdkp, buffer); | ||
1581 | } | 1743 | } |
1582 | 1744 | ||
1583 | /* | 1745 | /* |
@@ -1643,18 +1805,20 @@ static int sd_probe(struct device *dev) | |||
1643 | if (!gd) | 1805 | if (!gd) |
1644 | goto out_free; | 1806 | goto out_free; |
1645 | 1807 | ||
1646 | if (!idr_pre_get(&sd_index_idr, GFP_KERNEL)) | 1808 | do { |
1647 | goto out_put; | 1809 | if (!ida_pre_get(&sd_index_ida, GFP_KERNEL)) |
1810 | goto out_put; | ||
1648 | 1811 | ||
1649 | spin_lock(&sd_index_lock); | 1812 | error = ida_get_new(&sd_index_ida, &index); |
1650 | error = idr_get_new(&sd_index_idr, NULL, &index); | 1813 | } while (error == -EAGAIN); |
1651 | spin_unlock(&sd_index_lock); | ||
1652 | 1814 | ||
1653 | if (index >= SD_MAX_DISKS) | ||
1654 | error = -EBUSY; | ||
1655 | if (error) | 1815 | if (error) |
1656 | goto out_put; | 1816 | goto out_put; |
1657 | 1817 | ||
1818 | error = -EBUSY; | ||
1819 | if (index >= SD_MAX_DISKS) | ||
1820 | goto out_free_index; | ||
1821 | |||
1658 | sdkp->device = sdp; | 1822 | sdkp->device = sdp; |
1659 | sdkp->driver = &sd_template; | 1823 | sdkp->driver = &sd_template; |
1660 | sdkp->disk = gd; | 1824 | sdkp->disk = gd; |
@@ -1675,7 +1839,7 @@ static int sd_probe(struct device *dev) | |||
1675 | strncpy(sdkp->dev.bus_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE); | 1839 | strncpy(sdkp->dev.bus_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE); |
1676 | 1840 | ||
1677 | if (device_add(&sdkp->dev)) | 1841 | if (device_add(&sdkp->dev)) |
1678 | goto out_put; | 1842 | goto out_free_index; |
1679 | 1843 | ||
1680 | get_device(&sdp->sdev_gendev); | 1844 | get_device(&sdp->sdev_gendev); |
1681 | 1845 | ||
@@ -1711,12 +1875,15 @@ static int sd_probe(struct device *dev) | |||
1711 | 1875 | ||
1712 | dev_set_drvdata(dev, sdkp); | 1876 | dev_set_drvdata(dev, sdkp); |
1713 | add_disk(gd); | 1877 | add_disk(gd); |
1878 | sd_dif_config_host(sdkp); | ||
1714 | 1879 | ||
1715 | sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", | 1880 | sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", |
1716 | sdp->removable ? "removable " : ""); | 1881 | sdp->removable ? "removable " : ""); |
1717 | 1882 | ||
1718 | return 0; | 1883 | return 0; |
1719 | 1884 | ||
1885 | out_free_index: | ||
1886 | ida_remove(&sd_index_ida, index); | ||
1720 | out_put: | 1887 | out_put: |
1721 | put_disk(gd); | 1888 | put_disk(gd); |
1722 | out_free: | 1889 | out_free: |
@@ -1766,9 +1933,7 @@ static void scsi_disk_release(struct device *dev) | |||
1766 | struct scsi_disk *sdkp = to_scsi_disk(dev); | 1933 | struct scsi_disk *sdkp = to_scsi_disk(dev); |
1767 | struct gendisk *disk = sdkp->disk; | 1934 | struct gendisk *disk = sdkp->disk; |
1768 | 1935 | ||
1769 | spin_lock(&sd_index_lock); | 1936 | ida_remove(&sd_index_ida, sdkp->index); |
1770 | idr_remove(&sd_index_idr, sdkp->index); | ||
1771 | spin_unlock(&sd_index_lock); | ||
1772 | 1937 | ||
1773 | disk->private_data = NULL; | 1938 | disk->private_data = NULL; |
1774 | put_disk(disk); | 1939 | put_disk(disk); |
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 03a3d45cfa42..95b9f06534d5 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h | |||
@@ -31,6 +31,12 @@ | |||
31 | */ | 31 | */ |
32 | #define SD_BUF_SIZE 512 | 32 | #define SD_BUF_SIZE 512 |
33 | 33 | ||
34 | /* | ||
35 | * Number of sectors at the end of the device to avoid multi-sector | ||
36 | * accesses to in the case of last_sector_bug | ||
37 | */ | ||
38 | #define SD_LAST_BUGGY_SECTORS 8 | ||
39 | |||
34 | struct scsi_disk { | 40 | struct scsi_disk { |
35 | struct scsi_driver *driver; /* always &sd_template */ | 41 | struct scsi_driver *driver; /* always &sd_template */ |
36 | struct scsi_device *device; | 42 | struct scsi_device *device; |
@@ -41,7 +47,9 @@ struct scsi_disk { | |||
41 | u32 index; | 47 | u32 index; |
42 | u8 media_present; | 48 | u8 media_present; |
43 | u8 write_prot; | 49 | u8 write_prot; |
50 | u8 protection_type;/* Data Integrity Field */ | ||
44 | unsigned previous_state : 1; | 51 | unsigned previous_state : 1; |
52 | unsigned ATO : 1; /* state of disk ATO bit */ | ||
45 | unsigned WCE : 1; /* state of disk WCE bit */ | 53 | unsigned WCE : 1; /* state of disk WCE bit */ |
46 | unsigned RCD : 1; /* state of disk RCD bit, unused */ | 54 | unsigned RCD : 1; /* state of disk RCD bit, unused */ |
47 | unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ | 55 | unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ |
@@ -59,4 +67,50 @@ static inline struct scsi_disk *scsi_disk(struct gendisk *disk) | |||
59 | (sdsk)->disk->disk_name, ##a) : \ | 67 | (sdsk)->disk->disk_name, ##a) : \ |
60 | sdev_printk(prefix, (sdsk)->device, fmt, ##a) | 68 | sdev_printk(prefix, (sdsk)->device, fmt, ##a) |
61 | 69 | ||
70 | /* | ||
71 | * A DIF-capable target device can be formatted with different | ||
72 | * protection schemes. Currently 0 through 3 are defined: | ||
73 | * | ||
74 | * Type 0 is regular (unprotected) I/O | ||
75 | * | ||
76 | * Type 1 defines the contents of the guard and reference tags | ||
77 | * | ||
78 | * Type 2 defines the contents of the guard and reference tags and | ||
79 | * uses 32-byte commands to seed the latter | ||
80 | * | ||
81 | * Type 3 defines the contents of the guard tag only | ||
82 | */ | ||
83 | |||
84 | enum sd_dif_target_protection_types { | ||
85 | SD_DIF_TYPE0_PROTECTION = 0x0, | ||
86 | SD_DIF_TYPE1_PROTECTION = 0x1, | ||
87 | SD_DIF_TYPE2_PROTECTION = 0x2, | ||
88 | SD_DIF_TYPE3_PROTECTION = 0x3, | ||
89 | }; | ||
90 | |||
91 | /* | ||
92 | * Data Integrity Field tuple. | ||
93 | */ | ||
94 | struct sd_dif_tuple { | ||
95 | __be16 guard_tag; /* Checksum */ | ||
96 | __be16 app_tag; /* Opaque storage */ | ||
97 | __be32 ref_tag; /* Target LBA or indirect LBA */ | ||
98 | }; | ||
99 | |||
100 | #if defined(CONFIG_BLK_DEV_INTEGRITY) | ||
101 | |||
102 | extern void sd_dif_op(struct scsi_cmnd *, unsigned int, unsigned int); | ||
103 | extern void sd_dif_config_host(struct scsi_disk *); | ||
104 | extern int sd_dif_prepare(struct request *rq, sector_t, unsigned int); | ||
105 | extern void sd_dif_complete(struct scsi_cmnd *, unsigned int); | ||
106 | |||
107 | #else /* CONFIG_BLK_DEV_INTEGRITY */ | ||
108 | |||
109 | #define sd_dif_op(a, b, c) do { } while (0) | ||
110 | #define sd_dif_config_host(a) do { } while (0) | ||
111 | #define sd_dif_prepare(a, b, c) (0) | ||
112 | #define sd_dif_complete(a, b) (0) | ||
113 | |||
114 | #endif /* CONFIG_BLK_DEV_INTEGRITY */ | ||
115 | |||
62 | #endif /* _SCSI_DISK_H */ | 116 | #endif /* _SCSI_DISK_H */ |
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c new file mode 100644 index 000000000000..4d17f3d35aac --- /dev/null +++ b/drivers/scsi/sd_dif.c | |||
@@ -0,0 +1,538 @@ | |||
1 | /* | ||
2 | * sd_dif.c - SCSI Data Integrity Field | ||
3 | * | ||
4 | * Copyright (C) 2007, 2008 Oracle Corporation | ||
5 | * Written by: Martin K. Petersen <martin.petersen@oracle.com> | ||
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 version | ||
9 | * 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; see the file COPYING. If not, write to | ||
18 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, | ||
19 | * USA. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/blkdev.h> | ||
24 | #include <linux/crc-t10dif.h> | ||
25 | |||
26 | #include <scsi/scsi.h> | ||
27 | #include <scsi/scsi_cmnd.h> | ||
28 | #include <scsi/scsi_dbg.h> | ||
29 | #include <scsi/scsi_device.h> | ||
30 | #include <scsi/scsi_driver.h> | ||
31 | #include <scsi/scsi_eh.h> | ||
32 | #include <scsi/scsi_host.h> | ||
33 | #include <scsi/scsi_ioctl.h> | ||
34 | #include <scsi/scsicam.h> | ||
35 | |||
36 | #include <net/checksum.h> | ||
37 | |||
38 | #include "sd.h" | ||
39 | |||
40 | typedef __u16 (csum_fn) (void *, unsigned int); | ||
41 | |||
42 | static __u16 sd_dif_crc_fn(void *data, unsigned int len) | ||
43 | { | ||
44 | return cpu_to_be16(crc_t10dif(data, len)); | ||
45 | } | ||
46 | |||
47 | static __u16 sd_dif_ip_fn(void *data, unsigned int len) | ||
48 | { | ||
49 | return ip_compute_csum(data, len); | ||
50 | } | ||
51 | |||
52 | /* | ||
53 | * Type 1 and Type 2 protection use the same format: 16 bit guard tag, | ||
54 | * 16 bit app tag, 32 bit reference tag. | ||
55 | */ | ||
56 | static void sd_dif_type1_generate(struct blk_integrity_exchg *bix, csum_fn *fn) | ||
57 | { | ||
58 | void *buf = bix->data_buf; | ||
59 | struct sd_dif_tuple *sdt = bix->prot_buf; | ||
60 | sector_t sector = bix->sector; | ||
61 | unsigned int i; | ||
62 | |||
63 | for (i = 0 ; i < bix->data_size ; i += bix->sector_size, sdt++) { | ||
64 | sdt->guard_tag = fn(buf, bix->sector_size); | ||
65 | sdt->ref_tag = cpu_to_be32(sector & 0xffffffff); | ||
66 | sdt->app_tag = 0; | ||
67 | |||
68 | buf += bix->sector_size; | ||
69 | sector++; | ||
70 | } | ||
71 | } | ||
72 | |||
73 | static void sd_dif_type1_generate_crc(struct blk_integrity_exchg *bix) | ||
74 | { | ||
75 | sd_dif_type1_generate(bix, sd_dif_crc_fn); | ||
76 | } | ||
77 | |||
78 | static void sd_dif_type1_generate_ip(struct blk_integrity_exchg *bix) | ||
79 | { | ||
80 | sd_dif_type1_generate(bix, sd_dif_ip_fn); | ||
81 | } | ||
82 | |||
83 | static int sd_dif_type1_verify(struct blk_integrity_exchg *bix, csum_fn *fn) | ||
84 | { | ||
85 | void *buf = bix->data_buf; | ||
86 | struct sd_dif_tuple *sdt = bix->prot_buf; | ||
87 | sector_t sector = bix->sector; | ||
88 | unsigned int i; | ||
89 | __u16 csum; | ||
90 | |||
91 | for (i = 0 ; i < bix->data_size ; i += bix->sector_size, sdt++) { | ||
92 | /* Unwritten sectors */ | ||
93 | if (sdt->app_tag == 0xffff) | ||
94 | return 0; | ||
95 | |||
96 | /* Bad ref tag received from disk */ | ||
97 | if (sdt->ref_tag == 0xffffffff) { | ||
98 | printk(KERN_ERR | ||
99 | "%s: bad phys ref tag on sector %lu\n", | ||
100 | bix->disk_name, (unsigned long)sector); | ||
101 | return -EIO; | ||
102 | } | ||
103 | |||
104 | if (be32_to_cpu(sdt->ref_tag) != (sector & 0xffffffff)) { | ||
105 | printk(KERN_ERR | ||
106 | "%s: ref tag error on sector %lu (rcvd %u)\n", | ||
107 | bix->disk_name, (unsigned long)sector, | ||
108 | be32_to_cpu(sdt->ref_tag)); | ||
109 | return -EIO; | ||
110 | } | ||
111 | |||
112 | csum = fn(buf, bix->sector_size); | ||
113 | |||
114 | if (sdt->guard_tag != csum) { | ||
115 | printk(KERN_ERR "%s: guard tag error on sector %lu " \ | ||
116 | "(rcvd %04x, data %04x)\n", bix->disk_name, | ||
117 | (unsigned long)sector, | ||
118 | be16_to_cpu(sdt->guard_tag), be16_to_cpu(csum)); | ||
119 | return -EIO; | ||
120 | } | ||
121 | |||
122 | buf += bix->sector_size; | ||
123 | sector++; | ||
124 | } | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int sd_dif_type1_verify_crc(struct blk_integrity_exchg *bix) | ||
130 | { | ||
131 | return sd_dif_type1_verify(bix, sd_dif_crc_fn); | ||
132 | } | ||
133 | |||
134 | static int sd_dif_type1_verify_ip(struct blk_integrity_exchg *bix) | ||
135 | { | ||
136 | return sd_dif_type1_verify(bix, sd_dif_ip_fn); | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | * Functions for interleaving and deinterleaving application tags | ||
141 | */ | ||
142 | static void sd_dif_type1_set_tag(void *prot, void *tag_buf, unsigned int sectors) | ||
143 | { | ||
144 | struct sd_dif_tuple *sdt = prot; | ||
145 | char *tag = tag_buf; | ||
146 | unsigned int i, j; | ||
147 | |||
148 | for (i = 0, j = 0 ; i < sectors ; i++, j += 2, sdt++) { | ||
149 | sdt->app_tag = tag[j] << 8 | tag[j+1]; | ||
150 | BUG_ON(sdt->app_tag == 0xffff); | ||
151 | } | ||
152 | } | ||
153 | |||
154 | static void sd_dif_type1_get_tag(void *prot, void *tag_buf, unsigned int sectors) | ||
155 | { | ||
156 | struct sd_dif_tuple *sdt = prot; | ||
157 | char *tag = tag_buf; | ||
158 | unsigned int i, j; | ||
159 | |||
160 | for (i = 0, j = 0 ; i < sectors ; i++, j += 2, sdt++) { | ||
161 | tag[j] = (sdt->app_tag & 0xff00) >> 8; | ||
162 | tag[j+1] = sdt->app_tag & 0xff; | ||
163 | } | ||
164 | } | ||
165 | |||
166 | static struct blk_integrity dif_type1_integrity_crc = { | ||
167 | .name = "T10-DIF-TYPE1-CRC", | ||
168 | .generate_fn = sd_dif_type1_generate_crc, | ||
169 | .verify_fn = sd_dif_type1_verify_crc, | ||
170 | .get_tag_fn = sd_dif_type1_get_tag, | ||
171 | .set_tag_fn = sd_dif_type1_set_tag, | ||
172 | .tuple_size = sizeof(struct sd_dif_tuple), | ||
173 | .tag_size = 0, | ||
174 | }; | ||
175 | |||
176 | static struct blk_integrity dif_type1_integrity_ip = { | ||
177 | .name = "T10-DIF-TYPE1-IP", | ||
178 | .generate_fn = sd_dif_type1_generate_ip, | ||
179 | .verify_fn = sd_dif_type1_verify_ip, | ||
180 | .get_tag_fn = sd_dif_type1_get_tag, | ||
181 | .set_tag_fn = sd_dif_type1_set_tag, | ||
182 | .tuple_size = sizeof(struct sd_dif_tuple), | ||
183 | .tag_size = 0, | ||
184 | }; | ||
185 | |||
186 | |||
187 | /* | ||
188 | * Type 3 protection has a 16-bit guard tag and 16 + 32 bits of opaque | ||
189 | * tag space. | ||
190 | */ | ||
191 | static void sd_dif_type3_generate(struct blk_integrity_exchg *bix, csum_fn *fn) | ||
192 | { | ||
193 | void *buf = bix->data_buf; | ||
194 | struct sd_dif_tuple *sdt = bix->prot_buf; | ||
195 | unsigned int i; | ||
196 | |||
197 | for (i = 0 ; i < bix->data_size ; i += bix->sector_size, sdt++) { | ||
198 | sdt->guard_tag = fn(buf, bix->sector_size); | ||
199 | sdt->ref_tag = 0; | ||
200 | sdt->app_tag = 0; | ||
201 | |||
202 | buf += bix->sector_size; | ||
203 | } | ||
204 | } | ||
205 | |||
206 | static void sd_dif_type3_generate_crc(struct blk_integrity_exchg *bix) | ||
207 | { | ||
208 | sd_dif_type3_generate(bix, sd_dif_crc_fn); | ||
209 | } | ||
210 | |||
211 | static void sd_dif_type3_generate_ip(struct blk_integrity_exchg *bix) | ||
212 | { | ||
213 | sd_dif_type3_generate(bix, sd_dif_ip_fn); | ||
214 | } | ||
215 | |||
216 | static int sd_dif_type3_verify(struct blk_integrity_exchg *bix, csum_fn *fn) | ||
217 | { | ||
218 | void *buf = bix->data_buf; | ||
219 | struct sd_dif_tuple *sdt = bix->prot_buf; | ||
220 | sector_t sector = bix->sector; | ||
221 | unsigned int i; | ||
222 | __u16 csum; | ||
223 | |||
224 | for (i = 0 ; i < bix->data_size ; i += bix->sector_size, sdt++) { | ||
225 | /* Unwritten sectors */ | ||
226 | if (sdt->app_tag == 0xffff && sdt->ref_tag == 0xffffffff) | ||
227 | return 0; | ||
228 | |||
229 | csum = fn(buf, bix->sector_size); | ||
230 | |||
231 | if (sdt->guard_tag != csum) { | ||
232 | printk(KERN_ERR "%s: guard tag error on sector %lu " \ | ||
233 | "(rcvd %04x, data %04x)\n", bix->disk_name, | ||
234 | (unsigned long)sector, | ||
235 | be16_to_cpu(sdt->guard_tag), be16_to_cpu(csum)); | ||
236 | return -EIO; | ||
237 | } | ||
238 | |||
239 | buf += bix->sector_size; | ||
240 | sector++; | ||
241 | } | ||
242 | |||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static int sd_dif_type3_verify_crc(struct blk_integrity_exchg *bix) | ||
247 | { | ||
248 | return sd_dif_type3_verify(bix, sd_dif_crc_fn); | ||
249 | } | ||
250 | |||
251 | static int sd_dif_type3_verify_ip(struct blk_integrity_exchg *bix) | ||
252 | { | ||
253 | return sd_dif_type3_verify(bix, sd_dif_ip_fn); | ||
254 | } | ||
255 | |||
256 | static void sd_dif_type3_set_tag(void *prot, void *tag_buf, unsigned int sectors) | ||
257 | { | ||
258 | struct sd_dif_tuple *sdt = prot; | ||
259 | char *tag = tag_buf; | ||
260 | unsigned int i, j; | ||
261 | |||
262 | for (i = 0, j = 0 ; i < sectors ; i++, j += 6, sdt++) { | ||
263 | sdt->app_tag = tag[j] << 8 | tag[j+1]; | ||
264 | sdt->ref_tag = tag[j+2] << 24 | tag[j+3] << 16 | | ||
265 | tag[j+4] << 8 | tag[j+5]; | ||
266 | } | ||
267 | } | ||
268 | |||
269 | static void sd_dif_type3_get_tag(void *prot, void *tag_buf, unsigned int sectors) | ||
270 | { | ||
271 | struct sd_dif_tuple *sdt = prot; | ||
272 | char *tag = tag_buf; | ||
273 | unsigned int i, j; | ||
274 | |||
275 | for (i = 0, j = 0 ; i < sectors ; i++, j += 2, sdt++) { | ||
276 | tag[j] = (sdt->app_tag & 0xff00) >> 8; | ||
277 | tag[j+1] = sdt->app_tag & 0xff; | ||
278 | tag[j+2] = (sdt->ref_tag & 0xff000000) >> 24; | ||
279 | tag[j+3] = (sdt->ref_tag & 0xff0000) >> 16; | ||
280 | tag[j+4] = (sdt->ref_tag & 0xff00) >> 8; | ||
281 | tag[j+5] = sdt->ref_tag & 0xff; | ||
282 | BUG_ON(sdt->app_tag == 0xffff || sdt->ref_tag == 0xffffffff); | ||
283 | } | ||
284 | } | ||
285 | |||
286 | static struct blk_integrity dif_type3_integrity_crc = { | ||
287 | .name = "T10-DIF-TYPE3-CRC", | ||
288 | .generate_fn = sd_dif_type3_generate_crc, | ||
289 | .verify_fn = sd_dif_type3_verify_crc, | ||
290 | .get_tag_fn = sd_dif_type3_get_tag, | ||
291 | .set_tag_fn = sd_dif_type3_set_tag, | ||
292 | .tuple_size = sizeof(struct sd_dif_tuple), | ||
293 | .tag_size = 0, | ||
294 | }; | ||
295 | |||
296 | static struct blk_integrity dif_type3_integrity_ip = { | ||
297 | .name = "T10-DIF-TYPE3-IP", | ||
298 | .generate_fn = sd_dif_type3_generate_ip, | ||
299 | .verify_fn = sd_dif_type3_verify_ip, | ||
300 | .get_tag_fn = sd_dif_type3_get_tag, | ||
301 | .set_tag_fn = sd_dif_type3_set_tag, | ||
302 | .tuple_size = sizeof(struct sd_dif_tuple), | ||
303 | .tag_size = 0, | ||
304 | }; | ||
305 | |||
306 | /* | ||
307 | * Configure exchange of protection information between OS and HBA. | ||
308 | */ | ||
309 | void sd_dif_config_host(struct scsi_disk *sdkp) | ||
310 | { | ||
311 | struct scsi_device *sdp = sdkp->device; | ||
312 | struct gendisk *disk = sdkp->disk; | ||
313 | u8 type = sdkp->protection_type; | ||
314 | |||
315 | /* If this HBA doesn't support DIX, resort to normal I/O or DIF */ | ||
316 | if (scsi_host_dix_capable(sdp->host, type) == 0) { | ||
317 | |||
318 | if (type == SD_DIF_TYPE0_PROTECTION) | ||
319 | return; | ||
320 | |||
321 | if (scsi_host_dif_capable(sdp->host, type) == 0) { | ||
322 | sd_printk(KERN_INFO, sdkp, "Type %d protection " \ | ||
323 | "unsupported by HBA. Disabling DIF.\n", type); | ||
324 | sdkp->protection_type = 0; | ||
325 | return; | ||
326 | } | ||
327 | |||
328 | sd_printk(KERN_INFO, sdkp, "Enabling DIF Type %d protection\n", | ||
329 | type); | ||
330 | |||
331 | return; | ||
332 | } | ||
333 | |||
334 | /* Enable DMA of protection information */ | ||
335 | if (scsi_host_get_guard(sdkp->device->host) & SHOST_DIX_GUARD_IP) | ||
336 | if (type == SD_DIF_TYPE3_PROTECTION) | ||
337 | blk_integrity_register(disk, &dif_type3_integrity_ip); | ||
338 | else | ||
339 | blk_integrity_register(disk, &dif_type1_integrity_ip); | ||
340 | else | ||
341 | if (type == SD_DIF_TYPE3_PROTECTION) | ||
342 | blk_integrity_register(disk, &dif_type3_integrity_crc); | ||
343 | else | ||
344 | blk_integrity_register(disk, &dif_type1_integrity_crc); | ||
345 | |||
346 | sd_printk(KERN_INFO, sdkp, | ||
347 | "Enabling %s integrity protection\n", disk->integrity->name); | ||
348 | |||
349 | /* Signal to block layer that we support sector tagging */ | ||
350 | if (type && sdkp->ATO) { | ||
351 | if (type == SD_DIF_TYPE3_PROTECTION) | ||
352 | disk->integrity->tag_size = sizeof(u16) + sizeof(u32); | ||
353 | else | ||
354 | disk->integrity->tag_size = sizeof(u16); | ||
355 | |||
356 | sd_printk(KERN_INFO, sdkp, "DIF application tag size %u\n", | ||
357 | disk->integrity->tag_size); | ||
358 | } | ||
359 | } | ||
360 | |||
361 | /* | ||
362 | * DIF DMA operation magic decoder ring. | ||
363 | */ | ||
364 | void sd_dif_op(struct scsi_cmnd *scmd, unsigned int dif, unsigned int dix) | ||
365 | { | ||
366 | int csum_convert, prot_op; | ||
367 | |||
368 | prot_op = 0; | ||
369 | |||
370 | /* Convert checksum? */ | ||
371 | if (scsi_host_get_guard(scmd->device->host) != SHOST_DIX_GUARD_CRC) | ||
372 | csum_convert = 1; | ||
373 | else | ||
374 | csum_convert = 0; | ||
375 | |||
376 | switch (scmd->cmnd[0]) { | ||
377 | case READ_10: | ||
378 | case READ_12: | ||
379 | case READ_16: | ||
380 | if (dif && dix) | ||
381 | if (csum_convert) | ||
382 | prot_op = SCSI_PROT_READ_CONVERT; | ||
383 | else | ||
384 | prot_op = SCSI_PROT_READ_PASS; | ||
385 | else if (dif && !dix) | ||
386 | prot_op = SCSI_PROT_READ_STRIP; | ||
387 | else if (!dif && dix) | ||
388 | prot_op = SCSI_PROT_READ_INSERT; | ||
389 | |||
390 | break; | ||
391 | |||
392 | case WRITE_10: | ||
393 | case WRITE_12: | ||
394 | case WRITE_16: | ||
395 | if (dif && dix) | ||
396 | if (csum_convert) | ||
397 | prot_op = SCSI_PROT_WRITE_CONVERT; | ||
398 | else | ||
399 | prot_op = SCSI_PROT_WRITE_PASS; | ||
400 | else if (dif && !dix) | ||
401 | prot_op = SCSI_PROT_WRITE_INSERT; | ||
402 | else if (!dif && dix) | ||
403 | prot_op = SCSI_PROT_WRITE_STRIP; | ||
404 | |||
405 | break; | ||
406 | } | ||
407 | |||
408 | scsi_set_prot_op(scmd, prot_op); | ||
409 | scsi_set_prot_type(scmd, dif); | ||
410 | } | ||
411 | |||
412 | /* | ||
413 | * The virtual start sector is the one that was originally submitted | ||
414 | * by the block layer. Due to partitioning, MD/DM cloning, etc. the | ||
415 | * actual physical start sector is likely to be different. Remap | ||
416 | * protection information to match the physical LBA. | ||
417 | * | ||
418 | * From a protocol perspective there's a slight difference between | ||
419 | * Type 1 and 2. The latter uses 32-byte CDBs exclusively, and the | ||
420 | * reference tag is seeded in the CDB. This gives us the potential to | ||
421 | * avoid virt->phys remapping during write. However, at read time we | ||
422 | * don't know whether the virt sector is the same as when we wrote it | ||
423 | * (we could be reading from real disk as opposed to MD/DM device. So | ||
424 | * we always remap Type 2 making it identical to Type 1. | ||
425 | * | ||
426 | * Type 3 does not have a reference tag so no remapping is required. | ||
427 | */ | ||
428 | int sd_dif_prepare(struct request *rq, sector_t hw_sector, unsigned int sector_sz) | ||
429 | { | ||
430 | const int tuple_sz = sizeof(struct sd_dif_tuple); | ||
431 | struct bio *bio; | ||
432 | struct scsi_disk *sdkp; | ||
433 | struct sd_dif_tuple *sdt; | ||
434 | unsigned int i, j; | ||
435 | u32 phys, virt; | ||
436 | |||
437 | /* Already remapped? */ | ||
438 | if (rq->cmd_flags & REQ_INTEGRITY) | ||
439 | return 0; | ||
440 | |||
441 | sdkp = rq->bio->bi_bdev->bd_disk->private_data; | ||
442 | |||
443 | if (sdkp->protection_type == SD_DIF_TYPE3_PROTECTION) | ||
444 | return 0; | ||
445 | |||
446 | rq->cmd_flags |= REQ_INTEGRITY; | ||
447 | phys = hw_sector & 0xffffffff; | ||
448 | |||
449 | __rq_for_each_bio(bio, rq) { | ||
450 | struct bio_vec *iv; | ||
451 | |||
452 | virt = bio->bi_integrity->bip_sector & 0xffffffff; | ||
453 | |||
454 | bip_for_each_vec(iv, bio->bi_integrity, i) { | ||
455 | sdt = kmap_atomic(iv->bv_page, KM_USER0) | ||
456 | + iv->bv_offset; | ||
457 | |||
458 | for (j = 0 ; j < iv->bv_len ; j += tuple_sz, sdt++) { | ||
459 | |||
460 | if (be32_to_cpu(sdt->ref_tag) != virt) | ||
461 | goto error; | ||
462 | |||
463 | sdt->ref_tag = cpu_to_be32(phys); | ||
464 | virt++; | ||
465 | phys++; | ||
466 | } | ||
467 | |||
468 | kunmap_atomic(sdt, KM_USER0); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | return 0; | ||
473 | |||
474 | error: | ||
475 | kunmap_atomic(sdt, KM_USER0); | ||
476 | sd_printk(KERN_ERR, sdkp, "%s: virt %u, phys %u, ref %u\n", | ||
477 | __func__, virt, phys, be32_to_cpu(sdt->ref_tag)); | ||
478 | |||
479 | return -EIO; | ||
480 | } | ||
481 | |||
482 | /* | ||
483 | * Remap physical sector values in the reference tag to the virtual | ||
484 | * values expected by the block layer. | ||
485 | */ | ||
486 | void sd_dif_complete(struct scsi_cmnd *scmd, unsigned int good_bytes) | ||
487 | { | ||
488 | const int tuple_sz = sizeof(struct sd_dif_tuple); | ||
489 | struct scsi_disk *sdkp; | ||
490 | struct bio *bio; | ||
491 | struct sd_dif_tuple *sdt; | ||
492 | unsigned int i, j, sectors, sector_sz; | ||
493 | u32 phys, virt; | ||
494 | |||
495 | sdkp = scsi_disk(scmd->request->rq_disk); | ||
496 | |||
497 | if (sdkp->protection_type == SD_DIF_TYPE3_PROTECTION || good_bytes == 0) | ||
498 | return; | ||
499 | |||
500 | sector_sz = scmd->device->sector_size; | ||
501 | sectors = good_bytes / sector_sz; | ||
502 | |||
503 | phys = scmd->request->sector & 0xffffffff; | ||
504 | if (sector_sz == 4096) | ||
505 | phys >>= 3; | ||
506 | |||
507 | __rq_for_each_bio(bio, scmd->request) { | ||
508 | struct bio_vec *iv; | ||
509 | |||
510 | virt = bio->bi_integrity->bip_sector & 0xffffffff; | ||
511 | |||
512 | bip_for_each_vec(iv, bio->bi_integrity, i) { | ||
513 | sdt = kmap_atomic(iv->bv_page, KM_USER0) | ||
514 | + iv->bv_offset; | ||
515 | |||
516 | for (j = 0 ; j < iv->bv_len ; j += tuple_sz, sdt++) { | ||
517 | |||
518 | if (sectors == 0) { | ||
519 | kunmap_atomic(sdt, KM_USER0); | ||
520 | return; | ||
521 | } | ||
522 | |||
523 | if (be32_to_cpu(sdt->ref_tag) != phys && | ||
524 | sdt->app_tag != 0xffff) | ||
525 | sdt->ref_tag = 0xffffffff; /* Bad ref */ | ||
526 | else | ||
527 | sdt->ref_tag = cpu_to_be32(virt); | ||
528 | |||
529 | virt++; | ||
530 | phys++; | ||
531 | sectors--; | ||
532 | } | ||
533 | |||
534 | kunmap_atomic(sdt, KM_USER0); | ||
535 | } | ||
536 | } | ||
537 | } | ||
538 | |||
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 4684cc716aa4..c2bb53e3d941 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -17,7 +17,7 @@ | |||
17 | Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support | 17 | Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support |
18 | */ | 18 | */ |
19 | 19 | ||
20 | static const char *verstr = "20080224"; | 20 | static const char *verstr = "20080504"; |
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | 23 | ||
@@ -631,7 +631,7 @@ static int cross_eof(struct scsi_tape * STp, int forward) | |||
631 | /* Flush the write buffer (never need to write if variable blocksize). */ | 631 | /* Flush the write buffer (never need to write if variable blocksize). */ |
632 | static int st_flush_write_buffer(struct scsi_tape * STp) | 632 | static int st_flush_write_buffer(struct scsi_tape * STp) |
633 | { | 633 | { |
634 | int offset, transfer, blks; | 634 | int transfer, blks; |
635 | int result; | 635 | int result; |
636 | unsigned char cmd[MAX_COMMAND_SIZE]; | 636 | unsigned char cmd[MAX_COMMAND_SIZE]; |
637 | struct st_request *SRpnt; | 637 | struct st_request *SRpnt; |
@@ -644,14 +644,10 @@ static int st_flush_write_buffer(struct scsi_tape * STp) | |||
644 | result = 0; | 644 | result = 0; |
645 | if (STp->dirty == 1) { | 645 | if (STp->dirty == 1) { |
646 | 646 | ||
647 | offset = (STp->buffer)->buffer_bytes; | 647 | transfer = STp->buffer->buffer_bytes; |
648 | transfer = ((offset + STp->block_size - 1) / | ||
649 | STp->block_size) * STp->block_size; | ||
650 | DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n", | 648 | DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n", |
651 | tape_name(STp), transfer)); | 649 | tape_name(STp), transfer)); |
652 | 650 | ||
653 | memset((STp->buffer)->b_data + offset, 0, transfer - offset); | ||
654 | |||
655 | memset(cmd, 0, MAX_COMMAND_SIZE); | 651 | memset(cmd, 0, MAX_COMMAND_SIZE); |
656 | cmd[0] = WRITE_6; | 652 | cmd[0] = WRITE_6; |
657 | cmd[1] = 1; | 653 | cmd[1] = 1; |
@@ -1670,6 +1666,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) | |||
1670 | if (undone <= do_count) { | 1666 | if (undone <= do_count) { |
1671 | /* Only data from this write is not written */ | 1667 | /* Only data from this write is not written */ |
1672 | count += undone; | 1668 | count += undone; |
1669 | b_point -= undone; | ||
1673 | do_count -= undone; | 1670 | do_count -= undone; |
1674 | if (STp->block_size) | 1671 | if (STp->block_size) |
1675 | blks = (transfer - undone) / STp->block_size; | 1672 | blks = (transfer - undone) / STp->block_size; |
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index f308a0308829..3790906a77d1 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c | |||
@@ -467,7 +467,7 @@ stex_slave_alloc(struct scsi_device *sdev) | |||
467 | /* Cheat: usually extracted from Inquiry data */ | 467 | /* Cheat: usually extracted from Inquiry data */ |
468 | sdev->tagged_supported = 1; | 468 | sdev->tagged_supported = 1; |
469 | 469 | ||
470 | scsi_activate_tcq(sdev, sdev->host->can_queue); | 470 | scsi_activate_tcq(sdev, ST_CMD_PER_LUN); |
471 | 471 | ||
472 | return 0; | 472 | return 0; |
473 | } | 473 | } |
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c index 22a6aae78699..98df1651404f 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c | |||
@@ -5741,6 +5741,8 @@ void sym_hcb_free(struct sym_hcb *np) | |||
5741 | 5741 | ||
5742 | for (target = 0; target < SYM_CONF_MAX_TARGET ; target++) { | 5742 | for (target = 0; target < SYM_CONF_MAX_TARGET ; target++) { |
5743 | tp = &np->target[target]; | 5743 | tp = &np->target[target]; |
5744 | if (tp->luntbl) | ||
5745 | sym_mfree_dma(tp->luntbl, 256, "LUNTBL"); | ||
5744 | #if SYM_CONF_MAX_LUN > 1 | 5746 | #if SYM_CONF_MAX_LUN > 1 |
5745 | kfree(tp->lunmp); | 5747 | kfree(tp->lunmp); |
5746 | #endif | 5748 | #endif |
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c index 5b04ddfed26c..1723d71cbf3f 100644 --- a/drivers/scsi/tmscsim.c +++ b/drivers/scsi/tmscsim.c | |||
@@ -452,7 +452,7 @@ static int dc390_pci_map (struct dc390_srb* pSRB) | |||
452 | /* TODO: error handling */ | 452 | /* TODO: error handling */ |
453 | if (pSRB->SGcount != 1) | 453 | if (pSRB->SGcount != 1) |
454 | error = 1; | 454 | error = 1; |
455 | DEBUG1(printk("%s(): Mapped sense buffer %p at %x\n", __FUNCTION__, pcmd->sense_buffer, cmdp->saved_dma_handle)); | 455 | DEBUG1(printk("%s(): Mapped sense buffer %p at %x\n", __func__, pcmd->sense_buffer, cmdp->saved_dma_handle)); |
456 | /* Map SG list */ | 456 | /* Map SG list */ |
457 | } else if (scsi_sg_count(pcmd)) { | 457 | } else if (scsi_sg_count(pcmd)) { |
458 | int nseg; | 458 | int nseg; |
@@ -466,7 +466,7 @@ static int dc390_pci_map (struct dc390_srb* pSRB) | |||
466 | if (nseg < 0) | 466 | if (nseg < 0) |
467 | error = 1; | 467 | error = 1; |
468 | DEBUG1(printk("%s(): Mapped SG %p with %d (%d) elements\n",\ | 468 | DEBUG1(printk("%s(): Mapped SG %p with %d (%d) elements\n",\ |
469 | __FUNCTION__, scsi_sglist(pcmd), nseg, scsi_sg_count(pcmd))); | 469 | __func__, scsi_sglist(pcmd), nseg, scsi_sg_count(pcmd))); |
470 | /* Map single segment */ | 470 | /* Map single segment */ |
471 | } else | 471 | } else |
472 | pSRB->SGcount = 0; | 472 | pSRB->SGcount = 0; |
@@ -483,11 +483,11 @@ static void dc390_pci_unmap (struct dc390_srb* pSRB) | |||
483 | 483 | ||
484 | if (pSRB->SRBFlag) { | 484 | if (pSRB->SRBFlag) { |
485 | pci_unmap_sg(pdev, &pSRB->Segmentx, 1, DMA_FROM_DEVICE); | 485 | pci_unmap_sg(pdev, &pSRB->Segmentx, 1, DMA_FROM_DEVICE); |
486 | DEBUG1(printk("%s(): Unmapped sense buffer at %x\n", __FUNCTION__, cmdp->saved_dma_handle)); | 486 | DEBUG1(printk("%s(): Unmapped sense buffer at %x\n", __func__, cmdp->saved_dma_handle)); |
487 | } else { | 487 | } else { |
488 | scsi_dma_unmap(pcmd); | 488 | scsi_dma_unmap(pcmd); |
489 | DEBUG1(printk("%s(): Unmapped SG at %p with %d elements\n", | 489 | DEBUG1(printk("%s(): Unmapped SG at %p with %d elements\n", |
490 | __FUNCTION__, scsi_sglist(pcmd), scsi_sg_count(pcmd))); | 490 | __func__, scsi_sglist(pcmd), scsi_sg_count(pcmd))); |
491 | } | 491 | } |
492 | } | 492 | } |
493 | 493 | ||
diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c index c975c01b3a02..d4c13561f4a6 100644 --- a/drivers/scsi/wd7000.c +++ b/drivers/scsi/wd7000.c | |||
@@ -148,7 +148,7 @@ | |||
148 | * | 148 | * |
149 | * 2002/10/04 - Alan Cox <alan@redhat.com> | 149 | * 2002/10/04 - Alan Cox <alan@redhat.com> |
150 | * | 150 | * |
151 | * Use dev_id for interrupts, kill __FUNCTION__ pasting | 151 | * Use dev_id for interrupts, kill __func__ pasting |
152 | * Add a lock for the scb pool, clean up all other cli/sti usage stuff | 152 | * Add a lock for the scb pool, clean up all other cli/sti usage stuff |
153 | * Use the adapter lock for the other places we had the cli's | 153 | * Use the adapter lock for the other places we had the cli's |
154 | * | 154 | * |
@@ -640,12 +640,12 @@ static int __init wd7000_setup(char *str) | |||
640 | (void) get_options(str, ARRAY_SIZE(ints), ints); | 640 | (void) get_options(str, ARRAY_SIZE(ints), ints); |
641 | 641 | ||
642 | if (wd7000_card_num >= NUM_CONFIGS) { | 642 | if (wd7000_card_num >= NUM_CONFIGS) { |
643 | printk(KERN_ERR "%s: Too many \"wd7000=\" configurations in " "command line!\n", __FUNCTION__); | 643 | printk(KERN_ERR "%s: Too many \"wd7000=\" configurations in " "command line!\n", __func__); |
644 | return 0; | 644 | return 0; |
645 | } | 645 | } |
646 | 646 | ||
647 | if ((ints[0] < 3) || (ints[0] > 5)) { | 647 | if ((ints[0] < 3) || (ints[0] > 5)) { |
648 | printk(KERN_ERR "%s: Error in command line! " "Usage: wd7000=<IRQ>,<DMA>,IO>[,<BUS_ON>" "[,<BUS_OFF>]]\n", __FUNCTION__); | 648 | printk(KERN_ERR "%s: Error in command line! " "Usage: wd7000=<IRQ>,<DMA>,IO>[,<BUS_ON>" "[,<BUS_OFF>]]\n", __func__); |
649 | } else { | 649 | } else { |
650 | for (i = 0; i < NUM_IRQS; i++) | 650 | for (i = 0; i < NUM_IRQS; i++) |
651 | if (ints[1] == wd7000_irq[i]) | 651 | if (ints[1] == wd7000_irq[i]) |
@@ -1642,7 +1642,7 @@ static int wd7000_biosparam(struct scsi_device *sdev, | |||
1642 | ip[2] = info[2]; | 1642 | ip[2] = info[2]; |
1643 | 1643 | ||
1644 | if (info[0] == 255) | 1644 | if (info[0] == 255) |
1645 | printk(KERN_INFO "%s: current partition table is " "using extended translation.\n", __FUNCTION__); | 1645 | printk(KERN_INFO "%s: current partition table is " "using extended translation.\n", __func__); |
1646 | } | 1646 | } |
1647 | } | 1647 | } |
1648 | 1648 | ||
diff --git a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c index 4b5f908d35c3..3c4a300494a4 100644 --- a/drivers/scsi/zalon.c +++ b/drivers/scsi/zalon.c | |||
@@ -68,11 +68,11 @@ lasi_scsi_clock(void * hpa, int defaultclock) | |||
68 | if (status == PDC_RET_OK) { | 68 | if (status == PDC_RET_OK) { |
69 | clock = (int) pdc_result[16]; | 69 | clock = (int) pdc_result[16]; |
70 | } else { | 70 | } else { |
71 | printk(KERN_WARNING "%s: pdc_iodc_read returned %d\n", __FUNCTION__, status); | 71 | printk(KERN_WARNING "%s: pdc_iodc_read returned %d\n", __func__, status); |
72 | clock = defaultclock; | 72 | clock = defaultclock; |
73 | } | 73 | } |
74 | 74 | ||
75 | printk(KERN_DEBUG "%s: SCSI clock %d\n", __FUNCTION__, clock); | 75 | printk(KERN_DEBUG "%s: SCSI clock %d\n", __func__, clock); |
76 | return clock; | 76 | return clock; |
77 | } | 77 | } |
78 | #endif | 78 | #endif |
@@ -108,13 +108,13 @@ zalon_probe(struct parisc_device *dev) | |||
108 | */ | 108 | */ |
109 | dev->irq = gsc_alloc_irq(&gsc_irq); | 109 | dev->irq = gsc_alloc_irq(&gsc_irq); |
110 | 110 | ||
111 | printk(KERN_INFO "%s: Zalon version %d, IRQ %d\n", __FUNCTION__, | 111 | printk(KERN_INFO "%s: Zalon version %d, IRQ %d\n", __func__, |
112 | zalon_vers, dev->irq); | 112 | zalon_vers, dev->irq); |
113 | 113 | ||
114 | __raw_writel(gsc_irq.txn_addr | gsc_irq.txn_data, zalon + IO_MODULE_EIM); | 114 | __raw_writel(gsc_irq.txn_addr | gsc_irq.txn_data, zalon + IO_MODULE_EIM); |
115 | 115 | ||
116 | if (zalon_vers == 0) | 116 | if (zalon_vers == 0) |
117 | printk(KERN_WARNING "%s: Zalon 1.1 or earlier\n", __FUNCTION__); | 117 | printk(KERN_WARNING "%s: Zalon 1.1 or earlier\n", __func__); |
118 | 118 | ||
119 | memset(&device, 0, sizeof(struct ncr_device)); | 119 | memset(&device, 0, sizeof(struct ncr_device)); |
120 | 120 | ||
diff --git a/fs/proc/base.c b/fs/proc/base.c index e74308bdabd3..3d94906c7aa8 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #include <linux/time.h> | 53 | #include <linux/time.h> |
54 | #include <linux/proc_fs.h> | 54 | #include <linux/proc_fs.h> |
55 | #include <linux/stat.h> | 55 | #include <linux/stat.h> |
56 | #include <linux/task_io_accounting_ops.h> | ||
56 | #include <linux/init.h> | 57 | #include <linux/init.h> |
57 | #include <linux/capability.h> | 58 | #include <linux/capability.h> |
58 | #include <linux/file.h> | 59 | #include <linux/file.h> |
@@ -2402,44 +2403,17 @@ static int proc_base_fill_cache(struct file *filp, void *dirent, | |||
2402 | #ifdef CONFIG_TASK_IO_ACCOUNTING | 2403 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
2403 | static int do_io_accounting(struct task_struct *task, char *buffer, int whole) | 2404 | static int do_io_accounting(struct task_struct *task, char *buffer, int whole) |
2404 | { | 2405 | { |
2405 | u64 rchar, wchar, syscr, syscw; | 2406 | struct proc_io_accounting acct = task->ioac; |
2406 | struct task_io_accounting ioac; | 2407 | unsigned long flags; |
2407 | 2408 | ||
2408 | rchar = task->rchar; | 2409 | if (whole && lock_task_sighand(task, &flags)) { |
2409 | wchar = task->wchar; | 2410 | struct task_struct *t = task; |
2410 | syscr = task->syscr; | 2411 | |
2411 | syscw = task->syscw; | 2412 | task_io_accounting_add(&acct, &task->signal->ioac); |
2412 | memcpy(&ioac, &task->ioac, sizeof(ioac)); | 2413 | while_each_thread(task, t) |
2413 | 2414 | task_io_accounting_add(&acct, &t->ioac); | |
2414 | if (whole) { | 2415 | |
2415 | unsigned long flags; | 2416 | unlock_task_sighand(task, &flags); |
2416 | |||
2417 | if (lock_task_sighand(task, &flags)) { | ||
2418 | struct signal_struct *sig = task->signal; | ||
2419 | struct task_struct *t = task; | ||
2420 | |||
2421 | rchar += sig->rchar; | ||
2422 | wchar += sig->wchar; | ||
2423 | syscr += sig->syscr; | ||
2424 | syscw += sig->syscw; | ||
2425 | |||
2426 | ioac.read_bytes += sig->ioac.read_bytes; | ||
2427 | ioac.write_bytes += sig->ioac.write_bytes; | ||
2428 | ioac.cancelled_write_bytes += | ||
2429 | sig->ioac.cancelled_write_bytes; | ||
2430 | while_each_thread(task, t) { | ||
2431 | rchar += t->rchar; | ||
2432 | wchar += t->wchar; | ||
2433 | syscr += t->syscr; | ||
2434 | syscw += t->syscw; | ||
2435 | |||
2436 | ioac.read_bytes += t->ioac.read_bytes; | ||
2437 | ioac.write_bytes += t->ioac.write_bytes; | ||
2438 | ioac.cancelled_write_bytes += | ||
2439 | t->ioac.cancelled_write_bytes; | ||
2440 | } | ||
2441 | unlock_task_sighand(task, &flags); | ||
2442 | } | ||
2443 | } | 2417 | } |
2444 | return sprintf(buffer, | 2418 | return sprintf(buffer, |
2445 | "rchar: %llu\n" | 2419 | "rchar: %llu\n" |
@@ -2449,9 +2423,10 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole) | |||
2449 | "read_bytes: %llu\n" | 2423 | "read_bytes: %llu\n" |
2450 | "write_bytes: %llu\n" | 2424 | "write_bytes: %llu\n" |
2451 | "cancelled_write_bytes: %llu\n", | 2425 | "cancelled_write_bytes: %llu\n", |
2452 | rchar, wchar, syscr, syscw, | 2426 | acct.chr.rchar, acct.chr.wchar, |
2453 | ioac.read_bytes, ioac.write_bytes, | 2427 | acct.chr.syscr, acct.chr.syscw, |
2454 | ioac.cancelled_write_bytes); | 2428 | acct.blk.read_bytes, acct.blk.write_bytes, |
2429 | acct.blk.cancelled_write_bytes); | ||
2455 | } | 2430 | } |
2456 | 2431 | ||
2457 | static int proc_tid_io_accounting(struct task_struct *task, char *buffer) | 2432 | static int proc_tid_io_accounting(struct task_struct *task, char *buffer) |
diff --git a/include/Kbuild b/include/Kbuild index bdca155028ec..d8c3e3cbf416 100644 --- a/include/Kbuild +++ b/include/Kbuild | |||
@@ -1,3 +1,6 @@ | |||
1 | # Top-level Makefile calls into asm-$(ARCH) | ||
2 | # List only non-arch directories below | ||
3 | |||
1 | header-y += asm-generic/ | 4 | header-y += asm-generic/ |
2 | header-y += linux/ | 5 | header-y += linux/ |
3 | header-y += sound/ | 6 | header-y += sound/ |
@@ -5,5 +8,3 @@ header-y += mtd/ | |||
5 | header-y += rdma/ | 8 | header-y += rdma/ |
6 | header-y += video/ | 9 | header-y += video/ |
7 | header-y += drm/ | 10 | header-y += drm/ |
8 | |||
9 | header-y += asm-$(ARCH)/ | ||
diff --git a/include/asm-avr32/arch-at32ap/board.h b/include/asm-avr32/arch-at32ap/board.h index 893aa6d0cd11..e60e9076544d 100644 --- a/include/asm-avr32/arch-at32ap/board.h +++ b/include/asm-avr32/arch-at32ap/board.h | |||
@@ -82,7 +82,15 @@ struct mci_platform_data; | |||
82 | struct platform_device * | 82 | struct platform_device * |
83 | at32_add_device_mci(unsigned int id, struct mci_platform_data *data); | 83 | at32_add_device_mci(unsigned int id, struct mci_platform_data *data); |
84 | 84 | ||
85 | struct platform_device *at32_add_device_ac97c(unsigned int id); | 85 | struct ac97c_platform_data { |
86 | unsigned short dma_rx_periph_id; | ||
87 | unsigned short dma_tx_periph_id; | ||
88 | unsigned short dma_controller_id; | ||
89 | int reset_pin; | ||
90 | }; | ||
91 | struct platform_device * | ||
92 | at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data); | ||
93 | |||
86 | struct platform_device *at32_add_device_abdac(unsigned int id); | 94 | struct platform_device *at32_add_device_abdac(unsigned int id); |
87 | struct platform_device *at32_add_device_psif(unsigned int id); | 95 | struct platform_device *at32_add_device_psif(unsigned int id); |
88 | 96 | ||
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 9cd44b162ba1..6d88a923c945 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
@@ -221,6 +221,7 @@ | |||
221 | * during second ld run in second ld pass when generating System.map */ | 221 | * during second ld run in second ld pass when generating System.map */ |
222 | #define TEXT_TEXT \ | 222 | #define TEXT_TEXT \ |
223 | ALIGN_FUNCTION(); \ | 223 | ALIGN_FUNCTION(); \ |
224 | *(.text.hot) \ | ||
224 | *(.text) \ | 225 | *(.text) \ |
225 | *(.ref.text) \ | 226 | *(.ref.text) \ |
226 | *(.text.init.refok) \ | 227 | *(.text.init.refok) \ |
@@ -230,7 +231,8 @@ | |||
230 | CPU_KEEP(init.text) \ | 231 | CPU_KEEP(init.text) \ |
231 | CPU_KEEP(exit.text) \ | 232 | CPU_KEEP(exit.text) \ |
232 | MEM_KEEP(init.text) \ | 233 | MEM_KEEP(init.text) \ |
233 | MEM_KEEP(exit.text) | 234 | MEM_KEEP(exit.text) \ |
235 | *(.text.unlikely) | ||
234 | 236 | ||
235 | 237 | ||
236 | /* sched.text is aling to function alignment to secure we have same | 238 | /* sched.text is aling to function alignment to secure we have same |
diff --git a/include/asm-powerpc/kvm_ppc.h b/include/asm-powerpc/kvm_ppc.h index 5a21115228af..a8b068792260 100644 --- a/include/asm-powerpc/kvm_ppc.h +++ b/include/asm-powerpc/kvm_ppc.h | |||
@@ -61,7 +61,8 @@ extern int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu); | |||
61 | 61 | ||
62 | extern void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, | 62 | extern void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, |
63 | u64 asid, u32 flags); | 63 | u64 asid, u32 flags); |
64 | extern void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid); | 64 | extern void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr, |
65 | gva_t eend, u32 asid); | ||
65 | extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode); | 66 | extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode); |
66 | 67 | ||
67 | extern void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu); | 68 | extern void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu); |
diff --git a/include/asm-s390/kvm_host.h b/include/asm-s390/kvm_host.h index 3234dd5b3511..3c55e4107dcc 100644 --- a/include/asm-s390/kvm_host.h +++ b/include/asm-s390/kvm_host.h | |||
@@ -111,7 +111,7 @@ struct kvm_vcpu_stat { | |||
111 | u32 exit_validity; | 111 | u32 exit_validity; |
112 | u32 exit_instruction; | 112 | u32 exit_instruction; |
113 | u32 instruction_lctl; | 113 | u32 instruction_lctl; |
114 | u32 instruction_lctg; | 114 | u32 instruction_lctlg; |
115 | u32 exit_program_interruption; | 115 | u32 exit_program_interruption; |
116 | u32 exit_instr_and_program; | 116 | u32 exit_instr_and_program; |
117 | u32 deliver_emergency_signal; | 117 | u32 deliver_emergency_signal; |
@@ -231,5 +231,5 @@ struct kvm_arch{ | |||
231 | struct kvm_s390_float_interrupt float_int; | 231 | struct kvm_s390_float_interrupt float_int; |
232 | }; | 232 | }; |
233 | 233 | ||
234 | extern int sie64a(struct kvm_s390_sie_block *, __u64 *); | 234 | extern int sie64a(struct kvm_s390_sie_block *, unsigned long *); |
235 | #endif | 235 | #endif |
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index fdde0bedaa90..bc34dc21f178 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h | |||
@@ -556,6 +556,7 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu); | |||
556 | int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code); | 556 | int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code); |
557 | 557 | ||
558 | void kvm_enable_tdp(void); | 558 | void kvm_enable_tdp(void); |
559 | void kvm_disable_tdp(void); | ||
559 | 560 | ||
560 | int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3); | 561 | int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3); |
561 | int complete_pio(struct kvm_vcpu *vcpu); | 562 | int complete_pio(struct kvm_vcpu *vcpu); |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ffe479ba0779..35a78415accc 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -748,6 +748,7 @@ | |||
748 | #define PCI_VENDOR_ID_TI 0x104c | 748 | #define PCI_VENDOR_ID_TI 0x104c |
749 | #define PCI_DEVICE_ID_TI_TVP4020 0x3d07 | 749 | #define PCI_DEVICE_ID_TI_TVP4020 0x3d07 |
750 | #define PCI_DEVICE_ID_TI_4450 0x8011 | 750 | #define PCI_DEVICE_ID_TI_4450 0x8011 |
751 | #define PCI_DEVICE_ID_TI_TSB43AB22 0x8023 | ||
751 | #define PCI_DEVICE_ID_TI_XX21_XX11 0x8031 | 752 | #define PCI_DEVICE_ID_TI_XX21_XX11 0x8031 |
752 | #define PCI_DEVICE_ID_TI_XX21_XX11_FM 0x8033 | 753 | #define PCI_DEVICE_ID_TI_XX21_XX11_FM 0x8033 |
753 | #define PCI_DEVICE_ID_TI_XX21_XX11_SD 0x8034 | 754 | #define PCI_DEVICE_ID_TI_XX21_XX11_SD 0x8034 |
diff --git a/include/linux/sched.h b/include/linux/sched.h index f59318a0099b..034c1ca6b332 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -505,10 +505,7 @@ struct signal_struct { | |||
505 | unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; | 505 | unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; |
506 | unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt; | 506 | unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt; |
507 | unsigned long inblock, oublock, cinblock, coublock; | 507 | unsigned long inblock, oublock, cinblock, coublock; |
508 | #ifdef CONFIG_TASK_XACCT | 508 | struct proc_io_accounting ioac; |
509 | u64 rchar, wchar, syscr, syscw; | ||
510 | #endif | ||
511 | struct task_io_accounting ioac; | ||
512 | 509 | ||
513 | /* | 510 | /* |
514 | * Cumulative ns of scheduled CPU time for dead threads in the | 511 | * Cumulative ns of scheduled CPU time for dead threads in the |
@@ -1256,11 +1253,7 @@ struct task_struct { | |||
1256 | 1253 | ||
1257 | unsigned long ptrace_message; | 1254 | unsigned long ptrace_message; |
1258 | siginfo_t *last_siginfo; /* For ptrace use. */ | 1255 | siginfo_t *last_siginfo; /* For ptrace use. */ |
1259 | #ifdef CONFIG_TASK_XACCT | 1256 | struct proc_io_accounting ioac; |
1260 | /* i/o counters(bytes read/written, #syscalls */ | ||
1261 | u64 rchar, wchar, syscr, syscw; | ||
1262 | #endif | ||
1263 | struct task_io_accounting ioac; | ||
1264 | #if defined(CONFIG_TASK_XACCT) | 1257 | #if defined(CONFIG_TASK_XACCT) |
1265 | u64 acct_rss_mem1; /* accumulated rss usage */ | 1258 | u64 acct_rss_mem1; /* accumulated rss usage */ |
1266 | u64 acct_vm_mem1; /* accumulated virtual memory usage */ | 1259 | u64 acct_vm_mem1; /* accumulated virtual memory usage */ |
@@ -2190,22 +2183,22 @@ extern long sched_group_rt_period(struct task_group *tg); | |||
2190 | #ifdef CONFIG_TASK_XACCT | 2183 | #ifdef CONFIG_TASK_XACCT |
2191 | static inline void add_rchar(struct task_struct *tsk, ssize_t amt) | 2184 | static inline void add_rchar(struct task_struct *tsk, ssize_t amt) |
2192 | { | 2185 | { |
2193 | tsk->rchar += amt; | 2186 | tsk->ioac.chr.rchar += amt; |
2194 | } | 2187 | } |
2195 | 2188 | ||
2196 | static inline void add_wchar(struct task_struct *tsk, ssize_t amt) | 2189 | static inline void add_wchar(struct task_struct *tsk, ssize_t amt) |
2197 | { | 2190 | { |
2198 | tsk->wchar += amt; | 2191 | tsk->ioac.chr.wchar += amt; |
2199 | } | 2192 | } |
2200 | 2193 | ||
2201 | static inline void inc_syscr(struct task_struct *tsk) | 2194 | static inline void inc_syscr(struct task_struct *tsk) |
2202 | { | 2195 | { |
2203 | tsk->syscr++; | 2196 | tsk->ioac.chr.syscr++; |
2204 | } | 2197 | } |
2205 | 2198 | ||
2206 | static inline void inc_syscw(struct task_struct *tsk) | 2199 | static inline void inc_syscw(struct task_struct *tsk) |
2207 | { | 2200 | { |
2208 | tsk->syscw++; | 2201 | tsk->ioac.chr.syscw++; |
2209 | } | 2202 | } |
2210 | #else | 2203 | #else |
2211 | static inline void add_rchar(struct task_struct *tsk, ssize_t amt) | 2204 | static inline void add_rchar(struct task_struct *tsk, ssize_t amt) |
diff --git a/include/linux/task_io_accounting.h b/include/linux/task_io_accounting.h index 44d00e9cceea..165390f8b936 100644 --- a/include/linux/task_io_accounting.h +++ b/include/linux/task_io_accounting.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * task_io_accounting: a structure which is used for recording a single task's | 2 | * proc_io_accounting: a structure which is used for recording a single task's |
3 | * IO statistics. | 3 | * IO statistics. |
4 | * | 4 | * |
5 | * Don't include this header file directly - it is designed to be dragged in via | 5 | * Don't include this header file directly - it is designed to be dragged in via |
@@ -8,6 +8,22 @@ | |||
8 | * Blame akpm@osdl.org for all this. | 8 | * Blame akpm@osdl.org for all this. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #ifdef CONFIG_TASK_XACCT | ||
12 | struct task_chr_io_accounting { | ||
13 | /* bytes read */ | ||
14 | u64 rchar; | ||
15 | /* bytes written */ | ||
16 | u64 wchar; | ||
17 | /* # of read syscalls */ | ||
18 | u64 syscr; | ||
19 | /* # of write syscalls */ | ||
20 | u64 syscw; | ||
21 | }; | ||
22 | #else /* CONFIG_TASK_XACCT */ | ||
23 | struct task_chr_io_accounting { | ||
24 | }; | ||
25 | #endif /* CONFIG_TASK_XACCT */ | ||
26 | |||
11 | #ifdef CONFIG_TASK_IO_ACCOUNTING | 27 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
12 | struct task_io_accounting { | 28 | struct task_io_accounting { |
13 | /* | 29 | /* |
@@ -31,7 +47,12 @@ struct task_io_accounting { | |||
31 | */ | 47 | */ |
32 | u64 cancelled_write_bytes; | 48 | u64 cancelled_write_bytes; |
33 | }; | 49 | }; |
34 | #else | 50 | #else /* CONFIG_TASK_IO_ACCOUNTING */ |
35 | struct task_io_accounting { | 51 | struct task_io_accounting { |
36 | }; | 52 | }; |
37 | #endif | 53 | #endif /* CONFIG_TASK_IO_ACCOUNTING */ |
54 | |||
55 | struct proc_io_accounting { | ||
56 | struct task_chr_io_accounting chr; | ||
57 | struct task_io_accounting blk; | ||
58 | }; | ||
diff --git a/include/linux/task_io_accounting_ops.h b/include/linux/task_io_accounting_ops.h index ff46c6fad79d..e6f958ebe97f 100644 --- a/include/linux/task_io_accounting_ops.h +++ b/include/linux/task_io_accounting_ops.h | |||
@@ -9,7 +9,7 @@ | |||
9 | #ifdef CONFIG_TASK_IO_ACCOUNTING | 9 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
10 | static inline void task_io_account_read(size_t bytes) | 10 | static inline void task_io_account_read(size_t bytes) |
11 | { | 11 | { |
12 | current->ioac.read_bytes += bytes; | 12 | current->ioac.blk.read_bytes += bytes; |
13 | } | 13 | } |
14 | 14 | ||
15 | /* | 15 | /* |
@@ -18,12 +18,12 @@ static inline void task_io_account_read(size_t bytes) | |||
18 | */ | 18 | */ |
19 | static inline unsigned long task_io_get_inblock(const struct task_struct *p) | 19 | static inline unsigned long task_io_get_inblock(const struct task_struct *p) |
20 | { | 20 | { |
21 | return p->ioac.read_bytes >> 9; | 21 | return p->ioac.blk.read_bytes >> 9; |
22 | } | 22 | } |
23 | 23 | ||
24 | static inline void task_io_account_write(size_t bytes) | 24 | static inline void task_io_account_write(size_t bytes) |
25 | { | 25 | { |
26 | current->ioac.write_bytes += bytes; | 26 | current->ioac.blk.write_bytes += bytes; |
27 | } | 27 | } |
28 | 28 | ||
29 | /* | 29 | /* |
@@ -32,17 +32,25 @@ static inline void task_io_account_write(size_t bytes) | |||
32 | */ | 32 | */ |
33 | static inline unsigned long task_io_get_oublock(const struct task_struct *p) | 33 | static inline unsigned long task_io_get_oublock(const struct task_struct *p) |
34 | { | 34 | { |
35 | return p->ioac.write_bytes >> 9; | 35 | return p->ioac.blk.write_bytes >> 9; |
36 | } | 36 | } |
37 | 37 | ||
38 | static inline void task_io_account_cancelled_write(size_t bytes) | 38 | static inline void task_io_account_cancelled_write(size_t bytes) |
39 | { | 39 | { |
40 | current->ioac.cancelled_write_bytes += bytes; | 40 | current->ioac.blk.cancelled_write_bytes += bytes; |
41 | } | 41 | } |
42 | 42 | ||
43 | static inline void task_io_accounting_init(struct task_struct *tsk) | 43 | static inline void task_io_accounting_init(struct proc_io_accounting *ioac) |
44 | { | 44 | { |
45 | memset(&tsk->ioac, 0, sizeof(tsk->ioac)); | 45 | memset(ioac, 0, sizeof(*ioac)); |
46 | } | ||
47 | |||
48 | static inline void task_blk_io_accounting_add(struct proc_io_accounting *dst, | ||
49 | struct proc_io_accounting *src) | ||
50 | { | ||
51 | dst->blk.read_bytes += src->blk.read_bytes; | ||
52 | dst->blk.write_bytes += src->blk.write_bytes; | ||
53 | dst->blk.cancelled_write_bytes += src->blk.cancelled_write_bytes; | ||
46 | } | 54 | } |
47 | 55 | ||
48 | #else | 56 | #else |
@@ -69,9 +77,37 @@ static inline void task_io_account_cancelled_write(size_t bytes) | |||
69 | { | 77 | { |
70 | } | 78 | } |
71 | 79 | ||
72 | static inline void task_io_accounting_init(struct task_struct *tsk) | 80 | static inline void task_io_accounting_init(struct proc_io_accounting *ioac) |
81 | { | ||
82 | } | ||
83 | |||
84 | static inline void task_blk_io_accounting_add(struct proc_io_accounting *dst, | ||
85 | struct proc_io_accounting *src) | ||
73 | { | 86 | { |
74 | } | 87 | } |
75 | 88 | ||
76 | #endif /* CONFIG_TASK_IO_ACCOUNTING */ | 89 | #endif /* CONFIG_TASK_IO_ACCOUNTING */ |
77 | #endif /* __TASK_IO_ACCOUNTING_OPS_INCLUDED */ | 90 | |
91 | #ifdef CONFIG_TASK_XACCT | ||
92 | static inline void task_chr_io_accounting_add(struct proc_io_accounting *dst, | ||
93 | struct proc_io_accounting *src) | ||
94 | { | ||
95 | dst->chr.rchar += src->chr.rchar; | ||
96 | dst->chr.wchar += src->chr.wchar; | ||
97 | dst->chr.syscr += src->chr.syscr; | ||
98 | dst->chr.syscw += src->chr.syscw; | ||
99 | } | ||
100 | #else | ||
101 | static inline void task_chr_io_accounting_add(struct proc_io_accounting *dst, | ||
102 | struct proc_io_accounting *src) | ||
103 | { | ||
104 | } | ||
105 | #endif /* CONFIG_TASK_XACCT */ | ||
106 | |||
107 | static inline void task_io_accounting_add(struct proc_io_accounting *dst, | ||
108 | struct proc_io_accounting *src) | ||
109 | { | ||
110 | task_chr_io_accounting_add(dst, src); | ||
111 | task_blk_io_accounting_add(dst, src); | ||
112 | } | ||
113 | #endif /* __TASK_IO_ACCOUNTING_OPS_INCLUDED */ | ||
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 2d5c18514a2d..113028fb8f66 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h | |||
@@ -608,6 +608,8 @@ extern struct ctl_table *ipv6_icmp_sysctl_init(struct net *net); | |||
608 | extern struct ctl_table *ipv6_route_sysctl_init(struct net *net); | 608 | extern struct ctl_table *ipv6_route_sysctl_init(struct net *net); |
609 | extern int ipv6_sysctl_register(void); | 609 | extern int ipv6_sysctl_register(void); |
610 | extern void ipv6_sysctl_unregister(void); | 610 | extern void ipv6_sysctl_unregister(void); |
611 | extern int ipv6_static_sysctl_register(void); | ||
612 | extern void ipv6_static_sysctl_unregister(void); | ||
611 | #endif | 613 | #endif |
612 | 614 | ||
613 | #endif /* __KERNEL__ */ | 615 | #endif /* __KERNEL__ */ |
diff --git a/include/net/route.h b/include/net/route.h index 3140cc500854..4f0d8c14736c 100644 --- a/include/net/route.h +++ b/include/net/route.h | |||
@@ -204,6 +204,4 @@ static inline struct inet_peer *rt_get_peer(struct rtable *rt) | |||
204 | return rt->peer; | 204 | return rt->peer; |
205 | } | 205 | } |
206 | 206 | ||
207 | extern ctl_table ipv4_route_table[]; | ||
208 | |||
209 | #endif /* _ROUTE_H */ | 207 | #endif /* _ROUTE_H */ |
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 00137a7769ee..5c40cc537d4c 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h | |||
@@ -106,6 +106,7 @@ | |||
106 | #define VARIABLE_LENGTH_CMD 0x7f | 106 | #define VARIABLE_LENGTH_CMD 0x7f |
107 | #define REPORT_LUNS 0xa0 | 107 | #define REPORT_LUNS 0xa0 |
108 | #define MAINTENANCE_IN 0xa3 | 108 | #define MAINTENANCE_IN 0xa3 |
109 | #define MAINTENANCE_OUT 0xa4 | ||
109 | #define MOVE_MEDIUM 0xa5 | 110 | #define MOVE_MEDIUM 0xa5 |
110 | #define EXCHANGE_MEDIUM 0xa6 | 111 | #define EXCHANGE_MEDIUM 0xa6 |
111 | #define READ_12 0xa8 | 112 | #define READ_12 0xa8 |
@@ -125,6 +126,8 @@ | |||
125 | #define SAI_READ_CAPACITY_16 0x10 | 126 | #define SAI_READ_CAPACITY_16 0x10 |
126 | /* values for maintenance in */ | 127 | /* values for maintenance in */ |
127 | #define MI_REPORT_TARGET_PGS 0x0a | 128 | #define MI_REPORT_TARGET_PGS 0x0a |
129 | /* values for maintenance out */ | ||
130 | #define MO_SET_TARGET_PGS 0x0a | ||
128 | 131 | ||
129 | /* Values for T10/04-262r7 */ | 132 | /* Values for T10/04-262r7 */ |
130 | #define ATA_16 0x85 /* 16-byte pass-thru */ | 133 | #define ATA_16 0x85 /* 16-byte pass-thru */ |
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 66c944849d6b..f9f6e793575c 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h | |||
@@ -77,6 +77,9 @@ struct scsi_cmnd { | |||
77 | int allowed; | 77 | int allowed; |
78 | int timeout_per_command; | 78 | int timeout_per_command; |
79 | 79 | ||
80 | unsigned char prot_op; | ||
81 | unsigned char prot_type; | ||
82 | |||
80 | unsigned short cmd_len; | 83 | unsigned short cmd_len; |
81 | enum dma_data_direction sc_data_direction; | 84 | enum dma_data_direction sc_data_direction; |
82 | 85 | ||
@@ -87,6 +90,8 @@ struct scsi_cmnd { | |||
87 | 90 | ||
88 | /* These elements define the operation we ultimately want to perform */ | 91 | /* These elements define the operation we ultimately want to perform */ |
89 | struct scsi_data_buffer sdb; | 92 | struct scsi_data_buffer sdb; |
93 | struct scsi_data_buffer *prot_sdb; | ||
94 | |||
90 | unsigned underflow; /* Return error if less than | 95 | unsigned underflow; /* Return error if less than |
91 | this amount is transferred */ | 96 | this amount is transferred */ |
92 | 97 | ||
@@ -208,4 +213,85 @@ static inline int scsi_sg_copy_to_buffer(struct scsi_cmnd *cmd, | |||
208 | buf, buflen); | 213 | buf, buflen); |
209 | } | 214 | } |
210 | 215 | ||
216 | /* | ||
217 | * The operations below are hints that tell the controller driver how | ||
218 | * to handle I/Os with DIF or similar types of protection information. | ||
219 | */ | ||
220 | enum scsi_prot_operations { | ||
221 | /* Normal I/O */ | ||
222 | SCSI_PROT_NORMAL = 0, | ||
223 | |||
224 | /* OS-HBA: Protected, HBA-Target: Unprotected */ | ||
225 | SCSI_PROT_READ_INSERT, | ||
226 | SCSI_PROT_WRITE_STRIP, | ||
227 | |||
228 | /* OS-HBA: Unprotected, HBA-Target: Protected */ | ||
229 | SCSI_PROT_READ_STRIP, | ||
230 | SCSI_PROT_WRITE_INSERT, | ||
231 | |||
232 | /* OS-HBA: Protected, HBA-Target: Protected */ | ||
233 | SCSI_PROT_READ_PASS, | ||
234 | SCSI_PROT_WRITE_PASS, | ||
235 | |||
236 | /* OS-HBA: Protected, HBA-Target: Protected, checksum conversion */ | ||
237 | SCSI_PROT_READ_CONVERT, | ||
238 | SCSI_PROT_WRITE_CONVERT, | ||
239 | }; | ||
240 | |||
241 | static inline void scsi_set_prot_op(struct scsi_cmnd *scmd, unsigned char op) | ||
242 | { | ||
243 | scmd->prot_op = op; | ||
244 | } | ||
245 | |||
246 | static inline unsigned char scsi_get_prot_op(struct scsi_cmnd *scmd) | ||
247 | { | ||
248 | return scmd->prot_op; | ||
249 | } | ||
250 | |||
251 | /* | ||
252 | * The controller usually does not know anything about the target it | ||
253 | * is communicating with. However, when DIX is enabled the controller | ||
254 | * must be know target type so it can verify the protection | ||
255 | * information passed along with the I/O. | ||
256 | */ | ||
257 | enum scsi_prot_target_type { | ||
258 | SCSI_PROT_DIF_TYPE0 = 0, | ||
259 | SCSI_PROT_DIF_TYPE1, | ||
260 | SCSI_PROT_DIF_TYPE2, | ||
261 | SCSI_PROT_DIF_TYPE3, | ||
262 | }; | ||
263 | |||
264 | static inline void scsi_set_prot_type(struct scsi_cmnd *scmd, unsigned char type) | ||
265 | { | ||
266 | scmd->prot_type = type; | ||
267 | } | ||
268 | |||
269 | static inline unsigned char scsi_get_prot_type(struct scsi_cmnd *scmd) | ||
270 | { | ||
271 | return scmd->prot_type; | ||
272 | } | ||
273 | |||
274 | static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd) | ||
275 | { | ||
276 | return scmd->request->sector; | ||
277 | } | ||
278 | |||
279 | static inline unsigned scsi_prot_sg_count(struct scsi_cmnd *cmd) | ||
280 | { | ||
281 | return cmd->prot_sdb ? cmd->prot_sdb->table.nents : 0; | ||
282 | } | ||
283 | |||
284 | static inline struct scatterlist *scsi_prot_sglist(struct scsi_cmnd *cmd) | ||
285 | { | ||
286 | return cmd->prot_sdb ? cmd->prot_sdb->table.sgl : NULL; | ||
287 | } | ||
288 | |||
289 | static inline struct scsi_data_buffer *scsi_prot(struct scsi_cmnd *cmd) | ||
290 | { | ||
291 | return cmd->prot_sdb; | ||
292 | } | ||
293 | |||
294 | #define scsi_for_each_prot_sg(cmd, sg, nseg, __i) \ | ||
295 | for_each_sg(scsi_prot_sglist(cmd), sg, nseg, __i) | ||
296 | |||
211 | #endif /* _SCSI_SCSI_CMND_H */ | 297 | #endif /* _SCSI_SCSI_CMND_H */ |
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 6467f78b191f..291d56a19167 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h | |||
@@ -140,7 +140,8 @@ struct scsi_device { | |||
140 | unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */ | 140 | unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */ |
141 | unsigned guess_capacity:1; /* READ_CAPACITY might be too high by 1 */ | 141 | unsigned guess_capacity:1; /* READ_CAPACITY might be too high by 1 */ |
142 | unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */ | 142 | unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */ |
143 | unsigned last_sector_bug:1; /* Always read last sector in a 1 sector read */ | 143 | unsigned last_sector_bug:1; /* do not use multisector accesses on |
144 | SD_LAST_BUGGY_SECTORS */ | ||
144 | 145 | ||
145 | DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ | 146 | DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ |
146 | struct list_head event_list; /* asserted events */ | 147 | struct list_head event_list; /* asserted events */ |
@@ -167,15 +168,22 @@ struct scsi_device { | |||
167 | unsigned long sdev_data[0]; | 168 | unsigned long sdev_data[0]; |
168 | } __attribute__((aligned(sizeof(unsigned long)))); | 169 | } __attribute__((aligned(sizeof(unsigned long)))); |
169 | 170 | ||
171 | struct scsi_dh_devlist { | ||
172 | char *vendor; | ||
173 | char *model; | ||
174 | }; | ||
175 | |||
170 | struct scsi_device_handler { | 176 | struct scsi_device_handler { |
171 | /* Used by the infrastructure */ | 177 | /* Used by the infrastructure */ |
172 | struct list_head list; /* list of scsi_device_handlers */ | 178 | struct list_head list; /* list of scsi_device_handlers */ |
173 | struct notifier_block nb; | ||
174 | 179 | ||
175 | /* Filled by the hardware handler */ | 180 | /* Filled by the hardware handler */ |
176 | struct module *module; | 181 | struct module *module; |
177 | const char *name; | 182 | const char *name; |
183 | const struct scsi_dh_devlist *devlist; | ||
178 | int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *); | 184 | int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *); |
185 | int (*attach)(struct scsi_device *); | ||
186 | void (*detach)(struct scsi_device *); | ||
179 | int (*activate)(struct scsi_device *); | 187 | int (*activate)(struct scsi_device *); |
180 | int (*prep_fn)(struct scsi_device *, struct request *); | 188 | int (*prep_fn)(struct scsi_device *, struct request *); |
181 | }; | 189 | }; |
@@ -416,6 +424,11 @@ static inline int scsi_device_enclosure(struct scsi_device *sdev) | |||
416 | return sdev->inquiry[6] & (1<<6); | 424 | return sdev->inquiry[6] & (1<<6); |
417 | } | 425 | } |
418 | 426 | ||
427 | static inline int scsi_device_protection(struct scsi_device *sdev) | ||
428 | { | ||
429 | return sdev->inquiry[5] & (1<<0); | ||
430 | } | ||
431 | |||
419 | #define MODULE_ALIAS_SCSI_DEVICE(type) \ | 432 | #define MODULE_ALIAS_SCSI_DEVICE(type) \ |
420 | MODULE_ALIAS("scsi:t-" __stringify(type) "*") | 433 | MODULE_ALIAS("scsi:t-" __stringify(type) "*") |
421 | #define SCSI_DEVICE_MODALIAS_FMT "scsi:t-0x%02x" | 434 | #define SCSI_DEVICE_MODALIAS_FMT "scsi:t-0x%02x" |
diff --git a/include/scsi/scsi_dh.h b/include/scsi/scsi_dh.h index 3ad2303d1a16..33efce20c26c 100644 --- a/include/scsi/scsi_dh.h +++ b/include/scsi/scsi_dh.h | |||
@@ -32,6 +32,7 @@ enum { | |||
32 | */ | 32 | */ |
33 | SCSI_DH_DEV_FAILED, /* generic device error */ | 33 | SCSI_DH_DEV_FAILED, /* generic device error */ |
34 | SCSI_DH_DEV_TEMP_BUSY, | 34 | SCSI_DH_DEV_TEMP_BUSY, |
35 | SCSI_DH_DEV_UNSUPP, /* device handler not supported */ | ||
35 | SCSI_DH_DEVICE_MAX, /* max device blkerr definition */ | 36 | SCSI_DH_DEVICE_MAX, /* max device blkerr definition */ |
36 | 37 | ||
37 | /* | 38 | /* |
@@ -57,6 +58,8 @@ enum { | |||
57 | #if defined(CONFIG_SCSI_DH) || defined(CONFIG_SCSI_DH_MODULE) | 58 | #if defined(CONFIG_SCSI_DH) || defined(CONFIG_SCSI_DH_MODULE) |
58 | extern int scsi_dh_activate(struct request_queue *); | 59 | extern int scsi_dh_activate(struct request_queue *); |
59 | extern int scsi_dh_handler_exist(const char *); | 60 | extern int scsi_dh_handler_exist(const char *); |
61 | extern int scsi_dh_attach(struct request_queue *, const char *); | ||
62 | extern void scsi_dh_detach(struct request_queue *); | ||
60 | #else | 63 | #else |
61 | static inline int scsi_dh_activate(struct request_queue *req) | 64 | static inline int scsi_dh_activate(struct request_queue *req) |
62 | { | 65 | { |
@@ -66,4 +69,12 @@ static inline int scsi_dh_handler_exist(const char *name) | |||
66 | { | 69 | { |
67 | return 0; | 70 | return 0; |
68 | } | 71 | } |
72 | static inline int scsi_dh_attach(struct request_queue *req, const char *name) | ||
73 | { | ||
74 | return SCSI_DH_NOSYS; | ||
75 | } | ||
76 | static inline void scsi_dh_detach(struct request_queue *q) | ||
77 | { | ||
78 | return; | ||
79 | } | ||
69 | #endif | 80 | #endif |
diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h index 2a9add21267d..06a8790893ef 100644 --- a/include/scsi/scsi_eh.h +++ b/include/scsi/scsi_eh.h | |||
@@ -74,7 +74,9 @@ struct scsi_eh_save { | |||
74 | /* saved state */ | 74 | /* saved state */ |
75 | int result; | 75 | int result; |
76 | enum dma_data_direction data_direction; | 76 | enum dma_data_direction data_direction; |
77 | unsigned underflow; | ||
77 | unsigned char cmd_len; | 78 | unsigned char cmd_len; |
79 | unsigned char prot_op; | ||
78 | unsigned char *cmnd; | 80 | unsigned char *cmnd; |
79 | struct scsi_data_buffer sdb; | 81 | struct scsi_data_buffer sdb; |
80 | struct request *next_rq; | 82 | struct request *next_rq; |
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index a594bac4a77d..44a55d1bf530 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h | |||
@@ -547,7 +547,7 @@ struct Scsi_Host { | |||
547 | unsigned int host_failed; /* commands that failed. */ | 547 | unsigned int host_failed; /* commands that failed. */ |
548 | unsigned int host_eh_scheduled; /* EH scheduled without command */ | 548 | unsigned int host_eh_scheduled; /* EH scheduled without command */ |
549 | 549 | ||
550 | unsigned short host_no; /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */ | 550 | unsigned int host_no; /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */ |
551 | int resetting; /* if set, it means that last_reset is a valid value */ | 551 | int resetting; /* if set, it means that last_reset is a valid value */ |
552 | unsigned long last_reset; | 552 | unsigned long last_reset; |
553 | 553 | ||
@@ -636,6 +636,10 @@ struct Scsi_Host { | |||
636 | */ | 636 | */ |
637 | unsigned int max_host_blocked; | 637 | unsigned int max_host_blocked; |
638 | 638 | ||
639 | /* Protection Information */ | ||
640 | unsigned int prot_capabilities; | ||
641 | unsigned char prot_guard_type; | ||
642 | |||
639 | /* | 643 | /* |
640 | * q used for scsi_tgt msgs, async events or any other requests that | 644 | * q used for scsi_tgt msgs, async events or any other requests that |
641 | * need to be processed in userspace | 645 | * need to be processed in userspace |
@@ -756,6 +760,86 @@ extern struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, | |||
756 | extern void scsi_free_host_dev(struct scsi_device *); | 760 | extern void scsi_free_host_dev(struct scsi_device *); |
757 | extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *); | 761 | extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *); |
758 | 762 | ||
763 | /* | ||
764 | * DIF defines the exchange of protection information between | ||
765 | * initiator and SBC block device. | ||
766 | * | ||
767 | * DIX defines the exchange of protection information between OS and | ||
768 | * initiator. | ||
769 | */ | ||
770 | enum scsi_host_prot_capabilities { | ||
771 | SHOST_DIF_TYPE1_PROTECTION = 1 << 0, /* T10 DIF Type 1 */ | ||
772 | SHOST_DIF_TYPE2_PROTECTION = 1 << 1, /* T10 DIF Type 2 */ | ||
773 | SHOST_DIF_TYPE3_PROTECTION = 1 << 2, /* T10 DIF Type 3 */ | ||
774 | |||
775 | SHOST_DIX_TYPE0_PROTECTION = 1 << 3, /* DIX between OS and HBA only */ | ||
776 | SHOST_DIX_TYPE1_PROTECTION = 1 << 4, /* DIX with DIF Type 1 */ | ||
777 | SHOST_DIX_TYPE2_PROTECTION = 1 << 5, /* DIX with DIF Type 2 */ | ||
778 | SHOST_DIX_TYPE3_PROTECTION = 1 << 6, /* DIX with DIF Type 3 */ | ||
779 | }; | ||
780 | |||
781 | /* | ||
782 | * SCSI hosts which support the Data Integrity Extensions must | ||
783 | * indicate their capabilities by setting the prot_capabilities using | ||
784 | * this call. | ||
785 | */ | ||
786 | static inline void scsi_host_set_prot(struct Scsi_Host *shost, unsigned int mask) | ||
787 | { | ||
788 | shost->prot_capabilities = mask; | ||
789 | } | ||
790 | |||
791 | static inline unsigned int scsi_host_get_prot(struct Scsi_Host *shost) | ||
792 | { | ||
793 | return shost->prot_capabilities; | ||
794 | } | ||
795 | |||
796 | static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsigned int target_type) | ||
797 | { | ||
798 | switch (target_type) { | ||
799 | case 1: return shost->prot_capabilities & SHOST_DIF_TYPE1_PROTECTION; | ||
800 | case 2: return shost->prot_capabilities & SHOST_DIF_TYPE2_PROTECTION; | ||
801 | case 3: return shost->prot_capabilities & SHOST_DIF_TYPE3_PROTECTION; | ||
802 | } | ||
803 | |||
804 | return 0; | ||
805 | } | ||
806 | |||
807 | static inline unsigned int scsi_host_dix_capable(struct Scsi_Host *shost, unsigned int target_type) | ||
808 | { | ||
809 | switch (target_type) { | ||
810 | case 0: return shost->prot_capabilities & SHOST_DIX_TYPE0_PROTECTION; | ||
811 | case 1: return shost->prot_capabilities & SHOST_DIX_TYPE1_PROTECTION; | ||
812 | case 2: return shost->prot_capabilities & SHOST_DIX_TYPE2_PROTECTION; | ||
813 | case 3: return shost->prot_capabilities & SHOST_DIX_TYPE3_PROTECTION; | ||
814 | } | ||
815 | |||
816 | return 0; | ||
817 | } | ||
818 | |||
819 | /* | ||
820 | * All DIX-capable initiators must support the T10-mandated CRC | ||
821 | * checksum. Controllers can optionally implement the IP checksum | ||
822 | * scheme which has much lower impact on system performance. Note | ||
823 | * that the main rationale for the checksum is to match integrity | ||
824 | * metadata with data. Detecting bit errors are a job for ECC memory | ||
825 | * and buses. | ||
826 | */ | ||
827 | |||
828 | enum scsi_host_guard_type { | ||
829 | SHOST_DIX_GUARD_CRC = 1 << 0, | ||
830 | SHOST_DIX_GUARD_IP = 1 << 1, | ||
831 | }; | ||
832 | |||
833 | static inline void scsi_host_set_guard(struct Scsi_Host *shost, unsigned char type) | ||
834 | { | ||
835 | shost->prot_guard_type = type; | ||
836 | } | ||
837 | |||
838 | static inline unsigned char scsi_host_get_guard(struct Scsi_Host *shost) | ||
839 | { | ||
840 | return shost->prot_guard_type; | ||
841 | } | ||
842 | |||
759 | /* legacy interfaces */ | 843 | /* legacy interfaces */ |
760 | extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int); | 844 | extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int); |
761 | extern void scsi_unregister(struct Scsi_Host *); | 845 | extern void scsi_unregister(struct Scsi_Host *); |
diff --git a/init/Kconfig b/init/Kconfig index a50bdfed2df7..43d6989c275f 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -171,7 +171,7 @@ config BSD_PROCESS_ACCT_V3 | |||
171 | process and it's parent. Note that this file format is incompatible | 171 | process and it's parent. Note that this file format is incompatible |
172 | with previous v0/v1/v2 file formats, so you will need updated tools | 172 | with previous v0/v1/v2 file formats, so you will need updated tools |
173 | for processing it. A preliminary version of these tools is available | 173 | for processing it. A preliminary version of these tools is available |
174 | at <http://www.physik3.uni-rostock.de/tim/kernel/utils/acct/>. | 174 | at <http://www.gnu.org/software/acct/>. |
175 | 175 | ||
176 | config TASKSTATS | 176 | config TASKSTATS |
177 | bool "Export task/process statistics through netlink (EXPERIMENTAL)" | 177 | bool "Export task/process statistics through netlink (EXPERIMENTAL)" |
@@ -486,7 +486,7 @@ config PID_NS | |||
486 | default n | 486 | default n |
487 | depends on NAMESPACES && EXPERIMENTAL | 487 | depends on NAMESPACES && EXPERIMENTAL |
488 | help | 488 | help |
489 | Suport process id namespaces. This allows having multiple | 489 | Support process id namespaces. This allows having multiple |
490 | process with the same pid as long as they are in different | 490 | process with the same pid as long as they are in different |
491 | pid namespaces. This is a building block of containers. | 491 | pid namespaces. This is a building block of containers. |
492 | 492 | ||
diff --git a/kernel/exit.c b/kernel/exit.c index 0caf590548a0..eb4d6470d1d0 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -121,18 +121,7 @@ static void __exit_signal(struct task_struct *tsk) | |||
121 | sig->nivcsw += tsk->nivcsw; | 121 | sig->nivcsw += tsk->nivcsw; |
122 | sig->inblock += task_io_get_inblock(tsk); | 122 | sig->inblock += task_io_get_inblock(tsk); |
123 | sig->oublock += task_io_get_oublock(tsk); | 123 | sig->oublock += task_io_get_oublock(tsk); |
124 | #ifdef CONFIG_TASK_XACCT | 124 | task_io_accounting_add(&sig->ioac, &tsk->ioac); |
125 | sig->rchar += tsk->rchar; | ||
126 | sig->wchar += tsk->wchar; | ||
127 | sig->syscr += tsk->syscr; | ||
128 | sig->syscw += tsk->syscw; | ||
129 | #endif /* CONFIG_TASK_XACCT */ | ||
130 | #ifdef CONFIG_TASK_IO_ACCOUNTING | ||
131 | sig->ioac.read_bytes += tsk->ioac.read_bytes; | ||
132 | sig->ioac.write_bytes += tsk->ioac.write_bytes; | ||
133 | sig->ioac.cancelled_write_bytes += | ||
134 | tsk->ioac.cancelled_write_bytes; | ||
135 | #endif /* CONFIG_TASK_IO_ACCOUNTING */ | ||
136 | sig->sum_sched_runtime += tsk->se.sum_exec_runtime; | 125 | sig->sum_sched_runtime += tsk->se.sum_exec_runtime; |
137 | sig = NULL; /* Marker for below. */ | 126 | sig = NULL; /* Marker for below. */ |
138 | } | 127 | } |
@@ -1363,21 +1352,8 @@ static int wait_task_zombie(struct task_struct *p, int options, | |||
1363 | psig->coublock += | 1352 | psig->coublock += |
1364 | task_io_get_oublock(p) + | 1353 | task_io_get_oublock(p) + |
1365 | sig->oublock + sig->coublock; | 1354 | sig->oublock + sig->coublock; |
1366 | #ifdef CONFIG_TASK_XACCT | 1355 | task_io_accounting_add(&psig->ioac, &p->ioac); |
1367 | psig->rchar += p->rchar + sig->rchar; | 1356 | task_io_accounting_add(&psig->ioac, &sig->ioac); |
1368 | psig->wchar += p->wchar + sig->wchar; | ||
1369 | psig->syscr += p->syscr + sig->syscr; | ||
1370 | psig->syscw += p->syscw + sig->syscw; | ||
1371 | #endif /* CONFIG_TASK_XACCT */ | ||
1372 | #ifdef CONFIG_TASK_IO_ACCOUNTING | ||
1373 | psig->ioac.read_bytes += | ||
1374 | p->ioac.read_bytes + sig->ioac.read_bytes; | ||
1375 | psig->ioac.write_bytes += | ||
1376 | p->ioac.write_bytes + sig->ioac.write_bytes; | ||
1377 | psig->ioac.cancelled_write_bytes += | ||
1378 | p->ioac.cancelled_write_bytes + | ||
1379 | sig->ioac.cancelled_write_bytes; | ||
1380 | #endif /* CONFIG_TASK_IO_ACCOUNTING */ | ||
1381 | spin_unlock_irq(&p->parent->sighand->siglock); | 1357 | spin_unlock_irq(&p->parent->sighand->siglock); |
1382 | } | 1358 | } |
1383 | 1359 | ||
diff --git a/kernel/fork.c b/kernel/fork.c index 5e050c1317c4..8214ba7c8bb1 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -806,12 +806,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
806 | sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; | 806 | sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; |
807 | sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; | 807 | sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; |
808 | sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; | 808 | sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; |
809 | #ifdef CONFIG_TASK_XACCT | 809 | task_io_accounting_init(&sig->ioac); |
810 | sig->rchar = sig->wchar = sig->syscr = sig->syscw = 0; | ||
811 | #endif | ||
812 | #ifdef CONFIG_TASK_IO_ACCOUNTING | ||
813 | memset(&sig->ioac, 0, sizeof(sig->ioac)); | ||
814 | #endif | ||
815 | sig->sum_sched_runtime = 0; | 810 | sig->sum_sched_runtime = 0; |
816 | INIT_LIST_HEAD(&sig->cpu_timers[0]); | 811 | INIT_LIST_HEAD(&sig->cpu_timers[0]); |
817 | INIT_LIST_HEAD(&sig->cpu_timers[1]); | 812 | INIT_LIST_HEAD(&sig->cpu_timers[1]); |
@@ -994,13 +989,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
994 | p->last_switch_timestamp = 0; | 989 | p->last_switch_timestamp = 0; |
995 | #endif | 990 | #endif |
996 | 991 | ||
997 | #ifdef CONFIG_TASK_XACCT | 992 | task_io_accounting_init(&p->ioac); |
998 | p->rchar = 0; /* I/O counter: bytes read */ | ||
999 | p->wchar = 0; /* I/O counter: bytes written */ | ||
1000 | p->syscr = 0; /* I/O counter: read syscalls */ | ||
1001 | p->syscw = 0; /* I/O counter: write syscalls */ | ||
1002 | #endif | ||
1003 | task_io_accounting_init(p); | ||
1004 | acct_clear_integrals(p); | 993 | acct_clear_integrals(p); |
1005 | 994 | ||
1006 | p->it_virt_expires = cputime_zero; | 995 | p->it_virt_expires = cputime_zero; |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 911d846f0503..fe4713347275 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -1680,43 +1680,45 @@ static __init int sysctl_init(void) | |||
1680 | 1680 | ||
1681 | core_initcall(sysctl_init); | 1681 | core_initcall(sysctl_init); |
1682 | 1682 | ||
1683 | static int is_branch_in(struct ctl_table *branch, struct ctl_table *table) | 1683 | static struct ctl_table *is_branch_in(struct ctl_table *branch, |
1684 | struct ctl_table *table) | ||
1684 | { | 1685 | { |
1685 | struct ctl_table *p; | 1686 | struct ctl_table *p; |
1686 | const char *s = branch->procname; | 1687 | const char *s = branch->procname; |
1687 | 1688 | ||
1688 | /* branch should have named subdirectory as its first element */ | 1689 | /* branch should have named subdirectory as its first element */ |
1689 | if (!s || !branch->child) | 1690 | if (!s || !branch->child) |
1690 | return 0; | 1691 | return NULL; |
1691 | 1692 | ||
1692 | /* ... and nothing else */ | 1693 | /* ... and nothing else */ |
1693 | if (branch[1].procname || branch[1].ctl_name) | 1694 | if (branch[1].procname || branch[1].ctl_name) |
1694 | return 0; | 1695 | return NULL; |
1695 | 1696 | ||
1696 | /* table should contain subdirectory with the same name */ | 1697 | /* table should contain subdirectory with the same name */ |
1697 | for (p = table; p->procname || p->ctl_name; p++) { | 1698 | for (p = table; p->procname || p->ctl_name; p++) { |
1698 | if (!p->child) | 1699 | if (!p->child) |
1699 | continue; | 1700 | continue; |
1700 | if (p->procname && strcmp(p->procname, s) == 0) | 1701 | if (p->procname && strcmp(p->procname, s) == 0) |
1701 | return 1; | 1702 | return p; |
1702 | } | 1703 | } |
1703 | return 0; | 1704 | return NULL; |
1704 | } | 1705 | } |
1705 | 1706 | ||
1706 | /* see if attaching q to p would be an improvement */ | 1707 | /* see if attaching q to p would be an improvement */ |
1707 | static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q) | 1708 | static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q) |
1708 | { | 1709 | { |
1709 | struct ctl_table *to = p->ctl_table, *by = q->ctl_table; | 1710 | struct ctl_table *to = p->ctl_table, *by = q->ctl_table; |
1711 | struct ctl_table *next; | ||
1710 | int is_better = 0; | 1712 | int is_better = 0; |
1711 | int not_in_parent = !p->attached_by; | 1713 | int not_in_parent = !p->attached_by; |
1712 | 1714 | ||
1713 | while (is_branch_in(by, to)) { | 1715 | while ((next = is_branch_in(by, to)) != NULL) { |
1714 | if (by == q->attached_by) | 1716 | if (by == q->attached_by) |
1715 | is_better = 1; | 1717 | is_better = 1; |
1716 | if (to == p->attached_by) | 1718 | if (to == p->attached_by) |
1717 | not_in_parent = 1; | 1719 | not_in_parent = 1; |
1718 | by = by->child; | 1720 | by = by->child; |
1719 | to = to->child; | 1721 | to = next->child; |
1720 | } | 1722 | } |
1721 | 1723 | ||
1722 | if (is_better && not_in_parent) { | 1724 | if (is_better && not_in_parent) { |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index fc20e09a6cb1..8f3fb3db61c3 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -1183,7 +1183,6 @@ static void *find_next_entry_inc(struct trace_iterator *iter) | |||
1183 | static void *s_next(struct seq_file *m, void *v, loff_t *pos) | 1183 | static void *s_next(struct seq_file *m, void *v, loff_t *pos) |
1184 | { | 1184 | { |
1185 | struct trace_iterator *iter = m->private; | 1185 | struct trace_iterator *iter = m->private; |
1186 | void *last_ent = iter->ent; | ||
1187 | int i = (int)*pos; | 1186 | int i = (int)*pos; |
1188 | void *ent; | 1187 | void *ent; |
1189 | 1188 | ||
diff --git a/kernel/tsacct.c b/kernel/tsacct.c index 3da47ccdc5e5..f9cd2561689c 100644 --- a/kernel/tsacct.c +++ b/kernel/tsacct.c | |||
@@ -94,14 +94,14 @@ void xacct_add_tsk(struct taskstats *stats, struct task_struct *p) | |||
94 | stats->hiwater_vm = mm->hiwater_vm * PAGE_SIZE / KB; | 94 | stats->hiwater_vm = mm->hiwater_vm * PAGE_SIZE / KB; |
95 | mmput(mm); | 95 | mmput(mm); |
96 | } | 96 | } |
97 | stats->read_char = p->rchar; | 97 | stats->read_char = p->ioac.chr.rchar; |
98 | stats->write_char = p->wchar; | 98 | stats->write_char = p->ioac.chr.wchar; |
99 | stats->read_syscalls = p->syscr; | 99 | stats->read_syscalls = p->ioac.chr.syscr; |
100 | stats->write_syscalls = p->syscw; | 100 | stats->write_syscalls = p->ioac.chr.syscw; |
101 | #ifdef CONFIG_TASK_IO_ACCOUNTING | 101 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
102 | stats->read_bytes = p->ioac.read_bytes; | 102 | stats->read_bytes = p->ioac.blk.read_bytes; |
103 | stats->write_bytes = p->ioac.write_bytes; | 103 | stats->write_bytes = p->ioac.blk.write_bytes; |
104 | stats->cancelled_write_bytes = p->ioac.cancelled_write_bytes; | 104 | stats->cancelled_write_bytes = p->ioac.blk.cancelled_write_bytes; |
105 | #else | 105 | #else |
106 | stats->read_bytes = 0; | 106 | stats->read_bytes = 0; |
107 | stats->write_bytes = 0; | 107 | stats->write_bytes = 0; |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a507c5e27d0e..380d6474cf66 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -2914,7 +2914,7 @@ static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table, | |||
2914 | return 0; | 2914 | return 0; |
2915 | } | 2915 | } |
2916 | 2916 | ||
2917 | ctl_table ipv4_route_table[] = { | 2917 | static ctl_table ipv4_route_table[] = { |
2918 | { | 2918 | { |
2919 | .ctl_name = NET_IPV4_ROUTE_GC_THRESH, | 2919 | .ctl_name = NET_IPV4_ROUTE_GC_THRESH, |
2920 | .procname = "gc_thresh", | 2920 | .procname = "gc_thresh", |
@@ -3216,6 +3216,15 @@ int __init ip_rt_init(void) | |||
3216 | return rc; | 3216 | return rc; |
3217 | } | 3217 | } |
3218 | 3218 | ||
3219 | /* | ||
3220 | * We really need to sanitize the damn ipv4 init order, then all | ||
3221 | * this nonsense will go away. | ||
3222 | */ | ||
3223 | void __init ip_static_sysctl_init(void) | ||
3224 | { | ||
3225 | register_sysctl_paths(ipv4_route_path, ipv4_route_table); | ||
3226 | } | ||
3227 | |||
3219 | EXPORT_SYMBOL(__ip_select_ident); | 3228 | EXPORT_SYMBOL(__ip_select_ident); |
3220 | EXPORT_SYMBOL(ip_route_input); | 3229 | EXPORT_SYMBOL(ip_route_input); |
3221 | EXPORT_SYMBOL(ip_route_output_key); | 3230 | EXPORT_SYMBOL(ip_route_output_key); |
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index d63e9388d92d..770d827f5ab8 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
@@ -401,13 +401,6 @@ static struct ctl_table ipv4_table[] = { | |||
401 | .proc_handler = &ipv4_local_port_range, | 401 | .proc_handler = &ipv4_local_port_range, |
402 | .strategy = &ipv4_sysctl_local_port_range, | 402 | .strategy = &ipv4_sysctl_local_port_range, |
403 | }, | 403 | }, |
404 | { | ||
405 | .ctl_name = NET_IPV4_ROUTE, | ||
406 | .procname = "route", | ||
407 | .maxlen = 0, | ||
408 | .mode = 0555, | ||
409 | .child = ipv4_route_table | ||
410 | }, | ||
411 | #ifdef CONFIG_IP_MULTICAST | 404 | #ifdef CONFIG_IP_MULTICAST |
412 | { | 405 | { |
413 | .ctl_name = NET_IPV4_IGMP_MAX_MEMBERSHIPS, | 406 | .ctl_name = NET_IPV4_IGMP_MAX_MEMBERSHIPS, |
@@ -882,11 +875,4 @@ static __init int sysctl_ipv4_init(void) | |||
882 | return 0; | 875 | return 0; |
883 | } | 876 | } |
884 | 877 | ||
885 | /* set enough of tree skeleton to get rid of ordering problems */ | ||
886 | void __init ip_static_sysctl_init(void) | ||
887 | { | ||
888 | static ctl_table table[1]; | ||
889 | register_sysctl_paths(net_ipv4_ctl_path, table); | ||
890 | } | ||
891 | |||
892 | __initcall(sysctl_ipv4_init); | 878 | __initcall(sysctl_ipv4_init); |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index c708ca842298..95055f8c3f35 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -934,6 +934,11 @@ static int __init inet6_init(void) | |||
934 | if (err) | 934 | if (err) |
935 | goto out_unregister_sock; | 935 | goto out_unregister_sock; |
936 | 936 | ||
937 | #ifdef CONFIG_SYSCTL | ||
938 | err = ipv6_static_sysctl_register(); | ||
939 | if (err) | ||
940 | goto static_sysctl_fail; | ||
941 | #endif | ||
937 | /* | 942 | /* |
938 | * ipngwg API draft makes clear that the correct semantics | 943 | * ipngwg API draft makes clear that the correct semantics |
939 | * for TCP and UDP is to consider one TCP and UDP instance | 944 | * for TCP and UDP is to consider one TCP and UDP instance |
@@ -1058,6 +1063,10 @@ ipmr_fail: | |||
1058 | icmp_fail: | 1063 | icmp_fail: |
1059 | unregister_pernet_subsys(&inet6_net_ops); | 1064 | unregister_pernet_subsys(&inet6_net_ops); |
1060 | register_pernet_fail: | 1065 | register_pernet_fail: |
1066 | #ifdef CONFIG_SYSCTL | ||
1067 | ipv6_static_sysctl_unregister(); | ||
1068 | static_sysctl_fail: | ||
1069 | #endif | ||
1061 | cleanup_ipv6_mibs(); | 1070 | cleanup_ipv6_mibs(); |
1062 | out_unregister_sock: | 1071 | out_unregister_sock: |
1063 | sock_unregister(PF_INET6); | 1072 | sock_unregister(PF_INET6); |
@@ -1113,6 +1122,9 @@ static void __exit inet6_exit(void) | |||
1113 | rawv6_exit(); | 1122 | rawv6_exit(); |
1114 | 1123 | ||
1115 | unregister_pernet_subsys(&inet6_net_ops); | 1124 | unregister_pernet_subsys(&inet6_net_ops); |
1125 | #ifdef CONFIG_SYSCTL | ||
1126 | ipv6_static_sysctl_unregister(); | ||
1127 | #endif | ||
1116 | cleanup_ipv6_mibs(); | 1128 | cleanup_ipv6_mibs(); |
1117 | proto_unregister(&rawv6_prot); | 1129 | proto_unregister(&rawv6_prot); |
1118 | proto_unregister(&udplitev6_prot); | 1130 | proto_unregister(&udplitev6_prot); |
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 5c99274558bf..e6dfaeac6be3 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c | |||
@@ -150,3 +150,19 @@ void ipv6_sysctl_unregister(void) | |||
150 | unregister_net_sysctl_table(ip6_header); | 150 | unregister_net_sysctl_table(ip6_header); |
151 | unregister_pernet_subsys(&ipv6_sysctl_net_ops); | 151 | unregister_pernet_subsys(&ipv6_sysctl_net_ops); |
152 | } | 152 | } |
153 | |||
154 | static struct ctl_table_header *ip6_base; | ||
155 | |||
156 | int ipv6_static_sysctl_register(void) | ||
157 | { | ||
158 | static struct ctl_table empty[1]; | ||
159 | ip6_base = register_net_sysctl_rotable(net_ipv6_ctl_path, empty); | ||
160 | if (ip6_base == NULL) | ||
161 | return -ENOMEM; | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | void ipv6_static_sysctl_unregister(void) | ||
166 | { | ||
167 | unregister_net_sysctl_table(ip6_base); | ||
168 | } | ||
diff --git a/net/sysctl_net.c b/net/sysctl_net.c index cefbc367d8be..972201cd5fa7 100644 --- a/net/sysctl_net.c +++ b/net/sysctl_net.c | |||
@@ -73,7 +73,9 @@ static struct ctl_table_root net_sysctl_ro_root = { | |||
73 | 73 | ||
74 | static int sysctl_net_init(struct net *net) | 74 | static int sysctl_net_init(struct net *net) |
75 | { | 75 | { |
76 | setup_sysctl_set(&net->sysctls, NULL, is_seen); | 76 | setup_sysctl_set(&net->sysctls, |
77 | &net_sysctl_ro_root.default_set, | ||
78 | is_seen); | ||
77 | return 0; | 79 | return 0; |
78 | } | 80 | } |
79 | 81 | ||
diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst index 53dae3eb3d1f..612dc13ddd85 100644 --- a/scripts/Makefile.headersinst +++ b/scripts/Makefile.headersinst | |||
@@ -1,194 +1,98 @@ | |||
1 | # ========================================================================== | 1 | # ========================================================================== |
2 | # Installing headers | 2 | # Installing headers |
3 | # | 3 | # |
4 | # header-y files will be installed verbatim | 4 | # header-y - list files to be installed. They are preprocessed |
5 | # unifdef-y are the files where unifdef will be run before installing files | 5 | # to remove __KERNEL__ section of the file |
6 | # objhdr-y are generated files that will be installed verbatim | 6 | # unifdef-y - Same as header-y. Obsolete |
7 | # objhdr-y - Same as header-y but for generated files | ||
7 | # | 8 | # |
8 | # ========================================================================== | 9 | # ========================================================================== |
9 | 10 | ||
10 | UNIFDEF := scripts/unifdef -U__KERNEL__ | 11 | # called may set destination dir (when installing to asm/) |
11 | |||
12 | # Eliminate the contents of (and inclusions of) compiler.h | ||
13 | HDRSED := sed -e "s/ inline / __inline__ /g" \ | ||
14 | -e "s/[[:space:]]__user[[:space:]]\{1,\}/ /g" \ | ||
15 | -e "s/(__user[[:space:]]\{1,\}/ (/g" \ | ||
16 | -e "s/[[:space:]]__force[[:space:]]\{1,\}/ /g" \ | ||
17 | -e "s/(__force[[:space:]]\{1,\}/ (/g" \ | ||
18 | -e "s/[[:space:]]__iomem[[:space:]]\{1,\}/ /g" \ | ||
19 | -e "s/(__iomem[[:space:]]\{1,\}/ (/g" \ | ||
20 | -e "s/[[:space:]]__attribute_const__[[:space:]]\{1,\}/\ /g" \ | ||
21 | -e "s/[[:space:]]__attribute_const__$$//" \ | ||
22 | -e "/^\#include <linux\/compiler.h>/d" | ||
23 | |||
24 | _dst := $(if $(dst),$(dst),$(obj)) | 12 | _dst := $(if $(dst),$(dst),$(obj)) |
25 | 13 | ||
26 | ifeq (,$(patsubst include/asm/%,,$(obj)/)) | 14 | kbuild-file := $(srctree)/$(obj)/Kbuild |
27 | # For producing the generated stuff in include/asm for biarch builds, include | 15 | include $(kbuild-file) |
28 | # both sets of Kbuild files; we'll generate anything which is mentioned in | ||
29 | # _either_ arch, and recurse into subdirectories which are mentioned in either | ||
30 | # arch. Since some directories may exist in one but not the other, we must | ||
31 | # use $(wildcard...). | ||
32 | GENASM := 1 | ||
33 | archasm := $(subst include/asm,asm-$(ARCH),$(obj)) | ||
34 | altarchasm := $(subst include/asm,asm-$(ALTARCH),$(obj)) | ||
35 | KBUILDFILES := $(wildcard $(srctree)/include/$(archasm)/Kbuild $(srctree)/include/$(altarchasm)/Kbuild) | ||
36 | else | ||
37 | KBUILDFILES := $(srctree)/$(obj)/Kbuild | ||
38 | endif | ||
39 | 16 | ||
40 | include $(KBUILDFILES) | 17 | include scripts/Kbuild.include |
41 | 18 | ||
42 | include scripts/Kbuild.include | 19 | install := $(INSTALL_HDR_PATH)/$(_dst) |
43 | 20 | ||
44 | # If this is include/asm-$(ARCH) and there's no $(ALTARCH), then | 21 | header-y := $(sort $(header-y) $(unifdef-y)) |
45 | # override $(_dst) so that we install to include/asm directly. | 22 | subdirs := $(patsubst %/,%,$(filter %/, $(header-y))) |
46 | # Unless $(BIASMDIR) is set, in which case we're probably doing | 23 | header-y := $(filter-out %/, $(header-y)) |
47 | # a 'headers_install_all' build and we should keep the -$(ARCH) | ||
48 | # in the directory name. | ||
49 | ifeq ($(obj)$(ALTARCH),include/asm-$(ARCH)$(BIASMDIR)) | ||
50 | _dst := include/asm | ||
51 | endif | ||
52 | 24 | ||
53 | header-y := $(sort $(header-y)) | 25 | # files used to track state of install/check |
54 | unifdef-y := $(sort $(unifdef-y)) | 26 | install-file := $(install)/.install |
55 | subdir-y := $(patsubst %/,%,$(filter %/, $(header-y))) | 27 | check-file := $(install)/.check |
56 | header-y := $(filter-out %/, $(header-y)) | ||
57 | header-y := $(filter-out $(unifdef-y),$(header-y)) | ||
58 | 28 | ||
59 | # stamp files for header checks | 29 | # all headers files for this dir |
60 | check-y := $(patsubst %,.check.%,$(header-y) $(unifdef-y) $(objhdr-y)) | 30 | all-files := $(header-y) $(objhdr-y) |
31 | input-files := $(addprefix $(srctree)/$(obj)/,$(header-y)) \ | ||
32 | $(addprefix $(objtree)/$(obj)/,$(objhdr-y)) | ||
33 | output-files := $(addprefix $(install)/, $(all-files)) | ||
61 | 34 | ||
62 | # Work out what needs to be removed | 35 | # Work out what needs to be removed |
63 | oldheaders := $(patsubst $(INSTALL_HDR_PATH)/$(_dst)/%,%,$(wildcard $(INSTALL_HDR_PATH)/$(_dst)/*.h)) | 36 | oldheaders := $(patsubst $(install)/%,%,$(wildcard $(install)/*.h)) |
64 | unwanted := $(filter-out $(header-y) $(unifdef-y) $(objhdr-y),$(oldheaders)) | 37 | unwanted := $(filter-out $(all-files),$(oldheaders)) |
65 | 38 | ||
66 | oldcheckstamps := $(patsubst $(INSTALL_HDR_PATH)/$(_dst)/%,%,$(wildcard $(INSTALL_HDR_PATH)/$(_dst)/.check.*.h)) | 39 | # Prefix unwanted with full paths to $(INSTALL_HDR_PATH) |
67 | unwanted += $(filter-out $(check-y),$(oldcheckstamps)) | 40 | unwanted-file := $(addprefix $(install)/, $(unwanted)) |
68 | 41 | ||
69 | # Prefix them all with full paths to $(INSTALL_HDR_PATH) | 42 | printdir = $(patsubst $(INSTALL_HDR_PATH)/%/,%,$(dir $@)) |
70 | header-y := $(patsubst %,$(INSTALL_HDR_PATH)/$(_dst)/%,$(header-y)) | ||
71 | unifdef-y := $(patsubst %,$(INSTALL_HDR_PATH)/$(_dst)/%,$(unifdef-y)) | ||
72 | objhdr-y := $(patsubst %,$(INSTALL_HDR_PATH)/$(_dst)/%,$(objhdr-y)) | ||
73 | check-y := $(patsubst %,$(INSTALL_HDR_PATH)/$(_dst)/%,$(check-y)) | ||
74 | 43 | ||
44 | quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\ | ||
45 | file$(if $(word 2, $(all-files)),s)) | ||
46 | cmd_install = \ | ||
47 | $(PERL) $< $(srctree)/$(obj) $(install) $(SRCARCH) $(header-y); \ | ||
48 | $(PERL) $< $(objtree)/$(obj) $(install) $(SRCARCH) $(objhdr-y); \ | ||
49 | touch $@ | ||
75 | 50 | ||
76 | ifdef ALTARCH | 51 | quiet_cmd_remove = REMOVE $(unwanted) |
77 | ifeq ($(obj),include/asm-$(ARCH)) | 52 | cmd_remove = rm -f $(unwanted-file) |
78 | altarch-y := altarch-dir | ||
79 | endif | ||
80 | endif | ||
81 | 53 | ||
82 | # Make the definitions visible for recursive make invocations | 54 | quiet_cmd_check = CHECK $(printdir) ($(words $(all-files)) files) |
83 | export ALTARCH | 55 | cmd_check = $(PERL) $< $(INSTALL_HDR_PATH)/include $(SRCARCH) \ |
84 | export ARCHDEF | 56 | $(addprefix $(install)/, $(all-files)); \ |
85 | export ALTARCHDEF | 57 | touch $@ |
86 | |||
87 | quiet_cmd_o_hdr_install = INSTALL $(patsubst $(INSTALL_HDR_PATH)/%,%,$@) | ||
88 | cmd_o_hdr_install = cp $(patsubst $(INSTALL_HDR_PATH)/$(_dst)/%,$(objtree)/$(obj)/%,$@) \ | ||
89 | $(INSTALL_HDR_PATH)/$(_dst) | ||
90 | |||
91 | quiet_cmd_headers_install = INSTALL $(patsubst $(INSTALL_HDR_PATH)/%,%,$@) | ||
92 | cmd_headers_install = $(HDRSED) $(patsubst $(INSTALL_HDR_PATH)/$(_dst)/%,$(srctree)/$(obj)/%,$@) \ | ||
93 | > $@ | ||
94 | |||
95 | quiet_cmd_unifdef = UNIFDEF $(patsubst $(INSTALL_HDR_PATH)/%,%,$@) | ||
96 | cmd_unifdef = $(UNIFDEF) $(patsubst $(INSTALL_HDR_PATH)/$(_dst)/%,$(srctree)/$(obj)/%,$@) \ | ||
97 | | $(HDRSED) > $@ || : | ||
98 | |||
99 | quiet_cmd_check = CHECK $(patsubst $(INSTALL_HDR_PATH)/$(_dst)/.check.%,$(_dst)/%,$@) | ||
100 | cmd_check = $(CONFIG_SHELL) $(srctree)/scripts/hdrcheck.sh \ | ||
101 | $(INSTALL_HDR_PATH)/include $(subst /.check.,/,$@) $@ | ||
102 | |||
103 | quiet_cmd_remove = REMOVE $(_dst)/$@ | ||
104 | cmd_remove = rm -f $(INSTALL_HDR_PATH)/$(_dst)/$@ | ||
105 | |||
106 | quiet_cmd_mkdir = MKDIR $(patsubst $(INSTALL_HDR_PATH)/%,%,$@) | ||
107 | cmd_mkdir = mkdir -p $@ | ||
108 | |||
109 | quiet_cmd_gen = GEN $(patsubst $(INSTALL_HDR_PATH)/%,%,$@) | ||
110 | cmd_gen = \ | ||
111 | FNAME=$(patsubst $(INSTALL_HDR_PATH)/$(_dst)/%,%,$@); \ | ||
112 | STUBDEF=__ASM_STUB_`echo $$FNAME | tr a-z.- A-Z__`; \ | ||
113 | (echo "/* File autogenerated by 'make headers_install' */" ; \ | ||
114 | echo "\#ifndef $$STUBDEF" ; \ | ||
115 | echo "\#define $$STUBDEF" ; \ | ||
116 | echo "\# if $(ARCHDEF)" ; \ | ||
117 | if [ -r $(subst /$(_dst)/,/include/$(archasm)/,$@) ]; then \ | ||
118 | echo "\# include <$(archasm)/$$FNAME>" ; \ | ||
119 | else \ | ||
120 | echo "\# error $(archasm)/$$FNAME does not exist in" \ | ||
121 | "the $(ARCH) architecture" ; \ | ||
122 | fi ; \ | ||
123 | echo "\# elif $(ALTARCHDEF)" ; \ | ||
124 | if [ -r $(subst /$(_dst)/,/include/$(altarchasm)/,$@) ]; then \ | ||
125 | echo "\# include <$(altarchasm)/$$FNAME>" ; \ | ||
126 | else \ | ||
127 | echo "\# error $(altarchasm)/$$FNAME does not exist in" \ | ||
128 | "the $(ALTARCH) architecture" ; \ | ||
129 | fi ; \ | ||
130 | echo "\# else" ; \ | ||
131 | echo "\# warning This machine appears to be" \ | ||
132 | "neither $(ARCH) nor $(ALTARCH)." ; \ | ||
133 | echo "\# endif" ; \ | ||
134 | echo "\#endif /* $$STUBDEF */" ; \ | ||
135 | ) > $@ | ||
136 | |||
137 | .PHONY: __headersinst __headerscheck | ||
138 | |||
139 | ifdef HDRCHECK | ||
140 | __headerscheck: $(subdir-y) $(check-y) | ||
141 | @true | ||
142 | |||
143 | $(check-y) : $(INSTALL_HDR_PATH)/$(_dst)/.check.%.h : $(INSTALL_HDR_PATH)/$(_dst)/%.h | ||
144 | $(call cmd,check) | ||
145 | |||
146 | # Other dependencies for $(check-y) | ||
147 | include /dev/null $(wildcard $(check-y)) | ||
148 | |||
149 | # ... but leave $(check-y) as .PHONY for now until those deps are actually correct. | ||
150 | .PHONY: $(check-y) | ||
151 | 58 | ||
152 | else | 59 | PHONY += __headersinst __headerscheck |
153 | # Rules for installing headers | ||
154 | __headersinst: $(subdir-y) $(header-y) $(unifdef-y) $(altarch-y) $(objhdr-y) | ||
155 | @true | ||
156 | 60 | ||
157 | $(objhdr-y) $(subdir-y) $(header-y) $(unifdef-y): | $(INSTALL_HDR_PATH)/$(_dst) $(unwanted) | 61 | ifndef HDRCHECK |
158 | 62 | # Rules for installing headers | |
159 | $(INSTALL_HDR_PATH)/$(_dst): | 63 | __headersinst: $(subdirs) $(install-file) |
160 | $(call cmd,mkdir) | 64 | @: |
161 | |||
162 | .PHONY: $(unwanted) | ||
163 | $(unwanted): | ||
164 | $(call cmd,remove) | ||
165 | 65 | ||
166 | ifdef GENASM | 66 | targets += $(install-file) |
167 | $(objhdr-y) $(header-y) $(unifdef-y): $(KBUILDFILES) | 67 | $(install-file): scripts/headers_install.pl $(input-files) FORCE |
168 | $(call cmd,gen) | 68 | $(if $(unwanted),$(call cmd,remove),) |
69 | $(if $(wildcard $(dir $@)),,$(shell mkdir -p $(dir $@))) | ||
70 | $(call if_changed,install) | ||
169 | 71 | ||
170 | else | 72 | else |
171 | $(objhdr-y) : $(INSTALL_HDR_PATH)/$(_dst)/%.h: $(objtree)/$(obj)/%.h $(KBUILDFILES) | 73 | __headerscheck: $(subdirs) $(check-file) |
172 | $(call cmd,o_hdr_install) | 74 | @: |
173 | 75 | ||
174 | $(header-y) : $(INSTALL_HDR_PATH)/$(_dst)/%.h: $(srctree)/$(obj)/%.h $(KBUILDFILES) | 76 | targets += $(check-file) |
175 | $(call cmd,headers_install) | 77 | $(check-file): scripts/headers_check.pl $(output-files) FORCE |
78 | $(call if_changed,check) | ||
176 | 79 | ||
177 | $(unifdef-y) : $(INSTALL_HDR_PATH)/$(_dst)/%.h: $(srctree)/$(obj)/%.h $(KBUILDFILES) | ||
178 | $(call cmd,unifdef) | ||
179 | endif | ||
180 | endif | 80 | endif |
181 | 81 | ||
182 | hdrinst := -rR -f $(srctree)/scripts/Makefile.headersinst obj | 82 | # Recursion |
83 | hdr-inst := -rR -f $(srctree)/scripts/Makefile.headersinst obj | ||
84 | .PHONY: $(subdirs) | ||
85 | $(subdirs): | ||
86 | $(Q)$(MAKE) $(hdr-inst)=$(obj)/$@ dst=$(_dst)/$@ | ||
183 | 87 | ||
184 | .PHONY: altarch-dir | 88 | targets := $(wildcard $(sort $(targets))) |
185 | # All the files in the normal arch dir must be created first, since we test | 89 | cmd_files := $(wildcard \ |
186 | # for their existence. | 90 | $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) |
187 | altarch-dir: $(subdir-y) $(header-y) $(unifdef-y) $(objhdr-y) | ||
188 | $(Q)$(MAKE) $(hdrinst)=include/asm-$(ALTARCH) dst=include/asm-$(ALTARCH) | ||
189 | $(Q)$(MAKE) $(hdrinst)=include/asm dst=include/asm$(BIASMDIR) | ||
190 | 91 | ||
191 | # Recursion | 92 | ifneq ($(cmd_files),) |
192 | .PHONY: $(subdir-y) | 93 | include $(cmd_files) |
193 | $(subdir-y): | 94 | endif |
194 | $(Q)$(MAKE) $(hdrinst)=$(obj)/$@ dst=$(_dst)/$@ rel=../$(rel) | 95 | |
96 | .PHONY: $(PHONY) | ||
97 | PHONY += FORCE | ||
98 | FORCE: ; | ||
diff --git a/scripts/diffconfig b/scripts/diffconfig new file mode 100755 index 000000000000..b91f3e34d44d --- /dev/null +++ b/scripts/diffconfig | |||
@@ -0,0 +1,129 @@ | |||
1 | #!/usr/bin/python | ||
2 | # | ||
3 | # diffconfig - a tool to compare .config files. | ||
4 | # | ||
5 | # originally written in 2006 by Matt Mackall | ||
6 | # (at least, this was in his bloatwatch source code) | ||
7 | # last worked on 2008 by Tim Bird | ||
8 | # | ||
9 | |||
10 | import sys, os | ||
11 | |||
12 | def usage(): | ||
13 | print """Usage: diffconfig [-h] [-m] [<config1> <config2>] | ||
14 | |||
15 | Diffconfig is a simple utility for comparing two .config files. | ||
16 | Using standard diff to compare .config files often includes extraneous and | ||
17 | distracting information. This utility produces sorted output with only the | ||
18 | changes in configuration values between the two files. | ||
19 | |||
20 | Added and removed items are shown with a leading plus or minus, respectively. | ||
21 | Changed items show the old and new values on a single line. | ||
22 | |||
23 | If -m is specified, then output will be in "merge" style, which has the | ||
24 | changed and new values in kernel config option format. | ||
25 | |||
26 | If no config files are specified, .config and .config.old are used. | ||
27 | |||
28 | Example usage: | ||
29 | $ diffconfig .config config-with-some-changes | ||
30 | -EXT2_FS_XATTR n | ||
31 | -EXT2_FS_XIP n | ||
32 | CRAMFS n -> y | ||
33 | EXT2_FS y -> n | ||
34 | LOG_BUF_SHIFT 14 -> 16 | ||
35 | PRINTK_TIME n -> y | ||
36 | """ | ||
37 | sys.exit(0) | ||
38 | |||
39 | # returns a dictionary of name/value pairs for config items in the file | ||
40 | def readconfig(config_file): | ||
41 | d = {} | ||
42 | for line in config_file: | ||
43 | line = line[:-1] | ||
44 | if line[:7] == "CONFIG_": | ||
45 | name, val = line[7:].split("=", 1) | ||
46 | d[name] = val | ||
47 | if line[-11:] == " is not set": | ||
48 | d[line[9:-11]] = "n" | ||
49 | return d | ||
50 | |||
51 | def print_config(op, config, value, new_value): | ||
52 | global merge_style | ||
53 | |||
54 | if merge_style: | ||
55 | if new_value: | ||
56 | if new_value=="n": | ||
57 | print "# CONFIG_%s is not set" % config | ||
58 | else: | ||
59 | print "CONFIG_%s=%s" % (config, new_value) | ||
60 | else: | ||
61 | if op=="-": | ||
62 | print "-%s %s" % (config, value) | ||
63 | elif op=="+": | ||
64 | print "+%s %s" % (config, new_value) | ||
65 | else: | ||
66 | print " %s %s -> %s" % (config, value, new_value) | ||
67 | |||
68 | def main(): | ||
69 | global merge_style | ||
70 | |||
71 | # parse command line args | ||
72 | if ("-h" in sys.argv or "--help" in sys.argv): | ||
73 | usage() | ||
74 | |||
75 | merge_style = 0 | ||
76 | if "-m" in sys.argv: | ||
77 | merge_style = 1 | ||
78 | sys.argv.remove("-m") | ||
79 | |||
80 | argc = len(sys.argv) | ||
81 | if not (argc==1 or argc == 3): | ||
82 | print "Error: incorrect number of arguments or unrecognized option" | ||
83 | usage() | ||
84 | |||
85 | if argc == 1: | ||
86 | # if no filenames given, assume .config and .config.old | ||
87 | build_dir="" | ||
88 | if os.environ.has_key("KBUILD_OUTPUT"): | ||
89 | build_dir = os.environ["KBUILD_OUTPUT"]+"/" | ||
90 | |||
91 | configa_filename = build_dir + ".config.old" | ||
92 | configb_filename = build_dir + ".config" | ||
93 | else: | ||
94 | configa_filename = sys.argv[1] | ||
95 | configb_filename = sys.argv[2] | ||
96 | |||
97 | a = readconfig(file(configa_filename)) | ||
98 | b = readconfig(file(configb_filename)) | ||
99 | |||
100 | # print items in a but not b (accumulate, sort and print) | ||
101 | old = [] | ||
102 | for config in a: | ||
103 | if config not in b: | ||
104 | old.append(config) | ||
105 | old.sort() | ||
106 | for config in old: | ||
107 | print_config("-", config, a[config], None) | ||
108 | del a[config] | ||
109 | |||
110 | # print items that changed (accumulate, sort, and print) | ||
111 | changed = [] | ||
112 | for config in a: | ||
113 | if a[config] != b[config]: | ||
114 | changed.append(config) | ||
115 | else: | ||
116 | del b[config] | ||
117 | changed.sort() | ||
118 | for config in changed: | ||
119 | print_config("->", config, a[config], b[config]) | ||
120 | del b[config] | ||
121 | |||
122 | # now print items in b but not in a | ||
123 | # (items from b that were in a were removed above) | ||
124 | new = b.keys() | ||
125 | new.sort() | ||
126 | for config in new: | ||
127 | print_config("+", config, None, b[config]) | ||
128 | |||
129 | main() | ||
diff --git a/scripts/hdrcheck.sh b/scripts/hdrcheck.sh deleted file mode 100755 index 31598584f871..000000000000 --- a/scripts/hdrcheck.sh +++ /dev/null | |||
@@ -1,10 +0,0 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | for FILE in `grep '^[ \t]*#[ \t]*include[ \t]*<' $2 | cut -f2 -d\< | cut -f1 -d\> | egrep ^linux\|^asm` ; do | ||
4 | if [ ! -r $1/$FILE ]; then | ||
5 | echo $2 requires $FILE, which does not exist in exported headers | ||
6 | exit 1 | ||
7 | fi | ||
8 | done | ||
9 | # FIXME: List dependencies into $3 | ||
10 | touch $3 | ||
diff --git a/scripts/headers.sh b/scripts/headers.sh new file mode 100755 index 000000000000..d33426f866db --- /dev/null +++ b/scripts/headers.sh | |||
@@ -0,0 +1,41 @@ | |||
1 | #!/bin/sh | ||
2 | # Run headers_$1 command for all suitable architectures | ||
3 | |||
4 | # Stop on error | ||
5 | set -e | ||
6 | |||
7 | do_command() | ||
8 | { | ||
9 | if [ -f ${srctree}/arch/$2/include/asm/Kbuild ]; then | ||
10 | make ARCH=$2 KBUILD_HEADERS=$1 headers_$1 | ||
11 | elif [ -f ${srctree}/include/asm-$2/Kbuild ]; then | ||
12 | make ARCH=$2 KBUILD_HEADERS=$1 headers_$1 | ||
13 | else | ||
14 | printf "Ignoring arch: %s\n" ${arch} | ||
15 | fi | ||
16 | } | ||
17 | |||
18 | # Do not try this architecture | ||
19 | drop="generic um ppc sparc64 cris" | ||
20 | |||
21 | archs=$(ls ${srctree}/arch) | ||
22 | |||
23 | for arch in ${archs}; do | ||
24 | case ${arch} in | ||
25 | um) # no userspace export | ||
26 | ;; | ||
27 | ppc) # headers exported by powerpc | ||
28 | ;; | ||
29 | sparc64) # headers exported by sparc | ||
30 | ;; | ||
31 | cris) # headers export are known broken | ||
32 | ;; | ||
33 | *) | ||
34 | if [ -d ${srctree}/arch/${arch} ]; then | ||
35 | do_command $1 ${arch} | ||
36 | fi | ||
37 | ;; | ||
38 | esac | ||
39 | done | ||
40 | |||
41 | |||
diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl new file mode 100644 index 000000000000..15d53a6b1a1f --- /dev/null +++ b/scripts/headers_check.pl | |||
@@ -0,0 +1,56 @@ | |||
1 | #!/usr/bin/perl | ||
2 | # | ||
3 | # headers_check.pl execute a number of trivial consistency checks | ||
4 | # | ||
5 | # Usage: headers_check.pl dir [files...] | ||
6 | # dir: dir to look for included files | ||
7 | # arch: architecture | ||
8 | # files: list of files to check | ||
9 | # | ||
10 | # The script reads the supplied files line by line and: | ||
11 | # | ||
12 | # 1) for each include statement it checks if the | ||
13 | # included file actually exists. | ||
14 | # Only include files located in asm* and linux* are checked. | ||
15 | # The rest are assumed to be system include files. | ||
16 | # | ||
17 | # 2) TODO: check for leaked CONFIG_ symbols | ||
18 | |||
19 | use strict; | ||
20 | use warnings; | ||
21 | |||
22 | my ($dir, $arch, @files) = @ARGV; | ||
23 | |||
24 | my $ret = 0; | ||
25 | my $line; | ||
26 | my $lineno = 0; | ||
27 | my $filename; | ||
28 | |||
29 | foreach my $file (@files) { | ||
30 | $filename = $file; | ||
31 | open(my $fh, '<', "$filename") or die "$filename: $!\n"; | ||
32 | $lineno = 0; | ||
33 | while ($line = <$fh>) { | ||
34 | $lineno++; | ||
35 | check_include(); | ||
36 | } | ||
37 | close $fh; | ||
38 | } | ||
39 | exit $ret; | ||
40 | |||
41 | sub check_include | ||
42 | { | ||
43 | if ($line =~ m/^\s*#\s*include\s+<((asm|linux).*)>/) { | ||
44 | my $inc = $1; | ||
45 | my $found; | ||
46 | $found = stat($dir . "/" . $inc); | ||
47 | if (!$found) { | ||
48 | $inc =~ s#asm/#asm-$arch/#; | ||
49 | $found = stat($dir . "/" . $inc); | ||
50 | } | ||
51 | if (!$found) { | ||
52 | printf STDERR "$filename:$lineno: included file '$inc' is not exported\n"; | ||
53 | $ret = 1; | ||
54 | } | ||
55 | } | ||
56 | } | ||
diff --git a/scripts/headers_install.pl b/scripts/headers_install.pl new file mode 100644 index 000000000000..68591cd08731 --- /dev/null +++ b/scripts/headers_install.pl | |||
@@ -0,0 +1,45 @@ | |||
1 | #!/usr/bin/perl | ||
2 | # | ||
3 | # headers_install prepare the listed header files for use in | ||
4 | # user space and copy the files to their destination. | ||
5 | # | ||
6 | # Usage: headers_install.pl readdir installdir arch [files...] | ||
7 | # readdir: dir to open files | ||
8 | # installdir: dir to install the files | ||
9 | # arch: current architecture | ||
10 | # arch is used to force a reinstallation when the arch | ||
11 | # changes because kbuild then detect a command line change. | ||
12 | # files: list of files to check | ||
13 | # | ||
14 | # Step in preparation for users space: | ||
15 | # 1) Drop all use of compiler.h definitions | ||
16 | # 2) Drop include of compiler.h | ||
17 | # 3) Drop all sections defined out by __KERNEL__ (using unifdef) | ||
18 | |||
19 | use strict; | ||
20 | use warnings; | ||
21 | |||
22 | my ($readdir, $installdir, $arch, @files) = @ARGV; | ||
23 | |||
24 | my $unifdef = "scripts/unifdef -U__KERNEL__"; | ||
25 | |||
26 | foreach my $file (@files) { | ||
27 | my $tmpfile = "$installdir/$file.tmp"; | ||
28 | open(my $infile, '<', "$readdir/$file") | ||
29 | or die "$readdir/$file: $!\n"; | ||
30 | open(my $outfile, '>', "$tmpfile") or die "$tmpfile: $!\n"; | ||
31 | while (my $line = <$infile>) { | ||
32 | $line =~ s/([\s(])__user\s/$1/g; | ||
33 | $line =~ s/([\s(])__force\s/$1/g; | ||
34 | $line =~ s/([\s(])__iomem\s/$1/g; | ||
35 | $line =~ s/\s__attribute_const__\s/ /g; | ||
36 | $line =~ s/\s__attribute_const__$//g; | ||
37 | $line =~ s/^#include <linux\/compiler.h>//; | ||
38 | printf $outfile "%s", $line; | ||
39 | } | ||
40 | close $outfile; | ||
41 | close $infile; | ||
42 | system $unifdef . " $tmpfile > $installdir/$file"; | ||
43 | unlink $tmpfile; | ||
44 | } | ||
45 | exit 0; | ||
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index fda63136ae68..9fba838c7069 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c | |||
@@ -76,7 +76,6 @@ static void check_stdin(void) | |||
76 | static int conf_askvalue(struct symbol *sym, const char *def) | 76 | static int conf_askvalue(struct symbol *sym, const char *def) |
77 | { | 77 | { |
78 | enum symbol_type type = sym_get_type(sym); | 78 | enum symbol_type type = sym_get_type(sym); |
79 | tristate val; | ||
80 | 79 | ||
81 | if (!sym_has_value(sym)) | 80 | if (!sym_has_value(sym)) |
82 | printf(_("(NEW) ")); | 81 | printf(_("(NEW) ")); |
@@ -92,15 +91,6 @@ static int conf_askvalue(struct symbol *sym, const char *def) | |||
92 | } | 91 | } |
93 | 92 | ||
94 | switch (input_mode) { | 93 | switch (input_mode) { |
95 | case set_no: | ||
96 | case set_mod: | ||
97 | case set_yes: | ||
98 | case set_random: | ||
99 | if (sym_has_value(sym)) { | ||
100 | printf("%s\n", def); | ||
101 | return 0; | ||
102 | } | ||
103 | break; | ||
104 | case ask_new: | 94 | case ask_new: |
105 | case ask_silent: | 95 | case ask_silent: |
106 | if (sym_has_value(sym)) { | 96 | if (sym_has_value(sym)) { |
@@ -112,9 +102,6 @@ static int conf_askvalue(struct symbol *sym, const char *def) | |||
112 | fflush(stdout); | 102 | fflush(stdout); |
113 | fgets(line, 128, stdin); | 103 | fgets(line, 128, stdin); |
114 | return 1; | 104 | return 1; |
115 | case set_default: | ||
116 | printf("%s\n", def); | ||
117 | return 1; | ||
118 | default: | 105 | default: |
119 | break; | 106 | break; |
120 | } | 107 | } |
@@ -128,52 +115,6 @@ static int conf_askvalue(struct symbol *sym, const char *def) | |||
128 | default: | 115 | default: |
129 | ; | 116 | ; |
130 | } | 117 | } |
131 | switch (input_mode) { | ||
132 | case set_yes: | ||
133 | if (sym_tristate_within_range(sym, yes)) { | ||
134 | line[0] = 'y'; | ||
135 | line[1] = '\n'; | ||
136 | line[2] = 0; | ||
137 | break; | ||
138 | } | ||
139 | case set_mod: | ||
140 | if (type == S_TRISTATE) { | ||
141 | if (sym_tristate_within_range(sym, mod)) { | ||
142 | line[0] = 'm'; | ||
143 | line[1] = '\n'; | ||
144 | line[2] = 0; | ||
145 | break; | ||
146 | } | ||
147 | } else { | ||
148 | if (sym_tristate_within_range(sym, yes)) { | ||
149 | line[0] = 'y'; | ||
150 | line[1] = '\n'; | ||
151 | line[2] = 0; | ||
152 | break; | ||
153 | } | ||
154 | } | ||
155 | case set_no: | ||
156 | if (sym_tristate_within_range(sym, no)) { | ||
157 | line[0] = 'n'; | ||
158 | line[1] = '\n'; | ||
159 | line[2] = 0; | ||
160 | break; | ||
161 | } | ||
162 | case set_random: | ||
163 | do { | ||
164 | val = (tristate)(rand() % 3); | ||
165 | } while (!sym_tristate_within_range(sym, val)); | ||
166 | switch (val) { | ||
167 | case no: line[0] = 'n'; break; | ||
168 | case mod: line[0] = 'm'; break; | ||
169 | case yes: line[0] = 'y'; break; | ||
170 | } | ||
171 | line[1] = '\n'; | ||
172 | line[2] = 0; | ||
173 | break; | ||
174 | default: | ||
175 | break; | ||
176 | } | ||
177 | printf("%s", line); | 118 | printf("%s", line); |
178 | return 1; | 119 | return 1; |
179 | } | 120 | } |
@@ -374,15 +315,7 @@ static int conf_choice(struct menu *menu) | |||
374 | else | 315 | else |
375 | continue; | 316 | continue; |
376 | break; | 317 | break; |
377 | case set_random: | 318 | default: |
378 | if (is_new) | ||
379 | def = (rand() % cnt) + 1; | ||
380 | case set_default: | ||
381 | case set_yes: | ||
382 | case set_mod: | ||
383 | case set_no: | ||
384 | cnt = def; | ||
385 | printf("%d\n", cnt); | ||
386 | break; | 319 | break; |
387 | } | 320 | } |
388 | 321 | ||
@@ -494,6 +427,43 @@ static void check_conf(struct menu *menu) | |||
494 | check_conf(child); | 427 | check_conf(child); |
495 | } | 428 | } |
496 | 429 | ||
430 | static void conf_do_update(void) | ||
431 | { | ||
432 | /* Update until a loop caused no more changes */ | ||
433 | do { | ||
434 | conf_cnt = 0; | ||
435 | check_conf(&rootmenu); | ||
436 | } while (conf_cnt); | ||
437 | } | ||
438 | |||
439 | static int conf_silent_update(void) | ||
440 | { | ||
441 | const char *name; | ||
442 | |||
443 | if (conf_get_changed()) { | ||
444 | name = getenv("KCONFIG_NOSILENTUPDATE"); | ||
445 | if (name && *name) { | ||
446 | fprintf(stderr, | ||
447 | _("\n*** Kernel configuration requires explicit update.\n\n")); | ||
448 | return 1; | ||
449 | } | ||
450 | conf_do_update(); | ||
451 | } | ||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | static int conf_update(void) | ||
456 | { | ||
457 | rootEntry = &rootmenu; | ||
458 | conf(&rootmenu); | ||
459 | if (input_mode == ask_all) { | ||
460 | input_mode = ask_silent; | ||
461 | valid_stdin = 1; | ||
462 | } | ||
463 | conf_do_update(); | ||
464 | return 0; | ||
465 | } | ||
466 | |||
497 | int main(int ac, char **av) | 467 | int main(int ac, char **av) |
498 | { | 468 | { |
499 | int opt; | 469 | int opt; |
@@ -599,36 +569,43 @@ int main(int ac, char **av) | |||
599 | default: | 569 | default: |
600 | break; | 570 | break; |
601 | } | 571 | } |
572 | switch (input_mode) { | ||
573 | case set_no: | ||
574 | conf_set_all_new_symbols(def_no); | ||
575 | break; | ||
576 | case set_yes: | ||
577 | conf_set_all_new_symbols(def_yes); | ||
578 | break; | ||
579 | case set_mod: | ||
580 | conf_set_all_new_symbols(def_mod); | ||
581 | break; | ||
582 | case set_random: | ||
583 | conf_set_all_new_symbols(def_random); | ||
584 | break; | ||
585 | case set_default: | ||
586 | conf_set_all_new_symbols(def_default); | ||
587 | break; | ||
588 | case ask_silent: | ||
589 | case ask_new: | ||
590 | if (conf_silent_update()) | ||
591 | exit(1); | ||
592 | break; | ||
593 | case ask_all: | ||
594 | if (conf_update()) | ||
595 | exit(1); | ||
596 | break; | ||
597 | } | ||
602 | 598 | ||
603 | if (input_mode != ask_silent) { | 599 | if (conf_get_changed() && conf_write(NULL)) { |
604 | rootEntry = &rootmenu; | ||
605 | conf(&rootmenu); | ||
606 | if (input_mode == ask_all) { | ||
607 | input_mode = ask_silent; | ||
608 | valid_stdin = 1; | ||
609 | } | ||
610 | } else if (conf_get_changed()) { | ||
611 | name = getenv("KCONFIG_NOSILENTUPDATE"); | ||
612 | if (name && *name) { | ||
613 | fprintf(stderr, _("\n*** Kernel configuration requires explicit update.\n\n")); | ||
614 | return 1; | ||
615 | } | ||
616 | } else | ||
617 | goto skip_check; | ||
618 | |||
619 | do { | ||
620 | conf_cnt = 0; | ||
621 | check_conf(&rootmenu); | ||
622 | } while (conf_cnt); | ||
623 | if (conf_write(NULL)) { | ||
624 | fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); | 600 | fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); |
625 | return 1; | 601 | exit(1); |
626 | } | 602 | } |
627 | skip_check: | 603 | /* ask_silent is used during the build so we shall update autoconf. |
604 | * All other commands are only used to generate a config. | ||
605 | */ | ||
628 | if (input_mode == ask_silent && conf_write_autoconf()) { | 606 | if (input_mode == ask_silent && conf_write_autoconf()) { |
629 | fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); | 607 | fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); |
630 | return 1; | 608 | return 1; |
631 | } | 609 | } |
632 | |||
633 | return 0; | 610 | return 0; |
634 | } | 611 | } |
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index ee5fe943d58d..07597611cc50 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
@@ -812,3 +812,73 @@ void conf_set_changed_callback(void (*fn)(void)) | |||
812 | { | 812 | { |
813 | conf_changed_callback = fn; | 813 | conf_changed_callback = fn; |
814 | } | 814 | } |
815 | |||
816 | |||
817 | void conf_set_all_new_symbols(enum conf_def_mode mode) | ||
818 | { | ||
819 | struct symbol *sym, *csym; | ||
820 | struct property *prop; | ||
821 | struct expr *e; | ||
822 | int i, cnt, def; | ||
823 | |||
824 | for_all_symbols(i, sym) { | ||
825 | if (sym_has_value(sym)) | ||
826 | continue; | ||
827 | switch (sym_get_type(sym)) { | ||
828 | case S_BOOLEAN: | ||
829 | case S_TRISTATE: | ||
830 | switch (mode) { | ||
831 | case def_yes: | ||
832 | sym->def[S_DEF_USER].tri = yes; | ||
833 | break; | ||
834 | case def_mod: | ||
835 | sym->def[S_DEF_USER].tri = mod; | ||
836 | break; | ||
837 | case def_no: | ||
838 | sym->def[S_DEF_USER].tri = no; | ||
839 | break; | ||
840 | case def_random: | ||
841 | sym->def[S_DEF_USER].tri = (tristate)(rand() % 3); | ||
842 | break; | ||
843 | default: | ||
844 | continue; | ||
845 | } | ||
846 | if (!sym_is_choice(sym) || mode != def_random) | ||
847 | sym->flags |= SYMBOL_DEF_USER; | ||
848 | break; | ||
849 | default: | ||
850 | break; | ||
851 | } | ||
852 | |||
853 | } | ||
854 | |||
855 | if (modules_sym) | ||
856 | sym_calc_value(modules_sym); | ||
857 | |||
858 | if (mode != def_random) | ||
859 | return; | ||
860 | |||
861 | for_all_symbols(i, csym) { | ||
862 | if (sym_has_value(csym) || !sym_is_choice(csym)) | ||
863 | continue; | ||
864 | |||
865 | sym_calc_value(csym); | ||
866 | prop = sym_get_choice_prop(csym); | ||
867 | def = -1; | ||
868 | while (1) { | ||
869 | cnt = 0; | ||
870 | expr_list_for_each_sym(prop->expr, e, sym) { | ||
871 | if (sym->visible == no) | ||
872 | continue; | ||
873 | if (def == cnt++) { | ||
874 | csym->def[S_DEF_USER].val = sym; | ||
875 | break; | ||
876 | } | ||
877 | } | ||
878 | if (def >= 0 || cnt < 2) | ||
879 | break; | ||
880 | def = (rand() % cnt) + 1; | ||
881 | } | ||
882 | csym->flags |= SYMBOL_DEF_USER; | ||
883 | } | ||
884 | } | ||
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 96521cb087ec..4a9af6f7886b 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h | |||
@@ -42,6 +42,14 @@ extern "C" { | |||
42 | #define TF_PARAM 0x0002 | 42 | #define TF_PARAM 0x0002 |
43 | #define TF_OPTION 0x0004 | 43 | #define TF_OPTION 0x0004 |
44 | 44 | ||
45 | enum conf_def_mode { | ||
46 | def_default, | ||
47 | def_yes, | ||
48 | def_mod, | ||
49 | def_no, | ||
50 | def_random | ||
51 | }; | ||
52 | |||
45 | #define T_OPT_MODULES 1 | 53 | #define T_OPT_MODULES 1 |
46 | #define T_OPT_DEFCONFIG_LIST 2 | 54 | #define T_OPT_DEFCONFIG_LIST 2 |
47 | #define T_OPT_ENV 3 | 55 | #define T_OPT_ENV 3 |
@@ -69,6 +77,7 @@ const char *conf_get_configname(void); | |||
69 | char *conf_get_default_confname(void); | 77 | char *conf_get_default_confname(void); |
70 | void sym_set_change_count(int count); | 78 | void sym_set_change_count(int count); |
71 | void sym_add_change_count(int count); | 79 | void sym_add_change_count(int count); |
80 | void conf_set_all_new_symbols(enum conf_def_mode mode); | ||
72 | 81 | ||
73 | /* kconfig_load.c */ | 82 | /* kconfig_load.c */ |
74 | void kconfig_load(void); | 83 | void kconfig_load(void); |
diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 88e3934a8b8c..d8f77e26081c 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc | |||
@@ -1643,6 +1643,7 @@ sub dump_function($$) { | |||
1643 | $prototype =~ s/^__always_inline +//; | 1643 | $prototype =~ s/^__always_inline +//; |
1644 | $prototype =~ s/^noinline +//; | 1644 | $prototype =~ s/^noinline +//; |
1645 | $prototype =~ s/__devinit +//; | 1645 | $prototype =~ s/__devinit +//; |
1646 | $prototype =~ s/__init +//; | ||
1646 | $prototype =~ s/^#define\s+//; #ak added | 1647 | $prototype =~ s/^#define\s+//; #ak added |
1647 | $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//; | 1648 | $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//; |
1648 | 1649 | ||
diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 1c1bdaf7348a..83b75126c9f7 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion | |||
@@ -12,7 +12,9 @@ cd "${1:-.}" || usage | |||
12 | if head=`git rev-parse --verify HEAD 2>/dev/null`; then | 12 | if head=`git rev-parse --verify HEAD 2>/dev/null`; then |
13 | # Do we have an untagged version? | 13 | # Do we have an untagged version? |
14 | if git name-rev --tags HEAD | grep -E '^HEAD[[:space:]]+(.*~[0-9]*|undefined)$' > /dev/null; then | 14 | if git name-rev --tags HEAD | grep -E '^HEAD[[:space:]]+(.*~[0-9]*|undefined)$' > /dev/null; then |
15 | git describe | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' | 15 | if tag=`git describe 2>/dev/null`; then |
16 | echo $tag | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' | ||
17 | fi | ||
16 | fi | 18 | fi |
17 | 19 | ||
18 | # Are there uncommitted changes? | 20 | # Are there uncommitted changes? |
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index dbe63db4bfd6..4d4b8ddc26ba 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c | |||
@@ -325,6 +325,7 @@ static int __devinit snd_cs423x_pnp_init_mpu(int dev, struct pnp_dev *pdev) | |||
325 | static int __devinit snd_card_cs4232_pnp(int dev, struct snd_card_cs4236 *acard, | 325 | static int __devinit snd_card_cs4232_pnp(int dev, struct snd_card_cs4236 *acard, |
326 | struct pnp_dev *pdev) | 326 | struct pnp_dev *pdev) |
327 | { | 327 | { |
328 | acard->wss = pdev; | ||
328 | if (snd_cs423x_pnp_init_wss(dev, acard->wss) < 0) | 329 | if (snd_cs423x_pnp_init_wss(dev, acard->wss) < 0) |
329 | return -EBUSY; | 330 | return -EBUSY; |
330 | cport[dev] = -1; | 331 | cport[dev] = -1; |
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 41c047e665ec..0797ca441a37 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c | |||
@@ -68,7 +68,9 @@ MODULE_SUPPORTED_DEVICE("{{OPTi,82C924 (AD1848)}," | |||
68 | static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ | 68 | static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ |
69 | static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ | 69 | static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ |
70 | //static int enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */ | 70 | //static int enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */ |
71 | #ifdef CONFIG_PNP | ||
71 | static int isapnp = 1; /* Enable ISA PnP detection */ | 72 | static int isapnp = 1; /* Enable ISA PnP detection */ |
73 | #endif | ||
72 | static long port = SNDRV_DEFAULT_PORT1; /* 0x530,0xe80,0xf40,0x604 */ | 74 | static long port = SNDRV_DEFAULT_PORT1; /* 0x530,0xe80,0xf40,0x604 */ |
73 | static long mpu_port = SNDRV_DEFAULT_PORT1; /* 0x300,0x310,0x320,0x330 */ | 75 | static long mpu_port = SNDRV_DEFAULT_PORT1; /* 0x300,0x310,0x320,0x330 */ |
74 | static long fm_port = SNDRV_DEFAULT_PORT1; /* 0x388 */ | 76 | static long fm_port = SNDRV_DEFAULT_PORT1; /* 0x388 */ |
@@ -85,8 +87,10 @@ module_param(id, charp, 0444); | |||
85 | MODULE_PARM_DESC(id, "ID string for opti9xx based soundcard."); | 87 | MODULE_PARM_DESC(id, "ID string for opti9xx based soundcard."); |
86 | //module_param(enable, bool, 0444); | 88 | //module_param(enable, bool, 0444); |
87 | //MODULE_PARM_DESC(enable, "Enable opti9xx soundcard."); | 89 | //MODULE_PARM_DESC(enable, "Enable opti9xx soundcard."); |
90 | #ifdef CONFIG_PNP | ||
88 | module_param(isapnp, bool, 0444); | 91 | module_param(isapnp, bool, 0444); |
89 | MODULE_PARM_DESC(isapnp, "Enable ISA PnP detection for specified soundcard."); | 92 | MODULE_PARM_DESC(isapnp, "Enable ISA PnP detection for specified soundcard."); |
93 | #endif | ||
90 | module_param(port, long, 0444); | 94 | module_param(port, long, 0444); |
91 | MODULE_PARM_DESC(port, "WSS port # for opti9xx driver."); | 95 | MODULE_PARM_DESC(port, "WSS port # for opti9xx driver."); |
92 | module_param(mpu_port, long, 0444); | 96 | module_param(mpu_port, long, 0444); |
@@ -688,7 +692,7 @@ static void snd_card_opti9xx_free(struct snd_card *card) | |||
688 | if (chip) { | 692 | if (chip) { |
689 | #ifdef OPTi93X | 693 | #ifdef OPTi93X |
690 | struct snd_cs4231 *codec = chip->codec; | 694 | struct snd_cs4231 *codec = chip->codec; |
691 | if (codec->irq > 0) { | 695 | if (codec && codec->irq > 0) { |
692 | disable_irq(codec->irq); | 696 | disable_irq(codec->irq); |
693 | free_irq(codec->irq, codec); | 697 | free_irq(codec->irq, codec); |
694 | } | 698 | } |
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 07364c00768a..8c49a00a5e39 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c | |||
@@ -161,6 +161,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { | |||
161 | { 0x50534304, 0xffffffff, "UCB1400", patch_ucb1400, NULL }, | 161 | { 0x50534304, 0xffffffff, "UCB1400", patch_ucb1400, NULL }, |
162 | { 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH }, | 162 | { 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH }, |
163 | { 0x54524102, 0xffffffff, "TR28022", NULL, NULL }, | 163 | { 0x54524102, 0xffffffff, "TR28022", NULL, NULL }, |
164 | { 0x54524103, 0xffffffff, "TR28023", NULL, NULL }, | ||
164 | { 0x54524106, 0xffffffff, "TR28026", NULL, NULL }, | 165 | { 0x54524106, 0xffffffff, "TR28026", NULL, NULL }, |
165 | { 0x54524108, 0xffffffff, "TR28028", patch_tritech_tr28028, NULL }, // added by xin jin [07/09/99] | 166 | { 0x54524108, 0xffffffff, "TR28028", patch_tritech_tr28028, NULL }, // added by xin jin [07/09/99] |
166 | { 0x54524123, 0xffffffff, "TR28602", NULL, NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)] | 167 | { 0x54524123, 0xffffffff, "TR28602", NULL, NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)] |
@@ -169,7 +170,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { | |||
169 | { 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF | 170 | { 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF |
170 | { 0x56494182, 0xffffffff, "VIA1618", NULL, NULL }, | 171 | { 0x56494182, 0xffffffff, "VIA1618", NULL, NULL }, |
171 | { 0x57454301, 0xffffffff, "W83971D", NULL, NULL }, | 172 | { 0x57454301, 0xffffffff, "W83971D", NULL, NULL }, |
172 | { 0x574d4c00, 0xffffffff, "WM9701A", NULL, NULL }, | 173 | { 0x574d4c00, 0xffffffff, "WM9701,WM9701A", NULL, NULL }, |
173 | { 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL}, | 174 | { 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL}, |
174 | { 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q", patch_wolfson04, NULL}, | 175 | { 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q", patch_wolfson04, NULL}, |
175 | { 0x574d4C05, 0xffffffff, "WM9705,WM9710", patch_wolfson05, NULL}, | 176 | { 0x574d4C05, 0xffffffff, "WM9705,WM9710", patch_wolfson05, NULL}, |
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 0746e9ccc20b..f4fbc795ee81 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c | |||
@@ -3381,8 +3381,8 @@ static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97, | |||
3381 | } | 3381 | } |
3382 | 3382 | ||
3383 | /* create a virtual master control and add slaves */ | 3383 | /* create a virtual master control and add slaves */ |
3384 | int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name, | 3384 | static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name, |
3385 | const unsigned int *tlv, const char **slaves) | 3385 | const unsigned int *tlv, const char **slaves) |
3386 | { | 3386 | { |
3387 | struct snd_kcontrol *kctl; | 3387 | struct snd_kcontrol *kctl; |
3388 | const char **s; | 3388 | const char **s; |
diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h index 7e3e8942d073..974e05122f00 100644 --- a/sound/pci/azt3328.h +++ b/sound/pci/azt3328.h | |||
@@ -94,7 +94,7 @@ enum azf_freq_t { | |||
94 | AZF_FREQ(48000), | 94 | AZF_FREQ(48000), |
95 | AZF_FREQ(66200), | 95 | AZF_FREQ(66200), |
96 | #undef AZF_FREQ | 96 | #undef AZF_FREQ |
97 | } AZF_FREQUENCIES; | 97 | }; |
98 | 98 | ||
99 | /** recording area (see also: playback bit flag definitions) **/ | 99 | /** recording area (see also: playback bit flag definitions) **/ |
100 | #define IDX_IO_REC_FLAGS 0x20 /* ??, PU:0x0000 */ | 100 | #define IDX_IO_REC_FLAGS 0x20 /* ??, PU:0x0000 */ |
@@ -210,7 +210,7 @@ enum azf_freq_t { | |||
210 | 210 | ||
211 | enum { | 211 | enum { |
212 | AZF_GAME_LEGACY_IO_PORT = 0x200 | 212 | AZF_GAME_LEGACY_IO_PORT = 0x200 |
213 | } AZF_GAME_CONFIGS; | 213 | }; |
214 | 214 | ||
215 | #define IDX_GAME_LEGACY_COMPATIBLE 0x00 | 215 | #define IDX_GAME_LEGACY_COMPATIBLE 0x00 |
216 | /* in some operation mode, writing anything to this port | 216 | /* in some operation mode, writing anything to this port |
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index fbf1124f7c79..9bf95367c882 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c | |||
@@ -522,7 +522,7 @@ static unsigned int snd_es1371_wait_src_ready(struct ensoniq * ensoniq) | |||
522 | return r; | 522 | return r; |
523 | cond_resched(); | 523 | cond_resched(); |
524 | } | 524 | } |
525 | snd_printk(KERN_ERR "wait source ready timeout 0x%lx [0x%x]\n", | 525 | snd_printk(KERN_ERR "wait src ready timeout 0x%lx [0x%x]\n", |
526 | ES_REG(ensoniq, 1371_SMPRATE), r); | 526 | ES_REG(ensoniq, 1371_SMPRATE), r); |
527 | return 0; | 527 | return 0; |
528 | } | 528 | } |
@@ -1629,6 +1629,7 @@ static int __devinit snd_ensoniq_1371_mixer(struct ensoniq *ensoniq, | |||
1629 | memset(&ac97, 0, sizeof(ac97)); | 1629 | memset(&ac97, 0, sizeof(ac97)); |
1630 | ac97.private_data = ensoniq; | 1630 | ac97.private_data = ensoniq; |
1631 | ac97.private_free = snd_ensoniq_mixer_free_ac97; | 1631 | ac97.private_free = snd_ensoniq_mixer_free_ac97; |
1632 | ac97.pci = ensoniq->pci; | ||
1632 | ac97.scaps = AC97_SCAP_AUDIO; | 1633 | ac97.scaps = AC97_SCAP_AUDIO; |
1633 | if ((err = snd_ac97_mixer(pbus, &ac97, &ensoniq->u.es1371.ac97)) < 0) | 1634 | if ((err = snd_ac97_mixer(pbus, &ac97, &ensoniq->u.es1371.ac97)) < 0) |
1634 | return err; | 1635 | return err; |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 16715a68ba5e..ef9f072b47fc 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -1047,9 +1047,13 @@ static int azx_setup_periods(struct azx *chip, | |||
1047 | pos_adj = bdl_pos_adj[chip->dev_index]; | 1047 | pos_adj = bdl_pos_adj[chip->dev_index]; |
1048 | if (pos_adj > 0) { | 1048 | if (pos_adj > 0) { |
1049 | struct snd_pcm_runtime *runtime = substream->runtime; | 1049 | struct snd_pcm_runtime *runtime = substream->runtime; |
1050 | int pos_align = pos_adj; | ||
1050 | pos_adj = (pos_adj * runtime->rate + 47999) / 48000; | 1051 | pos_adj = (pos_adj * runtime->rate + 47999) / 48000; |
1051 | if (!pos_adj) | 1052 | if (!pos_adj) |
1052 | pos_adj = 1; | 1053 | pos_adj = pos_align; |
1054 | else | ||
1055 | pos_adj = ((pos_adj + pos_align - 1) / pos_align) * | ||
1056 | pos_align; | ||
1053 | pos_adj = frames_to_bytes(runtime, pos_adj); | 1057 | pos_adj = frames_to_bytes(runtime, pos_adj); |
1054 | if (pos_adj >= period_bytes) { | 1058 | if (pos_adj >= period_bytes) { |
1055 | snd_printk(KERN_WARNING "Too big adjustment %d\n", | 1059 | snd_printk(KERN_WARNING "Too big adjustment %d\n", |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 2807bc840d26..add4e87e0b20 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -122,6 +122,8 @@ enum { | |||
122 | /* ALC269 models */ | 122 | /* ALC269 models */ |
123 | enum { | 123 | enum { |
124 | ALC269_BASIC, | 124 | ALC269_BASIC, |
125 | ALC269_ASUS_EEEPC_P703, | ||
126 | ALC269_ASUS_EEEPC_P901, | ||
125 | ALC269_AUTO, | 127 | ALC269_AUTO, |
126 | ALC269_MODEL_LAST /* last tag */ | 128 | ALC269_MODEL_LAST /* last tag */ |
127 | }; | 129 | }; |
@@ -7905,6 +7907,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
7905 | SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), | 7907 | SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), |
7906 | SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), | 7908 | SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), |
7907 | SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), | 7909 | SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), |
7910 | SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), | ||
7908 | SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */ | 7911 | SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */ |
7909 | SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), | 7912 | SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), |
7910 | SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), | 7913 | SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), |
@@ -10946,7 +10949,23 @@ static int patch_alc268(struct hda_codec *codec) | |||
10946 | 10949 | ||
10947 | static hda_nid_t alc269_adc_nids[1] = { | 10950 | static hda_nid_t alc269_adc_nids[1] = { |
10948 | /* ADC1 */ | 10951 | /* ADC1 */ |
10949 | 0x07, | 10952 | 0x08, |
10953 | }; | ||
10954 | |||
10955 | static struct hda_input_mux alc269_eeepc_dmic_capture_source = { | ||
10956 | .num_items = 2, | ||
10957 | .items = { | ||
10958 | { "i-Mic", 0x5 }, | ||
10959 | { "e-Mic", 0x0 }, | ||
10960 | }, | ||
10961 | }; | ||
10962 | |||
10963 | static struct hda_input_mux alc269_eeepc_amic_capture_source = { | ||
10964 | .num_items = 2, | ||
10965 | .items = { | ||
10966 | { "i-Mic", 0x1 }, | ||
10967 | { "e-Mic", 0x0 }, | ||
10968 | }, | ||
10950 | }; | 10969 | }; |
10951 | 10970 | ||
10952 | #define alc269_modes alc260_modes | 10971 | #define alc269_modes alc260_modes |
@@ -10968,10 +10987,27 @@ static struct snd_kcontrol_new alc269_base_mixer[] = { | |||
10968 | { } /* end */ | 10987 | { } /* end */ |
10969 | }; | 10988 | }; |
10970 | 10989 | ||
10990 | /* bind volumes of both NID 0x0c and 0x0d */ | ||
10991 | static struct hda_bind_ctls alc269_epc_bind_vol = { | ||
10992 | .ops = &snd_hda_bind_vol, | ||
10993 | .values = { | ||
10994 | HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), | ||
10995 | HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), | ||
10996 | 0 | ||
10997 | }, | ||
10998 | }; | ||
10999 | |||
11000 | static struct snd_kcontrol_new alc269_eeepc_mixer[] = { | ||
11001 | HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
11002 | HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol), | ||
11003 | HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
11004 | { } /* end */ | ||
11005 | }; | ||
11006 | |||
10971 | /* capture mixer elements */ | 11007 | /* capture mixer elements */ |
10972 | static struct snd_kcontrol_new alc269_capture_mixer[] = { | 11008 | static struct snd_kcontrol_new alc269_capture_mixer[] = { |
10973 | HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), | 11009 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), |
10974 | HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), | 11010 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), |
10975 | { | 11011 | { |
10976 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 11012 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
10977 | /* The multiple "Capture Source" controls confuse alsamixer | 11013 | /* The multiple "Capture Source" controls confuse alsamixer |
@@ -10987,6 +11023,13 @@ static struct snd_kcontrol_new alc269_capture_mixer[] = { | |||
10987 | { } /* end */ | 11023 | { } /* end */ |
10988 | }; | 11024 | }; |
10989 | 11025 | ||
11026 | /* capture mixer elements */ | ||
11027 | static struct snd_kcontrol_new alc269_epc_capture_mixer[] = { | ||
11028 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
11029 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
11030 | { } /* end */ | ||
11031 | }; | ||
11032 | |||
10990 | /* | 11033 | /* |
10991 | * generic initialization of ADC, input mixers and output mixers | 11034 | * generic initialization of ADC, input mixers and output mixers |
10992 | */ | 11035 | */ |
@@ -10994,7 +11037,7 @@ static struct hda_verb alc269_init_verbs[] = { | |||
10994 | /* | 11037 | /* |
10995 | * Unmute ADC0 and set the default input to mic-in | 11038 | * Unmute ADC0 and set the default input to mic-in |
10996 | */ | 11039 | */ |
10997 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 11040 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
10998 | 11041 | ||
10999 | /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the | 11042 | /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the |
11000 | * analog-loopback mixer widget | 11043 | * analog-loopback mixer widget |
@@ -11057,6 +11100,98 @@ static struct hda_verb alc269_init_verbs[] = { | |||
11057 | { } | 11100 | { } |
11058 | }; | 11101 | }; |
11059 | 11102 | ||
11103 | static struct hda_verb alc269_eeepc_dmic_init_verbs[] = { | ||
11104 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
11105 | {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, | ||
11106 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, | ||
11107 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, | ||
11108 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
11109 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, | ||
11110 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
11111 | {} | ||
11112 | }; | ||
11113 | |||
11114 | static struct hda_verb alc269_eeepc_amic_init_verbs[] = { | ||
11115 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
11116 | {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
11117 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, | ||
11118 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))}, | ||
11119 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, | ||
11120 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
11121 | {} | ||
11122 | }; | ||
11123 | |||
11124 | /* toggle speaker-output according to the hp-jack state */ | ||
11125 | static void alc269_speaker_automute(struct hda_codec *codec) | ||
11126 | { | ||
11127 | unsigned int present; | ||
11128 | unsigned int bits; | ||
11129 | |||
11130 | present = snd_hda_codec_read(codec, 0x15, 0, | ||
11131 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
11132 | bits = present ? AMP_IN_MUTE(0) : 0; | ||
11133 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | ||
11134 | AMP_IN_MUTE(0), bits); | ||
11135 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | ||
11136 | AMP_IN_MUTE(0), bits); | ||
11137 | } | ||
11138 | |||
11139 | static void alc269_eeepc_dmic_automute(struct hda_codec *codec) | ||
11140 | { | ||
11141 | unsigned int present; | ||
11142 | |||
11143 | present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0) | ||
11144 | & AC_PINSENSE_PRESENCE; | ||
11145 | snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL, | ||
11146 | present ? 0 : 5); | ||
11147 | } | ||
11148 | |||
11149 | static void alc269_eeepc_amic_automute(struct hda_codec *codec) | ||
11150 | { | ||
11151 | unsigned int present; | ||
11152 | |||
11153 | present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0) | ||
11154 | & AC_PINSENSE_PRESENCE; | ||
11155 | snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
11156 | present ? AMP_IN_UNMUTE(0) : AMP_IN_MUTE(0)); | ||
11157 | snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
11158 | present ? AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1)); | ||
11159 | } | ||
11160 | |||
11161 | /* unsolicited event for HP jack sensing */ | ||
11162 | static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec, | ||
11163 | unsigned int res) | ||
11164 | { | ||
11165 | if ((res >> 26) == ALC880_HP_EVENT) | ||
11166 | alc269_speaker_automute(codec); | ||
11167 | |||
11168 | if ((res >> 26) == ALC880_MIC_EVENT) | ||
11169 | alc269_eeepc_dmic_automute(codec); | ||
11170 | } | ||
11171 | |||
11172 | static void alc269_eeepc_dmic_inithook(struct hda_codec *codec) | ||
11173 | { | ||
11174 | alc269_speaker_automute(codec); | ||
11175 | alc269_eeepc_dmic_automute(codec); | ||
11176 | } | ||
11177 | |||
11178 | /* unsolicited event for HP jack sensing */ | ||
11179 | static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec, | ||
11180 | unsigned int res) | ||
11181 | { | ||
11182 | if ((res >> 26) == ALC880_HP_EVENT) | ||
11183 | alc269_speaker_automute(codec); | ||
11184 | |||
11185 | if ((res >> 26) == ALC880_MIC_EVENT) | ||
11186 | alc269_eeepc_amic_automute(codec); | ||
11187 | } | ||
11188 | |||
11189 | static void alc269_eeepc_amic_inithook(struct hda_codec *codec) | ||
11190 | { | ||
11191 | alc269_speaker_automute(codec); | ||
11192 | alc269_eeepc_amic_automute(codec); | ||
11193 | } | ||
11194 | |||
11060 | /* add playback controls from the parsed DAC table */ | 11195 | /* add playback controls from the parsed DAC table */ |
11061 | static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec, | 11196 | static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec, |
11062 | const struct auto_pin_cfg *cfg) | 11197 | const struct auto_pin_cfg *cfg) |
@@ -11188,6 +11323,9 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
11188 | if (err < 0) | 11323 | if (err < 0) |
11189 | return err; | 11324 | return err; |
11190 | 11325 | ||
11326 | spec->mixers[spec->num_mixers] = alc269_capture_mixer; | ||
11327 | spec->num_mixers++; | ||
11328 | |||
11191 | return 1; | 11329 | return 1; |
11192 | } | 11330 | } |
11193 | 11331 | ||
@@ -11215,12 +11353,16 @@ static const char *alc269_models[ALC269_MODEL_LAST] = { | |||
11215 | }; | 11353 | }; |
11216 | 11354 | ||
11217 | static struct snd_pci_quirk alc269_cfg_tbl[] = { | 11355 | static struct snd_pci_quirk alc269_cfg_tbl[] = { |
11356 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", | ||
11357 | ALC269_ASUS_EEEPC_P703), | ||
11358 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", | ||
11359 | ALC269_ASUS_EEEPC_P901), | ||
11218 | {} | 11360 | {} |
11219 | }; | 11361 | }; |
11220 | 11362 | ||
11221 | static struct alc_config_preset alc269_presets[] = { | 11363 | static struct alc_config_preset alc269_presets[] = { |
11222 | [ALC269_BASIC] = { | 11364 | [ALC269_BASIC] = { |
11223 | .mixers = { alc269_base_mixer }, | 11365 | .mixers = { alc269_base_mixer, alc269_capture_mixer }, |
11224 | .init_verbs = { alc269_init_verbs }, | 11366 | .init_verbs = { alc269_init_verbs }, |
11225 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | 11367 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), |
11226 | .dac_nids = alc269_dac_nids, | 11368 | .dac_nids = alc269_dac_nids, |
@@ -11229,6 +11371,32 @@ static struct alc_config_preset alc269_presets[] = { | |||
11229 | .channel_mode = alc269_modes, | 11371 | .channel_mode = alc269_modes, |
11230 | .input_mux = &alc269_capture_source, | 11372 | .input_mux = &alc269_capture_source, |
11231 | }, | 11373 | }, |
11374 | [ALC269_ASUS_EEEPC_P703] = { | ||
11375 | .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer }, | ||
11376 | .init_verbs = { alc269_init_verbs, | ||
11377 | alc269_eeepc_amic_init_verbs }, | ||
11378 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
11379 | .dac_nids = alc269_dac_nids, | ||
11380 | .hp_nid = 0x03, | ||
11381 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
11382 | .channel_mode = alc269_modes, | ||
11383 | .input_mux = &alc269_eeepc_amic_capture_source, | ||
11384 | .unsol_event = alc269_eeepc_amic_unsol_event, | ||
11385 | .init_hook = alc269_eeepc_amic_inithook, | ||
11386 | }, | ||
11387 | [ALC269_ASUS_EEEPC_P901] = { | ||
11388 | .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer}, | ||
11389 | .init_verbs = { alc269_init_verbs, | ||
11390 | alc269_eeepc_dmic_init_verbs }, | ||
11391 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
11392 | .dac_nids = alc269_dac_nids, | ||
11393 | .hp_nid = 0x03, | ||
11394 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
11395 | .channel_mode = alc269_modes, | ||
11396 | .input_mux = &alc269_eeepc_dmic_capture_source, | ||
11397 | .unsol_event = alc269_eeepc_dmic_unsol_event, | ||
11398 | .init_hook = alc269_eeepc_dmic_inithook, | ||
11399 | }, | ||
11232 | }; | 11400 | }; |
11233 | 11401 | ||
11234 | static int patch_alc269(struct hda_codec *codec) | 11402 | static int patch_alc269(struct hda_codec *codec) |
@@ -11282,8 +11450,6 @@ static int patch_alc269(struct hda_codec *codec) | |||
11282 | 11450 | ||
11283 | spec->adc_nids = alc269_adc_nids; | 11451 | spec->adc_nids = alc269_adc_nids; |
11284 | spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); | 11452 | spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); |
11285 | spec->mixers[spec->num_mixers] = alc269_capture_mixer; | ||
11286 | spec->num_mixers++; | ||
11287 | 11453 | ||
11288 | codec->patch_ops = alc_patch_ops; | 11454 | codec->patch_ops = alc_patch_ops; |
11289 | if (board_config == ALC269_AUTO) | 11455 | if (board_config == ALC269_AUTO) |
@@ -12994,6 +13160,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { | |||
12994 | SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), | 13160 | SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), |
12995 | SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), | 13161 | SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), |
12996 | SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), | 13162 | SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), |
13163 | SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO), | ||
12997 | SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), | 13164 | SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), |
12998 | SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), | 13165 | SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), |
12999 | SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), | 13166 | SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 08cb77f51880..7fdafcb0015d 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -94,6 +94,9 @@ enum { | |||
94 | STAC_INTEL_MAC_V3, | 94 | STAC_INTEL_MAC_V3, |
95 | STAC_INTEL_MAC_V4, | 95 | STAC_INTEL_MAC_V4, |
96 | STAC_INTEL_MAC_V5, | 96 | STAC_INTEL_MAC_V5, |
97 | STAC_INTEL_MAC_AUTO, /* This model is selected if no module parameter | ||
98 | * is given, one of the above models will be | ||
99 | * chosen according to the subsystem id. */ | ||
97 | /* for backward compatibility */ | 100 | /* for backward compatibility */ |
98 | STAC_MACMINI, | 101 | STAC_MACMINI, |
99 | STAC_MACBOOK, | 102 | STAC_MACBOOK, |
@@ -1483,6 +1486,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { | |||
1483 | [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs, | 1486 | [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs, |
1484 | [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs, | 1487 | [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs, |
1485 | [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs, | 1488 | [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs, |
1489 | [STAC_INTEL_MAC_AUTO] = intel_mac_v3_pin_configs, | ||
1486 | /* for backward compatibility */ | 1490 | /* for backward compatibility */ |
1487 | [STAC_MACMINI] = intel_mac_v3_pin_configs, | 1491 | [STAC_MACMINI] = intel_mac_v3_pin_configs, |
1488 | [STAC_MACBOOK] = intel_mac_v5_pin_configs, | 1492 | [STAC_MACBOOK] = intel_mac_v5_pin_configs, |
@@ -1505,6 +1509,7 @@ static const char *stac922x_models[STAC_922X_MODELS] = { | |||
1505 | [STAC_INTEL_MAC_V3] = "intel-mac-v3", | 1509 | [STAC_INTEL_MAC_V3] = "intel-mac-v3", |
1506 | [STAC_INTEL_MAC_V4] = "intel-mac-v4", | 1510 | [STAC_INTEL_MAC_V4] = "intel-mac-v4", |
1507 | [STAC_INTEL_MAC_V5] = "intel-mac-v5", | 1511 | [STAC_INTEL_MAC_V5] = "intel-mac-v5", |
1512 | [STAC_INTEL_MAC_AUTO] = "intel-mac-auto", | ||
1508 | /* for backward compatibility */ | 1513 | /* for backward compatibility */ |
1509 | [STAC_MACMINI] = "macmini", | 1514 | [STAC_MACMINI] = "macmini", |
1510 | [STAC_MACBOOK] = "macbook", | 1515 | [STAC_MACBOOK] = "macbook", |
@@ -1576,9 +1581,9 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { | |||
1576 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707, | 1581 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707, |
1577 | "Intel D945P", STAC_D945GTP5), | 1582 | "Intel D945P", STAC_D945GTP5), |
1578 | /* other systems */ | 1583 | /* other systems */ |
1579 | /* Apple Mac Mini (early 2006) */ | 1584 | /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */ |
1580 | SND_PCI_QUIRK(0x8384, 0x7680, | 1585 | SND_PCI_QUIRK(0x8384, 0x7680, |
1581 | "Mac Mini", STAC_INTEL_MAC_V3), | 1586 | "Mac", STAC_INTEL_MAC_AUTO), |
1582 | /* Dell systems */ | 1587 | /* Dell systems */ |
1583 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7, | 1588 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7, |
1584 | "unknown Dell", STAC_922X_DELL_D81), | 1589 | "unknown Dell", STAC_922X_DELL_D81), |
@@ -3725,7 +3730,7 @@ static int patch_stac922x(struct hda_codec *codec) | |||
3725 | spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, | 3730 | spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, |
3726 | stac922x_models, | 3731 | stac922x_models, |
3727 | stac922x_cfg_tbl); | 3732 | stac922x_cfg_tbl); |
3728 | if (spec->board_config == STAC_INTEL_MAC_V3) { | 3733 | if (spec->board_config == STAC_INTEL_MAC_AUTO) { |
3729 | spec->gpio_mask = spec->gpio_dir = 0x03; | 3734 | spec->gpio_mask = spec->gpio_dir = 0x03; |
3730 | spec->gpio_data = 0x03; | 3735 | spec->gpio_data = 0x03; |
3731 | /* Intel Macs have all same PCI SSID, so we need to check | 3736 | /* Intel Macs have all same PCI SSID, so we need to check |
@@ -3757,6 +3762,9 @@ static int patch_stac922x(struct hda_codec *codec) | |||
3757 | case 0x106b2200: | 3762 | case 0x106b2200: |
3758 | spec->board_config = STAC_INTEL_MAC_V5; | 3763 | spec->board_config = STAC_INTEL_MAC_V5; |
3759 | break; | 3764 | break; |
3765 | default: | ||
3766 | spec->board_config = STAC_INTEL_MAC_V3; | ||
3767 | break; | ||
3760 | } | 3768 | } |
3761 | } | 3769 | } |
3762 | 3770 | ||
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index ba4b5c199f21..9384702c7ebd 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c | |||
@@ -231,7 +231,7 @@ static int au1xpsc_i2s_stop(struct au1xpsc_audio_data *pscdata, int stype) | |||
231 | 231 | ||
232 | /* if both TX and RX are idle, disable PSC */ | 232 | /* if both TX and RX are idle, disable PSC */ |
233 | stat = au_readl(I2S_STAT(pscdata)); | 233 | stat = au_readl(I2S_STAT(pscdata)); |
234 | if (!(stat & (PSC_I2SSTAT_RB | PSC_I2SSTAT_RB))) { | 234 | if (!(stat & (PSC_I2SSTAT_TB | PSC_I2SSTAT_RB))) { |
235 | au_writel(0, I2S_CFG(pscdata)); | 235 | au_writel(0, I2S_CFG(pscdata)); |
236 | au_sync(); | 236 | au_sync(); |
237 | au_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata)); | 237 | au_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata)); |
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 9fc8edd82225..1fb7f9a7aecd 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c | |||
@@ -427,20 +427,20 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
427 | {"HPOUTR", NULL, "Headphone PGA"}, | 427 | {"HPOUTR", NULL, "Headphone PGA"}, |
428 | {"Headphone PGA", NULL, "Right HP Mixer"}, | 428 | {"Headphone PGA", NULL, "Right HP Mixer"}, |
429 | 429 | ||
430 | /* mono hp mixer */ | 430 | /* mono mixer */ |
431 | {"Mono HP Mixer", NULL, "Left HP Mixer"}, | 431 | {"Mono Mixer", NULL, "Left HP Mixer"}, |
432 | {"Mono HP Mixer", NULL, "Right HP Mixer"}, | 432 | {"Mono Mixer", NULL, "Right HP Mixer"}, |
433 | 433 | ||
434 | /* Out3 Mux */ | 434 | /* Out3 Mux */ |
435 | {"Out3 Mux", "Left", "Left HP Mixer"}, | 435 | {"Out3 Mux", "Left", "Left HP Mixer"}, |
436 | {"Out3 Mux", "Mono", "Phone Mixer"}, | 436 | {"Out3 Mux", "Mono", "Phone Mixer"}, |
437 | {"Out3 Mux", "Left + Right", "Mono HP Mixer"}, | 437 | {"Out3 Mux", "Left + Right", "Mono Mixer"}, |
438 | {"Out 3 PGA", NULL, "Out3 Mux"}, | 438 | {"Out 3 PGA", NULL, "Out3 Mux"}, |
439 | {"OUT3", NULL, "Out 3 PGA"}, | 439 | {"OUT3", NULL, "Out 3 PGA"}, |
440 | 440 | ||
441 | /* speaker Mux */ | 441 | /* speaker Mux */ |
442 | {"Speaker Mux", "Speaker Mix", "Speaker Mixer"}, | 442 | {"Speaker Mux", "Speaker Mix", "Speaker Mixer"}, |
443 | {"Speaker Mux", "Headphone Mix", "Mono HP Mixer"}, | 443 | {"Speaker Mux", "Headphone Mix", "Mono Mixer"}, |
444 | {"Speaker PGA", NULL, "Speaker Mux"}, | 444 | {"Speaker PGA", NULL, "Speaker Mux"}, |
445 | {"LOUT2", NULL, "Speaker PGA"}, | 445 | {"LOUT2", NULL, "Speaker PGA"}, |
446 | {"ROUT2", NULL, "Speaker PGA"}, | 446 | {"ROUT2", NULL, "Speaker PGA"}, |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 2c87061c2a6b..820347c9ae4b 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -523,24 +523,6 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | |||
523 | continue; | 523 | continue; |
524 | } | 524 | } |
525 | 525 | ||
526 | /* programmable gain/attenuation */ | ||
527 | if (w->id == snd_soc_dapm_pga) { | ||
528 | int on; | ||
529 | in = is_connected_input_ep(w); | ||
530 | dapm_clear_walk(w->codec); | ||
531 | out = is_connected_output_ep(w); | ||
532 | dapm_clear_walk(w->codec); | ||
533 | w->power = on = (out != 0 && in != 0) ? 1 : 0; | ||
534 | |||
535 | if (!on) | ||
536 | dapm_set_pga(w, on); /* lower volume to reduce pops */ | ||
537 | dapm_update_bits(w); | ||
538 | if (on) | ||
539 | dapm_set_pga(w, on); /* restore volume from zero */ | ||
540 | |||
541 | continue; | ||
542 | } | ||
543 | |||
544 | /* pre and post event widgets */ | 526 | /* pre and post event widgets */ |
545 | if (w->id == snd_soc_dapm_pre) { | 527 | if (w->id == snd_soc_dapm_pre) { |
546 | if (!w->event) | 528 | if (!w->event) |
@@ -586,45 +568,56 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | |||
586 | power_change = (w->power == power) ? 0: 1; | 568 | power_change = (w->power == power) ? 0: 1; |
587 | w->power = power; | 569 | w->power = power; |
588 | 570 | ||
571 | if (!power_change) | ||
572 | continue; | ||
573 | |||
589 | /* call any power change event handlers */ | 574 | /* call any power change event handlers */ |
590 | if (power_change) { | 575 | if (w->event) |
591 | if (w->event) { | 576 | pr_debug("power %s event for %s flags %x\n", |
592 | pr_debug("power %s event for %s flags %x\n", | 577 | w->power ? "on" : "off", |
593 | w->power ? "on" : "off", w->name, w->event_flags); | 578 | w->name, w->event_flags); |
594 | if (power) { | 579 | |
595 | /* power up event */ | 580 | /* power up pre event */ |
596 | if (w->event_flags & SND_SOC_DAPM_PRE_PMU) { | 581 | if (power && w->event && |
597 | ret = w->event(w, | 582 | (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { |
598 | NULL, SND_SOC_DAPM_PRE_PMU); | 583 | ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); |
599 | if (ret < 0) | 584 | if (ret < 0) |
600 | return ret; | 585 | return ret; |
601 | } | 586 | } |
602 | dapm_update_bits(w); | 587 | |
603 | if (w->event_flags & SND_SOC_DAPM_POST_PMU){ | 588 | /* power down pre event */ |
604 | ret = w->event(w, | 589 | if (!power && w->event && |
605 | NULL, SND_SOC_DAPM_POST_PMU); | 590 | (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { |
606 | if (ret < 0) | 591 | ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); |
607 | return ret; | 592 | if (ret < 0) |
608 | } | 593 | return ret; |
609 | } else { | 594 | } |
610 | /* power down event */ | 595 | |
611 | if (w->event_flags & SND_SOC_DAPM_PRE_PMD) { | 596 | /* Lower PGA volume to reduce pops */ |
612 | ret = w->event(w, | 597 | if (w->id == snd_soc_dapm_pga && !power) |
613 | NULL, SND_SOC_DAPM_PRE_PMD); | 598 | dapm_set_pga(w, power); |
614 | if (ret < 0) | 599 | |
615 | return ret; | 600 | dapm_update_bits(w); |
616 | } | 601 | |
617 | dapm_update_bits(w); | 602 | /* Raise PGA volume to reduce pops */ |
618 | if (w->event_flags & SND_SOC_DAPM_POST_PMD) { | 603 | if (w->id == snd_soc_dapm_pga && power) |
619 | ret = w->event(w, | 604 | dapm_set_pga(w, power); |
620 | NULL, SND_SOC_DAPM_POST_PMD); | 605 | |
621 | if (ret < 0) | 606 | /* power up post event */ |
622 | return ret; | 607 | if (power && w->event && |
623 | } | 608 | (w->event_flags & SND_SOC_DAPM_POST_PMU)) { |
624 | } | 609 | ret = w->event(w, |
625 | } else | 610 | NULL, SND_SOC_DAPM_POST_PMU); |
626 | /* no event handler */ | 611 | if (ret < 0) |
627 | dapm_update_bits(w); | 612 | return ret; |
613 | } | ||
614 | |||
615 | /* power down post event */ | ||
616 | if (!power && w->event && | ||
617 | (w->event_flags & SND_SOC_DAPM_POST_PMD)) { | ||
618 | ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); | ||
619 | if (ret < 0) | ||
620 | return ret; | ||
628 | } | 621 | } |
629 | } | 622 | } |
630 | } | 623 | } |