diff options
170 files changed, 3694 insertions, 8628 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index b2361667839f..a13d69b2217d 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -422,7 +422,8 @@ and is between 256 and 4096 characters. It is defined in the file | |||
422 | hpet= [X86-32,HPET] option to control HPET usage | 422 | hpet= [X86-32,HPET] option to control HPET usage |
423 | Format: { enable (default) | disable | force } | 423 | Format: { enable (default) | disable | force } |
424 | disable: disable HPET and use PIT instead | 424 | disable: disable HPET and use PIT instead |
425 | force: allow force enabled of undocumented chips (ICH4, VIA) | 425 | force: allow force enabled of undocumented chips (ICH4, |
426 | VIA, nVidia) | ||
426 | 427 | ||
427 | com20020= [HW,NET] ARCnet - COM20020 chipset | 428 | com20020= [HW,NET] ARCnet - COM20020 chipset |
428 | Format: | 429 | Format: |
diff --git a/Documentation/scsi/sym53c8xx_2.txt b/Documentation/scsi/sym53c8xx_2.txt index 3d9f06bb3d00..49ea5c58c6bc 100644 --- a/Documentation/scsi/sym53c8xx_2.txt +++ b/Documentation/scsi/sym53c8xx_2.txt | |||
@@ -449,25 +449,14 @@ options as above. | |||
449 | cmd_per_lun=#tags (#tags > 1) tagged command queuing enabled | 449 | cmd_per_lun=#tags (#tags > 1) tagged command queuing enabled |
450 | #tags will be truncated to the max queued commands configuration parameter. | 450 | #tags will be truncated to the max queued commands configuration parameter. |
451 | 451 | ||
452 | 10.2.2 Detailed control of tagged commands | 452 | 10.2.2 Burst max |
453 | This option allows you to specify a command queue depth for each device | ||
454 | that supports tagged command queueing. | ||
455 | Example: | ||
456 | tag_ctrl=10/t2t3q16-t5q24/t1u2q32 | ||
457 | will set devices queue depth as follow: | ||
458 | - controller #0 target #2 and target #3 -> 16 commands, | ||
459 | - controller #0 target #5 -> 24 commands, | ||
460 | - controller #1 target #1 logical unit #2 -> 32 commands, | ||
461 | - all other logical units (all targets, all controllers) -> 10 commands. | ||
462 | |||
463 | 10.2.3 Burst max | ||
464 | burst=0 burst disabled | 453 | burst=0 burst disabled |
465 | burst=255 get burst length from initial IO register settings. | 454 | burst=255 get burst length from initial IO register settings. |
466 | burst=#x burst enabled (1<<#x burst transfers max) | 455 | burst=#x burst enabled (1<<#x burst transfers max) |
467 | #x is an integer value which is log base 2 of the burst transfers max. | 456 | #x is an integer value which is log base 2 of the burst transfers max. |
468 | By default the driver uses the maximum value supported by the chip. | 457 | By default the driver uses the maximum value supported by the chip. |
469 | 458 | ||
470 | 10.2.4 LED support | 459 | 10.2.3 LED support |
471 | led=1 enable LED support | 460 | led=1 enable LED support |
472 | led=0 disable LED support | 461 | led=0 disable LED support |
473 | Do not enable LED support if your scsi board does not use SDMS BIOS. | 462 | Do not enable LED support if your scsi board does not use SDMS BIOS. |
@@ -560,9 +549,9 @@ Previously, the sym2 driver accepted arguments of the form | |||
560 | sym53c8xx=tags:4,sync:10,debug:0x200 | 549 | sym53c8xx=tags:4,sync:10,debug:0x200 |
561 | 550 | ||
562 | As a result of the new module parameters, this is no longer available. | 551 | As a result of the new module parameters, this is no longer available. |
563 | Most of the options have remained the same, but tags has split into | 552 | Most of the options have remained the same, but tags has become |
564 | cmd_per_lun and tag_ctrl for its two different purposes. The sample above | 553 | cmd_per_lun to reflect its different purposes. The sample above would |
565 | would be specified as: | 554 | be specified as: |
566 | modprobe sym53c8xx cmd_per_lun=4 sync=10 debug=0x200 | 555 | modprobe sym53c8xx cmd_per_lun=4 sync=10 debug=0x200 |
567 | 556 | ||
568 | or on the kernel boot line as: | 557 | or on the kernel boot line as: |
diff --git a/Documentation/watchdog/src/watchdog-simple.c b/Documentation/watchdog/src/watchdog-simple.c index 47801bc7e742..4cf72f3fa8e9 100644 --- a/Documentation/watchdog/src/watchdog-simple.c +++ b/Documentation/watchdog/src/watchdog-simple.c | |||
@@ -3,15 +3,25 @@ | |||
3 | #include <unistd.h> | 3 | #include <unistd.h> |
4 | #include <fcntl.h> | 4 | #include <fcntl.h> |
5 | 5 | ||
6 | int main(int argc, const char *argv[]) { | 6 | int main(void) |
7 | { | ||
7 | int fd = open("/dev/watchdog", O_WRONLY); | 8 | int fd = open("/dev/watchdog", O_WRONLY); |
9 | int ret = 0; | ||
8 | if (fd == -1) { | 10 | if (fd == -1) { |
9 | perror("watchdog"); | 11 | perror("watchdog"); |
10 | exit(1); | 12 | exit(EXIT_FAILURE); |
11 | } | 13 | } |
12 | while (1) { | 14 | while (1) { |
13 | write(fd, "\0", 1); | 15 | ret = write(fd, "\0", 1); |
14 | fsync(fd); | 16 | if (ret != 1) { |
17 | ret = -1; | ||
18 | break; | ||
19 | } | ||
20 | ret = fsync(fd); | ||
21 | if (ret) | ||
22 | break; | ||
15 | sleep(10); | 23 | sleep(10); |
16 | } | 24 | } |
25 | close(fd); | ||
26 | return ret; | ||
17 | } | 27 | } |
diff --git a/MAINTAINERS b/MAINTAINERS index 9d0ae8d2915f..76b857157866 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -314,6 +314,12 @@ M: Juergen Fischer <fischer@norbit.de> | |||
314 | L: linux-scsi@vger.kernel.org | 314 | L: linux-scsi@vger.kernel.org |
315 | S: Maintained | 315 | S: Maintained |
316 | 316 | ||
317 | AIC7XXX / AIC79XX SCSI DRIVER | ||
318 | P: Hannes Reinecke | ||
319 | M: hare@suse.de | ||
320 | L: linux-scsi@vger.kernel.org | ||
321 | S: Maintained | ||
322 | |||
317 | ALCATEL SPEEDTOUCH USB DRIVER | 323 | ALCATEL SPEEDTOUCH USB DRIVER |
318 | P: Duncan Sands | 324 | P: Duncan Sands |
319 | M: duncan.sands@free.fr | 325 | M: duncan.sands@free.fr |
diff --git a/arch/arm/mach-pxa/pxa300.c b/arch/arm/mach-pxa/pxa300.c index 5363b1322652..7a34231f3172 100644 --- a/arch/arm/mach-pxa/pxa300.c +++ b/arch/arm/mach-pxa/pxa300.c | |||
@@ -23,8 +23,10 @@ static struct pxa3xx_mfp_addr_map pxa300_mfp_addr_map[] __initdata = { | |||
23 | 23 | ||
24 | MFP_ADDR_X(GPIO0, GPIO2, 0x00b4), | 24 | MFP_ADDR_X(GPIO0, GPIO2, 0x00b4), |
25 | MFP_ADDR_X(GPIO3, GPIO26, 0x027c), | 25 | MFP_ADDR_X(GPIO3, GPIO26, 0x027c), |
26 | MFP_ADDR_X(GPIO27, GPIO127, 0x0400), | 26 | MFP_ADDR_X(GPIO27, GPIO98, 0x0400), |
27 | MFP_ADDR_X(GPIO0_2, GPIO6_2, 0x02ec), | 27 | MFP_ADDR_X(GPIO99, GPIO127, 0x0600), |
28 | MFP_ADDR_X(GPIO0_2, GPIO1_2, 0x0674), | ||
29 | MFP_ADDR_X(GPIO2_2, GPIO6_2, 0x02dc), | ||
28 | 30 | ||
29 | MFP_ADDR(nBE0, 0x0204), | 31 | MFP_ADDR(nBE0, 0x0204), |
30 | MFP_ADDR(nBE1, 0x0208), | 32 | MFP_ADDR(nBE1, 0x0208), |
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index 74e89f8fb3ab..190a09ad18eb 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c | |||
@@ -1132,7 +1132,7 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) | |||
1132 | unsigned int vecitr, veclen, vecstride; | 1132 | unsigned int vecitr, veclen, vecstride; |
1133 | struct op *fop; | 1133 | struct op *fop; |
1134 | 1134 | ||
1135 | vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK)) * 2; | 1135 | vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK)); |
1136 | 1136 | ||
1137 | fop = (op == FOP_EXT) ? &fops_ext[FEXT_TO_IDX(inst)] : &fops[FOP_TO_IDX(op)]; | 1137 | fop = (op == FOP_EXT) ? &fops_ext[FEXT_TO_IDX(inst)] : &fops[FOP_TO_IDX(op)]; |
1138 | 1138 | ||
@@ -1184,10 +1184,10 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) | |||
1184 | * CHECK: It appears to be undefined whether we stop when | 1184 | * CHECK: It appears to be undefined whether we stop when |
1185 | * we encounter an exception. We continue. | 1185 | * we encounter an exception. We continue. |
1186 | */ | 1186 | */ |
1187 | dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 6); | 1187 | dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 3); |
1188 | dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 6); | 1188 | dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 3); |
1189 | if (FREG_BANK(dm) != 0) | 1189 | if (FREG_BANK(dm) != 0) |
1190 | dm = FREG_BANK(dm) + ((FREG_IDX(dm) + vecstride) & 6); | 1190 | dm = FREG_BANK(dm) + ((FREG_IDX(dm) + vecstride) & 3); |
1191 | } | 1191 | } |
1192 | return exceptions; | 1192 | return exceptions; |
1193 | 1193 | ||
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index eea3f50743d5..b4e210df92f2 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -229,7 +229,7 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) | |||
229 | /* | 229 | /* |
230 | * Enable access to the VFP so we can handle the bounce. | 230 | * Enable access to the VFP so we can handle the bounce. |
231 | */ | 231 | */ |
232 | fmxr(FPEXC, fpexc & ~(FPEXC_EX|FPEXC_INV|FPEXC_UFC|FPEXC_IOC)); | 232 | fmxr(FPEXC, fpexc & ~(FPEXC_EX|FPEXC_FPV2|FPEXC_INV|FPEXC_UFC|FPEXC_OFC|FPEXC_IOC)); |
233 | 233 | ||
234 | orig_fpscr = fpscr = fmrx(FPSCR); | 234 | orig_fpscr = fpscr = fmrx(FPSCR); |
235 | 235 | ||
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 5bed8be34ba5..b4437ce0f973 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -1270,6 +1270,8 @@ source "drivers/Kconfig" | |||
1270 | 1270 | ||
1271 | source "fs/Kconfig" | 1271 | source "fs/Kconfig" |
1272 | 1272 | ||
1273 | source "kernel/Kconfig.instrumentation" | ||
1274 | |||
1273 | source "arch/i386/Kconfig.debug" | 1275 | source "arch/i386/Kconfig.debug" |
1274 | 1276 | ||
1275 | source "security/Kconfig" | 1277 | source "security/Kconfig" |
diff --git a/arch/i386/Makefile b/arch/i386/Makefile index b81cb64d48e5..f5b9a37def8b 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile | |||
@@ -20,6 +20,12 @@ | |||
20 | # Fill in SRCARCH | 20 | # Fill in SRCARCH |
21 | SRCARCH := x86 | 21 | SRCARCH := x86 |
22 | 22 | ||
23 | # BITS is used as extension for files which are available in a 32 bit | ||
24 | # and a 64 bit version to simplify shared Makefiles. | ||
25 | # e.g.: obj-y += foo_$(BITS).o | ||
26 | BITS := 32 | ||
27 | export BITS | ||
28 | |||
23 | HAS_BIARCH := $(call cc-option-yn, -m32) | 29 | HAS_BIARCH := $(call cc-option-yn, -m32) |
24 | ifeq ($(HAS_BIARCH),y) | 30 | ifeq ($(HAS_BIARCH),y) |
25 | AS := $(AS) --32 | 31 | AS := $(AS) --32 |
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 03c4e5c1b94a..bd59ab0760b3 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig | |||
@@ -460,8 +460,6 @@ source "drivers/Kconfig" | |||
460 | 460 | ||
461 | source "drivers/sbus/char/Kconfig" | 461 | source "drivers/sbus/char/Kconfig" |
462 | 462 | ||
463 | source "drivers/fc4/Kconfig" | ||
464 | |||
465 | source "fs/Kconfig" | 463 | source "fs/Kconfig" |
466 | 464 | ||
467 | source "kernel/Kconfig.instrumentation" | 465 | source "kernel/Kconfig.instrumentation" |
diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h index 20bab9431acb..5f9a2e72a731 100644 --- a/arch/x86/boot/boot.h +++ b/arch/x86/boot/boot.h | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include <linux/edd.h> | 24 | #include <linux/edd.h> |
25 | #include <asm/boot.h> | 25 | #include <asm/boot.h> |
26 | #include <asm/bootparam.h> | 26 | #include <asm/setup.h> |
27 | 27 | ||
28 | /* Useful macros */ | 28 | /* Useful macros */ |
29 | #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) | 29 | #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) |
diff --git a/arch/x86/boot/compressed/relocs.c b/arch/x86/boot/compressed/relocs.c index 2d77ee728f92..7a0d00b2cf28 100644 --- a/arch/x86/boot/compressed/relocs.c +++ b/arch/x86/boot/compressed/relocs.c | |||
@@ -38,11 +38,9 @@ static const char* safe_abs_relocs[] = { | |||
38 | 38 | ||
39 | static int is_safe_abs_reloc(const char* sym_name) | 39 | static int is_safe_abs_reloc(const char* sym_name) |
40 | { | 40 | { |
41 | int i, array_size; | 41 | int i; |
42 | |||
43 | array_size = sizeof(safe_abs_relocs)/sizeof(char*); | ||
44 | 42 | ||
45 | for(i = 0; i < array_size; i++) { | 43 | for(i = 0; i < ARRAY_SIZE(safe_abs_relocs); i++) { |
46 | if (!strcmp(sym_name, safe_abs_relocs[i])) | 44 | if (!strcmp(sym_name, safe_abs_relocs[i])) |
47 | /* Match found */ | 45 | /* Match found */ |
48 | return 1; | 46 | return 1; |
diff --git a/arch/x86/boot/main.c b/arch/x86/boot/main.c index 0eeef3989a17..1f95750ede28 100644 --- a/arch/x86/boot/main.c +++ b/arch/x86/boot/main.c | |||
@@ -26,8 +26,6 @@ char *heap_end = _end; /* Default end of heap = no heap */ | |||
26 | * screws up the old-style command line protocol, adjust by | 26 | * screws up the old-style command line protocol, adjust by |
27 | * filling in the new-style command line pointer instead. | 27 | * filling in the new-style command line pointer instead. |
28 | */ | 28 | */ |
29 | #define OLD_CL_MAGIC 0xA33F | ||
30 | #define OLD_CL_ADDRESS 0x20 | ||
31 | 29 | ||
32 | static void copy_boot_params(void) | 30 | static void copy_boot_params(void) |
33 | { | 31 | { |
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile index 18dcdc6fb7aa..46bb609e2444 100644 --- a/arch/x86/crypto/Makefile +++ b/arch/x86/crypto/Makefile | |||
@@ -1,5 +1,15 @@ | |||
1 | ifeq ($(CONFIG_X86_32),y) | 1 | # |
2 | include ${srctree}/arch/x86/crypto/Makefile_32 | 2 | # Arch-specific CryptoAPI modules. |
3 | else | 3 | # |
4 | include ${srctree}/arch/x86/crypto/Makefile_64 | 4 | |
5 | endif | 5 | obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o |
6 | obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o | ||
7 | |||
8 | obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o | ||
9 | obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o | ||
10 | |||
11 | aes-i586-y := aes-i586-asm_32.o aes_32.o | ||
12 | twofish-i586-y := twofish-i586-asm_32.o twofish_32.o | ||
13 | |||
14 | aes-x86_64-y := aes-x86_64-asm_64.o aes_64.o | ||
15 | twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_64.o | ||
diff --git a/arch/x86/crypto/Makefile_32 b/arch/x86/crypto/Makefile_32 deleted file mode 100644 index 2d873a2388ed..000000000000 --- a/arch/x86/crypto/Makefile_32 +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | # | ||
2 | # x86/crypto/Makefile | ||
3 | # | ||
4 | # Arch-specific CryptoAPI modules. | ||
5 | # | ||
6 | |||
7 | obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o | ||
8 | obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o | ||
9 | |||
10 | aes-i586-y := aes-i586-asm_32.o aes_32.o | ||
11 | twofish-i586-y := twofish-i586-asm_32.o twofish_32.o | ||
12 | |||
diff --git a/arch/x86/crypto/Makefile_64 b/arch/x86/crypto/Makefile_64 deleted file mode 100644 index b40896276e93..000000000000 --- a/arch/x86/crypto/Makefile_64 +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | # | ||
2 | # x86/crypto/Makefile | ||
3 | # | ||
4 | # Arch-specific CryptoAPI modules. | ||
5 | # | ||
6 | |||
7 | obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o | ||
8 | obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o | ||
9 | |||
10 | aes-x86_64-y := aes-x86_64-asm_64.o aes_64.o | ||
11 | twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_64.o | ||
12 | |||
diff --git a/arch/x86/kernel/Makefile_32 b/arch/x86/kernel/Makefile_32 index ccea590bbb92..b9d679820306 100644 --- a/arch/x86/kernel/Makefile_32 +++ b/arch/x86/kernel/Makefile_32 | |||
@@ -26,7 +26,7 @@ obj-$(CONFIG_X86_MPPARSE) += mpparse_32.o | |||
26 | obj-$(CONFIG_X86_LOCAL_APIC) += apic_32.o nmi_32.o | 26 | obj-$(CONFIG_X86_LOCAL_APIC) += apic_32.o nmi_32.o |
27 | obj-$(CONFIG_X86_IO_APIC) += io_apic_32.o | 27 | obj-$(CONFIG_X86_IO_APIC) += io_apic_32.o |
28 | obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o | 28 | obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o |
29 | obj-$(CONFIG_KEXEC) += machine_kexec_32.o relocate_kernel_32.o crash_32.o | 29 | obj-$(CONFIG_KEXEC) += machine_kexec_32.o relocate_kernel_32.o crash.o |
30 | obj-$(CONFIG_CRASH_DUMP) += crash_dump_32.o | 30 | obj-$(CONFIG_CRASH_DUMP) += crash_dump_32.o |
31 | obj-$(CONFIG_X86_NUMAQ) += numaq_32.o | 31 | obj-$(CONFIG_X86_NUMAQ) += numaq_32.o |
32 | obj-$(CONFIG_X86_SUMMIT_NUMA) += summit_32.o | 32 | obj-$(CONFIG_X86_SUMMIT_NUMA) += summit_32.o |
diff --git a/arch/x86/kernel/Makefile_64 b/arch/x86/kernel/Makefile_64 index dec06e769281..466337ae9a1e 100644 --- a/arch/x86/kernel/Makefile_64 +++ b/arch/x86/kernel/Makefile_64 | |||
@@ -9,25 +9,21 @@ obj-y := process_64.o signal_64.o entry_64.o traps_64.o irq_64.o \ | |||
9 | x8664_ksyms_64.o i387_64.o syscall_64.o vsyscall_64.o \ | 9 | x8664_ksyms_64.o i387_64.o syscall_64.o vsyscall_64.o \ |
10 | setup64.o bootflag.o e820_64.o reboot_64.o quirks.o i8237.o \ | 10 | setup64.o bootflag.o e820_64.o reboot_64.o quirks.o i8237.o \ |
11 | pci-dma_64.o pci-nommu_64.o alternative.o hpet.o tsc_64.o bugs_64.o \ | 11 | pci-dma_64.o pci-nommu_64.o alternative.o hpet.o tsc_64.o bugs_64.o \ |
12 | perfctr-watchdog.o i8253.o | 12 | i8253.o |
13 | 13 | ||
14 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 14 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
15 | obj-$(CONFIG_X86_MCE) += mce_64.o therm_throt.o | 15 | obj-y += cpu/ |
16 | obj-$(CONFIG_X86_MCE_INTEL) += mce_intel_64.o | 16 | obj-y += acpi/ |
17 | obj-$(CONFIG_X86_MCE_AMD) += mce_amd_64.o | ||
18 | obj-$(CONFIG_MTRR) += cpu/mtrr/ | ||
19 | obj-$(CONFIG_ACPI) += acpi/ | ||
20 | obj-$(CONFIG_X86_MSR) += msr.o | 17 | obj-$(CONFIG_X86_MSR) += msr.o |
21 | obj-$(CONFIG_MICROCODE) += microcode.o | 18 | obj-$(CONFIG_MICROCODE) += microcode.o |
22 | obj-$(CONFIG_X86_CPUID) += cpuid.o | 19 | obj-$(CONFIG_X86_CPUID) += cpuid.o |
23 | obj-$(CONFIG_SMP) += smp_64.o smpboot_64.o trampoline_64.o tsc_sync.o | 20 | obj-$(CONFIG_SMP) += smp_64.o smpboot_64.o trampoline_64.o tsc_sync.o |
24 | obj-y += apic_64.o nmi_64.o | 21 | obj-y += apic_64.o nmi_64.o |
25 | obj-y += io_apic_64.o mpparse_64.o genapic_64.o genapic_flat_64.o | 22 | obj-y += io_apic_64.o mpparse_64.o genapic_64.o genapic_flat_64.o |
26 | obj-$(CONFIG_KEXEC) += machine_kexec_64.o relocate_kernel_64.o crash_64.o | 23 | obj-$(CONFIG_KEXEC) += machine_kexec_64.o relocate_kernel_64.o crash.o |
27 | obj-$(CONFIG_CRASH_DUMP) += crash_dump_64.o | 24 | obj-$(CONFIG_CRASH_DUMP) += crash_dump_64.o |
28 | obj-$(CONFIG_PM) += suspend_64.o | 25 | obj-$(CONFIG_PM) += suspend_64.o |
29 | obj-$(CONFIG_HIBERNATION) += suspend_asm_64.o | 26 | obj-$(CONFIG_HIBERNATION) += suspend_asm_64.o |
30 | obj-$(CONFIG_CPU_FREQ) += cpu/cpufreq/ | ||
31 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 27 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
32 | obj-$(CONFIG_IOMMU) += pci-gart_64.o aperture_64.o | 28 | obj-$(CONFIG_IOMMU) += pci-gart_64.o aperture_64.o |
33 | obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o | 29 | obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o |
@@ -42,13 +38,6 @@ obj-$(CONFIG_MODULES) += module_64.o | |||
42 | obj-$(CONFIG_PCI) += early-quirks.o | 38 | obj-$(CONFIG_PCI) += early-quirks.o |
43 | 39 | ||
44 | obj-y += topology.o | 40 | obj-y += topology.o |
45 | obj-y += intel_cacheinfo.o | ||
46 | obj-y += addon_cpuid_features.o | ||
47 | obj-y += pcspeaker.o | 41 | obj-y += pcspeaker.o |
48 | 42 | ||
49 | CFLAGS_vsyscall_64.o := $(PROFILING) -g0 | 43 | CFLAGS_vsyscall_64.o := $(PROFILING) -g0 |
50 | |||
51 | therm_throt-y += cpu/mcheck/therm_throt.o | ||
52 | intel_cacheinfo-y += cpu/intel_cacheinfo.o | ||
53 | addon_cpuid_features-y += cpu/addon_cpuid_features.o | ||
54 | perfctr-watchdog-y += cpu/perfctr-watchdog.o | ||
diff --git a/arch/x86/kernel/acpi/Makefile b/arch/x86/kernel/acpi/Makefile index 3d5671939542..1351c3982ee4 100644 --- a/arch/x86/kernel/acpi/Makefile +++ b/arch/x86/kernel/acpi/Makefile | |||
@@ -1,5 +1,7 @@ | |||
1 | ifeq ($(CONFIG_X86_32),y) | 1 | obj-$(CONFIG_ACPI) += boot.o |
2 | include ${srctree}/arch/x86/kernel/acpi/Makefile_32 | 2 | obj-$(CONFIG_ACPI_SLEEP) += sleep_$(BITS).o wakeup_$(BITS).o |
3 | else | 3 | |
4 | include ${srctree}/arch/x86/kernel/acpi/Makefile_64 | 4 | ifneq ($(CONFIG_ACPI_PROCESSOR),) |
5 | obj-y += cstate.o processor.o | ||
5 | endif | 6 | endif |
7 | |||
diff --git a/arch/x86/kernel/acpi/Makefile_32 b/arch/x86/kernel/acpi/Makefile_32 deleted file mode 100644 index 045dd54b33e0..000000000000 --- a/arch/x86/kernel/acpi/Makefile_32 +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | obj-$(CONFIG_ACPI) += boot.o | ||
2 | obj-$(CONFIG_ACPI_SLEEP) += sleep_32.o wakeup_32.o | ||
3 | |||
4 | ifneq ($(CONFIG_ACPI_PROCESSOR),) | ||
5 | obj-y += cstate.o processor.o | ||
6 | endif | ||
7 | |||
diff --git a/arch/x86/kernel/acpi/Makefile_64 b/arch/x86/kernel/acpi/Makefile_64 deleted file mode 100644 index 629425bc002d..000000000000 --- a/arch/x86/kernel/acpi/Makefile_64 +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | obj-y := boot.o | ||
2 | obj-$(CONFIG_ACPI_SLEEP) += sleep_64.o wakeup_64.o | ||
3 | |||
4 | ifneq ($(CONFIG_ACPI_PROCESSOR),) | ||
5 | obj-y += processor.o cstate.o | ||
6 | endif | ||
7 | |||
diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S index 55608ec2ed72..5ed3bc5c61d7 100644 --- a/arch/x86/kernel/acpi/wakeup_64.S +++ b/arch/x86/kernel/acpi/wakeup_64.S | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <asm/pgtable.h> | 4 | #include <asm/pgtable.h> |
5 | #include <asm/page.h> | 5 | #include <asm/page.h> |
6 | #include <asm/msr.h> | 6 | #include <asm/msr.h> |
7 | #include <asm/asm-offsets.h> | ||
7 | 8 | ||
8 | # Copyright 2003 Pavel Machek <pavel@suse.cz>, distribute under GPLv2 | 9 | # Copyright 2003 Pavel Machek <pavel@suse.cz>, distribute under GPLv2 |
9 | # | 10 | # |
@@ -342,31 +343,32 @@ do_suspend_lowlevel: | |||
342 | xorl %eax, %eax | 343 | xorl %eax, %eax |
343 | call save_processor_state | 344 | call save_processor_state |
344 | 345 | ||
345 | movq %rsp, saved_context_esp(%rip) | 346 | movq $saved_context, %rax |
346 | movq %rax, saved_context_eax(%rip) | 347 | movq %rsp, pt_regs_rsp(%rax) |
347 | movq %rbx, saved_context_ebx(%rip) | 348 | movq %rbp, pt_regs_rbp(%rax) |
348 | movq %rcx, saved_context_ecx(%rip) | 349 | movq %rsi, pt_regs_rsi(%rax) |
349 | movq %rdx, saved_context_edx(%rip) | 350 | movq %rdi, pt_regs_rdi(%rax) |
350 | movq %rbp, saved_context_ebp(%rip) | 351 | movq %rbx, pt_regs_rbx(%rax) |
351 | movq %rsi, saved_context_esi(%rip) | 352 | movq %rcx, pt_regs_rcx(%rax) |
352 | movq %rdi, saved_context_edi(%rip) | 353 | movq %rdx, pt_regs_rdx(%rax) |
353 | movq %r8, saved_context_r08(%rip) | 354 | movq %r8, pt_regs_r8(%rax) |
354 | movq %r9, saved_context_r09(%rip) | 355 | movq %r9, pt_regs_r9(%rax) |
355 | movq %r10, saved_context_r10(%rip) | 356 | movq %r10, pt_regs_r10(%rax) |
356 | movq %r11, saved_context_r11(%rip) | 357 | movq %r11, pt_regs_r11(%rax) |
357 | movq %r12, saved_context_r12(%rip) | 358 | movq %r12, pt_regs_r12(%rax) |
358 | movq %r13, saved_context_r13(%rip) | 359 | movq %r13, pt_regs_r13(%rax) |
359 | movq %r14, saved_context_r14(%rip) | 360 | movq %r14, pt_regs_r14(%rax) |
360 | movq %r15, saved_context_r15(%rip) | 361 | movq %r15, pt_regs_r15(%rax) |
361 | pushfq ; popq saved_context_eflags(%rip) | 362 | pushfq |
363 | popq pt_regs_eflags(%rax) | ||
362 | 364 | ||
363 | movq $.L97, saved_rip(%rip) | 365 | movq $.L97, saved_rip(%rip) |
364 | 366 | ||
365 | movq %rsp,saved_rsp | 367 | movq %rsp, saved_rsp |
366 | movq %rbp,saved_rbp | 368 | movq %rbp, saved_rbp |
367 | movq %rbx,saved_rbx | 369 | movq %rbx, saved_rbx |
368 | movq %rdi,saved_rdi | 370 | movq %rdi, saved_rdi |
369 | movq %rsi,saved_rsi | 371 | movq %rsi, saved_rsi |
370 | 372 | ||
371 | addq $8, %rsp | 373 | addq $8, %rsp |
372 | movl $3, %edi | 374 | movl $3, %edi |
@@ -377,32 +379,35 @@ do_suspend_lowlevel: | |||
377 | .L99: | 379 | .L99: |
378 | .align 4 | 380 | .align 4 |
379 | movl $24, %eax | 381 | movl $24, %eax |
380 | movw %ax, %ds | 382 | movw %ax, %ds |
381 | movq saved_context+58(%rip), %rax | 383 | |
382 | movq %rax, %cr4 | 384 | /* We don't restore %rax, it must be 0 anyway */ |
383 | movq saved_context+50(%rip), %rax | 385 | movq $saved_context, %rax |
384 | movq %rax, %cr3 | 386 | movq saved_context_cr4(%rax), %rbx |
385 | movq saved_context+42(%rip), %rax | 387 | movq %rbx, %cr4 |
386 | movq %rax, %cr2 | 388 | movq saved_context_cr3(%rax), %rbx |
387 | movq saved_context+34(%rip), %rax | 389 | movq %rbx, %cr3 |
388 | movq %rax, %cr0 | 390 | movq saved_context_cr2(%rax), %rbx |
389 | pushq saved_context_eflags(%rip) ; popfq | 391 | movq %rbx, %cr2 |
390 | movq saved_context_esp(%rip), %rsp | 392 | movq saved_context_cr0(%rax), %rbx |
391 | movq saved_context_ebp(%rip), %rbp | 393 | movq %rbx, %cr0 |
392 | movq saved_context_eax(%rip), %rax | 394 | pushq pt_regs_eflags(%rax) |
393 | movq saved_context_ebx(%rip), %rbx | 395 | popfq |
394 | movq saved_context_ecx(%rip), %rcx | 396 | movq pt_regs_rsp(%rax), %rsp |
395 | movq saved_context_edx(%rip), %rdx | 397 | movq pt_regs_rbp(%rax), %rbp |
396 | movq saved_context_esi(%rip), %rsi | 398 | movq pt_regs_rsi(%rax), %rsi |
397 | movq saved_context_edi(%rip), %rdi | 399 | movq pt_regs_rdi(%rax), %rdi |
398 | movq saved_context_r08(%rip), %r8 | 400 | movq pt_regs_rbx(%rax), %rbx |
399 | movq saved_context_r09(%rip), %r9 | 401 | movq pt_regs_rcx(%rax), %rcx |
400 | movq saved_context_r10(%rip), %r10 | 402 | movq pt_regs_rdx(%rax), %rdx |
401 | movq saved_context_r11(%rip), %r11 | 403 | movq pt_regs_r8(%rax), %r8 |
402 | movq saved_context_r12(%rip), %r12 | 404 | movq pt_regs_r9(%rax), %r9 |
403 | movq saved_context_r13(%rip), %r13 | 405 | movq pt_regs_r10(%rax), %r10 |
404 | movq saved_context_r14(%rip), %r14 | 406 | movq pt_regs_r11(%rax), %r11 |
405 | movq saved_context_r15(%rip), %r15 | 407 | movq pt_regs_r12(%rax), %r12 |
408 | movq pt_regs_r13(%rax), %r13 | ||
409 | movq pt_regs_r14(%rax), %r14 | ||
410 | movq pt_regs_r15(%rax), %r15 | ||
406 | 411 | ||
407 | xorl %eax, %eax | 412 | xorl %eax, %eax |
408 | addq $8, %rsp | 413 | addq $8, %rsp |
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c index f47bc493dba9..f28ccb588fba 100644 --- a/arch/x86/kernel/apic_64.c +++ b/arch/x86/kernel/apic_64.c | |||
@@ -287,6 +287,20 @@ void disable_local_APIC(void) | |||
287 | apic_write(APIC_SPIV, value); | 287 | apic_write(APIC_SPIV, value); |
288 | } | 288 | } |
289 | 289 | ||
290 | void lapic_shutdown(void) | ||
291 | { | ||
292 | unsigned long flags; | ||
293 | |||
294 | if (!cpu_has_apic) | ||
295 | return; | ||
296 | |||
297 | local_irq_save(flags); | ||
298 | |||
299 | disable_local_APIC(); | ||
300 | |||
301 | local_irq_restore(flags); | ||
302 | } | ||
303 | |||
290 | /* | 304 | /* |
291 | * This is to verify that we're looking at a real local APIC. | 305 | * This is to verify that we're looking at a real local APIC. |
292 | * Check these against your board if the CPUs aren't getting | 306 | * Check these against your board if the CPUs aren't getting |
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index 778953bc636c..7e50bda565b4 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c | |||
@@ -76,6 +76,34 @@ int main(void) | |||
76 | DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); | 76 | DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); |
77 | DEFINE(pbe_next, offsetof(struct pbe, next)); | 77 | DEFINE(pbe_next, offsetof(struct pbe, next)); |
78 | BLANK(); | 78 | BLANK(); |
79 | #define ENTRY(entry) DEFINE(pt_regs_ ## entry, offsetof(struct pt_regs, entry)) | ||
80 | ENTRY(rbx); | ||
81 | ENTRY(rbx); | ||
82 | ENTRY(rcx); | ||
83 | ENTRY(rdx); | ||
84 | ENTRY(rsp); | ||
85 | ENTRY(rbp); | ||
86 | ENTRY(rsi); | ||
87 | ENTRY(rdi); | ||
88 | ENTRY(r8); | ||
89 | ENTRY(r9); | ||
90 | ENTRY(r10); | ||
91 | ENTRY(r11); | ||
92 | ENTRY(r12); | ||
93 | ENTRY(r13); | ||
94 | ENTRY(r14); | ||
95 | ENTRY(r15); | ||
96 | ENTRY(eflags); | ||
97 | BLANK(); | ||
98 | #undef ENTRY | ||
99 | #define ENTRY(entry) DEFINE(saved_context_ ## entry, offsetof(struct saved_context, entry)) | ||
100 | ENTRY(cr0); | ||
101 | ENTRY(cr2); | ||
102 | ENTRY(cr3); | ||
103 | ENTRY(cr4); | ||
104 | ENTRY(cr8); | ||
105 | BLANK(); | ||
106 | #undef ENTRY | ||
79 | DEFINE(TSS_ist, offsetof(struct tss_struct, ist)); | 107 | DEFINE(TSS_ist, offsetof(struct tss_struct, ist)); |
80 | BLANK(); | 108 | BLANK(); |
81 | DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); | 109 | DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); |
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 778396c78d65..cfdb2f3bd763 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile | |||
@@ -2,19 +2,19 @@ | |||
2 | # Makefile for x86-compatible CPU details and quirks | 2 | # Makefile for x86-compatible CPU details and quirks |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := common.o proc.o bugs.o | 5 | obj-y := intel_cacheinfo.o addon_cpuid_features.o |
6 | 6 | ||
7 | obj-y += amd.o | 7 | obj-$(CONFIG_X86_32) += common.o proc.o bugs.o |
8 | obj-y += cyrix.o | 8 | obj-$(CONFIG_X86_32) += amd.o |
9 | obj-y += centaur.o | 9 | obj-$(CONFIG_X86_32) += cyrix.o |
10 | obj-y += transmeta.o | 10 | obj-$(CONFIG_X86_32) += centaur.o |
11 | obj-y += intel.o intel_cacheinfo.o addon_cpuid_features.o | 11 | obj-$(CONFIG_X86_32) += transmeta.o |
12 | obj-y += nexgen.o | 12 | obj-$(CONFIG_X86_32) += intel.o |
13 | obj-y += umc.o | 13 | obj-$(CONFIG_X86_32) += nexgen.o |
14 | obj-$(CONFIG_X86_32) += umc.o | ||
14 | 15 | ||
15 | obj-$(CONFIG_X86_MCE) += mcheck/ | 16 | obj-$(CONFIG_X86_MCE) += mcheck/ |
16 | 17 | obj-$(CONFIG_MTRR) += mtrr/ | |
17 | obj-$(CONFIG_MTRR) += mtrr/ | 18 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ |
18 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ | ||
19 | 19 | ||
20 | obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o | 20 | obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o |
diff --git a/arch/x86/kernel/cpu/mcheck/Makefile b/arch/x86/kernel/cpu/mcheck/Makefile index f1ebe1c1c17a..d7d2323bbb69 100644 --- a/arch/x86/kernel/cpu/mcheck/Makefile +++ b/arch/x86/kernel/cpu/mcheck/Makefile | |||
@@ -1,2 +1,6 @@ | |||
1 | obj-y = mce.o k7.o p4.o p5.o p6.o winchip.o therm_throt.o | 1 | obj-y = mce_$(BITS).o therm_throt.o |
2 | obj-$(CONFIG_X86_MCE_NONFATAL) += non-fatal.o | 2 | |
3 | obj-$(CONFIG_X86_32) += k7.o p4.o p5.o p6.o winchip.o | ||
4 | obj-$(CONFIG_X86_MCE_INTEL) += mce_intel_64.o | ||
5 | obj-$(CONFIG_X86_MCE_AMD) += mce_amd_64.o | ||
6 | obj-$(CONFIG_X86_MCE_NONFATAL) += non-fatal.o | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce_32.c index 34c781eddee4..34c781eddee4 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce_32.c | |||
diff --git a/arch/x86/kernel/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 07bbfe7aa7f7..b9f802e35209 100644 --- a/arch/x86/kernel/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Machine check handler. | 2 | * Machine check handler. |
3 | * K8 parts Copyright 2002,2003 Andi Kleen, SuSE Labs. | 3 | * K8 parts Copyright 2002,2003 Andi Kleen, SuSE Labs. |
4 | * Rest from unknown author(s). | 4 | * Rest from unknown author(s). |
5 | * 2004 Andi Kleen. Rewrote most of it. | 5 | * 2004 Andi Kleen. Rewrote most of it. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/ctype.h> | 23 | #include <linux/ctype.h> |
24 | #include <linux/kmod.h> | 24 | #include <linux/kmod.h> |
25 | #include <linux/kdebug.h> | 25 | #include <linux/kdebug.h> |
26 | #include <asm/processor.h> | 26 | #include <asm/processor.h> |
27 | #include <asm/msr.h> | 27 | #include <asm/msr.h> |
28 | #include <asm/mce.h> | 28 | #include <asm/mce.h> |
29 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
@@ -63,10 +63,10 @@ static DECLARE_WAIT_QUEUE_HEAD(mce_wait); | |||
63 | * separate MCEs from kernel messages to avoid bogus bug reports. | 63 | * separate MCEs from kernel messages to avoid bogus bug reports. |
64 | */ | 64 | */ |
65 | 65 | ||
66 | struct mce_log mcelog = { | 66 | struct mce_log mcelog = { |
67 | MCE_LOG_SIGNATURE, | 67 | MCE_LOG_SIGNATURE, |
68 | MCE_LOG_LEN, | 68 | MCE_LOG_LEN, |
69 | }; | 69 | }; |
70 | 70 | ||
71 | void mce_log(struct mce *mce) | 71 | void mce_log(struct mce *mce) |
72 | { | 72 | { |
@@ -111,42 +111,42 @@ static void print_mce(struct mce *m) | |||
111 | "CPU %d: Machine Check Exception: %16Lx Bank %d: %016Lx\n", | 111 | "CPU %d: Machine Check Exception: %16Lx Bank %d: %016Lx\n", |
112 | m->cpu, m->mcgstatus, m->bank, m->status); | 112 | m->cpu, m->mcgstatus, m->bank, m->status); |
113 | if (m->rip) { | 113 | if (m->rip) { |
114 | printk(KERN_EMERG | 114 | printk(KERN_EMERG "RIP%s %02x:<%016Lx> ", |
115 | "RIP%s %02x:<%016Lx> ", | ||
116 | !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "", | 115 | !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "", |
117 | m->cs, m->rip); | 116 | m->cs, m->rip); |
118 | if (m->cs == __KERNEL_CS) | 117 | if (m->cs == __KERNEL_CS) |
119 | print_symbol("{%s}", m->rip); | 118 | print_symbol("{%s}", m->rip); |
120 | printk("\n"); | 119 | printk("\n"); |
121 | } | 120 | } |
122 | printk(KERN_EMERG "TSC %Lx ", m->tsc); | 121 | printk(KERN_EMERG "TSC %Lx ", m->tsc); |
123 | if (m->addr) | 122 | if (m->addr) |
124 | printk("ADDR %Lx ", m->addr); | 123 | printk("ADDR %Lx ", m->addr); |
125 | if (m->misc) | 124 | if (m->misc) |
126 | printk("MISC %Lx ", m->misc); | 125 | printk("MISC %Lx ", m->misc); |
127 | printk("\n"); | 126 | printk("\n"); |
128 | printk(KERN_EMERG "This is not a software problem!\n"); | 127 | printk(KERN_EMERG "This is not a software problem!\n"); |
129 | printk(KERN_EMERG | 128 | printk(KERN_EMERG "Run through mcelog --ascii to decode " |
130 | "Run through mcelog --ascii to decode and contact your hardware vendor\n"); | 129 | "and contact your hardware vendor\n"); |
131 | } | 130 | } |
132 | 131 | ||
133 | static void mce_panic(char *msg, struct mce *backup, unsigned long start) | 132 | static void mce_panic(char *msg, struct mce *backup, unsigned long start) |
134 | { | 133 | { |
135 | int i; | 134 | int i; |
136 | 135 | ||
137 | oops_begin(); | 136 | oops_begin(); |
138 | for (i = 0; i < MCE_LOG_LEN; i++) { | 137 | for (i = 0; i < MCE_LOG_LEN; i++) { |
139 | unsigned long tsc = mcelog.entry[i].tsc; | 138 | unsigned long tsc = mcelog.entry[i].tsc; |
139 | |||
140 | if (time_before(tsc, start)) | 140 | if (time_before(tsc, start)) |
141 | continue; | 141 | continue; |
142 | print_mce(&mcelog.entry[i]); | 142 | print_mce(&mcelog.entry[i]); |
143 | if (backup && mcelog.entry[i].tsc == backup->tsc) | 143 | if (backup && mcelog.entry[i].tsc == backup->tsc) |
144 | backup = NULL; | 144 | backup = NULL; |
145 | } | 145 | } |
146 | if (backup) | 146 | if (backup) |
147 | print_mce(backup); | 147 | print_mce(backup); |
148 | panic(msg); | 148 | panic(msg); |
149 | } | 149 | } |
150 | 150 | ||
151 | static int mce_available(struct cpuinfo_x86 *c) | 151 | static int mce_available(struct cpuinfo_x86 *c) |
152 | { | 152 | { |
@@ -170,10 +170,9 @@ static inline void mce_get_rip(struct mce *m, struct pt_regs *regs) | |||
170 | } | 170 | } |
171 | } | 171 | } |
172 | 172 | ||
173 | /* | 173 | /* |
174 | * The actual machine check handler | 174 | * The actual machine check handler |
175 | */ | 175 | */ |
176 | |||
177 | void do_machine_check(struct pt_regs * regs, long error_code) | 176 | void do_machine_check(struct pt_regs * regs, long error_code) |
178 | { | 177 | { |
179 | struct mce m, panicm; | 178 | struct mce m, panicm; |
@@ -194,7 +193,8 @@ void do_machine_check(struct pt_regs * regs, long error_code) | |||
194 | atomic_inc(&mce_entry); | 193 | atomic_inc(&mce_entry); |
195 | 194 | ||
196 | if (regs) | 195 | if (regs) |
197 | notify_die(DIE_NMI, "machine check", regs, error_code, 18, SIGKILL); | 196 | notify_die(DIE_NMI, "machine check", regs, error_code, 18, |
197 | SIGKILL); | ||
198 | if (!banks) | 198 | if (!banks) |
199 | goto out2; | 199 | goto out2; |
200 | 200 | ||
@@ -204,15 +204,15 @@ void do_machine_check(struct pt_regs * regs, long error_code) | |||
204 | /* if the restart IP is not valid, we're done for */ | 204 | /* if the restart IP is not valid, we're done for */ |
205 | if (!(m.mcgstatus & MCG_STATUS_RIPV)) | 205 | if (!(m.mcgstatus & MCG_STATUS_RIPV)) |
206 | no_way_out = 1; | 206 | no_way_out = 1; |
207 | 207 | ||
208 | rdtscll(mcestart); | 208 | rdtscll(mcestart); |
209 | barrier(); | 209 | barrier(); |
210 | 210 | ||
211 | for (i = 0; i < banks; i++) { | 211 | for (i = 0; i < banks; i++) { |
212 | if (!bank[i]) | 212 | if (!bank[i]) |
213 | continue; | 213 | continue; |
214 | 214 | ||
215 | m.misc = 0; | 215 | m.misc = 0; |
216 | m.addr = 0; | 216 | m.addr = 0; |
217 | m.bank = i; | 217 | m.bank = i; |
218 | m.tsc = 0; | 218 | m.tsc = 0; |
@@ -372,7 +372,7 @@ static void mcheck_timer(struct work_struct *work) | |||
372 | if (mce_notify_user()) { | 372 | if (mce_notify_user()) { |
373 | next_interval = max(next_interval/2, HZ/100); | 373 | next_interval = max(next_interval/2, HZ/100); |
374 | } else { | 374 | } else { |
375 | next_interval = min(next_interval*2, | 375 | next_interval = min(next_interval * 2, |
376 | (int)round_jiffies_relative(check_interval*HZ)); | 376 | (int)round_jiffies_relative(check_interval*HZ)); |
377 | } | 377 | } |
378 | 378 | ||
@@ -423,18 +423,18 @@ static struct notifier_block mce_idle_notifier = { | |||
423 | }; | 423 | }; |
424 | 424 | ||
425 | static __init int periodic_mcheck_init(void) | 425 | static __init int periodic_mcheck_init(void) |
426 | { | 426 | { |
427 | next_interval = check_interval * HZ; | 427 | next_interval = check_interval * HZ; |
428 | if (next_interval) | 428 | if (next_interval) |
429 | schedule_delayed_work(&mcheck_work, | 429 | schedule_delayed_work(&mcheck_work, |
430 | round_jiffies_relative(next_interval)); | 430 | round_jiffies_relative(next_interval)); |
431 | idle_notifier_register(&mce_idle_notifier); | 431 | idle_notifier_register(&mce_idle_notifier); |
432 | return 0; | 432 | return 0; |
433 | } | 433 | } |
434 | __initcall(periodic_mcheck_init); | 434 | __initcall(periodic_mcheck_init); |
435 | 435 | ||
436 | 436 | ||
437 | /* | 437 | /* |
438 | * Initialize Machine Checks for a CPU. | 438 | * Initialize Machine Checks for a CPU. |
439 | */ | 439 | */ |
440 | static void mce_init(void *dummy) | 440 | static void mce_init(void *dummy) |
@@ -444,9 +444,9 @@ static void mce_init(void *dummy) | |||
444 | 444 | ||
445 | rdmsrl(MSR_IA32_MCG_CAP, cap); | 445 | rdmsrl(MSR_IA32_MCG_CAP, cap); |
446 | banks = cap & 0xff; | 446 | banks = cap & 0xff; |
447 | if (banks > NR_BANKS) { | 447 | if (banks > NR_BANKS) { |
448 | printk(KERN_INFO "MCE: warning: using only %d banks\n", banks); | 448 | printk(KERN_INFO "MCE: warning: using only %d banks\n", banks); |
449 | banks = NR_BANKS; | 449 | banks = NR_BANKS; |
450 | } | 450 | } |
451 | /* Use accurate RIP reporting if available. */ | 451 | /* Use accurate RIP reporting if available. */ |
452 | if ((cap & (1<<9)) && ((cap >> 16) & 0xff) >= 9) | 452 | if ((cap & (1<<9)) && ((cap >> 16) & 0xff) >= 9) |
@@ -464,15 +464,15 @@ static void mce_init(void *dummy) | |||
464 | for (i = 0; i < banks; i++) { | 464 | for (i = 0; i < banks; i++) { |
465 | wrmsrl(MSR_IA32_MC0_CTL+4*i, bank[i]); | 465 | wrmsrl(MSR_IA32_MC0_CTL+4*i, bank[i]); |
466 | wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0); | 466 | wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0); |
467 | } | 467 | } |
468 | } | 468 | } |
469 | 469 | ||
470 | /* Add per CPU specific workarounds here */ | 470 | /* Add per CPU specific workarounds here */ |
471 | static void __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c) | 471 | static void __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c) |
472 | { | 472 | { |
473 | /* This should be disabled by the BIOS, but isn't always */ | 473 | /* This should be disabled by the BIOS, but isn't always */ |
474 | if (c->x86_vendor == X86_VENDOR_AMD && c->x86 == 15) { | 474 | if (c->x86_vendor == X86_VENDOR_AMD && c->x86 == 15) { |
475 | /* disable GART TBL walk error reporting, which trips off | 475 | /* disable GART TBL walk error reporting, which trips off |
476 | incorrectly with the IOMMU & 3ware & Cerberus. */ | 476 | incorrectly with the IOMMU & 3ware & Cerberus. */ |
477 | clear_bit(10, &bank[4]); | 477 | clear_bit(10, &bank[4]); |
478 | /* Lots of broken BIOS around that don't clear them | 478 | /* Lots of broken BIOS around that don't clear them |
@@ -480,7 +480,7 @@ static void __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c) | |||
480 | mce_bootlog = 0; | 480 | mce_bootlog = 0; |
481 | } | 481 | } |
482 | 482 | ||
483 | } | 483 | } |
484 | 484 | ||
485 | static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c) | 485 | static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c) |
486 | { | 486 | { |
@@ -496,15 +496,15 @@ static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c) | |||
496 | } | 496 | } |
497 | } | 497 | } |
498 | 498 | ||
499 | /* | 499 | /* |
500 | * Called for each booted CPU to set up machine checks. | 500 | * Called for each booted CPU to set up machine checks. |
501 | * Must be called with preempt off. | 501 | * Must be called with preempt off. |
502 | */ | 502 | */ |
503 | void __cpuinit mcheck_init(struct cpuinfo_x86 *c) | 503 | void __cpuinit mcheck_init(struct cpuinfo_x86 *c) |
504 | { | 504 | { |
505 | static cpumask_t mce_cpus = CPU_MASK_NONE; | 505 | static cpumask_t mce_cpus = CPU_MASK_NONE; |
506 | 506 | ||
507 | mce_cpu_quirks(c); | 507 | mce_cpu_quirks(c); |
508 | 508 | ||
509 | if (mce_dont_init || | 509 | if (mce_dont_init || |
510 | cpu_test_and_set(smp_processor_id(), mce_cpus) || | 510 | cpu_test_and_set(smp_processor_id(), mce_cpus) || |
@@ -553,13 +553,15 @@ static int mce_release(struct inode *inode, struct file *file) | |||
553 | return 0; | 553 | return 0; |
554 | } | 554 | } |
555 | 555 | ||
556 | static void collect_tscs(void *data) | 556 | static void collect_tscs(void *data) |
557 | { | 557 | { |
558 | unsigned long *cpu_tsc = (unsigned long *)data; | 558 | unsigned long *cpu_tsc = (unsigned long *)data; |
559 | |||
559 | rdtscll(cpu_tsc[smp_processor_id()]); | 560 | rdtscll(cpu_tsc[smp_processor_id()]); |
560 | } | 561 | } |
561 | 562 | ||
562 | static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff_t *off) | 563 | static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, |
564 | loff_t *off) | ||
563 | { | 565 | { |
564 | unsigned long *cpu_tsc; | 566 | unsigned long *cpu_tsc; |
565 | static DECLARE_MUTEX(mce_read_sem); | 567 | static DECLARE_MUTEX(mce_read_sem); |
@@ -571,19 +573,20 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff | |||
571 | if (!cpu_tsc) | 573 | if (!cpu_tsc) |
572 | return -ENOMEM; | 574 | return -ENOMEM; |
573 | 575 | ||
574 | down(&mce_read_sem); | 576 | down(&mce_read_sem); |
575 | next = rcu_dereference(mcelog.next); | 577 | next = rcu_dereference(mcelog.next); |
576 | 578 | ||
577 | /* Only supports full reads right now */ | 579 | /* Only supports full reads right now */ |
578 | if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) { | 580 | if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) { |
579 | up(&mce_read_sem); | 581 | up(&mce_read_sem); |
580 | kfree(cpu_tsc); | 582 | kfree(cpu_tsc); |
581 | return -EINVAL; | 583 | return -EINVAL; |
582 | } | 584 | } |
583 | 585 | ||
584 | err = 0; | 586 | err = 0; |
585 | for (i = 0; i < next; i++) { | 587 | for (i = 0; i < next; i++) { |
586 | unsigned long start = jiffies; | 588 | unsigned long start = jiffies; |
589 | |||
587 | while (!mcelog.entry[i].finished) { | 590 | while (!mcelog.entry[i].finished) { |
588 | if (time_after_eq(jiffies, start + 2)) { | 591 | if (time_after_eq(jiffies, start + 2)) { |
589 | memset(mcelog.entry + i,0, sizeof(struct mce)); | 592 | memset(mcelog.entry + i,0, sizeof(struct mce)); |
@@ -593,31 +596,34 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff | |||
593 | } | 596 | } |
594 | smp_rmb(); | 597 | smp_rmb(); |
595 | err |= copy_to_user(buf, mcelog.entry + i, sizeof(struct mce)); | 598 | err |= copy_to_user(buf, mcelog.entry + i, sizeof(struct mce)); |
596 | buf += sizeof(struct mce); | 599 | buf += sizeof(struct mce); |
597 | timeout: | 600 | timeout: |
598 | ; | 601 | ; |
599 | } | 602 | } |
600 | 603 | ||
601 | memset(mcelog.entry, 0, next * sizeof(struct mce)); | 604 | memset(mcelog.entry, 0, next * sizeof(struct mce)); |
602 | mcelog.next = 0; | 605 | mcelog.next = 0; |
603 | 606 | ||
604 | synchronize_sched(); | 607 | synchronize_sched(); |
605 | 608 | ||
606 | /* Collect entries that were still getting written before the synchronize. */ | 609 | /* |
607 | 610 | * Collect entries that were still getting written before the | |
611 | * synchronize. | ||
612 | */ | ||
608 | on_each_cpu(collect_tscs, cpu_tsc, 1, 1); | 613 | on_each_cpu(collect_tscs, cpu_tsc, 1, 1); |
609 | for (i = next; i < MCE_LOG_LEN; i++) { | 614 | for (i = next; i < MCE_LOG_LEN; i++) { |
610 | if (mcelog.entry[i].finished && | 615 | if (mcelog.entry[i].finished && |
611 | mcelog.entry[i].tsc < cpu_tsc[mcelog.entry[i].cpu]) { | 616 | mcelog.entry[i].tsc < cpu_tsc[mcelog.entry[i].cpu]) { |
612 | err |= copy_to_user(buf, mcelog.entry+i, sizeof(struct mce)); | 617 | err |= copy_to_user(buf, mcelog.entry+i, |
618 | sizeof(struct mce)); | ||
613 | smp_rmb(); | 619 | smp_rmb(); |
614 | buf += sizeof(struct mce); | 620 | buf += sizeof(struct mce); |
615 | memset(&mcelog.entry[i], 0, sizeof(struct mce)); | 621 | memset(&mcelog.entry[i], 0, sizeof(struct mce)); |
616 | } | 622 | } |
617 | } | 623 | } |
618 | up(&mce_read_sem); | 624 | up(&mce_read_sem); |
619 | kfree(cpu_tsc); | 625 | kfree(cpu_tsc); |
620 | return err ? -EFAULT : buf - ubuf; | 626 | return err ? -EFAULT : buf - ubuf; |
621 | } | 627 | } |
622 | 628 | ||
623 | static unsigned int mce_poll(struct file *file, poll_table *wait) | 629 | static unsigned int mce_poll(struct file *file, poll_table *wait) |
@@ -628,26 +634,29 @@ static unsigned int mce_poll(struct file *file, poll_table *wait) | |||
628 | return 0; | 634 | return 0; |
629 | } | 635 | } |
630 | 636 | ||
631 | static int mce_ioctl(struct inode *i, struct file *f,unsigned int cmd, unsigned long arg) | 637 | static int mce_ioctl(struct inode *i, struct file *f,unsigned int cmd, |
638 | unsigned long arg) | ||
632 | { | 639 | { |
633 | int __user *p = (int __user *)arg; | 640 | int __user *p = (int __user *)arg; |
641 | |||
634 | if (!capable(CAP_SYS_ADMIN)) | 642 | if (!capable(CAP_SYS_ADMIN)) |
635 | return -EPERM; | 643 | return -EPERM; |
636 | switch (cmd) { | 644 | switch (cmd) { |
637 | case MCE_GET_RECORD_LEN: | 645 | case MCE_GET_RECORD_LEN: |
638 | return put_user(sizeof(struct mce), p); | 646 | return put_user(sizeof(struct mce), p); |
639 | case MCE_GET_LOG_LEN: | 647 | case MCE_GET_LOG_LEN: |
640 | return put_user(MCE_LOG_LEN, p); | 648 | return put_user(MCE_LOG_LEN, p); |
641 | case MCE_GETCLEAR_FLAGS: { | 649 | case MCE_GETCLEAR_FLAGS: { |
642 | unsigned flags; | 650 | unsigned flags; |
643 | do { | 651 | |
652 | do { | ||
644 | flags = mcelog.flags; | 653 | flags = mcelog.flags; |
645 | } while (cmpxchg(&mcelog.flags, flags, 0) != flags); | 654 | } while (cmpxchg(&mcelog.flags, flags, 0) != flags); |
646 | return put_user(flags, p); | 655 | return put_user(flags, p); |
647 | } | 656 | } |
648 | default: | 657 | default: |
649 | return -ENOTTY; | 658 | return -ENOTTY; |
650 | } | 659 | } |
651 | } | 660 | } |
652 | 661 | ||
653 | static const struct file_operations mce_chrdev_ops = { | 662 | static const struct file_operations mce_chrdev_ops = { |
@@ -678,10 +687,9 @@ void __init restart_mce(void) | |||
678 | set_in_cr4(X86_CR4_MCE); | 687 | set_in_cr4(X86_CR4_MCE); |
679 | } | 688 | } |
680 | 689 | ||
681 | /* | 690 | /* |
682 | * Old style boot options parsing. Only for compatibility. | 691 | * Old style boot options parsing. Only for compatibility. |
683 | */ | 692 | */ |
684 | |||
685 | static int __init mcheck_disable(char *str) | 693 | static int __init mcheck_disable(char *str) |
686 | { | 694 | { |
687 | mce_dont_init = 1; | 695 | mce_dont_init = 1; |
@@ -702,16 +710,16 @@ static int __init mcheck_enable(char *str) | |||
702 | else if (isdigit(str[0])) | 710 | else if (isdigit(str[0])) |
703 | get_option(&str, &tolerant); | 711 | get_option(&str, &tolerant); |
704 | else | 712 | else |
705 | printk("mce= argument %s ignored. Please use /sys", str); | 713 | printk("mce= argument %s ignored. Please use /sys", str); |
706 | return 1; | 714 | return 1; |
707 | } | 715 | } |
708 | 716 | ||
709 | __setup("nomce", mcheck_disable); | 717 | __setup("nomce", mcheck_disable); |
710 | __setup("mce=", mcheck_enable); | 718 | __setup("mce=", mcheck_enable); |
711 | 719 | ||
712 | /* | 720 | /* |
713 | * Sysfs support | 721 | * Sysfs support |
714 | */ | 722 | */ |
715 | 723 | ||
716 | /* On resume clear all MCE state. Don't want to see leftovers from the BIOS. | 724 | /* On resume clear all MCE state. Don't want to see leftovers from the BIOS. |
717 | Only one CPU is active at this time, the others get readded later using | 725 | Only one CPU is active at this time, the others get readded later using |
@@ -723,12 +731,12 @@ static int mce_resume(struct sys_device *dev) | |||
723 | } | 731 | } |
724 | 732 | ||
725 | /* Reinit MCEs after user configuration changes */ | 733 | /* Reinit MCEs after user configuration changes */ |
726 | static void mce_restart(void) | 734 | static void mce_restart(void) |
727 | { | 735 | { |
728 | if (next_interval) | 736 | if (next_interval) |
729 | cancel_delayed_work(&mcheck_work); | 737 | cancel_delayed_work(&mcheck_work); |
730 | /* Timer race is harmless here */ | 738 | /* Timer race is harmless here */ |
731 | on_each_cpu(mce_init, NULL, 1, 1); | 739 | on_each_cpu(mce_init, NULL, 1, 1); |
732 | next_interval = check_interval * HZ; | 740 | next_interval = check_interval * HZ; |
733 | if (next_interval) | 741 | if (next_interval) |
734 | schedule_delayed_work(&mcheck_work, | 742 | schedule_delayed_work(&mcheck_work, |
@@ -744,17 +752,17 @@ DEFINE_PER_CPU(struct sys_device, device_mce); | |||
744 | 752 | ||
745 | /* Why are there no generic functions for this? */ | 753 | /* Why are there no generic functions for this? */ |
746 | #define ACCESSOR(name, var, start) \ | 754 | #define ACCESSOR(name, var, start) \ |
747 | static ssize_t show_ ## name(struct sys_device *s, char *buf) { \ | 755 | static ssize_t show_ ## name(struct sys_device *s, char *buf) { \ |
748 | return sprintf(buf, "%lx\n", (unsigned long)var); \ | 756 | return sprintf(buf, "%lx\n", (unsigned long)var); \ |
749 | } \ | 757 | } \ |
750 | static ssize_t set_ ## name(struct sys_device *s,const char *buf,size_t siz) { \ | 758 | static ssize_t set_ ## name(struct sys_device *s,const char *buf,size_t siz) { \ |
751 | char *end; \ | 759 | char *end; \ |
752 | unsigned long new = simple_strtoul(buf, &end, 0); \ | 760 | unsigned long new = simple_strtoul(buf, &end, 0); \ |
753 | if (end == buf) return -EINVAL; \ | 761 | if (end == buf) return -EINVAL; \ |
754 | var = new; \ | 762 | var = new; \ |
755 | start; \ | 763 | start; \ |
756 | return end-buf; \ | 764 | return end-buf; \ |
757 | } \ | 765 | } \ |
758 | static SYSDEV_ATTR(name, 0644, show_ ## name, set_ ## name); | 766 | static SYSDEV_ATTR(name, 0644, show_ ## name, set_ ## name); |
759 | 767 | ||
760 | /* TBD should generate these dynamically based on number of available banks */ | 768 | /* TBD should generate these dynamically based on number of available banks */ |
diff --git a/arch/x86/kernel/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c index 752fb16a817d..752fb16a817d 100644 --- a/arch/x86/kernel/mce_amd_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c | |||
diff --git a/arch/x86/kernel/mce_intel_64.c b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c index c17eaf5dd6dd..c17eaf5dd6dd 100644 --- a/arch/x86/kernel/mce_intel_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c | |||
diff --git a/arch/x86/kernel/crash_32.c b/arch/x86/kernel/crash.c index 53589d1b1a05..af0253f94a9a 100644 --- a/arch/x86/kernel/crash_32.c +++ b/arch/x86/kernel/crash.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Architecture specific (i386) functions for kexec based crash dumps. | 2 | * Architecture specific (i386/x86_64) functions for kexec based crash dumps. |
3 | * | 3 | * |
4 | * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) | 4 | * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) |
5 | * | 5 | * |
@@ -25,8 +25,11 @@ | |||
25 | #include <linux/kdebug.h> | 25 | #include <linux/kdebug.h> |
26 | #include <asm/smp.h> | 26 | #include <asm/smp.h> |
27 | 27 | ||
28 | #ifdef X86_32 | ||
28 | #include <mach_ipi.h> | 29 | #include <mach_ipi.h> |
29 | 30 | #else | |
31 | #include <asm/mach_apic.h> | ||
32 | #endif | ||
30 | 33 | ||
31 | /* This keeps a track of which one is crashing cpu. */ | 34 | /* This keeps a track of which one is crashing cpu. */ |
32 | static int crashing_cpu; | 35 | static int crashing_cpu; |
@@ -38,7 +41,9 @@ static int crash_nmi_callback(struct notifier_block *self, | |||
38 | unsigned long val, void *data) | 41 | unsigned long val, void *data) |
39 | { | 42 | { |
40 | struct pt_regs *regs; | 43 | struct pt_regs *regs; |
44 | #ifdef X86_32 | ||
41 | struct pt_regs fixed_regs; | 45 | struct pt_regs fixed_regs; |
46 | #endif | ||
42 | int cpu; | 47 | int cpu; |
43 | 48 | ||
44 | if (val != DIE_NMI_IPI) | 49 | if (val != DIE_NMI_IPI) |
@@ -55,10 +60,12 @@ static int crash_nmi_callback(struct notifier_block *self, | |||
55 | return NOTIFY_STOP; | 60 | return NOTIFY_STOP; |
56 | local_irq_disable(); | 61 | local_irq_disable(); |
57 | 62 | ||
63 | #ifdef X86_32 | ||
58 | if (!user_mode_vm(regs)) { | 64 | if (!user_mode_vm(regs)) { |
59 | crash_fixup_ss_esp(&fixed_regs, regs); | 65 | crash_fixup_ss_esp(&fixed_regs, regs); |
60 | regs = &fixed_regs; | 66 | regs = &fixed_regs; |
61 | } | 67 | } |
68 | #endif | ||
62 | crash_save_cpu(regs, cpu); | 69 | crash_save_cpu(regs, cpu); |
63 | disable_local_APIC(); | 70 | disable_local_APIC(); |
64 | atomic_dec(&waiting_for_crash_ipi); | 71 | atomic_dec(&waiting_for_crash_ipi); |
diff --git a/arch/x86/kernel/crash_64.c b/arch/x86/kernel/crash_64.c deleted file mode 100644 index 13432a1ae904..000000000000 --- a/arch/x86/kernel/crash_64.c +++ /dev/null | |||
@@ -1,135 +0,0 @@ | |||
1 | /* | ||
2 | * Architecture specific (x86_64) functions for kexec based crash dumps. | ||
3 | * | ||
4 | * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) | ||
5 | * | ||
6 | * Copyright (C) IBM Corporation, 2004. All rights reserved. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/init.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/smp.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/reboot.h> | ||
16 | #include <linux/kexec.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/elf.h> | ||
19 | #include <linux/elfcore.h> | ||
20 | #include <linux/kdebug.h> | ||
21 | |||
22 | #include <asm/processor.h> | ||
23 | #include <asm/hardirq.h> | ||
24 | #include <asm/nmi.h> | ||
25 | #include <asm/hw_irq.h> | ||
26 | #include <asm/mach_apic.h> | ||
27 | |||
28 | /* This keeps a track of which one is crashing cpu. */ | ||
29 | static int crashing_cpu; | ||
30 | |||
31 | #ifdef CONFIG_SMP | ||
32 | static atomic_t waiting_for_crash_ipi; | ||
33 | |||
34 | static int crash_nmi_callback(struct notifier_block *self, | ||
35 | unsigned long val, void *data) | ||
36 | { | ||
37 | struct pt_regs *regs; | ||
38 | int cpu; | ||
39 | |||
40 | if (val != DIE_NMI_IPI) | ||
41 | return NOTIFY_OK; | ||
42 | |||
43 | regs = ((struct die_args *)data)->regs; | ||
44 | cpu = raw_smp_processor_id(); | ||
45 | |||
46 | /* | ||
47 | * Don't do anything if this handler is invoked on crashing cpu. | ||
48 | * Otherwise, system will completely hang. Crashing cpu can get | ||
49 | * an NMI if system was initially booted with nmi_watchdog parameter. | ||
50 | */ | ||
51 | if (cpu == crashing_cpu) | ||
52 | return NOTIFY_STOP; | ||
53 | local_irq_disable(); | ||
54 | |||
55 | crash_save_cpu(regs, cpu); | ||
56 | disable_local_APIC(); | ||
57 | atomic_dec(&waiting_for_crash_ipi); | ||
58 | /* Assume hlt works */ | ||
59 | for(;;) | ||
60 | halt(); | ||
61 | |||
62 | return 1; | ||
63 | } | ||
64 | |||
65 | static void smp_send_nmi_allbutself(void) | ||
66 | { | ||
67 | send_IPI_allbutself(NMI_VECTOR); | ||
68 | } | ||
69 | |||
70 | /* | ||
71 | * This code is a best effort heuristic to get the | ||
72 | * other cpus to stop executing. So races with | ||
73 | * cpu hotplug shouldn't matter. | ||
74 | */ | ||
75 | |||
76 | static struct notifier_block crash_nmi_nb = { | ||
77 | .notifier_call = crash_nmi_callback, | ||
78 | }; | ||
79 | |||
80 | static void nmi_shootdown_cpus(void) | ||
81 | { | ||
82 | unsigned long msecs; | ||
83 | |||
84 | atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); | ||
85 | if (register_die_notifier(&crash_nmi_nb)) | ||
86 | return; /* return what? */ | ||
87 | |||
88 | /* | ||
89 | * Ensure the new callback function is set before sending | ||
90 | * out the NMI | ||
91 | */ | ||
92 | wmb(); | ||
93 | |||
94 | smp_send_nmi_allbutself(); | ||
95 | |||
96 | msecs = 1000; /* Wait at most a second for the other cpus to stop */ | ||
97 | while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) { | ||
98 | mdelay(1); | ||
99 | msecs--; | ||
100 | } | ||
101 | /* Leave the nmi callback set */ | ||
102 | disable_local_APIC(); | ||
103 | } | ||
104 | #else | ||
105 | static void nmi_shootdown_cpus(void) | ||
106 | { | ||
107 | /* There are no cpus to shootdown */ | ||
108 | } | ||
109 | #endif | ||
110 | |||
111 | void machine_crash_shutdown(struct pt_regs *regs) | ||
112 | { | ||
113 | /* | ||
114 | * This function is only called after the system | ||
115 | * has panicked or is otherwise in a critical state. | ||
116 | * The minimum amount of code to allow a kexec'd kernel | ||
117 | * to run successfully needs to happen here. | ||
118 | * | ||
119 | * In practice this means shooting down the other cpus in | ||
120 | * an SMP system. | ||
121 | */ | ||
122 | /* The kernel is broken so disable interrupts */ | ||
123 | local_irq_disable(); | ||
124 | |||
125 | /* Make a note of crashing cpu. Will be used in NMI callback.*/ | ||
126 | crashing_cpu = smp_processor_id(); | ||
127 | nmi_shootdown_cpus(); | ||
128 | |||
129 | if(cpu_has_apic) | ||
130 | disable_local_APIC(); | ||
131 | |||
132 | disable_IO_APIC(); | ||
133 | |||
134 | crash_save_cpu(regs, smp_processor_id()); | ||
135 | } | ||
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 00b1c2c56454..374b7ece8961 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -124,12 +124,7 @@ ENTRY(startup_32) | |||
124 | movsl | 124 | movsl |
125 | movl boot_params - __PAGE_OFFSET + NEW_CL_POINTER,%esi | 125 | movl boot_params - __PAGE_OFFSET + NEW_CL_POINTER,%esi |
126 | andl %esi,%esi | 126 | andl %esi,%esi |
127 | jnz 2f # New command line protocol | 127 | jz 1f # No comand line |
128 | cmpw $(OLD_CL_MAGIC),OLD_CL_MAGIC_ADDR | ||
129 | jne 1f | ||
130 | movzwl OLD_CL_OFFSET,%esi | ||
131 | addl $(OLD_CL_BASE_ADDR),%esi | ||
132 | 2: | ||
133 | movl $(boot_command_line - __PAGE_OFFSET),%edi | 128 | movl $(boot_command_line - __PAGE_OFFSET),%edi |
134 | movl $(COMMAND_LINE_SIZE/4),%ecx | 129 | movl $(COMMAND_LINE_SIZE/4),%ecx |
135 | rep | 130 | rep |
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index a4ce1911efdf..fab30e134836 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c | |||
@@ -60,7 +60,8 @@ static enum { | |||
60 | NONE_FORCE_HPET_RESUME, | 60 | NONE_FORCE_HPET_RESUME, |
61 | OLD_ICH_FORCE_HPET_RESUME, | 61 | OLD_ICH_FORCE_HPET_RESUME, |
62 | ICH_FORCE_HPET_RESUME, | 62 | ICH_FORCE_HPET_RESUME, |
63 | VT8237_FORCE_HPET_RESUME | 63 | VT8237_FORCE_HPET_RESUME, |
64 | NVIDIA_FORCE_HPET_RESUME, | ||
64 | } force_hpet_resume_type; | 65 | } force_hpet_resume_type; |
65 | 66 | ||
66 | static void __iomem *rcba_base; | 67 | static void __iomem *rcba_base; |
@@ -321,6 +322,55 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, | |||
321 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, | 322 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, |
322 | vt8237_force_enable_hpet); | 323 | vt8237_force_enable_hpet); |
323 | 324 | ||
325 | /* | ||
326 | * Undocumented chipset feature taken from LinuxBIOS. | ||
327 | */ | ||
328 | static void nvidia_force_hpet_resume(void) | ||
329 | { | ||
330 | pci_write_config_dword(cached_dev, 0x44, 0xfed00001); | ||
331 | printk(KERN_DEBUG "Force enabled HPET at resume\n"); | ||
332 | } | ||
333 | |||
334 | static void nvidia_force_enable_hpet(struct pci_dev *dev) | ||
335 | { | ||
336 | u32 uninitialized_var(val); | ||
337 | |||
338 | if (!hpet_force_user || hpet_address || force_hpet_address) | ||
339 | return; | ||
340 | |||
341 | pci_write_config_dword(dev, 0x44, 0xfed00001); | ||
342 | pci_read_config_dword(dev, 0x44, &val); | ||
343 | force_hpet_address = val & 0xfffffffe; | ||
344 | force_hpet_resume_type = NVIDIA_FORCE_HPET_RESUME; | ||
345 | printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", | ||
346 | force_hpet_address); | ||
347 | cached_dev = dev; | ||
348 | return; | ||
349 | } | ||
350 | |||
351 | /* ISA Bridges */ | ||
352 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0050, | ||
353 | nvidia_force_enable_hpet); | ||
354 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0051, | ||
355 | nvidia_force_enable_hpet); | ||
356 | |||
357 | /* LPC bridges */ | ||
358 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0360, | ||
359 | nvidia_force_enable_hpet); | ||
360 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0361, | ||
361 | nvidia_force_enable_hpet); | ||
362 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0362, | ||
363 | nvidia_force_enable_hpet); | ||
364 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0363, | ||
365 | nvidia_force_enable_hpet); | ||
366 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0364, | ||
367 | nvidia_force_enable_hpet); | ||
368 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0365, | ||
369 | nvidia_force_enable_hpet); | ||
370 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0366, | ||
371 | nvidia_force_enable_hpet); | ||
372 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0367, | ||
373 | nvidia_force_enable_hpet); | ||
324 | 374 | ||
325 | void force_hpet_resume(void) | 375 | void force_hpet_resume(void) |
326 | { | 376 | { |
@@ -334,6 +384,9 @@ void force_hpet_resume(void) | |||
334 | case VT8237_FORCE_HPET_RESUME: | 384 | case VT8237_FORCE_HPET_RESUME: |
335 | return vt8237_force_hpet_resume(); | 385 | return vt8237_force_hpet_resume(); |
336 | 386 | ||
387 | case NVIDIA_FORCE_HPET_RESUME: | ||
388 | return nvidia_force_hpet_resume(); | ||
389 | |||
337 | default: | 390 | default: |
338 | break; | 391 | break; |
339 | } | 392 | } |
diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c index b7e768dd87c9..500670c93d81 100644 --- a/arch/x86/kernel/smpboot_64.c +++ b/arch/x86/kernel/smpboot_64.c | |||
@@ -388,7 +388,7 @@ static void inquire_remote_apic(int apicid) | |||
388 | 388 | ||
389 | printk(KERN_INFO "Inquiring remote APIC #%d...\n", apicid); | 389 | printk(KERN_INFO "Inquiring remote APIC #%d...\n", apicid); |
390 | 390 | ||
391 | for (i = 0; i < sizeof(regs) / sizeof(*regs); i++) { | 391 | for (i = 0; i < ARRAY_SIZE(regs); i++) { |
392 | printk("... APIC #%d %s: ", apicid, names[i]); | 392 | printk("... APIC #%d %s: ", apicid, names[i]); |
393 | 393 | ||
394 | /* | 394 | /* |
diff --git a/arch/x86/kernel/suspend_64.c b/arch/x86/kernel/suspend_64.c index bc9f59c246fd..db284ef44d53 100644 --- a/arch/x86/kernel/suspend_64.c +++ b/arch/x86/kernel/suspend_64.c | |||
@@ -19,12 +19,6 @@ extern const void __nosave_begin, __nosave_end; | |||
19 | 19 | ||
20 | struct saved_context saved_context; | 20 | struct saved_context saved_context; |
21 | 21 | ||
22 | unsigned long saved_context_eax, saved_context_ebx, saved_context_ecx, saved_context_edx; | ||
23 | unsigned long saved_context_esp, saved_context_ebp, saved_context_esi, saved_context_edi; | ||
24 | unsigned long saved_context_r08, saved_context_r09, saved_context_r10, saved_context_r11; | ||
25 | unsigned long saved_context_r12, saved_context_r13, saved_context_r14, saved_context_r15; | ||
26 | unsigned long saved_context_eflags; | ||
27 | |||
28 | void __save_processor_state(struct saved_context *ctxt) | 22 | void __save_processor_state(struct saved_context *ctxt) |
29 | { | 23 | { |
30 | kernel_fpu_begin(); | 24 | kernel_fpu_begin(); |
diff --git a/arch/x86/kernel/suspend_asm_64.S b/arch/x86/kernel/suspend_asm_64.S index 48344b666d2c..72f952103e50 100644 --- a/arch/x86/kernel/suspend_asm_64.S +++ b/arch/x86/kernel/suspend_asm_64.S | |||
@@ -17,24 +17,24 @@ | |||
17 | #include <asm/asm-offsets.h> | 17 | #include <asm/asm-offsets.h> |
18 | 18 | ||
19 | ENTRY(swsusp_arch_suspend) | 19 | ENTRY(swsusp_arch_suspend) |
20 | 20 | movq $saved_context, %rax | |
21 | movq %rsp, saved_context_esp(%rip) | 21 | movq %rsp, pt_regs_rsp(%rax) |
22 | movq %rax, saved_context_eax(%rip) | 22 | movq %rbp, pt_regs_rbp(%rax) |
23 | movq %rbx, saved_context_ebx(%rip) | 23 | movq %rsi, pt_regs_rsi(%rax) |
24 | movq %rcx, saved_context_ecx(%rip) | 24 | movq %rdi, pt_regs_rdi(%rax) |
25 | movq %rdx, saved_context_edx(%rip) | 25 | movq %rbx, pt_regs_rbx(%rax) |
26 | movq %rbp, saved_context_ebp(%rip) | 26 | movq %rcx, pt_regs_rcx(%rax) |
27 | movq %rsi, saved_context_esi(%rip) | 27 | movq %rdx, pt_regs_rdx(%rax) |
28 | movq %rdi, saved_context_edi(%rip) | 28 | movq %r8, pt_regs_r8(%rax) |
29 | movq %r8, saved_context_r08(%rip) | 29 | movq %r9, pt_regs_r9(%rax) |
30 | movq %r9, saved_context_r09(%rip) | 30 | movq %r10, pt_regs_r10(%rax) |
31 | movq %r10, saved_context_r10(%rip) | 31 | movq %r11, pt_regs_r11(%rax) |
32 | movq %r11, saved_context_r11(%rip) | 32 | movq %r12, pt_regs_r12(%rax) |
33 | movq %r12, saved_context_r12(%rip) | 33 | movq %r13, pt_regs_r13(%rax) |
34 | movq %r13, saved_context_r13(%rip) | 34 | movq %r14, pt_regs_r14(%rax) |
35 | movq %r14, saved_context_r14(%rip) | 35 | movq %r15, pt_regs_r15(%rax) |
36 | movq %r15, saved_context_r15(%rip) | 36 | pushfq |
37 | pushfq ; popq saved_context_eflags(%rip) | 37 | popq pt_regs_eflags(%rax) |
38 | 38 | ||
39 | /* save the address of restore_registers */ | 39 | /* save the address of restore_registers */ |
40 | movq $restore_registers, %rax | 40 | movq $restore_registers, %rax |
@@ -113,23 +113,25 @@ ENTRY(restore_registers) | |||
113 | movq %rcx, %cr3 | 113 | movq %rcx, %cr3 |
114 | movq %rax, %cr4; # turn PGE back on | 114 | movq %rax, %cr4; # turn PGE back on |
115 | 115 | ||
116 | movq saved_context_esp(%rip), %rsp | 116 | /* We don't restore %rax, it must be 0 anyway */ |
117 | movq saved_context_ebp(%rip), %rbp | 117 | movq $saved_context, %rax |
118 | /* restore GPRs (we don't restore %rax, it must be 0 anyway) */ | 118 | movq pt_regs_rsp(%rax), %rsp |
119 | movq saved_context_ebx(%rip), %rbx | 119 | movq pt_regs_rbp(%rax), %rbp |
120 | movq saved_context_ecx(%rip), %rcx | 120 | movq pt_regs_rsi(%rax), %rsi |
121 | movq saved_context_edx(%rip), %rdx | 121 | movq pt_regs_rdi(%rax), %rdi |
122 | movq saved_context_esi(%rip), %rsi | 122 | movq pt_regs_rbx(%rax), %rbx |
123 | movq saved_context_edi(%rip), %rdi | 123 | movq pt_regs_rcx(%rax), %rcx |
124 | movq saved_context_r08(%rip), %r8 | 124 | movq pt_regs_rdx(%rax), %rdx |
125 | movq saved_context_r09(%rip), %r9 | 125 | movq pt_regs_r8(%rax), %r8 |
126 | movq saved_context_r10(%rip), %r10 | 126 | movq pt_regs_r9(%rax), %r9 |
127 | movq saved_context_r11(%rip), %r11 | 127 | movq pt_regs_r10(%rax), %r10 |
128 | movq saved_context_r12(%rip), %r12 | 128 | movq pt_regs_r11(%rax), %r11 |
129 | movq saved_context_r13(%rip), %r13 | 129 | movq pt_regs_r12(%rax), %r12 |
130 | movq saved_context_r14(%rip), %r14 | 130 | movq pt_regs_r13(%rax), %r13 |
131 | movq saved_context_r15(%rip), %r15 | 131 | movq pt_regs_r14(%rax), %r14 |
132 | pushq saved_context_eflags(%rip) ; popfq | 132 | movq pt_regs_r15(%rax), %r15 |
133 | pushq pt_regs_eflags(%rax) | ||
134 | popfq | ||
133 | 135 | ||
134 | xorq %rax, %rax | 136 | xorq %rax, %rax |
135 | 137 | ||
diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c index d78444c788a3..9ebc0dab66b4 100644 --- a/arch/x86/kernel/tsc_32.c +++ b/arch/x86/kernel/tsc_32.c | |||
@@ -131,38 +131,43 @@ unsigned long native_calculate_cpu_khz(void) | |||
131 | { | 131 | { |
132 | unsigned long long start, end; | 132 | unsigned long long start, end; |
133 | unsigned long count; | 133 | unsigned long count; |
134 | u64 delta64; | 134 | u64 delta64 = (u64)ULLONG_MAX; |
135 | int i; | 135 | int i; |
136 | unsigned long flags; | 136 | unsigned long flags; |
137 | 137 | ||
138 | local_irq_save(flags); | 138 | local_irq_save(flags); |
139 | 139 | ||
140 | /* run 3 times to ensure the cache is warm */ | 140 | /* run 3 times to ensure the cache is warm and to get an accurate reading */ |
141 | for (i = 0; i < 3; i++) { | 141 | for (i = 0; i < 3; i++) { |
142 | mach_prepare_counter(); | 142 | mach_prepare_counter(); |
143 | rdtscll(start); | 143 | rdtscll(start); |
144 | mach_countup(&count); | 144 | mach_countup(&count); |
145 | rdtscll(end); | 145 | rdtscll(end); |
146 | } | ||
147 | /* | ||
148 | * Error: ECTCNEVERSET | ||
149 | * The CTC wasn't reliable: we got a hit on the very first read, | ||
150 | * or the CPU was so fast/slow that the quotient wouldn't fit in | ||
151 | * 32 bits.. | ||
152 | */ | ||
153 | if (count <= 1) | ||
154 | goto err; | ||
155 | 146 | ||
156 | delta64 = end - start; | 147 | /* |
148 | * Error: ECTCNEVERSET | ||
149 | * The CTC wasn't reliable: we got a hit on the very first read, | ||
150 | * or the CPU was so fast/slow that the quotient wouldn't fit in | ||
151 | * 32 bits.. | ||
152 | */ | ||
153 | if (count <= 1) | ||
154 | continue; | ||
155 | |||
156 | /* cpu freq too slow: */ | ||
157 | if ((end - start) <= CALIBRATE_TIME_MSEC) | ||
158 | continue; | ||
159 | |||
160 | /* | ||
161 | * We want the minimum time of all runs in case one of them | ||
162 | * is inaccurate due to SMI or other delay | ||
163 | */ | ||
164 | delta64 = min(delta64, (end - start)); | ||
165 | } | ||
157 | 166 | ||
158 | /* cpu freq too fast: */ | 167 | /* cpu freq too fast (or every run was bad): */ |
159 | if (delta64 > (1ULL<<32)) | 168 | if (delta64 > (1ULL<<32)) |
160 | goto err; | 169 | goto err; |
161 | 170 | ||
162 | /* cpu freq too slow: */ | ||
163 | if (delta64 <= CALIBRATE_TIME_MSEC) | ||
164 | goto err; | ||
165 | |||
166 | delta64 += CALIBRATE_TIME_MSEC/2; /* round for do_div */ | 171 | delta64 += CALIBRATE_TIME_MSEC/2; /* round for do_div */ |
167 | do_div(delta64,CALIBRATE_TIME_MSEC); | 172 | do_div(delta64,CALIBRATE_TIME_MSEC); |
168 | 173 | ||
diff --git a/arch/x86/oprofile/Kconfig b/arch/x86/oprofile/Kconfig deleted file mode 100644 index d8a84088471a..000000000000 --- a/arch/x86/oprofile/Kconfig +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | config PROFILING | ||
2 | bool "Profiling support (EXPERIMENTAL)" | ||
3 | help | ||
4 | Say Y here to enable the extended profiling support mechanisms used | ||
5 | by profilers such as OProfile. | ||
6 | |||
7 | |||
8 | config OPROFILE | ||
9 | tristate "OProfile system profiling (EXPERIMENTAL)" | ||
10 | depends on PROFILING | ||
11 | help | ||
12 | OProfile is a profiling system capable of profiling the | ||
13 | whole system, include the kernel, kernel modules, libraries, | ||
14 | and applications. | ||
15 | |||
16 | If unsure, say N. | ||
17 | |||
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index c2d24991bb2b..308970aa5382 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
@@ -833,6 +833,8 @@ source "drivers/firmware/Kconfig" | |||
833 | 833 | ||
834 | source fs/Kconfig | 834 | source fs/Kconfig |
835 | 835 | ||
836 | source "kernel/Kconfig.instrumentation" | ||
837 | |||
836 | source "arch/x86_64/Kconfig.debug" | 838 | source "arch/x86_64/Kconfig.debug" |
837 | 839 | ||
838 | source "security/Kconfig" | 840 | source "security/Kconfig" |
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index 6d89ab762ffc..20eb69bd5a6d 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile | |||
@@ -24,6 +24,12 @@ | |||
24 | # Fill in SRCARCH | 24 | # Fill in SRCARCH |
25 | SRCARCH := x86 | 25 | SRCARCH := x86 |
26 | 26 | ||
27 | # BITS is used as extension for files which are available in a 32 bit | ||
28 | # and a 64 bit version to simplify shared Makefiles. | ||
29 | # e.g.: obj-y += foo_$(BITS).o | ||
30 | BITS := 64 | ||
31 | export BITS | ||
32 | |||
27 | LDFLAGS := -m elf_x86_64 | 33 | LDFLAGS := -m elf_x86_64 |
28 | OBJCOPYFLAGS := -O binary -R .note -R .comment -S | 34 | OBJCOPYFLAGS := -O binary -R .note -R .comment -S |
29 | LDFLAGS_vmlinux := | 35 | LDFLAGS_vmlinux := |
diff --git a/drivers/Makefile b/drivers/Makefile index 560496b43306..8cb37e3557d4 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -34,7 +34,6 @@ obj-$(CONFIG_NUBUS) += nubus/ | |||
34 | obj-$(CONFIG_ATM) += atm/ | 34 | obj-$(CONFIG_ATM) += atm/ |
35 | obj-y += macintosh/ | 35 | obj-y += macintosh/ |
36 | obj-$(CONFIG_IDE) += ide/ | 36 | obj-$(CONFIG_IDE) += ide/ |
37 | obj-$(CONFIG_FC4) += fc4/ | ||
38 | obj-$(CONFIG_SCSI) += scsi/ | 37 | obj-$(CONFIG_SCSI) += scsi/ |
39 | obj-$(CONFIG_ATA) += ata/ | 38 | obj-$(CONFIG_ATA) += ata/ |
40 | obj-$(CONFIG_FUSION) += message/ | 39 | obj-$(CONFIG_FUSION) += message/ |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 47c806040524..95229e77bffe 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -227,7 +227,7 @@ struct ahci_port_priv { | |||
227 | 227 | ||
228 | static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); | 228 | static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); |
229 | static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); | 229 | static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); |
230 | static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 230 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); |
231 | static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); | 231 | static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); |
232 | static void ahci_irq_clear(struct ata_port *ap); | 232 | static void ahci_irq_clear(struct ata_port *ap); |
233 | static int ahci_port_start(struct ata_port *ap); | 233 | static int ahci_port_start(struct ata_port *ap); |
@@ -729,7 +729,7 @@ static int ahci_stop_engine(struct ata_port *ap) | |||
729 | 729 | ||
730 | /* wait for engine to stop. This could be as long as 500 msec */ | 730 | /* wait for engine to stop. This could be as long as 500 msec */ |
731 | tmp = ata_wait_register(port_mmio + PORT_CMD, | 731 | tmp = ata_wait_register(port_mmio + PORT_CMD, |
732 | PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500); | 732 | PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500); |
733 | if (tmp & PORT_CMD_LIST_ON) | 733 | if (tmp & PORT_CMD_LIST_ON) |
734 | return -EIO; | 734 | return -EIO; |
735 | 735 | ||
@@ -1564,9 +1564,9 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance) | |||
1564 | if (!irq_stat) | 1564 | if (!irq_stat) |
1565 | return IRQ_NONE; | 1565 | return IRQ_NONE; |
1566 | 1566 | ||
1567 | spin_lock(&host->lock); | 1567 | spin_lock(&host->lock); |
1568 | 1568 | ||
1569 | for (i = 0; i < host->n_ports; i++) { | 1569 | for (i = 0; i < host->n_ports; i++) { |
1570 | struct ata_port *ap; | 1570 | struct ata_port *ap; |
1571 | 1571 | ||
1572 | if (!(irq_stat & (1 << i))) | 1572 | if (!(irq_stat & (1 << i))) |
@@ -1829,9 +1829,9 @@ static int ahci_port_start(struct ata_port *ap) | |||
1829 | pp->cmd_tbl_dma = mem_dma; | 1829 | pp->cmd_tbl_dma = mem_dma; |
1830 | 1830 | ||
1831 | /* | 1831 | /* |
1832 | * Save off initial list of interrupts to be enabled. | 1832 | * Save off initial list of interrupts to be enabled. |
1833 | * This could be changed later | 1833 | * This could be changed later |
1834 | */ | 1834 | */ |
1835 | pp->intr_mask = DEF_PORT_IRQ; | 1835 | pp->intr_mask = DEF_PORT_IRQ; |
1836 | 1836 | ||
1837 | ap->private_data = pp; | 1837 | ap->private_data = pp; |
@@ -1918,12 +1918,12 @@ static void ahci_print_info(struct ata_host *host) | |||
1918 | dev_printk(KERN_INFO, &pdev->dev, | 1918 | dev_printk(KERN_INFO, &pdev->dev, |
1919 | "AHCI %02x%02x.%02x%02x " | 1919 | "AHCI %02x%02x.%02x%02x " |
1920 | "%u slots %u ports %s Gbps 0x%x impl %s mode\n" | 1920 | "%u slots %u ports %s Gbps 0x%x impl %s mode\n" |
1921 | , | 1921 | , |
1922 | 1922 | ||
1923 | (vers >> 24) & 0xff, | 1923 | (vers >> 24) & 0xff, |
1924 | (vers >> 16) & 0xff, | 1924 | (vers >> 16) & 0xff, |
1925 | (vers >> 8) & 0xff, | 1925 | (vers >> 8) & 0xff, |
1926 | vers & 0xff, | 1926 | vers & 0xff, |
1927 | 1927 | ||
1928 | ((cap >> 8) & 0x1f) + 1, | 1928 | ((cap >> 8) & 0x1f) + 1, |
1929 | (cap & 0x1f) + 1, | 1929 | (cap & 0x1f) + 1, |
@@ -1935,7 +1935,7 @@ static void ahci_print_info(struct ata_host *host) | |||
1935 | "flags: " | 1935 | "flags: " |
1936 | "%s%s%s%s%s%s%s" | 1936 | "%s%s%s%s%s%s%s" |
1937 | "%s%s%s%s%s%s%s\n" | 1937 | "%s%s%s%s%s%s%s\n" |
1938 | , | 1938 | , |
1939 | 1939 | ||
1940 | cap & (1 << 31) ? "64bit " : "", | 1940 | cap & (1 << 31) ? "64bit " : "", |
1941 | cap & (1 << 30) ? "ncq " : "", | 1941 | cap & (1 << 30) ? "ncq " : "", |
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 3c6f43e381f4..a4b2cb29f46c 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -157,12 +157,12 @@ struct piix_host_priv { | |||
157 | const int *map; | 157 | const int *map; |
158 | }; | 158 | }; |
159 | 159 | ||
160 | static int piix_init_one (struct pci_dev *pdev, | 160 | static int piix_init_one(struct pci_dev *pdev, |
161 | const struct pci_device_id *ent); | 161 | const struct pci_device_id *ent); |
162 | static void piix_pata_error_handler(struct ata_port *ap); | 162 | static void piix_pata_error_handler(struct ata_port *ap); |
163 | static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev); | 163 | static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev); |
164 | static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev); | 164 | static void piix_set_dmamode(struct ata_port *ap, struct ata_device *adev); |
165 | static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev); | 165 | static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev); |
166 | static int ich_pata_cable_detect(struct ata_port *ap); | 166 | static int ich_pata_cable_detect(struct ata_port *ap); |
167 | #ifdef CONFIG_PM | 167 | #ifdef CONFIG_PM |
168 | static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); | 168 | static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); |
@@ -650,9 +650,9 @@ static int ich_pata_cable_detect(struct ata_port *ap) | |||
650 | while (lap->device) { | 650 | while (lap->device) { |
651 | if (lap->device == pdev->device && | 651 | if (lap->device == pdev->device && |
652 | lap->subvendor == pdev->subsystem_vendor && | 652 | lap->subvendor == pdev->subsystem_vendor && |
653 | lap->subdevice == pdev->subsystem_device) { | 653 | lap->subdevice == pdev->subsystem_device) |
654 | return ATA_CBL_PATA40_SHORT; | 654 | return ATA_CBL_PATA40_SHORT; |
655 | } | 655 | |
656 | lap++; | 656 | lap++; |
657 | } | 657 | } |
658 | 658 | ||
@@ -699,7 +699,7 @@ static void piix_pata_error_handler(struct ata_port *ap) | |||
699 | * None (inherited from caller). | 699 | * None (inherited from caller). |
700 | */ | 700 | */ |
701 | 701 | ||
702 | static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev) | 702 | static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev) |
703 | { | 703 | { |
704 | unsigned int pio = adev->pio_mode - XFER_PIO_0; | 704 | unsigned int pio = adev->pio_mode - XFER_PIO_0; |
705 | struct pci_dev *dev = to_pci_dev(ap->host->dev); | 705 | struct pci_dev *dev = to_pci_dev(ap->host->dev); |
@@ -786,7 +786,7 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev) | |||
786 | * None (inherited from caller). | 786 | * None (inherited from caller). |
787 | */ | 787 | */ |
788 | 788 | ||
789 | static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, int isich) | 789 | static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, int isich) |
790 | { | 790 | { |
791 | struct pci_dev *dev = to_pci_dev(ap->host->dev); | 791 | struct pci_dev *dev = to_pci_dev(ap->host->dev); |
792 | u8 master_port = ap->port_no ? 0x42 : 0x40; | 792 | u8 master_port = ap->port_no ? 0x42 : 0x40; |
@@ -813,7 +813,7 @@ static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, i | |||
813 | int u_clock, u_speed; | 813 | int u_clock, u_speed; |
814 | 814 | ||
815 | /* | 815 | /* |
816 | * UDMA is handled by a combination of clock switching and | 816 | * UDMA is handled by a combination of clock switching and |
817 | * selection of dividers | 817 | * selection of dividers |
818 | * | 818 | * |
819 | * Handy rule: Odd modes are UDMATIMx 01, even are 02 | 819 | * Handy rule: Odd modes are UDMATIMx 01, even are 02 |
@@ -905,7 +905,7 @@ static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, i | |||
905 | * None (inherited from caller). | 905 | * None (inherited from caller). |
906 | */ | 906 | */ |
907 | 907 | ||
908 | static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev) | 908 | static void piix_set_dmamode(struct ata_port *ap, struct ata_device *adev) |
909 | { | 909 | { |
910 | do_pata_set_dmamode(ap, adev, 0); | 910 | do_pata_set_dmamode(ap, adev, 0); |
911 | } | 911 | } |
@@ -921,7 +921,7 @@ static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev) | |||
921 | * None (inherited from caller). | 921 | * None (inherited from caller). |
922 | */ | 922 | */ |
923 | 923 | ||
924 | static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev) | 924 | static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev) |
925 | { | 925 | { |
926 | do_pata_set_dmamode(ap, adev, 1); | 926 | do_pata_set_dmamode(ap, adev, 1); |
927 | } | 927 | } |
@@ -1106,8 +1106,7 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev) | |||
1106 | u16 cfg; | 1106 | u16 cfg; |
1107 | int no_piix_dma = 0; | 1107 | int no_piix_dma = 0; |
1108 | 1108 | ||
1109 | while((pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, pdev)) != NULL) | 1109 | while ((pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, pdev)) != NULL) { |
1110 | { | ||
1111 | /* Look for 450NX PXB. Check for problem configurations | 1110 | /* Look for 450NX PXB. Check for problem configurations |
1112 | A PCI quirk checks bit 6 already */ | 1111 | A PCI quirk checks bit 6 already */ |
1113 | pci_read_config_word(pdev, 0x41, &cfg); | 1112 | pci_read_config_word(pdev, 0x41, &cfg); |
@@ -1241,7 +1240,7 @@ static void piix_iocfg_bit18_quirk(struct pci_dev *pdev) | |||
1241 | * Zero on success, or -ERRNO value. | 1240 | * Zero on success, or -ERRNO value. |
1242 | */ | 1241 | */ |
1243 | 1242 | ||
1244 | static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | 1243 | static int piix_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
1245 | { | 1244 | { |
1246 | static int printed_version; | 1245 | static int printed_version; |
1247 | struct device *dev = &pdev->dev; | 1246 | struct device *dev = &pdev->dev; |
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 3f7533589041..08a52dd45fb6 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <acpi/actypes.h> | 26 | #include <acpi/actypes.h> |
27 | 27 | ||
28 | #define NO_PORT_MULT 0xffff | 28 | #define NO_PORT_MULT 0xffff |
29 | #define SATA_ADR(root,pmp) (((root) << 16) | (pmp)) | 29 | #define SATA_ADR(root, pmp) (((root) << 16) | (pmp)) |
30 | 30 | ||
31 | #define REGS_PER_GTF 7 | 31 | #define REGS_PER_GTF 7 |
32 | struct ata_acpi_gtf { | 32 | struct ata_acpi_gtf { |
@@ -96,8 +96,8 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) | |||
96 | } | 96 | } |
97 | } | 97 | } |
98 | 98 | ||
99 | static void ata_acpi_handle_hotplug (struct ata_port *ap, struct kobject *kobj, | 99 | static void ata_acpi_handle_hotplug(struct ata_port *ap, struct kobject *kobj, |
100 | u32 event) | 100 | u32 event) |
101 | { | 101 | { |
102 | char event_string[12]; | 102 | char event_string[12]; |
103 | char *envp[] = { event_string, NULL }; | 103 | char *envp[] = { event_string, NULL }; |
@@ -114,7 +114,7 @@ static void ata_acpi_handle_hotplug (struct ata_port *ap, struct kobject *kobj, | |||
114 | } | 114 | } |
115 | 115 | ||
116 | if (kobj) { | 116 | if (kobj) { |
117 | sprintf(event_string, "BAY_EVENT=%d", event); | 117 | sprintf(event_string, "BAY_EVENT=%d", event); |
118 | kobject_uevent_env(kobj, KOBJ_CHANGE, envp); | 118 | kobject_uevent_env(kobj, KOBJ_CHANGE, envp); |
119 | } | 119 | } |
120 | } | 120 | } |
@@ -127,14 +127,14 @@ static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) | |||
127 | if (dev->sdev) | 127 | if (dev->sdev) |
128 | kobj = &dev->sdev->sdev_gendev.kobj; | 128 | kobj = &dev->sdev->sdev_gendev.kobj; |
129 | 129 | ||
130 | ata_acpi_handle_hotplug (dev->link->ap, kobj, event); | 130 | ata_acpi_handle_hotplug(dev->link->ap, kobj, event); |
131 | } | 131 | } |
132 | 132 | ||
133 | static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) | 133 | static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) |
134 | { | 134 | { |
135 | struct ata_port *ap = data; | 135 | struct ata_port *ap = data; |
136 | 136 | ||
137 | ata_acpi_handle_hotplug (ap, &ap->dev->kobj, event); | 137 | ata_acpi_handle_hotplug(ap, &ap->dev->kobj, event); |
138 | } | 138 | } |
139 | 139 | ||
140 | /** | 140 | /** |
@@ -398,11 +398,11 @@ int ata_acpi_cbl_80wire(struct ata_port *ap) | |||
398 | { | 398 | { |
399 | struct ata_acpi_gtm gtm; | 399 | struct ata_acpi_gtm gtm; |
400 | int valid = 0; | 400 | int valid = 0; |
401 | 401 | ||
402 | /* No _GTM data, no information */ | 402 | /* No _GTM data, no information */ |
403 | if (ata_acpi_gtm(ap, >m) < 0) | 403 | if (ata_acpi_gtm(ap, >m) < 0) |
404 | return 0; | 404 | return 0; |
405 | 405 | ||
406 | /* Split timing, DMA enabled */ | 406 | /* Split timing, DMA enabled */ |
407 | if ((gtm.flags & 0x11) == 0x11 && gtm.drive[0].dma < 55) | 407 | if ((gtm.flags & 0x11) == 0x11 && gtm.drive[0].dma < 55) |
408 | valid |= 1; | 408 | valid |= 1; |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 69092bce1ada..2d147b51c978 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -49,11 +49,11 @@ | |||
49 | #include <linux/workqueue.h> | 49 | #include <linux/workqueue.h> |
50 | #include <linux/jiffies.h> | 50 | #include <linux/jiffies.h> |
51 | #include <linux/scatterlist.h> | 51 | #include <linux/scatterlist.h> |
52 | #include <linux/io.h> | ||
52 | #include <scsi/scsi.h> | 53 | #include <scsi/scsi.h> |
53 | #include <scsi/scsi_cmnd.h> | 54 | #include <scsi/scsi_cmnd.h> |
54 | #include <scsi/scsi_host.h> | 55 | #include <scsi/scsi_host.h> |
55 | #include <linux/libata.h> | 56 | #include <linux/libata.h> |
56 | #include <asm/io.h> | ||
57 | #include <asm/semaphore.h> | 57 | #include <asm/semaphore.h> |
58 | #include <asm/byteorder.h> | 58 | #include <asm/byteorder.h> |
59 | 59 | ||
@@ -93,7 +93,7 @@ int libata_fua = 0; | |||
93 | module_param_named(fua, libata_fua, int, 0444); | 93 | module_param_named(fua, libata_fua, int, 0444); |
94 | MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)"); | 94 | MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)"); |
95 | 95 | ||
96 | static int ata_ignore_hpa = 0; | 96 | static int ata_ignore_hpa; |
97 | module_param_named(ignore_hpa, ata_ignore_hpa, int, 0644); | 97 | module_param_named(ignore_hpa, ata_ignore_hpa, int, 0644); |
98 | MODULE_PARM_DESC(ignore_hpa, "Ignore HPA limit (0=keep BIOS limits, 1=ignore limits, using full disk)"); | 98 | MODULE_PARM_DESC(ignore_hpa, "Ignore HPA limit (0=keep BIOS limits, 1=ignore limits, using full disk)"); |
99 | 99 | ||
@@ -713,7 +713,7 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf) | |||
713 | } | 713 | } |
714 | 714 | ||
715 | if ((tf->lbam == 0x3c) && (tf->lbah == 0xc3)) { | 715 | if ((tf->lbam == 0x3c) && (tf->lbah == 0xc3)) { |
716 | printk("ata: SEMB device ignored\n"); | 716 | printk(KERN_INFO "ata: SEMB device ignored\n"); |
717 | return ATA_DEV_SEMB_UNSUP; /* not yet */ | 717 | return ATA_DEV_SEMB_UNSUP; /* not yet */ |
718 | } | 718 | } |
719 | 719 | ||
@@ -939,7 +939,7 @@ static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors) | |||
939 | *max_sectors = ata_tf_to_lba48(&tf); | 939 | *max_sectors = ata_tf_to_lba48(&tf); |
940 | else | 940 | else |
941 | *max_sectors = ata_tf_to_lba(&tf); | 941 | *max_sectors = ata_tf_to_lba(&tf); |
942 | if (dev->horkage & ATA_HORKAGE_HPA_SIZE) | 942 | if (dev->horkage & ATA_HORKAGE_HPA_SIZE) |
943 | (*max_sectors)--; | 943 | (*max_sectors)--; |
944 | return 0; | 944 | return 0; |
945 | } | 945 | } |
@@ -1151,7 +1151,7 @@ void ata_id_to_dma_mode(struct ata_device *dev, u8 unknown) | |||
1151 | * LOCKING: | 1151 | * LOCKING: |
1152 | * caller. | 1152 | * caller. |
1153 | */ | 1153 | */ |
1154 | void ata_noop_dev_select (struct ata_port *ap, unsigned int device) | 1154 | void ata_noop_dev_select(struct ata_port *ap, unsigned int device) |
1155 | { | 1155 | { |
1156 | } | 1156 | } |
1157 | 1157 | ||
@@ -1171,7 +1171,7 @@ void ata_noop_dev_select (struct ata_port *ap, unsigned int device) | |||
1171 | * caller. | 1171 | * caller. |
1172 | */ | 1172 | */ |
1173 | 1173 | ||
1174 | void ata_std_dev_select (struct ata_port *ap, unsigned int device) | 1174 | void ata_std_dev_select(struct ata_port *ap, unsigned int device) |
1175 | { | 1175 | { |
1176 | u8 tmp; | 1176 | u8 tmp; |
1177 | 1177 | ||
@@ -1292,7 +1292,7 @@ static unsigned int ata_id_xfermask(const u16 *id) | |||
1292 | */ | 1292 | */ |
1293 | u8 mode = (id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF; | 1293 | u8 mode = (id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF; |
1294 | if (mode < 5) /* Valid PIO range */ | 1294 | if (mode < 5) /* Valid PIO range */ |
1295 | pio_mask = (2 << mode) - 1; | 1295 | pio_mask = (2 << mode) - 1; |
1296 | else | 1296 | else |
1297 | pio_mask = 1; | 1297 | pio_mask = 1; |
1298 | 1298 | ||
@@ -1693,7 +1693,7 @@ static u32 ata_pio_mask_no_iordy(const struct ata_device *adev) | |||
1693 | * for pre-ATA4 drives. | 1693 | * for pre-ATA4 drives. |
1694 | * | 1694 | * |
1695 | * FIXME: ATA_CMD_ID_ATA is optional for early drives and right | 1695 | * FIXME: ATA_CMD_ID_ATA is optional for early drives and right |
1696 | * now we abort if we hit that case. | 1696 | * now we abort if we hit that case. |
1697 | * | 1697 | * |
1698 | * LOCKING: | 1698 | * LOCKING: |
1699 | * Kernel thread context (may sleep) | 1699 | * Kernel thread context (may sleep) |
@@ -1979,9 +1979,8 @@ int ata_dev_configure(struct ata_device *dev) | |||
1979 | "supports DRM functions and may " | 1979 | "supports DRM functions and may " |
1980 | "not be fully accessable.\n"); | 1980 | "not be fully accessable.\n"); |
1981 | snprintf(revbuf, 7, "CFA"); | 1981 | snprintf(revbuf, 7, "CFA"); |
1982 | } | 1982 | } else |
1983 | else | 1983 | snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id)); |
1984 | snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id)); | ||
1985 | 1984 | ||
1986 | dev->n_sectors = ata_id_n_sectors(id); | 1985 | dev->n_sectors = ata_id_n_sectors(id); |
1987 | 1986 | ||
@@ -2110,7 +2109,7 @@ int ata_dev_configure(struct ata_device *dev) | |||
2110 | /* Let the user know. We don't want to disallow opens for | 2109 | /* Let the user know. We don't want to disallow opens for |
2111 | rescue purposes, or in case the vendor is just a blithering | 2110 | rescue purposes, or in case the vendor is just a blithering |
2112 | idiot */ | 2111 | idiot */ |
2113 | if (print_info) { | 2112 | if (print_info) { |
2114 | ata_dev_printk(dev, KERN_WARNING, | 2113 | ata_dev_printk(dev, KERN_WARNING, |
2115 | "Drive reports diagnostics failure. This may indicate a drive\n"); | 2114 | "Drive reports diagnostics failure. This may indicate a drive\n"); |
2116 | ata_dev_printk(dev, KERN_WARNING, | 2115 | ata_dev_printk(dev, KERN_WARNING, |
@@ -2667,8 +2666,8 @@ static const struct ata_timing ata_timing[] = { | |||
2667 | { 0xFF } | 2666 | { 0xFF } |
2668 | }; | 2667 | }; |
2669 | 2668 | ||
2670 | #define ENOUGH(v,unit) (((v)-1)/(unit)+1) | 2669 | #define ENOUGH(v, unit) (((v)-1)/(unit)+1) |
2671 | #define EZ(v,unit) ((v)?ENOUGH(v,unit):0) | 2670 | #define EZ(v, unit) ((v)?ENOUGH(v, unit):0) |
2672 | 2671 | ||
2673 | static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT) | 2672 | static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT) |
2674 | { | 2673 | { |
@@ -2695,7 +2694,7 @@ void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b, | |||
2695 | if (what & ATA_TIMING_UDMA ) m->udma = max(a->udma, b->udma); | 2694 | if (what & ATA_TIMING_UDMA ) m->udma = max(a->udma, b->udma); |
2696 | } | 2695 | } |
2697 | 2696 | ||
2698 | static const struct ata_timing* ata_timing_find_mode(unsigned short speed) | 2697 | static const struct ata_timing *ata_timing_find_mode(unsigned short speed) |
2699 | { | 2698 | { |
2700 | const struct ata_timing *t; | 2699 | const struct ata_timing *t; |
2701 | 2700 | ||
@@ -2727,10 +2726,10 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, | |||
2727 | 2726 | ||
2728 | if (adev->id[ATA_ID_FIELD_VALID] & 2) { /* EIDE drive */ | 2727 | if (adev->id[ATA_ID_FIELD_VALID] & 2) { /* EIDE drive */ |
2729 | memset(&p, 0, sizeof(p)); | 2728 | memset(&p, 0, sizeof(p)); |
2730 | if(speed >= XFER_PIO_0 && speed <= XFER_SW_DMA_0) { | 2729 | if (speed >= XFER_PIO_0 && speed <= XFER_SW_DMA_0) { |
2731 | if (speed <= XFER_PIO_2) p.cycle = p.cyc8b = adev->id[ATA_ID_EIDE_PIO]; | 2730 | if (speed <= XFER_PIO_2) p.cycle = p.cyc8b = adev->id[ATA_ID_EIDE_PIO]; |
2732 | else p.cycle = p.cyc8b = adev->id[ATA_ID_EIDE_PIO_IORDY]; | 2731 | else p.cycle = p.cyc8b = adev->id[ATA_ID_EIDE_PIO_IORDY]; |
2733 | } else if(speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) { | 2732 | } else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) { |
2734 | p.cycle = adev->id[ATA_ID_EIDE_DMA_MIN]; | 2733 | p.cycle = adev->id[ATA_ID_EIDE_DMA_MIN]; |
2735 | } | 2734 | } |
2736 | ata_timing_merge(&p, t, t, ATA_TIMING_CYCLE | ATA_TIMING_CYC8B); | 2735 | ata_timing_merge(&p, t, t, ATA_TIMING_CYCLE | ATA_TIMING_CYC8B); |
@@ -2876,14 +2875,17 @@ static int ata_dev_set_mode(struct ata_device *dev) | |||
2876 | dev->flags |= ATA_DFLAG_PIO; | 2875 | dev->flags |= ATA_DFLAG_PIO; |
2877 | 2876 | ||
2878 | err_mask = ata_dev_set_xfermode(dev); | 2877 | err_mask = ata_dev_set_xfermode(dev); |
2878 | |||
2879 | /* Old CFA may refuse this command, which is just fine */ | 2879 | /* Old CFA may refuse this command, which is just fine */ |
2880 | if (dev->xfer_shift == ATA_SHIFT_PIO && ata_id_is_cfa(dev->id)) | 2880 | if (dev->xfer_shift == ATA_SHIFT_PIO && ata_id_is_cfa(dev->id)) |
2881 | err_mask &= ~AC_ERR_DEV; | 2881 | err_mask &= ~AC_ERR_DEV; |
2882 | |||
2882 | /* Some very old devices and some bad newer ones fail any kind of | 2883 | /* Some very old devices and some bad newer ones fail any kind of |
2883 | SET_XFERMODE request but support PIO0-2 timings and no IORDY */ | 2884 | SET_XFERMODE request but support PIO0-2 timings and no IORDY */ |
2884 | if (dev->xfer_shift == ATA_SHIFT_PIO && !ata_id_has_iordy(dev->id) && | 2885 | if (dev->xfer_shift == ATA_SHIFT_PIO && !ata_id_has_iordy(dev->id) && |
2885 | dev->pio_mode <= XFER_PIO_2) | 2886 | dev->pio_mode <= XFER_PIO_2) |
2886 | err_mask &= ~AC_ERR_DEV; | 2887 | err_mask &= ~AC_ERR_DEV; |
2888 | |||
2887 | if (err_mask) { | 2889 | if (err_mask) { |
2888 | ata_dev_printk(dev, KERN_ERR, "failed to set xfermode " | 2890 | ata_dev_printk(dev, KERN_ERR, "failed to set xfermode " |
2889 | "(err_mask=0x%x)\n", err_mask); | 2891 | "(err_mask=0x%x)\n", err_mask); |
@@ -3265,7 +3267,7 @@ static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask, | |||
3265 | * the bus shows 0xFF because the odd clown forgets the D7 | 3267 | * the bus shows 0xFF because the odd clown forgets the D7 |
3266 | * pulldown resistor. | 3268 | * pulldown resistor. |
3267 | */ | 3269 | */ |
3268 | if (ata_check_status(ap) == 0xFF) | 3270 | if (ata_chk_status(ap) == 0xFF) |
3269 | return -ENODEV; | 3271 | return -ENODEV; |
3270 | 3272 | ||
3271 | return ata_bus_post_reset(ap, devmask, deadline); | 3273 | return ata_bus_post_reset(ap, devmask, deadline); |
@@ -3943,7 +3945,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
3943 | { "SAMSUNG CD-ROM SC", NULL, ATA_HORKAGE_NODMA }, | 3945 | { "SAMSUNG CD-ROM SC", NULL, ATA_HORKAGE_NODMA }, |
3944 | { "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL,ATA_HORKAGE_NODMA }, | 3946 | { "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL,ATA_HORKAGE_NODMA }, |
3945 | { "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA }, | 3947 | { "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA }, |
3946 | { "SAMSUNG CD-ROM SN-124","N001", ATA_HORKAGE_NODMA }, | 3948 | { "SAMSUNG CD-ROM SN-124", "N001", ATA_HORKAGE_NODMA }, |
3947 | { "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA }, | 3949 | { "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA }, |
3948 | { "IOMEGA ZIP 250 ATAPI", NULL, ATA_HORKAGE_NODMA }, /* temporary fix */ | 3950 | { "IOMEGA ZIP 250 ATAPI", NULL, ATA_HORKAGE_NODMA }, /* temporary fix */ |
3949 | { "IOMEGA ZIP 250 ATAPI Floppy", | 3951 | { "IOMEGA ZIP 250 ATAPI Floppy", |
@@ -3959,7 +3961,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
3959 | 3961 | ||
3960 | /* Devices where NCQ should be avoided */ | 3962 | /* Devices where NCQ should be avoided */ |
3961 | /* NCQ is slow */ | 3963 | /* NCQ is slow */ |
3962 | { "WDC WD740ADFD-00", NULL, ATA_HORKAGE_NONCQ }, | 3964 | { "WDC WD740ADFD-00", NULL, ATA_HORKAGE_NONCQ }, |
3963 | /* http://thread.gmane.org/gmane.linux.ide/14907 */ | 3965 | /* http://thread.gmane.org/gmane.linux.ide/14907 */ |
3964 | { "FUJITSU MHT2060BH", NULL, ATA_HORKAGE_NONCQ }, | 3966 | { "FUJITSU MHT2060BH", NULL, ATA_HORKAGE_NONCQ }, |
3965 | /* NCQ is broken */ | 3967 | /* NCQ is broken */ |
@@ -3979,6 +3981,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
3979 | { "HTS541612J9SA00", "SBDIC7JP", ATA_HORKAGE_NONCQ, }, | 3981 | { "HTS541612J9SA00", "SBDIC7JP", ATA_HORKAGE_NONCQ, }, |
3980 | { "HDT722516DLA380", "V43OA96A", ATA_HORKAGE_NONCQ, }, | 3982 | { "HDT722516DLA380", "V43OA96A", ATA_HORKAGE_NONCQ, }, |
3981 | { "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, }, | 3983 | { "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, }, |
3984 | { "Hitachi HTS542525K9SA00", "BBFOC31P", ATA_HORKAGE_NONCQ, }, | ||
3982 | { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, }, | 3985 | { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, }, |
3983 | { "WDC WD3200AAJS-00RYA0", "12.01B01", ATA_HORKAGE_NONCQ, }, | 3986 | { "WDC WD3200AAJS-00RYA0", "12.01B01", ATA_HORKAGE_NONCQ, }, |
3984 | { "FUJITSU MHV2080BH", "00840028", ATA_HORKAGE_NONCQ, }, | 3987 | { "FUJITSU MHV2080BH", "00840028", ATA_HORKAGE_NONCQ, }, |
@@ -4106,7 +4109,7 @@ static void ata_dev_xfermask(struct ata_device *dev) | |||
4106 | } | 4109 | } |
4107 | 4110 | ||
4108 | if ((host->flags & ATA_HOST_SIMPLEX) && | 4111 | if ((host->flags & ATA_HOST_SIMPLEX) && |
4109 | host->simplex_claimed && host->simplex_claimed != ap) { | 4112 | host->simplex_claimed && host->simplex_claimed != ap) { |
4110 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); | 4113 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); |
4111 | ata_dev_printk(dev, KERN_WARNING, "simplex DMA is claimed by " | 4114 | ata_dev_printk(dev, KERN_WARNING, "simplex DMA is claimed by " |
4112 | "other device, disabling DMA\n"); | 4115 | "other device, disabling DMA\n"); |
@@ -4128,11 +4131,11 @@ static void ata_dev_xfermask(struct ata_device *dev) | |||
4128 | */ | 4131 | */ |
4129 | if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA)) | 4132 | if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA)) |
4130 | /* UDMA/44 or higher would be available */ | 4133 | /* UDMA/44 or higher would be available */ |
4131 | if((ap->cbl == ATA_CBL_PATA40) || | 4134 | if ((ap->cbl == ATA_CBL_PATA40) || |
4132 | (ata_drive_40wire(dev->id) && | 4135 | (ata_drive_40wire(dev->id) && |
4133 | (ap->cbl == ATA_CBL_PATA_UNK || | 4136 | (ap->cbl == ATA_CBL_PATA_UNK || |
4134 | ap->cbl == ATA_CBL_PATA80))) { | 4137 | ap->cbl == ATA_CBL_PATA80))) { |
4135 | ata_dev_printk(dev, KERN_WARNING, | 4138 | ata_dev_printk(dev, KERN_WARNING, |
4136 | "limited to UDMA/33 due to 40-wire cable\n"); | 4139 | "limited to UDMA/33 due to 40-wire cable\n"); |
4137 | xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); | 4140 | xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); |
4138 | } | 4141 | } |
@@ -4395,7 +4398,7 @@ static void ata_fill_sg_dumb(struct ata_queued_cmd *qc) | |||
4395 | u32 addr, offset; | 4398 | u32 addr, offset; |
4396 | u32 sg_len, len, blen; | 4399 | u32 sg_len, len, blen; |
4397 | 4400 | ||
4398 | /* determine if physical DMA addr spans 64K boundary. | 4401 | /* determine if physical DMA addr spans 64K boundary. |
4399 | * Note h/w doesn't support 64-bit, so we unconditionally | 4402 | * Note h/w doesn't support 64-bit, so we unconditionally |
4400 | * truncate dma_addr_t to u32. | 4403 | * truncate dma_addr_t to u32. |
4401 | */ | 4404 | */ |
@@ -4980,7 +4983,7 @@ next_sg: | |||
4980 | "%u bytes trailing data\n", bytes); | 4983 | "%u bytes trailing data\n", bytes); |
4981 | 4984 | ||
4982 | for (i = 0; i < words; i++) | 4985 | for (i = 0; i < words; i++) |
4983 | ap->ops->data_xfer(qc->dev, (unsigned char*)pad_buf, 2, do_write); | 4986 | ap->ops->data_xfer(qc->dev, (unsigned char *)pad_buf, 2, do_write); |
4984 | 4987 | ||
4985 | ap->hsm_task_state = HSM_ST_LAST; | 4988 | ap->hsm_task_state = HSM_ST_LAST; |
4986 | return; | 4989 | return; |
@@ -5908,8 +5911,8 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc) | |||
5908 | * One if interrupt was handled, zero if not (shared irq). | 5911 | * One if interrupt was handled, zero if not (shared irq). |
5909 | */ | 5912 | */ |
5910 | 5913 | ||
5911 | inline unsigned int ata_host_intr (struct ata_port *ap, | 5914 | inline unsigned int ata_host_intr(struct ata_port *ap, |
5912 | struct ata_queued_cmd *qc) | 5915 | struct ata_queued_cmd *qc) |
5913 | { | 5916 | { |
5914 | struct ata_eh_info *ehi = &ap->link.eh_info; | 5917 | struct ata_eh_info *ehi = &ap->link.eh_info; |
5915 | u8 status, host_stat = 0; | 5918 | u8 status, host_stat = 0; |
@@ -6009,7 +6012,7 @@ idle_irq: | |||
6009 | * IRQ_NONE or IRQ_HANDLED. | 6012 | * IRQ_NONE or IRQ_HANDLED. |
6010 | */ | 6013 | */ |
6011 | 6014 | ||
6012 | irqreturn_t ata_interrupt (int irq, void *dev_instance) | 6015 | irqreturn_t ata_interrupt(int irq, void *dev_instance) |
6013 | { | 6016 | { |
6014 | struct ata_host *host = dev_instance; | 6017 | struct ata_host *host = dev_instance; |
6015 | unsigned int i; | 6018 | unsigned int i; |
@@ -6212,7 +6215,7 @@ int ata_flush_cache(struct ata_device *dev) | |||
6212 | 6215 | ||
6213 | /* This is wrong. On a failed flush we get back the LBA of the lost | 6216 | /* This is wrong. On a failed flush we get back the LBA of the lost |
6214 | sector and we should (assuming it wasn't aborted as unknown) issue | 6217 | sector and we should (assuming it wasn't aborted as unknown) issue |
6215 | a further flush command to continue the writeback until it | 6218 | a further flush command to continue the writeback until it |
6216 | does not error */ | 6219 | does not error */ |
6217 | err_mask = ata_do_simple_cmd(dev, cmd); | 6220 | err_mask = ata_do_simple_cmd(dev, cmd); |
6218 | if (err_mask) { | 6221 | if (err_mask) { |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 2eaa39fc65d0..93e2b545b439 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -1197,7 +1197,7 @@ void ata_eh_done(struct ata_link *link, struct ata_device *dev, | |||
1197 | * RETURNS: | 1197 | * RETURNS: |
1198 | * Descriptive string for @err_mask | 1198 | * Descriptive string for @err_mask |
1199 | */ | 1199 | */ |
1200 | static const char * ata_err_string(unsigned int err_mask) | 1200 | static const char *ata_err_string(unsigned int err_mask) |
1201 | { | 1201 | { |
1202 | if (err_mask & AC_ERR_HOST_BUS) | 1202 | if (err_mask & AC_ERR_HOST_BUS) |
1203 | return "host bus error"; | 1203 | return "host bus error"; |
@@ -1934,7 +1934,7 @@ static void ata_eh_link_report(struct ata_link *link) | |||
1934 | ehc->i.serror & SERR_LINK_SEQ_ERR ? "LinkSeq " : "", | 1934 | ehc->i.serror & SERR_LINK_SEQ_ERR ? "LinkSeq " : "", |
1935 | ehc->i.serror & SERR_TRANS_ST_ERROR ? "TrStaTrns " : "", | 1935 | ehc->i.serror & SERR_TRANS_ST_ERROR ? "TrStaTrns " : "", |
1936 | ehc->i.serror & SERR_UNRECOG_FIS ? "UnrecFIS " : "", | 1936 | ehc->i.serror & SERR_UNRECOG_FIS ? "UnrecFIS " : "", |
1937 | ehc->i.serror & SERR_DEV_XCHG ? "DevExch " : "" ); | 1937 | ehc->i.serror & SERR_DEV_XCHG ? "DevExch " : ""); |
1938 | 1938 | ||
1939 | for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { | 1939 | for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { |
1940 | static const char *dma_str[] = { | 1940 | static const char *dma_str[] = { |
@@ -1969,17 +1969,17 @@ static void ata_eh_link_report(struct ata_link *link) | |||
1969 | qc->err_mask & AC_ERR_NCQ ? " <F>" : ""); | 1969 | qc->err_mask & AC_ERR_NCQ ? " <F>" : ""); |
1970 | 1970 | ||
1971 | if (res->command & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | | 1971 | if (res->command & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | |
1972 | ATA_ERR) ) { | 1972 | ATA_ERR)) { |
1973 | if (res->command & ATA_BUSY) | 1973 | if (res->command & ATA_BUSY) |
1974 | ata_dev_printk(qc->dev, KERN_ERR, | 1974 | ata_dev_printk(qc->dev, KERN_ERR, |
1975 | "status: { Busy }\n" ); | 1975 | "status: { Busy }\n"); |
1976 | else | 1976 | else |
1977 | ata_dev_printk(qc->dev, KERN_ERR, | 1977 | ata_dev_printk(qc->dev, KERN_ERR, |
1978 | "status: { %s%s%s%s}\n", | 1978 | "status: { %s%s%s%s}\n", |
1979 | res->command & ATA_DRDY ? "DRDY " : "", | 1979 | res->command & ATA_DRDY ? "DRDY " : "", |
1980 | res->command & ATA_DF ? "DF " : "", | 1980 | res->command & ATA_DF ? "DF " : "", |
1981 | res->command & ATA_DRQ ? "DRQ " : "", | 1981 | res->command & ATA_DRQ ? "DRQ " : "", |
1982 | res->command & ATA_ERR ? "ERR " : "" ); | 1982 | res->command & ATA_ERR ? "ERR " : ""); |
1983 | } | 1983 | } |
1984 | 1984 | ||
1985 | if (cmd->command != ATA_CMD_PACKET && | 1985 | if (cmd->command != ATA_CMD_PACKET && |
@@ -1990,7 +1990,7 @@ static void ata_eh_link_report(struct ata_link *link) | |||
1990 | res->feature & ATA_ICRC ? "ICRC " : "", | 1990 | res->feature & ATA_ICRC ? "ICRC " : "", |
1991 | res->feature & ATA_UNC ? "UNC " : "", | 1991 | res->feature & ATA_UNC ? "UNC " : "", |
1992 | res->feature & ATA_IDNF ? "IDNF " : "", | 1992 | res->feature & ATA_IDNF ? "IDNF " : "", |
1993 | res->feature & ATA_ABORTED ? "ABRT " : "" ); | 1993 | res->feature & ATA_ABORTED ? "ABRT " : ""); |
1994 | } | 1994 | } |
1995 | } | 1995 | } |
1996 | 1996 | ||
@@ -2611,7 +2611,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
2611 | ehc->i.flags = 0; | 2611 | ehc->i.flags = 0; |
2612 | continue; | 2612 | continue; |
2613 | 2613 | ||
2614 | dev_fail: | 2614 | dev_fail: |
2615 | nr_failed_devs++; | 2615 | nr_failed_devs++; |
2616 | if (ata_eh_handle_dev_fail(dev, rc)) | 2616 | if (ata_eh_handle_dev_fail(dev, rc)) |
2617 | nr_disabled_devs++; | 2617 | nr_disabled_devs++; |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 5b758b9ad0b8..f5d5420a1ba2 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -45,7 +45,7 @@ | |||
45 | #include <scsi/scsi_transport.h> | 45 | #include <scsi/scsi_transport.h> |
46 | #include <linux/libata.h> | 46 | #include <linux/libata.h> |
47 | #include <linux/hdreg.h> | 47 | #include <linux/hdreg.h> |
48 | #include <asm/uaccess.h> | 48 | #include <linux/uaccess.h> |
49 | 49 | ||
50 | #include "libata.h" | 50 | #include "libata.h" |
51 | 51 | ||
@@ -53,9 +53,9 @@ | |||
53 | 53 | ||
54 | typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc); | 54 | typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc); |
55 | 55 | ||
56 | static struct ata_device * __ata_scsi_find_dev(struct ata_port *ap, | 56 | static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, |
57 | const struct scsi_device *scsidev); | 57 | const struct scsi_device *scsidev); |
58 | static struct ata_device * ata_scsi_find_dev(struct ata_port *ap, | 58 | static struct ata_device *ata_scsi_find_dev(struct ata_port *ap, |
59 | const struct scsi_device *scsidev); | 59 | const struct scsi_device *scsidev); |
60 | static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, | 60 | static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, |
61 | unsigned int id, unsigned int lun); | 61 | unsigned int id, unsigned int lun); |
@@ -228,7 +228,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) | |||
228 | 228 | ||
229 | scsi_cmd[1] = (4 << 1); /* PIO Data-in */ | 229 | scsi_cmd[1] = (4 << 1); /* PIO Data-in */ |
230 | scsi_cmd[2] = 0x0e; /* no off.line or cc, read from dev, | 230 | scsi_cmd[2] = 0x0e; /* no off.line or cc, read from dev, |
231 | block count in sector count field */ | 231 | block count in sector count field */ |
232 | data_dir = DMA_FROM_DEVICE; | 232 | data_dir = DMA_FROM_DEVICE; |
233 | } else { | 233 | } else { |
234 | scsi_cmd[1] = (3 << 1); /* Non-data */ | 234 | scsi_cmd[1] = (3 << 1); /* Non-data */ |
@@ -252,7 +252,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) | |||
252 | /* Good values for timeout and retries? Values below | 252 | /* Good values for timeout and retries? Values below |
253 | from scsi_ioctl_send_command() for default case... */ | 253 | from scsi_ioctl_send_command() for default case... */ |
254 | cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize, | 254 | cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize, |
255 | sensebuf, (10*HZ), 5, 0); | 255 | sensebuf, (10*HZ), 5, 0); |
256 | 256 | ||
257 | if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */ | 257 | if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */ |
258 | u8 *desc = sensebuf + 8; | 258 | u8 *desc = sensebuf + 8; |
@@ -263,18 +263,18 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) | |||
263 | if (cmd_result & SAM_STAT_CHECK_CONDITION) { | 263 | if (cmd_result & SAM_STAT_CHECK_CONDITION) { |
264 | struct scsi_sense_hdr sshdr; | 264 | struct scsi_sense_hdr sshdr; |
265 | scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, | 265 | scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, |
266 | &sshdr); | 266 | &sshdr); |
267 | if (sshdr.sense_key==0 && | 267 | if (sshdr.sense_key == 0 && |
268 | sshdr.asc==0 && sshdr.ascq==0) | 268 | sshdr.asc == 0 && sshdr.ascq == 0) |
269 | cmd_result &= ~SAM_STAT_CHECK_CONDITION; | 269 | cmd_result &= ~SAM_STAT_CHECK_CONDITION; |
270 | } | 270 | } |
271 | 271 | ||
272 | /* Send userspace a few ATA registers (same as drivers/ide) */ | 272 | /* Send userspace a few ATA registers (same as drivers/ide) */ |
273 | if (sensebuf[0] == 0x72 && /* format is "descriptor" */ | 273 | if (sensebuf[0] == 0x72 && /* format is "descriptor" */ |
274 | desc[0] == 0x09 ) { /* code is "ATA Descriptor" */ | 274 | desc[0] == 0x09) { /* code is "ATA Descriptor" */ |
275 | args[0] = desc[13]; /* status */ | 275 | args[0] = desc[13]; /* status */ |
276 | args[1] = desc[3]; /* error */ | 276 | args[1] = desc[3]; /* error */ |
277 | args[2] = desc[5]; /* sector count (0:7) */ | 277 | args[2] = desc[5]; /* sector count (0:7) */ |
278 | if (copy_to_user(arg, args, sizeof(args))) | 278 | if (copy_to_user(arg, args, sizeof(args))) |
279 | rc = -EFAULT; | 279 | rc = -EFAULT; |
280 | } | 280 | } |
@@ -350,8 +350,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) | |||
350 | struct scsi_sense_hdr sshdr; | 350 | struct scsi_sense_hdr sshdr; |
351 | scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, | 351 | scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, |
352 | &sshdr); | 352 | &sshdr); |
353 | if (sshdr.sense_key==0 && | 353 | if (sshdr.sense_key == 0 && |
354 | sshdr.asc==0 && sshdr.ascq==0) | 354 | sshdr.asc == 0 && sshdr.ascq == 0) |
355 | cmd_result &= ~SAM_STAT_CHECK_CONDITION; | 355 | cmd_result &= ~SAM_STAT_CHECK_CONDITION; |
356 | } | 356 | } |
357 | 357 | ||
@@ -975,7 +975,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) | |||
975 | if ((qc->dev->flags & ATA_DFLAG_SPUNDOWN) && | 975 | if ((qc->dev->flags & ATA_DFLAG_SPUNDOWN) && |
976 | (system_state == SYSTEM_HALT || | 976 | (system_state == SYSTEM_HALT || |
977 | system_state == SYSTEM_POWER_OFF)) { | 977 | system_state == SYSTEM_POWER_OFF)) { |
978 | static unsigned long warned = 0; | 978 | static unsigned long warned; |
979 | 979 | ||
980 | if (!test_and_set_bit(0, &warned)) { | 980 | if (!test_and_set_bit(0, &warned)) { |
981 | ata_dev_printk(qc->dev, KERN_WARNING, | 981 | ata_dev_printk(qc->dev, KERN_WARNING, |
@@ -1364,7 +1364,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) | |||
1364 | struct ata_eh_info *ehi = &qc->dev->link->eh_info; | 1364 | struct ata_eh_info *ehi = &qc->dev->link->eh_info; |
1365 | struct scsi_cmnd *cmd = qc->scsicmd; | 1365 | struct scsi_cmnd *cmd = qc->scsicmd; |
1366 | u8 *cdb = cmd->cmnd; | 1366 | u8 *cdb = cmd->cmnd; |
1367 | int need_sense = (qc->err_mask != 0); | 1367 | int need_sense = (qc->err_mask != 0); |
1368 | 1368 | ||
1369 | /* We snoop the SET_FEATURES - Write Cache ON/OFF command, and | 1369 | /* We snoop the SET_FEATURES - Write Cache ON/OFF command, and |
1370 | * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE | 1370 | * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE |
@@ -1396,7 +1396,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) | |||
1396 | * was no error, SK, ASC and ASCQ will all be zero. | 1396 | * was no error, SK, ASC and ASCQ will all be zero. |
1397 | */ | 1397 | */ |
1398 | if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) && | 1398 | if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) && |
1399 | ((cdb[2] & 0x20) || need_sense)) { | 1399 | ((cdb[2] & 0x20) || need_sense)) { |
1400 | ata_gen_passthru_sense(qc); | 1400 | ata_gen_passthru_sense(qc); |
1401 | } else { | 1401 | } else { |
1402 | if (!need_sense) { | 1402 | if (!need_sense) { |
@@ -1500,7 +1500,7 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, | |||
1500 | return 0; | 1500 | return 0; |
1501 | 1501 | ||
1502 | early_finish: | 1502 | early_finish: |
1503 | ata_qc_free(qc); | 1503 | ata_qc_free(qc); |
1504 | qc->scsidone(cmd); | 1504 | qc->scsidone(cmd); |
1505 | DPRINTK("EXIT - early finish (good or error)\n"); | 1505 | DPRINTK("EXIT - early finish (good or error)\n"); |
1506 | return 0; | 1506 | return 0; |
@@ -1590,8 +1590,8 @@ static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf) | |||
1590 | */ | 1590 | */ |
1591 | 1591 | ||
1592 | void ata_scsi_rbuf_fill(struct ata_scsi_args *args, | 1592 | void ata_scsi_rbuf_fill(struct ata_scsi_args *args, |
1593 | unsigned int (*actor) (struct ata_scsi_args *args, | 1593 | unsigned int (*actor) (struct ata_scsi_args *args, |
1594 | u8 *rbuf, unsigned int buflen)) | 1594 | u8 *rbuf, unsigned int buflen)) |
1595 | { | 1595 | { |
1596 | u8 *rbuf; | 1596 | u8 *rbuf; |
1597 | unsigned int buflen, rc; | 1597 | unsigned int buflen, rc; |
@@ -2140,7 +2140,7 @@ saving_not_supp: | |||
2140 | * None. | 2140 | * None. |
2141 | */ | 2141 | */ |
2142 | unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf, | 2142 | unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf, |
2143 | unsigned int buflen) | 2143 | unsigned int buflen) |
2144 | { | 2144 | { |
2145 | u64 last_lba = args->dev->n_sectors - 1; /* LBA of the last block */ | 2145 | u64 last_lba = args->dev->n_sectors - 1; /* LBA of the last block */ |
2146 | 2146 | ||
@@ -2464,7 +2464,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) | |||
2464 | return 0; | 2464 | return 0; |
2465 | } | 2465 | } |
2466 | 2466 | ||
2467 | static struct ata_device * ata_find_dev(struct ata_port *ap, int devno) | 2467 | static struct ata_device *ata_find_dev(struct ata_port *ap, int devno) |
2468 | { | 2468 | { |
2469 | if (ap->nr_pmp_links == 0) { | 2469 | if (ap->nr_pmp_links == 0) { |
2470 | if (likely(devno < ata_link_max_devices(&ap->link))) | 2470 | if (likely(devno < ata_link_max_devices(&ap->link))) |
@@ -2477,8 +2477,8 @@ static struct ata_device * ata_find_dev(struct ata_port *ap, int devno) | |||
2477 | return NULL; | 2477 | return NULL; |
2478 | } | 2478 | } |
2479 | 2479 | ||
2480 | static struct ata_device * __ata_scsi_find_dev(struct ata_port *ap, | 2480 | static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, |
2481 | const struct scsi_device *scsidev) | 2481 | const struct scsi_device *scsidev) |
2482 | { | 2482 | { |
2483 | int devno; | 2483 | int devno; |
2484 | 2484 | ||
@@ -2564,27 +2564,27 @@ static u8 | |||
2564 | ata_scsi_map_proto(u8 byte1) | 2564 | ata_scsi_map_proto(u8 byte1) |
2565 | { | 2565 | { |
2566 | switch((byte1 & 0x1e) >> 1) { | 2566 | switch((byte1 & 0x1e) >> 1) { |
2567 | case 3: /* Non-data */ | 2567 | case 3: /* Non-data */ |
2568 | return ATA_PROT_NODATA; | 2568 | return ATA_PROT_NODATA; |
2569 | 2569 | ||
2570 | case 6: /* DMA */ | 2570 | case 6: /* DMA */ |
2571 | case 10: /* UDMA Data-in */ | 2571 | case 10: /* UDMA Data-in */ |
2572 | case 11: /* UDMA Data-Out */ | 2572 | case 11: /* UDMA Data-Out */ |
2573 | return ATA_PROT_DMA; | 2573 | return ATA_PROT_DMA; |
2574 | 2574 | ||
2575 | case 4: /* PIO Data-in */ | 2575 | case 4: /* PIO Data-in */ |
2576 | case 5: /* PIO Data-out */ | 2576 | case 5: /* PIO Data-out */ |
2577 | return ATA_PROT_PIO; | 2577 | return ATA_PROT_PIO; |
2578 | 2578 | ||
2579 | case 0: /* Hard Reset */ | 2579 | case 0: /* Hard Reset */ |
2580 | case 1: /* SRST */ | 2580 | case 1: /* SRST */ |
2581 | case 8: /* Device Diagnostic */ | 2581 | case 8: /* Device Diagnostic */ |
2582 | case 9: /* Device Reset */ | 2582 | case 9: /* Device Reset */ |
2583 | case 7: /* DMA Queued */ | 2583 | case 7: /* DMA Queued */ |
2584 | case 12: /* FPDMA */ | 2584 | case 12: /* FPDMA */ |
2585 | case 15: /* Return Response Info */ | 2585 | case 15: /* Return Response Info */ |
2586 | default: /* Reserved */ | 2586 | default: /* Reserved */ |
2587 | break; | 2587 | break; |
2588 | } | 2588 | } |
2589 | 2589 | ||
2590 | return ATA_PROT_UNKNOWN; | 2590 | return ATA_PROT_UNKNOWN; |
@@ -2919,94 +2919,94 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, | |||
2919 | args.done = done; | 2919 | args.done = done; |
2920 | 2920 | ||
2921 | switch(scsicmd[0]) { | 2921 | switch(scsicmd[0]) { |
2922 | /* TODO: worth improving? */ | 2922 | /* TODO: worth improving? */ |
2923 | case FORMAT_UNIT: | 2923 | case FORMAT_UNIT: |
2924 | ata_scsi_invalid_field(cmd, done); | ||
2925 | break; | ||
2926 | |||
2927 | case INQUIRY: | ||
2928 | if (scsicmd[1] & 2) /* is CmdDt set? */ | ||
2924 | ata_scsi_invalid_field(cmd, done); | 2929 | ata_scsi_invalid_field(cmd, done); |
2930 | else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */ | ||
2931 | ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std); | ||
2932 | else switch (scsicmd[2]) { | ||
2933 | case 0x00: | ||
2934 | ata_scsi_rbuf_fill(&args, ata_scsiop_inq_00); | ||
2925 | break; | 2935 | break; |
2926 | 2936 | case 0x80: | |
2927 | case INQUIRY: | 2937 | ata_scsi_rbuf_fill(&args, ata_scsiop_inq_80); |
2928 | if (scsicmd[1] & 2) /* is CmdDt set? */ | ||
2929 | ata_scsi_invalid_field(cmd, done); | ||
2930 | else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */ | ||
2931 | ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std); | ||
2932 | else switch (scsicmd[2]) { | ||
2933 | case 0x00: | ||
2934 | ata_scsi_rbuf_fill(&args, ata_scsiop_inq_00); | ||
2935 | break; | ||
2936 | case 0x80: | ||
2937 | ata_scsi_rbuf_fill(&args, ata_scsiop_inq_80); | ||
2938 | break; | ||
2939 | case 0x83: | ||
2940 | ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83); | ||
2941 | break; | ||
2942 | case 0x89: | ||
2943 | ata_scsi_rbuf_fill(&args, ata_scsiop_inq_89); | ||
2944 | break; | ||
2945 | default: | ||
2946 | ata_scsi_invalid_field(cmd, done); | ||
2947 | break; | ||
2948 | } | ||
2949 | break; | 2938 | break; |
2950 | 2939 | case 0x83: | |
2951 | case MODE_SENSE: | 2940 | ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83); |
2952 | case MODE_SENSE_10: | ||
2953 | ata_scsi_rbuf_fill(&args, ata_scsiop_mode_sense); | ||
2954 | break; | 2941 | break; |
2955 | 2942 | case 0x89: | |
2956 | case MODE_SELECT: /* unconditionally return */ | 2943 | ata_scsi_rbuf_fill(&args, ata_scsiop_inq_89); |
2957 | case MODE_SELECT_10: /* bad-field-in-cdb */ | 2944 | break; |
2945 | default: | ||
2958 | ata_scsi_invalid_field(cmd, done); | 2946 | ata_scsi_invalid_field(cmd, done); |
2959 | break; | 2947 | break; |
2948 | } | ||
2949 | break; | ||
2950 | |||
2951 | case MODE_SENSE: | ||
2952 | case MODE_SENSE_10: | ||
2953 | ata_scsi_rbuf_fill(&args, ata_scsiop_mode_sense); | ||
2954 | break; | ||
2960 | 2955 | ||
2961 | case READ_CAPACITY: | 2956 | case MODE_SELECT: /* unconditionally return */ |
2957 | case MODE_SELECT_10: /* bad-field-in-cdb */ | ||
2958 | ata_scsi_invalid_field(cmd, done); | ||
2959 | break; | ||
2960 | |||
2961 | case READ_CAPACITY: | ||
2962 | ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); | ||
2963 | break; | ||
2964 | |||
2965 | case SERVICE_ACTION_IN: | ||
2966 | if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16) | ||
2962 | ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); | 2967 | ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); |
2963 | break; | 2968 | else |
2969 | ata_scsi_invalid_field(cmd, done); | ||
2970 | break; | ||
2964 | 2971 | ||
2965 | case SERVICE_ACTION_IN: | 2972 | case REPORT_LUNS: |
2966 | if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16) | 2973 | ata_scsi_rbuf_fill(&args, ata_scsiop_report_luns); |
2967 | ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); | 2974 | break; |
2968 | else | ||
2969 | ata_scsi_invalid_field(cmd, done); | ||
2970 | break; | ||
2971 | 2975 | ||
2972 | case REPORT_LUNS: | 2976 | case REQUEST_SENSE: |
2973 | ata_scsi_rbuf_fill(&args, ata_scsiop_report_luns); | 2977 | ata_scsi_set_sense(cmd, 0, 0, 0); |
2974 | break; | 2978 | cmd->result = (DRIVER_SENSE << 24); |
2979 | done(cmd); | ||
2980 | break; | ||
2975 | 2981 | ||
2976 | case REQUEST_SENSE: | 2982 | /* if we reach this, then writeback caching is disabled, |
2977 | ata_scsi_set_sense(cmd, 0, 0, 0); | 2983 | * turning this into a no-op. |
2978 | cmd->result = (DRIVER_SENSE << 24); | 2984 | */ |
2979 | done(cmd); | 2985 | case SYNCHRONIZE_CACHE: |
2980 | break; | 2986 | /* fall through */ |
2987 | |||
2988 | /* no-op's, complete with success */ | ||
2989 | case REZERO_UNIT: | ||
2990 | case SEEK_6: | ||
2991 | case SEEK_10: | ||
2992 | case TEST_UNIT_READY: | ||
2993 | ata_scsi_rbuf_fill(&args, ata_scsiop_noop); | ||
2994 | break; | ||
2981 | 2995 | ||
2982 | /* if we reach this, then writeback caching is disabled, | 2996 | case SEND_DIAGNOSTIC: |
2983 | * turning this into a no-op. | 2997 | tmp8 = scsicmd[1] & ~(1 << 3); |
2984 | */ | 2998 | if ((tmp8 == 0x4) && (!scsicmd[3]) && (!scsicmd[4])) |
2985 | case SYNCHRONIZE_CACHE: | ||
2986 | /* fall through */ | ||
2987 | |||
2988 | /* no-op's, complete with success */ | ||
2989 | case REZERO_UNIT: | ||
2990 | case SEEK_6: | ||
2991 | case SEEK_10: | ||
2992 | case TEST_UNIT_READY: | ||
2993 | ata_scsi_rbuf_fill(&args, ata_scsiop_noop); | 2999 | ata_scsi_rbuf_fill(&args, ata_scsiop_noop); |
2994 | break; | 3000 | else |
2995 | 3001 | ata_scsi_invalid_field(cmd, done); | |
2996 | case SEND_DIAGNOSTIC: | 3002 | break; |
2997 | tmp8 = scsicmd[1] & ~(1 << 3); | ||
2998 | if ((tmp8 == 0x4) && (!scsicmd[3]) && (!scsicmd[4])) | ||
2999 | ata_scsi_rbuf_fill(&args, ata_scsiop_noop); | ||
3000 | else | ||
3001 | ata_scsi_invalid_field(cmd, done); | ||
3002 | break; | ||
3003 | 3003 | ||
3004 | /* all other commands */ | 3004 | /* all other commands */ |
3005 | default: | 3005 | default: |
3006 | ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x20, 0x0); | 3006 | ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x20, 0x0); |
3007 | /* "Invalid command operation code" */ | 3007 | /* "Invalid command operation code" */ |
3008 | done(cmd); | 3008 | done(cmd); |
3009 | break; | 3009 | break; |
3010 | } | 3010 | } |
3011 | } | 3011 | } |
3012 | 3012 | ||
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 8227c45109ec..48acc09dab96 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -248,7 +248,7 @@ void ata_bmdma_setup(struct ata_queued_cmd *qc) | |||
248 | * LOCKING: | 248 | * LOCKING: |
249 | * spin_lock_irqsave(host lock) | 249 | * spin_lock_irqsave(host lock) |
250 | */ | 250 | */ |
251 | void ata_bmdma_start (struct ata_queued_cmd *qc) | 251 | void ata_bmdma_start(struct ata_queued_cmd *qc) |
252 | { | 252 | { |
253 | struct ata_port *ap = qc->ap; | 253 | struct ata_port *ap = qc->ap; |
254 | u8 dmactl; | 254 | u8 dmactl; |
diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c index bb97ef583f9b..b9a17eb100d0 100644 --- a/drivers/ata/pata_ns87415.c +++ b/drivers/ata/pata_ns87415.c | |||
@@ -17,7 +17,7 @@ | |||
17 | * TODO: | 17 | * TODO: |
18 | * Test PARISC SuperIO | 18 | * Test PARISC SuperIO |
19 | * Get someone to test on SPARC | 19 | * Get someone to test on SPARC |
20 | * Implement lazy pio/dma switching for better performance | 20 | * Implement lazy pio/dma switching for better performance |
21 | * 8bit shared timing. | 21 | * 8bit shared timing. |
22 | * See if we need to kill the FIFO for ATAPI | 22 | * See if we need to kill the FIFO for ATAPI |
23 | */ | 23 | */ |
@@ -60,10 +60,10 @@ static void ns87415_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo | |||
60 | u16 clocking; | 60 | u16 clocking; |
61 | u8 iordy; | 61 | u8 iordy; |
62 | u8 status; | 62 | u8 status; |
63 | 63 | ||
64 | /* Timing register format is 17 - low nybble read timing with | 64 | /* Timing register format is 17 - low nybble read timing with |
65 | the high nybble being 16 - x for recovery time in PCI clocks */ | 65 | the high nybble being 16 - x for recovery time in PCI clocks */ |
66 | 66 | ||
67 | ata_timing_compute(adev, adev->pio_mode, &t, T, 0); | 67 | ata_timing_compute(adev, adev->pio_mode, &t, T, 0); |
68 | 68 | ||
69 | clocking = 17 - FIT(t.active, 2, 17); | 69 | clocking = 17 - FIT(t.active, 2, 17); |
@@ -71,7 +71,7 @@ static void ns87415_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo | |||
71 | /* Use the same timing for read and write bytes */ | 71 | /* Use the same timing for read and write bytes */ |
72 | clocking |= (clocking << 8); | 72 | clocking |= (clocking << 8); |
73 | pci_write_config_word(dev, timing, clocking); | 73 | pci_write_config_word(dev, timing, clocking); |
74 | 74 | ||
75 | /* Set the IORDY enable versus DMA enable on or off properly */ | 75 | /* Set the IORDY enable versus DMA enable on or off properly */ |
76 | pci_read_config_byte(dev, 0x42, &iordy); | 76 | pci_read_config_byte(dev, 0x42, &iordy); |
77 | iordy &= ~(1 << (4 + unit)); | 77 | iordy &= ~(1 << (4 + unit)); |
@@ -185,7 +185,7 @@ static void ns87415_bmdma_irq_clear(struct ata_port *ap) | |||
185 | 185 | ||
186 | if (!mmio) | 186 | if (!mmio) |
187 | return; | 187 | return; |
188 | iowrite8((ioread8(mmio + ATA_DMA_CMD) | ATA_DMA_INTR | ATA_DMA_ERR), | 188 | iowrite8((ioread8(mmio + ATA_DMA_CMD) | ATA_DMA_INTR | ATA_DMA_ERR), |
189 | mmio + ATA_DMA_CMD); | 189 | mmio + ATA_DMA_CMD); |
190 | } | 190 | } |
191 | 191 | ||
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 7f1b13e89cf7..b39648f0914b 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -845,7 +845,7 @@ static int __mv_stop_dma(struct ata_port *ap) | |||
845 | pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; | 845 | pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; |
846 | } else { | 846 | } else { |
847 | WARN_ON(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS)); | 847 | WARN_ON(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS)); |
848 | } | 848 | } |
849 | 849 | ||
850 | /* now properly wait for the eDMA to stop */ | 850 | /* now properly wait for the eDMA to stop */ |
851 | for (i = 1000; i > 0; i--) { | 851 | for (i = 1000; i > 0; i--) { |
@@ -883,7 +883,7 @@ static void mv_dump_mem(void __iomem *start, unsigned bytes) | |||
883 | for (b = 0; b < bytes; ) { | 883 | for (b = 0; b < bytes; ) { |
884 | DPRINTK("%p: ", start + b); | 884 | DPRINTK("%p: ", start + b); |
885 | for (w = 0; b < bytes && w < 4; w++) { | 885 | for (w = 0; b < bytes && w < 4; w++) { |
886 | printk("%08x ",readl(start + b)); | 886 | printk("%08x ", readl(start + b)); |
887 | b += sizeof(u32); | 887 | b += sizeof(u32); |
888 | } | 888 | } |
889 | printk("\n"); | 889 | printk("\n"); |
@@ -899,8 +899,8 @@ static void mv_dump_pci_cfg(struct pci_dev *pdev, unsigned bytes) | |||
899 | for (b = 0; b < bytes; ) { | 899 | for (b = 0; b < bytes; ) { |
900 | DPRINTK("%02x: ", b); | 900 | DPRINTK("%02x: ", b); |
901 | for (w = 0; b < bytes && w < 4; w++) { | 901 | for (w = 0; b < bytes && w < 4; w++) { |
902 | (void) pci_read_config_dword(pdev,b,&dw); | 902 | (void) pci_read_config_dword(pdev, b, &dw); |
903 | printk("%08x ",dw); | 903 | printk("%08x ", dw); |
904 | b += sizeof(u32); | 904 | b += sizeof(u32); |
905 | } | 905 | } |
906 | printk("\n"); | 906 | printk("\n"); |
@@ -944,9 +944,9 @@ static void mv_dump_all_regs(void __iomem *mmio_base, int port, | |||
944 | } | 944 | } |
945 | for (p = start_port; p < start_port + num_ports; p++) { | 945 | for (p = start_port; p < start_port + num_ports; p++) { |
946 | port_base = mv_port_base(mmio_base, p); | 946 | port_base = mv_port_base(mmio_base, p); |
947 | DPRINTK("EDMA regs (port %i):\n",p); | 947 | DPRINTK("EDMA regs (port %i):\n", p); |
948 | mv_dump_mem(port_base, 0x54); | 948 | mv_dump_mem(port_base, 0x54); |
949 | DPRINTK("SATA regs (port %i):\n",p); | 949 | DPRINTK("SATA regs (port %i):\n", p); |
950 | mv_dump_mem(port_base+0x300, 0x60); | 950 | mv_dump_mem(port_base+0x300, 0x60); |
951 | } | 951 | } |
952 | #endif | 952 | #endif |
@@ -1184,7 +1184,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) | |||
1184 | u16 flags = 0; | 1184 | u16 flags = 0; |
1185 | unsigned in_index; | 1185 | unsigned in_index; |
1186 | 1186 | ||
1187 | if (qc->tf.protocol != ATA_PROT_DMA) | 1187 | if (qc->tf.protocol != ATA_PROT_DMA) |
1188 | return; | 1188 | return; |
1189 | 1189 | ||
1190 | /* Fill in command request block | 1190 | /* Fill in command request block |
@@ -1276,7 +1276,7 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) | |||
1276 | unsigned in_index; | 1276 | unsigned in_index; |
1277 | u32 flags = 0; | 1277 | u32 flags = 0; |
1278 | 1278 | ||
1279 | if (qc->tf.protocol != ATA_PROT_DMA) | 1279 | if (qc->tf.protocol != ATA_PROT_DMA) |
1280 | return; | 1280 | return; |
1281 | 1281 | ||
1282 | /* Fill in Gen IIE command request block | 1282 | /* Fill in Gen IIE command request block |
@@ -1606,7 +1606,7 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc) | |||
1606 | writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); | 1606 | writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); |
1607 | 1607 | ||
1608 | VPRINTK("ENTER, hc%u relevant=0x%08x HC IRQ cause=0x%08x\n", | 1608 | VPRINTK("ENTER, hc%u relevant=0x%08x HC IRQ cause=0x%08x\n", |
1609 | hc,relevant,hc_irq_cause); | 1609 | hc, relevant, hc_irq_cause); |
1610 | 1610 | ||
1611 | for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) { | 1611 | for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) { |
1612 | struct ata_port *ap = host->ports[port]; | 1612 | struct ata_port *ap = host->ports[port]; |
@@ -1983,9 +1983,8 @@ static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, | |||
1983 | for (i = 0; i < 1000; i++) { | 1983 | for (i = 0; i < 1000; i++) { |
1984 | udelay(1); | 1984 | udelay(1); |
1985 | t = readl(reg); | 1985 | t = readl(reg); |
1986 | if (PCI_MASTER_EMPTY & t) { | 1986 | if (PCI_MASTER_EMPTY & t) |
1987 | break; | 1987 | break; |
1988 | } | ||
1989 | } | 1988 | } |
1990 | if (!(PCI_MASTER_EMPTY & t)) { | 1989 | if (!(PCI_MASTER_EMPTY & t)) { |
1991 | printk(KERN_ERR DRV_NAME ": PCI master won't flush\n"); | 1990 | printk(KERN_ERR DRV_NAME ": PCI master won't flush\n"); |
@@ -2668,7 +2667,7 @@ static void mv_print_info(struct ata_host *host) | |||
2668 | */ | 2667 | */ |
2669 | static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 2668 | static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
2670 | { | 2669 | { |
2671 | static int printed_version = 0; | 2670 | static int printed_version; |
2672 | unsigned int board_idx = (unsigned int)ent->driver_data; | 2671 | unsigned int board_idx = (unsigned int)ent->driver_data; |
2673 | const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL }; | 2672 | const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL }; |
2674 | struct ata_host *host; | 2673 | struct ata_host *host; |
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 240a8920d0bd..2e0279fdd7aa 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -163,7 +163,7 @@ enum { | |||
163 | NV_ADMA_STAT_STOPPED = (1 << 10), | 163 | NV_ADMA_STAT_STOPPED = (1 << 10), |
164 | NV_ADMA_STAT_DONE = (1 << 12), | 164 | NV_ADMA_STAT_DONE = (1 << 12), |
165 | NV_ADMA_STAT_ERR = NV_ADMA_STAT_CPBERR | | 165 | NV_ADMA_STAT_ERR = NV_ADMA_STAT_CPBERR | |
166 | NV_ADMA_STAT_TIMEOUT, | 166 | NV_ADMA_STAT_TIMEOUT, |
167 | 167 | ||
168 | /* port flags */ | 168 | /* port flags */ |
169 | NV_ADMA_PORT_REGISTER_MODE = (1 << 0), | 169 | NV_ADMA_PORT_REGISTER_MODE = (1 << 0), |
@@ -228,7 +228,7 @@ struct nv_adma_cpb { | |||
228 | u8 reserved1; /* 1 */ | 228 | u8 reserved1; /* 1 */ |
229 | u8 ctl_flags; /* 2 */ | 229 | u8 ctl_flags; /* 2 */ |
230 | /* len is length of taskfile in 64 bit words */ | 230 | /* len is length of taskfile in 64 bit words */ |
231 | u8 len; /* 3 */ | 231 | u8 len; /* 3 */ |
232 | u8 tag; /* 4 */ | 232 | u8 tag; /* 4 */ |
233 | u8 next_cpb_idx; /* 5 */ | 233 | u8 next_cpb_idx; /* 5 */ |
234 | __le16 reserved2; /* 6-7 */ | 234 | __le16 reserved2; /* 6-7 */ |
@@ -244,9 +244,9 @@ struct nv_adma_port_priv { | |||
244 | dma_addr_t cpb_dma; | 244 | dma_addr_t cpb_dma; |
245 | struct nv_adma_prd *aprd; | 245 | struct nv_adma_prd *aprd; |
246 | dma_addr_t aprd_dma; | 246 | dma_addr_t aprd_dma; |
247 | void __iomem * ctl_block; | 247 | void __iomem *ctl_block; |
248 | void __iomem * gen_block; | 248 | void __iomem *gen_block; |
249 | void __iomem * notifier_clear_block; | 249 | void __iomem *notifier_clear_block; |
250 | u8 flags; | 250 | u8 flags; |
251 | int last_issue_ncq; | 251 | int last_issue_ncq; |
252 | }; | 252 | }; |
@@ -293,7 +293,7 @@ struct nv_swncq_port_priv { | |||
293 | 293 | ||
294 | #define NV_ADMA_CHECK_INTR(GCTL, PORT) ((GCTL) & ( 1 << (19 + (12 * (PORT))))) | 294 | #define NV_ADMA_CHECK_INTR(GCTL, PORT) ((GCTL) & ( 1 << (19 + (12 * (PORT))))) |
295 | 295 | ||
296 | static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 296 | static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); |
297 | #ifdef CONFIG_PM | 297 | #ifdef CONFIG_PM |
298 | static int nv_pci_device_resume(struct pci_dev *pdev); | 298 | static int nv_pci_device_resume(struct pci_dev *pdev); |
299 | #endif | 299 | #endif |
@@ -301,8 +301,8 @@ static void nv_ck804_host_stop(struct ata_host *host); | |||
301 | static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance); | 301 | static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance); |
302 | static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance); | 302 | static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance); |
303 | static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance); | 303 | static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance); |
304 | static int nv_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val); | 304 | static int nv_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); |
305 | static int nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 305 | static int nv_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); |
306 | 306 | ||
307 | static void nv_nf2_freeze(struct ata_port *ap); | 307 | static void nv_nf2_freeze(struct ata_port *ap); |
308 | static void nv_nf2_thaw(struct ata_port *ap); | 308 | static void nv_nf2_thaw(struct ata_port *ap); |
@@ -653,12 +653,12 @@ static void nv_adma_register_mode(struct ata_port *ap) | |||
653 | return; | 653 | return; |
654 | 654 | ||
655 | status = readw(mmio + NV_ADMA_STAT); | 655 | status = readw(mmio + NV_ADMA_STAT); |
656 | while(!(status & NV_ADMA_STAT_IDLE) && count < 20) { | 656 | while (!(status & NV_ADMA_STAT_IDLE) && count < 20) { |
657 | ndelay(50); | 657 | ndelay(50); |
658 | status = readw(mmio + NV_ADMA_STAT); | 658 | status = readw(mmio + NV_ADMA_STAT); |
659 | count++; | 659 | count++; |
660 | } | 660 | } |
661 | if(count == 20) | 661 | if (count == 20) |
662 | ata_port_printk(ap, KERN_WARNING, | 662 | ata_port_printk(ap, KERN_WARNING, |
663 | "timeout waiting for ADMA IDLE, stat=0x%hx\n", | 663 | "timeout waiting for ADMA IDLE, stat=0x%hx\n", |
664 | status); | 664 | status); |
@@ -668,12 +668,12 @@ static void nv_adma_register_mode(struct ata_port *ap) | |||
668 | 668 | ||
669 | count = 0; | 669 | count = 0; |
670 | status = readw(mmio + NV_ADMA_STAT); | 670 | status = readw(mmio + NV_ADMA_STAT); |
671 | while(!(status & NV_ADMA_STAT_LEGACY) && count < 20) { | 671 | while (!(status & NV_ADMA_STAT_LEGACY) && count < 20) { |
672 | ndelay(50); | 672 | ndelay(50); |
673 | status = readw(mmio + NV_ADMA_STAT); | 673 | status = readw(mmio + NV_ADMA_STAT); |
674 | count++; | 674 | count++; |
675 | } | 675 | } |
676 | if(count == 20) | 676 | if (count == 20) |
677 | ata_port_printk(ap, KERN_WARNING, | 677 | ata_port_printk(ap, KERN_WARNING, |
678 | "timeout waiting for ADMA LEGACY, stat=0x%hx\n", | 678 | "timeout waiting for ADMA LEGACY, stat=0x%hx\n", |
679 | status); | 679 | status); |
@@ -697,13 +697,13 @@ static void nv_adma_mode(struct ata_port *ap) | |||
697 | writew(tmp | NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL); | 697 | writew(tmp | NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL); |
698 | 698 | ||
699 | status = readw(mmio + NV_ADMA_STAT); | 699 | status = readw(mmio + NV_ADMA_STAT); |
700 | while(((status & NV_ADMA_STAT_LEGACY) || | 700 | while (((status & NV_ADMA_STAT_LEGACY) || |
701 | !(status & NV_ADMA_STAT_IDLE)) && count < 20) { | 701 | !(status & NV_ADMA_STAT_IDLE)) && count < 20) { |
702 | ndelay(50); | 702 | ndelay(50); |
703 | status = readw(mmio + NV_ADMA_STAT); | 703 | status = readw(mmio + NV_ADMA_STAT); |
704 | count++; | 704 | count++; |
705 | } | 705 | } |
706 | if(count == 20) | 706 | if (count == 20) |
707 | ata_port_printk(ap, KERN_WARNING, | 707 | ata_port_printk(ap, KERN_WARNING, |
708 | "timeout waiting for ADMA LEGACY clear and IDLE, stat=0x%hx\n", | 708 | "timeout waiting for ADMA LEGACY clear and IDLE, stat=0x%hx\n", |
709 | status); | 709 | status); |
@@ -747,8 +747,7 @@ static int nv_adma_slave_config(struct scsi_device *sdev) | |||
747 | on the port. */ | 747 | on the port. */ |
748 | adma_enable = 0; | 748 | adma_enable = 0; |
749 | nv_adma_register_mode(ap); | 749 | nv_adma_register_mode(ap); |
750 | } | 750 | } else { |
751 | else { | ||
752 | bounce_limit = *ap->dev->dma_mask; | 751 | bounce_limit = *ap->dev->dma_mask; |
753 | segment_boundary = NV_ADMA_DMA_BOUNDARY; | 752 | segment_boundary = NV_ADMA_DMA_BOUNDARY; |
754 | sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN; | 753 | sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN; |
@@ -757,23 +756,22 @@ static int nv_adma_slave_config(struct scsi_device *sdev) | |||
757 | 756 | ||
758 | pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, ¤t_reg); | 757 | pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, ¤t_reg); |
759 | 758 | ||
760 | if(ap->port_no == 1) | 759 | if (ap->port_no == 1) |
761 | config_mask = NV_MCP_SATA_CFG_20_PORT1_EN | | 760 | config_mask = NV_MCP_SATA_CFG_20_PORT1_EN | |
762 | NV_MCP_SATA_CFG_20_PORT1_PWB_EN; | 761 | NV_MCP_SATA_CFG_20_PORT1_PWB_EN; |
763 | else | 762 | else |
764 | config_mask = NV_MCP_SATA_CFG_20_PORT0_EN | | 763 | config_mask = NV_MCP_SATA_CFG_20_PORT0_EN | |
765 | NV_MCP_SATA_CFG_20_PORT0_PWB_EN; | 764 | NV_MCP_SATA_CFG_20_PORT0_PWB_EN; |
766 | 765 | ||
767 | if(adma_enable) { | 766 | if (adma_enable) { |
768 | new_reg = current_reg | config_mask; | 767 | new_reg = current_reg | config_mask; |
769 | pp->flags &= ~NV_ADMA_ATAPI_SETUP_COMPLETE; | 768 | pp->flags &= ~NV_ADMA_ATAPI_SETUP_COMPLETE; |
770 | } | 769 | } else { |
771 | else { | ||
772 | new_reg = current_reg & ~config_mask; | 770 | new_reg = current_reg & ~config_mask; |
773 | pp->flags |= NV_ADMA_ATAPI_SETUP_COMPLETE; | 771 | pp->flags |= NV_ADMA_ATAPI_SETUP_COMPLETE; |
774 | } | 772 | } |
775 | 773 | ||
776 | if(current_reg != new_reg) | 774 | if (current_reg != new_reg) |
777 | pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, new_reg); | 775 | pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, new_reg); |
778 | 776 | ||
779 | blk_queue_bounce_limit(sdev->request_queue, bounce_limit); | 777 | blk_queue_bounce_limit(sdev->request_queue, bounce_limit); |
@@ -807,7 +805,7 @@ static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb) | |||
807 | { | 805 | { |
808 | unsigned int idx = 0; | 806 | unsigned int idx = 0; |
809 | 807 | ||
810 | if(tf->flags & ATA_TFLAG_ISADDR) { | 808 | if (tf->flags & ATA_TFLAG_ISADDR) { |
811 | if (tf->flags & ATA_TFLAG_LBA48) { | 809 | if (tf->flags & ATA_TFLAG_LBA48) { |
812 | cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->hob_feature | WNB); | 810 | cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->hob_feature | WNB); |
813 | cpb[idx++] = cpu_to_le16((ATA_REG_NSECT << 8) | tf->hob_nsect); | 811 | cpb[idx++] = cpu_to_le16((ATA_REG_NSECT << 8) | tf->hob_nsect); |
@@ -824,12 +822,12 @@ static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb) | |||
824 | cpb[idx++] = cpu_to_le16((ATA_REG_LBAH << 8) | tf->lbah); | 822 | cpb[idx++] = cpu_to_le16((ATA_REG_LBAH << 8) | tf->lbah); |
825 | } | 823 | } |
826 | 824 | ||
827 | if(tf->flags & ATA_TFLAG_DEVICE) | 825 | if (tf->flags & ATA_TFLAG_DEVICE) |
828 | cpb[idx++] = cpu_to_le16((ATA_REG_DEVICE << 8) | tf->device); | 826 | cpb[idx++] = cpu_to_le16((ATA_REG_DEVICE << 8) | tf->device); |
829 | 827 | ||
830 | cpb[idx++] = cpu_to_le16((ATA_REG_CMD << 8) | tf->command | CMDEND); | 828 | cpb[idx++] = cpu_to_le16((ATA_REG_CMD << 8) | tf->command | CMDEND); |
831 | 829 | ||
832 | while(idx < 12) | 830 | while (idx < 12) |
833 | cpb[idx++] = cpu_to_le16(IGN); | 831 | cpb[idx++] = cpu_to_le16(IGN); |
834 | 832 | ||
835 | return idx; | 833 | return idx; |
@@ -850,7 +848,7 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err) | |||
850 | int freeze = 0; | 848 | int freeze = 0; |
851 | 849 | ||
852 | ata_ehi_clear_desc(ehi); | 850 | ata_ehi_clear_desc(ehi); |
853 | __ata_ehi_push_desc(ehi, "CPB resp_flags 0x%x: ", flags ); | 851 | __ata_ehi_push_desc(ehi, "CPB resp_flags 0x%x: ", flags); |
854 | if (flags & NV_CPB_RESP_ATA_ERR) { | 852 | if (flags & NV_CPB_RESP_ATA_ERR) { |
855 | ata_ehi_push_desc(ehi, "ATA error"); | 853 | ata_ehi_push_desc(ehi, "ATA error"); |
856 | ehi->err_mask |= AC_ERR_DEV; | 854 | ehi->err_mask |= AC_ERR_DEV; |
@@ -879,7 +877,7 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err) | |||
879 | struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num); | 877 | struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num); |
880 | VPRINTK("CPB flags done, flags=0x%x\n", flags); | 878 | VPRINTK("CPB flags done, flags=0x%x\n", flags); |
881 | if (likely(qc)) { | 879 | if (likely(qc)) { |
882 | DPRINTK("Completing qc from tag %d\n",cpb_num); | 880 | DPRINTK("Completing qc from tag %d\n", cpb_num); |
883 | ata_qc_complete(qc); | 881 | ata_qc_complete(qc); |
884 | } else { | 882 | } else { |
885 | struct ata_eh_info *ehi = &ap->link.eh_info; | 883 | struct ata_eh_info *ehi = &ap->link.eh_info; |
@@ -952,7 +950,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) | |||
952 | if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) { | 950 | if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) { |
953 | u8 irq_stat = readb(host->iomap[NV_MMIO_BAR] + NV_INT_STATUS_CK804) | 951 | u8 irq_stat = readb(host->iomap[NV_MMIO_BAR] + NV_INT_STATUS_CK804) |
954 | >> (NV_INT_PORT_SHIFT * i); | 952 | >> (NV_INT_PORT_SHIFT * i); |
955 | if(ata_tag_valid(ap->link.active_tag)) | 953 | if (ata_tag_valid(ap->link.active_tag)) |
956 | /** NV_INT_DEV indication seems unreliable at times | 954 | /** NV_INT_DEV indication seems unreliable at times |
957 | at least in ADMA mode. Force it on always when a | 955 | at least in ADMA mode. Force it on always when a |
958 | command is active, to prevent losing interrupts. */ | 956 | command is active, to prevent losing interrupts. */ |
@@ -966,7 +964,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) | |||
966 | 964 | ||
967 | gen_ctl = readl(pp->gen_block + NV_ADMA_GEN_CTL); | 965 | gen_ctl = readl(pp->gen_block + NV_ADMA_GEN_CTL); |
968 | 966 | ||
969 | if( !NV_ADMA_CHECK_INTR(gen_ctl, ap->port_no) && !notifier && | 967 | if (!NV_ADMA_CHECK_INTR(gen_ctl, ap->port_no) && !notifier && |
970 | !notifier_error) | 968 | !notifier_error) |
971 | /* Nothing to do */ | 969 | /* Nothing to do */ |
972 | continue; | 970 | continue; |
@@ -990,7 +988,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) | |||
990 | struct ata_eh_info *ehi = &ap->link.eh_info; | 988 | struct ata_eh_info *ehi = &ap->link.eh_info; |
991 | 989 | ||
992 | ata_ehi_clear_desc(ehi); | 990 | ata_ehi_clear_desc(ehi); |
993 | __ata_ehi_push_desc(ehi, "ADMA status 0x%08x: ", status ); | 991 | __ata_ehi_push_desc(ehi, "ADMA status 0x%08x: ", status); |
994 | if (status & NV_ADMA_STAT_TIMEOUT) { | 992 | if (status & NV_ADMA_STAT_TIMEOUT) { |
995 | ehi->err_mask |= AC_ERR_SYSTEM; | 993 | ehi->err_mask |= AC_ERR_SYSTEM; |
996 | ata_ehi_push_desc(ehi, "timeout"); | 994 | ata_ehi_push_desc(ehi, "timeout"); |
@@ -1056,14 +1054,14 @@ static void nv_adma_freeze(struct ata_port *ap) | |||
1056 | return; | 1054 | return; |
1057 | 1055 | ||
1058 | /* clear any outstanding CK804 notifications */ | 1056 | /* clear any outstanding CK804 notifications */ |
1059 | writeb( NV_INT_ALL << (ap->port_no * NV_INT_PORT_SHIFT), | 1057 | writeb(NV_INT_ALL << (ap->port_no * NV_INT_PORT_SHIFT), |
1060 | ap->host->iomap[NV_MMIO_BAR] + NV_INT_STATUS_CK804); | 1058 | ap->host->iomap[NV_MMIO_BAR] + NV_INT_STATUS_CK804); |
1061 | 1059 | ||
1062 | /* Disable interrupt */ | 1060 | /* Disable interrupt */ |
1063 | tmp = readw(mmio + NV_ADMA_CTL); | 1061 | tmp = readw(mmio + NV_ADMA_CTL); |
1064 | writew( tmp & ~(NV_ADMA_CTL_AIEN | NV_ADMA_CTL_HOTPLUG_IEN), | 1062 | writew(tmp & ~(NV_ADMA_CTL_AIEN | NV_ADMA_CTL_HOTPLUG_IEN), |
1065 | mmio + NV_ADMA_CTL); | 1063 | mmio + NV_ADMA_CTL); |
1066 | readw( mmio + NV_ADMA_CTL ); /* flush posted write */ | 1064 | readw(mmio + NV_ADMA_CTL ); /* flush posted write */ |
1067 | } | 1065 | } |
1068 | 1066 | ||
1069 | static void nv_adma_thaw(struct ata_port *ap) | 1067 | static void nv_adma_thaw(struct ata_port *ap) |
@@ -1079,9 +1077,9 @@ static void nv_adma_thaw(struct ata_port *ap) | |||
1079 | 1077 | ||
1080 | /* Enable interrupt */ | 1078 | /* Enable interrupt */ |
1081 | tmp = readw(mmio + NV_ADMA_CTL); | 1079 | tmp = readw(mmio + NV_ADMA_CTL); |
1082 | writew( tmp | (NV_ADMA_CTL_AIEN | NV_ADMA_CTL_HOTPLUG_IEN), | 1080 | writew(tmp | (NV_ADMA_CTL_AIEN | NV_ADMA_CTL_HOTPLUG_IEN), |
1083 | mmio + NV_ADMA_CTL); | 1081 | mmio + NV_ADMA_CTL); |
1084 | readw( mmio + NV_ADMA_CTL ); /* flush posted write */ | 1082 | readw(mmio + NV_ADMA_CTL ); /* flush posted write */ |
1085 | } | 1083 | } |
1086 | 1084 | ||
1087 | static void nv_adma_irq_clear(struct ata_port *ap) | 1085 | static void nv_adma_irq_clear(struct ata_port *ap) |
@@ -1096,7 +1094,7 @@ static void nv_adma_irq_clear(struct ata_port *ap) | |||
1096 | } | 1094 | } |
1097 | 1095 | ||
1098 | /* clear any outstanding CK804 notifications */ | 1096 | /* clear any outstanding CK804 notifications */ |
1099 | writeb( NV_INT_ALL << (ap->port_no * NV_INT_PORT_SHIFT), | 1097 | writeb(NV_INT_ALL << (ap->port_no * NV_INT_PORT_SHIFT), |
1100 | ap->host->iomap[NV_MMIO_BAR] + NV_INT_STATUS_CK804); | 1098 | ap->host->iomap[NV_MMIO_BAR] + NV_INT_STATUS_CK804); |
1101 | 1099 | ||
1102 | /* clear ADMA status */ | 1100 | /* clear ADMA status */ |
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index 9f9f7b30654a..b6026bceccd1 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c | |||
@@ -62,13 +62,13 @@ | |||
62 | submit ATA packet to hardware | 62 | submit ATA packet to hardware |
63 | hardware executes ATA WRITE command, w/ data in DIMM | 63 | hardware executes ATA WRITE command, w/ data in DIMM |
64 | hardware raises interrupt | 64 | hardware raises interrupt |
65 | 65 | ||
66 | and each READ looks like this: | 66 | and each READ looks like this: |
67 | 67 | ||
68 | submit ATA packet to hardware | 68 | submit ATA packet to hardware |
69 | hardware executes ATA READ command, w/ data in DIMM | 69 | hardware executes ATA READ command, w/ data in DIMM |
70 | hardware raises interrupt | 70 | hardware raises interrupt |
71 | 71 | ||
72 | submit HDMA packet to hardware | 72 | submit HDMA packet to hardware |
73 | hardware copies data from DIMM to system memory | 73 | hardware copies data from DIMM to system memory |
74 | hardware raises interrupt | 74 | hardware raises interrupt |
diff --git a/drivers/fc4/Kconfig b/drivers/fc4/Kconfig deleted file mode 100644 index 345dbe6f10df..000000000000 --- a/drivers/fc4/Kconfig +++ /dev/null | |||
@@ -1,81 +0,0 @@ | |||
1 | # | ||
2 | # FC4 device configuration | ||
3 | # | ||
4 | |||
5 | menu "Fibre Channel support" | ||
6 | |||
7 | config FC4 | ||
8 | tristate "Fibre Channel and FC4 SCSI support" | ||
9 | ---help--- | ||
10 | Fibre Channel is a high speed serial protocol mainly used to | ||
11 | connect large storage devices to the computer; it is compatible with | ||
12 | and intended to replace SCSI. | ||
13 | |||
14 | This is an experimental support for storage arrays connected to your | ||
15 | computer using optical fibre cables and the "X3.269-199X Fibre | ||
16 | Channel Protocol for SCSI" specification. If you want to use this, | ||
17 | you need to say Y here and to "SCSI support" as well as to the | ||
18 | drivers for the storage array itself and for the interface adapter | ||
19 | such as SOC or SOC+. This subsystem could even serve for IP | ||
20 | networking, with some code extensions. | ||
21 | |||
22 | If unsure, say N. | ||
23 | |||
24 | comment "FC4 drivers" | ||
25 | depends on FC4 | ||
26 | |||
27 | config FC4_SOC | ||
28 | tristate "Sun SOC/Sbus" | ||
29 | depends on FC4!=n && SPARC | ||
30 | help | ||
31 | Serial Optical Channel is an interface card with one or two Fibre | ||
32 | Optic ports, each of which can be connected to a disk array. Note | ||
33 | that if you have older firmware in the card, you'll need the | ||
34 | microcode from the Solaris driver to make it work. | ||
35 | |||
36 | To compile this support as a module, choose M here: the module will | ||
37 | be called soc. | ||
38 | |||
39 | config FC4_SOCAL | ||
40 | tristate "Sun SOC+ (aka SOCAL)" | ||
41 | depends on FC4!=n && SPARC | ||
42 | ---help--- | ||
43 | Serial Optical Channel Plus is an interface card with up to two | ||
44 | Fibre Optic ports. This card supports FC Arbitrated Loop (usually | ||
45 | A5000 or internal FC disks in E[3-6]000 machines through the | ||
46 | Interface Board). You'll probably need the microcode from the | ||
47 | Solaris driver to make it work. | ||
48 | |||
49 | To compile this support as a module, choose M here: the module will | ||
50 | be called socal. | ||
51 | |||
52 | comment "FC4 targets" | ||
53 | depends on FC4 | ||
54 | |||
55 | config SCSI_PLUTO | ||
56 | tristate "SparcSTORAGE Array 100 and 200 series" | ||
57 | depends on FC4!=n && SCSI | ||
58 | help | ||
59 | If you never bought a disk array made by Sun, go with N. | ||
60 | |||
61 | To compile this support as a module, choose M here: the module will | ||
62 | be called pluto. | ||
63 | |||
64 | config SCSI_FCAL | ||
65 | tristate "Sun Enterprise Network Array (A5000 and EX500)" if SPARC | ||
66 | depends on FC4!=n && SCSI | ||
67 | help | ||
68 | This driver drives FC-AL disks connected through a Fibre Channel | ||
69 | card using the drivers/fc4 layer (currently only SOCAL). The most | ||
70 | common is either A5000 array or internal disks in E[3-6]000 | ||
71 | machines. | ||
72 | |||
73 | To compile this support as a module, choose M here: the module will | ||
74 | be called fcal. | ||
75 | |||
76 | config SCSI_FCAL | ||
77 | prompt "Generic FC-AL disk driver" | ||
78 | depends on FC4!=n && SCSI && !SPARC | ||
79 | |||
80 | endmenu | ||
81 | |||
diff --git a/drivers/fc4/Makefile b/drivers/fc4/Makefile deleted file mode 100644 index 0db3fbb553e9..000000000000 --- a/drivers/fc4/Makefile +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for the Linux Fibre Channel device drivers. | ||
3 | # | ||
4 | |||
5 | fc4-objs := fc.o fc_syms.o | ||
6 | |||
7 | obj-$(CONFIG_FC4) += fc4.o | ||
8 | obj-$(CONFIG_FC4_SOC) += soc.o | ||
9 | obj-$(CONFIG_FC4_SOCAL) += socal.o | ||
diff --git a/drivers/fc4/fc-al.h b/drivers/fc4/fc-al.h deleted file mode 100644 index 62d3ca436d72..000000000000 --- a/drivers/fc4/fc-al.h +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | /* fc-al.h: Definitions for Fibre Channel Arbitrated Loop topology. | ||
2 | * | ||
3 | * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
4 | * | ||
5 | * Sources: | ||
6 | * Fibre Channel Arbitrated Loop (FC-AL), ANSI, Rev. 4.5, 1995 | ||
7 | */ | ||
8 | |||
9 | #ifndef __FC_AL_H | ||
10 | #define __FC_AL_H | ||
11 | |||
12 | /* Loop initialization payloads */ | ||
13 | #define FC_AL_LISM 0x11010000 /* Select Master, 12B payload */ | ||
14 | #define FC_AL_LIFA 0x11020000 /* Fabric Assign AL_PA bitmap, 20B payload */ | ||
15 | #define FC_AL_LIPA 0x11030000 /* Previously Acquired AL_PA bitmap, 20B payload */ | ||
16 | #define FC_AL_LIHA 0x11040000 /* Hard Assigned AL_PA bitmap, 20B payload */ | ||
17 | #define FC_AL_LISA 0x11050000 /* Soft Assigned AL_PA bitmap, 20B payload */ | ||
18 | #define FC_AL_LIRP 0x11060000 /* Report AL_PA position map, 132B payload */ | ||
19 | #define FC_AL_LILP 0x11070000 /* Loop AL_PA position map, 132B payload */ | ||
20 | |||
21 | typedef struct { | ||
22 | u32 magic; | ||
23 | u8 len; | ||
24 | u8 alpa[127]; | ||
25 | } fc_al_posmap; | ||
26 | |||
27 | #endif /* !(__FC_H) */ | ||
diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c deleted file mode 100644 index 82de9e1adb1e..000000000000 --- a/drivers/fc4/fc.c +++ /dev/null | |||
@@ -1,1146 +0,0 @@ | |||
1 | /* fc.c: Generic Fibre Channel and FC4 SCSI driver. | ||
2 | * | ||
3 | * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz) | ||
4 | * Copyright (C) 1997,1998 Jirka Hanika (geo@ff.cuni.cz) | ||
5 | * | ||
6 | * There are two kinds of Fibre Channel adapters used in Linux. Either | ||
7 | * the adapter is "smart" and does all FC bookkeeping by itself and | ||
8 | * just presents a standard SCSI interface to the operating system | ||
9 | * (that's e.g. the case with Qlogic FC cards), or leaves most of the FC | ||
10 | * bookkeeping to the OS (e.g. soc, socal). Drivers for the former adapters | ||
11 | * will look like normal SCSI drivers (with the exception of max_id will be | ||
12 | * usually 127), the latter on the other side allows SCSI, IP over FC and other | ||
13 | * protocols. This driver tree is for the latter adapters. | ||
14 | * | ||
15 | * This file should support both Point-to-Point and Arbitrated Loop topologies. | ||
16 | * | ||
17 | * Sources: | ||
18 | * Fibre Channel Physical & Signaling Interface (FC-PH), dpANS, 1994 | ||
19 | * dpANS Fibre Channel Protocol for SCSI (X3.269-199X), Rev. 012, 1995 | ||
20 | * Fibre Channel Arbitrated Loop (FC-AL), Rev. 4.5, 1995 | ||
21 | * Fibre Channel Private Loop SCSI Direct Attach (FC-PLDA), Rev. 2.1, 1997 | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/jiffies.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/fcntl.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/ptrace.h> | ||
31 | #include <linux/ioport.h> | ||
32 | #include <linux/in.h> | ||
33 | #include <linux/slab.h> | ||
34 | #include <linux/string.h> | ||
35 | #include <linux/init.h> | ||
36 | |||
37 | #include <asm/pgtable.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/semaphore.h> | ||
40 | #include "fcp_impl.h" | ||
41 | #include <scsi/scsi_host.h> | ||
42 | |||
43 | /* #define FCDEBUG */ | ||
44 | |||
45 | #define fc_printk printk ("%s: ", fc->name); printk | ||
46 | |||
47 | #ifdef FCDEBUG | ||
48 | #define FCD(x) fc_printk x; | ||
49 | #define FCND(x) printk ("FC: "); printk x; | ||
50 | #else | ||
51 | #define FCD(x) | ||
52 | #define FCND(x) | ||
53 | #endif | ||
54 | |||
55 | #ifdef __sparc__ | ||
56 | #define dma_alloc_consistent(d,s,p) sbus_alloc_consistent(d,s,p) | ||
57 | #define dma_free_consistent(d,s,v,h) sbus_free_consistent(d,s,v,h) | ||
58 | #define dma_map_single(d,v,s,dir) sbus_map_single(d,v,s,dir) | ||
59 | #define dma_unmap_single(d,h,s,dir) sbus_unmap_single(d,h,s,dir) | ||
60 | #define dma_map_sg(d,s,n,dir) sbus_map_sg(d,s,n,dir) | ||
61 | #define dma_unmap_sg(d,s,n,dir) sbus_unmap_sg(d,s,n,dir) | ||
62 | #else | ||
63 | #define dma_alloc_consistent(d,s,p) pci_alloc_consistent(d,s,p) | ||
64 | #define dma_free_consistent(d,s,v,h) pci_free_consistent(d,s,v,h) | ||
65 | #define dma_map_single(d,v,s,dir) pci_map_single(d,v,s,dir) | ||
66 | #define dma_unmap_single(d,h,s,dir) pci_unmap_single(d,h,s,dir) | ||
67 | #define dma_map_sg(d,s,n,dir) pci_map_sg(d,s,n,dir) | ||
68 | #define dma_unmap_sg(d,s,n,dir) pci_unmap_sg(d,s,n,dir) | ||
69 | #endif | ||
70 | |||
71 | #define FCP_CMND(SCpnt) ((fcp_cmnd *)&(SCpnt->SCp)) | ||
72 | #define FC_SCMND(SCpnt) ((fc_channel *)(SCpnt->device->host->hostdata[0])) | ||
73 | #define SC_FCMND(fcmnd) ((struct scsi_cmnd *)((long)fcmnd - (long)&(((struct scsi_cmnd *)0)->SCp))) | ||
74 | |||
75 | static int fcp_scsi_queue_it(fc_channel *, struct scsi_cmnd *, fcp_cmnd *, int); | ||
76 | void fcp_queue_empty(fc_channel *); | ||
77 | |||
78 | static void fcp_scsi_insert_queue (fc_channel *fc, fcp_cmnd *fcmd) | ||
79 | { | ||
80 | if (!fc->scsi_que) { | ||
81 | fc->scsi_que = fcmd; | ||
82 | fcmd->next = fcmd; | ||
83 | fcmd->prev = fcmd; | ||
84 | } else { | ||
85 | fc->scsi_que->prev->next = fcmd; | ||
86 | fcmd->prev = fc->scsi_que->prev; | ||
87 | fc->scsi_que->prev = fcmd; | ||
88 | fcmd->next = fc->scsi_que; | ||
89 | } | ||
90 | } | ||
91 | |||
92 | static void fcp_scsi_remove_queue (fc_channel *fc, fcp_cmnd *fcmd) | ||
93 | { | ||
94 | if (fcmd == fcmd->next) { | ||
95 | fc->scsi_que = NULL; | ||
96 | return; | ||
97 | } | ||
98 | if (fcmd == fc->scsi_que) | ||
99 | fc->scsi_que = fcmd->next; | ||
100 | fcmd->prev->next = fcmd->next; | ||
101 | fcmd->next->prev = fcmd->prev; | ||
102 | } | ||
103 | |||
104 | fc_channel *fc_channels = NULL; | ||
105 | |||
106 | #define LSMAGIC 620829043 | ||
107 | typedef struct { | ||
108 | /* Must be first */ | ||
109 | struct semaphore sem; | ||
110 | int magic; | ||
111 | int count; | ||
112 | logi *logi; | ||
113 | fcp_cmnd *fcmds; | ||
114 | atomic_t todo; | ||
115 | struct timer_list timer; | ||
116 | unsigned char grace[0]; | ||
117 | } ls; | ||
118 | |||
119 | #define LSOMAGIC 654907799 | ||
120 | typedef struct { | ||
121 | /* Must be first */ | ||
122 | struct semaphore sem; | ||
123 | int magic; | ||
124 | int count; | ||
125 | fcp_cmnd *fcmds; | ||
126 | atomic_t todo; | ||
127 | struct timer_list timer; | ||
128 | } lso; | ||
129 | |||
130 | #define LSEMAGIC 84482456 | ||
131 | typedef struct { | ||
132 | /* Must be first */ | ||
133 | struct semaphore sem; | ||
134 | int magic; | ||
135 | int status; | ||
136 | struct timer_list timer; | ||
137 | } lse; | ||
138 | |||
139 | static void fcp_login_timeout(unsigned long data) | ||
140 | { | ||
141 | ls *l = (ls *)data; | ||
142 | FCND(("Login timeout\n")) | ||
143 | up(&l->sem); | ||
144 | } | ||
145 | |||
146 | static void fcp_login_done(fc_channel *fc, int i, int status) | ||
147 | { | ||
148 | fcp_cmnd *fcmd; | ||
149 | logi *plogi; | ||
150 | fc_hdr *fch; | ||
151 | ls *l = (ls *)fc->ls; | ||
152 | |||
153 | FCD(("Login done %d %d\n", i, status)) | ||
154 | if (i < l->count) { | ||
155 | if (fc->state == FC_STATE_FPORT_OK) { | ||
156 | FCD(("Additional FPORT_OK received with status %d\n", status)) | ||
157 | return; | ||
158 | } | ||
159 | switch (status) { | ||
160 | case FC_STATUS_OK: /* Oh, we found a fabric */ | ||
161 | case FC_STATUS_P_RJT: /* Oh, we haven't found any */ | ||
162 | fc->state = FC_STATE_FPORT_OK; | ||
163 | fcmd = l->fcmds + i; | ||
164 | plogi = l->logi + 3 * i; | ||
165 | dma_unmap_single (fc->dev, fcmd->cmd, 3 * sizeof(logi), | ||
166 | DMA_BIDIRECTIONAL); | ||
167 | plogi->code = LS_PLOGI; | ||
168 | memcpy (&plogi->nport_wwn, &fc->wwn_nport, sizeof(fc_wwn)); | ||
169 | memcpy (&plogi->node_wwn, &fc->wwn_node, sizeof(fc_wwn)); | ||
170 | memcpy (&plogi->common, fc->common_svc, sizeof(common_svc_parm)); | ||
171 | memcpy (&plogi->class1, fc->class_svcs, 3*sizeof(svc_parm)); | ||
172 | fch = &fcmd->fch; | ||
173 | fcmd->token += l->count; | ||
174 | FILL_FCHDR_RCTL_DID(fch, R_CTL_ELS_REQ, fc->did); | ||
175 | FILL_FCHDR_SID(fch, fc->sid); | ||
176 | #ifdef FCDEBUG | ||
177 | { | ||
178 | int i; | ||
179 | unsigned *x = (unsigned *)plogi; | ||
180 | printk ("logi: "); | ||
181 | for (i = 0; i < 21; i++) | ||
182 | printk ("%08x ", x[i]); | ||
183 | printk ("\n"); | ||
184 | } | ||
185 | #endif | ||
186 | fcmd->cmd = dma_map_single (fc->dev, plogi, 3 * sizeof(logi), | ||
187 | DMA_BIDIRECTIONAL); | ||
188 | fcmd->rsp = fcmd->cmd + 2 * sizeof(logi); | ||
189 | if (fc->hw_enque (fc, fcmd)) | ||
190 | printk ("FC: Cannot enque PLOGI packet on %s\n", fc->name); | ||
191 | break; | ||
192 | case FC_STATUS_ERR_OFFLINE: | ||
193 | fc->state = FC_STATE_MAYBEOFFLINE; | ||
194 | FCD (("FC is offline %d\n", l->grace[i])) | ||
195 | break; | ||
196 | default: | ||
197 | printk ("FLOGI failed for %s with status %d\n", fc->name, status); | ||
198 | /* Do some sort of error recovery here */ | ||
199 | break; | ||
200 | } | ||
201 | } else { | ||
202 | i -= l->count; | ||
203 | if (fc->state != FC_STATE_FPORT_OK) { | ||
204 | FCD(("Unexpected N-PORT rsp received")) | ||
205 | return; | ||
206 | } | ||
207 | switch (status) { | ||
208 | case FC_STATUS_OK: | ||
209 | plogi = l->logi + 3 * i; | ||
210 | dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi), | ||
211 | DMA_BIDIRECTIONAL); | ||
212 | if (!fc->wwn_dest.lo && !fc->wwn_dest.hi) { | ||
213 | memcpy (&fc->wwn_dest, &plogi[1].node_wwn, sizeof(fc_wwn)); | ||
214 | FCD(("Dest WWN %08x%08x\n", *(u32 *)&fc->wwn_dest, fc->wwn_dest.lo)) | ||
215 | } else if (fc->wwn_dest.lo != plogi[1].node_wwn.lo || | ||
216 | fc->wwn_dest.hi != plogi[1].node_wwn.hi) { | ||
217 | printk ("%s: mismatch in wwns. Got %08x%08x, expected %08x%08x\n", | ||
218 | fc->name, | ||
219 | *(u32 *)&plogi[1].node_wwn, plogi[1].node_wwn.lo, | ||
220 | *(u32 *)&fc->wwn_dest, fc->wwn_dest.lo); | ||
221 | } | ||
222 | fc->state = FC_STATE_ONLINE; | ||
223 | printk ("%s: ONLINE\n", fc->name); | ||
224 | if (atomic_dec_and_test (&l->todo)) | ||
225 | up(&l->sem); | ||
226 | break; | ||
227 | case FC_STATUS_ERR_OFFLINE: | ||
228 | fc->state = FC_STATE_OFFLINE; | ||
229 | dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi), | ||
230 | DMA_BIDIRECTIONAL); | ||
231 | printk ("%s: FC is offline\n", fc->name); | ||
232 | if (atomic_dec_and_test (&l->todo)) | ||
233 | up(&l->sem); | ||
234 | break; | ||
235 | default: | ||
236 | printk ("PLOGI failed for %s with status %d\n", fc->name, status); | ||
237 | /* Do some sort of error recovery here */ | ||
238 | break; | ||
239 | } | ||
240 | } | ||
241 | } | ||
242 | |||
243 | static void fcp_report_map_done(fc_channel *fc, int i, int status) | ||
244 | { | ||
245 | fcp_cmnd *fcmd; | ||
246 | fc_hdr *fch; | ||
247 | unsigned char j; | ||
248 | ls *l = (ls *)fc->ls; | ||
249 | fc_al_posmap *p; | ||
250 | |||
251 | FCD(("Report map done %d %d\n", i, status)) | ||
252 | switch (status) { | ||
253 | case FC_STATUS_OK: /* Ok, let's have a fun on a loop */ | ||
254 | dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi), | ||
255 | DMA_BIDIRECTIONAL); | ||
256 | p = (fc_al_posmap *)(l->logi + 3 * i); | ||
257 | #ifdef FCDEBUG | ||
258 | { | ||
259 | u32 *u = (u32 *)p; | ||
260 | FCD(("%08x\n", u[0])) | ||
261 | u ++; | ||
262 | FCD(("%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x\n", u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7])) | ||
263 | } | ||
264 | #endif | ||
265 | if ((p->magic & 0xffff0000) != FC_AL_LILP || !p->len) { | ||
266 | printk ("FC: Bad magic from REPORT_AL_MAP on %s - %08x\n", fc->name, p->magic); | ||
267 | fc->state = FC_STATE_OFFLINE; | ||
268 | } else { | ||
269 | fc->posmap = kzalloc(sizeof(fcp_posmap)+p->len, GFP_KERNEL); | ||
270 | if (!fc->posmap) { | ||
271 | printk("FC: Not enough memory, offlining channel\n"); | ||
272 | fc->state = FC_STATE_OFFLINE; | ||
273 | } else { | ||
274 | int k; | ||
275 | /* FIXME: This is where SOCAL transfers our AL-PA. | ||
276 | Keep it here till we found out what other cards do... */ | ||
277 | fc->sid = (p->magic & 0xff); | ||
278 | for (i = 0; i < p->len; i++) | ||
279 | if (p->alpa[i] == fc->sid) | ||
280 | break; | ||
281 | k = p->len; | ||
282 | if (i == p->len) | ||
283 | i = 0; | ||
284 | else { | ||
285 | p->len--; | ||
286 | i++; | ||
287 | } | ||
288 | fc->posmap->len = p->len; | ||
289 | for (j = 0; j < p->len; j++) { | ||
290 | if (i == k) i = 0; | ||
291 | fc->posmap->list[j] = p->alpa[i++]; | ||
292 | } | ||
293 | fc->state = FC_STATE_ONLINE; | ||
294 | } | ||
295 | } | ||
296 | printk ("%s: ONLINE\n", fc->name); | ||
297 | if (atomic_dec_and_test (&l->todo)) | ||
298 | up(&l->sem); | ||
299 | break; | ||
300 | case FC_STATUS_POINTTOPOINT: /* We're Point-to-Point, no AL... */ | ||
301 | FCD(("SID %d DID %d\n", fc->sid, fc->did)) | ||
302 | fcmd = l->fcmds + i; | ||
303 | dma_unmap_single(fc->dev, fcmd->cmd, 3 * sizeof(logi), | ||
304 | DMA_BIDIRECTIONAL); | ||
305 | fch = &fcmd->fch; | ||
306 | memset(l->logi + 3 * i, 0, 3 * sizeof(logi)); | ||
307 | FILL_FCHDR_RCTL_DID(fch, R_CTL_ELS_REQ, FS_FABRIC_F_PORT); | ||
308 | FILL_FCHDR_SID(fch, 0); | ||
309 | FILL_FCHDR_TYPE_FCTL(fch, TYPE_EXTENDED_LS, F_CTL_FIRST_SEQ | F_CTL_SEQ_INITIATIVE); | ||
310 | FILL_FCHDR_SEQ_DF_SEQ(fch, 0, 0, 0); | ||
311 | FILL_FCHDR_OXRX(fch, 0xffff, 0xffff); | ||
312 | fch->param = 0; | ||
313 | l->logi [3 * i].code = LS_FLOGI; | ||
314 | fcmd->cmd = dma_map_single (fc->dev, l->logi + 3 * i, 3 * sizeof(logi), | ||
315 | DMA_BIDIRECTIONAL); | ||
316 | fcmd->rsp = fcmd->cmd + sizeof(logi); | ||
317 | fcmd->cmdlen = sizeof(logi); | ||
318 | fcmd->rsplen = sizeof(logi); | ||
319 | fcmd->data = (dma_addr_t)NULL; | ||
320 | fcmd->class = FC_CLASS_SIMPLE; | ||
321 | fcmd->proto = TYPE_EXTENDED_LS; | ||
322 | if (fc->hw_enque (fc, fcmd)) | ||
323 | printk ("FC: Cannot enque FLOGI packet on %s\n", fc->name); | ||
324 | break; | ||
325 | case FC_STATUS_ERR_OFFLINE: | ||
326 | fc->state = FC_STATE_MAYBEOFFLINE; | ||
327 | FCD (("FC is offline %d\n", l->grace[i])) | ||
328 | break; | ||
329 | default: | ||
330 | printk ("FLOGI failed for %s with status %d\n", fc->name, status); | ||
331 | /* Do some sort of error recovery here */ | ||
332 | break; | ||
333 | } | ||
334 | } | ||
335 | |||
336 | void fcp_register(fc_channel *fc, u8 type, int unregister) | ||
337 | { | ||
338 | int size, i; | ||
339 | int slots = (fc->can_queue * 3) >> 1; | ||
340 | |||
341 | FCND(("Going to %sregister\n", unregister ? "un" : "")) | ||
342 | |||
343 | if (type == TYPE_SCSI_FCP) { | ||
344 | if (!unregister) { | ||
345 | fc->scsi_cmd_pool = (fcp_cmd *) | ||
346 | dma_alloc_consistent (fc->dev, | ||
347 | slots * (sizeof (fcp_cmd) + fc->rsp_size), | ||
348 | &fc->dma_scsi_cmd); | ||
349 | fc->scsi_rsp_pool = (char *)(fc->scsi_cmd_pool + slots); | ||
350 | fc->dma_scsi_rsp = fc->dma_scsi_cmd + slots * sizeof (fcp_cmd); | ||
351 | fc->scsi_bitmap_end = (slots + 63) & ~63; | ||
352 | size = fc->scsi_bitmap_end / 8; | ||
353 | fc->scsi_bitmap = kzalloc (size, GFP_KERNEL); | ||
354 | set_bit (0, fc->scsi_bitmap); | ||
355 | for (i = fc->can_queue; i < fc->scsi_bitmap_end; i++) | ||
356 | set_bit (i, fc->scsi_bitmap); | ||
357 | fc->scsi_free = fc->can_queue; | ||
358 | fc->cmd_slots = kzalloc(slots * sizeof(fcp_cmnd*), GFP_KERNEL); | ||
359 | fc->abort_count = 0; | ||
360 | } else { | ||
361 | fc->scsi_name[0] = 0; | ||
362 | kfree (fc->scsi_bitmap); | ||
363 | kfree (fc->cmd_slots); | ||
364 | FCND(("Unregistering\n")); | ||
365 | #if 0 | ||
366 | if (fc->rst_pkt) { | ||
367 | if (fc->rst_pkt->eh_state == SCSI_STATE_UNUSED) | ||
368 | kfree(fc->rst_pkt); | ||
369 | else { | ||
370 | /* Can't happen. Some memory would be lost. */ | ||
371 | printk("FC: Reset in progress. Now?!"); | ||
372 | } | ||
373 | } | ||
374 | #endif | ||
375 | FCND(("Unregistered\n")); | ||
376 | } | ||
377 | } else | ||
378 | printk ("FC: %segistering unknown type %02x\n", unregister ? "Unr" : "R", type); | ||
379 | } | ||
380 | |||
381 | static void fcp_scsi_done(struct scsi_cmnd *SCpnt); | ||
382 | |||
383 | static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hdr *fch) | ||
384 | { | ||
385 | fcp_cmnd *fcmd; | ||
386 | fcp_rsp *rsp; | ||
387 | int host_status; | ||
388 | struct scsi_cmnd *SCpnt; | ||
389 | int sense_len; | ||
390 | int rsp_status; | ||
391 | |||
392 | fcmd = fc->cmd_slots[token]; | ||
393 | if (!fcmd) return; | ||
394 | rsp = (fcp_rsp *) (fc->scsi_rsp_pool + fc->rsp_size * token); | ||
395 | SCpnt = SC_FCMND(fcmd); | ||
396 | |||
397 | if (SCpnt->done != fcp_scsi_done) | ||
398 | return; | ||
399 | |||
400 | rsp_status = rsp->fcp_status; | ||
401 | FCD(("rsp_status %08x status %08x\n", rsp_status, status)) | ||
402 | switch (status) { | ||
403 | case FC_STATUS_OK: | ||
404 | host_status=DID_OK; | ||
405 | |||
406 | if (rsp_status & FCP_STATUS_RESID) { | ||
407 | #ifdef FCDEBUG | ||
408 | FCD(("Resid %d\n", rsp->fcp_resid)) | ||
409 | { | ||
410 | fcp_cmd *cmd = fc->scsi_cmd_pool + token; | ||
411 | int i; | ||
412 | |||
413 | printk ("Command "); | ||
414 | for (i = 0; i < sizeof(fcp_cmd); i+=4) | ||
415 | printk ("%08x ", *(u32 *)(((char *)cmd)+i)); | ||
416 | printk ("\nResponse "); | ||
417 | for (i = 0; i < fc->rsp_size; i+=4) | ||
418 | printk ("%08x ", *(u32 *)(((char *)rsp)+i)); | ||
419 | printk ("\n"); | ||
420 | } | ||
421 | #endif | ||
422 | } | ||
423 | |||
424 | if (rsp_status & FCP_STATUS_SENSE_LEN) { | ||
425 | sense_len = rsp->fcp_sense_len; | ||
426 | if (sense_len > sizeof(SCpnt->sense_buffer)) sense_len = sizeof(SCpnt->sense_buffer); | ||
427 | memcpy(SCpnt->sense_buffer, ((char *)(rsp+1)), sense_len); | ||
428 | } | ||
429 | |||
430 | if (fcmd->data) | ||
431 | dma_unmap_sg(fc->dev, scsi_sglist(SCpnt), | ||
432 | scsi_sg_count(SCpnt), | ||
433 | SCpnt->sc_data_direction); | ||
434 | break; | ||
435 | default: | ||
436 | host_status=DID_ERROR; /* FIXME */ | ||
437 | FCD(("Wrong FC status %d for token %d\n", status, token)) | ||
438 | break; | ||
439 | } | ||
440 | |||
441 | if (status_byte(rsp_status) == QUEUE_FULL) { | ||
442 | printk ("%s: (%d,%d) Received rsp_status 0x%x\n", fc->name, SCpnt->device->channel, SCpnt->device->id, rsp_status); | ||
443 | } | ||
444 | |||
445 | SCpnt->result = (host_status << 16) | (rsp_status & 0xff); | ||
446 | #ifdef FCDEBUG | ||
447 | if (host_status || SCpnt->result || rsp_status) printk("FC: host_status %d, packet status %d\n", | ||
448 | host_status, SCpnt->result); | ||
449 | #endif | ||
450 | SCpnt->done = fcmd->done; | ||
451 | fcmd->done=NULL; | ||
452 | clear_bit(token, fc->scsi_bitmap); | ||
453 | fc->scsi_free++; | ||
454 | FCD(("Calling scsi_done with %08x\n", SCpnt->result)) | ||
455 | SCpnt->scsi_done(SCpnt); | ||
456 | } | ||
457 | |||
458 | void fcp_receive_solicited(fc_channel *fc, int proto, int token, int status, fc_hdr *fch) | ||
459 | { | ||
460 | int magic; | ||
461 | FCD(("receive_solicited %d %d %d\n", proto, token, status)) | ||
462 | switch (proto) { | ||
463 | case TYPE_SCSI_FCP: | ||
464 | fcp_scsi_receive(fc, token, status, fch); break; | ||
465 | case TYPE_EXTENDED_LS: | ||
466 | case PROTO_REPORT_AL_MAP: | ||
467 | magic = 0; | ||
468 | if (fc->ls) | ||
469 | magic = ((ls *)(fc->ls))->magic; | ||
470 | if (magic == LSMAGIC) { | ||
471 | ls *l = (ls *)fc->ls; | ||
472 | int i = (token >= l->count) ? token - l->count : token; | ||
473 | |||
474 | /* Let's be sure */ | ||
475 | if ((unsigned)i < l->count && l->fcmds[i].fc == fc) { | ||
476 | if (proto == TYPE_EXTENDED_LS) | ||
477 | fcp_login_done(fc, token, status); | ||
478 | else | ||
479 | fcp_report_map_done(fc, token, status); | ||
480 | break; | ||
481 | } | ||
482 | } | ||
483 | FCD(("fc %p fc->ls %p fc->cmd_slots %p\n", fc, fc->ls, fc->cmd_slots)) | ||
484 | if (proto == TYPE_EXTENDED_LS && !fc->ls && fc->cmd_slots) { | ||
485 | fcp_cmnd *fcmd; | ||
486 | |||
487 | fcmd = fc->cmd_slots[token]; | ||
488 | if (fcmd && fcmd->ls && ((ls *)(fcmd->ls))->magic == LSEMAGIC) { | ||
489 | lse *l = (lse *)fcmd->ls; | ||
490 | |||
491 | l->status = status; | ||
492 | up (&l->sem); | ||
493 | } | ||
494 | } | ||
495 | break; | ||
496 | case PROTO_OFFLINE: | ||
497 | if (fc->ls && ((lso *)(fc->ls))->magic == LSOMAGIC) { | ||
498 | lso *l = (lso *)fc->ls; | ||
499 | |||
500 | if ((unsigned)token < l->count && l->fcmds[token].fc == fc) { | ||
501 | /* Wow, OFFLINE response arrived :) */ | ||
502 | FCD(("OFFLINE Response arrived\n")) | ||
503 | fc->state = FC_STATE_OFFLINE; | ||
504 | if (atomic_dec_and_test (&l->todo)) | ||
505 | up(&l->sem); | ||
506 | } | ||
507 | } | ||
508 | break; | ||
509 | |||
510 | default: | ||
511 | break; | ||
512 | } | ||
513 | } | ||
514 | |||
515 | void fcp_state_change(fc_channel *fc, int state) | ||
516 | { | ||
517 | FCD(("state_change %d %d\n", state, fc->state)) | ||
518 | if (state == FC_STATE_ONLINE && fc->state == FC_STATE_MAYBEOFFLINE) | ||
519 | fc->state = FC_STATE_UNINITED; | ||
520 | else if (state == FC_STATE_ONLINE) | ||
521 | printk (KERN_WARNING "%s: state change to ONLINE\n", fc->name); | ||
522 | else | ||
523 | printk (KERN_ERR "%s: state change to OFFLINE\n", fc->name); | ||
524 | } | ||
525 | |||
526 | int fcp_initialize(fc_channel *fcchain, int count) | ||
527 | { | ||
528 | fc_channel *fc; | ||
529 | fcp_cmnd *fcmd; | ||
530 | int i, retry, ret; | ||
531 | ls *l; | ||
532 | |||
533 | FCND(("fcp_inititialize %08lx\n", (long)fcp_init)) | ||
534 | FCND(("fc_channels %08lx\n", (long)fc_channels)) | ||
535 | FCND((" SID %d DID %d\n", fcchain->sid, fcchain->did)) | ||
536 | l = kzalloc(sizeof (ls) + count, GFP_KERNEL); | ||
537 | if (!l) { | ||
538 | printk ("FC: Cannot allocate memory for initialization\n"); | ||
539 | return -ENOMEM; | ||
540 | } | ||
541 | l->magic = LSMAGIC; | ||
542 | l->count = count; | ||
543 | FCND(("FCP Init for %d channels\n", count)) | ||
544 | init_MUTEX_LOCKED(&l->sem); | ||
545 | init_timer(&l->timer); | ||
546 | l->timer.function = fcp_login_timeout; | ||
547 | l->timer.data = (unsigned long)l; | ||
548 | atomic_set (&l->todo, count); | ||
549 | l->logi = kzalloc (count * 3 * sizeof(logi), GFP_KERNEL); | ||
550 | l->fcmds = kzalloc (count * sizeof(fcp_cmnd), GFP_KERNEL); | ||
551 | if (!l->logi || !l->fcmds) { | ||
552 | kfree (l->logi); | ||
553 | kfree (l->fcmds); | ||
554 | kfree (l); | ||
555 | printk ("FC: Cannot allocate DMA memory for initialization\n"); | ||
556 | return -ENOMEM; | ||
557 | } | ||
558 | for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) { | ||
559 | fc->state = FC_STATE_UNINITED; | ||
560 | fc->rst_pkt = NULL; /* kmalloc when first used */ | ||
561 | } | ||
562 | /* First try if we are in a AL topology */ | ||
563 | FCND(("Initializing REPORT_MAP packets\n")) | ||
564 | for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) { | ||
565 | fcmd = l->fcmds + i; | ||
566 | fc->login = fcmd; | ||
567 | fc->ls = (void *)l; | ||
568 | /* Assumes sizeof(fc_al_posmap) < 3 * sizeof(logi), which is true */ | ||
569 | fcmd->cmd = dma_map_single (fc->dev, l->logi + 3 * i, 3 * sizeof(logi), | ||
570 | DMA_BIDIRECTIONAL); | ||
571 | fcmd->proto = PROTO_REPORT_AL_MAP; | ||
572 | fcmd->token = i; | ||
573 | fcmd->fc = fc; | ||
574 | } | ||
575 | for (retry = 0; retry < 8; retry++) { | ||
576 | int nqueued = 0; | ||
577 | FCND(("Sending REPORT_MAP/FLOGI/PLOGI packets\n")) | ||
578 | for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) { | ||
579 | if (fc->state == FC_STATE_ONLINE || fc->state == FC_STATE_OFFLINE) | ||
580 | continue; | ||
581 | disable_irq(fc->irq); | ||
582 | if (fc->state == FC_STATE_MAYBEOFFLINE) { | ||
583 | if (!l->grace[i]) { | ||
584 | l->grace[i]++; | ||
585 | FCD(("Grace\n")) | ||
586 | } else { | ||
587 | fc->state = FC_STATE_OFFLINE; | ||
588 | enable_irq(fc->irq); | ||
589 | dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi), DMA_BIDIRECTIONAL); | ||
590 | if (atomic_dec_and_test (&l->todo)) | ||
591 | goto all_done; | ||
592 | } | ||
593 | } | ||
594 | ret = fc->hw_enque (fc, fc->login); | ||
595 | enable_irq(fc->irq); | ||
596 | if (!ret) { | ||
597 | nqueued++; | ||
598 | continue; | ||
599 | } | ||
600 | if (ret == -ENOSYS && fc->login->proto == PROTO_REPORT_AL_MAP) { | ||
601 | /* Oh yes, this card handles Point-to-Point only, so let's try that. */ | ||
602 | fc_hdr *fch; | ||
603 | |||
604 | FCD(("SID %d DID %d\n", fc->sid, fc->did)) | ||
605 | fcmd = l->fcmds + i; | ||
606 | dma_unmap_single(fc->dev, fcmd->cmd, 3 * sizeof(logi), DMA_BIDIRECTIONAL); | ||
607 | fch = &fcmd->fch; | ||
608 | FILL_FCHDR_RCTL_DID(fch, R_CTL_ELS_REQ, FS_FABRIC_F_PORT); | ||
609 | FILL_FCHDR_SID(fch, 0); | ||
610 | FILL_FCHDR_TYPE_FCTL(fch, TYPE_EXTENDED_LS, F_CTL_FIRST_SEQ | F_CTL_SEQ_INITIATIVE); | ||
611 | FILL_FCHDR_SEQ_DF_SEQ(fch, 0, 0, 0); | ||
612 | FILL_FCHDR_OXRX(fch, 0xffff, 0xffff); | ||
613 | fch->param = 0; | ||
614 | l->logi [3 * i].code = LS_FLOGI; | ||
615 | fcmd->cmd = dma_map_single (fc->dev, l->logi + 3 * i, 3 * sizeof(logi), DMA_BIDIRECTIONAL); | ||
616 | fcmd->rsp = fcmd->cmd + sizeof(logi); | ||
617 | fcmd->cmdlen = sizeof(logi); | ||
618 | fcmd->rsplen = sizeof(logi); | ||
619 | fcmd->data = (dma_addr_t)NULL; | ||
620 | fcmd->class = FC_CLASS_SIMPLE; | ||
621 | fcmd->proto = TYPE_EXTENDED_LS; | ||
622 | } else | ||
623 | printk ("FC: Cannot enque FLOGI/REPORT_MAP packet on %s\n", fc->name); | ||
624 | } | ||
625 | |||
626 | if (nqueued) { | ||
627 | l->timer.expires = jiffies + 5 * HZ; | ||
628 | add_timer(&l->timer); | ||
629 | |||
630 | down(&l->sem); | ||
631 | if (!atomic_read(&l->todo)) { | ||
632 | FCND(("All channels answered in time\n")) | ||
633 | break; /* All fc channels have answered us */ | ||
634 | } | ||
635 | } | ||
636 | } | ||
637 | all_done: | ||
638 | for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) { | ||
639 | fc->ls = NULL; | ||
640 | switch (fc->state) { | ||
641 | case FC_STATE_ONLINE: break; | ||
642 | case FC_STATE_OFFLINE: break; | ||
643 | default: dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi), DMA_BIDIRECTIONAL); | ||
644 | break; | ||
645 | } | ||
646 | } | ||
647 | del_timer(&l->timer); | ||
648 | kfree (l->logi); | ||
649 | kfree (l->fcmds); | ||
650 | kfree (l); | ||
651 | return 0; | ||
652 | } | ||
653 | |||
654 | int fcp_forceoffline(fc_channel *fcchain, int count) | ||
655 | { | ||
656 | fc_channel *fc; | ||
657 | fcp_cmnd *fcmd; | ||
658 | int i, ret; | ||
659 | lso l; | ||
660 | |||
661 | memset (&l, 0, sizeof(lso)); | ||
662 | l.count = count; | ||
663 | l.magic = LSOMAGIC; | ||
664 | FCND(("FCP Force Offline for %d channels\n", count)) | ||
665 | init_MUTEX_LOCKED(&l.sem); | ||
666 | init_timer(&l.timer); | ||
667 | l.timer.function = fcp_login_timeout; | ||
668 | l.timer.data = (unsigned long)&l; | ||
669 | atomic_set (&l.todo, count); | ||
670 | l.fcmds = kzalloc (count * sizeof(fcp_cmnd), GFP_KERNEL); | ||
671 | if (!l.fcmds) { | ||
672 | printk ("FC: Cannot allocate memory for forcing offline\n"); | ||
673 | return -ENOMEM; | ||
674 | } | ||
675 | FCND(("Initializing OFFLINE packets\n")) | ||
676 | for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) { | ||
677 | fc->state = FC_STATE_UNINITED; | ||
678 | fcmd = l.fcmds + i; | ||
679 | fc->login = fcmd; | ||
680 | fc->ls = (void *)&l; | ||
681 | fcmd->did = fc->did; | ||
682 | fcmd->class = FC_CLASS_OFFLINE; | ||
683 | fcmd->proto = PROTO_OFFLINE; | ||
684 | fcmd->token = i; | ||
685 | fcmd->fc = fc; | ||
686 | disable_irq(fc->irq); | ||
687 | ret = fc->hw_enque (fc, fc->login); | ||
688 | enable_irq(fc->irq); | ||
689 | if (ret) printk ("FC: Cannot enque OFFLINE packet on %s\n", fc->name); | ||
690 | } | ||
691 | |||
692 | l.timer.expires = jiffies + 5 * HZ; | ||
693 | add_timer(&l.timer); | ||
694 | down(&l.sem); | ||
695 | del_timer(&l.timer); | ||
696 | |||
697 | for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) | ||
698 | fc->ls = NULL; | ||
699 | kfree (l.fcmds); | ||
700 | return 0; | ||
701 | } | ||
702 | |||
703 | int fcp_init(fc_channel *fcchain) | ||
704 | { | ||
705 | fc_channel *fc; | ||
706 | int count=0; | ||
707 | int ret; | ||
708 | |||
709 | for (fc = fcchain; fc; fc = fc->next) { | ||
710 | fc->fcp_register = fcp_register; | ||
711 | count++; | ||
712 | } | ||
713 | |||
714 | ret = fcp_initialize (fcchain, count); | ||
715 | if (ret) | ||
716 | return ret; | ||
717 | |||
718 | if (!fc_channels) | ||
719 | fc_channels = fcchain; | ||
720 | else { | ||
721 | for (fc = fc_channels; fc->next; fc = fc->next); | ||
722 | fc->next = fcchain; | ||
723 | } | ||
724 | return ret; | ||
725 | } | ||
726 | |||
727 | void fcp_release(fc_channel *fcchain, int count) /* count must > 0 */ | ||
728 | { | ||
729 | fc_channel *fc; | ||
730 | fc_channel *fcx; | ||
731 | |||
732 | for (fc = fcchain; --count && fc->next; fc = fc->next); | ||
733 | if (count) { | ||
734 | printk("FC: nothing to release\n"); | ||
735 | return; | ||
736 | } | ||
737 | |||
738 | if (fc_channels == fcchain) | ||
739 | fc_channels = fc->next; | ||
740 | else { | ||
741 | for (fcx = fc_channels; fcx->next != fcchain; fcx = fcx->next); | ||
742 | fcx->next = fc->next; | ||
743 | } | ||
744 | fc->next = NULL; | ||
745 | |||
746 | /* | ||
747 | * We've just grabbed fcchain out of the fc_channel list | ||
748 | * and zero-terminated it, while destroying the count. | ||
749 | * | ||
750 | * Freeing the fc's is the low level driver's responsibility. | ||
751 | */ | ||
752 | } | ||
753 | |||
754 | |||
755 | static void fcp_scsi_done(struct scsi_cmnd *SCpnt) | ||
756 | { | ||
757 | if (FCP_CMND(SCpnt)->done) | ||
758 | FCP_CMND(SCpnt)->done(SCpnt); | ||
759 | } | ||
760 | |||
761 | static int fcp_scsi_queue_it(fc_channel *fc, struct scsi_cmnd *SCpnt, | ||
762 | fcp_cmnd *fcmd, int prepare) | ||
763 | { | ||
764 | long i; | ||
765 | fcp_cmd *cmd; | ||
766 | u32 fcp_cntl; | ||
767 | if (prepare) { | ||
768 | i = find_first_zero_bit (fc->scsi_bitmap, fc->scsi_bitmap_end); | ||
769 | set_bit (i, fc->scsi_bitmap); | ||
770 | fcmd->token = i; | ||
771 | cmd = fc->scsi_cmd_pool + i; | ||
772 | |||
773 | if (fc->encode_addr (SCpnt, cmd->fcp_addr, fc, fcmd)) { | ||
774 | /* Invalid channel/id/lun and couldn't map it into fcp_addr */ | ||
775 | clear_bit (i, fc->scsi_bitmap); | ||
776 | SCpnt->result = (DID_BAD_TARGET << 16); | ||
777 | SCpnt->scsi_done(SCpnt); | ||
778 | return 0; | ||
779 | } | ||
780 | fc->scsi_free--; | ||
781 | fc->cmd_slots[fcmd->token] = fcmd; | ||
782 | |||
783 | if (SCpnt->device->tagged_supported) { | ||
784 | if (jiffies - fc->ages[SCpnt->device->channel * fc->targets + SCpnt->device->id] > (5 * 60 * HZ)) { | ||
785 | fc->ages[SCpnt->device->channel * fc->targets + SCpnt->device->id] = jiffies; | ||
786 | fcp_cntl = FCP_CNTL_QTYPE_ORDERED; | ||
787 | } else | ||
788 | fcp_cntl = FCP_CNTL_QTYPE_SIMPLE; | ||
789 | } else | ||
790 | fcp_cntl = FCP_CNTL_QTYPE_UNTAGGED; | ||
791 | |||
792 | if (!scsi_bufflen(SCpnt)) { | ||
793 | cmd->fcp_cntl = fcp_cntl; | ||
794 | fcmd->data = (dma_addr_t)NULL; | ||
795 | } else { | ||
796 | struct scatterlist *sg; | ||
797 | int nents; | ||
798 | |||
799 | switch (SCpnt->cmnd[0]) { | ||
800 | case WRITE_6: | ||
801 | case WRITE_10: | ||
802 | case WRITE_12: | ||
803 | cmd->fcp_cntl = (FCP_CNTL_WRITE | fcp_cntl); break; | ||
804 | default: | ||
805 | cmd->fcp_cntl = (FCP_CNTL_READ | fcp_cntl); break; | ||
806 | } | ||
807 | |||
808 | sg = scsi_sglist(SCpnt); | ||
809 | nents = dma_map_sg(fc->dev, sg, scsi_sg_count(SCpnt), | ||
810 | SCpnt->sc_data_direction); | ||
811 | fcmd->data = sg_dma_address(sg); | ||
812 | cmd->fcp_data_len = sg_dma_len(sg); | ||
813 | } | ||
814 | memcpy (cmd->fcp_cdb, SCpnt->cmnd, SCpnt->cmd_len); | ||
815 | memset (cmd->fcp_cdb+SCpnt->cmd_len, 0, sizeof(cmd->fcp_cdb)-SCpnt->cmd_len); | ||
816 | FCD(("XXX: %04x.%04x.%04x.%04x - %08x%08x%08x\n", cmd->fcp_addr[0], cmd->fcp_addr[1], cmd->fcp_addr[2], cmd->fcp_addr[3], *(u32 *)SCpnt->cmnd, *(u32 *)(SCpnt->cmnd+4), *(u32 *)(SCpnt->cmnd+8))) | ||
817 | } | ||
818 | FCD(("Trying to enque %p\n", fcmd)) | ||
819 | if (!fc->scsi_que) { | ||
820 | if (!fc->hw_enque (fc, fcmd)) { | ||
821 | FCD(("hw_enque succeeded for %p\n", fcmd)) | ||
822 | return 0; | ||
823 | } | ||
824 | } | ||
825 | FCD(("Putting into que1 %p\n", fcmd)) | ||
826 | fcp_scsi_insert_queue (fc, fcmd); | ||
827 | return 0; | ||
828 | } | ||
829 | |||
830 | int fcp_scsi_queuecommand(struct scsi_cmnd *SCpnt, | ||
831 | void (* done)(struct scsi_cmnd *)) | ||
832 | { | ||
833 | fcp_cmnd *fcmd = FCP_CMND(SCpnt); | ||
834 | fc_channel *fc = FC_SCMND(SCpnt); | ||
835 | |||
836 | FCD(("Entering SCSI queuecommand %p\n", fcmd)) | ||
837 | if (SCpnt->done != fcp_scsi_done) { | ||
838 | fcmd->done = SCpnt->done; | ||
839 | SCpnt->done = fcp_scsi_done; | ||
840 | SCpnt->scsi_done = done; | ||
841 | fcmd->proto = TYPE_SCSI_FCP; | ||
842 | if (!fc->scsi_free) { | ||
843 | FCD(("FC: !scsi_free, putting cmd on ML queue\n")) | ||
844 | #if (FCP_SCSI_USE_NEW_EH_CODE == 0) | ||
845 | printk("fcp_scsi_queue_command: queue full, losing cmd, bad\n"); | ||
846 | #endif | ||
847 | return 1; | ||
848 | } | ||
849 | return fcp_scsi_queue_it(fc, SCpnt, fcmd, 1); | ||
850 | } | ||
851 | return fcp_scsi_queue_it(fc, SCpnt, fcmd, 0); | ||
852 | } | ||
853 | |||
854 | void fcp_queue_empty(fc_channel *fc) | ||
855 | { | ||
856 | fcp_cmnd *fcmd; | ||
857 | |||
858 | FCD(("Queue empty\n")) | ||
859 | while ((fcmd = fc->scsi_que)) { | ||
860 | /* The hw told us we can try again queue some packet */ | ||
861 | if (fc->hw_enque (fc, fcmd)) | ||
862 | break; | ||
863 | fcp_scsi_remove_queue (fc, fcmd); | ||
864 | } | ||
865 | } | ||
866 | |||
867 | int fcp_scsi_abort(struct scsi_cmnd *SCpnt) | ||
868 | { | ||
869 | /* Internal bookkeeping only. Lose 1 cmd_slots slot. */ | ||
870 | fcp_cmnd *fcmd = FCP_CMND(SCpnt); | ||
871 | fc_channel *fc = FC_SCMND(SCpnt); | ||
872 | |||
873 | /* | ||
874 | * We react to abort requests by simply forgetting | ||
875 | * about the command and pretending everything's sweet. | ||
876 | * This may or may not be silly. We can't, however, | ||
877 | * immediately reuse the command's cmd_slots slot, | ||
878 | * as its result may arrive later and we cannot | ||
879 | * check whether it is the aborted one, can't we? | ||
880 | * | ||
881 | * Therefore, after the first few aborts are done, | ||
882 | * we tell the scsi error handler to do something clever. | ||
883 | * It will eventually call host reset, refreshing | ||
884 | * cmd_slots for us. | ||
885 | * | ||
886 | * There is a theoretical chance that we sometimes allow | ||
887 | * more than can_queue packets to the jungle this way, | ||
888 | * but the worst outcome possible is a series of | ||
889 | * more aborts and eventually the dev_reset catharsis. | ||
890 | */ | ||
891 | |||
892 | if (++fc->abort_count < (fc->can_queue >> 1)) { | ||
893 | SCpnt->result = DID_ABORT; | ||
894 | fcmd->done(SCpnt); | ||
895 | printk("FC: soft abort\n"); | ||
896 | return SUCCESS; | ||
897 | } else { | ||
898 | printk("FC: hard abort refused\n"); | ||
899 | return FAILED; | ||
900 | } | ||
901 | } | ||
902 | |||
903 | #if 0 | ||
904 | void fcp_scsi_reset_done(struct scsi_cmnd *SCpnt) | ||
905 | { | ||
906 | fc_channel *fc = FC_SCMND(SCpnt); | ||
907 | |||
908 | fc->rst_pkt->eh_state = SCSI_STATE_FINISHED; | ||
909 | up(fc->rst_pkt->device->host->eh_action); | ||
910 | } | ||
911 | #endif | ||
912 | |||
913 | #define FCP_RESET_TIMEOUT (2*HZ) | ||
914 | |||
915 | int fcp_scsi_dev_reset(struct scsi_cmnd *SCpnt) | ||
916 | { | ||
917 | #if 0 /* broken junk, but if davem wants to compile this driver, let him.. */ | ||
918 | unsigned long flags; | ||
919 | fcp_cmd *cmd; | ||
920 | fcp_cmnd *fcmd; | ||
921 | fc_channel *fc = FC_SCMND(SCpnt); | ||
922 | DECLARE_MUTEX_LOCKED(sem); | ||
923 | |||
924 | if (!fc->rst_pkt) { | ||
925 | fc->rst_pkt = kmalloc(sizeof(SCpnt), GFP_KERNEL); | ||
926 | if (!fc->rst_pkt) return FAILED; | ||
927 | |||
928 | fcmd = FCP_CMND(fc->rst_pkt); | ||
929 | |||
930 | |||
931 | fcmd->token = 0; | ||
932 | cmd = fc->scsi_cmd_pool + 0; | ||
933 | FCD(("Preparing rst packet\n")) | ||
934 | fc->encode_addr (SCpnt, cmd->fcp_addr, fc, fcmd); | ||
935 | fc->rst_pkt->device = SCpnt->device; | ||
936 | fc->rst_pkt->cmd_len = 0; | ||
937 | |||
938 | fc->cmd_slots[0] = fcmd; | ||
939 | |||
940 | cmd->fcp_cntl = FCP_CNTL_QTYPE_ORDERED | FCP_CNTL_RESET; | ||
941 | fcmd->data = (dma_addr_t)NULL; | ||
942 | fcmd->proto = TYPE_SCSI_FCP; | ||
943 | |||
944 | memcpy (cmd->fcp_cdb, SCpnt->cmnd, SCpnt->cmd_len); | ||
945 | memset (cmd->fcp_cdb+SCpnt->cmd_len, 0, sizeof(cmd->fcp_cdb)-SCpnt->cmd_len); | ||
946 | FCD(("XXX: %04x.%04x.%04x.%04x - %08x%08x%08x\n", cmd->fcp_addr[0], cmd->fcp_addr[1], cmd->fcp_addr[2], cmd->fcp_addr[3], *(u32 *)SCpnt->cmnd, *(u32 *)(SCpnt->cmnd+4), *(u32 *)(SCpnt->cmnd+8))) | ||
947 | } else { | ||
948 | fcmd = FCP_CMND(fc->rst_pkt); | ||
949 | if (fc->rst_pkt->eh_state == SCSI_STATE_QUEUED) | ||
950 | return FAILED; /* or SUCCESS. Only these */ | ||
951 | } | ||
952 | fc->rst_pkt->done = NULL; | ||
953 | |||
954 | |||
955 | fc->rst_pkt->eh_state = SCSI_STATE_QUEUED; | ||
956 | init_timer(&fc->rst_pkt->eh_timeout); | ||
957 | fc->rst_pkt->eh_timeout.data = (unsigned long) fc->rst_pkt; | ||
958 | fc->rst_pkt->eh_timeout.expires = jiffies + FCP_RESET_TIMEOUT; | ||
959 | fc->rst_pkt->eh_timeout.function = (void (*)(unsigned long))fcp_scsi_reset_done; | ||
960 | |||
961 | add_timer(&fc->rst_pkt->eh_timeout); | ||
962 | |||
963 | /* | ||
964 | * Set up the semaphore so we wait for the command to complete. | ||
965 | */ | ||
966 | |||
967 | fc->rst_pkt->device->host->eh_action = &sem; | ||
968 | |||
969 | fc->rst_pkt->done = fcp_scsi_reset_done; | ||
970 | |||
971 | spin_lock_irqsave(SCpnt->device->host->host_lock, flags); | ||
972 | fcp_scsi_queue_it(fc, fc->rst_pkt, fcmd, 0); | ||
973 | spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags); | ||
974 | |||
975 | down(&sem); | ||
976 | |||
977 | fc->rst_pkt->device->host->eh_action = NULL; | ||
978 | del_timer(&fc->rst_pkt->eh_timeout); | ||
979 | |||
980 | /* | ||
981 | * See if timeout. If so, tell the host to forget about it. | ||
982 | * In other words, we don't want a callback any more. | ||
983 | */ | ||
984 | if (fc->rst_pkt->eh_state == SCSI_STATE_TIMEOUT ) { | ||
985 | fc->rst_pkt->eh_state = SCSI_STATE_UNUSED; | ||
986 | return FAILED; | ||
987 | } | ||
988 | fc->rst_pkt->eh_state = SCSI_STATE_UNUSED; | ||
989 | #endif | ||
990 | return SUCCESS; | ||
991 | } | ||
992 | |||
993 | static int __fcp_scsi_host_reset(struct scsi_cmnd *SCpnt) | ||
994 | { | ||
995 | fc_channel *fc = FC_SCMND(SCpnt); | ||
996 | fcp_cmnd *fcmd = FCP_CMND(SCpnt); | ||
997 | int i; | ||
998 | |||
999 | printk ("FC: host reset\n"); | ||
1000 | |||
1001 | for (i=0; i < fc->can_queue; i++) { | ||
1002 | if (fc->cmd_slots[i] && SCpnt->result != DID_ABORT) { | ||
1003 | SCpnt->result = DID_RESET; | ||
1004 | fcmd->done(SCpnt); | ||
1005 | fc->cmd_slots[i] = NULL; | ||
1006 | } | ||
1007 | } | ||
1008 | fc->reset(fc); | ||
1009 | fc->abort_count = 0; | ||
1010 | if (fcp_initialize(fc, 1)) return SUCCESS; | ||
1011 | else return FAILED; | ||
1012 | } | ||
1013 | |||
1014 | int fcp_scsi_host_reset(struct scsi_cmnd *SCpnt) | ||
1015 | { | ||
1016 | unsigned long flags; | ||
1017 | int rc; | ||
1018 | |||
1019 | spin_lock_irqsave(SCpnt->device->host->host_lock, flags); | ||
1020 | rc = __fcp_scsi_host_reset(SCpnt); | ||
1021 | spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags); | ||
1022 | |||
1023 | return rc; | ||
1024 | } | ||
1025 | |||
1026 | static int fcp_els_queue_it(fc_channel *fc, fcp_cmnd *fcmd) | ||
1027 | { | ||
1028 | long i; | ||
1029 | |||
1030 | i = find_first_zero_bit (fc->scsi_bitmap, fc->scsi_bitmap_end); | ||
1031 | set_bit (i, fc->scsi_bitmap); | ||
1032 | fcmd->token = i; | ||
1033 | fc->scsi_free--; | ||
1034 | fc->cmd_slots[fcmd->token] = fcmd; | ||
1035 | return fcp_scsi_queue_it(fc, NULL, fcmd, 0); | ||
1036 | } | ||
1037 | |||
1038 | static int fc_do_els(fc_channel *fc, unsigned int alpa, void *data, int len) | ||
1039 | { | ||
1040 | fcp_cmnd _fcmd, *fcmd; | ||
1041 | fc_hdr *fch; | ||
1042 | lse l; | ||
1043 | int i; | ||
1044 | |||
1045 | fcmd = &_fcmd; | ||
1046 | memset(fcmd, 0, sizeof(fcp_cmnd)); | ||
1047 | FCD(("PLOGI SID %d DID %d\n", fc->sid, alpa)) | ||
1048 | fch = &fcmd->fch; | ||
1049 | FILL_FCHDR_RCTL_DID(fch, R_CTL_ELS_REQ, alpa); | ||
1050 | FILL_FCHDR_SID(fch, fc->sid); | ||
1051 | FILL_FCHDR_TYPE_FCTL(fch, TYPE_EXTENDED_LS, F_CTL_FIRST_SEQ | F_CTL_SEQ_INITIATIVE); | ||
1052 | FILL_FCHDR_SEQ_DF_SEQ(fch, 0, 0, 0); | ||
1053 | FILL_FCHDR_OXRX(fch, 0xffff, 0xffff); | ||
1054 | fch->param = 0; | ||
1055 | fcmd->cmd = dma_map_single (fc->dev, data, 2 * len, DMA_BIDIRECTIONAL); | ||
1056 | fcmd->rsp = fcmd->cmd + len; | ||
1057 | fcmd->cmdlen = len; | ||
1058 | fcmd->rsplen = len; | ||
1059 | fcmd->data = (dma_addr_t)NULL; | ||
1060 | fcmd->fc = fc; | ||
1061 | fcmd->class = FC_CLASS_SIMPLE; | ||
1062 | fcmd->proto = TYPE_EXTENDED_LS; | ||
1063 | |||
1064 | memset (&l, 0, sizeof(lse)); | ||
1065 | l.magic = LSEMAGIC; | ||
1066 | init_MUTEX_LOCKED(&l.sem); | ||
1067 | l.timer.function = fcp_login_timeout; | ||
1068 | l.timer.data = (unsigned long)&l; | ||
1069 | l.status = FC_STATUS_TIMED_OUT; | ||
1070 | fcmd->ls = (void *)&l; | ||
1071 | |||
1072 | disable_irq(fc->irq); | ||
1073 | fcp_els_queue_it(fc, fcmd); | ||
1074 | enable_irq(fc->irq); | ||
1075 | |||
1076 | for (i = 0;;) { | ||
1077 | l.timer.expires = jiffies + 5 * HZ; | ||
1078 | add_timer(&l.timer); | ||
1079 | down(&l.sem); | ||
1080 | del_timer(&l.timer); | ||
1081 | if (l.status != FC_STATUS_TIMED_OUT) break; | ||
1082 | if (++i == 3) break; | ||
1083 | disable_irq(fc->irq); | ||
1084 | fcp_scsi_queue_it(fc, NULL, fcmd, 0); | ||
1085 | enable_irq(fc->irq); | ||
1086 | } | ||
1087 | |||
1088 | clear_bit(fcmd->token, fc->scsi_bitmap); | ||
1089 | fc->scsi_free++; | ||
1090 | dma_unmap_single (fc->dev, fcmd->cmd, 2 * len, DMA_BIDIRECTIONAL); | ||
1091 | return l.status; | ||
1092 | } | ||
1093 | |||
1094 | int fc_do_plogi(fc_channel *fc, unsigned char alpa, fc_wwn *node, fc_wwn *nport) | ||
1095 | { | ||
1096 | logi *l; | ||
1097 | int status; | ||
1098 | |||
1099 | l = kzalloc(2 * sizeof(logi), GFP_KERNEL); | ||
1100 | if (!l) return -ENOMEM; | ||
1101 | l->code = LS_PLOGI; | ||
1102 | memcpy (&l->nport_wwn, &fc->wwn_nport, sizeof(fc_wwn)); | ||
1103 | memcpy (&l->node_wwn, &fc->wwn_node, sizeof(fc_wwn)); | ||
1104 | memcpy (&l->common, fc->common_svc, sizeof(common_svc_parm)); | ||
1105 | memcpy (&l->class1, fc->class_svcs, 3*sizeof(svc_parm)); | ||
1106 | status = fc_do_els(fc, alpa, l, sizeof(logi)); | ||
1107 | if (status == FC_STATUS_OK) { | ||
1108 | if (l[1].code == LS_ACC) { | ||
1109 | #ifdef FCDEBUG | ||
1110 | u32 *u = (u32 *)&l[1].nport_wwn; | ||
1111 | FCD(("AL-PA %02x: Port WWN %08x%08x Node WWN %08x%08x\n", alpa, | ||
1112 | u[0], u[1], u[2], u[3])) | ||
1113 | #endif | ||
1114 | memcpy(nport, &l[1].nport_wwn, sizeof(fc_wwn)); | ||
1115 | memcpy(node, &l[1].node_wwn, sizeof(fc_wwn)); | ||
1116 | } else | ||
1117 | status = FC_STATUS_BAD_RSP; | ||
1118 | } | ||
1119 | kfree(l); | ||
1120 | return status; | ||
1121 | } | ||
1122 | |||
1123 | typedef struct { | ||
1124 | unsigned int code; | ||
1125 | unsigned params[4]; | ||
1126 | } prli; | ||
1127 | |||
1128 | int fc_do_prli(fc_channel *fc, unsigned char alpa) | ||
1129 | { | ||
1130 | prli *p; | ||
1131 | int status; | ||
1132 | |||
1133 | p = kzalloc(2 * sizeof(prli), GFP_KERNEL); | ||
1134 | if (!p) return -ENOMEM; | ||
1135 | p->code = LS_PRLI; | ||
1136 | p->params[0] = 0x08002000; | ||
1137 | p->params[3] = 0x00000022; | ||
1138 | status = fc_do_els(fc, alpa, p, sizeof(prli)); | ||
1139 | if (status == FC_STATUS_OK && p[1].code != LS_PRLI_ACC && p[1].code != LS_ACC) | ||
1140 | status = FC_STATUS_BAD_RSP; | ||
1141 | kfree(p); | ||
1142 | return status; | ||
1143 | } | ||
1144 | |||
1145 | MODULE_LICENSE("GPL"); | ||
1146 | |||
diff --git a/drivers/fc4/fc.h b/drivers/fc4/fc.h deleted file mode 100644 index 13f89d4c8cb9..000000000000 --- a/drivers/fc4/fc.h +++ /dev/null | |||
@@ -1,230 +0,0 @@ | |||
1 | /* fc.h: Definitions for Fibre Channel Physical and Signaling Interface. | ||
2 | * | ||
3 | * Copyright (C) 1996-1997,1999 Jakub Jelinek (jj@ultra.linux.cz) | ||
4 | * | ||
5 | * Sources: | ||
6 | * Fibre Channel Physical & Signaling Interface (FC-PH), dpANS, 1994 | ||
7 | * dpANS Fibre Channel Protocol for SCSI (X3.269-199X), Rev. 012, 1995 | ||
8 | */ | ||
9 | |||
10 | #ifndef __FC_H | ||
11 | #define __FC_H | ||
12 | |||
13 | /* World Wide Name */ | ||
14 | #define NAAID_IEEE 1 | ||
15 | #define NAAID_IEEE_EXT 2 | ||
16 | #define NAAID_LOCAL 3 | ||
17 | #define NAAID_IP 4 | ||
18 | #define NAAID_IEEE_REG 5 | ||
19 | #define NAAID_IEEE_REG_EXT 6 | ||
20 | #define NAAID_CCITT 12 | ||
21 | #define NAAID_CCITT_GRP 14 | ||
22 | |||
23 | /* This is NAAID_IEEE_EXT scheme */ | ||
24 | typedef struct { | ||
25 | u32 naaid:4; | ||
26 | u32 nportid:12; | ||
27 | u32 hi:16; | ||
28 | u32 lo; | ||
29 | } fc_wwn; | ||
30 | |||
31 | /* Frame header for FC-PH frames */ | ||
32 | |||
33 | /* r_ctl field */ | ||
34 | #define R_CTL_DEVICE_DATA 0x00 /* FC4 Device_Data frame */ | ||
35 | #define R_CTL_EXTENDED_SVC 0x20 /* Extended Link_Data frame */ | ||
36 | #define R_CTL_FC4_SVC 0x30 /* FC4 Link_Data frame */ | ||
37 | #define R_CTL_VIDEO 0x40 /* Video_Data frame */ | ||
38 | #define R_CTL_BASIC_SVC 0x80 /* Basic Link_Data frame */ | ||
39 | #define R_CTL_LINK_CTL 0xc0 /* Link_Control frame */ | ||
40 | /* FC4 Device_Data frames */ | ||
41 | #define R_CTL_UNCATEGORIZED 0x00 | ||
42 | #define R_CTL_SOLICITED_DATA 0x01 | ||
43 | #define R_CTL_UNSOL_CONTROL 0x02 | ||
44 | #define R_CTL_SOLICITED_CONTROL 0x03 | ||
45 | #define R_CTL_UNSOL_DATA 0x04 | ||
46 | #define R_CTL_XFER_RDY 0x05 | ||
47 | #define R_CTL_COMMAND 0x06 | ||
48 | #define R_CTL_STATUS 0x07 | ||
49 | /* Basic Link_Data frames */ | ||
50 | #define R_CTL_LS_NOP 0x80 | ||
51 | #define R_CTL_LS_ABTS 0x81 | ||
52 | #define R_CTL_LS_RMC 0x82 | ||
53 | #define R_CTL_LS_BA_ACC 0x84 | ||
54 | #define R_CTL_LS_BA_RJT 0x85 | ||
55 | /* Extended Link_Data frames */ | ||
56 | #define R_CTL_ELS_REQ 0x22 | ||
57 | #define R_CTL_ELS_RSP 0x23 | ||
58 | /* Link_Control frames */ | ||
59 | #define R_CTL_ACK_1 0xc0 | ||
60 | #define R_CTL_ACK_N 0xc1 | ||
61 | #define R_CTL_P_RJT 0xc2 | ||
62 | #define R_CTL_F_RJT 0xc3 | ||
63 | #define R_CTL_P_BSY 0xc4 | ||
64 | #define R_CTL_F_BSY_DF 0xc5 | ||
65 | #define R_CTL_F_BSY_LC 0xc6 | ||
66 | #define R_CTL_LCR 0xc7 | ||
67 | |||
68 | /* type field */ | ||
69 | #define TYPE_BASIC_LS 0x00 | ||
70 | #define TYPE_EXTENDED_LS 0x01 | ||
71 | #define TYPE_IS8802 0x04 | ||
72 | #define TYPE_IS8802_SNAP 0x05 | ||
73 | #define TYPE_SCSI_FCP 0x08 | ||
74 | #define TYPE_SCSI_GPP 0x09 | ||
75 | #define TYPE_HIPP_FP 0x0a | ||
76 | #define TYPE_IPI3_MASTER 0x11 | ||
77 | #define TYPE_IPI3_SLAVE 0x12 | ||
78 | #define TYPE_IPI3_PEER 0x13 | ||
79 | |||
80 | /* f_ctl field */ | ||
81 | #define F_CTL_FILL_BYTES 0x000003 | ||
82 | #define F_CTL_XCHG_REASSEMBLE 0x000004 | ||
83 | #define F_CTL_RO_PRESENT 0x000008 | ||
84 | #define F_CTL_ABORT_SEQ 0x000030 | ||
85 | #define F_CTL_CONTINUE_SEQ 0x0000c0 | ||
86 | #define F_CTL_INVALIDATE_XID 0x004000 | ||
87 | #define F_CTL_XID_REASSIGNED 0x008000 | ||
88 | #define F_CTL_SEQ_INITIATIVE 0x010000 | ||
89 | #define F_CTL_CHAINED_SEQ 0x020000 | ||
90 | #define F_CTL_END_CONNECT 0x040000 | ||
91 | #define F_CTL_END_SEQ 0x080000 | ||
92 | #define F_CTL_LAST_SEQ 0x100000 | ||
93 | #define F_CTL_FIRST_SEQ 0x200000 | ||
94 | #define F_CTL_SEQ_CONTEXT 0x400000 | ||
95 | #define F_CTL_XCHG_CONTEXT 0x800000 | ||
96 | |||
97 | typedef struct { | ||
98 | u32 r_ctl:8, did:24; | ||
99 | u32 xxx1:8, sid:24; | ||
100 | u32 type:8, f_ctl:24; | ||
101 | u32 seq_id:8, df_ctl:8, seq_cnt:16; | ||
102 | u16 ox_id, rx_id; | ||
103 | u32 param; | ||
104 | } fc_hdr; | ||
105 | /* The following are ugly macros to make setup of this structure faster */ | ||
106 | #define FILL_FCHDR_RCTL_DID(fch, r_ctl, did) *(u32 *)(fch) = ((r_ctl) << 24) | (did); | ||
107 | #define FILL_FCHDR_SID(fch, sid) *((u32 *)(fch)+1) = (sid); | ||
108 | #define FILL_FCHDR_TYPE_FCTL(fch, type, f_ctl) *((u32 *)(fch)+2) = ((type) << 24) | (f_ctl); | ||
109 | #define FILL_FCHDR_SEQ_DF_SEQ(fch, seq_id, df_ctl, seq_cnt) *((u32 *)(fch)+3) = ((seq_id) << 24) | ((df_ctl) << 16) | (seq_cnt); | ||
110 | #define FILL_FCHDR_OXRX(fch, ox_id, rx_id) *((u32 *)(fch)+4) = ((ox_id) << 16) | (rx_id); | ||
111 | |||
112 | /* Well known addresses */ | ||
113 | #define FS_GENERAL_MULTICAST 0xfffff7 | ||
114 | #define FS_WELL_KNOWN_MULTICAST 0xfffff8 | ||
115 | #define FS_HUNT_GROUP 0xfffff9 | ||
116 | #define FS_MANAGEMENT_SERVER 0xfffffa | ||
117 | #define FS_TIME_SERVER 0xfffffb | ||
118 | #define FS_NAME_SERVER 0xfffffc | ||
119 | #define FS_FABRIC_CONTROLLER 0xfffffd | ||
120 | #define FS_FABRIC_F_PORT 0xfffffe | ||
121 | #define FS_BROADCAST 0xffffff | ||
122 | |||
123 | /* Reject frames */ | ||
124 | /* The param field should be cast to this structure */ | ||
125 | typedef struct { | ||
126 | u8 action; | ||
127 | u8 reason; | ||
128 | u8 xxx; | ||
129 | u8 vendor_unique; | ||
130 | } rjt_param; | ||
131 | |||
132 | /* Reject action codes */ | ||
133 | #define RJT_RETRY 0x01 | ||
134 | #define RJT_NONRETRY 0x02 | ||
135 | |||
136 | /* Reject reason codes */ | ||
137 | #define RJT_INVALID_DID 0x01 | ||
138 | #define RJT_INVALID_SID 0x02 | ||
139 | #define RJT_NPORT_NOT_AVAIL_TEMP 0x03 | ||
140 | #define RJT_NPORT_NOT_AVAIL_PERM 0x04 | ||
141 | #define RJT_CLASS_NOT_SUPPORTED 0x05 | ||
142 | #define RJT_DELIMITER_ERROR 0x06 | ||
143 | #define RJT_TYPE_NOT_SUPPORTED 0x07 | ||
144 | #define RJT_INVALID_LINK_CONTROL 0x08 | ||
145 | #define RJT_INVALID_R_CTL 0x09 | ||
146 | #define RJT_INVALID_F_CTL 0x0a | ||
147 | #define RJT_INVALID_OX_ID 0x0b | ||
148 | #define RJT_INVALID_RX_ID 0x0c | ||
149 | #define RJT_INVALID_SEQ_ID 0x0d | ||
150 | #define RJT_INVALID_DF_CTL 0x0e | ||
151 | #define RJT_INVALID_SEQ_CNT 0x0f | ||
152 | #define RJT_INVALID_PARAMETER 0x10 | ||
153 | #define RJT_EXCHANGE_ERROR 0x11 | ||
154 | #define RJT_PROTOCOL_ERROR 0x12 | ||
155 | #define RJT_INCORRECT_LENGTH 0x13 | ||
156 | #define RJT_UNEXPECTED_ACK 0x14 | ||
157 | #define RJT_UNEXPECTED_LINK_RESP 0x15 | ||
158 | #define RJT_LOGIN_REQUIRED 0x16 | ||
159 | #define RJT_EXCESSIVE_SEQUENCES 0x17 | ||
160 | #define RJT_CANT_ESTABLISH_EXCHANGE 0x18 | ||
161 | #define RJT_SECURITY_NOT_SUPPORTED 0x19 | ||
162 | #define RJT_FABRIC_NA 0x1a | ||
163 | #define RJT_VENDOR_UNIQUE 0xff | ||
164 | |||
165 | |||
166 | #define SP_F_PORT_LOGIN 0x10 | ||
167 | |||
168 | /* Extended SVC commands */ | ||
169 | #define LS_RJT 0x01000000 | ||
170 | #define LS_ACC 0x02000000 | ||
171 | #define LS_PRLI_ACC 0x02100014 | ||
172 | #define LS_PLOGI 0x03000000 | ||
173 | #define LS_FLOGI 0x04000000 | ||
174 | #define LS_LOGO 0x05000000 | ||
175 | #define LS_ABTX 0x06000000 | ||
176 | #define LS_RCS 0x07000000 | ||
177 | #define LS_RES 0x08000000 | ||
178 | #define LS_RSS 0x09000000 | ||
179 | #define LS_RSI 0x0a000000 | ||
180 | #define LS_ESTS 0x0b000000 | ||
181 | #define LS_ESTC 0x0c000000 | ||
182 | #define LS_ADVC 0x0d000000 | ||
183 | #define LS_RTV 0x0e000000 | ||
184 | #define LS_RLS 0x0f000000 | ||
185 | #define LS_ECHO 0x10000000 | ||
186 | #define LS_TEST 0x11000000 | ||
187 | #define LS_RRQ 0x12000000 | ||
188 | #define LS_IDENT 0x20000000 | ||
189 | #define LS_PRLI 0x20100014 | ||
190 | #define LS_DISPLAY 0x21000000 | ||
191 | #define LS_PRLO 0x21100014 | ||
192 | #define LS_PDISC 0x50000000 | ||
193 | #define LS_ADISC 0x52000000 | ||
194 | |||
195 | typedef struct { | ||
196 | u8 fcph_hi, fcph_lo; | ||
197 | u16 buf2buf_credit; | ||
198 | u8 common_features; | ||
199 | u8 xxx1; | ||
200 | u16 buf2buf_size; | ||
201 | u8 xxx2; | ||
202 | u8 total_concurrent; | ||
203 | u16 off_by_info; | ||
204 | u32 e_d_tov; | ||
205 | } common_svc_parm; | ||
206 | |||
207 | typedef struct { | ||
208 | u16 serv_opts; | ||
209 | u16 initiator_ctl; | ||
210 | u16 rcpt_ctl; | ||
211 | u16 recv_size; | ||
212 | u8 xxx1; | ||
213 | u8 concurrent_seqs; | ||
214 | u16 end2end_credit; | ||
215 | u16 open_seqs_per_xchg; | ||
216 | u16 xxx2; | ||
217 | } svc_parm; | ||
218 | |||
219 | /* Login */ | ||
220 | typedef struct { | ||
221 | u32 code; | ||
222 | common_svc_parm common; | ||
223 | fc_wwn nport_wwn; | ||
224 | fc_wwn node_wwn; | ||
225 | svc_parm class1; | ||
226 | svc_parm class2; | ||
227 | svc_parm class3; | ||
228 | } logi; | ||
229 | |||
230 | #endif /* !(__FC_H) */ | ||
diff --git a/drivers/fc4/fc_syms.c b/drivers/fc4/fc_syms.c deleted file mode 100644 index bd3918ddf7ac..000000000000 --- a/drivers/fc4/fc_syms.c +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | /* | ||
2 | * We should not even be trying to compile this if we are not doing | ||
3 | * a module. | ||
4 | */ | ||
5 | #include <linux/module.h> | ||
6 | |||
7 | #ifdef CONFIG_MODULES | ||
8 | |||
9 | #include <linux/types.h> | ||
10 | #include <linux/string.h> | ||
11 | #include <linux/kernel.h> | ||
12 | |||
13 | #include "fcp_impl.h" | ||
14 | |||
15 | EXPORT_SYMBOL(fcp_init); | ||
16 | EXPORT_SYMBOL(fcp_release); | ||
17 | EXPORT_SYMBOL(fcp_queue_empty); | ||
18 | EXPORT_SYMBOL(fcp_receive_solicited); | ||
19 | EXPORT_SYMBOL(fc_channels); | ||
20 | EXPORT_SYMBOL(fcp_state_change); | ||
21 | EXPORT_SYMBOL(fc_do_plogi); | ||
22 | EXPORT_SYMBOL(fc_do_prli); | ||
23 | |||
24 | /* SCSI stuff */ | ||
25 | EXPORT_SYMBOL(fcp_scsi_queuecommand); | ||
26 | EXPORT_SYMBOL(fcp_scsi_abort); | ||
27 | EXPORT_SYMBOL(fcp_scsi_dev_reset); | ||
28 | EXPORT_SYMBOL(fcp_scsi_host_reset); | ||
29 | |||
30 | #endif /* CONFIG_MODULES */ | ||
diff --git a/drivers/fc4/fcp.h b/drivers/fc4/fcp.h deleted file mode 100644 index 6aa34a7a4c11..000000000000 --- a/drivers/fc4/fcp.h +++ /dev/null | |||
@@ -1,94 +0,0 @@ | |||
1 | /* fcp.h: Definitions for Fibre Channel Protocol. | ||
2 | * | ||
3 | * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
4 | * | ||
5 | */ | ||
6 | |||
7 | #ifndef __FCP_H | ||
8 | #define __FCP_H | ||
9 | |||
10 | /* FCP addressing is hierarchical with up to 4 layers, MS first. | ||
11 | Exact meaning of the addresses is up to the vendor */ | ||
12 | |||
13 | /* fcp_cntl field */ | ||
14 | #define FCP_CNTL_WRITE 0x00000001 /* Initiator write */ | ||
15 | #define FCP_CNTL_READ 0x00000002 /* Initiator read */ | ||
16 | #define FCP_CNTL_ABORT_TSK 0x00000200 /* Abort task set */ | ||
17 | #define FCP_CNTL_CLR_TASK 0x00000400 /* Clear task set */ | ||
18 | #define FCP_CNTL_RESET 0x00002000 /* Reset */ | ||
19 | #define FCP_CNTL_CLR_ACA 0x00004000 /* Clear ACA */ | ||
20 | #define FCP_CNTL_KILL_TASK 0x00008000 /* Terminate task */ | ||
21 | #define FCP_CNTL_QTYPE_MASK 0x00070000 /* Tagged queueing type */ | ||
22 | #define FCP_CNTL_QTYPE_SIMPLE 0x00000000 | ||
23 | #define FCP_CNTL_QTYPE_HEAD_OF_Q 0x00010000 | ||
24 | #define FCP_CNTL_QTYPE_ORDERED 0x00020000 | ||
25 | #define FCP_CNTL_QTYPE_ACA_Q_TAG 0x00040000 | ||
26 | #define FCP_CNTL_QTYPE_UNTAGGED 0x00050000 | ||
27 | |||
28 | typedef struct { | ||
29 | u16 fcp_addr[4]; | ||
30 | u32 fcp_cntl; | ||
31 | u8 fcp_cdb[16]; | ||
32 | u32 fcp_data_len; | ||
33 | } fcp_cmd; | ||
34 | |||
35 | /* fcp_status field */ | ||
36 | #define FCP_STATUS_MASK 0x000000ff /* scsi status of command */ | ||
37 | #define FCP_STATUS_RSP_LEN 0x00000100 /* response_len != 0 */ | ||
38 | #define FCP_STATUS_SENSE_LEN 0x00000200 /* sense_len != 0 */ | ||
39 | #define FCP_STATUS_RESID 0x00000400 /* resid != 0 */ | ||
40 | |||
41 | typedef struct { | ||
42 | u32 xxx[2]; | ||
43 | u32 fcp_status; | ||
44 | u32 fcp_resid; | ||
45 | u32 fcp_sense_len; | ||
46 | u32 fcp_response_len; | ||
47 | /* u8 fcp_sense[fcp_sense_len]; */ | ||
48 | /* u8 fcp_response[fcp_response_len]; */ | ||
49 | } fcp_rsp; | ||
50 | |||
51 | /* fcp errors */ | ||
52 | |||
53 | /* rsp_info_type field */ | ||
54 | #define FCP_RSP_SCSI_BUS_ERR 0x01 | ||
55 | #define FCP_RSP_SCSI_PORT_ERR 0x02 | ||
56 | #define FCP_RSP_CARD_ERR 0x03 | ||
57 | |||
58 | /* isp_status field */ | ||
59 | #define FCP_RSP_CMD_COMPLETE 0x0000 | ||
60 | #define FCP_RSP_CMD_INCOMPLETE 0x0001 | ||
61 | #define FCP_RSP_CMD_DMA_ERR 0x0002 | ||
62 | #define FCP_RSP_CMD_TRAN_ERR 0x0003 | ||
63 | #define FCP_RSP_CMD_RESET 0x0004 | ||
64 | #define FCP_RSP_CMD_ABORTED 0x0005 | ||
65 | #define FCP_RSP_CMD_TIMEOUT 0x0006 | ||
66 | #define FCP_RSP_CMD_OVERRUN 0x0007 | ||
67 | |||
68 | /* isp_state_flags field */ | ||
69 | #define FCP_RSP_ST_GOT_BUS 0x0100 | ||
70 | #define FCP_RSP_ST_GOT_TARGET 0x0200 | ||
71 | #define FCP_RSP_ST_SENT_CMD 0x0400 | ||
72 | #define FCP_RSP_ST_XFRD_DATA 0x0800 | ||
73 | #define FCP_RSP_ST_GOT_STATUS 0x1000 | ||
74 | #define FCP_RSP_ST_GOT_SENSE 0x2000 | ||
75 | |||
76 | /* isp_stat_flags field */ | ||
77 | #define FCP_RSP_STAT_DISC 0x0001 | ||
78 | #define FCP_RSP_STAT_SYNC 0x0002 | ||
79 | #define FCP_RSP_STAT_PERR 0x0004 | ||
80 | #define FCP_RSP_STAT_BUS_RESET 0x0008 | ||
81 | #define FCP_RSP_STAT_DEV_RESET 0x0010 | ||
82 | #define FCP_RSP_STAT_ABORTED 0x0020 | ||
83 | #define FCP_RSP_STAT_TIMEOUT 0x0040 | ||
84 | #define FCP_RSP_STAT_NEGOTIATE 0x0080 | ||
85 | |||
86 | typedef struct { | ||
87 | u8 rsp_info_type; | ||
88 | u8 xxx; | ||
89 | u16 isp_status; | ||
90 | u16 isp_state_flags; | ||
91 | u16 isp_stat_flags; | ||
92 | } fcp_scsi_err; | ||
93 | |||
94 | #endif /* !(__FCP_H) */ | ||
diff --git a/drivers/fc4/fcp_impl.h b/drivers/fc4/fcp_impl.h deleted file mode 100644 index 506338a461ba..000000000000 --- a/drivers/fc4/fcp_impl.h +++ /dev/null | |||
@@ -1,164 +0,0 @@ | |||
1 | /* fcp_impl.h: Generic SCSI on top of FC4 - our interface defines. | ||
2 | * | ||
3 | * Copyright (C) 1997-1999 Jakub Jelinek (jj@ultra.linux.cz) | ||
4 | * Copyright (C) 1998 Jirka Hanika (geo@ff.cuni.cz) | ||
5 | */ | ||
6 | |||
7 | #ifndef _FCP_SCSI_H | ||
8 | #define _FCP_SCSI_H | ||
9 | |||
10 | #include <linux/types.h> | ||
11 | #include "../scsi/scsi.h" | ||
12 | |||
13 | #include "fc.h" | ||
14 | #include "fcp.h" | ||
15 | #include "fc-al.h" | ||
16 | |||
17 | #include <asm/io.h> | ||
18 | #ifdef __sparc__ | ||
19 | #include <asm/sbus.h> | ||
20 | #endif | ||
21 | |||
22 | /* 0 or 1 */ | ||
23 | #define FCP_SCSI_USE_NEW_EH_CODE 0 | ||
24 | |||
25 | #define FC_CLASS_OUTBOUND 0x01 | ||
26 | #define FC_CLASS_INBOUND 0x02 | ||
27 | #define FC_CLASS_SIMPLE 0x03 | ||
28 | #define FC_CLASS_IO_WRITE 0x04 | ||
29 | #define FC_CLASS_IO_READ 0x05 | ||
30 | #define FC_CLASS_UNSOLICITED 0x06 | ||
31 | #define FC_CLASS_OFFLINE 0x08 | ||
32 | |||
33 | #define PROTO_OFFLINE 0x02 | ||
34 | #define PROTO_REPORT_AL_MAP 0x03 | ||
35 | #define PROTO_FORCE_LIP 0x06 | ||
36 | |||
37 | struct _fc_channel; | ||
38 | |||
39 | typedef struct fcp_cmnd { | ||
40 | struct fcp_cmnd *next; | ||
41 | struct fcp_cmnd *prev; | ||
42 | void (*done)(struct scsi_cmnd *); | ||
43 | unsigned short proto; | ||
44 | unsigned short token; | ||
45 | unsigned int did; | ||
46 | /* FCP SCSI stuff */ | ||
47 | dma_addr_t data; | ||
48 | /* From now on this cannot be touched for proto == TYPE_SCSI_FCP */ | ||
49 | fc_hdr fch; | ||
50 | dma_addr_t cmd; | ||
51 | dma_addr_t rsp; | ||
52 | int cmdlen; | ||
53 | int rsplen; | ||
54 | int class; | ||
55 | int datalen; | ||
56 | /* This is just used as a verification during login */ | ||
57 | struct _fc_channel *fc; | ||
58 | void *ls; | ||
59 | } fcp_cmnd; | ||
60 | |||
61 | typedef struct { | ||
62 | unsigned int len; | ||
63 | unsigned char list[0]; | ||
64 | } fcp_posmap; | ||
65 | |||
66 | typedef struct _fc_channel { | ||
67 | struct _fc_channel *next; | ||
68 | int irq; | ||
69 | int state; | ||
70 | int sid; | ||
71 | int did; | ||
72 | char name[16]; | ||
73 | void (*fcp_register)(struct _fc_channel *, u8, int); | ||
74 | void (*reset)(struct _fc_channel *); | ||
75 | int (*hw_enque)(struct _fc_channel *, fcp_cmnd *); | ||
76 | fc_wwn wwn_node; | ||
77 | fc_wwn wwn_nport; | ||
78 | fc_wwn wwn_dest; | ||
79 | common_svc_parm *common_svc; | ||
80 | svc_parm *class_svcs; | ||
81 | #ifdef __sparc__ | ||
82 | struct sbus_dev *dev; | ||
83 | #else | ||
84 | struct pci_dev *dev; | ||
85 | #endif | ||
86 | struct module *module; | ||
87 | /* FCP SCSI stuff */ | ||
88 | short can_queue; | ||
89 | short abort_count; | ||
90 | int rsp_size; | ||
91 | fcp_cmd *scsi_cmd_pool; | ||
92 | char *scsi_rsp_pool; | ||
93 | dma_addr_t dma_scsi_cmd, dma_scsi_rsp; | ||
94 | unsigned long *scsi_bitmap; | ||
95 | long scsi_bitmap_end; | ||
96 | int scsi_free; | ||
97 | int (*encode_addr)(struct scsi_cmnd *, u16 *, struct _fc_channel *, fcp_cmnd *); | ||
98 | fcp_cmnd *scsi_que; | ||
99 | char scsi_name[4]; | ||
100 | fcp_cmnd **cmd_slots; | ||
101 | int channels; | ||
102 | int targets; | ||
103 | long *ages; | ||
104 | struct scsi_cmnd *rst_pkt; | ||
105 | fcp_posmap *posmap; | ||
106 | /* LOGIN stuff */ | ||
107 | fcp_cmnd *login; | ||
108 | void *ls; | ||
109 | } fc_channel; | ||
110 | |||
111 | extern fc_channel *fc_channels; | ||
112 | |||
113 | #define FC_STATE_UNINITED 0 | ||
114 | #define FC_STATE_ONLINE 1 | ||
115 | #define FC_STATE_OFFLINE 2 | ||
116 | #define FC_STATE_RESETING 3 | ||
117 | #define FC_STATE_FPORT_OK 4 | ||
118 | #define FC_STATE_MAYBEOFFLINE 5 | ||
119 | |||
120 | #define FC_STATUS_OK 0 | ||
121 | #define FC_STATUS_P_RJT 2 | ||
122 | #define FC_STATUS_F_RJT 3 | ||
123 | #define FC_STATUS_P_BSY 4 | ||
124 | #define FC_STATUS_F_BSY 5 | ||
125 | #define FC_STATUS_ERR_OFFLINE 0x11 | ||
126 | #define FC_STATUS_TIMEOUT 0x12 | ||
127 | #define FC_STATUS_ERR_OVERRUN 0x13 | ||
128 | #define FC_STATUS_POINTTOPOINT 0x15 | ||
129 | #define FC_STATUS_AL 0x16 | ||
130 | #define FC_STATUS_UNKNOWN_CQ_TYPE 0x20 | ||
131 | #define FC_STATUS_BAD_SEG_CNT 0x21 | ||
132 | #define FC_STATUS_MAX_XCHG_EXCEEDED 0x22 | ||
133 | #define FC_STATUS_BAD_XID 0x23 | ||
134 | #define FC_STATUS_XCHG_BUSY 0x24 | ||
135 | #define FC_STATUS_BAD_POOL_ID 0x25 | ||
136 | #define FC_STATUS_INSUFFICIENT_CQES 0x26 | ||
137 | #define FC_STATUS_ALLOC_FAIL 0x27 | ||
138 | #define FC_STATUS_BAD_SID 0x28 | ||
139 | #define FC_STATUS_NO_SEQ_INIT 0x29 | ||
140 | #define FC_STATUS_TIMED_OUT -1 | ||
141 | #define FC_STATUS_BAD_RSP -2 | ||
142 | |||
143 | void fcp_queue_empty(fc_channel *); | ||
144 | int fcp_init(fc_channel *); | ||
145 | void fcp_release(fc_channel *fc_chain, int count); | ||
146 | void fcp_receive_solicited(fc_channel *, int, int, int, fc_hdr *); | ||
147 | void fcp_state_change(fc_channel *, int); | ||
148 | int fc_do_plogi(fc_channel *, unsigned char, fc_wwn *, fc_wwn *); | ||
149 | int fc_do_prli(fc_channel *, unsigned char); | ||
150 | |||
151 | #define for_each_fc_channel(fc) \ | ||
152 | for (fc = fc_channels; fc; fc = fc->next) | ||
153 | |||
154 | #define for_each_online_fc_channel(fc) \ | ||
155 | for_each_fc_channel(fc) \ | ||
156 | if (fc->state == FC_STATE_ONLINE) | ||
157 | |||
158 | int fcp_scsi_queuecommand(struct scsi_cmnd *, | ||
159 | void (* done) (struct scsi_cmnd *)); | ||
160 | int fcp_scsi_abort(struct scsi_cmnd *); | ||
161 | int fcp_scsi_dev_reset(struct scsi_cmnd *); | ||
162 | int fcp_scsi_host_reset(struct scsi_cmnd *); | ||
163 | |||
164 | #endif /* !(_FCP_SCSI_H) */ | ||
diff --git a/drivers/fc4/soc.c b/drivers/fc4/soc.c deleted file mode 100644 index d517734462e6..000000000000 --- a/drivers/fc4/soc.c +++ /dev/null | |||
@@ -1,764 +0,0 @@ | |||
1 | /* soc.c: Sparc SUNW,soc (Serial Optical Channel) Fibre Channel Sbus adapter support. | ||
2 | * | ||
3 | * Copyright (C) 1996,1997,1999 Jakub Jelinek (jj@ultra.linux.cz) | ||
4 | * Copyright (C) 1997,1998 Jirka Hanika (geo@ff.cuni.cz) | ||
5 | * | ||
6 | * Sources: | ||
7 | * Fibre Channel Physical & Signaling Interface (FC-PH), dpANS, 1994 | ||
8 | * dpANS Fibre Channel Protocol for SCSI (X3.269-199X), Rev. 012, 1995 | ||
9 | * | ||
10 | * Supported hardware: | ||
11 | * Tested on SOC sbus card bought with SS1000 in Linux running on SS5 and Ultra1. | ||
12 | * For SOC sbus cards, you have to make sure your FCode is 1.52 or later. | ||
13 | * If you have older FCode, you should try to upgrade or get SOC microcode from Sun | ||
14 | * (the microcode is present in Solaris soc driver as well). In that case you need | ||
15 | * to #define HAVE_SOC_UCODE and format the microcode into soc_asm.c. For the exact | ||
16 | * format mail me and I will tell you. I cannot offer you the actual microcode though, | ||
17 | * unless Sun confirms they don't mind. | ||
18 | */ | ||
19 | |||
20 | static char *version = | ||
21 | "soc.c:v1.3 9/Feb/99 Jakub Jelinek (jj@ultra.linux.cz), Jirka Hanika (geo@ff.cuni.cz)\n"; | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/types.h> | ||
26 | #include <linux/fcntl.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/ptrace.h> | ||
29 | #include <linux/ioport.h> | ||
30 | #include <linux/in.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <linux/string.h> | ||
33 | #include <linux/init.h> | ||
34 | #include <linux/bitops.h> | ||
35 | #include <asm/io.h> | ||
36 | #include <asm/dma.h> | ||
37 | #include <linux/errno.h> | ||
38 | #include <asm/byteorder.h> | ||
39 | |||
40 | #include <asm/openprom.h> | ||
41 | #include <asm/oplib.h> | ||
42 | #include <asm/pgtable.h> | ||
43 | #include <asm/irq.h> | ||
44 | |||
45 | /* #define SOCDEBUG */ | ||
46 | /* #define HAVE_SOC_UCODE */ | ||
47 | |||
48 | #include "fcp_impl.h" | ||
49 | #include "soc.h" | ||
50 | #ifdef HAVE_SOC_UCODE | ||
51 | #include "soc_asm.h" | ||
52 | #endif | ||
53 | |||
54 | #define soc_printk printk ("soc%d: ", s->soc_no); printk | ||
55 | |||
56 | #ifdef SOCDEBUG | ||
57 | #define SOD(x) soc_printk x; | ||
58 | #else | ||
59 | #define SOD(x) | ||
60 | #endif | ||
61 | |||
62 | #define for_each_soc(s) for (s = socs; s; s = s->next) | ||
63 | struct soc *socs = NULL; | ||
64 | |||
65 | static inline void soc_disable(struct soc *s) | ||
66 | { | ||
67 | sbus_writel(0, s->regs + IMASK); | ||
68 | sbus_writel(SOC_CMD_SOFT_RESET, s->regs + CMD); | ||
69 | } | ||
70 | |||
71 | static inline void soc_enable(struct soc *s) | ||
72 | { | ||
73 | SOD(("enable %08x\n", s->cfg)) | ||
74 | sbus_writel(0, s->regs + SAE); | ||
75 | sbus_writel(s->cfg, s->regs + CFG); | ||
76 | sbus_writel(SOC_CMD_RSP_QALL, s->regs + CMD); | ||
77 | SOC_SETIMASK(s, SOC_IMASK_RSP_QALL | SOC_IMASK_SAE); | ||
78 | SOD(("imask %08lx %08lx\n", s->imask, sbus_readl(s->regs + IMAK))); | ||
79 | } | ||
80 | |||
81 | static void soc_reset(fc_channel *fc) | ||
82 | { | ||
83 | soc_port *port = (soc_port *)fc; | ||
84 | struct soc *s = port->s; | ||
85 | |||
86 | /* FIXME */ | ||
87 | soc_disable(s); | ||
88 | s->req[0].seqno = 1; | ||
89 | s->req[1].seqno = 1; | ||
90 | s->rsp[0].seqno = 1; | ||
91 | s->rsp[1].seqno = 1; | ||
92 | s->req[0].in = 0; | ||
93 | s->req[1].in = 0; | ||
94 | s->rsp[0].in = 0; | ||
95 | s->rsp[1].in = 0; | ||
96 | s->req[0].out = 0; | ||
97 | s->req[1].out = 0; | ||
98 | s->rsp[0].out = 0; | ||
99 | s->rsp[1].out = 0; | ||
100 | |||
101 | /* FIXME */ | ||
102 | soc_enable(s); | ||
103 | } | ||
104 | |||
105 | static inline void soc_solicited (struct soc *s) | ||
106 | { | ||
107 | fc_hdr fchdr; | ||
108 | soc_rsp __iomem *hwrsp; | ||
109 | soc_cq_rsp *sw_cq; | ||
110 | int token; | ||
111 | int status; | ||
112 | fc_channel *fc; | ||
113 | |||
114 | sw_cq = &s->rsp[SOC_SOLICITED_RSP_Q]; | ||
115 | |||
116 | if (sw_cq->pool == NULL) | ||
117 | sw_cq->pool = (soc_req __iomem *) | ||
118 | (s->xram + xram_get_32low ((xram_p)&sw_cq->hw_cq->address)); | ||
119 | sw_cq->in = xram_get_8 ((xram_p)&sw_cq->hw_cq->in); | ||
120 | SOD (("soc_solicited, %d pkts arrived\n", (sw_cq->in-sw_cq->out) & sw_cq->last)) | ||
121 | for (;;) { | ||
122 | hwrsp = (soc_rsp __iomem *)sw_cq->pool + sw_cq->out; | ||
123 | token = xram_get_32low ((xram_p)&hwrsp->shdr.token); | ||
124 | status = xram_get_32low ((xram_p)&hwrsp->status); | ||
125 | fc = (fc_channel *)(&s->port[(token >> 11) & 1]); | ||
126 | |||
127 | if (status == SOC_OK) { | ||
128 | fcp_receive_solicited(fc, token >> 12, | ||
129 | token & ((1 << 11) - 1), | ||
130 | FC_STATUS_OK, NULL); | ||
131 | } else { | ||
132 | xram_copy_from(&fchdr, (xram_p)&hwrsp->fchdr, sizeof(fchdr)); | ||
133 | /* We have intentionally defined FC_STATUS_* constants | ||
134 | * to match SOC_* constants, otherwise we'd have to | ||
135 | * translate status. | ||
136 | */ | ||
137 | fcp_receive_solicited(fc, token >> 12, | ||
138 | token & ((1 << 11) - 1), | ||
139 | status, &fchdr); | ||
140 | } | ||
141 | |||
142 | if (++sw_cq->out > sw_cq->last) { | ||
143 | sw_cq->seqno++; | ||
144 | sw_cq->out = 0; | ||
145 | } | ||
146 | |||
147 | if (sw_cq->out == sw_cq->in) { | ||
148 | sw_cq->in = xram_get_8 ((xram_p)&sw_cq->hw_cq->in); | ||
149 | if (sw_cq->out == sw_cq->in) { | ||
150 | /* Tell the hardware about it */ | ||
151 | sbus_writel((sw_cq->out << 24) | | ||
152 | (SOC_CMD_RSP_QALL & | ||
153 | ~(SOC_CMD_RSP_Q0 << SOC_SOLICITED_RSP_Q)), | ||
154 | s->regs + CMD); | ||
155 | |||
156 | /* Read it, so that we're sure it has been updated */ | ||
157 | sbus_readl(s->regs + CMD); | ||
158 | sw_cq->in = xram_get_8 ((xram_p)&sw_cq->hw_cq->in); | ||
159 | if (sw_cq->out == sw_cq->in) | ||
160 | break; | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | } | ||
165 | |||
166 | static inline void soc_request (struct soc *s, u32 cmd) | ||
167 | { | ||
168 | SOC_SETIMASK(s, s->imask & ~(cmd & SOC_CMD_REQ_QALL)); | ||
169 | SOD(("imask %08lx %08lx\n", s->imask, sbus_readl(s->regs + IMASK))); | ||
170 | |||
171 | SOD(("Queues available %08x OUT %X %X\n", cmd, | ||
172 | xram_get_8((xram_p)&s->req[0].hw_cq->out), | ||
173 | xram_get_8((xram_p)&s->req[0].hw_cq->out))) | ||
174 | if (s->port[s->curr_port].fc.state != FC_STATE_OFFLINE) { | ||
175 | fcp_queue_empty ((fc_channel *)&(s->port[s->curr_port])); | ||
176 | if (((s->req[1].in + 1) & s->req[1].last) != (s->req[1].out)) | ||
177 | fcp_queue_empty ((fc_channel *)&(s->port[1 - s->curr_port])); | ||
178 | } else { | ||
179 | fcp_queue_empty ((fc_channel *)&(s->port[1 - s->curr_port])); | ||
180 | } | ||
181 | if (s->port[1 - s->curr_port].fc.state != FC_STATE_OFFLINE) | ||
182 | s->curr_port ^= 1; | ||
183 | } | ||
184 | |||
185 | static inline void soc_unsolicited (struct soc *s) | ||
186 | { | ||
187 | soc_rsp __iomem *hwrsp, *hwrspc; | ||
188 | soc_cq_rsp *sw_cq; | ||
189 | int count; | ||
190 | int status; | ||
191 | int flags; | ||
192 | fc_channel *fc; | ||
193 | |||
194 | sw_cq = &s->rsp[SOC_UNSOLICITED_RSP_Q]; | ||
195 | if (sw_cq->pool == NULL) | ||
196 | sw_cq->pool = (soc_req __iomem *) | ||
197 | (s->xram + (xram_get_32low ((xram_p)&sw_cq->hw_cq->address))); | ||
198 | |||
199 | sw_cq->in = xram_get_8 ((xram_p)&sw_cq->hw_cq->in); | ||
200 | SOD (("soc_unsolicited, %d packets arrived\n", (sw_cq->in - sw_cq->out) & sw_cq->last)) | ||
201 | while (sw_cq->in != sw_cq->out) { | ||
202 | /* ...real work per entry here... */ | ||
203 | hwrsp = (soc_rsp __iomem *)sw_cq->pool + sw_cq->out; | ||
204 | |||
205 | hwrspc = NULL; | ||
206 | flags = xram_get_16 ((xram_p)&hwrsp->shdr.flags); | ||
207 | count = xram_get_8 ((xram_p)&hwrsp->count); | ||
208 | fc = (fc_channel *)&s->port[flags & SOC_PORT_B]; | ||
209 | SOD(("FC %08lx fcp_state_change %08lx\n", | ||
210 | (long)fc, (long)fc->fcp_state_change)) | ||
211 | |||
212 | if (count != 1) { | ||
213 | /* Ugh, continuation entries */ | ||
214 | u8 in; | ||
215 | |||
216 | if (count != 2) { | ||
217 | printk("%s: Too many continuations entries %d\n", | ||
218 | fc->name, count); | ||
219 | goto update_out; | ||
220 | } | ||
221 | |||
222 | in = sw_cq->in; | ||
223 | if (in < sw_cq->out) in += sw_cq->last + 1; | ||
224 | if (in < sw_cq->out + 2) { | ||
225 | /* Ask the hardware if they haven't arrived yet. */ | ||
226 | sbus_writel((sw_cq->out << 24) | | ||
227 | (SOC_CMD_RSP_QALL & | ||
228 | ~(SOC_CMD_RSP_Q0 << SOC_UNSOLICITED_RSP_Q)), | ||
229 | s->regs + CMD); | ||
230 | |||
231 | /* Read it, so that we're sure it has been updated */ | ||
232 | sbus_readl(s->regs + CMD); | ||
233 | sw_cq->in = xram_get_8 ((xram_p)&sw_cq->hw_cq->in); | ||
234 | in = sw_cq->in; | ||
235 | if (in < sw_cq->out) | ||
236 | in += sw_cq->last + 1; | ||
237 | if (in < sw_cq->out + 2) /* Nothing came, let us wait */ | ||
238 | return; | ||
239 | } | ||
240 | if (sw_cq->out == sw_cq->last) | ||
241 | hwrspc = (soc_rsp __iomem *)sw_cq->pool; | ||
242 | else | ||
243 | hwrspc = hwrsp + 1; | ||
244 | } | ||
245 | |||
246 | switch (flags & ~SOC_PORT_B) { | ||
247 | case SOC_STATUS: | ||
248 | status = xram_get_32low ((xram_p)&hwrsp->status); | ||
249 | switch (status) { | ||
250 | case SOC_ONLINE: | ||
251 | SOD(("State change to ONLINE\n")); | ||
252 | fcp_state_change(fc, FC_STATE_ONLINE); | ||
253 | break; | ||
254 | case SOC_OFFLINE: | ||
255 | SOD(("State change to OFFLINE\n")); | ||
256 | fcp_state_change(fc, FC_STATE_OFFLINE); | ||
257 | break; | ||
258 | default: | ||
259 | printk ("%s: Unknown STATUS no %d\n", | ||
260 | fc->name, status); | ||
261 | break; | ||
262 | } | ||
263 | break; | ||
264 | case (SOC_UNSOLICITED|SOC_FC_HDR): | ||
265 | { | ||
266 | int r_ctl = xram_get_8 ((xram_p)&hwrsp->fchdr); | ||
267 | unsigned len; | ||
268 | char buf[64]; | ||
269 | |||
270 | if ((r_ctl & 0xf0) == R_CTL_EXTENDED_SVC) { | ||
271 | len = xram_get_32 ((xram_p)&hwrsp->shdr.bytecnt); | ||
272 | if (len < 4 || !hwrspc) { | ||
273 | printk ("%s: Invalid R_CTL %02x " | ||
274 | "continuation entries\n", | ||
275 | fc->name, r_ctl); | ||
276 | } else { | ||
277 | if (len > 60) | ||
278 | len = 60; | ||
279 | xram_copy_from (buf, (xram_p)hwrspc, | ||
280 | (len + 3) & ~3); | ||
281 | if (*(u32 *)buf == LS_DISPLAY) { | ||
282 | int i; | ||
283 | |||
284 | for (i = 4; i < len; i++) | ||
285 | if (buf[i] == '\n') | ||
286 | buf[i] = ' '; | ||
287 | buf[len] = 0; | ||
288 | printk ("%s message: %s\n", | ||
289 | fc->name, buf + 4); | ||
290 | } else { | ||
291 | printk ("%s: Unknown LS_CMD " | ||
292 | "%02x\n", fc->name, | ||
293 | buf[0]); | ||
294 | } | ||
295 | } | ||
296 | } else { | ||
297 | printk ("%s: Unsolicited R_CTL %02x " | ||
298 | "not handled\n", fc->name, r_ctl); | ||
299 | } | ||
300 | } | ||
301 | break; | ||
302 | default: | ||
303 | printk ("%s: Unexpected flags %08x\n", fc->name, flags); | ||
304 | break; | ||
305 | }; | ||
306 | update_out: | ||
307 | if (++sw_cq->out > sw_cq->last) { | ||
308 | sw_cq->seqno++; | ||
309 | sw_cq->out = 0; | ||
310 | } | ||
311 | |||
312 | if (hwrspc) { | ||
313 | if (++sw_cq->out > sw_cq->last) { | ||
314 | sw_cq->seqno++; | ||
315 | sw_cq->out = 0; | ||
316 | } | ||
317 | } | ||
318 | |||
319 | if (sw_cq->out == sw_cq->in) { | ||
320 | sw_cq->in = xram_get_8 ((xram_p)&sw_cq->hw_cq->in); | ||
321 | if (sw_cq->out == sw_cq->in) { | ||
322 | /* Tell the hardware about it */ | ||
323 | sbus_writel((sw_cq->out << 24) | | ||
324 | (SOC_CMD_RSP_QALL & | ||
325 | ~(SOC_CMD_RSP_Q0 << SOC_UNSOLICITED_RSP_Q)), | ||
326 | s->regs + CMD); | ||
327 | |||
328 | /* Read it, so that we're sure it has been updated */ | ||
329 | sbus_readl(s->regs + CMD); | ||
330 | sw_cq->in = xram_get_8 ((xram_p)&sw_cq->hw_cq->in); | ||
331 | } | ||
332 | } | ||
333 | } | ||
334 | } | ||
335 | |||
336 | static irqreturn_t soc_intr(int irq, void *dev_id) | ||
337 | { | ||
338 | u32 cmd; | ||
339 | unsigned long flags; | ||
340 | register struct soc *s = (struct soc *)dev_id; | ||
341 | |||
342 | spin_lock_irqsave(&s->lock, flags); | ||
343 | cmd = sbus_readl(s->regs + CMD); | ||
344 | for (; (cmd = SOC_INTR (s, cmd)); cmd = sbus_readl(s->regs + CMD)) { | ||
345 | if (cmd & SOC_CMD_RSP_Q1) soc_unsolicited (s); | ||
346 | if (cmd & SOC_CMD_RSP_Q0) soc_solicited (s); | ||
347 | if (cmd & SOC_CMD_REQ_QALL) soc_request (s, cmd); | ||
348 | } | ||
349 | spin_unlock_irqrestore(&s->lock, flags); | ||
350 | |||
351 | return IRQ_HANDLED; | ||
352 | } | ||
353 | |||
354 | #define TOKEN(proto, port, token) (((proto)<<12)|(token)|(port)) | ||
355 | |||
356 | static int soc_hw_enque (fc_channel *fc, fcp_cmnd *fcmd) | ||
357 | { | ||
358 | soc_port *port = (soc_port *)fc; | ||
359 | struct soc *s = port->s; | ||
360 | int qno; | ||
361 | soc_cq_req *sw_cq; | ||
362 | int cq_next_in; | ||
363 | soc_req *request; | ||
364 | fc_hdr *fch; | ||
365 | int i; | ||
366 | |||
367 | if (fcmd->proto == TYPE_SCSI_FCP) | ||
368 | qno = 1; | ||
369 | else | ||
370 | qno = 0; | ||
371 | SOD(("Putting a FCP packet type %d into hw queue %d\n", fcmd->proto, qno)) | ||
372 | if (s->imask & (SOC_IMASK_REQ_Q0 << qno)) { | ||
373 | SOD(("EIO %08x\n", s->imask)) | ||
374 | return -EIO; | ||
375 | } | ||
376 | sw_cq = s->req + qno; | ||
377 | cq_next_in = (sw_cq->in + 1) & sw_cq->last; | ||
378 | |||
379 | if (cq_next_in == sw_cq->out && | ||
380 | cq_next_in == (sw_cq->out = xram_get_8((xram_p)&sw_cq->hw_cq->out))) { | ||
381 | SOD(("%d IN %d OUT %d LAST %d\n", qno, sw_cq->in, sw_cq->out, sw_cq->last)) | ||
382 | SOC_SETIMASK(s, s->imask | (SOC_IMASK_REQ_Q0 << qno)); | ||
383 | SOD(("imask %08lx %08lx\n", s->imask, sbus_readl(s->regs + IMASK))); | ||
384 | /* If queue is full, just say NO */ | ||
385 | return -EBUSY; | ||
386 | } | ||
387 | |||
388 | request = sw_cq->pool + sw_cq->in; | ||
389 | fch = &request->fchdr; | ||
390 | |||
391 | switch (fcmd->proto) { | ||
392 | case TYPE_SCSI_FCP: | ||
393 | request->shdr.token = TOKEN(TYPE_SCSI_FCP, port->mask, fcmd->token); | ||
394 | request->data[0].base = fc->dma_scsi_cmd + fcmd->token * sizeof(fcp_cmd); | ||
395 | request->data[0].count = sizeof(fcp_cmd); | ||
396 | request->data[1].base = fc->dma_scsi_rsp + fcmd->token * fc->rsp_size; | ||
397 | request->data[1].count = fc->rsp_size; | ||
398 | if (fcmd->data) { | ||
399 | request->shdr.segcnt = 3; | ||
400 | i = fc->scsi_cmd_pool[fcmd->token].fcp_data_len; | ||
401 | request->shdr.bytecnt = i; | ||
402 | request->data[2].base = fcmd->data; | ||
403 | request->data[2].count = i; | ||
404 | request->type = | ||
405 | (fc->scsi_cmd_pool[fcmd->token].fcp_cntl & FCP_CNTL_WRITE) ? | ||
406 | SOC_CQTYPE_IO_WRITE : SOC_CQTYPE_IO_READ; | ||
407 | } else { | ||
408 | request->shdr.segcnt = 2; | ||
409 | request->shdr.bytecnt = 0; | ||
410 | request->data[2].base = 0; | ||
411 | request->data[2].count = 0; | ||
412 | request->type = SOC_CQTYPE_SIMPLE; | ||
413 | } | ||
414 | FILL_FCHDR_RCTL_DID(fch, R_CTL_COMMAND, fc->did); | ||
415 | FILL_FCHDR_SID(fch, fc->sid); | ||
416 | FILL_FCHDR_TYPE_FCTL(fch, TYPE_SCSI_FCP, | ||
417 | F_CTL_FIRST_SEQ | F_CTL_SEQ_INITIATIVE); | ||
418 | FILL_FCHDR_SEQ_DF_SEQ(fch, 0, 0, 0); | ||
419 | FILL_FCHDR_OXRX(fch, 0xffff, 0xffff); | ||
420 | fch->param = 0; | ||
421 | request->shdr.flags = port->flags; | ||
422 | request->shdr.class = 2; | ||
423 | break; | ||
424 | |||
425 | case PROTO_OFFLINE: | ||
426 | memset (request, 0, sizeof(*request)); | ||
427 | request->shdr.token = TOKEN(PROTO_OFFLINE, port->mask, fcmd->token); | ||
428 | request->type = SOC_CQTYPE_OFFLINE; | ||
429 | FILL_FCHDR_RCTL_DID(fch, R_CTL_COMMAND, fc->did); | ||
430 | FILL_FCHDR_SID(fch, fc->sid); | ||
431 | FILL_FCHDR_TYPE_FCTL(fch, TYPE_SCSI_FCP, | ||
432 | F_CTL_FIRST_SEQ | F_CTL_SEQ_INITIATIVE); | ||
433 | FILL_FCHDR_SEQ_DF_SEQ(fch, 0, 0, 0); | ||
434 | FILL_FCHDR_OXRX(fch, 0xffff, 0xffff); | ||
435 | request->shdr.flags = port->flags; | ||
436 | break; | ||
437 | |||
438 | case PROTO_REPORT_AL_MAP: | ||
439 | /* SOC only supports Point-to-Point topology, no FC-AL, sorry... */ | ||
440 | return -ENOSYS; | ||
441 | |||
442 | default: | ||
443 | request->shdr.token = TOKEN(fcmd->proto, port->mask, fcmd->token); | ||
444 | request->shdr.class = 2; | ||
445 | request->shdr.flags = port->flags; | ||
446 | memcpy (fch, &fcmd->fch, sizeof(fc_hdr)); | ||
447 | request->data[0].count = fcmd->cmdlen; | ||
448 | request->data[1].count = fcmd->rsplen; | ||
449 | request->type = fcmd->class; | ||
450 | switch (fcmd->class) { | ||
451 | case FC_CLASS_OUTBOUND: | ||
452 | request->data[0].base = fcmd->cmd; | ||
453 | request->data[0].count = fcmd->cmdlen; | ||
454 | request->type = SOC_CQTYPE_OUTBOUND; | ||
455 | request->shdr.bytecnt = fcmd->cmdlen; | ||
456 | request->shdr.segcnt = 1; | ||
457 | break; | ||
458 | case FC_CLASS_INBOUND: | ||
459 | request->data[0].base = fcmd->rsp; | ||
460 | request->data[0].count = fcmd->rsplen; | ||
461 | request->type = SOC_CQTYPE_INBOUND; | ||
462 | request->shdr.bytecnt = 0; | ||
463 | request->shdr.segcnt = 1; | ||
464 | break; | ||
465 | case FC_CLASS_SIMPLE: | ||
466 | request->data[0].base = fcmd->cmd; | ||
467 | request->data[1].base = fcmd->rsp; | ||
468 | request->data[0].count = fcmd->cmdlen; | ||
469 | request->data[1].count = fcmd->rsplen; | ||
470 | request->type = SOC_CQTYPE_SIMPLE; | ||
471 | request->shdr.bytecnt = fcmd->cmdlen; | ||
472 | request->shdr.segcnt = 2; | ||
473 | break; | ||
474 | case FC_CLASS_IO_READ: | ||
475 | case FC_CLASS_IO_WRITE: | ||
476 | request->data[0].base = fcmd->cmd; | ||
477 | request->data[1].base = fcmd->rsp; | ||
478 | request->data[0].count = fcmd->cmdlen; | ||
479 | request->data[1].count = fcmd->rsplen; | ||
480 | request->type = | ||
481 | (fcmd->class == FC_CLASS_IO_READ) ? | ||
482 | SOC_CQTYPE_IO_READ : SOC_CQTYPE_IO_WRITE; | ||
483 | if (fcmd->data) { | ||
484 | request->data[2].base = fcmd->data; | ||
485 | request->data[2].count = fcmd->datalen; | ||
486 | request->shdr.bytecnt = fcmd->datalen; | ||
487 | request->shdr.segcnt = 3; | ||
488 | } else { | ||
489 | request->shdr.bytecnt = 0; | ||
490 | request->shdr.segcnt = 2; | ||
491 | } | ||
492 | break; | ||
493 | }; | ||
494 | break; | ||
495 | }; | ||
496 | |||
497 | request->count = 1; | ||
498 | request->flags = 0; | ||
499 | request->seqno = sw_cq->seqno; | ||
500 | |||
501 | /* And now tell the SOC about it */ | ||
502 | |||
503 | if (++sw_cq->in > sw_cq->last) { | ||
504 | sw_cq->in = 0; | ||
505 | sw_cq->seqno++; | ||
506 | } | ||
507 | |||
508 | SOD(("Putting %08x into cmd\n", | ||
509 | SOC_CMD_RSP_QALL | (sw_cq->in << 24) | (SOC_CMD_REQ_Q0 << qno))) | ||
510 | |||
511 | sbus_writel(SOC_CMD_RSP_QALL | (sw_cq->in << 24) | (SOC_CMD_REQ_Q0 << qno), | ||
512 | s->regs + CMD); | ||
513 | |||
514 | /* Read so that command is completed. */ | ||
515 | sbus_readl(s->regs + CMD); | ||
516 | |||
517 | return 0; | ||
518 | } | ||
519 | |||
520 | static inline void soc_download_fw(struct soc *s) | ||
521 | { | ||
522 | #ifdef HAVE_SOC_UCODE | ||
523 | xram_copy_to (s->xram, soc_ucode, sizeof(soc_ucode)); | ||
524 | xram_bzero (s->xram + sizeof(soc_ucode), 32768 - sizeof(soc_ucode)); | ||
525 | #endif | ||
526 | } | ||
527 | |||
528 | /* Check for what the best SBUS burst we can use happens | ||
529 | * to be on this machine. | ||
530 | */ | ||
531 | static inline void soc_init_bursts(struct soc *s, struct sbus_dev *sdev) | ||
532 | { | ||
533 | int bsizes, bsizes_more; | ||
534 | |||
535 | bsizes = (prom_getintdefault(sdev->prom_node,"burst-sizes",0xff) & 0xff); | ||
536 | bsizes_more = (prom_getintdefault(sdev->bus->prom_node, "burst-sizes", 0xff) & 0xff); | ||
537 | bsizes &= bsizes_more; | ||
538 | if ((bsizes & 0x7f) == 0x7f) | ||
539 | s->cfg = SOC_CFG_BURST_64; | ||
540 | else if ((bsizes & 0x3f) == 0x3f) | ||
541 | s->cfg = SOC_CFG_BURST_32; | ||
542 | else if ((bsizes & 0x1f) == 0x1f) | ||
543 | s->cfg = SOC_CFG_BURST_16; | ||
544 | else | ||
545 | s->cfg = SOC_CFG_BURST_4; | ||
546 | } | ||
547 | |||
548 | static inline void soc_init(struct sbus_dev *sdev, int no) | ||
549 | { | ||
550 | unsigned char tmp[60]; | ||
551 | int propl; | ||
552 | struct soc *s; | ||
553 | static int version_printed = 0; | ||
554 | soc_hw_cq cq[8]; | ||
555 | int size, i; | ||
556 | int irq; | ||
557 | |||
558 | s = kzalloc (sizeof (struct soc), GFP_KERNEL); | ||
559 | if (s == NULL) | ||
560 | return; | ||
561 | spin_lock_init(&s->lock); | ||
562 | s->soc_no = no; | ||
563 | |||
564 | SOD(("socs %08lx soc_intr %08lx soc_hw_enque %08x\n", | ||
565 | (long)socs, (long)soc_intr, (long)soc_hw_enque)) | ||
566 | if (version_printed++ == 0) | ||
567 | printk (version); | ||
568 | |||
569 | s->port[0].fc.module = THIS_MODULE; | ||
570 | s->port[1].fc.module = THIS_MODULE; | ||
571 | |||
572 | s->next = socs; | ||
573 | socs = s; | ||
574 | s->port[0].fc.dev = sdev; | ||
575 | s->port[1].fc.dev = sdev; | ||
576 | s->port[0].s = s; | ||
577 | s->port[1].s = s; | ||
578 | |||
579 | s->port[0].fc.next = &s->port[1].fc; | ||
580 | |||
581 | /* World Wide Name of SOC */ | ||
582 | propl = prom_getproperty (sdev->prom_node, "soc-wwn", tmp, sizeof(tmp)); | ||
583 | if (propl != sizeof (fc_wwn)) { | ||
584 | s->wwn.naaid = NAAID_IEEE; | ||
585 | s->wwn.lo = 0x12345678; | ||
586 | } else | ||
587 | memcpy (&s->wwn, tmp, sizeof (fc_wwn)); | ||
588 | |||
589 | propl = prom_getproperty (sdev->prom_node, "port-wwns", tmp, sizeof(tmp)); | ||
590 | if (propl != 2 * sizeof (fc_wwn)) { | ||
591 | s->port[0].fc.wwn_nport.naaid = NAAID_IEEE_EXT; | ||
592 | s->port[0].fc.wwn_nport.hi = s->wwn.hi; | ||
593 | s->port[0].fc.wwn_nport.lo = s->wwn.lo; | ||
594 | s->port[1].fc.wwn_nport.naaid = NAAID_IEEE_EXT; | ||
595 | s->port[1].fc.wwn_nport.nportid = 1; | ||
596 | s->port[1].fc.wwn_nport.hi = s->wwn.hi; | ||
597 | s->port[1].fc.wwn_nport.lo = s->wwn.lo; | ||
598 | } else { | ||
599 | memcpy (&s->port[0].fc.wwn_nport, tmp, sizeof (fc_wwn)); | ||
600 | memcpy (&s->port[1].fc.wwn_nport, tmp + sizeof (fc_wwn), sizeof (fc_wwn)); | ||
601 | } | ||
602 | memcpy (&s->port[0].fc.wwn_node, &s->wwn, sizeof (fc_wwn)); | ||
603 | memcpy (&s->port[1].fc.wwn_node, &s->wwn, sizeof (fc_wwn)); | ||
604 | SOD(("Got wwns %08x%08x ports %08x%08x and %08x%08x\n", | ||
605 | *(u32 *)&s->port[0].fc.wwn_nport, s->port[0].fc.wwn_nport.lo, | ||
606 | *(u32 *)&s->port[0].fc.wwn_nport, s->port[0].fc.wwn_nport.lo, | ||
607 | *(u32 *)&s->port[1].fc.wwn_nport, s->port[1].fc.wwn_nport.lo)) | ||
608 | |||
609 | s->port[0].fc.sid = 1; | ||
610 | s->port[1].fc.sid = 17; | ||
611 | s->port[0].fc.did = 2; | ||
612 | s->port[1].fc.did = 18; | ||
613 | |||
614 | s->port[0].fc.reset = soc_reset; | ||
615 | s->port[1].fc.reset = soc_reset; | ||
616 | |||
617 | if (sdev->num_registers == 1) { | ||
618 | /* Probably SunFire onboard SOC */ | ||
619 | s->xram = sbus_ioremap(&sdev->resource[0], 0, | ||
620 | 0x10000UL, "soc xram"); | ||
621 | s->regs = sbus_ioremap(&sdev->resource[0], 0x10000UL, | ||
622 | 0x10UL, "soc regs"); | ||
623 | } else { | ||
624 | /* Probably SOC sbus card */ | ||
625 | s->xram = sbus_ioremap(&sdev->resource[1], 0, | ||
626 | sdev->reg_addrs[1].reg_size, "soc xram"); | ||
627 | s->regs = sbus_ioremap(&sdev->resource[2], 0, | ||
628 | sdev->reg_addrs[2].reg_size, "soc regs"); | ||
629 | } | ||
630 | |||
631 | soc_init_bursts(s, sdev); | ||
632 | |||
633 | SOD(("Disabling SOC\n")) | ||
634 | |||
635 | soc_disable (s); | ||
636 | |||
637 | irq = sdev->irqs[0]; | ||
638 | |||
639 | if (request_irq (irq, soc_intr, IRQF_SHARED, "SOC", (void *)s)) { | ||
640 | soc_printk ("Cannot order irq %d to go\n", irq); | ||
641 | socs = s->next; | ||
642 | return; | ||
643 | } | ||
644 | |||
645 | SOD(("SOC uses IRQ %d\n", irq)) | ||
646 | |||
647 | s->port[0].fc.irq = irq; | ||
648 | s->port[1].fc.irq = irq; | ||
649 | |||
650 | sprintf (s->port[0].fc.name, "soc%d port A", no); | ||
651 | sprintf (s->port[1].fc.name, "soc%d port B", no); | ||
652 | s->port[0].flags = SOC_FC_HDR | SOC_PORT_A; | ||
653 | s->port[1].flags = SOC_FC_HDR | SOC_PORT_B; | ||
654 | s->port[1].mask = (1 << 11); | ||
655 | |||
656 | s->port[0].fc.hw_enque = soc_hw_enque; | ||
657 | s->port[1].fc.hw_enque = soc_hw_enque; | ||
658 | |||
659 | soc_download_fw (s); | ||
660 | |||
661 | SOD(("Downloaded firmware\n")) | ||
662 | |||
663 | /* Now setup xram circular queues */ | ||
664 | memset (cq, 0, sizeof(cq)); | ||
665 | |||
666 | size = (SOC_CQ_REQ0_SIZE + SOC_CQ_REQ1_SIZE) * sizeof(soc_req); | ||
667 | s->req_cpu = sbus_alloc_consistent(sdev, size, &s->req_dvma); | ||
668 | s->req[0].pool = s->req_cpu; | ||
669 | cq[0].address = s->req_dvma; | ||
670 | s->req[1].pool = s->req[0].pool + SOC_CQ_REQ0_SIZE; | ||
671 | |||
672 | s->req[0].hw_cq = (soc_hw_cq __iomem *)(s->xram + SOC_CQ_REQ_OFFSET); | ||
673 | s->req[1].hw_cq = (soc_hw_cq __iomem *)(s->xram + SOC_CQ_REQ_OFFSET + sizeof(soc_hw_cq)); | ||
674 | s->rsp[0].hw_cq = (soc_hw_cq __iomem *)(s->xram + SOC_CQ_RSP_OFFSET); | ||
675 | s->rsp[1].hw_cq = (soc_hw_cq __iomem *)(s->xram + SOC_CQ_RSP_OFFSET + sizeof(soc_hw_cq)); | ||
676 | |||
677 | cq[1].address = cq[0].address + (SOC_CQ_REQ0_SIZE * sizeof(soc_req)); | ||
678 | cq[4].address = 1; | ||
679 | cq[5].address = 1; | ||
680 | cq[0].last = SOC_CQ_REQ0_SIZE - 1; | ||
681 | cq[1].last = SOC_CQ_REQ1_SIZE - 1; | ||
682 | cq[4].last = SOC_CQ_RSP0_SIZE - 1; | ||
683 | cq[5].last = SOC_CQ_RSP1_SIZE - 1; | ||
684 | for (i = 0; i < 8; i++) | ||
685 | cq[i].seqno = 1; | ||
686 | |||
687 | s->req[0].last = SOC_CQ_REQ0_SIZE - 1; | ||
688 | s->req[1].last = SOC_CQ_REQ1_SIZE - 1; | ||
689 | s->rsp[0].last = SOC_CQ_RSP0_SIZE - 1; | ||
690 | s->rsp[1].last = SOC_CQ_RSP1_SIZE - 1; | ||
691 | |||
692 | s->req[0].seqno = 1; | ||
693 | s->req[1].seqno = 1; | ||
694 | s->rsp[0].seqno = 1; | ||
695 | s->rsp[1].seqno = 1; | ||
696 | |||
697 | xram_copy_to (s->xram + SOC_CQ_REQ_OFFSET, cq, sizeof(cq)); | ||
698 | |||
699 | /* Make our sw copy of SOC service parameters */ | ||
700 | xram_copy_from (s->serv_params, s->xram + 0x140, sizeof (s->serv_params)); | ||
701 | |||
702 | s->port[0].fc.common_svc = (common_svc_parm *)s->serv_params; | ||
703 | s->port[0].fc.class_svcs = (svc_parm *)(s->serv_params + 0x20); | ||
704 | s->port[1].fc.common_svc = (common_svc_parm *)&s->serv_params; | ||
705 | s->port[1].fc.class_svcs = (svc_parm *)(s->serv_params + 0x20); | ||
706 | |||
707 | soc_enable (s); | ||
708 | |||
709 | SOD(("Enabled SOC\n")) | ||
710 | } | ||
711 | |||
712 | static int __init soc_probe(void) | ||
713 | { | ||
714 | struct sbus_bus *sbus; | ||
715 | struct sbus_dev *sdev = NULL; | ||
716 | struct soc *s; | ||
717 | int cards = 0; | ||
718 | |||
719 | for_each_sbus(sbus) { | ||
720 | for_each_sbusdev(sdev, sbus) { | ||
721 | if(!strcmp(sdev->prom_name, "SUNW,soc")) { | ||
722 | soc_init(sdev, cards); | ||
723 | cards++; | ||
724 | } | ||
725 | } | ||
726 | } | ||
727 | if (!cards) return -EIO; | ||
728 | |||
729 | for_each_soc(s) | ||
730 | if (s->next) | ||
731 | s->port[1].fc.next = &s->next->port[0].fc; | ||
732 | fcp_init (&socs->port[0].fc); | ||
733 | return 0; | ||
734 | } | ||
735 | |||
736 | static void __exit soc_cleanup(void) | ||
737 | { | ||
738 | struct soc *s; | ||
739 | int irq; | ||
740 | struct sbus_dev *sdev; | ||
741 | |||
742 | for_each_soc(s) { | ||
743 | irq = s->port[0].fc.irq; | ||
744 | free_irq (irq, s); | ||
745 | |||
746 | fcp_release(&(s->port[0].fc), 2); | ||
747 | |||
748 | sdev = s->port[0].fc.dev; | ||
749 | if (sdev->num_registers == 1) { | ||
750 | sbus_iounmap(s->xram, 0x10000UL); | ||
751 | sbus_iounmap(s->regs, 0x10UL); | ||
752 | } else { | ||
753 | sbus_iounmap(s->xram, sdev->reg_addrs[1].reg_size); | ||
754 | sbus_iounmap(s->regs, sdev->reg_addrs[2].reg_size); | ||
755 | } | ||
756 | sbus_free_consistent(sdev, | ||
757 | (SOC_CQ_REQ0_SIZE+SOC_CQ_REQ1_SIZE)*sizeof(soc_req), | ||
758 | s->req_cpu, s->req_dvma); | ||
759 | } | ||
760 | } | ||
761 | |||
762 | module_init(soc_probe); | ||
763 | module_exit(soc_cleanup); | ||
764 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/fc4/soc.h b/drivers/fc4/soc.h deleted file mode 100644 index d38cf5b28eed..000000000000 --- a/drivers/fc4/soc.h +++ /dev/null | |||
@@ -1,301 +0,0 @@ | |||
1 | /* soc.h: Definitions for Sparc SUNW,soc Fibre Channel Sbus driver. | ||
2 | * | ||
3 | * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
4 | */ | ||
5 | |||
6 | #ifndef __SOC_H | ||
7 | #define __SOC_H | ||
8 | |||
9 | #include "fc.h" | ||
10 | #include "fcp.h" | ||
11 | #include "fcp_impl.h" | ||
12 | |||
13 | /* Hardware register offsets and constants first {{{ */ | ||
14 | #define CFG 0x00UL /* Config Register */ | ||
15 | #define SAE 0x04UL /* Slave Access Error Register */ | ||
16 | #define CMD 0x08UL /* Command and Status Register */ | ||
17 | #define IMASK 0x0cUL /* Interrupt Mask Register */ | ||
18 | |||
19 | /* Config Register */ | ||
20 | #define SOC_CFG_EXT_RAM_BANK_MASK 0x07000000 | ||
21 | #define SOC_CFG_EEPROM_BANK_MASK 0x00030000 | ||
22 | #define SOC_CFG_BURST64_MASK 0x00000700 | ||
23 | #define SOC_CFG_SBUS_PARITY_TEST 0x00000020 | ||
24 | #define SOC_CFG_SBUS_PARITY_CHECK 0x00000010 | ||
25 | #define SOC_CFG_SBUS_ENHANCED 0x00000008 | ||
26 | #define SOC_CFG_BURST_MASK 0x00000007 | ||
27 | /* Bursts */ | ||
28 | #define SOC_CFG_BURST_4 0x00000000 | ||
29 | #define SOC_CFG_BURST_16 0x00000004 | ||
30 | #define SOC_CFG_BURST_32 0x00000005 | ||
31 | #define SOC_CFG_BURST_64 0x00000006 | ||
32 | |||
33 | /* Slave Access Error Register */ | ||
34 | #define SOC_SAE_ALIGNMENT 0x00000004 | ||
35 | #define SOC_SAE_UNSUPPORTED 0x00000002 | ||
36 | #define SOC_SAE_PARITY 0x00000001 | ||
37 | |||
38 | /* Command & Status Register */ | ||
39 | #define SOC_CMD_RSP_QALL 0x000f0000 | ||
40 | #define SOC_CMD_RSP_Q0 0x00010000 | ||
41 | #define SOC_CMD_RSP_Q1 0x00020000 | ||
42 | #define SOC_CMD_RSP_Q2 0x00040000 | ||
43 | #define SOC_CMD_RSP_Q3 0x00080000 | ||
44 | #define SOC_CMD_REQ_QALL 0x00000f00 | ||
45 | #define SOC_CMD_REQ_Q0 0x00000100 | ||
46 | #define SOC_CMD_REQ_Q1 0x00000200 | ||
47 | #define SOC_CMD_REQ_Q2 0x00000400 | ||
48 | #define SOC_CMD_REQ_Q3 0x00000800 | ||
49 | #define SOC_CMD_SAE 0x00000080 | ||
50 | #define SOC_CMD_INTR_PENDING 0x00000008 | ||
51 | #define SOC_CMD_NON_QUEUED 0x00000004 | ||
52 | #define SOC_CMD_IDLE 0x00000002 | ||
53 | #define SOC_CMD_SOFT_RESET 0x00000001 | ||
54 | |||
55 | /* Interrupt Mask Register */ | ||
56 | #define SOC_IMASK_RSP_QALL 0x000f0000 | ||
57 | #define SOC_IMASK_RSP_Q0 0x00010000 | ||
58 | #define SOC_IMASK_RSP_Q1 0x00020000 | ||
59 | #define SOC_IMASK_RSP_Q2 0x00040000 | ||
60 | #define SOC_IMASK_RSP_Q3 0x00080000 | ||
61 | #define SOC_IMASK_REQ_QALL 0x00000f00 | ||
62 | #define SOC_IMASK_REQ_Q0 0x00000100 | ||
63 | #define SOC_IMASK_REQ_Q1 0x00000200 | ||
64 | #define SOC_IMASK_REQ_Q2 0x00000400 | ||
65 | #define SOC_IMASK_REQ_Q3 0x00000800 | ||
66 | #define SOC_IMASK_SAE 0x00000080 | ||
67 | #define SOC_IMASK_NON_QUEUED 0x00000004 | ||
68 | |||
69 | #define SOC_INTR(s, cmd) \ | ||
70 | (((cmd & SOC_CMD_RSP_QALL) | ((~cmd) & SOC_CMD_REQ_QALL)) \ | ||
71 | & s->imask) | ||
72 | |||
73 | #define SOC_SETIMASK(s, i) \ | ||
74 | do { (s)->imask = (i); \ | ||
75 | sbus_writel((i), (s)->regs + IMASK); \ | ||
76 | } while(0) | ||
77 | |||
78 | /* XRAM | ||
79 | * | ||
80 | * This is a 64KB register area. It accepts only halfword access. | ||
81 | * That's why here are the following inline functions... | ||
82 | */ | ||
83 | |||
84 | typedef void __iomem *xram_p; | ||
85 | |||
86 | /* Get 32bit number from XRAM */ | ||
87 | static inline u32 xram_get_32(xram_p x) | ||
88 | { | ||
89 | return ((sbus_readw(x + 0x00UL) << 16) | | ||
90 | (sbus_readw(x + 0x02UL))); | ||
91 | } | ||
92 | |||
93 | /* Like the above, but when we don't care about the high 16 bits */ | ||
94 | static inline u32 xram_get_32low(xram_p x) | ||
95 | { | ||
96 | return (u32) sbus_readw(x + 0x02UL); | ||
97 | } | ||
98 | |||
99 | static inline u16 xram_get_16(xram_p x) | ||
100 | { | ||
101 | return sbus_readw(x); | ||
102 | } | ||
103 | |||
104 | static inline u8 xram_get_8(xram_p x) | ||
105 | { | ||
106 | if ((unsigned long)x & 0x1UL) { | ||
107 | x = x - 1; | ||
108 | return (u8) sbus_readw(x); | ||
109 | } else { | ||
110 | return (u8) (sbus_readw(x) >> 8); | ||
111 | } | ||
112 | } | ||
113 | |||
114 | static inline void xram_copy_from(void *p, xram_p x, int len) | ||
115 | { | ||
116 | for (len >>= 2; len > 0; len--, x += sizeof(u32)) { | ||
117 | u32 val, *p32 = p; | ||
118 | |||
119 | val = ((sbus_readw(x + 0x00UL) << 16) | | ||
120 | (sbus_readw(x + 0x02UL))); | ||
121 | *p32++ = val; | ||
122 | p = p32; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | static inline void xram_copy_to(xram_p x, void *p, int len) | ||
127 | { | ||
128 | for (len >>= 2; len > 0; len--, x += sizeof(u32)) { | ||
129 | u32 tmp, *p32 = p; | ||
130 | |||
131 | tmp = *p32++; | ||
132 | p = p32; | ||
133 | sbus_writew(tmp >> 16, x + 0x00UL); | ||
134 | sbus_writew(tmp, x + 0x02UL); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | static inline void xram_bzero(xram_p x, int len) | ||
139 | { | ||
140 | for (len >>= 1; len > 0; len--, x += sizeof(u16)) | ||
141 | sbus_writew(0, x); | ||
142 | } | ||
143 | |||
144 | /* Circular Queue */ | ||
145 | |||
146 | #define SOC_CQ_REQ_OFFSET (0x100 * sizeof(u16)) | ||
147 | #define SOC_CQ_RSP_OFFSET (0x110 * sizeof(u16)) | ||
148 | |||
149 | typedef struct { | ||
150 | u32 address; | ||
151 | u8 in; | ||
152 | u8 out; | ||
153 | u8 last; | ||
154 | u8 seqno; | ||
155 | } soc_hw_cq; | ||
156 | |||
157 | #define SOC_PORT_A 0x0000 /* From/To Port A */ | ||
158 | #define SOC_PORT_B 0x0001 /* From/To Port A */ | ||
159 | #define SOC_FC_HDR 0x0002 /* Contains FC Header */ | ||
160 | #define SOC_NORSP 0x0004 /* Don't generate response nor interrupt */ | ||
161 | #define SOC_NOINT 0x0008 /* Generate response but not interrupt */ | ||
162 | #define SOC_XFERRDY 0x0010 /* Generate XFERRDY */ | ||
163 | #define SOC_IGNOREPARAM 0x0020 /* Ignore PARAM field in the FC header */ | ||
164 | #define SOC_COMPLETE 0x0040 /* Command completed */ | ||
165 | #define SOC_UNSOLICITED 0x0080 /* For request this is the packet to establish unsolicited pools, */ | ||
166 | /* for rsp this is unsolicited packet */ | ||
167 | #define SOC_STATUS 0x0100 /* State change (on/off line) */ | ||
168 | |||
169 | typedef struct { | ||
170 | u32 token; | ||
171 | u16 flags; | ||
172 | u8 class; | ||
173 | u8 segcnt; | ||
174 | u32 bytecnt; | ||
175 | } soc_hdr; | ||
176 | |||
177 | typedef struct { | ||
178 | u32 base; | ||
179 | u32 count; | ||
180 | } soc_data; | ||
181 | |||
182 | #define SOC_CQTYPE_OUTBOUND 0x01 | ||
183 | #define SOC_CQTYPE_INBOUND 0x02 | ||
184 | #define SOC_CQTYPE_SIMPLE 0x03 | ||
185 | #define SOC_CQTYPE_IO_WRITE 0x04 | ||
186 | #define SOC_CQTYPE_IO_READ 0x05 | ||
187 | #define SOC_CQTYPE_UNSOLICITED 0x06 | ||
188 | #define SOC_CQTYPE_DIAG 0x07 | ||
189 | #define SOC_CQTYPE_OFFLINE 0x08 | ||
190 | #define SOC_CQTYPE_RESPONSE 0x10 | ||
191 | #define SOC_CQTYPE_INLINE 0x20 | ||
192 | |||
193 | #define SOC_CQFLAGS_CONT 0x01 | ||
194 | #define SOC_CQFLAGS_FULL 0x02 | ||
195 | #define SOC_CQFLAGS_BADHDR 0x04 | ||
196 | #define SOC_CQFLAGS_BADPKT 0x08 | ||
197 | |||
198 | typedef struct { | ||
199 | soc_hdr shdr; | ||
200 | soc_data data[3]; | ||
201 | fc_hdr fchdr; | ||
202 | u8 count; | ||
203 | u8 type; | ||
204 | u8 flags; | ||
205 | u8 seqno; | ||
206 | } soc_req; | ||
207 | |||
208 | #define SOC_OK 0 | ||
209 | #define SOC_P_RJT 2 | ||
210 | #define SOC_F_RJT 3 | ||
211 | #define SOC_P_BSY 4 | ||
212 | #define SOC_F_BSY 5 | ||
213 | #define SOC_ONLINE 0x10 | ||
214 | #define SOC_OFFLINE 0x11 | ||
215 | #define SOC_TIMEOUT 0x12 | ||
216 | #define SOC_OVERRUN 0x13 | ||
217 | #define SOC_UNKOWN_CQ_TYPE 0x20 | ||
218 | #define SOC_BAD_SEG_CNT 0x21 | ||
219 | #define SOC_MAX_XCHG_EXCEEDED 0x22 | ||
220 | #define SOC_BAD_XID 0x23 | ||
221 | #define SOC_XCHG_BUSY 0x24 | ||
222 | #define SOC_BAD_POOL_ID 0x25 | ||
223 | #define SOC_INSUFFICIENT_CQES 0x26 | ||
224 | #define SOC_ALLOC_FAIL 0x27 | ||
225 | #define SOC_BAD_SID 0x28 | ||
226 | #define SOC_NO_SEG_INIT 0x29 | ||
227 | |||
228 | typedef struct { | ||
229 | soc_hdr shdr; | ||
230 | u32 status; | ||
231 | soc_data data; | ||
232 | u8 xxx1[12]; | ||
233 | fc_hdr fchdr; | ||
234 | u8 count; | ||
235 | u8 type; | ||
236 | u8 flags; | ||
237 | u8 seqno; | ||
238 | } soc_rsp; | ||
239 | |||
240 | /* }}} */ | ||
241 | |||
242 | /* Now our software structures and constants we use to drive the beast {{{ */ | ||
243 | |||
244 | #define SOC_CQ_REQ0_SIZE 4 | ||
245 | #define SOC_CQ_REQ1_SIZE 64 | ||
246 | #define SOC_CQ_RSP0_SIZE 8 | ||
247 | #define SOC_CQ_RSP1_SIZE 4 | ||
248 | |||
249 | #define SOC_SOLICITED_RSP_Q 0 | ||
250 | #define SOC_UNSOLICITED_RSP_Q 1 | ||
251 | |||
252 | struct soc; | ||
253 | |||
254 | typedef struct { | ||
255 | /* This must come first */ | ||
256 | fc_channel fc; | ||
257 | struct soc *s; | ||
258 | u16 flags; | ||
259 | u16 mask; | ||
260 | } soc_port; | ||
261 | |||
262 | typedef struct { | ||
263 | soc_hw_cq __iomem *hw_cq; /* Related XRAM cq */ | ||
264 | soc_req __iomem *pool; | ||
265 | u8 in; | ||
266 | u8 out; | ||
267 | u8 last; | ||
268 | u8 seqno; | ||
269 | } soc_cq_rsp; | ||
270 | |||
271 | typedef struct { | ||
272 | soc_hw_cq __iomem *hw_cq; /* Related XRAM cq */ | ||
273 | soc_req *pool; | ||
274 | u8 in; | ||
275 | u8 out; | ||
276 | u8 last; | ||
277 | u8 seqno; | ||
278 | } soc_cq_req; | ||
279 | |||
280 | struct soc { | ||
281 | spinlock_t lock; | ||
282 | soc_port port[2]; /* Every SOC has one or two FC ports */ | ||
283 | soc_cq_req req[2]; /* Request CQs */ | ||
284 | soc_cq_rsp rsp[2]; /* Response CQs */ | ||
285 | int soc_no; | ||
286 | void __iomem *regs; | ||
287 | xram_p xram; | ||
288 | fc_wwn wwn; | ||
289 | u32 imask; /* Our copy of regs->imask */ | ||
290 | u32 cfg; /* Our copy of regs->cfg */ | ||
291 | char serv_params[80]; | ||
292 | struct soc *next; | ||
293 | int curr_port; /* Which port will have priority to fcp_queue_empty */ | ||
294 | |||
295 | soc_req *req_cpu; | ||
296 | u32 req_dvma; | ||
297 | }; | ||
298 | |||
299 | /* }}} */ | ||
300 | |||
301 | #endif /* !(__SOC_H) */ | ||
diff --git a/drivers/fc4/socal.c b/drivers/fc4/socal.c deleted file mode 100644 index c903ebfab526..000000000000 --- a/drivers/fc4/socal.c +++ /dev/null | |||
@@ -1,904 +0,0 @@ | |||
1 | /* socal.c: Sparc SUNW,socal (SOC+) Fibre Channel Sbus adapter support. | ||
2 | * | ||
3 | * Copyright (C) 1998,1999 Jakub Jelinek (jj@ultra.linux.cz) | ||
4 | * | ||
5 | * Sources: | ||
6 | * Fibre Channel Physical & Signaling Interface (FC-PH), dpANS, 1994 | ||
7 | * dpANS Fibre Channel Protocol for SCSI (X3.269-199X), Rev. 012, 1995 | ||
8 | * SOC+ Programming Guide 0.1 | ||
9 | * Fibre Channel Arbitrated Loop (FC-AL), dpANS rev. 4.5, 1995 | ||
10 | * | ||
11 | * Supported hardware: | ||
12 | * On-board SOC+ adapters of Ultra Enterprise servers and sun4d. | ||
13 | */ | ||
14 | |||
15 | static char *version = | ||
16 | "socal.c: SOC+ driver v1.1 9/Feb/99 Jakub Jelinek (jj@ultra.linux.cz)\n"; | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/types.h> | ||
21 | #include <linux/fcntl.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/ptrace.h> | ||
24 | #include <linux/ioport.h> | ||
25 | #include <linux/in.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/string.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/bitops.h> | ||
30 | #include <asm/system.h> | ||
31 | #include <asm/io.h> | ||
32 | #include <asm/dma.h> | ||
33 | #include <linux/errno.h> | ||
34 | #include <asm/byteorder.h> | ||
35 | |||
36 | #include <asm/openprom.h> | ||
37 | #include <asm/oplib.h> | ||
38 | #include <asm/pgtable.h> | ||
39 | #include <asm/irq.h> | ||
40 | |||
41 | /* #define SOCALDEBUG */ | ||
42 | /* #define HAVE_SOCAL_UCODE */ | ||
43 | /* #define USE_64BIT_MODE */ | ||
44 | |||
45 | #include "fcp_impl.h" | ||
46 | #include "socal.h" | ||
47 | #ifdef HAVE_SOCAL_UCODE | ||
48 | #include "socal_asm.h" | ||
49 | #endif | ||
50 | |||
51 | #define socal_printk printk ("socal%d: ", s->socal_no); printk | ||
52 | |||
53 | #ifdef SOCALDEBUG | ||
54 | #define SOD(x) socal_printk x; | ||
55 | #else | ||
56 | #define SOD(x) | ||
57 | #endif | ||
58 | |||
59 | #define for_each_socal(s) for (s = socals; s; s = s->next) | ||
60 | struct socal *socals = NULL; | ||
61 | |||
62 | static void socal_copy_from_xram(void *d, void __iomem *xram, long size) | ||
63 | { | ||
64 | u32 *dp = (u32 *) d; | ||
65 | while (size) { | ||
66 | *dp++ = sbus_readl(xram); | ||
67 | xram += sizeof(u32); | ||
68 | size -= sizeof(u32); | ||
69 | } | ||
70 | } | ||
71 | |||
72 | static void socal_copy_to_xram(void __iomem *xram, void *s, long size) | ||
73 | { | ||
74 | u32 *sp = (u32 *) s; | ||
75 | while (size) { | ||
76 | u32 val = *sp++; | ||
77 | sbus_writel(val, xram); | ||
78 | xram += sizeof(u32); | ||
79 | size -= sizeof(u32); | ||
80 | } | ||
81 | } | ||
82 | |||
83 | #ifdef HAVE_SOCAL_UCODE | ||
84 | static void socal_bzero(unsigned long xram, int size) | ||
85 | { | ||
86 | while (size) { | ||
87 | sbus_writel(0, xram); | ||
88 | xram += sizeof(u32); | ||
89 | size -= sizeof(u32); | ||
90 | } | ||
91 | } | ||
92 | #endif | ||
93 | |||
94 | static inline void socal_disable(struct socal *s) | ||
95 | { | ||
96 | sbus_writel(0, s->regs + IMASK); | ||
97 | sbus_writel(SOCAL_CMD_SOFT_RESET, s->regs + CMD); | ||
98 | } | ||
99 | |||
100 | static inline void socal_enable(struct socal *s) | ||
101 | { | ||
102 | SOD(("enable %08x\n", s->cfg)) | ||
103 | sbus_writel(0, s->regs + SAE); | ||
104 | sbus_writel(s->cfg, s->regs + CFG); | ||
105 | sbus_writel(SOCAL_CMD_RSP_QALL, s->regs + CMD); | ||
106 | SOCAL_SETIMASK(s, SOCAL_IMASK_RSP_QALL | SOCAL_IMASK_SAE); | ||
107 | SOD(("imask %08x %08x\n", s->imask, sbus_readl(s->regs + IMASK))); | ||
108 | } | ||
109 | |||
110 | static void socal_reset(fc_channel *fc) | ||
111 | { | ||
112 | socal_port *port = (socal_port *)fc; | ||
113 | struct socal *s = port->s; | ||
114 | |||
115 | /* FIXME */ | ||
116 | socal_disable(s); | ||
117 | s->req[0].seqno = 1; | ||
118 | s->req[1].seqno = 1; | ||
119 | s->rsp[0].seqno = 1; | ||
120 | s->rsp[1].seqno = 1; | ||
121 | s->req[0].in = 0; | ||
122 | s->req[1].in = 0; | ||
123 | s->rsp[0].in = 0; | ||
124 | s->rsp[1].in = 0; | ||
125 | s->req[0].out = 0; | ||
126 | s->req[1].out = 0; | ||
127 | s->rsp[0].out = 0; | ||
128 | s->rsp[1].out = 0; | ||
129 | |||
130 | /* FIXME */ | ||
131 | socal_enable(s); | ||
132 | } | ||
133 | |||
134 | static inline void socal_solicited(struct socal *s, unsigned long qno) | ||
135 | { | ||
136 | socal_rsp *hwrsp; | ||
137 | socal_cq *sw_cq; | ||
138 | int token; | ||
139 | int status; | ||
140 | fc_channel *fc; | ||
141 | |||
142 | sw_cq = &s->rsp[qno]; | ||
143 | |||
144 | /* Finally an improvement against old SOC :) */ | ||
145 | sw_cq->in = sbus_readb(s->regs + RESP + qno); | ||
146 | SOD (("socal_solicited, %d packets arrived\n", | ||
147 | (sw_cq->in - sw_cq->out) & sw_cq->last)) | ||
148 | for (;;) { | ||
149 | hwrsp = (socal_rsp *)sw_cq->pool + sw_cq->out; | ||
150 | SOD(("hwrsp %p out %d\n", hwrsp, sw_cq->out)) | ||
151 | |||
152 | #if defined(SOCALDEBUG) && 0 | ||
153 | { | ||
154 | u32 *u = (u32 *)hwrsp; | ||
155 | SOD(("%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x\n", | ||
156 | u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7])) | ||
157 | u += 8; | ||
158 | SOD(("%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x\n", | ||
159 | u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7])) | ||
160 | u = (u32 *)s->xram; | ||
161 | while (u < ((u32 *)s->regs)) { | ||
162 | if (sbus_readl(&u[0]) == 0x00003000 || | ||
163 | sbus_readl(&u[0]) == 0x00003801) { | ||
164 | SOD(("Found at %04lx\n", | ||
165 | (unsigned long)u - (unsigned long)s->xram)) | ||
166 | SOD((" %08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x\n", | ||
167 | sbus_readl(&u[0]), sbus_readl(&u[1]), | ||
168 | sbus_readl(&u[2]), sbus_readl(&u[3]), | ||
169 | sbus_readl(&u[4]), sbus_readl(&u[5]), | ||
170 | sbus_readl(&u[6]), sbus_readl(&u[7]))) | ||
171 | u += 8; | ||
172 | SOD((" %08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x\n", | ||
173 | sbus_readl(&u[0]), sbus_readl(&u[1]), | ||
174 | sbus_readl(&u[2]), sbus_readl(&u[3]), | ||
175 | sbus_readl(&u[4]), sbus_readl(&u[5]), | ||
176 | sbus_readl(&u[6]), sbus_readl(&u[7]))) | ||
177 | u -= 8; | ||
178 | } | ||
179 | u++; | ||
180 | } | ||
181 | } | ||
182 | #endif | ||
183 | |||
184 | token = hwrsp->shdr.token; | ||
185 | status = hwrsp->status; | ||
186 | fc = (fc_channel *)(&s->port[(token >> 11) & 1]); | ||
187 | |||
188 | SOD(("Solicited token %08x status %08x\n", token, status)) | ||
189 | if (status == SOCAL_OK) { | ||
190 | fcp_receive_solicited(fc, token >> 12, | ||
191 | token & ((1 << 11) - 1), | ||
192 | FC_STATUS_OK, NULL); | ||
193 | } else { | ||
194 | /* We have intentionally defined FC_STATUS_* constants | ||
195 | * to match SOCAL_* constants, otherwise we'd have to | ||
196 | * translate status. | ||
197 | */ | ||
198 | fcp_receive_solicited(fc, token >> 12, | ||
199 | token & ((1 << 11) - 1), status, &hwrsp->fchdr); | ||
200 | } | ||
201 | |||
202 | if (++sw_cq->out > sw_cq->last) { | ||
203 | sw_cq->seqno++; | ||
204 | sw_cq->out = 0; | ||
205 | } | ||
206 | |||
207 | if (sw_cq->out == sw_cq->in) { | ||
208 | sw_cq->in = sbus_readb(s->regs + RESP + qno); | ||
209 | if (sw_cq->out == sw_cq->in) { | ||
210 | /* Tell the hardware about it */ | ||
211 | sbus_writel((sw_cq->out << 24) | | ||
212 | (SOCAL_CMD_RSP_QALL & | ||
213 | ~(SOCAL_CMD_RSP_Q0 << qno)), | ||
214 | s->regs + CMD); | ||
215 | |||
216 | /* Read it, so that we're sure it has been updated */ | ||
217 | sbus_readl(s->regs + CMD); | ||
218 | sw_cq->in = sbus_readb(s->regs + RESP + qno); | ||
219 | if (sw_cq->out == sw_cq->in) | ||
220 | break; | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | } | ||
225 | |||
226 | static inline void socal_request (struct socal *s, u32 cmd) | ||
227 | { | ||
228 | SOCAL_SETIMASK(s, s->imask & ~(cmd & SOCAL_CMD_REQ_QALL)); | ||
229 | SOD(("imask %08x %08x\n", s->imask, sbus_readl(s->regs + IMASK))); | ||
230 | |||
231 | SOD(("Queues available %08x OUT %X\n", cmd, s->regs->reqpr[0])) | ||
232 | if (s->port[s->curr_port].fc.state != FC_STATE_OFFLINE) { | ||
233 | fcp_queue_empty ((fc_channel *)&(s->port[s->curr_port])); | ||
234 | if (((s->req[1].in + 1) & s->req[1].last) != (s->req[1].out)) | ||
235 | fcp_queue_empty ((fc_channel *)&(s->port[1 - s->curr_port])); | ||
236 | } else { | ||
237 | fcp_queue_empty ((fc_channel *)&(s->port[1 - s->curr_port])); | ||
238 | } | ||
239 | if (s->port[1 - s->curr_port].fc.state != FC_STATE_OFFLINE) | ||
240 | s->curr_port ^= 1; | ||
241 | } | ||
242 | |||
243 | static inline void socal_unsolicited (struct socal *s, unsigned long qno) | ||
244 | { | ||
245 | socal_rsp *hwrsp, *hwrspc; | ||
246 | socal_cq *sw_cq; | ||
247 | int count; | ||
248 | int status; | ||
249 | int flags; | ||
250 | fc_channel *fc; | ||
251 | |||
252 | sw_cq = &s->rsp[qno]; | ||
253 | |||
254 | sw_cq->in = sbus_readb(s->regs + RESP + qno); | ||
255 | SOD (("socal_unsolicited, %d packets arrived, in %d\n", | ||
256 | (sw_cq->in - sw_cq->out) & sw_cq->last, sw_cq->in)) | ||
257 | while (sw_cq->in != sw_cq->out) { | ||
258 | /* ...real work per entry here... */ | ||
259 | hwrsp = (socal_rsp *)sw_cq->pool + sw_cq->out; | ||
260 | SOD(("hwrsp %p out %d\n", hwrsp, sw_cq->out)) | ||
261 | |||
262 | #if defined(SOCALDEBUG) && 0 | ||
263 | { | ||
264 | u32 *u = (u32 *)hwrsp; | ||
265 | SOD(("%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x\n", | ||
266 | u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7])) | ||
267 | u += 8; | ||
268 | SOD(("%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x\n", | ||
269 | u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7])) | ||
270 | } | ||
271 | #endif | ||
272 | |||
273 | hwrspc = NULL; | ||
274 | flags = hwrsp->shdr.flags; | ||
275 | count = hwrsp->count; | ||
276 | fc = (fc_channel *)&s->port[flags & SOCAL_PORT_B]; | ||
277 | SOD(("FC %08lx\n", (long)fc)) | ||
278 | |||
279 | if (count != 1) { | ||
280 | /* Ugh, continuation entries */ | ||
281 | u8 in; | ||
282 | |||
283 | if (count != 2) { | ||
284 | printk("%s: Too many continuations entries %d\n", | ||
285 | fc->name, count); | ||
286 | goto update_out; | ||
287 | } | ||
288 | |||
289 | in = sw_cq->in; | ||
290 | if (in < sw_cq->out) | ||
291 | in += sw_cq->last + 1; | ||
292 | if (in < sw_cq->out + 2) { | ||
293 | /* Ask the hardware if they haven't arrived yet. */ | ||
294 | sbus_writel((sw_cq->out << 24) | | ||
295 | (SOCAL_CMD_RSP_QALL & | ||
296 | ~(SOCAL_CMD_RSP_Q0 << qno)), | ||
297 | s->regs + CMD); | ||
298 | |||
299 | /* Read it, so that we're sure it has been updated */ | ||
300 | sbus_readl(s->regs + CMD); | ||
301 | sw_cq->in = sbus_readb(s->regs + RESP + qno); | ||
302 | in = sw_cq->in; | ||
303 | if (in < sw_cq->out) | ||
304 | in += sw_cq->last + 1; | ||
305 | if (in < sw_cq->out + 2) /* Nothing came, let us wait */ | ||
306 | return; | ||
307 | } | ||
308 | if (sw_cq->out == sw_cq->last) | ||
309 | hwrspc = (socal_rsp *)sw_cq->pool; | ||
310 | else | ||
311 | hwrspc = hwrsp + 1; | ||
312 | } | ||
313 | |||
314 | switch (flags & ~SOCAL_PORT_B) { | ||
315 | case SOCAL_STATUS: | ||
316 | status = hwrsp->status; | ||
317 | switch (status) { | ||
318 | case SOCAL_ONLINE: | ||
319 | SOD(("State change to ONLINE\n")); | ||
320 | fcp_state_change(fc, FC_STATE_ONLINE); | ||
321 | break; | ||
322 | case SOCAL_ONLINE_LOOP: | ||
323 | SOD(("State change to ONLINE_LOOP\n")); | ||
324 | fcp_state_change(fc, FC_STATE_ONLINE); | ||
325 | break; | ||
326 | case SOCAL_OFFLINE: | ||
327 | SOD(("State change to OFFLINE\n")); | ||
328 | fcp_state_change(fc, FC_STATE_OFFLINE); | ||
329 | break; | ||
330 | default: | ||
331 | printk ("%s: Unknown STATUS no %d\n", | ||
332 | fc->name, status); | ||
333 | break; | ||
334 | }; | ||
335 | |||
336 | break; | ||
337 | case (SOCAL_UNSOLICITED|SOCAL_FC_HDR): | ||
338 | { | ||
339 | int r_ctl = *((u8 *)&hwrsp->fchdr); | ||
340 | unsigned len; | ||
341 | |||
342 | if ((r_ctl & 0xf0) == R_CTL_EXTENDED_SVC) { | ||
343 | len = hwrsp->shdr.bytecnt; | ||
344 | if (len < 4 || !hwrspc) { | ||
345 | printk ("%s: Invalid R_CTL %02x " | ||
346 | "continuation entries\n", | ||
347 | fc->name, r_ctl); | ||
348 | } else { | ||
349 | if (len > 60) | ||
350 | len = 60; | ||
351 | if (*(u32 *)hwrspc == LS_DISPLAY) { | ||
352 | int i; | ||
353 | |||
354 | for (i = 4; i < len; i++) | ||
355 | if (((u8 *)hwrspc)[i] == '\n') | ||
356 | ((u8 *)hwrspc)[i] = ' '; | ||
357 | ((u8 *)hwrspc)[len] = 0; | ||
358 | printk ("%s message: %s\n", | ||
359 | fc->name, ((u8 *)hwrspc) + 4); | ||
360 | } else { | ||
361 | printk ("%s: Unknown LS_CMD " | ||
362 | "%08x\n", fc->name, | ||
363 | *(u32 *)hwrspc); | ||
364 | } | ||
365 | } | ||
366 | } else { | ||
367 | printk ("%s: Unsolicited R_CTL %02x " | ||
368 | "not handled\n", fc->name, r_ctl); | ||
369 | } | ||
370 | } | ||
371 | break; | ||
372 | default: | ||
373 | printk ("%s: Unexpected flags %08x\n", fc->name, flags); | ||
374 | break; | ||
375 | }; | ||
376 | update_out: | ||
377 | if (++sw_cq->out > sw_cq->last) { | ||
378 | sw_cq->seqno++; | ||
379 | sw_cq->out = 0; | ||
380 | } | ||
381 | |||
382 | if (hwrspc) { | ||
383 | if (++sw_cq->out > sw_cq->last) { | ||
384 | sw_cq->seqno++; | ||
385 | sw_cq->out = 0; | ||
386 | } | ||
387 | } | ||
388 | |||
389 | if (sw_cq->out == sw_cq->in) { | ||
390 | sw_cq->in = sbus_readb(s->regs + RESP + qno); | ||
391 | if (sw_cq->out == sw_cq->in) { | ||
392 | /* Tell the hardware about it */ | ||
393 | sbus_writel((sw_cq->out << 24) | | ||
394 | (SOCAL_CMD_RSP_QALL & | ||
395 | ~(SOCAL_CMD_RSP_Q0 << qno)), | ||
396 | s->regs + CMD); | ||
397 | |||
398 | /* Read it, so that we're sure it has been updated */ | ||
399 | sbus_readl(s->regs + CMD); | ||
400 | sw_cq->in = sbus_readb(s->regs + RESP + qno); | ||
401 | } | ||
402 | } | ||
403 | } | ||
404 | } | ||
405 | |||
406 | static irqreturn_t socal_intr(int irq, void *dev_id) | ||
407 | { | ||
408 | u32 cmd; | ||
409 | unsigned long flags; | ||
410 | register struct socal *s = (struct socal *)dev_id; | ||
411 | |||
412 | spin_lock_irqsave(&s->lock, flags); | ||
413 | cmd = sbus_readl(s->regs + CMD); | ||
414 | for (; (cmd = SOCAL_INTR (s, cmd)); cmd = sbus_readl(s->regs + CMD)) { | ||
415 | #ifdef SOCALDEBUG | ||
416 | static int cnt = 0; | ||
417 | if (cnt++ < 50) | ||
418 | printk("soc_intr %08x\n", cmd); | ||
419 | #endif | ||
420 | if (cmd & SOCAL_CMD_RSP_Q2) | ||
421 | socal_unsolicited (s, SOCAL_UNSOLICITED_RSP_Q); | ||
422 | if (cmd & SOCAL_CMD_RSP_Q1) | ||
423 | socal_unsolicited (s, SOCAL_SOLICITED_BAD_RSP_Q); | ||
424 | if (cmd & SOCAL_CMD_RSP_Q0) | ||
425 | socal_solicited (s, SOCAL_SOLICITED_RSP_Q); | ||
426 | if (cmd & SOCAL_CMD_REQ_QALL) | ||
427 | socal_request (s, cmd); | ||
428 | } | ||
429 | spin_unlock_irqrestore(&s->lock, flags); | ||
430 | |||
431 | return IRQ_HANDLED; | ||
432 | } | ||
433 | |||
434 | #define TOKEN(proto, port, token) (((proto)<<12)|(token)|(port)) | ||
435 | |||
436 | static int socal_hw_enque (fc_channel *fc, fcp_cmnd *fcmd) | ||
437 | { | ||
438 | socal_port *port = (socal_port *)fc; | ||
439 | struct socal *s = port->s; | ||
440 | unsigned long qno; | ||
441 | socal_cq *sw_cq; | ||
442 | int cq_next_in; | ||
443 | socal_req *request; | ||
444 | fc_hdr *fch; | ||
445 | int i; | ||
446 | |||
447 | if (fcmd->proto == TYPE_SCSI_FCP) | ||
448 | qno = 1; | ||
449 | else | ||
450 | qno = 0; | ||
451 | SOD(("Putting a FCP packet type %d into hw queue %d\n", fcmd->proto, qno)) | ||
452 | if (s->imask & (SOCAL_IMASK_REQ_Q0 << qno)) { | ||
453 | SOD(("EIO %08x\n", s->imask)) | ||
454 | return -EIO; | ||
455 | } | ||
456 | sw_cq = s->req + qno; | ||
457 | cq_next_in = (sw_cq->in + 1) & sw_cq->last; | ||
458 | |||
459 | if (cq_next_in == sw_cq->out && | ||
460 | cq_next_in == (sw_cq->out = sbus_readb(s->regs + REQP + qno))) { | ||
461 | SOD(("%d IN %d OUT %d LAST %d\n", | ||
462 | qno, sw_cq->in, | ||
463 | sw_cq->out, sw_cq->last)) | ||
464 | SOCAL_SETIMASK(s, s->imask | (SOCAL_IMASK_REQ_Q0 << qno)); | ||
465 | SOD(("imask %08x %08x\n", s->imask, sbus_readl(s->regs + IMASK))); | ||
466 | |||
467 | /* If queue is full, just say NO. */ | ||
468 | return -EBUSY; | ||
469 | } | ||
470 | |||
471 | request = sw_cq->pool + sw_cq->in; | ||
472 | fch = &request->fchdr; | ||
473 | |||
474 | switch (fcmd->proto) { | ||
475 | case TYPE_SCSI_FCP: | ||
476 | request->shdr.token = TOKEN(TYPE_SCSI_FCP, port->mask, fcmd->token); | ||
477 | request->data[0].base = fc->dma_scsi_cmd + fcmd->token * sizeof(fcp_cmd); | ||
478 | request->data[0].count = sizeof(fcp_cmd); | ||
479 | request->data[1].base = fc->dma_scsi_rsp + fcmd->token * fc->rsp_size; | ||
480 | request->data[1].count = fc->rsp_size; | ||
481 | if (fcmd->data) { | ||
482 | request->shdr.segcnt = 3; | ||
483 | i = fc->scsi_cmd_pool[fcmd->token].fcp_data_len; | ||
484 | request->shdr.bytecnt = i; | ||
485 | request->data[2].base = fcmd->data; | ||
486 | request->data[2].count = i; | ||
487 | request->type = (fc->scsi_cmd_pool[fcmd->token].fcp_cntl & FCP_CNTL_WRITE) ? | ||
488 | SOCAL_CQTYPE_IO_WRITE : SOCAL_CQTYPE_IO_READ; | ||
489 | } else { | ||
490 | request->shdr.segcnt = 2; | ||
491 | request->shdr.bytecnt = 0; | ||
492 | request->data[2].base = 0; | ||
493 | request->data[2].count = 0; | ||
494 | request->type = SOCAL_CQTYPE_SIMPLE; | ||
495 | } | ||
496 | FILL_FCHDR_RCTL_DID(fch, R_CTL_COMMAND, fcmd->did); | ||
497 | FILL_FCHDR_SID(fch, fc->sid); | ||
498 | FILL_FCHDR_TYPE_FCTL(fch, TYPE_SCSI_FCP, F_CTL_FIRST_SEQ | F_CTL_SEQ_INITIATIVE); | ||
499 | FILL_FCHDR_SEQ_DF_SEQ(fch, 0, 0, 0); | ||
500 | FILL_FCHDR_OXRX(fch, 0xffff, 0xffff); | ||
501 | fch->param = 0; | ||
502 | request->shdr.flags = port->flags; | ||
503 | request->shdr.class = fc->posmap ? 3 : 2; | ||
504 | break; | ||
505 | |||
506 | case PROTO_OFFLINE: | ||
507 | memset (request, 0, sizeof(*request)); | ||
508 | request->shdr.token = TOKEN(PROTO_OFFLINE, port->mask, fcmd->token); | ||
509 | request->type = SOCAL_CQTYPE_OFFLINE; | ||
510 | FILL_FCHDR_RCTL_DID(fch, R_CTL_COMMAND, fcmd->did); | ||
511 | FILL_FCHDR_SID(fch, fc->sid); | ||
512 | FILL_FCHDR_TYPE_FCTL(fch, TYPE_SCSI_FCP, F_CTL_FIRST_SEQ | F_CTL_SEQ_INITIATIVE); | ||
513 | FILL_FCHDR_SEQ_DF_SEQ(fch, 0, 0, 0); | ||
514 | FILL_FCHDR_OXRX(fch, 0xffff, 0xffff); | ||
515 | request->shdr.flags = port->flags; | ||
516 | break; | ||
517 | |||
518 | case PROTO_REPORT_AL_MAP: | ||
519 | memset (request, 0, sizeof(*request)); | ||
520 | request->shdr.token = TOKEN(PROTO_REPORT_AL_MAP, port->mask, fcmd->token); | ||
521 | request->type = SOCAL_CQTYPE_REPORT_MAP; | ||
522 | request->shdr.flags = port->flags; | ||
523 | request->shdr.segcnt = 1; | ||
524 | request->shdr.bytecnt = sizeof(fc_al_posmap); | ||
525 | request->data[0].base = fcmd->cmd; | ||
526 | request->data[0].count = sizeof(fc_al_posmap); | ||
527 | break; | ||
528 | |||
529 | default: | ||
530 | request->shdr.token = TOKEN(fcmd->proto, port->mask, fcmd->token); | ||
531 | request->shdr.class = fc->posmap ? 3 : 2; | ||
532 | request->shdr.flags = port->flags; | ||
533 | memcpy (fch, &fcmd->fch, sizeof(fc_hdr)); | ||
534 | request->data[0].count = fcmd->cmdlen; | ||
535 | request->data[1].count = fcmd->rsplen; | ||
536 | request->type = fcmd->class; | ||
537 | switch (fcmd->class) { | ||
538 | case FC_CLASS_OUTBOUND: | ||
539 | request->data[0].base = fcmd->cmd; | ||
540 | request->data[0].count = fcmd->cmdlen; | ||
541 | request->type = SOCAL_CQTYPE_OUTBOUND; | ||
542 | request->shdr.bytecnt = fcmd->cmdlen; | ||
543 | request->shdr.segcnt = 1; | ||
544 | break; | ||
545 | case FC_CLASS_INBOUND: | ||
546 | request->data[0].base = fcmd->rsp; | ||
547 | request->data[0].count = fcmd->rsplen; | ||
548 | request->type = SOCAL_CQTYPE_INBOUND; | ||
549 | request->shdr.bytecnt = 0; | ||
550 | request->shdr.segcnt = 1; | ||
551 | break; | ||
552 | case FC_CLASS_SIMPLE: | ||
553 | request->data[0].base = fcmd->cmd; | ||
554 | request->data[1].base = fcmd->rsp; | ||
555 | request->data[0].count = fcmd->cmdlen; | ||
556 | request->data[1].count = fcmd->rsplen; | ||
557 | request->type = SOCAL_CQTYPE_SIMPLE; | ||
558 | request->shdr.bytecnt = fcmd->cmdlen; | ||
559 | request->shdr.segcnt = 2; | ||
560 | break; | ||
561 | case FC_CLASS_IO_READ: | ||
562 | case FC_CLASS_IO_WRITE: | ||
563 | request->data[0].base = fcmd->cmd; | ||
564 | request->data[1].base = fcmd->rsp; | ||
565 | request->data[0].count = fcmd->cmdlen; | ||
566 | request->data[1].count = fcmd->rsplen; | ||
567 | request->type = (fcmd->class == FC_CLASS_IO_READ) ? SOCAL_CQTYPE_IO_READ : SOCAL_CQTYPE_IO_WRITE; | ||
568 | if (fcmd->data) { | ||
569 | request->data[2].base = fcmd->data; | ||
570 | request->data[2].count = fcmd->datalen; | ||
571 | request->shdr.bytecnt = fcmd->datalen; | ||
572 | request->shdr.segcnt = 3; | ||
573 | } else { | ||
574 | request->shdr.bytecnt = 0; | ||
575 | request->shdr.segcnt = 2; | ||
576 | } | ||
577 | break; | ||
578 | } | ||
579 | break; | ||
580 | } | ||
581 | |||
582 | request->count = 1; | ||
583 | request->flags = 0; | ||
584 | request->seqno = sw_cq->seqno; | ||
585 | |||
586 | SOD(("queueing token %08x\n", request->shdr.token)) | ||
587 | |||
588 | /* And now tell the SOCAL about it */ | ||
589 | |||
590 | if (++sw_cq->in > sw_cq->last) { | ||
591 | sw_cq->in = 0; | ||
592 | sw_cq->seqno++; | ||
593 | } | ||
594 | |||
595 | SOD(("Putting %08x into cmd\n", SOCAL_CMD_RSP_QALL | (sw_cq->in << 24) | (SOCAL_CMD_REQ_Q0 << qno))) | ||
596 | |||
597 | sbus_writel(SOCAL_CMD_RSP_QALL | (sw_cq->in << 24) | (SOCAL_CMD_REQ_Q0 << qno), | ||
598 | s->regs + CMD); | ||
599 | |||
600 | /* Read so that command is completed */ | ||
601 | sbus_readl(s->regs + CMD); | ||
602 | |||
603 | return 0; | ||
604 | } | ||
605 | |||
606 | static inline void socal_download_fw(struct socal *s) | ||
607 | { | ||
608 | #ifdef HAVE_SOCAL_UCODE | ||
609 | SOD(("Loading %ld bytes from %p to %p\n", sizeof(socal_ucode), socal_ucode, s->xram)) | ||
610 | socal_copy_to_xram(s->xram, socal_ucode, sizeof(socal_ucode)); | ||
611 | SOD(("Clearing the rest of memory\n")) | ||
612 | socal_bzero (s->xram + sizeof(socal_ucode), 65536 - sizeof(socal_ucode)); | ||
613 | SOD(("Done\n")) | ||
614 | #endif | ||
615 | } | ||
616 | |||
617 | /* Check for what the best SBUS burst we can use happens | ||
618 | * to be on this machine. | ||
619 | */ | ||
620 | static inline void socal_init_bursts(struct socal *s, struct sbus_dev *sdev) | ||
621 | { | ||
622 | int bsizes, bsizes_more; | ||
623 | u32 cfg; | ||
624 | |||
625 | bsizes = (prom_getintdefault(sdev->prom_node,"burst-sizes",0xff) & 0xff); | ||
626 | bsizes_more = (prom_getintdefault(sdev->bus->prom_node, "burst-sizes", 0xff) & 0xff); | ||
627 | bsizes &= bsizes_more; | ||
628 | #ifdef USE_64BIT_MODE | ||
629 | #ifdef __sparc_v9__ | ||
630 | mmu_set_sbus64(sdev, bsizes >> 16); | ||
631 | #endif | ||
632 | #endif | ||
633 | if ((bsizes & 0x7f) == 0x7f) | ||
634 | cfg = SOCAL_CFG_BURST_64; | ||
635 | else if ((bsizes & 0x3f) == 0x3f) | ||
636 | cfg = SOCAL_CFG_BURST_32; | ||
637 | else if ((bsizes & 0x1f) == 0x1f) | ||
638 | cfg = SOCAL_CFG_BURST_16; | ||
639 | else | ||
640 | cfg = SOCAL_CFG_BURST_4; | ||
641 | #ifdef USE_64BIT_MODE | ||
642 | #ifdef __sparc_v9__ | ||
643 | /* What is BURST_128? -jj */ | ||
644 | if ((bsizes & 0x780000) == 0x780000) | ||
645 | cfg |= (SOCAL_CFG_BURST_64 << 8) | SOCAL_CFG_SBUS_ENHANCED; | ||
646 | else if ((bsizes & 0x380000) == 0x380000) | ||
647 | cfg |= (SOCAL_CFG_BURST_32 << 8) | SOCAL_CFG_SBUS_ENHANCED; | ||
648 | else if ((bsizes & 0x180000) == 0x180000) | ||
649 | cfg |= (SOCAL_CFG_BURST_16 << 8) | SOCAL_CFG_SBUS_ENHANCED; | ||
650 | else | ||
651 | cfg |= (SOCAL_CFG_BURST_8 << 8) | SOCAL_CFG_SBUS_ENHANCED; | ||
652 | #endif | ||
653 | #endif | ||
654 | s->cfg = cfg; | ||
655 | } | ||
656 | |||
657 | static inline void socal_init(struct sbus_dev *sdev, int no) | ||
658 | { | ||
659 | unsigned char tmp[60]; | ||
660 | int propl; | ||
661 | struct socal *s; | ||
662 | static unsigned version_printed = 0; | ||
663 | socal_hw_cq cq[8]; | ||
664 | int size, i; | ||
665 | int irq, node; | ||
666 | |||
667 | s = kzalloc (sizeof (struct socal), GFP_KERNEL); | ||
668 | if (!s) return; | ||
669 | spin_lock_init(&s->lock); | ||
670 | s->socal_no = no; | ||
671 | |||
672 | SOD(("socals %08lx socal_intr %08lx socal_hw_enque %08lx\n", | ||
673 | (long)socals, (long)socal_intr, (long)socal_hw_enque)) | ||
674 | if (version_printed++ == 0) | ||
675 | printk (version); | ||
676 | |||
677 | s->port[0].fc.module = THIS_MODULE; | ||
678 | s->port[1].fc.module = THIS_MODULE; | ||
679 | |||
680 | s->next = socals; | ||
681 | socals = s; | ||
682 | s->port[0].fc.dev = sdev; | ||
683 | s->port[1].fc.dev = sdev; | ||
684 | s->port[0].s = s; | ||
685 | s->port[1].s = s; | ||
686 | |||
687 | s->port[0].fc.next = &s->port[1].fc; | ||
688 | |||
689 | /* World Wide Name of SOCAL */ | ||
690 | propl = prom_getproperty (sdev->prom_node, "wwn", tmp, sizeof(tmp)); | ||
691 | if (propl != sizeof (fc_wwn)) { | ||
692 | s->wwn.naaid = NAAID_IEEE_REG; | ||
693 | s->wwn.nportid = 0x123; | ||
694 | s->wwn.hi = 0x1234; | ||
695 | s->wwn.lo = 0x12345678; | ||
696 | } else | ||
697 | memcpy (&s->wwn, tmp, sizeof (fc_wwn)); | ||
698 | |||
699 | memcpy (&s->port[0].fc.wwn_nport, &s->wwn, sizeof (fc_wwn)); | ||
700 | s->port[0].fc.wwn_nport.lo++; | ||
701 | memcpy (&s->port[1].fc.wwn_nport, &s->wwn, sizeof (fc_wwn)); | ||
702 | s->port[1].fc.wwn_nport.lo+=2; | ||
703 | |||
704 | node = prom_getchild (sdev->prom_node); | ||
705 | while (node && (node = prom_searchsiblings (node, "sf"))) { | ||
706 | int port; | ||
707 | |||
708 | port = prom_getintdefault(node, "port#", -1); | ||
709 | switch (port) { | ||
710 | case 0: | ||
711 | case 1: | ||
712 | if (prom_getproplen(node, "port-wwn") == sizeof (fc_wwn)) | ||
713 | prom_getproperty (node, "port-wwn", | ||
714 | (char *)&s->port[port].fc.wwn_nport, | ||
715 | sizeof (fc_wwn)); | ||
716 | break; | ||
717 | default: | ||
718 | break; | ||
719 | }; | ||
720 | |||
721 | node = prom_getsibling(node); | ||
722 | } | ||
723 | |||
724 | memcpy (&s->port[0].fc.wwn_node, &s->wwn, sizeof (fc_wwn)); | ||
725 | memcpy (&s->port[1].fc.wwn_node, &s->wwn, sizeof (fc_wwn)); | ||
726 | SOD(("Got wwns %08x%08x ports %08x%08x and %08x%08x\n", | ||
727 | *(u32 *)&s->port[0].fc.wwn_node, s->port[0].fc.wwn_node.lo, | ||
728 | *(u32 *)&s->port[0].fc.wwn_nport, s->port[0].fc.wwn_nport.lo, | ||
729 | *(u32 *)&s->port[1].fc.wwn_nport, s->port[1].fc.wwn_nport.lo)) | ||
730 | |||
731 | s->port[0].fc.sid = 1; | ||
732 | s->port[1].fc.sid = 17; | ||
733 | s->port[0].fc.did = 2; | ||
734 | s->port[1].fc.did = 18; | ||
735 | |||
736 | s->port[0].fc.reset = socal_reset; | ||
737 | s->port[1].fc.reset = socal_reset; | ||
738 | |||
739 | if (sdev->num_registers == 1) { | ||
740 | s->eeprom = sbus_ioremap(&sdev->resource[0], 0, | ||
741 | sdev->reg_addrs[0].reg_size, "socal xram"); | ||
742 | if (sdev->reg_addrs[0].reg_size > 0x20000) | ||
743 | s->xram = s->eeprom + 0x10000UL; | ||
744 | else | ||
745 | s->xram = s->eeprom; | ||
746 | s->regs = (s->xram + 0x10000UL); | ||
747 | } else { | ||
748 | /* E.g. starfire presents 3 registers for SOCAL */ | ||
749 | s->xram = sbus_ioremap(&sdev->resource[1], 0, | ||
750 | sdev->reg_addrs[1].reg_size, "socal xram"); | ||
751 | s->regs = sbus_ioremap(&sdev->resource[2], 0, | ||
752 | sdev->reg_addrs[2].reg_size, "socal regs"); | ||
753 | } | ||
754 | |||
755 | socal_init_bursts(s, sdev); | ||
756 | |||
757 | SOD(("Disabling SOCAL\n")) | ||
758 | |||
759 | socal_disable (s); | ||
760 | |||
761 | irq = sdev->irqs[0]; | ||
762 | |||
763 | if (request_irq (irq, socal_intr, IRQF_SHARED, "SOCAL", (void *)s)) { | ||
764 | socal_printk ("Cannot order irq %d to go\n", irq); | ||
765 | socals = s->next; | ||
766 | return; | ||
767 | } | ||
768 | |||
769 | SOD(("SOCAL uses IRQ %d\n", irq)) | ||
770 | |||
771 | s->port[0].fc.irq = irq; | ||
772 | s->port[1].fc.irq = irq; | ||
773 | |||
774 | sprintf (s->port[0].fc.name, "socal%d port A", no); | ||
775 | sprintf (s->port[1].fc.name, "socal%d port B", no); | ||
776 | s->port[0].flags = SOCAL_FC_HDR | SOCAL_PORT_A; | ||
777 | s->port[1].flags = SOCAL_FC_HDR | SOCAL_PORT_B; | ||
778 | s->port[1].mask = (1 << 11); | ||
779 | |||
780 | s->port[0].fc.hw_enque = socal_hw_enque; | ||
781 | s->port[1].fc.hw_enque = socal_hw_enque; | ||
782 | |||
783 | socal_download_fw (s); | ||
784 | |||
785 | SOD(("Downloaded firmware\n")) | ||
786 | |||
787 | /* Now setup xram circular queues */ | ||
788 | memset (cq, 0, sizeof(cq)); | ||
789 | |||
790 | size = (SOCAL_CQ_REQ0_SIZE + SOCAL_CQ_REQ1_SIZE + | ||
791 | SOCAL_CQ_RSP0_SIZE + SOCAL_CQ_RSP1_SIZE + | ||
792 | SOCAL_CQ_RSP2_SIZE) * sizeof(socal_req); | ||
793 | s->req_cpu = sbus_alloc_consistent(sdev, size, &s->req_dvma); | ||
794 | s->req[0].pool = s->req_cpu; | ||
795 | cq[0].address = s->req_dvma; | ||
796 | s->req[1].pool = s->req[0].pool + SOCAL_CQ_REQ0_SIZE; | ||
797 | s->rsp[0].pool = s->req[1].pool + SOCAL_CQ_REQ1_SIZE; | ||
798 | s->rsp[1].pool = s->rsp[0].pool + SOCAL_CQ_RSP0_SIZE; | ||
799 | s->rsp[2].pool = s->rsp[1].pool + SOCAL_CQ_RSP1_SIZE; | ||
800 | |||
801 | s->req[0].hw_cq = (socal_hw_cq __iomem *)(s->xram + SOCAL_CQ_REQ_OFFSET); | ||
802 | s->req[1].hw_cq = (socal_hw_cq __iomem *)(s->xram + SOCAL_CQ_REQ_OFFSET + sizeof(socal_hw_cq)); | ||
803 | s->rsp[0].hw_cq = (socal_hw_cq __iomem *)(s->xram + SOCAL_CQ_RSP_OFFSET); | ||
804 | s->rsp[1].hw_cq = (socal_hw_cq __iomem *)(s->xram + SOCAL_CQ_RSP_OFFSET + sizeof(socal_hw_cq)); | ||
805 | s->rsp[2].hw_cq = (socal_hw_cq __iomem *)(s->xram + SOCAL_CQ_RSP_OFFSET + 2 * sizeof(socal_hw_cq)); | ||
806 | |||
807 | cq[1].address = cq[0].address + (SOCAL_CQ_REQ0_SIZE * sizeof(socal_req)); | ||
808 | cq[4].address = cq[1].address + (SOCAL_CQ_REQ1_SIZE * sizeof(socal_req)); | ||
809 | cq[5].address = cq[4].address + (SOCAL_CQ_RSP0_SIZE * sizeof(socal_req)); | ||
810 | cq[6].address = cq[5].address + (SOCAL_CQ_RSP1_SIZE * sizeof(socal_req)); | ||
811 | |||
812 | cq[0].last = SOCAL_CQ_REQ0_SIZE - 1; | ||
813 | cq[1].last = SOCAL_CQ_REQ1_SIZE - 1; | ||
814 | cq[4].last = SOCAL_CQ_RSP0_SIZE - 1; | ||
815 | cq[5].last = SOCAL_CQ_RSP1_SIZE - 1; | ||
816 | cq[6].last = SOCAL_CQ_RSP2_SIZE - 1; | ||
817 | for (i = 0; i < 8; i++) | ||
818 | cq[i].seqno = 1; | ||
819 | |||
820 | s->req[0].last = SOCAL_CQ_REQ0_SIZE - 1; | ||
821 | s->req[1].last = SOCAL_CQ_REQ1_SIZE - 1; | ||
822 | s->rsp[0].last = SOCAL_CQ_RSP0_SIZE - 1; | ||
823 | s->rsp[1].last = SOCAL_CQ_RSP1_SIZE - 1; | ||
824 | s->rsp[2].last = SOCAL_CQ_RSP2_SIZE - 1; | ||
825 | |||
826 | s->req[0].seqno = 1; | ||
827 | s->req[1].seqno = 1; | ||
828 | s->rsp[0].seqno = 1; | ||
829 | s->rsp[1].seqno = 1; | ||
830 | s->rsp[2].seqno = 1; | ||
831 | |||
832 | socal_copy_to_xram(s->xram + SOCAL_CQ_REQ_OFFSET, cq, sizeof(cq)); | ||
833 | |||
834 | SOD(("Setting up params\n")) | ||
835 | |||
836 | /* Make our sw copy of SOCAL service parameters */ | ||
837 | socal_copy_from_xram(s->serv_params, s->xram + 0x280, sizeof (s->serv_params)); | ||
838 | |||
839 | s->port[0].fc.common_svc = (common_svc_parm *)s->serv_params; | ||
840 | s->port[0].fc.class_svcs = (svc_parm *)(s->serv_params + 0x20); | ||
841 | s->port[1].fc.common_svc = (common_svc_parm *)&s->serv_params; | ||
842 | s->port[1].fc.class_svcs = (svc_parm *)(s->serv_params + 0x20); | ||
843 | |||
844 | socal_enable (s); | ||
845 | |||
846 | SOD(("Enabled SOCAL\n")) | ||
847 | } | ||
848 | |||
849 | static int __init socal_probe(void) | ||
850 | { | ||
851 | struct sbus_bus *sbus; | ||
852 | struct sbus_dev *sdev = NULL; | ||
853 | struct socal *s; | ||
854 | int cards = 0; | ||
855 | |||
856 | for_each_sbus(sbus) { | ||
857 | for_each_sbusdev(sdev, sbus) { | ||
858 | if(!strcmp(sdev->prom_name, "SUNW,socal")) { | ||
859 | socal_init(sdev, cards); | ||
860 | cards++; | ||
861 | } | ||
862 | } | ||
863 | } | ||
864 | if (!cards) | ||
865 | return -EIO; | ||
866 | |||
867 | for_each_socal(s) | ||
868 | if (s->next) | ||
869 | s->port[1].fc.next = &s->next->port[0].fc; | ||
870 | |||
871 | fcp_init (&socals->port[0].fc); | ||
872 | return 0; | ||
873 | } | ||
874 | |||
875 | static void __exit socal_cleanup(void) | ||
876 | { | ||
877 | struct socal *s; | ||
878 | int irq; | ||
879 | struct sbus_dev *sdev; | ||
880 | |||
881 | for_each_socal(s) { | ||
882 | irq = s->port[0].fc.irq; | ||
883 | free_irq (irq, s); | ||
884 | |||
885 | fcp_release(&(s->port[0].fc), 2); | ||
886 | |||
887 | sdev = s->port[0].fc.dev; | ||
888 | if (sdev->num_registers == 1) { | ||
889 | sbus_iounmap(s->eeprom, sdev->reg_addrs[0].reg_size); | ||
890 | } else { | ||
891 | sbus_iounmap(s->xram, sdev->reg_addrs[1].reg_size); | ||
892 | sbus_iounmap(s->regs, sdev->reg_addrs[2].reg_size); | ||
893 | } | ||
894 | sbus_free_consistent(sdev, | ||
895 | (SOCAL_CQ_REQ0_SIZE + SOCAL_CQ_REQ1_SIZE + | ||
896 | SOCAL_CQ_RSP0_SIZE + SOCAL_CQ_RSP1_SIZE + | ||
897 | SOCAL_CQ_RSP2_SIZE) * sizeof(socal_req), | ||
898 | s->req_cpu, s->req_dvma); | ||
899 | } | ||
900 | } | ||
901 | |||
902 | module_init(socal_probe); | ||
903 | module_exit(socal_cleanup); | ||
904 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/fc4/socal.h b/drivers/fc4/socal.h deleted file mode 100644 index 774edf68e4d2..000000000000 --- a/drivers/fc4/socal.h +++ /dev/null | |||
@@ -1,314 +0,0 @@ | |||
1 | /* socal.h: Definitions for Sparc SUNW,socal (SOC+) Fibre Channel Sbus driver. | ||
2 | * | ||
3 | * Copyright (C) 1998,1999 Jakub Jelinek (jj@ultra.linux.cz) | ||
4 | */ | ||
5 | |||
6 | #ifndef __SOCAL_H | ||
7 | #define __SOCAL_H | ||
8 | |||
9 | #include "fc.h" | ||
10 | #include "fcp.h" | ||
11 | #include "fcp_impl.h" | ||
12 | |||
13 | /* Hardware register offsets and constants first {{{ */ | ||
14 | #define CFG 0x00UL | ||
15 | #define SAE 0x04UL | ||
16 | #define CMD 0x08UL | ||
17 | #define IMASK 0x0cUL | ||
18 | #define REQP 0x10UL | ||
19 | #define RESP 0x14UL | ||
20 | |||
21 | /* Config Register */ | ||
22 | #define SOCAL_CFG_EXT_RAM_BANK_MASK 0x07000000 | ||
23 | #define SOCAL_CFG_EEPROM_BANK_MASK 0x00030000 | ||
24 | #define SOCAL_CFG_BURST64_MASK 0x00000700 | ||
25 | #define SOCAL_CFG_SBUS_PARITY_TEST 0x00000020 | ||
26 | #define SOCAL_CFG_SBUS_PARITY_CHECK 0x00000010 | ||
27 | #define SOCAL_CFG_SBUS_ENHANCED 0x00000008 | ||
28 | #define SOCAL_CFG_BURST_MASK 0x00000007 | ||
29 | /* Bursts */ | ||
30 | #define SOCAL_CFG_BURST_4 0x00000000 | ||
31 | #define SOCAL_CFG_BURST_8 0x00000003 | ||
32 | #define SOCAL_CFG_BURST_16 0x00000004 | ||
33 | #define SOCAL_CFG_BURST_32 0x00000005 | ||
34 | #define SOCAL_CFG_BURST_64 0x00000006 | ||
35 | #define SOCAL_CFG_BURST_128 0x00000007 | ||
36 | |||
37 | /* Slave Access Error Register */ | ||
38 | #define SOCAL_SAE_ALIGNMENT 0x00000004 | ||
39 | #define SOCAL_SAE_UNSUPPORTED 0x00000002 | ||
40 | #define SOCAL_SAE_PARITY 0x00000001 | ||
41 | |||
42 | /* Command & Status Register */ | ||
43 | #define SOCAL_CMD_RSP_QALL 0x000f0000 | ||
44 | #define SOCAL_CMD_RSP_Q0 0x00010000 | ||
45 | #define SOCAL_CMD_RSP_Q1 0x00020000 | ||
46 | #define SOCAL_CMD_RSP_Q2 0x00040000 | ||
47 | #define SOCAL_CMD_RSP_Q3 0x00080000 | ||
48 | #define SOCAL_CMD_REQ_QALL 0x00000f00 | ||
49 | #define SOCAL_CMD_REQ_Q0 0x00000100 | ||
50 | #define SOCAL_CMD_REQ_Q1 0x00000200 | ||
51 | #define SOCAL_CMD_REQ_Q2 0x00000400 | ||
52 | #define SOCAL_CMD_REQ_Q3 0x00000800 | ||
53 | #define SOCAL_CMD_SAE 0x00000080 | ||
54 | #define SOCAL_CMD_INTR_PENDING 0x00000008 | ||
55 | #define SOCAL_CMD_NON_QUEUED 0x00000004 | ||
56 | #define SOCAL_CMD_IDLE 0x00000002 | ||
57 | #define SOCAL_CMD_SOFT_RESET 0x00000001 | ||
58 | |||
59 | /* Interrupt Mask Register */ | ||
60 | #define SOCAL_IMASK_RSP_QALL 0x000f0000 | ||
61 | #define SOCAL_IMASK_RSP_Q0 0x00010000 | ||
62 | #define SOCAL_IMASK_RSP_Q1 0x00020000 | ||
63 | #define SOCAL_IMASK_RSP_Q2 0x00040000 | ||
64 | #define SOCAL_IMASK_RSP_Q3 0x00080000 | ||
65 | #define SOCAL_IMASK_REQ_QALL 0x00000f00 | ||
66 | #define SOCAL_IMASK_REQ_Q0 0x00000100 | ||
67 | #define SOCAL_IMASK_REQ_Q1 0x00000200 | ||
68 | #define SOCAL_IMASK_REQ_Q2 0x00000400 | ||
69 | #define SOCAL_IMASK_REQ_Q3 0x00000800 | ||
70 | #define SOCAL_IMASK_SAE 0x00000080 | ||
71 | #define SOCAL_IMASK_NON_QUEUED 0x00000004 | ||
72 | |||
73 | #define SOCAL_INTR(s, cmd) \ | ||
74 | (((cmd & SOCAL_CMD_RSP_QALL) | ((~cmd) & SOCAL_CMD_REQ_QALL)) \ | ||
75 | & s->imask) | ||
76 | |||
77 | #define SOCAL_SETIMASK(s, i) \ | ||
78 | do { (s)->imask = (i); \ | ||
79 | sbus_writel((i), (s)->regs + IMASK); \ | ||
80 | } while (0) | ||
81 | |||
82 | #define SOCAL_MAX_EXCHANGES 1024 | ||
83 | |||
84 | /* XRAM | ||
85 | * | ||
86 | * This is a 64KB register area. | ||
87 | * From the documentation, it seems like it is finally able to cope | ||
88 | * at least with 1,2,4 byte accesses for read and 2,4 byte accesses for write. | ||
89 | */ | ||
90 | |||
91 | /* Circular Queue */ | ||
92 | |||
93 | #define SOCAL_CQ_REQ_OFFSET 0x200 | ||
94 | #define SOCAL_CQ_RSP_OFFSET 0x220 | ||
95 | |||
96 | typedef struct { | ||
97 | u32 address; | ||
98 | u8 in; | ||
99 | u8 out; | ||
100 | u8 last; | ||
101 | u8 seqno; | ||
102 | } socal_hw_cq; | ||
103 | |||
104 | #define SOCAL_PORT_A 0x0000 /* From/To Port A */ | ||
105 | #define SOCAL_PORT_B 0x0001 /* From/To Port A */ | ||
106 | #define SOCAL_FC_HDR 0x0002 /* Contains FC Header */ | ||
107 | #define SOCAL_NORSP 0x0004 /* Don't generate response nor interrupt */ | ||
108 | #define SOCAL_NOINT 0x0008 /* Generate response but not interrupt */ | ||
109 | #define SOCAL_XFERRDY 0x0010 /* Generate XFERRDY */ | ||
110 | #define SOCAL_IGNOREPARAM 0x0020 /* Ignore PARAM field in the FC header */ | ||
111 | #define SOCAL_COMPLETE 0x0040 /* Command completed */ | ||
112 | #define SOCAL_UNSOLICITED 0x0080 /* For request this is the packet to establish unsolicited pools, */ | ||
113 | /* for rsp this is unsolicited packet */ | ||
114 | #define SOCAL_STATUS 0x0100 /* State change (on/off line) */ | ||
115 | #define SOCAL_RSP_HDR 0x0200 /* Return frame header in any case */ | ||
116 | |||
117 | typedef struct { | ||
118 | u32 token; | ||
119 | u16 flags; | ||
120 | u8 class; | ||
121 | u8 segcnt; | ||
122 | u32 bytecnt; | ||
123 | } socal_hdr; | ||
124 | |||
125 | typedef struct { | ||
126 | u32 base; | ||
127 | u32 count; | ||
128 | } socal_data; | ||
129 | |||
130 | #define SOCAL_CQTYPE_NOP 0x00 | ||
131 | #define SOCAL_CQTYPE_OUTBOUND 0x01 | ||
132 | #define SOCAL_CQTYPE_INBOUND 0x02 | ||
133 | #define SOCAL_CQTYPE_SIMPLE 0x03 | ||
134 | #define SOCAL_CQTYPE_IO_WRITE 0x04 | ||
135 | #define SOCAL_CQTYPE_IO_READ 0x05 | ||
136 | #define SOCAL_CQTYPE_UNSOLICITED 0x06 | ||
137 | #define SOCAL_CQTYPE_BYPASS_DEV 0x06 | ||
138 | #define SOCAL_CQTYPE_DIAG 0x07 | ||
139 | #define SOCAL_CQTYPE_OFFLINE 0x08 | ||
140 | #define SOCAL_CQTYPE_ADD_POOL 0x09 | ||
141 | #define SOCAL_CQTYPE_DELETE_POOL 0x0a | ||
142 | #define SOCAL_CQTYPE_ADD_BUFFER 0x0b | ||
143 | #define SOCAL_CQTYPE_ADD_POOL_BUFFER 0x0c | ||
144 | #define SOCAL_CQTYPE_REQUEST_ABORT 0x0d | ||
145 | #define SOCAL_CQTYPE_REQUEST_LIP 0x0e | ||
146 | #define SOCAL_CQTYPE_REPORT_MAP 0x0f | ||
147 | #define SOCAL_CQTYPE_RESPONSE 0x10 | ||
148 | #define SOCAL_CQTYPE_INLINE 0x20 | ||
149 | |||
150 | #define SOCAL_CQFLAGS_CONT 0x01 | ||
151 | #define SOCAL_CQFLAGS_FULL 0x02 | ||
152 | #define SOCAL_CQFLAGS_BADHDR 0x04 | ||
153 | #define SOCAL_CQFLAGS_BADPKT 0x08 | ||
154 | |||
155 | typedef struct { | ||
156 | socal_hdr shdr; | ||
157 | socal_data data[3]; | ||
158 | fc_hdr fchdr; | ||
159 | u8 count; | ||
160 | u8 type; | ||
161 | u8 flags; | ||
162 | u8 seqno; | ||
163 | } socal_req; | ||
164 | |||
165 | #define SOCAL_OK 0 | ||
166 | #define SOCAL_P_RJT 2 | ||
167 | #define SOCAL_F_RJT 3 | ||
168 | #define SOCAL_P_BSY 4 | ||
169 | #define SOCAL_F_BSY 5 | ||
170 | #define SOCAL_ONLINE 0x10 | ||
171 | #define SOCAL_OFFLINE 0x11 | ||
172 | #define SOCAL_TIMEOUT 0x12 | ||
173 | #define SOCAL_OVERRUN 0x13 | ||
174 | #define SOCAL_ONLINE_LOOP 0x14 | ||
175 | #define SOCAL_OLD_PORT 0x15 | ||
176 | #define SOCAL_AL_PORT 0x16 | ||
177 | #define SOCAL_UNKOWN_CQ_TYPE 0x20 | ||
178 | #define SOCAL_BAD_SEG_CNT 0x21 | ||
179 | #define SOCAL_MAX_XCHG_EXCEEDED 0x22 | ||
180 | #define SOCAL_BAD_XID 0x23 | ||
181 | #define SOCAL_XCHG_BUSY 0x24 | ||
182 | #define SOCAL_BAD_POOL_ID 0x25 | ||
183 | #define SOCAL_INSUFFICIENT_CQES 0x26 | ||
184 | #define SOCAL_ALLOC_FAIL 0x27 | ||
185 | #define SOCAL_BAD_SID 0x28 | ||
186 | #define SOCAL_NO_SEG_INIT 0x29 | ||
187 | #define SOCAL_BAD_DID 0x2a | ||
188 | #define SOCAL_ABORTED 0x30 | ||
189 | #define SOCAL_ABORT_FAILED 0x31 | ||
190 | |||
191 | typedef struct { | ||
192 | socal_hdr shdr; | ||
193 | u32 status; | ||
194 | socal_data data; | ||
195 | u8 xxx1[10]; | ||
196 | u16 ncmds; | ||
197 | fc_hdr fchdr; | ||
198 | u8 count; | ||
199 | u8 type; | ||
200 | u8 flags; | ||
201 | u8 seqno; | ||
202 | } socal_rsp; | ||
203 | |||
204 | typedef struct { | ||
205 | socal_hdr shdr; | ||
206 | u8 xxx1[48]; | ||
207 | u8 count; | ||
208 | u8 type; | ||
209 | u8 flags; | ||
210 | u8 seqno; | ||
211 | } socal_cmdonly; | ||
212 | |||
213 | #define SOCAL_DIAG_NOP 0x00 | ||
214 | #define SOCAL_DIAG_INT_LOOP 0x01 | ||
215 | #define SOCAL_DIAG_EXT_LOOP 0x02 | ||
216 | #define SOCAL_DIAG_REM_LOOP 0x03 | ||
217 | #define SOCAL_DIAG_XRAM_TEST 0x04 | ||
218 | #define SOCAL_DIAG_SOC_TEST 0x05 | ||
219 | #define SOCAL_DIAG_HCB_TEST 0x06 | ||
220 | #define SOCAL_DIAG_SOCLB_TEST 0x07 | ||
221 | #define SOCAL_DIAG_SRDSLB_TEST 0x08 | ||
222 | #define SOCAL_DIAG_EXTOE_TEST 0x09 | ||
223 | |||
224 | typedef struct { | ||
225 | socal_hdr shdr; | ||
226 | u32 cmd; | ||
227 | u8 xxx1[44]; | ||
228 | u8 count; | ||
229 | u8 type; | ||
230 | u8 flags; | ||
231 | u8 seqno; | ||
232 | } socal_diag_req; | ||
233 | |||
234 | #define SOCAL_POOL_MASK_RCTL 0x800000 | ||
235 | #define SOCAL_POOL_MASK_DID 0x700000 | ||
236 | #define SOCAL_POOL_MASK_SID 0x070000 | ||
237 | #define SOCAL_POOL_MASK_TYPE 0x008000 | ||
238 | #define SOCAL_POOL_MASK_F_CTL 0x007000 | ||
239 | #define SOCAL_POOL_MASK_SEQ_ID 0x000800 | ||
240 | #define SOCAL_POOL_MASK_D_CTL 0x000400 | ||
241 | #define SOCAL_POOL_MASK_SEQ_CNT 0x000300 | ||
242 | #define SOCAL_POOL_MASK_OX_ID 0x0000f0 | ||
243 | #define SOCAL_POOL_MASK_PARAM 0x00000f | ||
244 | |||
245 | typedef struct { | ||
246 | socal_hdr shdr; | ||
247 | u32 pool_id; | ||
248 | u32 header_mask; | ||
249 | u32 buf_size; | ||
250 | u32 entries; | ||
251 | u8 xxx1[8]; | ||
252 | fc_hdr fchdr; | ||
253 | u8 count; | ||
254 | u8 type; | ||
255 | u8 flags; | ||
256 | u8 seqno; | ||
257 | } socal_pool_req; | ||
258 | |||
259 | /* }}} */ | ||
260 | |||
261 | /* Now our software structures and constants we use to drive the beast {{{ */ | ||
262 | |||
263 | #define SOCAL_CQ_REQ0_SIZE 4 | ||
264 | #define SOCAL_CQ_REQ1_SIZE 256 | ||
265 | #define SOCAL_CQ_RSP0_SIZE 8 | ||
266 | #define SOCAL_CQ_RSP1_SIZE 4 | ||
267 | #define SOCAL_CQ_RSP2_SIZE 4 | ||
268 | |||
269 | #define SOCAL_SOLICITED_RSP_Q 0 | ||
270 | #define SOCAL_SOLICITED_BAD_RSP_Q 1 | ||
271 | #define SOCAL_UNSOLICITED_RSP_Q 2 | ||
272 | |||
273 | struct socal; | ||
274 | |||
275 | typedef struct { | ||
276 | /* This must come first */ | ||
277 | fc_channel fc; | ||
278 | struct socal *s; | ||
279 | u16 flags; | ||
280 | u16 mask; | ||
281 | } socal_port; | ||
282 | |||
283 | typedef struct { | ||
284 | socal_hw_cq __iomem *hw_cq; /* Related XRAM cq */ | ||
285 | socal_req *pool; | ||
286 | u8 in; | ||
287 | u8 out; | ||
288 | u8 last; | ||
289 | u8 seqno; | ||
290 | } socal_cq; | ||
291 | |||
292 | struct socal { | ||
293 | spinlock_t lock; | ||
294 | socal_port port[2]; /* Every SOCAL has one or two FC ports */ | ||
295 | socal_cq req[4]; /* Request CQs */ | ||
296 | socal_cq rsp[4]; /* Response CQs */ | ||
297 | int socal_no; | ||
298 | void __iomem *regs; | ||
299 | void __iomem *xram; | ||
300 | void __iomem *eeprom; | ||
301 | fc_wwn wwn; | ||
302 | u32 imask; /* Our copy of regs->imask */ | ||
303 | u32 cfg; /* Our copy of regs->cfg */ | ||
304 | char serv_params[80]; | ||
305 | struct socal *next; | ||
306 | int curr_port; /* Which port will have priority to fcp_queue_empty */ | ||
307 | |||
308 | socal_req * req_cpu; | ||
309 | u32 req_dvma; | ||
310 | }; | ||
311 | |||
312 | /* }}} */ | ||
313 | |||
314 | #endif /* !(__SOCAL_H) */ | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 59d4da2734c1..d0bb5b9d2120 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -1230,7 +1230,7 @@ static void quirk_jmicron_ata(struct pci_dev *pdev) | |||
1230 | case PCI_DEVICE_ID_JMICRON_JMB363: | 1230 | case PCI_DEVICE_ID_JMICRON_JMB363: |
1231 | /* Enable dual function mode, AHCI on fn 0, IDE fn1 */ | 1231 | /* Enable dual function mode, AHCI on fn 0, IDE fn1 */ |
1232 | /* Set the class codes correctly and then direct IDE 0 */ | 1232 | /* Set the class codes correctly and then direct IDE 0 */ |
1233 | conf1 |= 0x00C2A102; /* Set 1, 8, 13, 15, 17, 22, 23 */ | 1233 | conf1 |= 0x00C2A1B3; /* Set 0, 1, 4, 5, 7, 8, 13, 15, 17, 22, 23 */ |
1234 | break; | 1234 | break; |
1235 | 1235 | ||
1236 | case PCI_DEVICE_ID_JMICRON_JMB368: | 1236 | case PCI_DEVICE_ID_JMICRON_JMB368: |
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 6141389dcdb2..2e6129f13d38 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile | |||
@@ -115,7 +115,6 @@ obj-$(CONFIG_SCSI_QLOGICPTI) += qlogicpti.o | |||
115 | obj-$(CONFIG_BLK_DEV_IDESCSI) += ide-scsi.o | 115 | obj-$(CONFIG_BLK_DEV_IDESCSI) += ide-scsi.o |
116 | obj-$(CONFIG_SCSI_MESH) += mesh.o | 116 | obj-$(CONFIG_SCSI_MESH) += mesh.o |
117 | obj-$(CONFIG_SCSI_MAC53C94) += mac53c94.o | 117 | obj-$(CONFIG_SCSI_MAC53C94) += mac53c94.o |
118 | obj-$(CONFIG_SCSI_PLUTO) += pluto.o | ||
119 | obj-$(CONFIG_SCSI_DECNCR) += NCR53C9x.o dec_esp.o | 118 | obj-$(CONFIG_SCSI_DECNCR) += NCR53C9x.o dec_esp.o |
120 | obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o | 119 | obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o |
121 | obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o | 120 | obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o |
@@ -123,7 +122,6 @@ obj-$(CONFIG_SCSI_PPA) += ppa.o | |||
123 | obj-$(CONFIG_SCSI_IMM) += imm.o | 122 | obj-$(CONFIG_SCSI_IMM) += imm.o |
124 | obj-$(CONFIG_JAZZ_ESP) += esp_scsi.o jazz_esp.o | 123 | obj-$(CONFIG_JAZZ_ESP) += esp_scsi.o jazz_esp.o |
125 | obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o | 124 | obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o |
126 | obj-$(CONFIG_SCSI_FCAL) += fcal.o | ||
127 | obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o | 125 | obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o |
128 | obj-$(CONFIG_SCSI_SNI_53C710) += 53c700.o sni_53c710.o | 126 | obj-$(CONFIG_SCSI_SNI_53C710) += 53c700.o sni_53c710.o |
129 | obj-$(CONFIG_SCSI_NSP32) += nsp32.o | 127 | obj-$(CONFIG_SCSI_NSP32) += nsp32.o |
diff --git a/drivers/scsi/aic7xxx/aic7770.c b/drivers/scsi/aic7xxx/aic7770.c index c4d17231c828..6d86a9be538f 100644 --- a/drivers/scsi/aic7xxx/aic7770.c +++ b/drivers/scsi/aic7xxx/aic7770.c | |||
@@ -60,8 +60,6 @@ | |||
60 | #define ID_OLV_274xD 0x04907783 /* Olivetti OEM (Differential) */ | 60 | #define ID_OLV_274xD 0x04907783 /* Olivetti OEM (Differential) */ |
61 | 61 | ||
62 | static int aic7770_chip_init(struct ahc_softc *ahc); | 62 | static int aic7770_chip_init(struct ahc_softc *ahc); |
63 | static int aic7770_suspend(struct ahc_softc *ahc); | ||
64 | static int aic7770_resume(struct ahc_softc *ahc); | ||
65 | static int aha2840_load_seeprom(struct ahc_softc *ahc); | 63 | static int aha2840_load_seeprom(struct ahc_softc *ahc); |
66 | static ahc_device_setup_t ahc_aic7770_VL_setup; | 64 | static ahc_device_setup_t ahc_aic7770_VL_setup; |
67 | static ahc_device_setup_t ahc_aic7770_EISA_setup; | 65 | static ahc_device_setup_t ahc_aic7770_EISA_setup; |
@@ -155,8 +153,6 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io) | |||
155 | return (error); | 153 | return (error); |
156 | 154 | ||
157 | ahc->bus_chip_init = aic7770_chip_init; | 155 | ahc->bus_chip_init = aic7770_chip_init; |
158 | ahc->bus_suspend = aic7770_suspend; | ||
159 | ahc->bus_resume = aic7770_resume; | ||
160 | 156 | ||
161 | error = ahc_reset(ahc, /*reinit*/FALSE); | 157 | error = ahc_reset(ahc, /*reinit*/FALSE); |
162 | if (error != 0) | 158 | if (error != 0) |
@@ -272,18 +268,6 @@ aic7770_chip_init(struct ahc_softc *ahc) | |||
272 | return (ahc_chip_init(ahc)); | 268 | return (ahc_chip_init(ahc)); |
273 | } | 269 | } |
274 | 270 | ||
275 | static int | ||
276 | aic7770_suspend(struct ahc_softc *ahc) | ||
277 | { | ||
278 | return (ahc_suspend(ahc)); | ||
279 | } | ||
280 | |||
281 | static int | ||
282 | aic7770_resume(struct ahc_softc *ahc) | ||
283 | { | ||
284 | return (ahc_resume(ahc)); | ||
285 | } | ||
286 | |||
287 | /* | 271 | /* |
288 | * Read the 284x SEEPROM. | 272 | * Read the 284x SEEPROM. |
289 | */ | 273 | */ |
diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h index 27adbb294ac1..ce638aa6005a 100644 --- a/drivers/scsi/aic7xxx/aic79xx.h +++ b/drivers/scsi/aic7xxx/aic79xx.h | |||
@@ -1003,8 +1003,15 @@ struct ahd_suspend_channel_state { | |||
1003 | uint8_t seqctl; | 1003 | uint8_t seqctl; |
1004 | }; | 1004 | }; |
1005 | 1005 | ||
1006 | struct ahd_suspend_pci_state { | ||
1007 | uint32_t devconfig; | ||
1008 | uint8_t command; | ||
1009 | uint8_t csize_lattime; | ||
1010 | }; | ||
1011 | |||
1006 | struct ahd_suspend_state { | 1012 | struct ahd_suspend_state { |
1007 | struct ahd_suspend_channel_state channel[2]; | 1013 | struct ahd_suspend_channel_state channel[2]; |
1014 | struct ahd_suspend_pci_state pci_state; | ||
1008 | uint8_t optionmode; | 1015 | uint8_t optionmode; |
1009 | uint8_t dscommand0; | 1016 | uint8_t dscommand0; |
1010 | uint8_t dspcistatus; | 1017 | uint8_t dspcistatus; |
@@ -1333,6 +1340,8 @@ struct ahd_pci_identity *ahd_find_pci_device(ahd_dev_softc_t); | |||
1333 | int ahd_pci_config(struct ahd_softc *, | 1340 | int ahd_pci_config(struct ahd_softc *, |
1334 | struct ahd_pci_identity *); | 1341 | struct ahd_pci_identity *); |
1335 | int ahd_pci_test_register_access(struct ahd_softc *); | 1342 | int ahd_pci_test_register_access(struct ahd_softc *); |
1343 | void ahd_pci_suspend(struct ahd_softc *); | ||
1344 | void ahd_pci_resume(struct ahd_softc *); | ||
1336 | 1345 | ||
1337 | /************************** SCB and SCB queue management **********************/ | 1346 | /************************** SCB and SCB queue management **********************/ |
1338 | void ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, | 1347 | void ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, |
@@ -1343,6 +1352,8 @@ struct ahd_softc *ahd_alloc(void *platform_arg, char *name); | |||
1343 | int ahd_softc_init(struct ahd_softc *); | 1352 | int ahd_softc_init(struct ahd_softc *); |
1344 | void ahd_controller_info(struct ahd_softc *ahd, char *buf); | 1353 | void ahd_controller_info(struct ahd_softc *ahd, char *buf); |
1345 | int ahd_init(struct ahd_softc *ahd); | 1354 | int ahd_init(struct ahd_softc *ahd); |
1355 | int ahd_suspend(struct ahd_softc *ahd); | ||
1356 | void ahd_resume(struct ahd_softc *ahd); | ||
1346 | int ahd_default_config(struct ahd_softc *ahd); | 1357 | int ahd_default_config(struct ahd_softc *ahd); |
1347 | int ahd_parse_vpddata(struct ahd_softc *ahd, | 1358 | int ahd_parse_vpddata(struct ahd_softc *ahd, |
1348 | struct vpd_config *vpd); | 1359 | struct vpd_config *vpd); |
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 05f692bd0adc..a7dd8cdda472 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c | |||
@@ -7175,7 +7175,6 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd) | |||
7175 | ahd->flags &= ~AHD_ALL_INTERRUPTS; | 7175 | ahd->flags &= ~AHD_ALL_INTERRUPTS; |
7176 | } | 7176 | } |
7177 | 7177 | ||
7178 | #if 0 | ||
7179 | int | 7178 | int |
7180 | ahd_suspend(struct ahd_softc *ahd) | 7179 | ahd_suspend(struct ahd_softc *ahd) |
7181 | { | 7180 | { |
@@ -7189,19 +7188,15 @@ ahd_suspend(struct ahd_softc *ahd) | |||
7189 | ahd_shutdown(ahd); | 7188 | ahd_shutdown(ahd); |
7190 | return (0); | 7189 | return (0); |
7191 | } | 7190 | } |
7192 | #endif /* 0 */ | ||
7193 | 7191 | ||
7194 | #if 0 | 7192 | void |
7195 | int | ||
7196 | ahd_resume(struct ahd_softc *ahd) | 7193 | ahd_resume(struct ahd_softc *ahd) |
7197 | { | 7194 | { |
7198 | 7195 | ||
7199 | ahd_reset(ahd, /*reinit*/TRUE); | 7196 | ahd_reset(ahd, /*reinit*/TRUE); |
7200 | ahd_intr_enable(ahd, TRUE); | 7197 | ahd_intr_enable(ahd, TRUE); |
7201 | ahd_restart(ahd); | 7198 | ahd_restart(ahd); |
7202 | return (0); | ||
7203 | } | 7199 | } |
7204 | #endif /* 0 */ | ||
7205 | 7200 | ||
7206 | /************************** Busy Target Table *********************************/ | 7201 | /************************** Busy Target Table *********************************/ |
7207 | /* | 7202 | /* |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 42c0f14a262c..2d020405480c 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c | |||
@@ -315,8 +315,8 @@ uint32_t aic79xx_slowcrc; | |||
315 | */ | 315 | */ |
316 | static char *aic79xx = NULL; | 316 | static char *aic79xx = NULL; |
317 | 317 | ||
318 | MODULE_AUTHOR("Maintainer: Justin T. Gibbs <gibbs@scsiguy.com>"); | 318 | MODULE_AUTHOR("Maintainer: Hannes Reinecke <hare@suse.de>"); |
319 | MODULE_DESCRIPTION("Adaptec Aic790X U320 SCSI Host Bus Adapter driver"); | 319 | MODULE_DESCRIPTION("Adaptec AIC790X U320 SCSI Host Bus Adapter driver"); |
320 | MODULE_LICENSE("Dual BSD/GPL"); | 320 | MODULE_LICENSE("Dual BSD/GPL"); |
321 | MODULE_VERSION(AIC79XX_DRIVER_VERSION); | 321 | MODULE_VERSION(AIC79XX_DRIVER_VERSION); |
322 | module_param(aic79xx, charp, 0444); | 322 | module_param(aic79xx, charp, 0444); |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c index c62ce41f2793..66f0259edb69 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c | |||
@@ -50,6 +50,8 @@ static int ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, | |||
50 | static int ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, | 50 | static int ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, |
51 | u_long *bus_addr, | 51 | u_long *bus_addr, |
52 | uint8_t __iomem **maddr); | 52 | uint8_t __iomem **maddr); |
53 | static int ahd_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg); | ||
54 | static int ahd_linux_pci_dev_resume(struct pci_dev *pdev); | ||
53 | static void ahd_linux_pci_dev_remove(struct pci_dev *pdev); | 55 | static void ahd_linux_pci_dev_remove(struct pci_dev *pdev); |
54 | 56 | ||
55 | /* Define the macro locally since it's different for different class of chips. | 57 | /* Define the macro locally since it's different for different class of chips. |
@@ -86,10 +88,58 @@ MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table); | |||
86 | static struct pci_driver aic79xx_pci_driver = { | 88 | static struct pci_driver aic79xx_pci_driver = { |
87 | .name = "aic79xx", | 89 | .name = "aic79xx", |
88 | .probe = ahd_linux_pci_dev_probe, | 90 | .probe = ahd_linux_pci_dev_probe, |
91 | #ifdef CONFIG_PM | ||
92 | .suspend = ahd_linux_pci_dev_suspend, | ||
93 | .resume = ahd_linux_pci_dev_resume, | ||
94 | #endif | ||
89 | .remove = ahd_linux_pci_dev_remove, | 95 | .remove = ahd_linux_pci_dev_remove, |
90 | .id_table = ahd_linux_pci_id_table | 96 | .id_table = ahd_linux_pci_id_table |
91 | }; | 97 | }; |
92 | 98 | ||
99 | static int | ||
100 | ahd_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg) | ||
101 | { | ||
102 | struct ahd_softc *ahd = pci_get_drvdata(pdev); | ||
103 | int rc; | ||
104 | |||
105 | if ((rc = ahd_suspend(ahd))) | ||
106 | return rc; | ||
107 | |||
108 | ahd_pci_suspend(ahd); | ||
109 | |||
110 | pci_save_state(pdev); | ||
111 | pci_disable_device(pdev); | ||
112 | |||
113 | if (mesg.event == PM_EVENT_SUSPEND) | ||
114 | pci_set_power_state(pdev, PCI_D3hot); | ||
115 | |||
116 | return rc; | ||
117 | } | ||
118 | |||
119 | static int | ||
120 | ahd_linux_pci_dev_resume(struct pci_dev *pdev) | ||
121 | { | ||
122 | struct ahd_softc *ahd = pci_get_drvdata(pdev); | ||
123 | int rc; | ||
124 | |||
125 | pci_set_power_state(pdev, PCI_D0); | ||
126 | pci_restore_state(pdev); | ||
127 | |||
128 | if ((rc = pci_enable_device(pdev))) { | ||
129 | dev_printk(KERN_ERR, &pdev->dev, | ||
130 | "failed to enable device after resume (%d)\n", rc); | ||
131 | return rc; | ||
132 | } | ||
133 | |||
134 | pci_set_master(pdev); | ||
135 | |||
136 | ahd_pci_resume(ahd); | ||
137 | |||
138 | ahd_resume(ahd); | ||
139 | |||
140 | return rc; | ||
141 | } | ||
142 | |||
93 | static void | 143 | static void |
94 | ahd_linux_pci_dev_remove(struct pci_dev *pdev) | 144 | ahd_linux_pci_dev_remove(struct pci_dev *pdev) |
95 | { | 145 | { |
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c index 0bada0028aa0..7a203a90601a 100644 --- a/drivers/scsi/aic7xxx/aic79xx_pci.c +++ b/drivers/scsi/aic7xxx/aic79xx_pci.c | |||
@@ -389,6 +389,33 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry) | |||
389 | return error; | 389 | return error; |
390 | } | 390 | } |
391 | 391 | ||
392 | void | ||
393 | ahd_pci_suspend(struct ahd_softc *ahd) | ||
394 | { | ||
395 | /* | ||
396 | * Save chip register configuration data for chip resets | ||
397 | * that occur during runtime and resume events. | ||
398 | */ | ||
399 | ahd->suspend_state.pci_state.devconfig = | ||
400 | ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4); | ||
401 | ahd->suspend_state.pci_state.command = | ||
402 | ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/1); | ||
403 | ahd->suspend_state.pci_state.csize_lattime = | ||
404 | ahd_pci_read_config(ahd->dev_softc, CSIZE_LATTIME, /*bytes*/1); | ||
405 | |||
406 | } | ||
407 | |||
408 | void | ||
409 | ahd_pci_resume(struct ahd_softc *ahd) | ||
410 | { | ||
411 | ahd_pci_write_config(ahd->dev_softc, DEVCONFIG, | ||
412 | ahd->suspend_state.pci_state.devconfig, /*bytes*/4); | ||
413 | ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, | ||
414 | ahd->suspend_state.pci_state.command, /*bytes*/1); | ||
415 | ahd_pci_write_config(ahd->dev_softc, CSIZE_LATTIME, | ||
416 | ahd->suspend_state.pci_state.csize_lattime, /*bytes*/1); | ||
417 | } | ||
418 | |||
392 | /* | 419 | /* |
393 | * Perform some simple tests that should catch situations where | 420 | * Perform some simple tests that should catch situations where |
394 | * our registers are invalidly mapped. | 421 | * our registers are invalidly mapped. |
diff --git a/drivers/scsi/aic7xxx/aic7xxx.h b/drivers/scsi/aic7xxx/aic7xxx.h index e1bd57b9f23d..3d4e42d90452 100644 --- a/drivers/scsi/aic7xxx/aic7xxx.h +++ b/drivers/scsi/aic7xxx/aic7xxx.h | |||
@@ -962,16 +962,6 @@ struct ahc_softc { | |||
962 | ahc_bus_chip_init_t bus_chip_init; | 962 | ahc_bus_chip_init_t bus_chip_init; |
963 | 963 | ||
964 | /* | 964 | /* |
965 | * Bus specific suspend routine. | ||
966 | */ | ||
967 | ahc_bus_suspend_t bus_suspend; | ||
968 | |||
969 | /* | ||
970 | * Bus specific resume routine. | ||
971 | */ | ||
972 | ahc_bus_resume_t bus_resume; | ||
973 | |||
974 | /* | ||
975 | * Target mode related state kept on a per enabled lun basis. | 965 | * Target mode related state kept on a per enabled lun basis. |
976 | * Targets that are not enabled will have null entries. | 966 | * Targets that are not enabled will have null entries. |
977 | * As an initiator, we keep one target entry for our initiator | 967 | * As an initiator, we keep one target entry for our initiator |
@@ -1153,6 +1143,7 @@ struct ahc_pci_identity *ahc_find_pci_device(ahc_dev_softc_t); | |||
1153 | int ahc_pci_config(struct ahc_softc *, | 1143 | int ahc_pci_config(struct ahc_softc *, |
1154 | struct ahc_pci_identity *); | 1144 | struct ahc_pci_identity *); |
1155 | int ahc_pci_test_register_access(struct ahc_softc *); | 1145 | int ahc_pci_test_register_access(struct ahc_softc *); |
1146 | void ahc_pci_resume(struct ahc_softc *ahc); | ||
1156 | 1147 | ||
1157 | /*************************** EISA/VL Front End ********************************/ | 1148 | /*************************** EISA/VL Front End ********************************/ |
1158 | struct aic7770_identity *aic7770_find_device(uint32_t); | 1149 | struct aic7770_identity *aic7770_find_device(uint32_t); |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 7770befbf50c..390b0fc991c5 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c | |||
@@ -335,8 +335,8 @@ static uint32_t aic7xxx_periodic_otag; | |||
335 | */ | 335 | */ |
336 | static char *aic7xxx = NULL; | 336 | static char *aic7xxx = NULL; |
337 | 337 | ||
338 | MODULE_AUTHOR("Maintainer: Justin T. Gibbs <gibbs@scsiguy.com>"); | 338 | MODULE_AUTHOR("Maintainer: Hannes Reinecke <hare@suse.de>"); |
339 | MODULE_DESCRIPTION("Adaptec Aic77XX/78XX SCSI Host Bus Adapter driver"); | 339 | MODULE_DESCRIPTION("Adaptec AIC77XX/78XX SCSI Host Bus Adapter driver"); |
340 | MODULE_LICENSE("Dual BSD/GPL"); | 340 | MODULE_LICENSE("Dual BSD/GPL"); |
341 | MODULE_VERSION(AIC7XXX_DRIVER_VERSION); | 341 | MODULE_VERSION(AIC7XXX_DRIVER_VERSION); |
342 | module_param(aic7xxx, charp, 0444); | 342 | module_param(aic7xxx, charp, 0444); |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c index ea5687df732d..4488946cff2e 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | |||
@@ -49,6 +49,8 @@ static int ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, | |||
49 | static int ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc, | 49 | static int ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc, |
50 | u_long *bus_addr, | 50 | u_long *bus_addr, |
51 | uint8_t __iomem **maddr); | 51 | uint8_t __iomem **maddr); |
52 | static int ahc_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg); | ||
53 | static int ahc_linux_pci_dev_resume(struct pci_dev *pdev); | ||
52 | static void ahc_linux_pci_dev_remove(struct pci_dev *pdev); | 54 | static void ahc_linux_pci_dev_remove(struct pci_dev *pdev); |
53 | 55 | ||
54 | /* Define the macro locally since it's different for different class of chips. | 56 | /* Define the macro locally since it's different for different class of chips. |
@@ -133,10 +135,54 @@ MODULE_DEVICE_TABLE(pci, ahc_linux_pci_id_table); | |||
133 | static struct pci_driver aic7xxx_pci_driver = { | 135 | static struct pci_driver aic7xxx_pci_driver = { |
134 | .name = "aic7xxx", | 136 | .name = "aic7xxx", |
135 | .probe = ahc_linux_pci_dev_probe, | 137 | .probe = ahc_linux_pci_dev_probe, |
138 | #ifdef CONFIG_PM | ||
139 | .suspend = ahc_linux_pci_dev_suspend, | ||
140 | .resume = ahc_linux_pci_dev_resume, | ||
141 | #endif | ||
136 | .remove = ahc_linux_pci_dev_remove, | 142 | .remove = ahc_linux_pci_dev_remove, |
137 | .id_table = ahc_linux_pci_id_table | 143 | .id_table = ahc_linux_pci_id_table |
138 | }; | 144 | }; |
139 | 145 | ||
146 | static int | ||
147 | ahc_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg) | ||
148 | { | ||
149 | struct ahc_softc *ahc = pci_get_drvdata(pdev); | ||
150 | int rc; | ||
151 | |||
152 | if ((rc = ahc_suspend(ahc))) | ||
153 | return rc; | ||
154 | |||
155 | pci_save_state(pdev); | ||
156 | pci_disable_device(pdev); | ||
157 | |||
158 | if (mesg.event == PM_EVENT_SUSPEND) | ||
159 | pci_set_power_state(pdev, PCI_D3hot); | ||
160 | |||
161 | return rc; | ||
162 | } | ||
163 | |||
164 | static int | ||
165 | ahc_linux_pci_dev_resume(struct pci_dev *pdev) | ||
166 | { | ||
167 | struct ahc_softc *ahc = pci_get_drvdata(pdev); | ||
168 | int rc; | ||
169 | |||
170 | pci_set_power_state(pdev, PCI_D0); | ||
171 | pci_restore_state(pdev); | ||
172 | |||
173 | if ((rc = pci_enable_device(pdev))) { | ||
174 | dev_printk(KERN_ERR, &pdev->dev, | ||
175 | "failed to enable device after resume (%d)\n", rc); | ||
176 | return rc; | ||
177 | } | ||
178 | |||
179 | pci_set_master(pdev); | ||
180 | |||
181 | ahc_pci_resume(ahc); | ||
182 | |||
183 | return (ahc_resume(ahc)); | ||
184 | } | ||
185 | |||
140 | static void | 186 | static void |
141 | ahc_linux_pci_dev_remove(struct pci_dev *pdev) | 187 | ahc_linux_pci_dev_remove(struct pci_dev *pdev) |
142 | { | 188 | { |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c index 09c8172c9e5e..ae35937b8055 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c | |||
@@ -633,8 +633,6 @@ static void write_brdctl(struct ahc_softc *ahc, uint8_t value); | |||
633 | static uint8_t read_brdctl(struct ahc_softc *ahc); | 633 | static uint8_t read_brdctl(struct ahc_softc *ahc); |
634 | static void ahc_pci_intr(struct ahc_softc *ahc); | 634 | static void ahc_pci_intr(struct ahc_softc *ahc); |
635 | static int ahc_pci_chip_init(struct ahc_softc *ahc); | 635 | static int ahc_pci_chip_init(struct ahc_softc *ahc); |
636 | static int ahc_pci_suspend(struct ahc_softc *ahc); | ||
637 | static int ahc_pci_resume(struct ahc_softc *ahc); | ||
638 | 636 | ||
639 | static int | 637 | static int |
640 | ahc_9005_subdevinfo_valid(uint16_t device, uint16_t vendor, | 638 | ahc_9005_subdevinfo_valid(uint16_t device, uint16_t vendor, |
@@ -791,8 +789,6 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) | |||
791 | 789 | ||
792 | ahc->bus_intr = ahc_pci_intr; | 790 | ahc->bus_intr = ahc_pci_intr; |
793 | ahc->bus_chip_init = ahc_pci_chip_init; | 791 | ahc->bus_chip_init = ahc_pci_chip_init; |
794 | ahc->bus_suspend = ahc_pci_suspend; | ||
795 | ahc->bus_resume = ahc_pci_resume; | ||
796 | 792 | ||
797 | /* Remeber how the card was setup in case there is no SEEPROM */ | 793 | /* Remeber how the card was setup in case there is no SEEPROM */ |
798 | if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) { | 794 | if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) { |
@@ -2024,18 +2020,9 @@ ahc_pci_chip_init(struct ahc_softc *ahc) | |||
2024 | return (ahc_chip_init(ahc)); | 2020 | return (ahc_chip_init(ahc)); |
2025 | } | 2021 | } |
2026 | 2022 | ||
2027 | static int | 2023 | void |
2028 | ahc_pci_suspend(struct ahc_softc *ahc) | ||
2029 | { | ||
2030 | return (ahc_suspend(ahc)); | ||
2031 | } | ||
2032 | |||
2033 | static int | ||
2034 | ahc_pci_resume(struct ahc_softc *ahc) | 2024 | ahc_pci_resume(struct ahc_softc *ahc) |
2035 | { | 2025 | { |
2036 | |||
2037 | pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0); | ||
2038 | |||
2039 | /* | 2026 | /* |
2040 | * We assume that the OS has restored our register | 2027 | * We assume that the OS has restored our register |
2041 | * mappings, etc. Just update the config space registers | 2028 | * mappings, etc. Just update the config space registers |
@@ -2063,7 +2050,6 @@ ahc_pci_resume(struct ahc_softc *ahc) | |||
2063 | &sxfrctl1); | 2050 | &sxfrctl1); |
2064 | ahc_release_seeprom(&sd); | 2051 | ahc_release_seeprom(&sd); |
2065 | } | 2052 | } |
2066 | return (ahc_resume(ahc)); | ||
2067 | } | 2053 | } |
2068 | 2054 | ||
2069 | static int | 2055 | static int |
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l index f06e7035cb35..c0457b8c3b77 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l | |||
@@ -66,6 +66,7 @@ static char string_buf[MAX_STR_CONST]; | |||
66 | static char *string_buf_ptr; | 66 | static char *string_buf_ptr; |
67 | static int parren_count; | 67 | static int parren_count; |
68 | static char buf[255]; | 68 | static char buf[255]; |
69 | int mmlineno; | ||
69 | %} | 70 | %} |
70 | 71 | ||
71 | WORD [A-Za-z_][-A-Za-z_0-9]* | 72 | WORD [A-Za-z_][-A-Za-z_0-9]* |
@@ -76,7 +77,7 @@ MCARG [^(), \t]+ | |||
76 | 77 | ||
77 | %% | 78 | %% |
78 | \n { | 79 | \n { |
79 | ++yylineno; | 80 | ++mmlineno; |
80 | } | 81 | } |
81 | \r ; | 82 | \r ; |
82 | <ARGLIST>{SPACE} ; | 83 | <ARGLIST>{SPACE} ; |
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c index 4025608d6964..8f8db5f0aef7 100644 --- a/drivers/scsi/aic7xxx_old.c +++ b/drivers/scsi/aic7xxx_old.c | |||
@@ -8417,7 +8417,7 @@ aic7xxx_alloc(struct scsi_host_template *sht, struct aic7xxx_host *temp) | |||
8417 | p->host = host; | 8417 | p->host = host; |
8418 | 8418 | ||
8419 | p->scb_data = kzalloc(sizeof(scb_data_type), GFP_ATOMIC); | 8419 | p->scb_data = kzalloc(sizeof(scb_data_type), GFP_ATOMIC); |
8420 | if (!p->scb_data) | 8420 | if (p->scb_data) |
8421 | { | 8421 | { |
8422 | scbq_init (&p->scb_data->free_scbs); | 8422 | scbq_init (&p->scb_data->free_scbs); |
8423 | } | 8423 | } |
diff --git a/drivers/scsi/fcal.c b/drivers/scsi/fcal.c deleted file mode 100644 index c4e16c0775de..000000000000 --- a/drivers/scsi/fcal.c +++ /dev/null | |||
@@ -1,317 +0,0 @@ | |||
1 | /* fcal.c: Fibre Channel Arbitrated Loop SCSI host adapter driver. | ||
2 | * | ||
3 | * Copyright (C) 1998,1999 Jakub Jelinek (jj@ultra.linux.cz) | ||
4 | * | ||
5 | */ | ||
6 | |||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/delay.h> | ||
9 | #include <linux/types.h> | ||
10 | #include <linux/string.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/blkdev.h> | ||
13 | #include <linux/proc_fs.h> | ||
14 | #include <linux/stat.h> | ||
15 | #include <linux/init.h> | ||
16 | #ifdef CONFIG_KMOD | ||
17 | #include <linux/kmod.h> | ||
18 | #endif | ||
19 | |||
20 | #include <asm/irq.h> | ||
21 | |||
22 | #include "scsi.h" | ||
23 | #include <scsi/scsi_host.h> | ||
24 | #include "../fc4/fcp_impl.h" | ||
25 | #include "fcal.h" | ||
26 | |||
27 | #include <linux/module.h> | ||
28 | |||
29 | /* #define FCAL_DEBUG */ | ||
30 | |||
31 | #define fcal_printk printk ("FCAL %s: ", fc->name); printk | ||
32 | |||
33 | #ifdef FCAL_DEBUG | ||
34 | #define FCALD(x) fcal_printk x; | ||
35 | #define FCALND(x) printk ("FCAL: "); printk x; | ||
36 | #else | ||
37 | #define FCALD(x) | ||
38 | #define FCALND(x) | ||
39 | #endif | ||
40 | |||
41 | static unsigned char alpa2target[] = { | ||
42 | 0x7e, 0x7d, 0x7c, 0xff, 0x7b, 0xff, 0xff, 0xff, 0x7a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x79, | ||
43 | 0x78, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x77, 0x76, 0xff, 0xff, 0x75, 0xff, 0x74, 0x73, 0x72, | ||
44 | 0xff, 0xff, 0xff, 0x71, 0xff, 0x70, 0x6f, 0x6e, 0xff, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0xff, | ||
45 | 0xff, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0xff, 0xff, 0x61, 0x60, 0xff, 0x5f, 0xff, 0xff, 0xff, | ||
46 | 0xff, 0xff, 0xff, 0x5e, 0xff, 0x5d, 0x5c, 0x5b, 0xff, 0x5a, 0x59, 0x58, 0x57, 0x56, 0x55, 0xff, | ||
47 | 0xff, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f, 0xff, 0xff, 0x4e, 0x4d, 0xff, 0x4c, 0xff, 0xff, 0xff, | ||
48 | 0xff, 0xff, 0xff, 0x4b, 0xff, 0x4a, 0x49, 0x48, 0xff, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0xff, | ||
49 | 0xff, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0xff, 0xff, 0x3b, 0x3a, 0xff, 0x39, 0xff, 0xff, 0xff, | ||
50 | 0x38, 0x37, 0x36, 0xff, 0x35, 0xff, 0xff, 0xff, 0x34, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x33, | ||
51 | 0x32, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x31, 0x30, 0xff, 0xff, 0x2f, 0xff, 0x2e, 0x2d, 0x2c, | ||
52 | 0xff, 0xff, 0xff, 0x2b, 0xff, 0x2a, 0x29, 0x28, 0xff, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0xff, | ||
53 | 0xff, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0xff, 0xff, 0x1b, 0x1a, 0xff, 0x19, 0xff, 0xff, 0xff, | ||
54 | 0xff, 0xff, 0xff, 0x18, 0xff, 0x17, 0x16, 0x15, 0xff, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0xff, | ||
55 | 0xff, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0xff, 0xff, 0x08, 0x07, 0xff, 0x06, 0xff, 0xff, 0xff, | ||
56 | 0x05, 0x04, 0x03, 0xff, 0x02, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 | ||
57 | }; | ||
58 | |||
59 | static unsigned char target2alpa[] = { | ||
60 | 0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda, 0xd9, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce, | ||
61 | 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc7, 0xc6, 0xc5, 0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 0xb4, 0xb3, | ||
62 | 0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b, | ||
63 | 0x98, 0x97, 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81, 0x80, 0x7c, 0x7a, 0x79, 0x76, 0x75, 0x74, 0x73, | ||
64 | 0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56, | ||
65 | 0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c, | ||
66 | 0x3a, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x27, 0x26, | ||
67 | 0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17, 0x10, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x00 | ||
68 | }; | ||
69 | |||
70 | static int fcal_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd); | ||
71 | |||
72 | int fcal_slave_configure(struct scsi_device *device) | ||
73 | { | ||
74 | int depth_to_use; | ||
75 | |||
76 | if (device->tagged_supported) | ||
77 | depth_to_use = /* 254 */ 8; | ||
78 | else | ||
79 | depth_to_use = 2; | ||
80 | |||
81 | scsi_adjust_queue_depth(device, | ||
82 | (device->tagged_supported ? | ||
83 | MSG_SIMPLE_TAG : 0), | ||
84 | depth_to_use); | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | /* Detect all FC Arbitrated Loops attached to the machine. | ||
90 | fc4 module has done all the work for us... */ | ||
91 | int __init fcal_detect(struct scsi_host_template *tpnt) | ||
92 | { | ||
93 | int nfcals = 0; | ||
94 | fc_channel *fc; | ||
95 | int fcalcount; | ||
96 | int i; | ||
97 | |||
98 | tpnt->proc_name = "fcal"; | ||
99 | fcalcount = 0; | ||
100 | for_each_online_fc_channel(fc) | ||
101 | if (fc->posmap) | ||
102 | fcalcount++; | ||
103 | FCALND(("%d channels online\n", fcalcount)) | ||
104 | if (!fcalcount) { | ||
105 | #if defined(MODULE) && defined(CONFIG_FC4_SOCAL_MODULE) && defined(CONFIG_KMOD) | ||
106 | request_module("socal"); | ||
107 | |||
108 | for_each_online_fc_channel(fc) | ||
109 | if (fc->posmap) | ||
110 | fcalcount++; | ||
111 | if (!fcalcount) | ||
112 | #endif | ||
113 | return 0; | ||
114 | } | ||
115 | for_each_online_fc_channel(fc) { | ||
116 | struct Scsi_Host *host; | ||
117 | long *ages; | ||
118 | struct fcal *fcal; | ||
119 | |||
120 | if (!fc->posmap) continue; | ||
121 | |||
122 | /* Strange, this is already registered to some other SCSI host, then it cannot be fcal */ | ||
123 | if (fc->scsi_name[0]) continue; | ||
124 | memcpy (fc->scsi_name, "FCAL", 4); | ||
125 | |||
126 | fc->can_queue = FCAL_CAN_QUEUE; | ||
127 | fc->rsp_size = 64; | ||
128 | fc->encode_addr = fcal_encode_addr; | ||
129 | |||
130 | ages = kmalloc (128 * sizeof(long), GFP_KERNEL); | ||
131 | if (!ages) continue; | ||
132 | |||
133 | host = scsi_register (tpnt, sizeof (struct fcal)); | ||
134 | if (!host) | ||
135 | { | ||
136 | kfree(ages); | ||
137 | continue; | ||
138 | } | ||
139 | |||
140 | if (!try_module_get(fc->module)) { | ||
141 | kfree(ages); | ||
142 | scsi_unregister(host); | ||
143 | continue; | ||
144 | } | ||
145 | |||
146 | nfcals++; | ||
147 | |||
148 | fcal = (struct fcal *)host->hostdata; | ||
149 | |||
150 | fc->fcp_register(fc, TYPE_SCSI_FCP, 0); | ||
151 | |||
152 | for (i = 0; i < fc->posmap->len; i++) { | ||
153 | int status, target, alpa; | ||
154 | |||
155 | alpa = fc->posmap->list[i]; | ||
156 | FCALD(("Sending PLOGI to %02x\n", alpa)) | ||
157 | target = alpa2target[alpa]; | ||
158 | status = fc_do_plogi(fc, alpa, fcal->node_wwn + target, | ||
159 | fcal->nport_wwn + target); | ||
160 | FCALD(("PLOGI returned with status %d\n", status)) | ||
161 | if (status != FC_STATUS_OK) | ||
162 | continue; | ||
163 | FCALD(("Sending PRLI to %02x\n", alpa)) | ||
164 | status = fc_do_prli(fc, alpa); | ||
165 | FCALD(("PRLI returned with status %d\n", status)) | ||
166 | if (status == FC_STATUS_OK) | ||
167 | fcal->map[target] = 1; | ||
168 | } | ||
169 | |||
170 | host->max_id = 127; | ||
171 | host->irq = fc->irq; | ||
172 | #ifdef __sparc_v9__ | ||
173 | host->unchecked_isa_dma = 1; | ||
174 | #endif | ||
175 | |||
176 | fc->channels = 1; | ||
177 | fc->targets = 127; | ||
178 | fc->ages = ages; | ||
179 | memset (ages, 0, 128 * sizeof(long)); | ||
180 | |||
181 | fcal->fc = fc; | ||
182 | |||
183 | FCALD(("Found FCAL\n")) | ||
184 | } | ||
185 | if (nfcals) | ||
186 | #ifdef __sparc__ | ||
187 | printk ("FCAL: Total of %d Sun Enterprise Network Array (A5000 or EX500) channels found\n", nfcals); | ||
188 | #else | ||
189 | printk ("FCAL: Total of %d Fibre Channel Arbitrated Loops found\n", nfcals); | ||
190 | #endif | ||
191 | return nfcals; | ||
192 | } | ||
193 | |||
194 | int fcal_release(struct Scsi_Host *host) | ||
195 | { | ||
196 | struct fcal *fcal = (struct fcal *)host->hostdata; | ||
197 | fc_channel *fc = fcal->fc; | ||
198 | |||
199 | module_put(fc->module); | ||
200 | |||
201 | fc->fcp_register(fc, TYPE_SCSI_FCP, 1); | ||
202 | FCALND((" releasing fcal.\n")); | ||
203 | kfree (fc->ages); | ||
204 | FCALND(("released fcal!\n")); | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | #undef SPRINTF | ||
209 | #define SPRINTF(args...) { if (pos < (buffer + length)) pos += sprintf (pos, ## args); } | ||
210 | |||
211 | int fcal_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout) | ||
212 | { | ||
213 | struct fcal *fcal; | ||
214 | fc_channel *fc; | ||
215 | char *pos = buffer; | ||
216 | int i, j; | ||
217 | |||
218 | if (inout) return length; | ||
219 | |||
220 | fcal = (struct fcal *)host->hostdata; | ||
221 | fc = fcal->fc; | ||
222 | |||
223 | #ifdef __sparc__ | ||
224 | SPRINTF ("Sun Enterprise Network Array (A5000 or E?500) on %s PROM node %x\n", fc->name, fc->dev->prom_node); | ||
225 | #else | ||
226 | SPRINTF ("Fibre Channel Arbitrated Loop on %s\n", fc->name); | ||
227 | #endif | ||
228 | SPRINTF ("Initiator AL-PA: %02x\n", fc->sid); | ||
229 | |||
230 | SPRINTF ("\nAttached devices:\n"); | ||
231 | |||
232 | for (i = 0; i < fc->posmap->len; i++) { | ||
233 | unsigned char alpa = fc->posmap->list[i]; | ||
234 | unsigned char target; | ||
235 | u32 *u1, *u2; | ||
236 | |||
237 | target = alpa2target[alpa]; | ||
238 | u1 = (u32 *)&fcal->nport_wwn[target]; | ||
239 | u2 = (u32 *)&fcal->node_wwn[target]; | ||
240 | if (!u1[0] && !u1[1]) { | ||
241 | SPRINTF (" [AL-PA: %02x] Not responded to PLOGI\n", alpa); | ||
242 | } else if (!fcal->map[target]) { | ||
243 | SPRINTF (" [AL-PA: %02x, Port WWN: %08x%08x, Node WWN: %08x%08x] Not responded to PRLI\n", | ||
244 | alpa, u1[0], u1[1], u2[0], u2[1]); | ||
245 | } else { | ||
246 | struct scsi_device *scd; | ||
247 | shost_for_each_device(scd, host) | ||
248 | if (scd->id == target) { | ||
249 | SPRINTF (" [AL-PA: %02x, Id: %02d, Port WWN: %08x%08x, Node WWN: %08x%08x] ", | ||
250 | alpa, target, u1[0], u1[1], u2[0], u2[1]); | ||
251 | SPRINTF ("%s ", scsi_device_type(scd->type)); | ||
252 | |||
253 | for (j = 0; (j < 8) && (scd->vendor[j] >= 0x20); j++) | ||
254 | SPRINTF ("%c", scd->vendor[j]); | ||
255 | SPRINTF (" "); | ||
256 | |||
257 | for (j = 0; (j < 16) && (scd->model[j] >= 0x20); j++) | ||
258 | SPRINTF ("%c", scd->model[j]); | ||
259 | |||
260 | SPRINTF ("\n"); | ||
261 | } | ||
262 | } | ||
263 | } | ||
264 | SPRINTF ("\n"); | ||
265 | |||
266 | *start = buffer + offset; | ||
267 | |||
268 | if ((pos - buffer) < offset) | ||
269 | return 0; | ||
270 | else if (pos - buffer - offset < length) | ||
271 | return pos - buffer - offset; | ||
272 | else | ||
273 | return length; | ||
274 | } | ||
275 | |||
276 | /* | ||
277 | For FC-AL, we use a simple addressing: we have just one channel 0, | ||
278 | and all AL-PAs are mapped to targets 0..0x7e | ||
279 | */ | ||
280 | static int fcal_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd) | ||
281 | { | ||
282 | struct fcal *f; | ||
283 | |||
284 | /* We don't support LUNs yet - I'm not sure if LUN should be in SCSI fcp_cdb, or in second byte of addr[0] */ | ||
285 | if (SCpnt->cmnd[1] & 0xe0) return -EINVAL; | ||
286 | /* FC-PLDA tells us... */ | ||
287 | memset(addr, 0, 8); | ||
288 | f = (struct fcal *)SCpnt->device->host->hostdata; | ||
289 | if (!f->map[SCpnt->device->id]) | ||
290 | return -EINVAL; | ||
291 | /* Now, determine DID: It will be Native Identifier, so we zero upper | ||
292 | 2 bytes of the 3 byte DID, lowest byte will be AL-PA */ | ||
293 | fcmd->did = target2alpa[SCpnt->device->id]; | ||
294 | FCALD(("trying DID %06x\n", fcmd->did)) | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static struct scsi_host_template driver_template = { | ||
299 | .name = "Fibre Channel Arbitrated Loop", | ||
300 | .detect = fcal_detect, | ||
301 | .release = fcal_release, | ||
302 | .proc_info = fcal_proc_info, | ||
303 | .queuecommand = fcp_scsi_queuecommand, | ||
304 | .slave_configure = fcal_slave_configure, | ||
305 | .can_queue = FCAL_CAN_QUEUE, | ||
306 | .this_id = -1, | ||
307 | .sg_tablesize = 1, | ||
308 | .cmd_per_lun = 1, | ||
309 | .use_clustering = ENABLE_CLUSTERING, | ||
310 | .eh_abort_handler = fcp_scsi_abort, | ||
311 | .eh_device_reset_handler = fcp_scsi_dev_reset, | ||
312 | .eh_host_reset_handler = fcp_scsi_host_reset, | ||
313 | }; | ||
314 | #include "scsi_module.c" | ||
315 | |||
316 | MODULE_LICENSE("GPL"); | ||
317 | |||
diff --git a/drivers/scsi/fcal.h b/drivers/scsi/fcal.h deleted file mode 100644 index 7ff2c3494f9e..000000000000 --- a/drivers/scsi/fcal.h +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | /* fcal.h: Generic Fibre Channel Arbitrated Loop SCSI host adapter driver definitions. | ||
2 | * | ||
3 | * Copyright (C) 1998,1999 Jakub Jelinek (jj@ultra.linux.cz) | ||
4 | */ | ||
5 | |||
6 | #ifndef _FCAL_H | ||
7 | #define _FCAL_H | ||
8 | |||
9 | #include "../fc4/fcp_impl.h" | ||
10 | |||
11 | struct fcal { | ||
12 | /* fc must be first */ | ||
13 | fc_channel *fc; | ||
14 | unsigned char map[128]; | ||
15 | fc_wwn nport_wwn[128]; | ||
16 | fc_wwn node_wwn[128]; | ||
17 | }; | ||
18 | |||
19 | /* Arbitrary constant. Cannot be too large, as fc4 layer has limitations | ||
20 | for a particular channel */ | ||
21 | #define FCAL_CAN_QUEUE 512 | ||
22 | |||
23 | int fcal_detect(struct scsi_host_template *); | ||
24 | int fcal_release(struct Scsi_Host *); | ||
25 | int fcal_slave_configure(struct scsi_device *); | ||
26 | |||
27 | #endif /* !(_FCAL_H) */ | ||
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 5ab3ce762485..b253b8c718d3 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c | |||
@@ -4734,7 +4734,7 @@ static struct scsi_host_template gdth_template = { | |||
4734 | }; | 4734 | }; |
4735 | 4735 | ||
4736 | #ifdef CONFIG_ISA | 4736 | #ifdef CONFIG_ISA |
4737 | static int gdth_isa_probe_one(ulong32 isa_bios) | 4737 | static int __init gdth_isa_probe_one(ulong32 isa_bios) |
4738 | { | 4738 | { |
4739 | struct Scsi_Host *shp; | 4739 | struct Scsi_Host *shp; |
4740 | gdth_ha_str *ha; | 4740 | gdth_ha_str *ha; |
@@ -4862,7 +4862,7 @@ static int gdth_isa_probe_one(ulong32 isa_bios) | |||
4862 | #endif /* CONFIG_ISA */ | 4862 | #endif /* CONFIG_ISA */ |
4863 | 4863 | ||
4864 | #ifdef CONFIG_EISA | 4864 | #ifdef CONFIG_EISA |
4865 | static int gdth_eisa_probe_one(ushort eisa_slot) | 4865 | static int __init gdth_eisa_probe_one(ushort eisa_slot) |
4866 | { | 4866 | { |
4867 | struct Scsi_Host *shp; | 4867 | struct Scsi_Host *shp; |
4868 | gdth_ha_str *ha; | 4868 | gdth_ha_str *ha; |
@@ -4991,7 +4991,7 @@ static int gdth_eisa_probe_one(ushort eisa_slot) | |||
4991 | #endif /* CONFIG_EISA */ | 4991 | #endif /* CONFIG_EISA */ |
4992 | 4992 | ||
4993 | #ifdef CONFIG_PCI | 4993 | #ifdef CONFIG_PCI |
4994 | static int gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) | 4994 | static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) |
4995 | { | 4995 | { |
4996 | struct Scsi_Host *shp; | 4996 | struct Scsi_Host *shp; |
4997 | gdth_ha_str *ha; | 4997 | gdth_ha_str *ha; |
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 112ab6abe62b..24271a871b8c 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
@@ -345,6 +345,12 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) | |||
345 | shost->active_mode = sht->supported_mode; | 345 | shost->active_mode = sht->supported_mode; |
346 | shost->use_sg_chaining = sht->use_sg_chaining; | 346 | shost->use_sg_chaining = sht->use_sg_chaining; |
347 | 347 | ||
348 | if (sht->supported_mode == MODE_UNKNOWN) | ||
349 | /* means we didn't set it ... default to INITIATOR */ | ||
350 | shost->active_mode = MODE_INITIATOR; | ||
351 | else | ||
352 | shost->active_mode = sht->supported_mode; | ||
353 | |||
348 | if (sht->max_host_blocked) | 354 | if (sht->max_host_blocked) |
349 | shost->max_host_blocked = sht->max_host_blocked; | 355 | shost->max_host_blocked = sht->max_host_blocked; |
350 | else | 356 | else |
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index 8515054cdf70..0844331abb87 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c | |||
@@ -375,8 +375,9 @@ static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 _tag) | |||
375 | scp->result = SAM_STAT_CHECK_CONDITION; | 375 | scp->result = SAM_STAT_CHECK_CONDITION; |
376 | memset(&scp->sense_buffer, | 376 | memset(&scp->sense_buffer, |
377 | 0, sizeof(scp->sense_buffer)); | 377 | 0, sizeof(scp->sense_buffer)); |
378 | memcpy(&scp->sense_buffer, | 378 | memcpy(&scp->sense_buffer, &req->sg_list, |
379 | &req->sg_list, le32_to_cpu(req->dataxfer_length)); | 379 | min(sizeof(scp->sense_buffer), |
380 | le32_to_cpu(req->dataxfer_length))); | ||
380 | break; | 381 | break; |
381 | 382 | ||
382 | default: | 383 | default: |
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index 22d40fd5845b..4c4465d39a1d 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c | |||
@@ -665,7 +665,7 @@ static void initio_init(struct initio_host * host, u8 *bios_addr) | |||
665 | host->max_tags[i] = 0xFF; | 665 | host->max_tags[i] = 0xFF; |
666 | } /* for */ | 666 | } /* for */ |
667 | printk("i91u: PCI Base=0x%04X, IRQ=%d, BIOS=0x%04X0, SCSI ID=%d\n", | 667 | printk("i91u: PCI Base=0x%04X, IRQ=%d, BIOS=0x%04X0, SCSI ID=%d\n", |
668 | host->addr, host->irq, | 668 | host->addr, host->pci_dev->irq, |
669 | host->bios_addr, host->scsi_id); | 669 | host->bios_addr, host->scsi_id); |
670 | /* Reset SCSI Bus */ | 670 | /* Reset SCSI Bus */ |
671 | if (host->config & HCC_SCSI_RESET) { | 671 | if (host->config & HCC_SCSI_RESET) { |
@@ -2891,6 +2891,8 @@ static int initio_probe_one(struct pci_dev *pdev, | |||
2891 | goto out_release_region; | 2891 | goto out_release_region; |
2892 | } | 2892 | } |
2893 | 2893 | ||
2894 | host->pci_dev = pdev; | ||
2895 | |||
2894 | host->num_scbs = num_scb; | 2896 | host->num_scbs = num_scb; |
2895 | host->scb = scb; | 2897 | host->scb = scb; |
2896 | host->next_pending = scb; | 2898 | host->next_pending = scb; |
@@ -2905,6 +2907,7 @@ static int initio_probe_one(struct pci_dev *pdev, | |||
2905 | host->scb_end = tmp; | 2907 | host->scb_end = tmp; |
2906 | host->first_avail = scb; | 2908 | host->first_avail = scb; |
2907 | host->last_avail = prev; | 2909 | host->last_avail = prev; |
2910 | spin_lock_init(&host->avail_lock); | ||
2908 | 2911 | ||
2909 | initio_init(host, phys_to_virt(bios_seg << 4)); | 2912 | initio_init(host, phys_to_virt(bios_seg << 4)); |
2910 | 2913 | ||
@@ -2928,7 +2931,6 @@ static int initio_probe_one(struct pci_dev *pdev, | |||
2928 | } | 2931 | } |
2929 | 2932 | ||
2930 | pci_set_drvdata(pdev, shost); | 2933 | pci_set_drvdata(pdev, shost); |
2931 | host->pci_dev = pdev; | ||
2932 | 2934 | ||
2933 | error = scsi_add_host(shost, &pdev->dev); | 2935 | error = scsi_add_host(shost, &pdev->dev); |
2934 | if (error) | 2936 | if (error) |
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 149fdd25f8e8..d6a98bc970ff 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c | |||
@@ -901,7 +901,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) | |||
901 | } | 901 | } |
902 | } | 902 | } |
903 | 903 | ||
904 | vport->disc_trc = kmzlloc( | 904 | vport->disc_trc = kzalloc( |
905 | (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc), | 905 | (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc), |
906 | GFP_KERNEL); | 906 | GFP_KERNEL); |
907 | 907 | ||
diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c deleted file mode 100644 index 0363c1cd68c1..000000000000 --- a/drivers/scsi/pluto.c +++ /dev/null | |||
@@ -1,349 +0,0 @@ | |||
1 | /* pluto.c: SparcSTORAGE Array SCSI host adapter driver. | ||
2 | * | ||
3 | * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
4 | * | ||
5 | */ | ||
6 | |||
7 | #include <linux/completion.h> | ||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/delay.h> | ||
10 | #include <linux/types.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/blkdev.h> | ||
14 | #include <linux/proc_fs.h> | ||
15 | #include <linux/stat.h> | ||
16 | #include <linux/init.h> | ||
17 | #ifdef CONFIG_KMOD | ||
18 | #include <linux/kmod.h> | ||
19 | #endif | ||
20 | |||
21 | #include <asm/irq.h> | ||
22 | |||
23 | #include "scsi.h" | ||
24 | #include <scsi/scsi_host.h> | ||
25 | #include "../fc4/fcp_impl.h" | ||
26 | #include "pluto.h" | ||
27 | |||
28 | #include <linux/module.h> | ||
29 | |||
30 | #define RQ_SCSI_BUSY 0xffff | ||
31 | #define RQ_SCSI_DONE 0xfffe | ||
32 | |||
33 | /* #define PLUTO_DEBUG */ | ||
34 | |||
35 | #define pluto_printk printk ("PLUTO %s: ", fc->name); printk | ||
36 | |||
37 | #ifdef PLUTO_DEBUG | ||
38 | #define PLD(x) pluto_printk x; | ||
39 | #define PLND(x) printk ("PLUTO: "); printk x; | ||
40 | #else | ||
41 | #define PLD(x) | ||
42 | #define PLND(x) | ||
43 | #endif | ||
44 | |||
45 | static struct ctrl_inquiry { | ||
46 | struct Scsi_Host host; | ||
47 | struct pluto pluto; | ||
48 | Scsi_Cmnd cmd; | ||
49 | char inquiry[256]; | ||
50 | fc_channel *fc; | ||
51 | } *fcs __initdata; | ||
52 | static int fcscount __initdata = 0; | ||
53 | static atomic_t fcss __initdata = ATOMIC_INIT(0); | ||
54 | static DECLARE_COMPLETION(fc_detect_complete); | ||
55 | |||
56 | static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd); | ||
57 | |||
58 | static void __init pluto_detect_done(Scsi_Cmnd *SCpnt) | ||
59 | { | ||
60 | /* Do nothing */ | ||
61 | } | ||
62 | |||
63 | static void __init pluto_detect_scsi_done(Scsi_Cmnd *SCpnt) | ||
64 | { | ||
65 | PLND(("Detect done %08lx\n", (long)SCpnt)) | ||
66 | if (atomic_dec_and_test (&fcss)) | ||
67 | complete(&fc_detect_complete); | ||
68 | } | ||
69 | |||
70 | int pluto_slave_configure(struct scsi_device *device) | ||
71 | { | ||
72 | int depth_to_use; | ||
73 | |||
74 | if (device->tagged_supported) | ||
75 | depth_to_use = /* 254 */ 8; | ||
76 | else | ||
77 | depth_to_use = 2; | ||
78 | |||
79 | scsi_adjust_queue_depth(device, | ||
80 | (device->tagged_supported ? | ||
81 | MSG_SIMPLE_TAG : 0), | ||
82 | depth_to_use); | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | /* Detect all SSAs attached to the machine. | ||
88 | To be fast, do it on all online FC channels at the same time. */ | ||
89 | int __init pluto_detect(struct scsi_host_template *tpnt) | ||
90 | { | ||
91 | int i, retry, nplutos; | ||
92 | fc_channel *fc; | ||
93 | struct scsi_device dev; | ||
94 | |||
95 | tpnt->proc_name = "pluto"; | ||
96 | fcscount = 0; | ||
97 | for_each_online_fc_channel(fc) { | ||
98 | if (!fc->posmap) | ||
99 | fcscount++; | ||
100 | } | ||
101 | PLND(("%d channels online\n", fcscount)) | ||
102 | if (!fcscount) { | ||
103 | #if defined(MODULE) && defined(CONFIG_FC4_SOC_MODULE) && defined(CONFIG_KMOD) | ||
104 | request_module("soc"); | ||
105 | |||
106 | for_each_online_fc_channel(fc) { | ||
107 | if (!fc->posmap) | ||
108 | fcscount++; | ||
109 | } | ||
110 | if (!fcscount) | ||
111 | #endif | ||
112 | return 0; | ||
113 | } | ||
114 | fcs = kcalloc(fcscount, sizeof (struct ctrl_inquiry), GFP_DMA); | ||
115 | if (!fcs) { | ||
116 | printk ("PLUTO: Not enough memory to probe\n"); | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | memset (&dev, 0, sizeof(dev)); | ||
121 | atomic_set (&fcss, fcscount); | ||
122 | |||
123 | i = 0; | ||
124 | for_each_online_fc_channel(fc) { | ||
125 | Scsi_Cmnd *SCpnt; | ||
126 | struct Scsi_Host *host; | ||
127 | struct pluto *pluto; | ||
128 | |||
129 | if (i == fcscount) break; | ||
130 | if (fc->posmap) continue; | ||
131 | |||
132 | PLD(("trying to find SSA\n")) | ||
133 | |||
134 | /* If this is already registered to some other SCSI host, then it cannot be pluto */ | ||
135 | if (fc->scsi_name[0]) continue; | ||
136 | memcpy (fc->scsi_name, "SSA", 4); | ||
137 | |||
138 | fcs[i].fc = fc; | ||
139 | |||
140 | fc->can_queue = PLUTO_CAN_QUEUE; | ||
141 | fc->rsp_size = 64; | ||
142 | fc->encode_addr = pluto_encode_addr; | ||
143 | |||
144 | fc->fcp_register(fc, TYPE_SCSI_FCP, 0); | ||
145 | |||
146 | SCpnt = &(fcs[i].cmd); | ||
147 | host = &(fcs[i].host); | ||
148 | pluto = (struct pluto *)host->hostdata; | ||
149 | |||
150 | pluto->fc = fc; | ||
151 | |||
152 | SCpnt->cmnd[0] = INQUIRY; | ||
153 | SCpnt->cmnd[4] = 255; | ||
154 | |||
155 | /* FC layer requires this, so that SCpnt->device->tagged_supported is initially 0 */ | ||
156 | SCpnt->device = &dev; | ||
157 | dev.host = host; | ||
158 | |||
159 | SCpnt->cmd_len = COMMAND_SIZE(INQUIRY); | ||
160 | |||
161 | SCpnt->request->cmd_flags &= ~REQ_STARTED; | ||
162 | |||
163 | SCpnt->request_bufflen = 256; | ||
164 | SCpnt->request_buffer = fcs[i].inquiry; | ||
165 | PLD(("set up %d %08lx\n", i, (long)SCpnt)) | ||
166 | i++; | ||
167 | } | ||
168 | |||
169 | for (retry = 0; retry < 5; retry++) { | ||
170 | for (i = 0; i < fcscount; i++) { | ||
171 | if (!fcs[i].fc) break; | ||
172 | if (!(fcs[i].cmd.request->cmd_flags & REQ_STARTED)) { | ||
173 | fcs[i].cmd.request->cmd_flags |= REQ_STARTED; | ||
174 | disable_irq(fcs[i].fc->irq); | ||
175 | PLND(("queuecommand %d %d\n", retry, i)) | ||
176 | fcp_scsi_queuecommand (&(fcs[i].cmd), | ||
177 | pluto_detect_scsi_done); | ||
178 | enable_irq(fcs[i].fc->irq); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | wait_for_completion_timeout(&fc_detect_complete, 10 * HZ); | ||
183 | PLND(("Woken up\n")) | ||
184 | if (!atomic_read(&fcss)) | ||
185 | break; /* All fc channels have answered us */ | ||
186 | } | ||
187 | |||
188 | PLND(("Finished search\n")) | ||
189 | for (i = 0, nplutos = 0; i < fcscount; i++) { | ||
190 | Scsi_Cmnd *SCpnt; | ||
191 | |||
192 | if (!(fc = fcs[i].fc)) break; | ||
193 | |||
194 | SCpnt = &(fcs[i].cmd); | ||
195 | |||
196 | /* Let FC mid-level free allocated resources */ | ||
197 | pluto_detect_scsi_done(SCpnt); | ||
198 | |||
199 | if (!SCpnt->result) { | ||
200 | struct pluto_inquiry *inq; | ||
201 | struct pluto *pluto; | ||
202 | struct Scsi_Host *host; | ||
203 | |||
204 | inq = (struct pluto_inquiry *)fcs[i].inquiry; | ||
205 | |||
206 | if ((inq->dtype & 0x1f) == TYPE_PROCESSOR && | ||
207 | !strncmp (inq->vendor_id, "SUN", 3) && | ||
208 | !strncmp (inq->product_id, "SSA", 3)) { | ||
209 | char *p; | ||
210 | long *ages; | ||
211 | |||
212 | ages = kcalloc((inq->channels + 1) * inq->targets, sizeof(long), GFP_KERNEL); | ||
213 | if (!ages) continue; | ||
214 | |||
215 | host = scsi_register (tpnt, sizeof (struct pluto)); | ||
216 | if(!host) | ||
217 | { | ||
218 | kfree(ages); | ||
219 | continue; | ||
220 | } | ||
221 | |||
222 | if (!try_module_get(fc->module)) { | ||
223 | kfree(ages); | ||
224 | scsi_unregister(host); | ||
225 | continue; | ||
226 | } | ||
227 | |||
228 | nplutos++; | ||
229 | |||
230 | pluto = (struct pluto *)host->hostdata; | ||
231 | |||
232 | host->max_id = inq->targets; | ||
233 | host->max_channel = inq->channels; | ||
234 | host->irq = fc->irq; | ||
235 | |||
236 | fc->channels = inq->channels + 1; | ||
237 | fc->targets = inq->targets; | ||
238 | fc->ages = ages; | ||
239 | |||
240 | pluto->fc = fc; | ||
241 | memcpy (pluto->rev_str, inq->revision, 4); | ||
242 | pluto->rev_str[4] = 0; | ||
243 | p = strchr (pluto->rev_str, ' '); | ||
244 | if (p) *p = 0; | ||
245 | memcpy (pluto->fw_rev_str, inq->fw_revision, 4); | ||
246 | pluto->fw_rev_str[4] = 0; | ||
247 | p = strchr (pluto->fw_rev_str, ' '); | ||
248 | if (p) *p = 0; | ||
249 | memcpy (pluto->serial_str, inq->serial, 12); | ||
250 | pluto->serial_str[12] = 0; | ||
251 | p = strchr (pluto->serial_str, ' '); | ||
252 | if (p) *p = 0; | ||
253 | |||
254 | PLD(("Found SSA rev %s fw rev %s serial %s %dx%d\n", pluto->rev_str, pluto->fw_rev_str, pluto->serial_str, host->max_channel, host->max_id)) | ||
255 | } else | ||
256 | fc->fcp_register(fc, TYPE_SCSI_FCP, 1); | ||
257 | } else | ||
258 | fc->fcp_register(fc, TYPE_SCSI_FCP, 1); | ||
259 | } | ||
260 | kfree(fcs); | ||
261 | if (nplutos) | ||
262 | printk ("PLUTO: Total of %d SparcSTORAGE Arrays found\n", nplutos); | ||
263 | return nplutos; | ||
264 | } | ||
265 | |||
266 | int pluto_release(struct Scsi_Host *host) | ||
267 | { | ||
268 | struct pluto *pluto = (struct pluto *)host->hostdata; | ||
269 | fc_channel *fc = pluto->fc; | ||
270 | |||
271 | module_put(fc->module); | ||
272 | |||
273 | fc->fcp_register(fc, TYPE_SCSI_FCP, 1); | ||
274 | PLND((" releasing pluto.\n")); | ||
275 | kfree (fc->ages); | ||
276 | PLND(("released pluto!\n")); | ||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | const char *pluto_info(struct Scsi_Host *host) | ||
281 | { | ||
282 | static char buf[128], *p; | ||
283 | struct pluto *pluto = (struct pluto *) host->hostdata; | ||
284 | |||
285 | sprintf(buf, "SUN SparcSTORAGE Array %s fw %s serial %s %dx%d on %s", | ||
286 | pluto->rev_str, pluto->fw_rev_str, pluto->serial_str, | ||
287 | host->max_channel, host->max_id, pluto->fc->name); | ||
288 | #ifdef __sparc__ | ||
289 | p = strchr(buf, 0); | ||
290 | sprintf(p, " PROM node %x", pluto->fc->dev->prom_node); | ||
291 | #endif | ||
292 | return buf; | ||
293 | } | ||
294 | |||
295 | /* SSA uses this FC4S addressing: | ||
296 | switch (addr[0]) | ||
297 | { | ||
298 | case 0: CONTROLLER - All of addr[1]..addr[3] has to be 0 | ||
299 | case 1: SINGLE DISK - addr[1] channel, addr[2] id, addr[3] 0 | ||
300 | case 2: DISK GROUP - ??? | ||
301 | } | ||
302 | |||
303 | So that SCSI mid-layer can access to these, we reserve | ||
304 | channel 0 id 0 lun 0 for CONTROLLER | ||
305 | and channels 1 .. max_channel are normal single disks. | ||
306 | */ | ||
307 | static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd) | ||
308 | { | ||
309 | PLND(("encode addr %d %d %d\n", SCpnt->device->channel, SCpnt->device->id, SCpnt->cmnd[1] & 0xe0)) | ||
310 | /* We don't support LUNs - neither does SSA :) */ | ||
311 | if (SCpnt->cmnd[1] & 0xe0) | ||
312 | return -EINVAL; | ||
313 | if (!SCpnt->device->channel) { | ||
314 | if (SCpnt->device->id) | ||
315 | return -EINVAL; | ||
316 | memset (addr, 0, 4 * sizeof(u16)); | ||
317 | } else { | ||
318 | addr[0] = 1; | ||
319 | addr[1] = SCpnt->device->channel - 1; | ||
320 | addr[2] = SCpnt->device->id; | ||
321 | addr[3] = 0; | ||
322 | } | ||
323 | /* We're Point-to-Point, so target it to the default DID */ | ||
324 | fcmd->did = fc->did; | ||
325 | PLND(("trying %04x%04x%04x%04x\n", addr[0], addr[1], addr[2], addr[3])) | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static struct scsi_host_template driver_template = { | ||
330 | .name = "Sparc Storage Array 100/200", | ||
331 | .detect = pluto_detect, | ||
332 | .release = pluto_release, | ||
333 | .info = pluto_info, | ||
334 | .queuecommand = fcp_scsi_queuecommand, | ||
335 | .slave_configure = pluto_slave_configure, | ||
336 | .can_queue = PLUTO_CAN_QUEUE, | ||
337 | .this_id = -1, | ||
338 | .sg_tablesize = 1, | ||
339 | .cmd_per_lun = 1, | ||
340 | .use_clustering = ENABLE_CLUSTERING, | ||
341 | .eh_abort_handler = fcp_scsi_abort, | ||
342 | .eh_device_reset_handler = fcp_scsi_dev_reset, | ||
343 | .eh_host_reset_handler = fcp_scsi_host_reset, | ||
344 | }; | ||
345 | |||
346 | #include "scsi_module.c" | ||
347 | |||
348 | MODULE_LICENSE("GPL"); | ||
349 | |||
diff --git a/drivers/scsi/pluto.h b/drivers/scsi/pluto.h deleted file mode 100644 index 5da20616ac36..000000000000 --- a/drivers/scsi/pluto.h +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
1 | /* pluto.h: SparcSTORAGE Array SCSI host adapter driver definitions. | ||
2 | * | ||
3 | * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
4 | */ | ||
5 | |||
6 | #ifndef _PLUTO_H | ||
7 | #define _PLUTO_H | ||
8 | |||
9 | #include "../fc4/fcp_impl.h" | ||
10 | |||
11 | struct pluto { | ||
12 | /* This must be first */ | ||
13 | fc_channel *fc; | ||
14 | char rev_str[5]; | ||
15 | char fw_rev_str[5]; | ||
16 | char serial_str[13]; | ||
17 | }; | ||
18 | |||
19 | struct pluto_inquiry { | ||
20 | u8 dtype; | ||
21 | u8 removable:1, qualifier:7; | ||
22 | u8 iso:2, ecma:3, ansi:3; | ||
23 | u8 aenc:1, trmiop:1, :2, rdf:4; | ||
24 | u8 len; | ||
25 | u8 xxx1; | ||
26 | u8 xxx2; | ||
27 | u8 reladdr:1, wbus32:1, wbus16:1, sync:1, linked:1, :1, cmdque:1, softreset:1; | ||
28 | u8 vendor_id[8]; | ||
29 | u8 product_id[16]; | ||
30 | u8 revision[4]; | ||
31 | u8 fw_revision[4]; | ||
32 | u8 serial[12]; | ||
33 | u8 xxx3[2]; | ||
34 | u8 channels; | ||
35 | u8 targets; | ||
36 | }; | ||
37 | |||
38 | /* This is the max number of outstanding SCSI commands per pluto */ | ||
39 | #define PLUTO_CAN_QUEUE 254 | ||
40 | |||
41 | int pluto_detect(struct scsi_host_template *); | ||
42 | int pluto_release(struct Scsi_Host *); | ||
43 | const char * pluto_info(struct Scsi_Host *); | ||
44 | int pluto_slave_configure(struct scsi_device *); | ||
45 | |||
46 | #endif /* !(_PLUTO_H) */ | ||
47 | |||
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 76089cf55f4e..3aeb68bcb7ac 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c | |||
@@ -4310,7 +4310,7 @@ qla1280_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
4310 | printk(KERN_WARNING "scsi(%li): Unable to set a " | 4310 | printk(KERN_WARNING "scsi(%li): Unable to set a " |
4311 | "suitable DMA mask - aborting\n", ha->host_no); | 4311 | "suitable DMA mask - aborting\n", ha->host_no); |
4312 | error = -ENODEV; | 4312 | error = -ENODEV; |
4313 | goto error_free_irq; | 4313 | goto error_put_host; |
4314 | } | 4314 | } |
4315 | } else | 4315 | } else |
4316 | dprintk(2, "scsi(%li): 64 Bit PCI Addressing Enabled\n", | 4316 | dprintk(2, "scsi(%li): 64 Bit PCI Addressing Enabled\n", |
@@ -4320,7 +4320,7 @@ qla1280_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
4320 | printk(KERN_WARNING "scsi(%li): Unable to set a " | 4320 | printk(KERN_WARNING "scsi(%li): Unable to set a " |
4321 | "suitable DMA mask - aborting\n", ha->host_no); | 4321 | "suitable DMA mask - aborting\n", ha->host_no); |
4322 | error = -ENODEV; | 4322 | error = -ENODEV; |
4323 | goto error_free_irq; | 4323 | goto error_put_host; |
4324 | } | 4324 | } |
4325 | #endif | 4325 | #endif |
4326 | 4326 | ||
diff --git a/drivers/scsi/qla1280.h b/drivers/scsi/qla1280.h index 59915fb70301..ff2c363ead26 100644 --- a/drivers/scsi/qla1280.h +++ b/drivers/scsi/qla1280.h | |||
@@ -91,8 +91,8 @@ | |||
91 | #define INVALID_HANDLE (MAX_OUTSTANDING_COMMANDS + 2) | 91 | #define INVALID_HANDLE (MAX_OUTSTANDING_COMMANDS + 2) |
92 | 92 | ||
93 | /* ISP request and response entry counts (37-65535) */ | 93 | /* ISP request and response entry counts (37-65535) */ |
94 | #define REQUEST_ENTRY_CNT 256 /* Number of request entries. */ | 94 | #define REQUEST_ENTRY_CNT 255 /* Number of request entries. */ |
95 | #define RESPONSE_ENTRY_CNT 16 /* Number of response entries. */ | 95 | #define RESPONSE_ENTRY_CNT 63 /* Number of response entries. */ |
96 | 96 | ||
97 | /* | 97 | /* |
98 | * SCSI Request Block structure (sp) that is placed | 98 | * SCSI Request Block structure (sp) that is placed |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 05fa7796a559..fb388b8c07cf 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -114,7 +114,6 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj, | |||
114 | { | 114 | { |
115 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 115 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
116 | struct device, kobj))); | 116 | struct device, kobj))); |
117 | unsigned long flags; | ||
118 | uint16_t cnt; | 117 | uint16_t cnt; |
119 | 118 | ||
120 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size) | 119 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size) |
@@ -144,11 +143,9 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj, | |||
144 | } | 143 | } |
145 | 144 | ||
146 | /* Write NVRAM. */ | 145 | /* Write NVRAM. */ |
147 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
148 | ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count); | 146 | ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count); |
149 | ha->isp_ops->read_nvram(ha, (uint8_t *)ha->nvram, ha->nvram_base, | 147 | ha->isp_ops->read_nvram(ha, (uint8_t *)ha->nvram, ha->nvram_base, |
150 | count); | 148 | count); |
151 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
152 | 149 | ||
153 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 150 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
154 | 151 | ||
@@ -397,16 +394,13 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj, | |||
397 | { | 394 | { |
398 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 395 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
399 | struct device, kobj))); | 396 | struct device, kobj))); |
400 | unsigned long flags; | ||
401 | 397 | ||
402 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size) | 398 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size) |
403 | return 0; | 399 | return 0; |
404 | 400 | ||
405 | /* Write NVRAM. */ | 401 | /* Write NVRAM. */ |
406 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
407 | ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count); | 402 | ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count); |
408 | ha->isp_ops->read_nvram(ha, (uint8_t *)ha->vpd, ha->vpd_base, count); | 403 | ha->isp_ops->read_nvram(ha, (uint8_t *)ha->vpd, ha->vpd_base, count); |
409 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
410 | 404 | ||
411 | return count; | 405 | return count; |
412 | } | 406 | } |
@@ -544,6 +538,9 @@ qla2x00_serial_num_show(struct class_device *cdev, char *buf) | |||
544 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); | 538 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
545 | uint32_t sn; | 539 | uint32_t sn; |
546 | 540 | ||
541 | if (IS_FWI2_CAPABLE(ha)) | ||
542 | return snprintf(buf, PAGE_SIZE, "\n"); | ||
543 | |||
547 | sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; | 544 | sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; |
548 | return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000, | 545 | return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000, |
549 | sn % 100000); | 546 | sn % 100000); |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 1900fbf6cd74..04e8cbca4c0d 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2271,6 +2271,7 @@ typedef struct scsi_qla_host { | |||
2271 | 2271 | ||
2272 | spinlock_t hardware_lock ____cacheline_aligned; | 2272 | spinlock_t hardware_lock ____cacheline_aligned; |
2273 | 2273 | ||
2274 | int bars; | ||
2274 | device_reg_t __iomem *iobase; /* Base I/O address */ | 2275 | device_reg_t __iomem *iobase; /* Base I/O address */ |
2275 | unsigned long pio_address; | 2276 | unsigned long pio_address; |
2276 | unsigned long pio_length; | 2277 | unsigned long pio_length; |
diff --git a/drivers/scsi/qla2xxx/qla_devtbl.h b/drivers/scsi/qla2xxx/qla_devtbl.h index dd435410dfa2..d78d35e681ab 100644 --- a/drivers/scsi/qla2xxx/qla_devtbl.h +++ b/drivers/scsi/qla2xxx/qla_devtbl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | #define QLA_MODEL_NAMES 0x57 | 1 | #define QLA_MODEL_NAMES 0x5C |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Adapter model names and descriptions. | 4 | * Adapter model names and descriptions. |
@@ -91,4 +91,9 @@ static char *qla2x00_model_name[QLA_MODEL_NAMES*2] = { | |||
91 | " ", " ", /* 0x154 */ | 91 | " ", " ", /* 0x154 */ |
92 | "QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x155 */ | 92 | "QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x155 */ |
93 | "QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x156 */ | 93 | "QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x156 */ |
94 | " ", " ", /* 0x157 */ | ||
95 | " ", " ", /* 0x158 */ | ||
96 | " ", " ", /* 0x159 */ | ||
97 | " ", " ", /* 0x15a */ | ||
98 | "QME2472", "Dell BS PCI-Express to 4Gb FC, Dual Channel", /* 0x15b */ | ||
94 | }; | 99 | }; |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 7f6a89bd94f3..024c662ec34d 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -525,7 +525,7 @@ qla2x00_req_pkt(scsi_qla_host_t *ha) | |||
525 | 525 | ||
526 | /* Check for pending interrupts. */ | 526 | /* Check for pending interrupts. */ |
527 | /* During init we issue marker directly */ | 527 | /* During init we issue marker directly */ |
528 | if (!ha->marker_needed) | 528 | if (!ha->marker_needed && !ha->flags.init_done) |
529 | qla2x00_poll(ha); | 529 | qla2x00_poll(ha); |
530 | 530 | ||
531 | spin_lock_irq(&ha->hardware_lock); | 531 | spin_lock_irq(&ha->hardware_lock); |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index c4768c4f3990..1104bd2eed40 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -1012,8 +1012,14 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1012 | case CS_DATA_UNDERRUN: | 1012 | case CS_DATA_UNDERRUN: |
1013 | resid = resid_len; | 1013 | resid = resid_len; |
1014 | /* Use F/W calculated residual length. */ | 1014 | /* Use F/W calculated residual length. */ |
1015 | if (IS_FWI2_CAPABLE(ha)) | 1015 | if (IS_FWI2_CAPABLE(ha)) { |
1016 | if (scsi_status & SS_RESIDUAL_UNDER && | ||
1017 | resid != fw_resid_len) { | ||
1018 | scsi_status &= ~SS_RESIDUAL_UNDER; | ||
1019 | lscsi_status = 0; | ||
1020 | } | ||
1016 | resid = fw_resid_len; | 1021 | resid = fw_resid_len; |
1022 | } | ||
1017 | 1023 | ||
1018 | if (scsi_status & SS_RESIDUAL_UNDER) { | 1024 | if (scsi_status & SS_RESIDUAL_UNDER) { |
1019 | scsi_set_resid(cp, resid); | 1025 | scsi_set_resid(cp, resid); |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index c53ec67c47f4..ccd662a6f5dc 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -252,7 +252,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *pvha, mbx_cmd_t *mcp) | |||
252 | /* Clean up */ | 252 | /* Clean up */ |
253 | ha->mcp = NULL; | 253 | ha->mcp = NULL; |
254 | 254 | ||
255 | if (!abort_active) { | 255 | if (abort_active || !io_lock_on) { |
256 | DEBUG11(printk("%s(%ld): checking for additional resp " | 256 | DEBUG11(printk("%s(%ld): checking for additional resp " |
257 | "interrupt.\n", __func__, ha->host_no)); | 257 | "interrupt.\n", __func__, ha->host_no)); |
258 | 258 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 0351d380c2d7..a5bcf1f390b3 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -1482,6 +1482,17 @@ qla2x00_iospace_config(scsi_qla_host_t *ha) | |||
1482 | unsigned long pio, pio_len, pio_flags; | 1482 | unsigned long pio, pio_len, pio_flags; |
1483 | unsigned long mmio, mmio_len, mmio_flags; | 1483 | unsigned long mmio, mmio_len, mmio_flags; |
1484 | 1484 | ||
1485 | if (pci_request_selected_regions(ha->pdev, ha->bars, | ||
1486 | QLA2XXX_DRIVER_NAME)) { | ||
1487 | qla_printk(KERN_WARNING, ha, | ||
1488 | "Failed to reserve PIO/MMIO regions (%s)\n", | ||
1489 | pci_name(ha->pdev)); | ||
1490 | |||
1491 | goto iospace_error_exit; | ||
1492 | } | ||
1493 | if (!(ha->bars & 1)) | ||
1494 | goto skip_pio; | ||
1495 | |||
1485 | /* We only need PIO for Flash operations on ISP2312 v2 chips. */ | 1496 | /* We only need PIO for Flash operations on ISP2312 v2 chips. */ |
1486 | pio = pci_resource_start(ha->pdev, 0); | 1497 | pio = pci_resource_start(ha->pdev, 0); |
1487 | pio_len = pci_resource_len(ha->pdev, 0); | 1498 | pio_len = pci_resource_len(ha->pdev, 0); |
@@ -1499,7 +1510,10 @@ qla2x00_iospace_config(scsi_qla_host_t *ha) | |||
1499 | pci_name(ha->pdev)); | 1510 | pci_name(ha->pdev)); |
1500 | pio = 0; | 1511 | pio = 0; |
1501 | } | 1512 | } |
1513 | ha->pio_address = pio; | ||
1514 | ha->pio_length = pio_len; | ||
1502 | 1515 | ||
1516 | skip_pio: | ||
1503 | /* Use MMIO operations for all accesses. */ | 1517 | /* Use MMIO operations for all accesses. */ |
1504 | mmio = pci_resource_start(ha->pdev, 1); | 1518 | mmio = pci_resource_start(ha->pdev, 1); |
1505 | mmio_len = pci_resource_len(ha->pdev, 1); | 1519 | mmio_len = pci_resource_len(ha->pdev, 1); |
@@ -1518,16 +1532,6 @@ qla2x00_iospace_config(scsi_qla_host_t *ha) | |||
1518 | goto iospace_error_exit; | 1532 | goto iospace_error_exit; |
1519 | } | 1533 | } |
1520 | 1534 | ||
1521 | if (pci_request_regions(ha->pdev, QLA2XXX_DRIVER_NAME)) { | ||
1522 | qla_printk(KERN_WARNING, ha, | ||
1523 | "Failed to reserve PIO/MMIO regions (%s)\n", | ||
1524 | pci_name(ha->pdev)); | ||
1525 | |||
1526 | goto iospace_error_exit; | ||
1527 | } | ||
1528 | |||
1529 | ha->pio_address = pio; | ||
1530 | ha->pio_length = pio_len; | ||
1531 | ha->iobase = ioremap(mmio, MIN_IOBASE_LEN); | 1535 | ha->iobase = ioremap(mmio, MIN_IOBASE_LEN); |
1532 | if (!ha->iobase) { | 1536 | if (!ha->iobase) { |
1533 | qla_printk(KERN_ERR, ha, | 1537 | qla_printk(KERN_ERR, ha, |
@@ -1579,21 +1583,26 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1579 | char pci_info[30]; | 1583 | char pci_info[30]; |
1580 | char fw_str[30]; | 1584 | char fw_str[30]; |
1581 | struct scsi_host_template *sht; | 1585 | struct scsi_host_template *sht; |
1586 | int bars; | ||
1582 | 1587 | ||
1583 | if (pci_enable_device(pdev)) | 1588 | bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO); |
1584 | goto probe_out; | ||
1585 | |||
1586 | if (pci_find_aer_capability(pdev)) | ||
1587 | if (pci_enable_pcie_error_reporting(pdev)) | ||
1588 | goto probe_out; | ||
1589 | |||
1590 | sht = &qla2x00_driver_template; | 1589 | sht = &qla2x00_driver_template; |
1591 | if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || | 1590 | if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || |
1592 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || | 1591 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || |
1593 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 || | 1592 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 || |
1594 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 || | 1593 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 || |
1595 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) | 1594 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) { |
1595 | bars = pci_select_bars(pdev, IORESOURCE_MEM); | ||
1596 | sht = &qla24xx_driver_template; | 1596 | sht = &qla24xx_driver_template; |
1597 | } | ||
1598 | |||
1599 | if (pci_enable_device_bars(pdev, bars)) | ||
1600 | goto probe_out; | ||
1601 | |||
1602 | if (pci_find_aer_capability(pdev)) | ||
1603 | if (pci_enable_pcie_error_reporting(pdev)) | ||
1604 | goto probe_out; | ||
1605 | |||
1597 | host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t)); | 1606 | host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t)); |
1598 | if (host == NULL) { | 1607 | if (host == NULL) { |
1599 | printk(KERN_WARNING | 1608 | printk(KERN_WARNING |
@@ -1610,6 +1619,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1610 | ha->host_no = host->host_no; | 1619 | ha->host_no = host->host_no; |
1611 | sprintf(ha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, ha->host_no); | 1620 | sprintf(ha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, ha->host_no); |
1612 | ha->parent = NULL; | 1621 | ha->parent = NULL; |
1622 | ha->bars = bars; | ||
1613 | 1623 | ||
1614 | /* Set ISP-type information. */ | 1624 | /* Set ISP-type information. */ |
1615 | qla2x00_set_isp_flags(ha); | 1625 | qla2x00_set_isp_flags(ha); |
@@ -1880,7 +1890,7 @@ qla2x00_free_device(scsi_qla_host_t *ha) | |||
1880 | /* release io space registers */ | 1890 | /* release io space registers */ |
1881 | if (ha->iobase) | 1891 | if (ha->iobase) |
1882 | iounmap(ha->iobase); | 1892 | iounmap(ha->iobase); |
1883 | pci_release_regions(ha->pdev); | 1893 | pci_release_selected_regions(ha->pdev, ha->bars); |
1884 | } | 1894 | } |
1885 | 1895 | ||
1886 | static inline void | 1896 | static inline void |
@@ -2890,7 +2900,7 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) | |||
2890 | pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT; | 2900 | pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT; |
2891 | scsi_qla_host_t *ha = pci_get_drvdata(pdev); | 2901 | scsi_qla_host_t *ha = pci_get_drvdata(pdev); |
2892 | 2902 | ||
2893 | if (pci_enable_device(pdev)) { | 2903 | if (pci_enable_device_bars(pdev, ha->bars)) { |
2894 | qla_printk(KERN_WARNING, ha, | 2904 | qla_printk(KERN_WARNING, ha, |
2895 | "Can't re-enable PCI device after reset.\n"); | 2905 | "Can't re-enable PCI device after reset.\n"); |
2896 | 2906 | ||
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 40b059fc1981..ad2fa01bd233 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include "qla_def.h" | 7 | #include "qla_def.h" |
8 | 8 | ||
9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
10 | #include <linux/vmalloc.h> | ||
10 | #include <asm/uaccess.h> | 11 | #include <asm/uaccess.h> |
11 | 12 | ||
12 | static uint16_t qla2x00_nvram_request(scsi_qla_host_t *, uint32_t); | 13 | static uint16_t qla2x00_nvram_request(scsi_qla_host_t *, uint32_t); |
@@ -642,7 +643,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | |||
642 | } | 643 | } |
643 | 644 | ||
644 | /* Go with burst-write. */ | 645 | /* Go with burst-write. */ |
645 | if (optrom && (liter + OPTROM_BURST_DWORDS) < dwords) { | 646 | if (optrom && (liter + OPTROM_BURST_DWORDS) <= dwords) { |
646 | /* Copy data to DMA'ble buffer. */ | 647 | /* Copy data to DMA'ble buffer. */ |
647 | for (miter = 0, s = optrom, d = dwptr; | 648 | for (miter = 0, s = optrom, d = dwptr; |
648 | miter < OPTROM_BURST_DWORDS; miter++, s++, d++) | 649 | miter < OPTROM_BURST_DWORDS; miter++, s++, d++) |
@@ -656,7 +657,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | |||
656 | "Unable to burst-write optrom segment " | 657 | "Unable to burst-write optrom segment " |
657 | "(%x/%x/%llx).\n", ret, | 658 | "(%x/%x/%llx).\n", ret, |
658 | flash_data_to_access_addr(faddr), | 659 | flash_data_to_access_addr(faddr), |
659 | optrom_dma); | 660 | (unsigned long long)optrom_dma); |
660 | qla_printk(KERN_WARNING, ha, | 661 | qla_printk(KERN_WARNING, ha, |
661 | "Reverting to slow-write.\n"); | 662 | "Reverting to slow-write.\n"); |
662 | 663 | ||
@@ -745,9 +746,11 @@ qla2x00_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, | |||
745 | int ret, stat; | 746 | int ret, stat; |
746 | uint32_t i; | 747 | uint32_t i; |
747 | uint16_t *wptr; | 748 | uint16_t *wptr; |
749 | unsigned long flags; | ||
748 | 750 | ||
749 | ret = QLA_SUCCESS; | 751 | ret = QLA_SUCCESS; |
750 | 752 | ||
753 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
751 | qla2x00_lock_nvram_access(ha); | 754 | qla2x00_lock_nvram_access(ha); |
752 | 755 | ||
753 | /* Disable NVRAM write-protection. */ | 756 | /* Disable NVRAM write-protection. */ |
@@ -764,6 +767,7 @@ qla2x00_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, | |||
764 | qla2x00_set_nvram_protection(ha, stat); | 767 | qla2x00_set_nvram_protection(ha, stat); |
765 | 768 | ||
766 | qla2x00_unlock_nvram_access(ha); | 769 | qla2x00_unlock_nvram_access(ha); |
770 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
767 | 771 | ||
768 | return ret; | 772 | return ret; |
769 | } | 773 | } |
@@ -776,9 +780,11 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, | |||
776 | uint32_t i; | 780 | uint32_t i; |
777 | uint32_t *dwptr; | 781 | uint32_t *dwptr; |
778 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 782 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
783 | unsigned long flags; | ||
779 | 784 | ||
780 | ret = QLA_SUCCESS; | 785 | ret = QLA_SUCCESS; |
781 | 786 | ||
787 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
782 | /* Enable flash write. */ | 788 | /* Enable flash write. */ |
783 | WRT_REG_DWORD(®->ctrl_status, | 789 | WRT_REG_DWORD(®->ctrl_status, |
784 | RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); | 790 | RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); |
@@ -812,6 +818,7 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, | |||
812 | WRT_REG_DWORD(®->ctrl_status, | 818 | WRT_REG_DWORD(®->ctrl_status, |
813 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); | 819 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); |
814 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ | 820 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ |
821 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
815 | 822 | ||
816 | return ret; | 823 | return ret; |
817 | } | 824 | } |
@@ -836,8 +843,20 @@ int | |||
836 | qla25xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, | 843 | qla25xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, |
837 | uint32_t bytes) | 844 | uint32_t bytes) |
838 | { | 845 | { |
839 | return qla24xx_write_flash_data(ha, (uint32_t *)buf, | 846 | #define RMW_BUFFER_SIZE (64 * 1024) |
840 | FA_VPD_NVRAM_ADDR | naddr, bytes >> 2); | 847 | uint8_t *dbuf; |
848 | |||
849 | dbuf = vmalloc(RMW_BUFFER_SIZE); | ||
850 | if (!dbuf) | ||
851 | return QLA_MEMORY_ALLOC_FAILED; | ||
852 | ha->isp_ops->read_optrom(ha, dbuf, FA_VPD_NVRAM_ADDR << 2, | ||
853 | RMW_BUFFER_SIZE); | ||
854 | memcpy(dbuf + (naddr << 2), buf, bytes); | ||
855 | ha->isp_ops->write_optrom(ha, dbuf, FA_VPD_NVRAM_ADDR << 2, | ||
856 | RMW_BUFFER_SIZE); | ||
857 | vfree(dbuf); | ||
858 | |||
859 | return QLA_SUCCESS; | ||
841 | } | 860 | } |
842 | 861 | ||
843 | static inline void | 862 | static inline void |
@@ -1853,7 +1872,8 @@ qla25xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, | |||
1853 | qla_printk(KERN_WARNING, ha, | 1872 | qla_printk(KERN_WARNING, ha, |
1854 | "Unable to burst-read optrom segment " | 1873 | "Unable to burst-read optrom segment " |
1855 | "(%x/%x/%llx).\n", rval, | 1874 | "(%x/%x/%llx).\n", rval, |
1856 | flash_data_to_access_addr(faddr), optrom_dma); | 1875 | flash_data_to_access_addr(faddr), |
1876 | (unsigned long long)optrom_dma); | ||
1857 | qla_printk(KERN_WARNING, ha, | 1877 | qla_printk(KERN_WARNING, ha, |
1858 | "Reverting to slow-read.\n"); | 1878 | "Reverting to slow-read.\n"); |
1859 | 1879 | ||
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 2d551a3006f6..ae6f7a2fb19f 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.00-k4" | 10 | #define QLA2XXX_VERSION "8.02.00-k5" |
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/scsi_error.c b/drivers/scsi/scsi_error.c index d29f8464b74f..ebaca4ca4a13 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/blkdev.h> | 25 | #include <linux/blkdev.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/scatterlist.h> | ||
28 | 27 | ||
29 | #include <scsi/scsi.h> | 28 | #include <scsi/scsi.h> |
30 | #include <scsi/scsi_cmnd.h> | 29 | #include <scsi/scsi_cmnd.h> |
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index daed37df00b1..d531ceeb0d8c 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -209,11 +209,13 @@ show_shost_mode(unsigned int mode, char *buf) | |||
209 | static ssize_t show_shost_supported_mode(struct class_device *class_dev, char *buf) | 209 | static ssize_t show_shost_supported_mode(struct class_device *class_dev, char *buf) |
210 | { | 210 | { |
211 | struct Scsi_Host *shost = class_to_shost(class_dev); | 211 | struct Scsi_Host *shost = class_to_shost(class_dev); |
212 | unsigned int supported_mode = shost->hostt->supported_mode; | ||
212 | 213 | ||
213 | if (shost->hostt->supported_mode == MODE_UNKNOWN) | 214 | if (supported_mode == MODE_UNKNOWN) |
214 | return snprintf(buf, 20, "unknown\n"); | 215 | /* by default this should be initiator */ |
215 | else | 216 | supported_mode = MODE_INITIATOR; |
216 | return show_shost_mode(shost->hostt->supported_mode, buf); | 217 | |
218 | return show_shost_mode(supported_mode, buf); | ||
217 | } | 219 | } |
218 | 220 | ||
219 | static CLASS_DEVICE_ATTR(supported_mode, S_IRUGO | S_IWUSR, show_shost_supported_mode, NULL); | 221 | static CLASS_DEVICE_ATTR(supported_mode, S_IRUGO | S_IWUSR, show_shost_supported_mode, NULL); |
diff --git a/drivers/scsi/sym53c8xx_2/sym53c8xx.h b/drivers/scsi/sym53c8xx_2/sym53c8xx.h index 7519728dfc38..62d29cfac9e4 100644 --- a/drivers/scsi/sym53c8xx_2/sym53c8xx.h +++ b/drivers/scsi/sym53c8xx_2/sym53c8xx.h | |||
@@ -127,7 +127,6 @@ struct sym_driver_setup { | |||
127 | u_char settle_delay; | 127 | u_char settle_delay; |
128 | u_char use_nvram; | 128 | u_char use_nvram; |
129 | u_long excludes[8]; | 129 | u_long excludes[8]; |
130 | char tag_ctrl[100]; | ||
131 | }; | 130 | }; |
132 | 131 | ||
133 | #define SYM_SETUP_MAX_TAG sym_driver_setup.max_tag | 132 | #define SYM_SETUP_MAX_TAG sym_driver_setup.max_tag |
diff --git a/drivers/scsi/sym53c8xx_2/sym_fw.c b/drivers/scsi/sym53c8xx_2/sym_fw.c index 9916a2a22558..190770bdc194 100644 --- a/drivers/scsi/sym53c8xx_2/sym_fw.c +++ b/drivers/scsi/sym53c8xx_2/sym_fw.c | |||
@@ -104,8 +104,9 @@ static struct sym_fwz_ofs sym_fw2z_ofs = { | |||
104 | * Patch routine for firmware #1. | 104 | * Patch routine for firmware #1. |
105 | */ | 105 | */ |
106 | static void | 106 | static void |
107 | sym_fw1_patch(struct sym_hcb *np) | 107 | sym_fw1_patch(struct Scsi_Host *shost) |
108 | { | 108 | { |
109 | struct sym_hcb *np = sym_get_hcb(shost); | ||
109 | struct sym_fw1a_scr *scripta0; | 110 | struct sym_fw1a_scr *scripta0; |
110 | struct sym_fw1b_scr *scriptb0; | 111 | struct sym_fw1b_scr *scriptb0; |
111 | 112 | ||
@@ -145,8 +146,11 @@ sym_fw1_patch(struct sym_hcb *np) | |||
145 | * Patch routine for firmware #2. | 146 | * Patch routine for firmware #2. |
146 | */ | 147 | */ |
147 | static void | 148 | static void |
148 | sym_fw2_patch(struct sym_hcb *np) | 149 | sym_fw2_patch(struct Scsi_Host *shost) |
149 | { | 150 | { |
151 | struct sym_data *sym_data = shost_priv(shost); | ||
152 | struct pci_dev *pdev = sym_data->pdev; | ||
153 | struct sym_hcb *np = sym_data->ncb; | ||
150 | struct sym_fw2a_scr *scripta0; | 154 | struct sym_fw2a_scr *scripta0; |
151 | struct sym_fw2b_scr *scriptb0; | 155 | struct sym_fw2b_scr *scriptb0; |
152 | 156 | ||
@@ -167,7 +171,7 @@ sym_fw2_patch(struct sym_hcb *np) | |||
167 | * Remove useless 64 bit DMA specific SCRIPTS, | 171 | * Remove useless 64 bit DMA specific SCRIPTS, |
168 | * when this feature is not available. | 172 | * when this feature is not available. |
169 | */ | 173 | */ |
170 | if (!np->use_dac) { | 174 | if (!use_dac(np)) { |
171 | scripta0->is_dmap_dirty[0] = cpu_to_scr(SCR_NO_OP); | 175 | scripta0->is_dmap_dirty[0] = cpu_to_scr(SCR_NO_OP); |
172 | scripta0->is_dmap_dirty[1] = 0; | 176 | scripta0->is_dmap_dirty[1] = 0; |
173 | scripta0->is_dmap_dirty[2] = cpu_to_scr(SCR_NO_OP); | 177 | scripta0->is_dmap_dirty[2] = cpu_to_scr(SCR_NO_OP); |
@@ -205,14 +209,14 @@ sym_fw2_patch(struct sym_hcb *np) | |||
205 | * Remove a couple of work-arounds specific to C1010 if | 209 | * Remove a couple of work-arounds specific to C1010 if |
206 | * they are not desirable. See `sym_fw2.h' for more details. | 210 | * they are not desirable. See `sym_fw2.h' for more details. |
207 | */ | 211 | */ |
208 | if (!(np->device_id == PCI_DEVICE_ID_LSI_53C1010_66 && | 212 | if (!(pdev->device == PCI_DEVICE_ID_LSI_53C1010_66 && |
209 | np->revision_id < 0x1 && | 213 | pdev->revision < 0x1 && |
210 | np->pciclk_khz < 60000)) { | 214 | np->pciclk_khz < 60000)) { |
211 | scripta0->datao_phase[0] = cpu_to_scr(SCR_NO_OP); | 215 | scripta0->datao_phase[0] = cpu_to_scr(SCR_NO_OP); |
212 | scripta0->datao_phase[1] = cpu_to_scr(0); | 216 | scripta0->datao_phase[1] = cpu_to_scr(0); |
213 | } | 217 | } |
214 | if (!(np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 && | 218 | if (!(pdev->device == PCI_DEVICE_ID_LSI_53C1010_33 /* && |
215 | /* np->revision_id < 0xff */ 1)) { | 219 | pdev->revision < 0xff */)) { |
216 | scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP); | 220 | scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP); |
217 | scripta0->sel_done[1] = cpu_to_scr(0); | 221 | scripta0->sel_done[1] = cpu_to_scr(0); |
218 | } | 222 | } |
diff --git a/drivers/scsi/sym53c8xx_2/sym_fw.h b/drivers/scsi/sym53c8xx_2/sym_fw.h index 66ec35beab5b..ae7e0f9e93fc 100644 --- a/drivers/scsi/sym53c8xx_2/sym_fw.h +++ b/drivers/scsi/sym53c8xx_2/sym_fw.h | |||
@@ -143,7 +143,7 @@ struct sym_fw { | |||
143 | *z_ofs; /* Useful offsets in script Z */ | 143 | *z_ofs; /* Useful offsets in script Z */ |
144 | /* Setup and patch methods for this firmware */ | 144 | /* Setup and patch methods for this firmware */ |
145 | void (*setup)(struct sym_hcb *, struct sym_fw *); | 145 | void (*setup)(struct sym_hcb *, struct sym_fw *); |
146 | void (*patch)(struct sym_hcb *); | 146 | void (*patch)(struct Scsi_Host *); |
147 | }; | 147 | }; |
148 | 148 | ||
149 | /* | 149 | /* |
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index db03c4c8ec1e..0f74aba5b237 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c | |||
@@ -39,7 +39,6 @@ | |||
39 | */ | 39 | */ |
40 | #include <linux/ctype.h> | 40 | #include <linux/ctype.h> |
41 | #include <linux/init.h> | 41 | #include <linux/init.h> |
42 | #include <linux/interrupt.h> | ||
43 | #include <linux/module.h> | 42 | #include <linux/module.h> |
44 | #include <linux/moduleparam.h> | 43 | #include <linux/moduleparam.h> |
45 | #include <linux/spinlock.h> | 44 | #include <linux/spinlock.h> |
@@ -54,16 +53,12 @@ | |||
54 | #define NAME53C "sym53c" | 53 | #define NAME53C "sym53c" |
55 | #define NAME53C8XX "sym53c8xx" | 54 | #define NAME53C8XX "sym53c8xx" |
56 | 55 | ||
57 | #define IRQ_FMT "%d" | ||
58 | #define IRQ_PRM(x) (x) | ||
59 | |||
60 | struct sym_driver_setup sym_driver_setup = SYM_LINUX_DRIVER_SETUP; | 56 | struct sym_driver_setup sym_driver_setup = SYM_LINUX_DRIVER_SETUP; |
61 | unsigned int sym_debug_flags = 0; | 57 | unsigned int sym_debug_flags = 0; |
62 | 58 | ||
63 | static char *excl_string; | 59 | static char *excl_string; |
64 | static char *safe_string; | 60 | static char *safe_string; |
65 | module_param_named(cmd_per_lun, sym_driver_setup.max_tag, ushort, 0); | 61 | module_param_named(cmd_per_lun, sym_driver_setup.max_tag, ushort, 0); |
66 | module_param_string(tag_ctrl, sym_driver_setup.tag_ctrl, 100, 0); | ||
67 | module_param_named(burst, sym_driver_setup.burst_order, byte, 0); | 62 | module_param_named(burst, sym_driver_setup.burst_order, byte, 0); |
68 | module_param_named(led, sym_driver_setup.scsi_led, byte, 0); | 63 | module_param_named(led, sym_driver_setup.scsi_led, byte, 0); |
69 | module_param_named(diff, sym_driver_setup.scsi_diff, byte, 0); | 64 | module_param_named(diff, sym_driver_setup.scsi_diff, byte, 0); |
@@ -78,7 +73,6 @@ module_param_named(excl, excl_string, charp, 0); | |||
78 | module_param_named(safe, safe_string, charp, 0); | 73 | module_param_named(safe, safe_string, charp, 0); |
79 | 74 | ||
80 | MODULE_PARM_DESC(cmd_per_lun, "The maximum number of tags to use by default"); | 75 | MODULE_PARM_DESC(cmd_per_lun, "The maximum number of tags to use by default"); |
81 | MODULE_PARM_DESC(tag_ctrl, "More detailed control over tags per LUN"); | ||
82 | MODULE_PARM_DESC(burst, "Maximum burst. 0 to disable, 255 to read from registers"); | 76 | MODULE_PARM_DESC(burst, "Maximum burst. 0 to disable, 255 to read from registers"); |
83 | MODULE_PARM_DESC(led, "Set to 1 to enable LED support"); | 77 | MODULE_PARM_DESC(led, "Set to 1 to enable LED support"); |
84 | MODULE_PARM_DESC(diff, "0 for no differential mode, 1 for BIOS, 2 for always, 3 for not GPIO3"); | 78 | MODULE_PARM_DESC(diff, "0 for no differential mode, 1 for BIOS, 2 for always, 3 for not GPIO3"); |
@@ -134,56 +128,26 @@ static struct scsi_transport_template *sym2_transport_template = NULL; | |||
134 | * Driver private area in the SCSI command structure. | 128 | * Driver private area in the SCSI command structure. |
135 | */ | 129 | */ |
136 | struct sym_ucmd { /* Override the SCSI pointer structure */ | 130 | struct sym_ucmd { /* Override the SCSI pointer structure */ |
137 | dma_addr_t data_mapping; | 131 | struct completion *eh_done; /* SCSI error handling */ |
138 | unsigned char data_mapped; | ||
139 | unsigned char to_do; /* For error handling */ | ||
140 | void (*old_done)(struct scsi_cmnd *); /* For error handling */ | ||
141 | struct completion *eh_done; /* For error handling */ | ||
142 | }; | 132 | }; |
143 | 133 | ||
144 | #define SYM_UCMD_PTR(cmd) ((struct sym_ucmd *)(&(cmd)->SCp)) | 134 | #define SYM_UCMD_PTR(cmd) ((struct sym_ucmd *)(&(cmd)->SCp)) |
145 | #define SYM_SOFTC_PTR(cmd) sym_get_hcb(cmd->device->host) | 135 | #define SYM_SOFTC_PTR(cmd) sym_get_hcb(cmd->device->host) |
146 | 136 | ||
147 | static void __unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) | ||
148 | { | ||
149 | if (SYM_UCMD_PTR(cmd)->data_mapped) | ||
150 | scsi_dma_unmap(cmd); | ||
151 | |||
152 | SYM_UCMD_PTR(cmd)->data_mapped = 0; | ||
153 | } | ||
154 | |||
155 | static int __map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) | ||
156 | { | ||
157 | int use_sg; | ||
158 | |||
159 | use_sg = scsi_dma_map(cmd); | ||
160 | if (use_sg > 0) { | ||
161 | SYM_UCMD_PTR(cmd)->data_mapped = 2; | ||
162 | SYM_UCMD_PTR(cmd)->data_mapping = use_sg; | ||
163 | } | ||
164 | |||
165 | return use_sg; | ||
166 | } | ||
167 | |||
168 | #define unmap_scsi_data(np, cmd) \ | ||
169 | __unmap_scsi_data(np->s.device, cmd) | ||
170 | #define map_scsi_sg_data(np, cmd) \ | ||
171 | __map_scsi_sg_data(np->s.device, cmd) | ||
172 | /* | 137 | /* |
173 | * Complete a pending CAM CCB. | 138 | * Complete a pending CAM CCB. |
174 | */ | 139 | */ |
175 | void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *cmd) | 140 | void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *cmd) |
176 | { | 141 | { |
177 | unmap_scsi_data(np, cmd); | 142 | struct sym_ucmd *ucmd = SYM_UCMD_PTR(cmd); |
178 | cmd->scsi_done(cmd); | 143 | BUILD_BUG_ON(sizeof(struct scsi_pointer) < sizeof(struct sym_ucmd)); |
179 | } | ||
180 | 144 | ||
181 | static void sym_xpt_done2(struct sym_hcb *np, struct scsi_cmnd *cmd, int cam_status) | 145 | if (ucmd->eh_done) |
182 | { | 146 | complete(ucmd->eh_done); |
183 | sym_set_cam_status(cmd, cam_status); | ||
184 | sym_xpt_done(np, cmd); | ||
185 | } | ||
186 | 147 | ||
148 | scsi_dma_unmap(cmd); | ||
149 | cmd->scsi_done(cmd); | ||
150 | } | ||
187 | 151 | ||
188 | /* | 152 | /* |
189 | * Tell the SCSI layer about a BUS RESET. | 153 | * Tell the SCSI layer about a BUS RESET. |
@@ -199,14 +163,6 @@ void sym_xpt_async_bus_reset(struct sym_hcb *np) | |||
199 | } | 163 | } |
200 | 164 | ||
201 | /* | 165 | /* |
202 | * Tell the SCSI layer about a BUS DEVICE RESET message sent. | ||
203 | */ | ||
204 | void sym_xpt_async_sent_bdr(struct sym_hcb *np, int target) | ||
205 | { | ||
206 | printf_notice("%s: TARGET %d has been reset.\n", sym_name(np), target); | ||
207 | } | ||
208 | |||
209 | /* | ||
210 | * Choose the more appropriate CAM status if | 166 | * Choose the more appropriate CAM status if |
211 | * the IO encountered an extended error. | 167 | * the IO encountered an extended error. |
212 | */ | 168 | */ |
@@ -307,14 +263,14 @@ static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd | |||
307 | 263 | ||
308 | cp->data_len = 0; | 264 | cp->data_len = 0; |
309 | 265 | ||
310 | use_sg = map_scsi_sg_data(np, cmd); | 266 | use_sg = scsi_dma_map(cmd); |
311 | if (use_sg > 0) { | 267 | if (use_sg > 0) { |
312 | struct scatterlist *sg; | 268 | struct scatterlist *sg; |
313 | struct sym_tcb *tp = &np->target[cp->target]; | 269 | struct sym_tcb *tp = &np->target[cp->target]; |
314 | struct sym_tblmove *data; | 270 | struct sym_tblmove *data; |
315 | 271 | ||
316 | if (use_sg > SYM_CONF_MAX_SG) { | 272 | if (use_sg > SYM_CONF_MAX_SG) { |
317 | unmap_scsi_data(np, cmd); | 273 | scsi_dma_unmap(cmd); |
318 | return -1; | 274 | return -1; |
319 | } | 275 | } |
320 | 276 | ||
@@ -351,15 +307,6 @@ static int sym_queue_command(struct sym_hcb *np, struct scsi_cmnd *cmd) | |||
351 | int order; | 307 | int order; |
352 | 308 | ||
353 | /* | 309 | /* |
354 | * Minimal checkings, so that we will not | ||
355 | * go outside our tables. | ||
356 | */ | ||
357 | if (sdev->id == np->myaddr) { | ||
358 | sym_xpt_done2(np, cmd, DID_NO_CONNECT); | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | /* | ||
363 | * Retrieve the target descriptor. | 310 | * Retrieve the target descriptor. |
364 | */ | 311 | */ |
365 | tp = &np->target[sdev->id]; | 312 | tp = &np->target[sdev->id]; |
@@ -433,7 +380,7 @@ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct s | |||
433 | */ | 380 | */ |
434 | switch (dir) { | 381 | switch (dir) { |
435 | case DMA_BIDIRECTIONAL: | 382 | case DMA_BIDIRECTIONAL: |
436 | printk("%s: got DMA_BIDIRECTIONAL command", sym_name(np)); | 383 | scmd_printk(KERN_INFO, cmd, "got DMA_BIDIRECTIONAL command"); |
437 | sym_set_cam_status(cmd, DID_ERROR); | 384 | sym_set_cam_status(cmd, DID_ERROR); |
438 | goto out_abort; | 385 | goto out_abort; |
439 | case DMA_TO_DEVICE: | 386 | case DMA_TO_DEVICE: |
@@ -542,14 +489,16 @@ static void sym_timer(struct sym_hcb *np) | |||
542 | /* | 489 | /* |
543 | * PCI BUS error handler. | 490 | * PCI BUS error handler. |
544 | */ | 491 | */ |
545 | void sym_log_bus_error(struct sym_hcb *np) | 492 | void sym_log_bus_error(struct Scsi_Host *shost) |
546 | { | 493 | { |
547 | u_short pci_sts; | 494 | struct sym_data *sym_data = shost_priv(shost); |
548 | pci_read_config_word(np->s.device, PCI_STATUS, &pci_sts); | 495 | struct pci_dev *pdev = sym_data->pdev; |
496 | unsigned short pci_sts; | ||
497 | pci_read_config_word(pdev, PCI_STATUS, &pci_sts); | ||
549 | if (pci_sts & 0xf900) { | 498 | if (pci_sts & 0xf900) { |
550 | pci_write_config_word(np->s.device, PCI_STATUS, pci_sts); | 499 | pci_write_config_word(pdev, PCI_STATUS, pci_sts); |
551 | printf("%s: PCI STATUS = 0x%04x\n", | 500 | shost_printk(KERN_WARNING, shost, |
552 | sym_name(np), pci_sts & 0xf900); | 501 | "PCI bus error: status = 0x%04x\n", pci_sts & 0xf900); |
553 | } | 502 | } |
554 | } | 503 | } |
555 | 504 | ||
@@ -564,7 +513,7 @@ static int sym53c8xx_queue_command(struct scsi_cmnd *cmd, | |||
564 | struct sym_ucmd *ucp = SYM_UCMD_PTR(cmd); | 513 | struct sym_ucmd *ucp = SYM_UCMD_PTR(cmd); |
565 | int sts = 0; | 514 | int sts = 0; |
566 | 515 | ||
567 | cmd->scsi_done = done; | 516 | cmd->scsi_done = done; |
568 | memset(ucp, 0, sizeof(*ucp)); | 517 | memset(ucp, 0, sizeof(*ucp)); |
569 | 518 | ||
570 | /* | 519 | /* |
@@ -593,18 +542,23 @@ static int sym53c8xx_queue_command(struct scsi_cmnd *cmd, | |||
593 | */ | 542 | */ |
594 | static irqreturn_t sym53c8xx_intr(int irq, void *dev_id) | 543 | static irqreturn_t sym53c8xx_intr(int irq, void *dev_id) |
595 | { | 544 | { |
596 | unsigned long flags; | 545 | struct Scsi_Host *shost = dev_id; |
597 | struct sym_hcb *np = (struct sym_hcb *)dev_id; | 546 | struct sym_data *sym_data = shost_priv(shost); |
547 | irqreturn_t result; | ||
548 | |||
549 | /* Avoid spinloop trying to handle interrupts on frozen device */ | ||
550 | if (pci_channel_offline(sym_data->pdev)) | ||
551 | return IRQ_NONE; | ||
598 | 552 | ||
599 | if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("["); | 553 | if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("["); |
600 | 554 | ||
601 | spin_lock_irqsave(np->s.host->host_lock, flags); | 555 | spin_lock(shost->host_lock); |
602 | sym_interrupt(np); | 556 | result = sym_interrupt(shost); |
603 | spin_unlock_irqrestore(np->s.host->host_lock, flags); | 557 | spin_unlock(shost->host_lock); |
604 | 558 | ||
605 | if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("]\n"); | 559 | if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("]\n"); |
606 | 560 | ||
607 | return IRQ_HANDLED; | 561 | return result; |
608 | } | 562 | } |
609 | 563 | ||
610 | /* | 564 | /* |
@@ -630,59 +584,61 @@ static void sym53c8xx_timer(unsigned long npref) | |||
630 | #define SYM_EH_HOST_RESET 3 | 584 | #define SYM_EH_HOST_RESET 3 |
631 | 585 | ||
632 | /* | 586 | /* |
633 | * What we will do regarding the involved SCSI command. | ||
634 | */ | ||
635 | #define SYM_EH_DO_IGNORE 0 | ||
636 | #define SYM_EH_DO_WAIT 2 | ||
637 | |||
638 | /* | ||
639 | * scsi_done() alias when error recovery is in progress. | ||
640 | */ | ||
641 | static void sym_eh_done(struct scsi_cmnd *cmd) | ||
642 | { | ||
643 | struct sym_ucmd *ucmd = SYM_UCMD_PTR(cmd); | ||
644 | BUILD_BUG_ON(sizeof(struct scsi_pointer) < sizeof(struct sym_ucmd)); | ||
645 | |||
646 | cmd->scsi_done = ucmd->old_done; | ||
647 | |||
648 | if (ucmd->to_do == SYM_EH_DO_WAIT) | ||
649 | complete(ucmd->eh_done); | ||
650 | } | ||
651 | |||
652 | /* | ||
653 | * Generic method for our eh processing. | 587 | * Generic method for our eh processing. |
654 | * The 'op' argument tells what we have to do. | 588 | * The 'op' argument tells what we have to do. |
655 | */ | 589 | */ |
656 | static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd) | 590 | static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd) |
657 | { | 591 | { |
658 | struct sym_hcb *np = SYM_SOFTC_PTR(cmd); | ||
659 | struct sym_ucmd *ucmd = SYM_UCMD_PTR(cmd); | 592 | struct sym_ucmd *ucmd = SYM_UCMD_PTR(cmd); |
660 | struct Scsi_Host *host = cmd->device->host; | 593 | struct Scsi_Host *shost = cmd->device->host; |
594 | struct sym_data *sym_data = shost_priv(shost); | ||
595 | struct pci_dev *pdev = sym_data->pdev; | ||
596 | struct sym_hcb *np = sym_data->ncb; | ||
661 | SYM_QUEHEAD *qp; | 597 | SYM_QUEHEAD *qp; |
662 | int to_do = SYM_EH_DO_IGNORE; | 598 | int cmd_queued = 0; |
663 | int sts = -1; | 599 | int sts = -1; |
664 | struct completion eh_done; | 600 | struct completion eh_done; |
665 | 601 | ||
666 | dev_warn(&cmd->device->sdev_gendev, "%s operation started.\n", opname); | 602 | scmd_printk(KERN_WARNING, cmd, "%s operation started\n", opname); |
603 | |||
604 | /* We may be in an error condition because the PCI bus | ||
605 | * went down. In this case, we need to wait until the | ||
606 | * PCI bus is reset, the card is reset, and only then | ||
607 | * proceed with the scsi error recovery. There's no | ||
608 | * point in hurrying; take a leisurely wait. | ||
609 | */ | ||
610 | #define WAIT_FOR_PCI_RECOVERY 35 | ||
611 | if (pci_channel_offline(pdev)) { | ||
612 | struct completion *io_reset; | ||
613 | int finished_reset = 0; | ||
614 | init_completion(&eh_done); | ||
615 | spin_lock_irq(shost->host_lock); | ||
616 | /* Make sure we didn't race */ | ||
617 | if (pci_channel_offline(pdev)) { | ||
618 | if (!sym_data->io_reset) | ||
619 | sym_data->io_reset = &eh_done; | ||
620 | io_reset = sym_data->io_reset; | ||
621 | } else { | ||
622 | finished_reset = 1; | ||
623 | } | ||
624 | spin_unlock_irq(shost->host_lock); | ||
625 | if (!finished_reset) | ||
626 | finished_reset = wait_for_completion_timeout(io_reset, | ||
627 | WAIT_FOR_PCI_RECOVERY*HZ); | ||
628 | if (!finished_reset) | ||
629 | return SCSI_FAILED; | ||
630 | } | ||
667 | 631 | ||
668 | spin_lock_irq(host->host_lock); | 632 | spin_lock_irq(shost->host_lock); |
669 | /* This one is queued in some place -> to wait for completion */ | 633 | /* This one is queued in some place -> to wait for completion */ |
670 | FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) { | 634 | FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) { |
671 | struct sym_ccb *cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); | 635 | struct sym_ccb *cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); |
672 | if (cp->cmd == cmd) { | 636 | if (cp->cmd == cmd) { |
673 | to_do = SYM_EH_DO_WAIT; | 637 | cmd_queued = 1; |
674 | break; | 638 | break; |
675 | } | 639 | } |
676 | } | 640 | } |
677 | 641 | ||
678 | if (to_do == SYM_EH_DO_WAIT) { | ||
679 | init_completion(&eh_done); | ||
680 | ucmd->old_done = cmd->scsi_done; | ||
681 | ucmd->eh_done = &eh_done; | ||
682 | wmb(); | ||
683 | cmd->scsi_done = sym_eh_done; | ||
684 | } | ||
685 | |||
686 | /* Try to proceed the operation we have been asked for */ | 642 | /* Try to proceed the operation we have been asked for */ |
687 | sts = -1; | 643 | sts = -1; |
688 | switch(op) { | 644 | switch(op) { |
@@ -698,7 +654,7 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd) | |||
698 | break; | 654 | break; |
699 | case SYM_EH_HOST_RESET: | 655 | case SYM_EH_HOST_RESET: |
700 | sym_reset_scsi_bus(np, 0); | 656 | sym_reset_scsi_bus(np, 0); |
701 | sym_start_up (np, 1); | 657 | sym_start_up(shost, 1); |
702 | sts = 0; | 658 | sts = 0; |
703 | break; | 659 | break; |
704 | default: | 660 | default: |
@@ -706,21 +662,21 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd) | |||
706 | } | 662 | } |
707 | 663 | ||
708 | /* On error, restore everything and cross fingers :) */ | 664 | /* On error, restore everything and cross fingers :) */ |
709 | if (sts) { | 665 | if (sts) |
710 | cmd->scsi_done = ucmd->old_done; | 666 | cmd_queued = 0; |
711 | to_do = SYM_EH_DO_IGNORE; | ||
712 | } | ||
713 | |||
714 | ucmd->to_do = to_do; | ||
715 | spin_unlock_irq(host->host_lock); | ||
716 | 667 | ||
717 | if (to_do == SYM_EH_DO_WAIT) { | 668 | if (cmd_queued) { |
669 | init_completion(&eh_done); | ||
670 | ucmd->eh_done = &eh_done; | ||
671 | spin_unlock_irq(shost->host_lock); | ||
718 | if (!wait_for_completion_timeout(&eh_done, 5*HZ)) { | 672 | if (!wait_for_completion_timeout(&eh_done, 5*HZ)) { |
719 | ucmd->to_do = SYM_EH_DO_IGNORE; | 673 | ucmd->eh_done = NULL; |
720 | wmb(); | ||
721 | sts = -2; | 674 | sts = -2; |
722 | } | 675 | } |
676 | } else { | ||
677 | spin_unlock_irq(shost->host_lock); | ||
723 | } | 678 | } |
679 | |||
724 | dev_warn(&cmd->device->sdev_gendev, "%s operation %s.\n", opname, | 680 | dev_warn(&cmd->device->sdev_gendev, "%s operation %s.\n", opname, |
725 | sts==0 ? "complete" :sts==-2 ? "timed-out" : "failed"); | 681 | sts==0 ? "complete" :sts==-2 ? "timed-out" : "failed"); |
726 | return sts ? SCSI_FAILED : SCSI_SUCCESS; | 682 | return sts ? SCSI_FAILED : SCSI_SUCCESS; |
@@ -775,59 +731,6 @@ static void sym_tune_dev_queuing(struct sym_tcb *tp, int lun, u_short reqtags) | |||
775 | } | 731 | } |
776 | } | 732 | } |
777 | 733 | ||
778 | /* | ||
779 | * Linux select queue depths function | ||
780 | */ | ||
781 | #define DEF_DEPTH (sym_driver_setup.max_tag) | ||
782 | #define ALL_TARGETS -2 | ||
783 | #define NO_TARGET -1 | ||
784 | #define ALL_LUNS -2 | ||
785 | #define NO_LUN -1 | ||
786 | |||
787 | static int device_queue_depth(struct sym_hcb *np, int target, int lun) | ||
788 | { | ||
789 | int c, h, t, u, v; | ||
790 | char *p = sym_driver_setup.tag_ctrl; | ||
791 | char *ep; | ||
792 | |||
793 | h = -1; | ||
794 | t = NO_TARGET; | ||
795 | u = NO_LUN; | ||
796 | while ((c = *p++) != 0) { | ||
797 | v = simple_strtoul(p, &ep, 0); | ||
798 | switch(c) { | ||
799 | case '/': | ||
800 | ++h; | ||
801 | t = ALL_TARGETS; | ||
802 | u = ALL_LUNS; | ||
803 | break; | ||
804 | case 't': | ||
805 | if (t != target) | ||
806 | t = (target == v) ? v : NO_TARGET; | ||
807 | u = ALL_LUNS; | ||
808 | break; | ||
809 | case 'u': | ||
810 | if (u != lun) | ||
811 | u = (lun == v) ? v : NO_LUN; | ||
812 | break; | ||
813 | case 'q': | ||
814 | if (h == np->s.unit && | ||
815 | (t == ALL_TARGETS || t == target) && | ||
816 | (u == ALL_LUNS || u == lun)) | ||
817 | return v; | ||
818 | break; | ||
819 | case '-': | ||
820 | t = ALL_TARGETS; | ||
821 | u = ALL_LUNS; | ||
822 | break; | ||
823 | default: | ||
824 | break; | ||
825 | } | ||
826 | p = ep; | ||
827 | } | ||
828 | return DEF_DEPTH; | ||
829 | } | ||
830 | |||
831 | static int sym53c8xx_slave_alloc(struct scsi_device *sdev) | 734 | static int sym53c8xx_slave_alloc(struct scsi_device *sdev) |
832 | { | 735 | { |
833 | struct sym_hcb *np = sym_get_hcb(sdev->host); | 736 | struct sym_hcb *np = sym_get_hcb(sdev->host); |
@@ -892,21 +795,16 @@ static int sym53c8xx_slave_configure(struct scsi_device *sdev) | |||
892 | * Use at least 2. | 795 | * Use at least 2. |
893 | * Donnot use more than our maximum. | 796 | * Donnot use more than our maximum. |
894 | */ | 797 | */ |
895 | reqtags = device_queue_depth(np, sdev->id, sdev->lun); | 798 | reqtags = sym_driver_setup.max_tag; |
896 | if (reqtags > tp->usrtags) | 799 | if (reqtags > tp->usrtags) |
897 | reqtags = tp->usrtags; | 800 | reqtags = tp->usrtags; |
898 | if (!sdev->tagged_supported) | 801 | if (!sdev->tagged_supported) |
899 | reqtags = 0; | 802 | reqtags = 0; |
900 | #if 1 /* Avoid to locally queue commands for no good reasons */ | ||
901 | if (reqtags > SYM_CONF_MAX_TAG) | 803 | if (reqtags > SYM_CONF_MAX_TAG) |
902 | reqtags = SYM_CONF_MAX_TAG; | 804 | reqtags = SYM_CONF_MAX_TAG; |
903 | depth_to_use = (reqtags ? reqtags : 2); | 805 | depth_to_use = reqtags ? reqtags : 2; |
904 | #else | ||
905 | depth_to_use = (reqtags ? SYM_CONF_MAX_TAG : 2); | ||
906 | #endif | ||
907 | scsi_adjust_queue_depth(sdev, | 806 | scsi_adjust_queue_depth(sdev, |
908 | (sdev->tagged_supported ? | 807 | sdev->tagged_supported ? MSG_SIMPLE_TAG : 0, |
909 | MSG_SIMPLE_TAG : 0), | ||
910 | depth_to_use); | 808 | depth_to_use); |
911 | lp->s.scdev_depth = depth_to_use; | 809 | lp->s.scdev_depth = depth_to_use; |
912 | sym_tune_dev_queuing(tp, sdev->lun, reqtags); | 810 | sym_tune_dev_queuing(tp, sdev->lun, reqtags); |
@@ -1089,8 +987,9 @@ static int is_keyword(char *ptr, int len, char *verb) | |||
1089 | * Parse a control command | 987 | * Parse a control command |
1090 | */ | 988 | */ |
1091 | 989 | ||
1092 | static int sym_user_command(struct sym_hcb *np, char *buffer, int length) | 990 | static int sym_user_command(struct Scsi_Host *shost, char *buffer, int length) |
1093 | { | 991 | { |
992 | struct sym_hcb *np = sym_get_hcb(shost); | ||
1094 | char *ptr = buffer; | 993 | char *ptr = buffer; |
1095 | int len = length; | 994 | int len = length; |
1096 | struct sym_usrcmd cmd, *uc = &cmd; | 995 | struct sym_usrcmd cmd, *uc = &cmd; |
@@ -1217,9 +1116,9 @@ printk("sym_user_command: data=%ld\n", uc->data); | |||
1217 | else { | 1116 | else { |
1218 | unsigned long flags; | 1117 | unsigned long flags; |
1219 | 1118 | ||
1220 | spin_lock_irqsave(np->s.host->host_lock, flags); | 1119 | spin_lock_irqsave(shost->host_lock, flags); |
1221 | sym_exec_user_command (np, uc); | 1120 | sym_exec_user_command(np, uc); |
1222 | spin_unlock_irqrestore(np->s.host->host_lock, flags); | 1121 | spin_unlock_irqrestore(shost->host_lock, flags); |
1223 | } | 1122 | } |
1224 | return length; | 1123 | return length; |
1225 | } | 1124 | } |
@@ -1275,8 +1174,11 @@ static int copy_info(struct info_str *info, char *fmt, ...) | |||
1275 | /* | 1174 | /* |
1276 | * Copy formatted information into the input buffer. | 1175 | * Copy formatted information into the input buffer. |
1277 | */ | 1176 | */ |
1278 | static int sym_host_info(struct sym_hcb *np, char *ptr, off_t offset, int len) | 1177 | static int sym_host_info(struct Scsi_Host *shost, char *ptr, off_t offset, int len) |
1279 | { | 1178 | { |
1179 | struct sym_data *sym_data = shost_priv(shost); | ||
1180 | struct pci_dev *pdev = sym_data->pdev; | ||
1181 | struct sym_hcb *np = sym_data->ncb; | ||
1280 | struct info_str info; | 1182 | struct info_str info; |
1281 | 1183 | ||
1282 | info.buffer = ptr; | 1184 | info.buffer = ptr; |
@@ -1285,10 +1187,10 @@ static int sym_host_info(struct sym_hcb *np, char *ptr, off_t offset, int len) | |||
1285 | info.pos = 0; | 1187 | info.pos = 0; |
1286 | 1188 | ||
1287 | copy_info(&info, "Chip " NAME53C "%s, device id 0x%x, " | 1189 | copy_info(&info, "Chip " NAME53C "%s, device id 0x%x, " |
1288 | "revision id 0x%x\n", | 1190 | "revision id 0x%x\n", np->s.chip_name, |
1289 | np->s.chip_name, np->device_id, np->revision_id); | 1191 | pdev->device, pdev->revision); |
1290 | copy_info(&info, "At PCI address %s, IRQ " IRQ_FMT "\n", | 1192 | copy_info(&info, "At PCI address %s, IRQ %u\n", |
1291 | pci_name(np->s.device), IRQ_PRM(np->s.irq)); | 1193 | pci_name(pdev), pdev->irq); |
1292 | copy_info(&info, "Min. period factor %d, %s SCSI BUS%s\n", | 1194 | copy_info(&info, "Min. period factor %d, %s SCSI BUS%s\n", |
1293 | (int) (np->minsync_dt ? np->minsync_dt : np->minsync), | 1195 | (int) (np->minsync_dt ? np->minsync_dt : np->minsync), |
1294 | np->maxwide ? "Wide" : "Narrow", | 1196 | np->maxwide ? "Wide" : "Narrow", |
@@ -1307,15 +1209,14 @@ static int sym_host_info(struct sym_hcb *np, char *ptr, off_t offset, int len) | |||
1307 | * - func = 0 means read (returns adapter infos) | 1209 | * - func = 0 means read (returns adapter infos) |
1308 | * - func = 1 means write (not yet merget from sym53c8xx) | 1210 | * - func = 1 means write (not yet merget from sym53c8xx) |
1309 | */ | 1211 | */ |
1310 | static int sym53c8xx_proc_info(struct Scsi_Host *host, char *buffer, | 1212 | static int sym53c8xx_proc_info(struct Scsi_Host *shost, char *buffer, |
1311 | char **start, off_t offset, int length, int func) | 1213 | char **start, off_t offset, int length, int func) |
1312 | { | 1214 | { |
1313 | struct sym_hcb *np = sym_get_hcb(host); | ||
1314 | int retv; | 1215 | int retv; |
1315 | 1216 | ||
1316 | if (func) { | 1217 | if (func) { |
1317 | #ifdef SYM_LINUX_USER_COMMAND_SUPPORT | 1218 | #ifdef SYM_LINUX_USER_COMMAND_SUPPORT |
1318 | retv = sym_user_command(np, buffer, length); | 1219 | retv = sym_user_command(shost, buffer, length); |
1319 | #else | 1220 | #else |
1320 | retv = -EINVAL; | 1221 | retv = -EINVAL; |
1321 | #endif | 1222 | #endif |
@@ -1323,7 +1224,7 @@ static int sym53c8xx_proc_info(struct Scsi_Host *host, char *buffer, | |||
1323 | if (start) | 1224 | if (start) |
1324 | *start = buffer; | 1225 | *start = buffer; |
1325 | #ifdef SYM_LINUX_USER_INFO_SUPPORT | 1226 | #ifdef SYM_LINUX_USER_INFO_SUPPORT |
1326 | retv = sym_host_info(np, buffer, offset, length); | 1227 | retv = sym_host_info(shost, buffer, offset, length); |
1327 | #else | 1228 | #else |
1328 | retv = -EINVAL; | 1229 | retv = -EINVAL; |
1329 | #endif | 1230 | #endif |
@@ -1341,8 +1242,8 @@ static void sym_free_resources(struct sym_hcb *np, struct pci_dev *pdev) | |||
1341 | /* | 1242 | /* |
1342 | * Free O/S specific resources. | 1243 | * Free O/S specific resources. |
1343 | */ | 1244 | */ |
1344 | if (np->s.irq) | 1245 | if (pdev->irq) |
1345 | free_irq(np->s.irq, np); | 1246 | free_irq(pdev->irq, np); |
1346 | if (np->s.ioaddr) | 1247 | if (np->s.ioaddr) |
1347 | pci_iounmap(pdev, np->s.ioaddr); | 1248 | pci_iounmap(pdev, np->s.ioaddr); |
1348 | if (np->s.ramaddr) | 1249 | if (np->s.ramaddr) |
@@ -1356,31 +1257,6 @@ static void sym_free_resources(struct sym_hcb *np, struct pci_dev *pdev) | |||
1356 | } | 1257 | } |
1357 | 1258 | ||
1358 | /* | 1259 | /* |
1359 | * Ask/tell the system about DMA addressing. | ||
1360 | */ | ||
1361 | static int sym_setup_bus_dma_mask(struct sym_hcb *np) | ||
1362 | { | ||
1363 | #if SYM_CONF_DMA_ADDRESSING_MODE > 0 | ||
1364 | #if SYM_CONF_DMA_ADDRESSING_MODE == 1 | ||
1365 | #define DMA_DAC_MASK DMA_40BIT_MASK | ||
1366 | #elif SYM_CONF_DMA_ADDRESSING_MODE == 2 | ||
1367 | #define DMA_DAC_MASK DMA_64BIT_MASK | ||
1368 | #endif | ||
1369 | if ((np->features & FE_DAC) && | ||
1370 | !pci_set_dma_mask(np->s.device, DMA_DAC_MASK)) { | ||
1371 | np->use_dac = 1; | ||
1372 | return 0; | ||
1373 | } | ||
1374 | #endif | ||
1375 | |||
1376 | if (!pci_set_dma_mask(np->s.device, DMA_32BIT_MASK)) | ||
1377 | return 0; | ||
1378 | |||
1379 | printf_warning("%s: No suitable DMA available\n", sym_name(np)); | ||
1380 | return -1; | ||
1381 | } | ||
1382 | |||
1383 | /* | ||
1384 | * Host attach and initialisations. | 1260 | * Host attach and initialisations. |
1385 | * | 1261 | * |
1386 | * Allocate host data and ncb structure. | 1262 | * Allocate host data and ncb structure. |
@@ -1392,32 +1268,28 @@ static int sym_setup_bus_dma_mask(struct sym_hcb *np) | |||
1392 | static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | 1268 | static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, |
1393 | int unit, struct sym_device *dev) | 1269 | int unit, struct sym_device *dev) |
1394 | { | 1270 | { |
1395 | struct host_data *host_data; | 1271 | struct sym_data *sym_data; |
1396 | struct sym_hcb *np = NULL; | 1272 | struct sym_hcb *np = NULL; |
1397 | struct Scsi_Host *instance = NULL; | 1273 | struct Scsi_Host *shost; |
1398 | struct pci_dev *pdev = dev->pdev; | 1274 | struct pci_dev *pdev = dev->pdev; |
1399 | unsigned long flags; | 1275 | unsigned long flags; |
1400 | struct sym_fw *fw; | 1276 | struct sym_fw *fw; |
1401 | 1277 | ||
1402 | printk(KERN_INFO | 1278 | printk(KERN_INFO "sym%d: <%s> rev 0x%x at pci %s irq %u\n", |
1403 | "sym%d: <%s> rev 0x%x at pci %s irq " IRQ_FMT "\n", | 1279 | unit, dev->chip.name, pdev->revision, pci_name(pdev), |
1404 | unit, dev->chip.name, dev->chip.revision_id, | 1280 | pdev->irq); |
1405 | pci_name(pdev), IRQ_PRM(pdev->irq)); | ||
1406 | 1281 | ||
1407 | /* | 1282 | /* |
1408 | * Get the firmware for this chip. | 1283 | * Get the firmware for this chip. |
1409 | */ | 1284 | */ |
1410 | fw = sym_find_firmware(&dev->chip); | 1285 | fw = sym_find_firmware(&dev->chip); |
1411 | if (!fw) | 1286 | if (!fw) |
1412 | goto attach_failed; | 1287 | return NULL; |
1413 | 1288 | ||
1414 | /* | 1289 | shost = scsi_host_alloc(tpnt, sizeof(*sym_data)); |
1415 | * Allocate host_data structure | 1290 | if (!shost) |
1416 | */ | 1291 | return NULL; |
1417 | instance = scsi_host_alloc(tpnt, sizeof(*host_data)); | 1292 | sym_data = shost_priv(shost); |
1418 | if (!instance) | ||
1419 | goto attach_failed; | ||
1420 | host_data = (struct host_data *) instance->hostdata; | ||
1421 | 1293 | ||
1422 | /* | 1294 | /* |
1423 | * Allocate immediately the host control block, | 1295 | * Allocate immediately the host control block, |
@@ -1428,22 +1300,19 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1428 | np = __sym_calloc_dma(&pdev->dev, sizeof(*np), "HCB"); | 1300 | np = __sym_calloc_dma(&pdev->dev, sizeof(*np), "HCB"); |
1429 | if (!np) | 1301 | if (!np) |
1430 | goto attach_failed; | 1302 | goto attach_failed; |
1431 | np->s.device = pdev; | ||
1432 | np->bus_dmat = &pdev->dev; /* Result in 1 DMA pool per HBA */ | 1303 | np->bus_dmat = &pdev->dev; /* Result in 1 DMA pool per HBA */ |
1433 | host_data->ncb = np; | 1304 | sym_data->ncb = np; |
1434 | np->s.host = instance; | 1305 | sym_data->pdev = pdev; |
1306 | np->s.host = shost; | ||
1435 | 1307 | ||
1436 | pci_set_drvdata(pdev, np); | 1308 | pci_set_drvdata(pdev, shost); |
1437 | 1309 | ||
1438 | /* | 1310 | /* |
1439 | * Copy some useful infos to the HCB. | 1311 | * Copy some useful infos to the HCB. |
1440 | */ | 1312 | */ |
1441 | np->hcb_ba = vtobus(np); | 1313 | np->hcb_ba = vtobus(np); |
1442 | np->verbose = sym_driver_setup.verbose; | 1314 | np->verbose = sym_driver_setup.verbose; |
1443 | np->s.device = pdev; | ||
1444 | np->s.unit = unit; | 1315 | np->s.unit = unit; |
1445 | np->device_id = dev->chip.device_id; | ||
1446 | np->revision_id = dev->chip.revision_id; | ||
1447 | np->features = dev->chip.features; | 1316 | np->features = dev->chip.features; |
1448 | np->clock_divn = dev->chip.nr_divisor; | 1317 | np->clock_divn = dev->chip.nr_divisor; |
1449 | np->maxoffs = dev->chip.offset_max; | 1318 | np->maxoffs = dev->chip.offset_max; |
@@ -1456,8 +1325,13 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1456 | strlcpy(np->s.chip_name, dev->chip.name, sizeof(np->s.chip_name)); | 1325 | strlcpy(np->s.chip_name, dev->chip.name, sizeof(np->s.chip_name)); |
1457 | sprintf(np->s.inst_name, "sym%d", np->s.unit); | 1326 | sprintf(np->s.inst_name, "sym%d", np->s.unit); |
1458 | 1327 | ||
1459 | if (sym_setup_bus_dma_mask(np)) | 1328 | if ((SYM_CONF_DMA_ADDRESSING_MODE > 0) && (np->features & FE_DAC) && |
1329 | !pci_set_dma_mask(pdev, DMA_DAC_MASK)) { | ||
1330 | set_dac(np); | ||
1331 | } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { | ||
1332 | printf_warning("%s: No suitable DMA available\n", sym_name(np)); | ||
1460 | goto attach_failed; | 1333 | goto attach_failed; |
1334 | } | ||
1461 | 1335 | ||
1462 | /* | 1336 | /* |
1463 | * Try to map the controller chip to | 1337 | * Try to map the controller chip to |
@@ -1466,19 +1340,16 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1466 | np->mmio_ba = (u32)dev->mmio_base; | 1340 | np->mmio_ba = (u32)dev->mmio_base; |
1467 | np->s.ioaddr = dev->s.ioaddr; | 1341 | np->s.ioaddr = dev->s.ioaddr; |
1468 | np->s.ramaddr = dev->s.ramaddr; | 1342 | np->s.ramaddr = dev->s.ramaddr; |
1469 | np->s.io_ws = (np->features & FE_IO256) ? 256 : 128; | ||
1470 | 1343 | ||
1471 | /* | 1344 | /* |
1472 | * Map on-chip RAM if present and supported. | 1345 | * Map on-chip RAM if present and supported. |
1473 | */ | 1346 | */ |
1474 | if (!(np->features & FE_RAM)) | 1347 | if (!(np->features & FE_RAM)) |
1475 | dev->ram_base = 0; | 1348 | dev->ram_base = 0; |
1476 | if (dev->ram_base) { | 1349 | if (dev->ram_base) |
1477 | np->ram_ba = (u32)dev->ram_base; | 1350 | np->ram_ba = (u32)dev->ram_base; |
1478 | np->ram_ws = (np->features & FE_RAM8K) ? 8192 : 4096; | ||
1479 | } | ||
1480 | 1351 | ||
1481 | if (sym_hcb_attach(instance, fw, dev->nvram)) | 1352 | if (sym_hcb_attach(shost, fw, dev->nvram)) |
1482 | goto attach_failed; | 1353 | goto attach_failed; |
1483 | 1354 | ||
1484 | /* | 1355 | /* |
@@ -1486,25 +1357,25 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1486 | * If we synchonize the C code with SCRIPTS on interrupt, | 1357 | * If we synchonize the C code with SCRIPTS on interrupt, |
1487 | * we do not want to share the INTR line at all. | 1358 | * we do not want to share the INTR line at all. |
1488 | */ | 1359 | */ |
1489 | if (request_irq(pdev->irq, sym53c8xx_intr, IRQF_SHARED, NAME53C8XX, np)) { | 1360 | if (request_irq(pdev->irq, sym53c8xx_intr, IRQF_SHARED, NAME53C8XX, |
1490 | printf_err("%s: request irq %d failure\n", | 1361 | shost)) { |
1362 | printf_err("%s: request irq %u failure\n", | ||
1491 | sym_name(np), pdev->irq); | 1363 | sym_name(np), pdev->irq); |
1492 | goto attach_failed; | 1364 | goto attach_failed; |
1493 | } | 1365 | } |
1494 | np->s.irq = pdev->irq; | ||
1495 | 1366 | ||
1496 | /* | 1367 | /* |
1497 | * After SCSI devices have been opened, we cannot | 1368 | * After SCSI devices have been opened, we cannot |
1498 | * reset the bus safely, so we do it here. | 1369 | * reset the bus safely, so we do it here. |
1499 | */ | 1370 | */ |
1500 | spin_lock_irqsave(instance->host_lock, flags); | 1371 | spin_lock_irqsave(shost->host_lock, flags); |
1501 | if (sym_reset_scsi_bus(np, 0)) | 1372 | if (sym_reset_scsi_bus(np, 0)) |
1502 | goto reset_failed; | 1373 | goto reset_failed; |
1503 | 1374 | ||
1504 | /* | 1375 | /* |
1505 | * Start the SCRIPTS. | 1376 | * Start the SCRIPTS. |
1506 | */ | 1377 | */ |
1507 | sym_start_up (np, 1); | 1378 | sym_start_up(shost, 1); |
1508 | 1379 | ||
1509 | /* | 1380 | /* |
1510 | * Start the timer daemon | 1381 | * Start the timer daemon |
@@ -1519,33 +1390,37 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1519 | * Fill Linux host instance structure | 1390 | * Fill Linux host instance structure |
1520 | * and return success. | 1391 | * and return success. |
1521 | */ | 1392 | */ |
1522 | instance->max_channel = 0; | 1393 | shost->max_channel = 0; |
1523 | instance->this_id = np->myaddr; | 1394 | shost->this_id = np->myaddr; |
1524 | instance->max_id = np->maxwide ? 16 : 8; | 1395 | shost->max_id = np->maxwide ? 16 : 8; |
1525 | instance->max_lun = SYM_CONF_MAX_LUN; | 1396 | shost->max_lun = SYM_CONF_MAX_LUN; |
1526 | instance->unique_id = pci_resource_start(pdev, 0); | 1397 | shost->unique_id = pci_resource_start(pdev, 0); |
1527 | instance->cmd_per_lun = SYM_CONF_MAX_TAG; | 1398 | shost->cmd_per_lun = SYM_CONF_MAX_TAG; |
1528 | instance->can_queue = (SYM_CONF_MAX_START-2); | 1399 | shost->can_queue = (SYM_CONF_MAX_START-2); |
1529 | instance->sg_tablesize = SYM_CONF_MAX_SG; | 1400 | shost->sg_tablesize = SYM_CONF_MAX_SG; |
1530 | instance->max_cmd_len = 16; | 1401 | shost->max_cmd_len = 16; |
1531 | BUG_ON(sym2_transport_template == NULL); | 1402 | BUG_ON(sym2_transport_template == NULL); |
1532 | instance->transportt = sym2_transport_template; | 1403 | shost->transportt = sym2_transport_template; |
1404 | |||
1405 | /* 53c896 rev 1 errata: DMA may not cross 16MB boundary */ | ||
1406 | if (pdev->device == PCI_DEVICE_ID_NCR_53C896 && pdev->revision < 2) | ||
1407 | shost->dma_boundary = 0xFFFFFF; | ||
1533 | 1408 | ||
1534 | spin_unlock_irqrestore(instance->host_lock, flags); | 1409 | spin_unlock_irqrestore(shost->host_lock, flags); |
1535 | 1410 | ||
1536 | return instance; | 1411 | return shost; |
1537 | 1412 | ||
1538 | reset_failed: | 1413 | reset_failed: |
1539 | printf_err("%s: FATAL ERROR: CHECK SCSI BUS - CABLES, " | 1414 | printf_err("%s: FATAL ERROR: CHECK SCSI BUS - CABLES, " |
1540 | "TERMINATION, DEVICE POWER etc.!\n", sym_name(np)); | 1415 | "TERMINATION, DEVICE POWER etc.!\n", sym_name(np)); |
1541 | spin_unlock_irqrestore(instance->host_lock, flags); | 1416 | spin_unlock_irqrestore(shost->host_lock, flags); |
1542 | attach_failed: | 1417 | attach_failed: |
1543 | if (!instance) | 1418 | if (!shost) |
1544 | return NULL; | 1419 | return NULL; |
1545 | printf_info("%s: giving up ...\n", sym_name(np)); | 1420 | printf_info("%s: giving up ...\n", sym_name(np)); |
1546 | if (np) | 1421 | if (np) |
1547 | sym_free_resources(np, pdev); | 1422 | sym_free_resources(np, pdev); |
1548 | scsi_host_put(instance); | 1423 | scsi_host_put(shost); |
1549 | 1424 | ||
1550 | return NULL; | 1425 | return NULL; |
1551 | } | 1426 | } |
@@ -1558,7 +1433,6 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1558 | static void __devinit sym_get_nvram(struct sym_device *devp, struct sym_nvram *nvp) | 1433 | static void __devinit sym_get_nvram(struct sym_device *devp, struct sym_nvram *nvp) |
1559 | { | 1434 | { |
1560 | devp->nvram = nvp; | 1435 | devp->nvram = nvp; |
1561 | devp->device_id = devp->chip.device_id; | ||
1562 | nvp->type = 0; | 1436 | nvp->type = 0; |
1563 | 1437 | ||
1564 | sym_read_nvram(devp, nvp); | 1438 | sym_read_nvram(devp, nvp); |
@@ -1573,7 +1447,6 @@ static int __devinit sym_check_supported(struct sym_device *device) | |||
1573 | { | 1447 | { |
1574 | struct sym_chip *chip; | 1448 | struct sym_chip *chip; |
1575 | struct pci_dev *pdev = device->pdev; | 1449 | struct pci_dev *pdev = device->pdev; |
1576 | u_char revision; | ||
1577 | unsigned long io_port = pci_resource_start(pdev, 0); | 1450 | unsigned long io_port = pci_resource_start(pdev, 0); |
1578 | int i; | 1451 | int i; |
1579 | 1452 | ||
@@ -1593,14 +1466,12 @@ static int __devinit sym_check_supported(struct sym_device *device) | |||
1593 | * to our device structure so we can make it match the actual device | 1466 | * to our device structure so we can make it match the actual device |
1594 | * and options. | 1467 | * and options. |
1595 | */ | 1468 | */ |
1596 | pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); | 1469 | chip = sym_lookup_chip_table(pdev->device, pdev->revision); |
1597 | chip = sym_lookup_chip_table(pdev->device, revision); | ||
1598 | if (!chip) { | 1470 | if (!chip) { |
1599 | dev_info(&pdev->dev, "device not supported\n"); | 1471 | dev_info(&pdev->dev, "device not supported\n"); |
1600 | return -ENODEV; | 1472 | return -ENODEV; |
1601 | } | 1473 | } |
1602 | memcpy(&device->chip, chip, sizeof(device->chip)); | 1474 | memcpy(&device->chip, chip, sizeof(device->chip)); |
1603 | device->chip.revision_id = revision; | ||
1604 | 1475 | ||
1605 | return 0; | 1476 | return 0; |
1606 | } | 1477 | } |
@@ -1641,7 +1512,7 @@ static int __devinit sym_set_workarounds(struct sym_device *device) | |||
1641 | * We must ensure the chip will use WRITE AND INVALIDATE. | 1512 | * We must ensure the chip will use WRITE AND INVALIDATE. |
1642 | * The revision number limit is for now arbitrary. | 1513 | * The revision number limit is for now arbitrary. |
1643 | */ | 1514 | */ |
1644 | if (pdev->device == PCI_DEVICE_ID_NCR_53C896 && chip->revision_id < 0x4) { | 1515 | if (pdev->device == PCI_DEVICE_ID_NCR_53C896 && pdev->revision < 0x4) { |
1645 | chip->features |= (FE_WRIE | FE_CLSE); | 1516 | chip->features |= (FE_WRIE | FE_CLSE); |
1646 | } | 1517 | } |
1647 | 1518 | ||
@@ -1769,8 +1640,9 @@ static void sym_config_pqs(struct pci_dev *pdev, struct sym_device *sym_dev) | |||
1769 | * Detach the host. | 1640 | * Detach the host. |
1770 | * We have to free resources and halt the NCR chip. | 1641 | * We have to free resources and halt the NCR chip. |
1771 | */ | 1642 | */ |
1772 | static int sym_detach(struct sym_hcb *np, struct pci_dev *pdev) | 1643 | static int sym_detach(struct Scsi_Host *shost, struct pci_dev *pdev) |
1773 | { | 1644 | { |
1645 | struct sym_hcb *np = sym_get_hcb(shost); | ||
1774 | printk("%s: detaching ...\n", sym_name(np)); | 1646 | printk("%s: detaching ...\n", sym_name(np)); |
1775 | 1647 | ||
1776 | del_timer_sync(&np->s.timer); | 1648 | del_timer_sync(&np->s.timer); |
@@ -1823,7 +1695,7 @@ static int __devinit sym2_probe(struct pci_dev *pdev, | |||
1823 | { | 1695 | { |
1824 | struct sym_device sym_dev; | 1696 | struct sym_device sym_dev; |
1825 | struct sym_nvram nvram; | 1697 | struct sym_nvram nvram; |
1826 | struct Scsi_Host *instance; | 1698 | struct Scsi_Host *shost; |
1827 | 1699 | ||
1828 | memset(&sym_dev, 0, sizeof(sym_dev)); | 1700 | memset(&sym_dev, 0, sizeof(sym_dev)); |
1829 | memset(&nvram, 0, sizeof(nvram)); | 1701 | memset(&nvram, 0, sizeof(nvram)); |
@@ -1850,13 +1722,13 @@ static int __devinit sym2_probe(struct pci_dev *pdev, | |||
1850 | 1722 | ||
1851 | sym_get_nvram(&sym_dev, &nvram); | 1723 | sym_get_nvram(&sym_dev, &nvram); |
1852 | 1724 | ||
1853 | instance = sym_attach(&sym2_template, attach_count, &sym_dev); | 1725 | shost = sym_attach(&sym2_template, attach_count, &sym_dev); |
1854 | if (!instance) | 1726 | if (!shost) |
1855 | goto free; | 1727 | goto free; |
1856 | 1728 | ||
1857 | if (scsi_add_host(instance, &pdev->dev)) | 1729 | if (scsi_add_host(shost, &pdev->dev)) |
1858 | goto detach; | 1730 | goto detach; |
1859 | scsi_scan_host(instance); | 1731 | scsi_scan_host(shost); |
1860 | 1732 | ||
1861 | attach_count++; | 1733 | attach_count++; |
1862 | 1734 | ||
@@ -1874,20 +1746,143 @@ static int __devinit sym2_probe(struct pci_dev *pdev, | |||
1874 | 1746 | ||
1875 | static void __devexit sym2_remove(struct pci_dev *pdev) | 1747 | static void __devexit sym2_remove(struct pci_dev *pdev) |
1876 | { | 1748 | { |
1877 | struct sym_hcb *np = pci_get_drvdata(pdev); | 1749 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
1878 | struct Scsi_Host *host = np->s.host; | ||
1879 | |||
1880 | scsi_remove_host(host); | ||
1881 | scsi_host_put(host); | ||
1882 | |||
1883 | sym_detach(np, pdev); | ||
1884 | 1750 | ||
1751 | scsi_remove_host(shost); | ||
1752 | scsi_host_put(shost); | ||
1753 | sym_detach(shost, pdev); | ||
1885 | pci_release_regions(pdev); | 1754 | pci_release_regions(pdev); |
1886 | pci_disable_device(pdev); | 1755 | pci_disable_device(pdev); |
1887 | 1756 | ||
1888 | attach_count--; | 1757 | attach_count--; |
1889 | } | 1758 | } |
1890 | 1759 | ||
1760 | /** | ||
1761 | * sym2_io_error_detected() - called when PCI error is detected | ||
1762 | * @pdev: pointer to PCI device | ||
1763 | * @state: current state of the PCI slot | ||
1764 | */ | ||
1765 | static pci_ers_result_t sym2_io_error_detected(struct pci_dev *pdev, | ||
1766 | enum pci_channel_state state) | ||
1767 | { | ||
1768 | /* If slot is permanently frozen, turn everything off */ | ||
1769 | if (state == pci_channel_io_perm_failure) { | ||
1770 | sym2_remove(pdev); | ||
1771 | return PCI_ERS_RESULT_DISCONNECT; | ||
1772 | } | ||
1773 | |||
1774 | disable_irq(pdev->irq); | ||
1775 | pci_disable_device(pdev); | ||
1776 | |||
1777 | /* Request that MMIO be enabled, so register dump can be taken. */ | ||
1778 | return PCI_ERS_RESULT_CAN_RECOVER; | ||
1779 | } | ||
1780 | |||
1781 | /** | ||
1782 | * sym2_io_slot_dump - Enable MMIO and dump debug registers | ||
1783 | * @pdev: pointer to PCI device | ||
1784 | */ | ||
1785 | static pci_ers_result_t sym2_io_slot_dump(struct pci_dev *pdev) | ||
1786 | { | ||
1787 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | ||
1788 | |||
1789 | sym_dump_registers(shost); | ||
1790 | |||
1791 | /* Request a slot reset. */ | ||
1792 | return PCI_ERS_RESULT_NEED_RESET; | ||
1793 | } | ||
1794 | |||
1795 | /** | ||
1796 | * sym2_reset_workarounds - hardware-specific work-arounds | ||
1797 | * | ||
1798 | * This routine is similar to sym_set_workarounds(), except | ||
1799 | * that, at this point, we already know that the device was | ||
1800 | * succesfully intialized at least once before, and so most | ||
1801 | * of the steps taken there are un-needed here. | ||
1802 | */ | ||
1803 | static void sym2_reset_workarounds(struct pci_dev *pdev) | ||
1804 | { | ||
1805 | u_short status_reg; | ||
1806 | struct sym_chip *chip; | ||
1807 | |||
1808 | chip = sym_lookup_chip_table(pdev->device, pdev->revision); | ||
1809 | |||
1810 | /* Work around for errant bit in 895A, in a fashion | ||
1811 | * similar to what is done in sym_set_workarounds(). | ||
1812 | */ | ||
1813 | pci_read_config_word(pdev, PCI_STATUS, &status_reg); | ||
1814 | if (!(chip->features & FE_66MHZ) && (status_reg & PCI_STATUS_66MHZ)) { | ||
1815 | status_reg = PCI_STATUS_66MHZ; | ||
1816 | pci_write_config_word(pdev, PCI_STATUS, status_reg); | ||
1817 | pci_read_config_word(pdev, PCI_STATUS, &status_reg); | ||
1818 | } | ||
1819 | } | ||
1820 | |||
1821 | /** | ||
1822 | * sym2_io_slot_reset() - called when the pci bus has been reset. | ||
1823 | * @pdev: pointer to PCI device | ||
1824 | * | ||
1825 | * Restart the card from scratch. | ||
1826 | */ | ||
1827 | static pci_ers_result_t sym2_io_slot_reset(struct pci_dev *pdev) | ||
1828 | { | ||
1829 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | ||
1830 | struct sym_hcb *np = sym_get_hcb(shost); | ||
1831 | |||
1832 | printk(KERN_INFO "%s: recovering from a PCI slot reset\n", | ||
1833 | sym_name(np)); | ||
1834 | |||
1835 | if (pci_enable_device(pdev)) { | ||
1836 | printk(KERN_ERR "%s: Unable to enable after PCI reset\n", | ||
1837 | sym_name(np)); | ||
1838 | return PCI_ERS_RESULT_DISCONNECT; | ||
1839 | } | ||
1840 | |||
1841 | pci_set_master(pdev); | ||
1842 | enable_irq(pdev->irq); | ||
1843 | |||
1844 | /* If the chip can do Memory Write Invalidate, enable it */ | ||
1845 | if (np->features & FE_WRIE) { | ||
1846 | if (pci_set_mwi(pdev)) | ||
1847 | return PCI_ERS_RESULT_DISCONNECT; | ||
1848 | } | ||
1849 | |||
1850 | /* Perform work-arounds, analogous to sym_set_workarounds() */ | ||
1851 | sym2_reset_workarounds(pdev); | ||
1852 | |||
1853 | /* Perform host reset only on one instance of the card */ | ||
1854 | if (PCI_FUNC(pdev->devfn) == 0) { | ||
1855 | if (sym_reset_scsi_bus(np, 0)) { | ||
1856 | printk(KERN_ERR "%s: Unable to reset scsi host\n", | ||
1857 | sym_name(np)); | ||
1858 | return PCI_ERS_RESULT_DISCONNECT; | ||
1859 | } | ||
1860 | sym_start_up(shost, 1); | ||
1861 | } | ||
1862 | |||
1863 | return PCI_ERS_RESULT_RECOVERED; | ||
1864 | } | ||
1865 | |||
1866 | /** | ||
1867 | * sym2_io_resume() - resume normal ops after PCI reset | ||
1868 | * @pdev: pointer to PCI device | ||
1869 | * | ||
1870 | * Called when the error recovery driver tells us that its | ||
1871 | * OK to resume normal operation. Use completion to allow | ||
1872 | * halted scsi ops to resume. | ||
1873 | */ | ||
1874 | static void sym2_io_resume(struct pci_dev *pdev) | ||
1875 | { | ||
1876 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | ||
1877 | struct sym_data *sym_data = shost_priv(shost); | ||
1878 | |||
1879 | spin_lock_irq(shost->host_lock); | ||
1880 | if (sym_data->io_reset) | ||
1881 | complete_all(sym_data->io_reset); | ||
1882 | sym_data->io_reset = NULL; | ||
1883 | spin_unlock_irq(shost->host_lock); | ||
1884 | } | ||
1885 | |||
1891 | static void sym2_get_signalling(struct Scsi_Host *shost) | 1886 | static void sym2_get_signalling(struct Scsi_Host *shost) |
1892 | { | 1887 | { |
1893 | struct sym_hcb *np = sym_get_hcb(shost); | 1888 | struct sym_hcb *np = sym_get_hcb(shost); |
@@ -2050,11 +2045,19 @@ static struct pci_device_id sym2_id_table[] __devinitdata = { | |||
2050 | 2045 | ||
2051 | MODULE_DEVICE_TABLE(pci, sym2_id_table); | 2046 | MODULE_DEVICE_TABLE(pci, sym2_id_table); |
2052 | 2047 | ||
2048 | static struct pci_error_handlers sym2_err_handler = { | ||
2049 | .error_detected = sym2_io_error_detected, | ||
2050 | .mmio_enabled = sym2_io_slot_dump, | ||
2051 | .slot_reset = sym2_io_slot_reset, | ||
2052 | .resume = sym2_io_resume, | ||
2053 | }; | ||
2054 | |||
2053 | static struct pci_driver sym2_driver = { | 2055 | static struct pci_driver sym2_driver = { |
2054 | .name = NAME53C8XX, | 2056 | .name = NAME53C8XX, |
2055 | .id_table = sym2_id_table, | 2057 | .id_table = sym2_id_table, |
2056 | .probe = sym2_probe, | 2058 | .probe = sym2_probe, |
2057 | .remove = __devexit_p(sym2_remove), | 2059 | .remove = __devexit_p(sym2_remove), |
2060 | .err_handler = &sym2_err_handler, | ||
2058 | }; | 2061 | }; |
2059 | 2062 | ||
2060 | static int __init sym2_init(void) | 2063 | static int __init sym2_init(void) |
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h index 0f097ba4f712..567fbe0b4f09 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.h +++ b/drivers/scsi/sym53c8xx_2/sym_glue.h | |||
@@ -40,7 +40,9 @@ | |||
40 | #ifndef SYM_GLUE_H | 40 | #ifndef SYM_GLUE_H |
41 | #define SYM_GLUE_H | 41 | #define SYM_GLUE_H |
42 | 42 | ||
43 | #include <linux/completion.h> | ||
43 | #include <linux/delay.h> | 44 | #include <linux/delay.h> |
45 | #include <linux/interrupt.h> | ||
44 | #include <linux/ioport.h> | 46 | #include <linux/ioport.h> |
45 | #include <linux/pci.h> | 47 | #include <linux/pci.h> |
46 | #include <linux/string.h> | 48 | #include <linux/string.h> |
@@ -177,14 +179,11 @@ struct sym_shcb { | |||
177 | int unit; | 179 | int unit; |
178 | char inst_name[16]; | 180 | char inst_name[16]; |
179 | char chip_name[8]; | 181 | char chip_name[8]; |
180 | struct pci_dev *device; | ||
181 | 182 | ||
182 | struct Scsi_Host *host; | 183 | struct Scsi_Host *host; |
183 | 184 | ||
184 | void __iomem * ioaddr; /* MMIO kernel io address */ | 185 | void __iomem * ioaddr; /* MMIO kernel io address */ |
185 | void __iomem * ramaddr; /* RAM kernel io address */ | 186 | void __iomem * ramaddr; /* RAM kernel io address */ |
186 | u_short io_ws; /* IO window size */ | ||
187 | int irq; /* IRQ number */ | ||
188 | 187 | ||
189 | struct timer_list timer; /* Timer handler link header */ | 188 | struct timer_list timer; /* Timer handler link header */ |
190 | u_long lasttime; | 189 | u_long lasttime; |
@@ -212,20 +211,21 @@ struct sym_device { | |||
212 | } s; | 211 | } s; |
213 | struct sym_chip chip; | 212 | struct sym_chip chip; |
214 | struct sym_nvram *nvram; | 213 | struct sym_nvram *nvram; |
215 | u_short device_id; | ||
216 | u_char host_id; | 214 | u_char host_id; |
217 | }; | 215 | }; |
218 | 216 | ||
219 | /* | 217 | /* |
220 | * Driver host data structure. | 218 | * Driver host data structure. |
221 | */ | 219 | */ |
222 | struct host_data { | 220 | struct sym_data { |
223 | struct sym_hcb *ncb; | 221 | struct sym_hcb *ncb; |
222 | struct completion *io_reset; /* PCI error handling */ | ||
223 | struct pci_dev *pdev; | ||
224 | }; | 224 | }; |
225 | 225 | ||
226 | static inline struct sym_hcb * sym_get_hcb(struct Scsi_Host *host) | 226 | static inline struct sym_hcb * sym_get_hcb(struct Scsi_Host *host) |
227 | { | 227 | { |
228 | return ((struct host_data *)host->hostdata)->ncb; | 228 | return ((struct sym_data *)host->hostdata)->ncb; |
229 | } | 229 | } |
230 | 230 | ||
231 | #include "sym_fw.h" | 231 | #include "sym_fw.h" |
@@ -263,8 +263,8 @@ void sym_set_cam_result_error(struct sym_hcb *np, struct sym_ccb *cp, int resid) | |||
263 | void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *ccb); | 263 | void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *ccb); |
264 | #define sym_print_addr(cmd, arg...) dev_info(&cmd->device->sdev_gendev , ## arg) | 264 | #define sym_print_addr(cmd, arg...) dev_info(&cmd->device->sdev_gendev , ## arg) |
265 | void sym_xpt_async_bus_reset(struct sym_hcb *np); | 265 | void sym_xpt_async_bus_reset(struct sym_hcb *np); |
266 | void sym_xpt_async_sent_bdr(struct sym_hcb *np, int target); | ||
267 | int sym_setup_data_and_start (struct sym_hcb *np, struct scsi_cmnd *csio, struct sym_ccb *cp); | 266 | int sym_setup_data_and_start (struct sym_hcb *np, struct scsi_cmnd *csio, struct sym_ccb *cp); |
268 | void sym_log_bus_error(struct sym_hcb *np); | 267 | void sym_log_bus_error(struct Scsi_Host *); |
268 | void sym_dump_registers(struct Scsi_Host *); | ||
269 | 269 | ||
270 | #endif /* SYM_GLUE_H */ | 270 | #endif /* SYM_GLUE_H */ |
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c index 21cd4c7f5289..463f119f20e9 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c | |||
@@ -52,7 +52,7 @@ | |||
52 | * Needed function prototypes. | 52 | * Needed function prototypes. |
53 | */ | 53 | */ |
54 | static void sym_int_ma (struct sym_hcb *np); | 54 | static void sym_int_ma (struct sym_hcb *np); |
55 | static void sym_int_sir (struct sym_hcb *np); | 55 | static void sym_int_sir(struct sym_hcb *); |
56 | static struct sym_ccb *sym_alloc_ccb(struct sym_hcb *np); | 56 | static struct sym_ccb *sym_alloc_ccb(struct sym_hcb *np); |
57 | static struct sym_ccb *sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa); | 57 | static struct sym_ccb *sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa); |
58 | static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln); | 58 | static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln); |
@@ -684,6 +684,8 @@ static void sym_set_bus_mode(struct sym_hcb *np, struct sym_nvram *nvram) | |||
684 | */ | 684 | */ |
685 | static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram) | 685 | static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram) |
686 | { | 686 | { |
687 | struct sym_data *sym_data = shost_priv(shost); | ||
688 | struct pci_dev *pdev = sym_data->pdev; | ||
687 | u_char burst_max; | 689 | u_char burst_max; |
688 | u32 period; | 690 | u32 period; |
689 | int i; | 691 | int i; |
@@ -778,19 +780,12 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru | |||
778 | * 64 bit addressing (895A/896/1010) ? | 780 | * 64 bit addressing (895A/896/1010) ? |
779 | */ | 781 | */ |
780 | if (np->features & FE_DAC) { | 782 | if (np->features & FE_DAC) { |
781 | #if SYM_CONF_DMA_ADDRESSING_MODE == 0 | 783 | if (!use_dac(np)) |
782 | np->rv_ccntl1 |= (DDAC); | 784 | np->rv_ccntl1 |= (DDAC); |
783 | #elif SYM_CONF_DMA_ADDRESSING_MODE == 1 | 785 | else if (SYM_CONF_DMA_ADDRESSING_MODE == 1) |
784 | if (!np->use_dac) | 786 | np->rv_ccntl1 |= (XTIMOD | EXTIBMV); |
785 | np->rv_ccntl1 |= (DDAC); | 787 | else if (SYM_CONF_DMA_ADDRESSING_MODE == 2) |
786 | else | 788 | np->rv_ccntl1 |= (0 | EXTIBMV); |
787 | np->rv_ccntl1 |= (XTIMOD | EXTIBMV); | ||
788 | #elif SYM_CONF_DMA_ADDRESSING_MODE == 2 | ||
789 | if (!np->use_dac) | ||
790 | np->rv_ccntl1 |= (DDAC); | ||
791 | else | ||
792 | np->rv_ccntl1 |= (0 | EXTIBMV); | ||
793 | #endif | ||
794 | } | 789 | } |
795 | 790 | ||
796 | /* | 791 | /* |
@@ -804,8 +799,8 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru | |||
804 | * In dual channel mode, contention occurs if internal cycles | 799 | * In dual channel mode, contention occurs if internal cycles |
805 | * are used. Disable internal cycles. | 800 | * are used. Disable internal cycles. |
806 | */ | 801 | */ |
807 | if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 && | 802 | if (pdev->device == PCI_DEVICE_ID_LSI_53C1010_33 && |
808 | np->revision_id < 0x1) | 803 | pdev->revision < 0x1) |
809 | np->rv_ccntl0 |= DILS; | 804 | np->rv_ccntl0 |= DILS; |
810 | 805 | ||
811 | /* | 806 | /* |
@@ -828,10 +823,10 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru | |||
828 | * this driver. The generic ncr driver that does not use | 823 | * this driver. The generic ncr driver that does not use |
829 | * LOAD/STORE instructions does not need this work-around. | 824 | * LOAD/STORE instructions does not need this work-around. |
830 | */ | 825 | */ |
831 | if ((np->device_id == PCI_DEVICE_ID_NCR_53C810 && | 826 | if ((pdev->device == PCI_DEVICE_ID_NCR_53C810 && |
832 | np->revision_id >= 0x10 && np->revision_id <= 0x11) || | 827 | pdev->revision >= 0x10 && pdev->revision <= 0x11) || |
833 | (np->device_id == PCI_DEVICE_ID_NCR_53C860 && | 828 | (pdev->device == PCI_DEVICE_ID_NCR_53C860 && |
834 | np->revision_id <= 0x1)) | 829 | pdev->revision <= 0x1)) |
835 | np->features &= ~(FE_WRIE|FE_ERL|FE_ERMP); | 830 | np->features &= ~(FE_WRIE|FE_ERL|FE_ERMP); |
836 | 831 | ||
837 | /* | 832 | /* |
@@ -897,7 +892,7 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru | |||
897 | if ((SYM_SETUP_SCSI_LED || | 892 | if ((SYM_SETUP_SCSI_LED || |
898 | (nvram->type == SYM_SYMBIOS_NVRAM || | 893 | (nvram->type == SYM_SYMBIOS_NVRAM || |
899 | (nvram->type == SYM_TEKRAM_NVRAM && | 894 | (nvram->type == SYM_TEKRAM_NVRAM && |
900 | np->device_id == PCI_DEVICE_ID_NCR_53C895))) && | 895 | pdev->device == PCI_DEVICE_ID_NCR_53C895))) && |
901 | !(np->features & FE_LEDC) && !(np->sv_gpcntl & 0x01)) | 896 | !(np->features & FE_LEDC) && !(np->sv_gpcntl & 0x01)) |
902 | np->features |= FE_LED0; | 897 | np->features |= FE_LED0; |
903 | 898 | ||
@@ -1135,8 +1130,9 @@ restart_test: | |||
1135 | * First 24 register of the chip: | 1130 | * First 24 register of the chip: |
1136 | * r0..rf | 1131 | * r0..rf |
1137 | */ | 1132 | */ |
1138 | static void sym_log_hard_error(struct sym_hcb *np, u_short sist, u_char dstat) | 1133 | static void sym_log_hard_error(struct Scsi_Host *shost, u_short sist, u_char dstat) |
1139 | { | 1134 | { |
1135 | struct sym_hcb *np = sym_get_hcb(shost); | ||
1140 | u32 dsp; | 1136 | u32 dsp; |
1141 | int script_ofs; | 1137 | int script_ofs; |
1142 | int script_size; | 1138 | int script_size; |
@@ -1180,16 +1176,27 @@ static void sym_log_hard_error(struct sym_hcb *np, u_short sist, u_char dstat) | |||
1180 | scr_to_cpu((int) *(u32 *)(script_base + script_ofs))); | 1176 | scr_to_cpu((int) *(u32 *)(script_base + script_ofs))); |
1181 | } | 1177 | } |
1182 | 1178 | ||
1183 | printf ("%s: regdump:", sym_name(np)); | 1179 | printf("%s: regdump:", sym_name(np)); |
1184 | for (i=0; i<24;i++) | 1180 | for (i = 0; i < 24; i++) |
1185 | printf (" %02x", (unsigned)INB_OFF(np, i)); | 1181 | printf(" %02x", (unsigned)INB_OFF(np, i)); |
1186 | printf (".\n"); | 1182 | printf(".\n"); |
1187 | 1183 | ||
1188 | /* | 1184 | /* |
1189 | * PCI BUS error. | 1185 | * PCI BUS error. |
1190 | */ | 1186 | */ |
1191 | if (dstat & (MDPE|BF)) | 1187 | if (dstat & (MDPE|BF)) |
1192 | sym_log_bus_error(np); | 1188 | sym_log_bus_error(shost); |
1189 | } | ||
1190 | |||
1191 | void sym_dump_registers(struct Scsi_Host *shost) | ||
1192 | { | ||
1193 | struct sym_hcb *np = sym_get_hcb(shost); | ||
1194 | u_short sist; | ||
1195 | u_char dstat; | ||
1196 | |||
1197 | sist = INW(np, nc_sist); | ||
1198 | dstat = INB(np, nc_dstat); | ||
1199 | sym_log_hard_error(shost, sist, dstat); | ||
1193 | } | 1200 | } |
1194 | 1201 | ||
1195 | static struct sym_chip sym_dev_table[] = { | 1202 | static struct sym_chip sym_dev_table[] = { |
@@ -1312,7 +1319,7 @@ int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s) | |||
1312 | { | 1319 | { |
1313 | int i; | 1320 | int i; |
1314 | 1321 | ||
1315 | if (!np->use_dac) | 1322 | if (!use_dac(np)) |
1316 | goto weird; | 1323 | goto weird; |
1317 | 1324 | ||
1318 | /* Look up existing mappings */ | 1325 | /* Look up existing mappings */ |
@@ -1519,7 +1526,8 @@ void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp) | |||
1519 | np->squeueput = qidx; | 1526 | np->squeueput = qidx; |
1520 | 1527 | ||
1521 | if (DEBUG_FLAGS & DEBUG_QUEUE) | 1528 | if (DEBUG_FLAGS & DEBUG_QUEUE) |
1522 | printf ("%s: queuepos=%d.\n", sym_name (np), np->squeueput); | 1529 | scmd_printk(KERN_DEBUG, cp->cmd, "queuepos=%d\n", |
1530 | np->squeueput); | ||
1523 | 1531 | ||
1524 | /* | 1532 | /* |
1525 | * Script processor may be waiting for reselect. | 1533 | * Script processor may be waiting for reselect. |
@@ -1696,8 +1704,11 @@ static void sym_flush_busy_queue (struct sym_hcb *np, int cam_status) | |||
1696 | * 1: SCSI BUS RESET delivered or received. | 1704 | * 1: SCSI BUS RESET delivered or received. |
1697 | * 2: SCSI BUS MODE changed. | 1705 | * 2: SCSI BUS MODE changed. |
1698 | */ | 1706 | */ |
1699 | void sym_start_up (struct sym_hcb *np, int reason) | 1707 | void sym_start_up(struct Scsi_Host *shost, int reason) |
1700 | { | 1708 | { |
1709 | struct sym_data *sym_data = shost_priv(shost); | ||
1710 | struct pci_dev *pdev = sym_data->pdev; | ||
1711 | struct sym_hcb *np = sym_data->ncb; | ||
1701 | int i; | 1712 | int i; |
1702 | u32 phys; | 1713 | u32 phys; |
1703 | 1714 | ||
@@ -1746,7 +1757,7 @@ void sym_start_up (struct sym_hcb *np, int reason) | |||
1746 | * This also let point to first position the start | 1757 | * This also let point to first position the start |
1747 | * and done queue pointers used from SCRIPTS. | 1758 | * and done queue pointers used from SCRIPTS. |
1748 | */ | 1759 | */ |
1749 | np->fw_patch(np); | 1760 | np->fw_patch(shost); |
1750 | 1761 | ||
1751 | /* | 1762 | /* |
1752 | * Wakeup all pending jobs. | 1763 | * Wakeup all pending jobs. |
@@ -1788,7 +1799,7 @@ void sym_start_up (struct sym_hcb *np, int reason) | |||
1788 | /* | 1799 | /* |
1789 | * For now, disable AIP generation on C1010-66. | 1800 | * For now, disable AIP generation on C1010-66. |
1790 | */ | 1801 | */ |
1791 | if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66) | 1802 | if (pdev->device == PCI_DEVICE_ID_LSI_53C1010_66) |
1792 | OUTB(np, nc_aipcntl1, DISAIP); | 1803 | OUTB(np, nc_aipcntl1, DISAIP); |
1793 | 1804 | ||
1794 | /* | 1805 | /* |
@@ -1798,8 +1809,8 @@ void sym_start_up (struct sym_hcb *np, int reason) | |||
1798 | * that from SCRIPTS for each selection/reselection, but | 1809 | * that from SCRIPTS for each selection/reselection, but |
1799 | * I just don't want. :) | 1810 | * I just don't want. :) |
1800 | */ | 1811 | */ |
1801 | if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 && | 1812 | if (pdev->device == PCI_DEVICE_ID_LSI_53C1010_33 && |
1802 | np->revision_id < 1) | 1813 | pdev->revision < 1) |
1803 | OUTB(np, nc_stest1, INB(np, nc_stest1) | 0x30); | 1814 | OUTB(np, nc_stest1, INB(np, nc_stest1) | 0x30); |
1804 | 1815 | ||
1805 | /* | 1816 | /* |
@@ -1807,9 +1818,9 @@ void sym_start_up (struct sym_hcb *np, int reason) | |||
1807 | * Disable overlapped arbitration for some dual function devices, | 1818 | * Disable overlapped arbitration for some dual function devices, |
1808 | * regardless revision id (kind of post-chip-design feature. ;-)) | 1819 | * regardless revision id (kind of post-chip-design feature. ;-)) |
1809 | */ | 1820 | */ |
1810 | if (np->device_id == PCI_DEVICE_ID_NCR_53C875) | 1821 | if (pdev->device == PCI_DEVICE_ID_NCR_53C875) |
1811 | OUTB(np, nc_ctest0, (1<<5)); | 1822 | OUTB(np, nc_ctest0, (1<<5)); |
1812 | else if (np->device_id == PCI_DEVICE_ID_NCR_53C896) | 1823 | else if (pdev->device == PCI_DEVICE_ID_NCR_53C896) |
1813 | np->rv_ccntl0 |= DPR; | 1824 | np->rv_ccntl0 |= DPR; |
1814 | 1825 | ||
1815 | /* | 1826 | /* |
@@ -1827,7 +1838,7 @@ void sym_start_up (struct sym_hcb *np, int reason) | |||
1827 | * Set up scratch C and DRS IO registers to map the 32 bit | 1838 | * Set up scratch C and DRS IO registers to map the 32 bit |
1828 | * DMA address range our data structures are located in. | 1839 | * DMA address range our data structures are located in. |
1829 | */ | 1840 | */ |
1830 | if (np->use_dac) { | 1841 | if (use_dac(np)) { |
1831 | np->dmap_bah[0] = 0; /* ??? */ | 1842 | np->dmap_bah[0] = 0; /* ??? */ |
1832 | OUTL(np, nc_scrx[0], np->dmap_bah[0]); | 1843 | OUTL(np, nc_scrx[0], np->dmap_bah[0]); |
1833 | OUTL(np, nc_drs, np->dmap_bah[0]); | 1844 | OUTL(np, nc_drs, np->dmap_bah[0]); |
@@ -1900,7 +1911,7 @@ void sym_start_up (struct sym_hcb *np, int reason) | |||
1900 | if (sym_verbose >= 2) | 1911 | if (sym_verbose >= 2) |
1901 | printf("%s: Downloading SCSI SCRIPTS.\n", sym_name(np)); | 1912 | printf("%s: Downloading SCSI SCRIPTS.\n", sym_name(np)); |
1902 | memcpy_toio(np->s.ramaddr, np->scripta0, np->scripta_sz); | 1913 | memcpy_toio(np->s.ramaddr, np->scripta0, np->scripta_sz); |
1903 | if (np->ram_ws == 8192) { | 1914 | if (np->features & FE_RAM8K) { |
1904 | memcpy_toio(np->s.ramaddr + 4096, np->scriptb0, np->scriptb_sz); | 1915 | memcpy_toio(np->s.ramaddr + 4096, np->scriptb0, np->scriptb_sz); |
1905 | phys = scr_to_cpu(np->scr_ram_seg); | 1916 | phys = scr_to_cpu(np->scr_ram_seg); |
1906 | OUTL(np, nc_mmws, phys); | 1917 | OUTL(np, nc_mmws, phys); |
@@ -2214,8 +2225,9 @@ static void sym_int_udc (struct sym_hcb *np) | |||
2214 | * mode to eight bit asynchronous, etc... | 2225 | * mode to eight bit asynchronous, etc... |
2215 | * So, just reinitializing all except chip should be enough. | 2226 | * So, just reinitializing all except chip should be enough. |
2216 | */ | 2227 | */ |
2217 | static void sym_int_sbmc (struct sym_hcb *np) | 2228 | static void sym_int_sbmc(struct Scsi_Host *shost) |
2218 | { | 2229 | { |
2230 | struct sym_hcb *np = sym_get_hcb(shost); | ||
2219 | u_char scsi_mode = INB(np, nc_stest4) & SMODE; | 2231 | u_char scsi_mode = INB(np, nc_stest4) & SMODE; |
2220 | 2232 | ||
2221 | /* | 2233 | /* |
@@ -2228,7 +2240,7 @@ static void sym_int_sbmc (struct sym_hcb *np) | |||
2228 | * Should suspend command processing for a few seconds and | 2240 | * Should suspend command processing for a few seconds and |
2229 | * reinitialize all except the chip. | 2241 | * reinitialize all except the chip. |
2230 | */ | 2242 | */ |
2231 | sym_start_up (np, 2); | 2243 | sym_start_up(shost, 2); |
2232 | } | 2244 | } |
2233 | 2245 | ||
2234 | /* | 2246 | /* |
@@ -2756,8 +2768,11 @@ reset_all: | |||
2756 | * Use at your own decision and risk. | 2768 | * Use at your own decision and risk. |
2757 | */ | 2769 | */ |
2758 | 2770 | ||
2759 | void sym_interrupt (struct sym_hcb *np) | 2771 | irqreturn_t sym_interrupt(struct Scsi_Host *shost) |
2760 | { | 2772 | { |
2773 | struct sym_data *sym_data = shost_priv(shost); | ||
2774 | struct sym_hcb *np = sym_data->ncb; | ||
2775 | struct pci_dev *pdev = sym_data->pdev; | ||
2761 | u_char istat, istatc; | 2776 | u_char istat, istatc; |
2762 | u_char dstat; | 2777 | u_char dstat; |
2763 | u_short sist; | 2778 | u_short sist; |
@@ -2782,7 +2797,7 @@ void sym_interrupt (struct sym_hcb *np) | |||
2782 | } | 2797 | } |
2783 | 2798 | ||
2784 | if (!(istat & (SIP|DIP))) | 2799 | if (!(istat & (SIP|DIP))) |
2785 | return; | 2800 | return (istat & INTF) ? IRQ_HANDLED : IRQ_NONE; |
2786 | 2801 | ||
2787 | #if 0 /* We should never get this one */ | 2802 | #if 0 /* We should never get this one */ |
2788 | if (istat & CABRT) | 2803 | if (istat & CABRT) |
@@ -2809,6 +2824,13 @@ void sym_interrupt (struct sym_hcb *np) | |||
2809 | dstat |= INB(np, nc_dstat); | 2824 | dstat |= INB(np, nc_dstat); |
2810 | istatc = INB(np, nc_istat); | 2825 | istatc = INB(np, nc_istat); |
2811 | istat |= istatc; | 2826 | istat |= istatc; |
2827 | |||
2828 | /* Prevent deadlock waiting on a condition that may | ||
2829 | * never clear. */ | ||
2830 | if (unlikely(sist == 0xffff && dstat == 0xff)) { | ||
2831 | if (pci_channel_offline(pdev)) | ||
2832 | return IRQ_NONE; | ||
2833 | } | ||
2812 | } while (istatc & (SIP|DIP)); | 2834 | } while (istatc & (SIP|DIP)); |
2813 | 2835 | ||
2814 | if (DEBUG_FLAGS & DEBUG_TINY) | 2836 | if (DEBUG_FLAGS & DEBUG_TINY) |
@@ -2842,10 +2864,10 @@ void sym_interrupt (struct sym_hcb *np) | |||
2842 | !(dstat & (MDPE|BF|ABRT|IID))) { | 2864 | !(dstat & (MDPE|BF|ABRT|IID))) { |
2843 | if (sist & PAR) sym_int_par (np, sist); | 2865 | if (sist & PAR) sym_int_par (np, sist); |
2844 | else if (sist & MA) sym_int_ma (np); | 2866 | else if (sist & MA) sym_int_ma (np); |
2845 | else if (dstat & SIR) sym_int_sir (np); | 2867 | else if (dstat & SIR) sym_int_sir(np); |
2846 | else if (dstat & SSI) OUTONB_STD(); | 2868 | else if (dstat & SSI) OUTONB_STD(); |
2847 | else goto unknown_int; | 2869 | else goto unknown_int; |
2848 | return; | 2870 | return IRQ_HANDLED; |
2849 | } | 2871 | } |
2850 | 2872 | ||
2851 | /* | 2873 | /* |
@@ -2861,8 +2883,8 @@ void sym_interrupt (struct sym_hcb *np) | |||
2861 | */ | 2883 | */ |
2862 | if (sist & RST) { | 2884 | if (sist & RST) { |
2863 | printf("%s: SCSI BUS reset detected.\n", sym_name(np)); | 2885 | printf("%s: SCSI BUS reset detected.\n", sym_name(np)); |
2864 | sym_start_up (np, 1); | 2886 | sym_start_up(shost, 1); |
2865 | return; | 2887 | return IRQ_HANDLED; |
2866 | } | 2888 | } |
2867 | 2889 | ||
2868 | OUTB(np, nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */ | 2890 | OUTB(np, nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */ |
@@ -2870,11 +2892,11 @@ void sym_interrupt (struct sym_hcb *np) | |||
2870 | 2892 | ||
2871 | if (!(sist & (GEN|HTH|SGE)) && | 2893 | if (!(sist & (GEN|HTH|SGE)) && |
2872 | !(dstat & (MDPE|BF|ABRT|IID))) { | 2894 | !(dstat & (MDPE|BF|ABRT|IID))) { |
2873 | if (sist & SBMC) sym_int_sbmc (np); | 2895 | if (sist & SBMC) sym_int_sbmc(shost); |
2874 | else if (sist & STO) sym_int_sto (np); | 2896 | else if (sist & STO) sym_int_sto (np); |
2875 | else if (sist & UDC) sym_int_udc (np); | 2897 | else if (sist & UDC) sym_int_udc (np); |
2876 | else goto unknown_int; | 2898 | else goto unknown_int; |
2877 | return; | 2899 | return IRQ_HANDLED; |
2878 | } | 2900 | } |
2879 | 2901 | ||
2880 | /* | 2902 | /* |
@@ -2884,12 +2906,12 @@ void sym_interrupt (struct sym_hcb *np) | |||
2884 | * Reset everything. | 2906 | * Reset everything. |
2885 | */ | 2907 | */ |
2886 | 2908 | ||
2887 | sym_log_hard_error(np, sist, dstat); | 2909 | sym_log_hard_error(shost, sist, dstat); |
2888 | 2910 | ||
2889 | if ((sist & (GEN|HTH|SGE)) || | 2911 | if ((sist & (GEN|HTH|SGE)) || |
2890 | (dstat & (MDPE|BF|ABRT|IID))) { | 2912 | (dstat & (MDPE|BF|ABRT|IID))) { |
2891 | sym_start_reset(np); | 2913 | sym_start_reset(np); |
2892 | return; | 2914 | return IRQ_HANDLED; |
2893 | } | 2915 | } |
2894 | 2916 | ||
2895 | unknown_int: | 2917 | unknown_int: |
@@ -2900,6 +2922,7 @@ unknown_int: | |||
2900 | printf( "%s: unknown interrupt(s) ignored, " | 2922 | printf( "%s: unknown interrupt(s) ignored, " |
2901 | "ISTAT=0x%x DSTAT=0x%x SIST=0x%x\n", | 2923 | "ISTAT=0x%x DSTAT=0x%x SIST=0x%x\n", |
2902 | sym_name(np), istat, dstat, sist); | 2924 | sym_name(np), istat, dstat, sist); |
2925 | return IRQ_NONE; | ||
2903 | } | 2926 | } |
2904 | 2927 | ||
2905 | /* | 2928 | /* |
@@ -3520,7 +3543,8 @@ static void sym_sir_task_recovery(struct sym_hcb *np, int num) | |||
3520 | * If we sent a BDR, make upper layer aware of that. | 3543 | * If we sent a BDR, make upper layer aware of that. |
3521 | */ | 3544 | */ |
3522 | if (np->abrt_msg[0] == M_RESET) | 3545 | if (np->abrt_msg[0] == M_RESET) |
3523 | sym_xpt_async_sent_bdr(np, target); | 3546 | starget_printk(KERN_NOTICE, starget, |
3547 | "has been reset\n"); | ||
3524 | break; | 3548 | break; |
3525 | } | 3549 | } |
3526 | 3550 | ||
@@ -4304,7 +4328,7 @@ static void sym_nego_rejected(struct sym_hcb *np, struct sym_tcb *tp, struct sym | |||
4304 | /* | 4328 | /* |
4305 | * chip exception handler for programmed interrupts. | 4329 | * chip exception handler for programmed interrupts. |
4306 | */ | 4330 | */ |
4307 | static void sym_int_sir (struct sym_hcb *np) | 4331 | static void sym_int_sir(struct sym_hcb *np) |
4308 | { | 4332 | { |
4309 | u_char num = INB(np, nc_dsps); | 4333 | u_char num = INB(np, nc_dsps); |
4310 | u32 dsa = INL(np, nc_dsa); | 4334 | u32 dsa = INL(np, nc_dsa); |
@@ -4343,31 +4367,30 @@ static void sym_int_sir (struct sym_hcb *np) | |||
4343 | return; | 4367 | return; |
4344 | /* | 4368 | /* |
4345 | * The device didn't go to MSG OUT phase after having | 4369 | * The device didn't go to MSG OUT phase after having |
4346 | * been selected with ATN. We donnot want to handle | 4370 | * been selected with ATN. We do not want to handle that. |
4347 | * that. | ||
4348 | */ | 4371 | */ |
4349 | case SIR_SEL_ATN_NO_MSG_OUT: | 4372 | case SIR_SEL_ATN_NO_MSG_OUT: |
4350 | printf ("%s:%d: No MSG OUT phase after selection with ATN.\n", | 4373 | scmd_printk(KERN_WARNING, cp->cmd, |
4351 | sym_name (np), target); | 4374 | "No MSG OUT phase after selection with ATN\n"); |
4352 | goto out_stuck; | 4375 | goto out_stuck; |
4353 | /* | 4376 | /* |
4354 | * The device didn't switch to MSG IN phase after | 4377 | * The device didn't switch to MSG IN phase after |
4355 | * having reseleted the initiator. | 4378 | * having reselected the initiator. |
4356 | */ | 4379 | */ |
4357 | case SIR_RESEL_NO_MSG_IN: | 4380 | case SIR_RESEL_NO_MSG_IN: |
4358 | printf ("%s:%d: No MSG IN phase after reselection.\n", | 4381 | scmd_printk(KERN_WARNING, cp->cmd, |
4359 | sym_name (np), target); | 4382 | "No MSG IN phase after reselection\n"); |
4360 | goto out_stuck; | 4383 | goto out_stuck; |
4361 | /* | 4384 | /* |
4362 | * After reselection, the device sent a message that wasn't | 4385 | * After reselection, the device sent a message that wasn't |
4363 | * an IDENTIFY. | 4386 | * an IDENTIFY. |
4364 | */ | 4387 | */ |
4365 | case SIR_RESEL_NO_IDENTIFY: | 4388 | case SIR_RESEL_NO_IDENTIFY: |
4366 | printf ("%s:%d: No IDENTIFY after reselection.\n", | 4389 | scmd_printk(KERN_WARNING, cp->cmd, |
4367 | sym_name (np), target); | 4390 | "No IDENTIFY after reselection\n"); |
4368 | goto out_stuck; | 4391 | goto out_stuck; |
4369 | /* | 4392 | /* |
4370 | * The device reselected a LUN we donnot know about. | 4393 | * The device reselected a LUN we do not know about. |
4371 | */ | 4394 | */ |
4372 | case SIR_RESEL_BAD_LUN: | 4395 | case SIR_RESEL_BAD_LUN: |
4373 | np->msgout[0] = M_RESET; | 4396 | np->msgout[0] = M_RESET; |
@@ -4380,8 +4403,7 @@ static void sym_int_sir (struct sym_hcb *np) | |||
4380 | np->msgout[0] = M_ABORT; | 4403 | np->msgout[0] = M_ABORT; |
4381 | goto out; | 4404 | goto out; |
4382 | /* | 4405 | /* |
4383 | * The device reselected for a tagged nexus that we donnot | 4406 | * The device reselected for a tagged nexus that we do not have. |
4384 | * have. | ||
4385 | */ | 4407 | */ |
4386 | case SIR_RESEL_BAD_I_T_L_Q: | 4408 | case SIR_RESEL_BAD_I_T_L_Q: |
4387 | np->msgout[0] = M_ABORT_TAG; | 4409 | np->msgout[0] = M_ABORT_TAG; |
@@ -4393,8 +4415,8 @@ static void sym_int_sir (struct sym_hcb *np) | |||
4393 | case SIR_RESEL_ABORTED: | 4415 | case SIR_RESEL_ABORTED: |
4394 | np->lastmsg = np->msgout[0]; | 4416 | np->lastmsg = np->msgout[0]; |
4395 | np->msgout[0] = M_NOOP; | 4417 | np->msgout[0] = M_NOOP; |
4396 | printf ("%s:%d: message %x sent on bad reselection.\n", | 4418 | scmd_printk(KERN_WARNING, cp->cmd, |
4397 | sym_name (np), target, np->lastmsg); | 4419 | "message %x sent on bad reselection\n", np->lastmsg); |
4398 | goto out; | 4420 | goto out; |
4399 | /* | 4421 | /* |
4400 | * The SCRIPTS let us know that a message has been | 4422 | * The SCRIPTS let us know that a message has been |
@@ -5578,16 +5600,13 @@ int sym_hcb_attach(struct Scsi_Host *shost, struct sym_fw *fw, struct sym_nvram | |||
5578 | np->scriptz_ba = vtobus(np->scriptz0); | 5600 | np->scriptz_ba = vtobus(np->scriptz0); |
5579 | 5601 | ||
5580 | if (np->ram_ba) { | 5602 | if (np->ram_ba) { |
5581 | np->scripta_ba = np->ram_ba; | 5603 | np->scripta_ba = np->ram_ba; |
5582 | if (np->features & FE_RAM8K) { | 5604 | if (np->features & FE_RAM8K) { |
5583 | np->ram_ws = 8192; | ||
5584 | np->scriptb_ba = np->scripta_ba + 4096; | 5605 | np->scriptb_ba = np->scripta_ba + 4096; |
5585 | #if 0 /* May get useful for 64 BIT PCI addressing */ | 5606 | #if 0 /* May get useful for 64 BIT PCI addressing */ |
5586 | np->scr_ram_seg = cpu_to_scr(np->scripta_ba >> 32); | 5607 | np->scr_ram_seg = cpu_to_scr(np->scripta_ba >> 32); |
5587 | #endif | 5608 | #endif |
5588 | } | 5609 | } |
5589 | else | ||
5590 | np->ram_ws = 4096; | ||
5591 | } | 5610 | } |
5592 | 5611 | ||
5593 | /* | 5612 | /* |
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h index 79ab6a177039..ad078805e62b 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.h +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h | |||
@@ -883,10 +883,7 @@ struct sym_hcb { | |||
883 | * Physical bus addresses of the chip. | 883 | * Physical bus addresses of the chip. |
884 | */ | 884 | */ |
885 | u32 mmio_ba; /* MMIO 32 bit BUS address */ | 885 | u32 mmio_ba; /* MMIO 32 bit BUS address */ |
886 | int mmio_ws; /* MMIO Window size */ | ||
887 | |||
888 | u32 ram_ba; /* RAM 32 bit BUS address */ | 886 | u32 ram_ba; /* RAM 32 bit BUS address */ |
889 | int ram_ws; /* RAM window size */ | ||
890 | 887 | ||
891 | /* | 888 | /* |
892 | * SCRIPTS virtual and physical bus addresses. | 889 | * SCRIPTS virtual and physical bus addresses. |
@@ -912,14 +909,12 @@ struct sym_hcb { | |||
912 | struct sym_fwb_ba fwb_bas; /* Useful SCRIPTB bus addresses */ | 909 | struct sym_fwb_ba fwb_bas; /* Useful SCRIPTB bus addresses */ |
913 | struct sym_fwz_ba fwz_bas; /* Useful SCRIPTZ bus addresses */ | 910 | struct sym_fwz_ba fwz_bas; /* Useful SCRIPTZ bus addresses */ |
914 | void (*fw_setup)(struct sym_hcb *np, struct sym_fw *fw); | 911 | void (*fw_setup)(struct sym_hcb *np, struct sym_fw *fw); |
915 | void (*fw_patch)(struct sym_hcb *np); | 912 | void (*fw_patch)(struct Scsi_Host *); |
916 | char *fw_name; | 913 | char *fw_name; |
917 | 914 | ||
918 | /* | 915 | /* |
919 | * General controller parameters and configuration. | 916 | * General controller parameters and configuration. |
920 | */ | 917 | */ |
921 | u_short device_id; /* PCI device id */ | ||
922 | u_char revision_id; /* PCI device revision id */ | ||
923 | u_int features; /* Chip features map */ | 918 | u_int features; /* Chip features map */ |
924 | u_char myaddr; /* SCSI id of the adapter */ | 919 | u_char myaddr; /* SCSI id of the adapter */ |
925 | u_char maxburst; /* log base 2 of dwords burst */ | 920 | u_char maxburst; /* log base 2 of dwords burst */ |
@@ -1031,6 +1026,14 @@ struct sym_hcb { | |||
1031 | #endif | 1026 | #endif |
1032 | }; | 1027 | }; |
1033 | 1028 | ||
1029 | #if SYM_CONF_DMA_ADDRESSING_MODE == 0 | ||
1030 | #define use_dac(np) 0 | ||
1031 | #define set_dac(np) do { } while (0) | ||
1032 | #else | ||
1033 | #define use_dac(np) (np)->use_dac | ||
1034 | #define set_dac(np) (np)->use_dac = 1 | ||
1035 | #endif | ||
1036 | |||
1034 | #define HCB_BA(np, lbl) (np->hcb_ba + offsetof(struct sym_hcb, lbl)) | 1037 | #define HCB_BA(np, lbl) (np->hcb_ba + offsetof(struct sym_hcb, lbl)) |
1035 | 1038 | ||
1036 | 1039 | ||
@@ -1052,8 +1055,8 @@ void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn); | |||
1052 | #else | 1055 | #else |
1053 | void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp); | 1056 | void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp); |
1054 | #endif | 1057 | #endif |
1055 | void sym_start_up(struct sym_hcb *np, int reason); | 1058 | void sym_start_up(struct Scsi_Host *, int reason); |
1056 | void sym_interrupt(struct sym_hcb *np); | 1059 | irqreturn_t sym_interrupt(struct Scsi_Host *); |
1057 | int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task); | 1060 | int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task); |
1058 | struct sym_ccb *sym_get_ccb(struct sym_hcb *np, struct scsi_cmnd *cmd, u_char tag_order); | 1061 | struct sym_ccb *sym_get_ccb(struct sym_hcb *np, struct scsi_cmnd *cmd, u_char tag_order); |
1059 | void sym_free_ccb(struct sym_hcb *np, struct sym_ccb *cp); | 1062 | void sym_free_ccb(struct sym_hcb *np, struct sym_ccb *cp); |
@@ -1073,18 +1076,21 @@ int sym_hcb_attach(struct Scsi_Host *shost, struct sym_fw *fw, struct sym_nvram | |||
1073 | */ | 1076 | */ |
1074 | 1077 | ||
1075 | #if SYM_CONF_DMA_ADDRESSING_MODE == 0 | 1078 | #if SYM_CONF_DMA_ADDRESSING_MODE == 0 |
1079 | #define DMA_DAC_MASK DMA_32BIT_MASK | ||
1076 | #define sym_build_sge(np, data, badd, len) \ | 1080 | #define sym_build_sge(np, data, badd, len) \ |
1077 | do { \ | 1081 | do { \ |
1078 | (data)->addr = cpu_to_scr(badd); \ | 1082 | (data)->addr = cpu_to_scr(badd); \ |
1079 | (data)->size = cpu_to_scr(len); \ | 1083 | (data)->size = cpu_to_scr(len); \ |
1080 | } while (0) | 1084 | } while (0) |
1081 | #elif SYM_CONF_DMA_ADDRESSING_MODE == 1 | 1085 | #elif SYM_CONF_DMA_ADDRESSING_MODE == 1 |
1086 | #define DMA_DAC_MASK DMA_40BIT_MASK | ||
1082 | #define sym_build_sge(np, data, badd, len) \ | 1087 | #define sym_build_sge(np, data, badd, len) \ |
1083 | do { \ | 1088 | do { \ |
1084 | (data)->addr = cpu_to_scr(badd); \ | 1089 | (data)->addr = cpu_to_scr(badd); \ |
1085 | (data)->size = cpu_to_scr((((badd) >> 8) & 0xff000000) + len); \ | 1090 | (data)->size = cpu_to_scr((((badd) >> 8) & 0xff000000) + len); \ |
1086 | } while (0) | 1091 | } while (0) |
1087 | #elif SYM_CONF_DMA_ADDRESSING_MODE == 2 | 1092 | #elif SYM_CONF_DMA_ADDRESSING_MODE == 2 |
1093 | #define DMA_DAC_MASK DMA_64BIT_MASK | ||
1088 | int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s); | 1094 | int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s); |
1089 | static __inline void | 1095 | static __inline void |
1090 | sym_build_sge(struct sym_hcb *np, struct sym_tblmove *data, u64 badd, int len) | 1096 | sym_build_sge(struct sym_hcb *np, struct sym_tblmove *data, u64 badd, int len) |
diff --git a/drivers/scsi/sym53c8xx_2/sym_nvram.c b/drivers/scsi/sym53c8xx_2/sym_nvram.c index 15d69298ab6e..5662fbb3ff60 100644 --- a/drivers/scsi/sym53c8xx_2/sym_nvram.c +++ b/drivers/scsi/sym53c8xx_2/sym_nvram.c | |||
@@ -696,7 +696,7 @@ static int sym_read_Tekram_nvram (struct sym_device *np, Tekram_nvram *nvram) | |||
696 | u_short csum; | 696 | u_short csum; |
697 | int x; | 697 | int x; |
698 | 698 | ||
699 | switch (np->device_id) { | 699 | switch (np->pdev->device) { |
700 | case PCI_DEVICE_ID_NCR_53C885: | 700 | case PCI_DEVICE_ID_NCR_53C885: |
701 | case PCI_DEVICE_ID_NCR_53C895: | 701 | case PCI_DEVICE_ID_NCR_53C895: |
702 | case PCI_DEVICE_ID_NCR_53C896: | 702 | case PCI_DEVICE_ID_NCR_53C896: |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 37bddc1802de..81db48f07ca1 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -343,11 +343,12 @@ config IBMASR | |||
343 | module will be called ibmasr. | 343 | module will be called ibmasr. |
344 | 344 | ||
345 | config WAFER_WDT | 345 | config WAFER_WDT |
346 | tristate "ICP Wafer 5823 Single Board Computer Watchdog" | 346 | tristate "ICP Single Board Computer Watchdog Timer" |
347 | depends on X86 | 347 | depends on X86 |
348 | help | 348 | help |
349 | This is a driver for the hardware watchdog on the ICP Wafer 5823 | 349 | This is a driver for the hardware watchdog on the ICP Single |
350 | Single Board Computer (and probably other similar models). | 350 | Board Computer. This driver is working on (at least) the following |
351 | IPC SBC's: Wafer 5823, Rocky 4783, Rocky 3703 and Rocky 3782. | ||
351 | 352 | ||
352 | To compile this driver as a module, choose M here: the | 353 | To compile this driver as a module, choose M here: the |
353 | module will be called wafer5823wdt. | 354 | module will be called wafer5823wdt. |
@@ -609,6 +610,12 @@ config WDT_RM9K_GPI | |||
609 | To compile this driver as a module, choose M here: the | 610 | To compile this driver as a module, choose M here: the |
610 | module will be called rm9k_wdt. | 611 | module will be called rm9k_wdt. |
611 | 612 | ||
613 | config AR7_WDT | ||
614 | tristate "TI AR7 Watchdog Timer" | ||
615 | depends on AR7 | ||
616 | help | ||
617 | Hardware driver for the TI AR7 Watchdog Timer. | ||
618 | |||
612 | # PARISC Architecture | 619 | # PARISC Architecture |
613 | 620 | ||
614 | # POWERPC Architecture | 621 | # POWERPC Architecture |
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 389f8b14ccc4..7d9e5734f8bb 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile | |||
@@ -90,6 +90,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o | |||
90 | obj-$(CONFIG_INDYDOG) += indydog.o | 90 | obj-$(CONFIG_INDYDOG) += indydog.o |
91 | obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o | 91 | obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o |
92 | obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o | 92 | obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o |
93 | obj-$(CONFIG_AR7_WDT) += ar7_wdt.o | ||
93 | 94 | ||
94 | # PARISC Architecture | 95 | # PARISC Architecture |
95 | 96 | ||
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c new file mode 100644 index 000000000000..cdaab8c3d3d0 --- /dev/null +++ b/drivers/watchdog/ar7_wdt.c | |||
@@ -0,0 +1,349 @@ | |||
1 | /* | ||
2 | * drivers/watchdog/ar7_wdt.c | ||
3 | * | ||
4 | * Copyright (C) 2007 Nicolas Thill <nico@openwrt.org> | ||
5 | * Copyright (c) 2005 Enrik Berkhan <Enrik.Berkhan@akk.org> | ||
6 | * | ||
7 | * Some code taken from: | ||
8 | * National Semiconductor SCx200 Watchdog support | ||
9 | * Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
24 | */ | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/moduleparam.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/miscdevice.h> | ||
31 | #include <linux/watchdog.h> | ||
32 | #include <linux/notifier.h> | ||
33 | #include <linux/reboot.h> | ||
34 | #include <linux/fs.h> | ||
35 | #include <linux/ioport.h> | ||
36 | #include <linux/io.h> | ||
37 | #include <linux/uaccess.h> | ||
38 | |||
39 | #include <asm/addrspace.h> | ||
40 | #include <asm/ar7/ar7.h> | ||
41 | |||
42 | #define DRVNAME "ar7_wdt" | ||
43 | #define LONGNAME "TI AR7 Watchdog Timer" | ||
44 | |||
45 | MODULE_AUTHOR("Nicolas Thill <nico@openwrt.org>"); | ||
46 | MODULE_DESCRIPTION(LONGNAME); | ||
47 | MODULE_LICENSE("GPL"); | ||
48 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
49 | |||
50 | static int margin = 60; | ||
51 | module_param(margin, int, 0); | ||
52 | MODULE_PARM_DESC(margin, "Watchdog margin in seconds"); | ||
53 | |||
54 | static int nowayout = WATCHDOG_NOWAYOUT; | ||
55 | module_param(nowayout, int, 0); | ||
56 | MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); | ||
57 | |||
58 | #define READ_REG(x) readl((void __iomem *)&(x)) | ||
59 | #define WRITE_REG(x, v) writel((v), (void __iomem *)&(x)) | ||
60 | |||
61 | struct ar7_wdt { | ||
62 | u32 kick_lock; | ||
63 | u32 kick; | ||
64 | u32 change_lock; | ||
65 | u32 change; | ||
66 | u32 disable_lock; | ||
67 | u32 disable; | ||
68 | u32 prescale_lock; | ||
69 | u32 prescale; | ||
70 | }; | ||
71 | |||
72 | static struct semaphore open_semaphore; | ||
73 | static unsigned expect_close; | ||
74 | |||
75 | /* XXX currently fixed, allows max margin ~68.72 secs */ | ||
76 | #define prescale_value 0xffff | ||
77 | |||
78 | /* Offset of the WDT registers */ | ||
79 | static unsigned long ar7_regs_wdt; | ||
80 | /* Pointer to the remapped WDT IO space */ | ||
81 | static struct ar7_wdt *ar7_wdt; | ||
82 | static void ar7_wdt_get_regs(void) | ||
83 | { | ||
84 | u16 chip_id = ar7_chip_id(); | ||
85 | switch (chip_id) { | ||
86 | case AR7_CHIP_7100: | ||
87 | case AR7_CHIP_7200: | ||
88 | ar7_regs_wdt = AR7_REGS_WDT; | ||
89 | break; | ||
90 | default: | ||
91 | ar7_regs_wdt = UR8_REGS_WDT; | ||
92 | break; | ||
93 | } | ||
94 | } | ||
95 | |||
96 | |||
97 | static void ar7_wdt_kick(u32 value) | ||
98 | { | ||
99 | WRITE_REG(ar7_wdt->kick_lock, 0x5555); | ||
100 | if ((READ_REG(ar7_wdt->kick_lock) & 3) == 1) { | ||
101 | WRITE_REG(ar7_wdt->kick_lock, 0xaaaa); | ||
102 | if ((READ_REG(ar7_wdt->kick_lock) & 3) == 3) { | ||
103 | WRITE_REG(ar7_wdt->kick, value); | ||
104 | return; | ||
105 | } | ||
106 | } | ||
107 | printk(KERN_ERR DRVNAME ": failed to unlock WDT kick reg\n"); | ||
108 | } | ||
109 | |||
110 | static void ar7_wdt_prescale(u32 value) | ||
111 | { | ||
112 | WRITE_REG(ar7_wdt->prescale_lock, 0x5a5a); | ||
113 | if ((READ_REG(ar7_wdt->prescale_lock) & 3) == 1) { | ||
114 | WRITE_REG(ar7_wdt->prescale_lock, 0xa5a5); | ||
115 | if ((READ_REG(ar7_wdt->prescale_lock) & 3) == 3) { | ||
116 | WRITE_REG(ar7_wdt->prescale, value); | ||
117 | return; | ||
118 | } | ||
119 | } | ||
120 | printk(KERN_ERR DRVNAME ": failed to unlock WDT prescale reg\n"); | ||
121 | } | ||
122 | |||
123 | static void ar7_wdt_change(u32 value) | ||
124 | { | ||
125 | WRITE_REG(ar7_wdt->change_lock, 0x6666); | ||
126 | if ((READ_REG(ar7_wdt->change_lock) & 3) == 1) { | ||
127 | WRITE_REG(ar7_wdt->change_lock, 0xbbbb); | ||
128 | if ((READ_REG(ar7_wdt->change_lock) & 3) == 3) { | ||
129 | WRITE_REG(ar7_wdt->change, value); | ||
130 | return; | ||
131 | } | ||
132 | } | ||
133 | printk(KERN_ERR DRVNAME ": failed to unlock WDT change reg\n"); | ||
134 | } | ||
135 | |||
136 | static void ar7_wdt_disable(u32 value) | ||
137 | { | ||
138 | WRITE_REG(ar7_wdt->disable_lock, 0x7777); | ||
139 | if ((READ_REG(ar7_wdt->disable_lock) & 3) == 1) { | ||
140 | WRITE_REG(ar7_wdt->disable_lock, 0xcccc); | ||
141 | if ((READ_REG(ar7_wdt->disable_lock) & 3) == 2) { | ||
142 | WRITE_REG(ar7_wdt->disable_lock, 0xdddd); | ||
143 | if ((READ_REG(ar7_wdt->disable_lock) & 3) == 3) { | ||
144 | WRITE_REG(ar7_wdt->disable, value); | ||
145 | return; | ||
146 | } | ||
147 | } | ||
148 | } | ||
149 | printk(KERN_ERR DRVNAME ": failed to unlock WDT disable reg\n"); | ||
150 | } | ||
151 | |||
152 | static void ar7_wdt_update_margin(int new_margin) | ||
153 | { | ||
154 | u32 change; | ||
155 | |||
156 | change = new_margin * (ar7_vbus_freq() / prescale_value); | ||
157 | if (change < 1) change = 1; | ||
158 | if (change > 0xffff) change = 0xffff; | ||
159 | ar7_wdt_change(change); | ||
160 | margin = change * prescale_value / ar7_vbus_freq(); | ||
161 | printk(KERN_INFO DRVNAME | ||
162 | ": timer margin %d seconds (prescale %d, change %d, freq %d)\n", | ||
163 | margin, prescale_value, change, ar7_vbus_freq()); | ||
164 | } | ||
165 | |||
166 | static void ar7_wdt_enable_wdt(void) | ||
167 | { | ||
168 | printk(KERN_DEBUG DRVNAME ": enabling watchdog timer\n"); | ||
169 | ar7_wdt_disable(1); | ||
170 | ar7_wdt_kick(1); | ||
171 | } | ||
172 | |||
173 | static void ar7_wdt_disable_wdt(void) | ||
174 | { | ||
175 | printk(KERN_DEBUG DRVNAME ": disabling watchdog timer\n"); | ||
176 | ar7_wdt_disable(0); | ||
177 | } | ||
178 | |||
179 | static int ar7_wdt_open(struct inode *inode, struct file *file) | ||
180 | { | ||
181 | /* only allow one at a time */ | ||
182 | if (down_trylock(&open_semaphore)) | ||
183 | return -EBUSY; | ||
184 | ar7_wdt_enable_wdt(); | ||
185 | expect_close = 0; | ||
186 | |||
187 | return nonseekable_open(inode, file); | ||
188 | } | ||
189 | |||
190 | static int ar7_wdt_release(struct inode *inode, struct file *file) | ||
191 | { | ||
192 | if (!expect_close) | ||
193 | printk(KERN_WARNING DRVNAME | ||
194 | ": watchdog device closed unexpectedly," | ||
195 | "will not disable the watchdog timer\n"); | ||
196 | else if (!nowayout) | ||
197 | ar7_wdt_disable_wdt(); | ||
198 | |||
199 | up(&open_semaphore); | ||
200 | |||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int ar7_wdt_notify_sys(struct notifier_block *this, | ||
205 | unsigned long code, void *unused) | ||
206 | { | ||
207 | if (code == SYS_HALT || code == SYS_POWER_OFF) | ||
208 | if (!nowayout) | ||
209 | ar7_wdt_disable_wdt(); | ||
210 | |||
211 | return NOTIFY_DONE; | ||
212 | } | ||
213 | |||
214 | static struct notifier_block ar7_wdt_notifier = { | ||
215 | .notifier_call = ar7_wdt_notify_sys | ||
216 | }; | ||
217 | |||
218 | static ssize_t ar7_wdt_write(struct file *file, const char *data, | ||
219 | size_t len, loff_t *ppos) | ||
220 | { | ||
221 | /* check for a magic close character */ | ||
222 | if (len) { | ||
223 | size_t i; | ||
224 | |||
225 | ar7_wdt_kick(1); | ||
226 | |||
227 | expect_close = 0; | ||
228 | for (i = 0; i < len; ++i) { | ||
229 | char c; | ||
230 | if (get_user(c, data+i)) | ||
231 | return -EFAULT; | ||
232 | if (c == 'V') | ||
233 | expect_close = 1; | ||
234 | } | ||
235 | |||
236 | } | ||
237 | return len; | ||
238 | } | ||
239 | |||
240 | static int ar7_wdt_ioctl(struct inode *inode, struct file *file, | ||
241 | unsigned int cmd, unsigned long arg) | ||
242 | { | ||
243 | static struct watchdog_info ident = { | ||
244 | .identity = LONGNAME, | ||
245 | .firmware_version = 1, | ||
246 | .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING), | ||
247 | }; | ||
248 | int new_margin; | ||
249 | |||
250 | switch (cmd) { | ||
251 | default: | ||
252 | return -ENOTTY; | ||
253 | case WDIOC_GETSUPPORT: | ||
254 | if (copy_to_user((struct watchdog_info *)arg, &ident, | ||
255 | sizeof(ident))) | ||
256 | return -EFAULT; | ||
257 | return 0; | ||
258 | case WDIOC_GETSTATUS: | ||
259 | case WDIOC_GETBOOTSTATUS: | ||
260 | if (put_user(0, (int *)arg)) | ||
261 | return -EFAULT; | ||
262 | return 0; | ||
263 | case WDIOC_KEEPALIVE: | ||
264 | ar7_wdt_kick(1); | ||
265 | return 0; | ||
266 | case WDIOC_SETTIMEOUT: | ||
267 | if (get_user(new_margin, (int *)arg)) | ||
268 | return -EFAULT; | ||
269 | if (new_margin < 1) | ||
270 | return -EINVAL; | ||
271 | |||
272 | ar7_wdt_update_margin(new_margin); | ||
273 | ar7_wdt_kick(1); | ||
274 | |||
275 | case WDIOC_GETTIMEOUT: | ||
276 | if (put_user(margin, (int *)arg)) | ||
277 | return -EFAULT; | ||
278 | return 0; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | static struct file_operations ar7_wdt_fops = { | ||
283 | .owner = THIS_MODULE, | ||
284 | .write = ar7_wdt_write, | ||
285 | .ioctl = ar7_wdt_ioctl, | ||
286 | .open = ar7_wdt_open, | ||
287 | .release = ar7_wdt_release, | ||
288 | }; | ||
289 | |||
290 | static struct miscdevice ar7_wdt_miscdev = { | ||
291 | .minor = WATCHDOG_MINOR, | ||
292 | .name = "watchdog", | ||
293 | .fops = &ar7_wdt_fops, | ||
294 | }; | ||
295 | |||
296 | static int __init ar7_wdt_init(void) | ||
297 | { | ||
298 | int rc; | ||
299 | |||
300 | ar7_wdt_get_regs(); | ||
301 | |||
302 | if (!request_mem_region(ar7_regs_wdt, sizeof(struct ar7_wdt), | ||
303 | LONGNAME)) { | ||
304 | printk(KERN_WARNING DRVNAME ": watchdog I/O region busy\n"); | ||
305 | return -EBUSY; | ||
306 | } | ||
307 | |||
308 | ar7_wdt = (struct ar7_wdt *) | ||
309 | ioremap(ar7_regs_wdt, sizeof(struct ar7_wdt)); | ||
310 | |||
311 | ar7_wdt_disable_wdt(); | ||
312 | ar7_wdt_prescale(prescale_value); | ||
313 | ar7_wdt_update_margin(margin); | ||
314 | |||
315 | sema_init(&open_semaphore, 1); | ||
316 | |||
317 | rc = register_reboot_notifier(&ar7_wdt_notifier); | ||
318 | if (rc) { | ||
319 | printk(KERN_ERR DRVNAME | ||
320 | ": unable to register reboot notifier\n"); | ||
321 | goto out_alloc; | ||
322 | } | ||
323 | |||
324 | rc = misc_register(&ar7_wdt_miscdev); | ||
325 | if (rc) { | ||
326 | printk(KERN_ERR DRVNAME ": unable to register misc device\n"); | ||
327 | goto out_register; | ||
328 | } | ||
329 | goto out; | ||
330 | |||
331 | out_register: | ||
332 | unregister_reboot_notifier(&ar7_wdt_notifier); | ||
333 | out_alloc: | ||
334 | iounmap(ar7_wdt); | ||
335 | release_mem_region(ar7_regs_wdt, sizeof(struct ar7_wdt)); | ||
336 | out: | ||
337 | return rc; | ||
338 | } | ||
339 | |||
340 | static void __exit ar7_wdt_cleanup(void) | ||
341 | { | ||
342 | misc_deregister(&ar7_wdt_miscdev); | ||
343 | unregister_reboot_notifier(&ar7_wdt_notifier); | ||
344 | iounmap(ar7_wdt); | ||
345 | release_mem_region(ar7_regs_wdt, sizeof(struct ar7_wdt)); | ||
346 | } | ||
347 | |||
348 | module_init(ar7_wdt_init); | ||
349 | module_exit(ar7_wdt_cleanup); | ||
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 32fe97211eea..afcab007a22b 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -549,13 +549,13 @@ static void nfs_direct_write_result(struct rpc_task *task, void *calldata) | |||
549 | 549 | ||
550 | spin_lock(&dreq->lock); | 550 | spin_lock(&dreq->lock); |
551 | 551 | ||
552 | if (unlikely(dreq->error != 0)) | ||
553 | goto out_unlock; | ||
554 | if (unlikely(status < 0)) { | 552 | if (unlikely(status < 0)) { |
555 | /* An error has occured, so we should not commit */ | 553 | /* An error has occurred, so we should not commit */ |
556 | dreq->flags = 0; | 554 | dreq->flags = 0; |
557 | dreq->error = status; | 555 | dreq->error = status; |
558 | } | 556 | } |
557 | if (unlikely(dreq->error != 0)) | ||
558 | goto out_unlock; | ||
559 | 559 | ||
560 | dreq->count += data->res.count; | 560 | dreq->count += data->res.count; |
561 | 561 | ||
diff --git a/include/asm-x86/Kbuild b/include/asm-x86/Kbuild index 5e3539c129b9..12db5a1cdd74 100644 --- a/include/asm-x86/Kbuild +++ b/include/asm-x86/Kbuild | |||
@@ -11,41 +11,16 @@ header-y += sigcontext32.h | |||
11 | header-y += ucontext.h | 11 | header-y += ucontext.h |
12 | header-y += vsyscall32.h | 12 | header-y += vsyscall32.h |
13 | 13 | ||
14 | unifdef-y += a.out_32.h | ||
15 | unifdef-y += a.out_64.h | ||
16 | unifdef-y += byteorder_32.h | ||
17 | unifdef-y += byteorder_64.h | ||
18 | unifdef-y += e820.h | 14 | unifdef-y += e820.h |
19 | unifdef-y += elf_32.h | ||
20 | unifdef-y += elf_64.h | ||
21 | unifdef-y += ist.h | 15 | unifdef-y += ist.h |
22 | unifdef-y += mce.h | 16 | unifdef-y += mce.h |
23 | unifdef-y += msgbuf_32.h | ||
24 | unifdef-y += msgbuf_64.h | ||
25 | unifdef-y += msr_32.h | ||
26 | unifdef-y += msr_64.h | ||
27 | unifdef-y += msr.h | 17 | unifdef-y += msr.h |
28 | unifdef-y += mtrr_32.h | ||
29 | unifdef-y += mtrr_64.h | ||
30 | unifdef-y += mtrr.h | 18 | unifdef-y += mtrr.h |
31 | unifdef-y += page_32.h | 19 | unifdef-y += page_32.h |
32 | unifdef-y += page_64.h | 20 | unifdef-y += page_64.h |
33 | unifdef-y += posix_types_32.h | 21 | unifdef-y += posix_types_32.h |
34 | unifdef-y += posix_types_64.h | 22 | unifdef-y += posix_types_64.h |
35 | unifdef-y += ptrace_32.h | 23 | unifdef-y += ptrace.h |
36 | unifdef-y += ptrace_64.h | ||
37 | unifdef-y += setup_32.h | ||
38 | unifdef-y += setup_64.h | ||
39 | unifdef-y += shmbuf_32.h | ||
40 | unifdef-y += shmbuf_64.h | ||
41 | unifdef-y += sigcontext_32.h | ||
42 | unifdef-y += sigcontext_64.h | ||
43 | unifdef-y += signal_32.h | ||
44 | unifdef-y += signal_64.h | ||
45 | unifdef-y += stat_32.h | ||
46 | unifdef-y += stat_64.h | ||
47 | unifdef-y += statfs_32.h | ||
48 | unifdef-y += statfs_64.h | ||
49 | unifdef-y += unistd_32.h | 24 | unifdef-y += unistd_32.h |
50 | unifdef-y += unistd_64.h | 25 | unifdef-y += unistd_64.h |
51 | unifdef-y += user_32.h | 26 | unifdef-y += user_32.h |
diff --git a/include/asm-x86/a.out.h b/include/asm-x86/a.out.h index 5bc9b1d3b227..a62443e38eb8 100644 --- a/include/asm-x86/a.out.h +++ b/include/asm-x86/a.out.h | |||
@@ -1,13 +1,30 @@ | |||
1 | #ifndef _ASM_X86_A_OUT_H | ||
2 | #define _ASM_X86_A_OUT_H | ||
3 | |||
4 | struct exec | ||
5 | { | ||
6 | unsigned int a_info; /* Use macros N_MAGIC, etc for access */ | ||
7 | unsigned a_text; /* length of text, in bytes */ | ||
8 | unsigned a_data; /* length of data, in bytes */ | ||
9 | unsigned a_bss; /* length of uninitialized data area for file, in bytes */ | ||
10 | unsigned a_syms; /* length of symbol table data in file, in bytes */ | ||
11 | unsigned a_entry; /* start address */ | ||
12 | unsigned a_trsize; /* length of relocation info for text, in bytes */ | ||
13 | unsigned a_drsize; /* length of relocation info for data, in bytes */ | ||
14 | }; | ||
15 | |||
16 | #define N_TRSIZE(a) ((a).a_trsize) | ||
17 | #define N_DRSIZE(a) ((a).a_drsize) | ||
18 | #define N_SYMSIZE(a) ((a).a_syms) | ||
19 | |||
1 | #ifdef __KERNEL__ | 20 | #ifdef __KERNEL__ |
21 | # include <linux/thread_info.h> | ||
22 | # define STACK_TOP TASK_SIZE | ||
2 | # ifdef CONFIG_X86_32 | 23 | # ifdef CONFIG_X86_32 |
3 | # include "a.out_32.h" | 24 | # define STACK_TOP_MAX STACK_TOP |
4 | # else | 25 | # else |
5 | # include "a.out_64.h" | 26 | # define STACK_TOP_MAX TASK_SIZE64 |
6 | # endif | ||
7 | #else | ||
8 | # ifdef __i386__ | ||
9 | # include "a.out_32.h" | ||
10 | # else | ||
11 | # include "a.out_64.h" | ||
12 | # endif | 27 | # endif |
13 | #endif | 28 | #endif |
29 | |||
30 | #endif /* _ASM_X86_A_OUT_H */ | ||
diff --git a/include/asm-x86/a.out_32.h b/include/asm-x86/a.out_32.h deleted file mode 100644 index 851a60f8258c..000000000000 --- a/include/asm-x86/a.out_32.h +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | #ifndef __I386_A_OUT_H__ | ||
2 | #define __I386_A_OUT_H__ | ||
3 | |||
4 | struct exec | ||
5 | { | ||
6 | unsigned long a_info; /* Use macros N_MAGIC, etc for access */ | ||
7 | unsigned a_text; /* length of text, in bytes */ | ||
8 | unsigned a_data; /* length of data, in bytes */ | ||
9 | unsigned a_bss; /* length of uninitialized data area for file, in bytes */ | ||
10 | unsigned a_syms; /* length of symbol table data in file, in bytes */ | ||
11 | unsigned a_entry; /* start address */ | ||
12 | unsigned a_trsize; /* length of relocation info for text, in bytes */ | ||
13 | unsigned a_drsize; /* length of relocation info for data, in bytes */ | ||
14 | }; | ||
15 | |||
16 | #define N_TRSIZE(a) ((a).a_trsize) | ||
17 | #define N_DRSIZE(a) ((a).a_drsize) | ||
18 | #define N_SYMSIZE(a) ((a).a_syms) | ||
19 | |||
20 | #ifdef __KERNEL__ | ||
21 | |||
22 | #define STACK_TOP TASK_SIZE | ||
23 | #define STACK_TOP_MAX STACK_TOP | ||
24 | |||
25 | #endif | ||
26 | |||
27 | #endif /* __A_OUT_GNU_H__ */ | ||
diff --git a/include/asm-x86/a.out_64.h b/include/asm-x86/a.out_64.h deleted file mode 100644 index e789300e41a5..000000000000 --- a/include/asm-x86/a.out_64.h +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | #ifndef __X8664_A_OUT_H__ | ||
2 | #define __X8664_A_OUT_H__ | ||
3 | |||
4 | /* 32bit a.out */ | ||
5 | |||
6 | struct exec | ||
7 | { | ||
8 | unsigned int a_info; /* Use macros N_MAGIC, etc for access */ | ||
9 | unsigned a_text; /* length of text, in bytes */ | ||
10 | unsigned a_data; /* length of data, in bytes */ | ||
11 | unsigned a_bss; /* length of uninitialized data area for file, in bytes */ | ||
12 | unsigned a_syms; /* length of symbol table data in file, in bytes */ | ||
13 | unsigned a_entry; /* start address */ | ||
14 | unsigned a_trsize; /* length of relocation info for text, in bytes */ | ||
15 | unsigned a_drsize; /* length of relocation info for data, in bytes */ | ||
16 | }; | ||
17 | |||
18 | #define N_TRSIZE(a) ((a).a_trsize) | ||
19 | #define N_DRSIZE(a) ((a).a_drsize) | ||
20 | #define N_SYMSIZE(a) ((a).a_syms) | ||
21 | |||
22 | #ifdef __KERNEL__ | ||
23 | #include <linux/thread_info.h> | ||
24 | #define STACK_TOP TASK_SIZE | ||
25 | #define STACK_TOP_MAX TASK_SIZE64 | ||
26 | #endif | ||
27 | |||
28 | #endif /* __A_OUT_GNU_H__ */ | ||
diff --git a/include/asm-x86/apic_64.h b/include/asm-x86/apic_64.h index 3c8f21eef0be..2747a11a2b19 100644 --- a/include/asm-x86/apic_64.h +++ b/include/asm-x86/apic_64.h | |||
@@ -69,6 +69,7 @@ extern void clear_local_APIC (void); | |||
69 | extern void connect_bsp_APIC (void); | 69 | extern void connect_bsp_APIC (void); |
70 | extern void disconnect_bsp_APIC (int virt_wire_setup); | 70 | extern void disconnect_bsp_APIC (int virt_wire_setup); |
71 | extern void disable_local_APIC (void); | 71 | extern void disable_local_APIC (void); |
72 | extern void lapic_shutdown (void); | ||
72 | extern int verify_local_APIC (void); | 73 | extern int verify_local_APIC (void); |
73 | extern void cache_APIC_registers (void); | 74 | extern void cache_APIC_registers (void); |
74 | extern void sync_Arb_IDs (void); | 75 | extern void sync_Arb_IDs (void); |
diff --git a/include/asm-x86/bitops_32.h b/include/asm-x86/bitops_32.h index 3268a341cf49..36ebb5b02b4f 100644 --- a/include/asm-x86/bitops_32.h +++ b/include/asm-x86/bitops_32.h | |||
@@ -80,6 +80,20 @@ static inline void clear_bit(int nr, volatile unsigned long * addr) | |||
80 | :"Ir" (nr)); | 80 | :"Ir" (nr)); |
81 | } | 81 | } |
82 | 82 | ||
83 | /* | ||
84 | * clear_bit_unlock - Clears a bit in memory | ||
85 | * @nr: Bit to clear | ||
86 | * @addr: Address to start counting from | ||
87 | * | ||
88 | * clear_bit() is atomic and implies release semantics before the memory | ||
89 | * operation. It can be used for an unlock. | ||
90 | */ | ||
91 | static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *addr) | ||
92 | { | ||
93 | barrier(); | ||
94 | clear_bit(nr, addr); | ||
95 | } | ||
96 | |||
83 | static inline void __clear_bit(int nr, volatile unsigned long * addr) | 97 | static inline void __clear_bit(int nr, volatile unsigned long * addr) |
84 | { | 98 | { |
85 | __asm__ __volatile__( | 99 | __asm__ __volatile__( |
@@ -87,6 +101,25 @@ static inline void __clear_bit(int nr, volatile unsigned long * addr) | |||
87 | :"+m" (ADDR) | 101 | :"+m" (ADDR) |
88 | :"Ir" (nr)); | 102 | :"Ir" (nr)); |
89 | } | 103 | } |
104 | |||
105 | /* | ||
106 | * __clear_bit_unlock - Clears a bit in memory | ||
107 | * @nr: Bit to clear | ||
108 | * @addr: Address to start counting from | ||
109 | * | ||
110 | * __clear_bit() is non-atomic and implies release semantics before the memory | ||
111 | * operation. It can be used for an unlock if no other CPUs can concurrently | ||
112 | * modify other bits in the word. | ||
113 | * | ||
114 | * No memory barrier is required here, because x86 cannot reorder stores past | ||
115 | * older loads. Same principle as spin_unlock. | ||
116 | */ | ||
117 | static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr) | ||
118 | { | ||
119 | barrier(); | ||
120 | __clear_bit(nr, addr); | ||
121 | } | ||
122 | |||
90 | #define smp_mb__before_clear_bit() barrier() | 123 | #define smp_mb__before_clear_bit() barrier() |
91 | #define smp_mb__after_clear_bit() barrier() | 124 | #define smp_mb__after_clear_bit() barrier() |
92 | 125 | ||
@@ -146,6 +179,15 @@ static inline int test_and_set_bit(int nr, volatile unsigned long * addr) | |||
146 | } | 179 | } |
147 | 180 | ||
148 | /** | 181 | /** |
182 | * test_and_set_bit_lock - Set a bit and return its old value for lock | ||
183 | * @nr: Bit to set | ||
184 | * @addr: Address to count from | ||
185 | * | ||
186 | * This is the same as test_and_set_bit on x86 | ||
187 | */ | ||
188 | #define test_and_set_bit_lock test_and_set_bit | ||
189 | |||
190 | /** | ||
149 | * __test_and_set_bit - Set a bit and return its old value | 191 | * __test_and_set_bit - Set a bit and return its old value |
150 | * @nr: Bit to set | 192 | * @nr: Bit to set |
151 | * @addr: Address to count from | 193 | * @addr: Address to count from |
@@ -406,7 +448,6 @@ static inline int fls(int x) | |||
406 | } | 448 | } |
407 | 449 | ||
408 | #include <asm-generic/bitops/hweight.h> | 450 | #include <asm-generic/bitops/hweight.h> |
409 | #include <asm-generic/bitops/lock.h> | ||
410 | 451 | ||
411 | #endif /* __KERNEL__ */ | 452 | #endif /* __KERNEL__ */ |
412 | 453 | ||
diff --git a/include/asm-x86/bitops_64.h b/include/asm-x86/bitops_64.h index dacaa5f1febc..b4d47940b959 100644 --- a/include/asm-x86/bitops_64.h +++ b/include/asm-x86/bitops_64.h | |||
@@ -72,6 +72,20 @@ static __inline__ void clear_bit(int nr, volatile void * addr) | |||
72 | :"dIr" (nr)); | 72 | :"dIr" (nr)); |
73 | } | 73 | } |
74 | 74 | ||
75 | /* | ||
76 | * clear_bit_unlock - Clears a bit in memory | ||
77 | * @nr: Bit to clear | ||
78 | * @addr: Address to start counting from | ||
79 | * | ||
80 | * clear_bit() is atomic and implies release semantics before the memory | ||
81 | * operation. It can be used for an unlock. | ||
82 | */ | ||
83 | static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *addr) | ||
84 | { | ||
85 | barrier(); | ||
86 | clear_bit(nr, addr); | ||
87 | } | ||
88 | |||
75 | static __inline__ void __clear_bit(int nr, volatile void * addr) | 89 | static __inline__ void __clear_bit(int nr, volatile void * addr) |
76 | { | 90 | { |
77 | __asm__ __volatile__( | 91 | __asm__ __volatile__( |
@@ -80,6 +94,24 @@ static __inline__ void __clear_bit(int nr, volatile void * addr) | |||
80 | :"dIr" (nr)); | 94 | :"dIr" (nr)); |
81 | } | 95 | } |
82 | 96 | ||
97 | /* | ||
98 | * __clear_bit_unlock - Clears a bit in memory | ||
99 | * @nr: Bit to clear | ||
100 | * @addr: Address to start counting from | ||
101 | * | ||
102 | * __clear_bit() is non-atomic and implies release semantics before the memory | ||
103 | * operation. It can be used for an unlock if no other CPUs can concurrently | ||
104 | * modify other bits in the word. | ||
105 | * | ||
106 | * No memory barrier is required here, because x86 cannot reorder stores past | ||
107 | * older loads. Same principle as spin_unlock. | ||
108 | */ | ||
109 | static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr) | ||
110 | { | ||
111 | barrier(); | ||
112 | __clear_bit(nr, addr); | ||
113 | } | ||
114 | |||
83 | #define smp_mb__before_clear_bit() barrier() | 115 | #define smp_mb__before_clear_bit() barrier() |
84 | #define smp_mb__after_clear_bit() barrier() | 116 | #define smp_mb__after_clear_bit() barrier() |
85 | 117 | ||
@@ -137,6 +169,15 @@ static __inline__ int test_and_set_bit(int nr, volatile void * addr) | |||
137 | } | 169 | } |
138 | 170 | ||
139 | /** | 171 | /** |
172 | * test_and_set_bit_lock - Set a bit and return its old value for lock | ||
173 | * @nr: Bit to set | ||
174 | * @addr: Address to count from | ||
175 | * | ||
176 | * This is the same as test_and_set_bit on x86 | ||
177 | */ | ||
178 | #define test_and_set_bit_lock test_and_set_bit | ||
179 | |||
180 | /** | ||
140 | * __test_and_set_bit - Set a bit and return its old value | 181 | * __test_and_set_bit - Set a bit and return its old value |
141 | * @nr: Bit to set | 182 | * @nr: Bit to set |
142 | * @addr: Address to count from | 183 | * @addr: Address to count from |
@@ -412,7 +453,6 @@ static __inline__ int fls(int x) | |||
412 | #define ARCH_HAS_FAST_MULTIPLIER 1 | 453 | #define ARCH_HAS_FAST_MULTIPLIER 1 |
413 | 454 | ||
414 | #include <asm-generic/bitops/hweight.h> | 455 | #include <asm-generic/bitops/hweight.h> |
415 | #include <asm-generic/bitops/lock.h> | ||
416 | 456 | ||
417 | #endif /* __KERNEL__ */ | 457 | #endif /* __KERNEL__ */ |
418 | 458 | ||
diff --git a/include/asm-x86/byteorder.h b/include/asm-x86/byteorder.h index eb14b1870ed7..1f2d6d5bf20d 100644 --- a/include/asm-x86/byteorder.h +++ b/include/asm-x86/byteorder.h | |||
@@ -1,13 +1,72 @@ | |||
1 | #ifdef __KERNEL__ | 1 | #ifndef _ASM_X86_BYTEORDER_H |
2 | # ifdef CONFIG_X86_32 | 2 | #define _ASM_X86_BYTEORDER_H |
3 | # include "byteorder_32.h" | 3 | |
4 | # else | 4 | #include <asm/types.h> |
5 | # include "byteorder_64.h" | 5 | #include <linux/compiler.h> |
6 | # endif | 6 | |
7 | #ifdef __GNUC__ | ||
8 | |||
9 | #ifdef __i386__ | ||
10 | |||
11 | static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) | ||
12 | { | ||
13 | #ifdef CONFIG_X86_BSWAP | ||
14 | __asm__("bswap %0" : "=r" (x) : "0" (x)); | ||
7 | #else | 15 | #else |
8 | # ifdef __i386__ | 16 | __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ |
9 | # include "byteorder_32.h" | 17 | "rorl $16,%0\n\t" /* swap words */ |
10 | # else | 18 | "xchgb %b0,%h0" /* swap higher bytes */ |
11 | # include "byteorder_64.h" | 19 | :"=q" (x) |
12 | # endif | 20 | : "0" (x)); |
13 | #endif | 21 | #endif |
22 | return x; | ||
23 | } | ||
24 | |||
25 | static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 val) | ||
26 | { | ||
27 | union { | ||
28 | struct { __u32 a,b; } s; | ||
29 | __u64 u; | ||
30 | } v; | ||
31 | v.u = val; | ||
32 | #ifdef CONFIG_X86_BSWAP | ||
33 | asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1" | ||
34 | : "=r" (v.s.a), "=r" (v.s.b) | ||
35 | : "0" (v.s.a), "1" (v.s.b)); | ||
36 | #else | ||
37 | v.s.a = ___arch__swab32(v.s.a); | ||
38 | v.s.b = ___arch__swab32(v.s.b); | ||
39 | asm("xchgl %0,%1" : "=r" (v.s.a), "=r" (v.s.b) : "0" (v.s.a), "1" (v.s.b)); | ||
40 | #endif | ||
41 | return v.u; | ||
42 | } | ||
43 | |||
44 | #else /* __i386__ */ | ||
45 | |||
46 | static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x) | ||
47 | { | ||
48 | __asm__("bswapq %0" : "=r" (x) : "0" (x)); | ||
49 | return x; | ||
50 | } | ||
51 | |||
52 | static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) | ||
53 | { | ||
54 | __asm__("bswapl %0" : "=r" (x) : "0" (x)); | ||
55 | return x; | ||
56 | } | ||
57 | |||
58 | #endif | ||
59 | |||
60 | /* Do not define swab16. Gcc is smart enough to recognize "C" version and | ||
61 | convert it into rotation or exhange. */ | ||
62 | |||
63 | #define __arch__swab64(x) ___arch__swab64(x) | ||
64 | #define __arch__swab32(x) ___arch__swab32(x) | ||
65 | |||
66 | #define __BYTEORDER_HAS_U64__ | ||
67 | |||
68 | #endif /* __GNUC__ */ | ||
69 | |||
70 | #include <linux/byteorder/little_endian.h> | ||
71 | |||
72 | #endif /* _ASM_X86_BYTEORDER_H */ | ||
diff --git a/include/asm-x86/byteorder_32.h b/include/asm-x86/byteorder_32.h deleted file mode 100644 index a45470a8b74a..000000000000 --- a/include/asm-x86/byteorder_32.h +++ /dev/null | |||
@@ -1,58 +0,0 @@ | |||
1 | #ifndef _I386_BYTEORDER_H | ||
2 | #define _I386_BYTEORDER_H | ||
3 | |||
4 | #include <asm/types.h> | ||
5 | #include <linux/compiler.h> | ||
6 | |||
7 | #ifdef __GNUC__ | ||
8 | |||
9 | /* For avoiding bswap on i386 */ | ||
10 | #ifdef __KERNEL__ | ||
11 | #endif | ||
12 | |||
13 | static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) | ||
14 | { | ||
15 | #ifdef CONFIG_X86_BSWAP | ||
16 | __asm__("bswap %0" : "=r" (x) : "0" (x)); | ||
17 | #else | ||
18 | __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ | ||
19 | "rorl $16,%0\n\t" /* swap words */ | ||
20 | "xchgb %b0,%h0" /* swap higher bytes */ | ||
21 | :"=q" (x) | ||
22 | : "0" (x)); | ||
23 | #endif | ||
24 | return x; | ||
25 | } | ||
26 | |||
27 | static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 val) | ||
28 | { | ||
29 | union { | ||
30 | struct { __u32 a,b; } s; | ||
31 | __u64 u; | ||
32 | } v; | ||
33 | v.u = val; | ||
34 | #ifdef CONFIG_X86_BSWAP | ||
35 | asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1" | ||
36 | : "=r" (v.s.a), "=r" (v.s.b) | ||
37 | : "0" (v.s.a), "1" (v.s.b)); | ||
38 | #else | ||
39 | v.s.a = ___arch__swab32(v.s.a); | ||
40 | v.s.b = ___arch__swab32(v.s.b); | ||
41 | asm("xchgl %0,%1" : "=r" (v.s.a), "=r" (v.s.b) : "0" (v.s.a), "1" (v.s.b)); | ||
42 | #endif | ||
43 | return v.u; | ||
44 | } | ||
45 | |||
46 | /* Do not define swab16. Gcc is smart enough to recognize "C" version and | ||
47 | convert it into rotation or exhange. */ | ||
48 | |||
49 | #define __arch__swab64(x) ___arch__swab64(x) | ||
50 | #define __arch__swab32(x) ___arch__swab32(x) | ||
51 | |||
52 | #define __BYTEORDER_HAS_U64__ | ||
53 | |||
54 | #endif /* __GNUC__ */ | ||
55 | |||
56 | #include <linux/byteorder/little_endian.h> | ||
57 | |||
58 | #endif /* _I386_BYTEORDER_H */ | ||
diff --git a/include/asm-x86/byteorder_64.h b/include/asm-x86/byteorder_64.h deleted file mode 100644 index 5e86c868c75e..000000000000 --- a/include/asm-x86/byteorder_64.h +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | #ifndef _X86_64_BYTEORDER_H | ||
2 | #define _X86_64_BYTEORDER_H | ||
3 | |||
4 | #include <asm/types.h> | ||
5 | #include <linux/compiler.h> | ||
6 | |||
7 | #ifdef __GNUC__ | ||
8 | |||
9 | static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x) | ||
10 | { | ||
11 | __asm__("bswapq %0" : "=r" (x) : "0" (x)); | ||
12 | return x; | ||
13 | } | ||
14 | |||
15 | static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) | ||
16 | { | ||
17 | __asm__("bswapl %0" : "=r" (x) : "0" (x)); | ||
18 | return x; | ||
19 | } | ||
20 | |||
21 | /* Do not define swab16. Gcc is smart enough to recognize "C" version and | ||
22 | convert it into rotation or exhange. */ | ||
23 | |||
24 | #define __arch__swab32(x) ___arch__swab32(x) | ||
25 | #define __arch__swab64(x) ___arch__swab64(x) | ||
26 | |||
27 | #endif /* __GNUC__ */ | ||
28 | |||
29 | #define __BYTEORDER_HAS_U64__ | ||
30 | |||
31 | #include <linux/byteorder/little_endian.h> | ||
32 | |||
33 | #endif /* _X86_64_BYTEORDER_H */ | ||
diff --git a/include/asm-x86/div64.h b/include/asm-x86/div64.h index 8ac7da6ca284..e98d16e7a37a 100644 --- a/include/asm-x86/div64.h +++ b/include/asm-x86/div64.h | |||
@@ -1,5 +1,59 @@ | |||
1 | #ifndef _ASM_X86_DIV64_H | ||
2 | #define _ASM_X86_DIV64_H | ||
3 | |||
1 | #ifdef CONFIG_X86_32 | 4 | #ifdef CONFIG_X86_32 |
2 | # include "div64_32.h" | 5 | |
6 | #include <linux/types.h> | ||
7 | |||
8 | /* | ||
9 | * do_div() is NOT a C function. It wants to return | ||
10 | * two values (the quotient and the remainder), but | ||
11 | * since that doesn't work very well in C, what it | ||
12 | * does is: | ||
13 | * | ||
14 | * - modifies the 64-bit dividend _in_place_ | ||
15 | * - returns the 32-bit remainder | ||
16 | * | ||
17 | * This ends up being the most efficient "calling | ||
18 | * convention" on x86. | ||
19 | */ | ||
20 | #define do_div(n,base) ({ \ | ||
21 | unsigned long __upper, __low, __high, __mod, __base; \ | ||
22 | __base = (base); \ | ||
23 | asm("":"=a" (__low), "=d" (__high):"A" (n)); \ | ||
24 | __upper = __high; \ | ||
25 | if (__high) { \ | ||
26 | __upper = __high % (__base); \ | ||
27 | __high = __high / (__base); \ | ||
28 | } \ | ||
29 | asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \ | ||
30 | asm("":"=A" (n):"a" (__low),"d" (__high)); \ | ||
31 | __mod; \ | ||
32 | }) | ||
33 | |||
34 | /* | ||
35 | * (long)X = ((long long)divs) / (long)div | ||
36 | * (long)rem = ((long long)divs) % (long)div | ||
37 | * | ||
38 | * Warning, this will do an exception if X overflows. | ||
39 | */ | ||
40 | #define div_long_long_rem(a,b,c) div_ll_X_l_rem(a,b,c) | ||
41 | |||
42 | static inline long | ||
43 | div_ll_X_l_rem(long long divs, long div, long *rem) | ||
44 | { | ||
45 | long dum2; | ||
46 | __asm__("divl %2":"=a"(dum2), "=d"(*rem) | ||
47 | : "rm"(div), "A"(divs)); | ||
48 | |||
49 | return dum2; | ||
50 | |||
51 | } | ||
52 | |||
53 | extern uint64_t div64_64(uint64_t dividend, uint64_t divisor); | ||
54 | |||
3 | #else | 55 | #else |
4 | # include "div64_64.h" | 56 | # include <asm-generic/div64.h> |
5 | #endif | 57 | #endif /* CONFIG_X86_32 */ |
58 | |||
59 | #endif /* _ASM_X86_DIV64_H */ | ||
diff --git a/include/asm-x86/div64_32.h b/include/asm-x86/div64_32.h deleted file mode 100644 index 438e980068bd..000000000000 --- a/include/asm-x86/div64_32.h +++ /dev/null | |||
@@ -1,52 +0,0 @@ | |||
1 | #ifndef __I386_DIV64 | ||
2 | #define __I386_DIV64 | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | |||
6 | /* | ||
7 | * do_div() is NOT a C function. It wants to return | ||
8 | * two values (the quotient and the remainder), but | ||
9 | * since that doesn't work very well in C, what it | ||
10 | * does is: | ||
11 | * | ||
12 | * - modifies the 64-bit dividend _in_place_ | ||
13 | * - returns the 32-bit remainder | ||
14 | * | ||
15 | * This ends up being the most efficient "calling | ||
16 | * convention" on x86. | ||
17 | */ | ||
18 | #define do_div(n,base) ({ \ | ||
19 | unsigned long __upper, __low, __high, __mod, __base; \ | ||
20 | __base = (base); \ | ||
21 | asm("":"=a" (__low), "=d" (__high):"A" (n)); \ | ||
22 | __upper = __high; \ | ||
23 | if (__high) { \ | ||
24 | __upper = __high % (__base); \ | ||
25 | __high = __high / (__base); \ | ||
26 | } \ | ||
27 | asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \ | ||
28 | asm("":"=A" (n):"a" (__low),"d" (__high)); \ | ||
29 | __mod; \ | ||
30 | }) | ||
31 | |||
32 | /* | ||
33 | * (long)X = ((long long)divs) / (long)div | ||
34 | * (long)rem = ((long long)divs) % (long)div | ||
35 | * | ||
36 | * Warning, this will do an exception if X overflows. | ||
37 | */ | ||
38 | #define div_long_long_rem(a,b,c) div_ll_X_l_rem(a,b,c) | ||
39 | |||
40 | static inline long | ||
41 | div_ll_X_l_rem(long long divs, long div, long *rem) | ||
42 | { | ||
43 | long dum2; | ||
44 | __asm__("divl %2":"=a"(dum2), "=d"(*rem) | ||
45 | : "rm"(div), "A"(divs)); | ||
46 | |||
47 | return dum2; | ||
48 | |||
49 | } | ||
50 | |||
51 | extern uint64_t div64_64(uint64_t dividend, uint64_t divisor); | ||
52 | #endif | ||
diff --git a/include/asm-x86/div64_64.h b/include/asm-x86/div64_64.h deleted file mode 100644 index 6cd978cefb28..000000000000 --- a/include/asm-x86/div64_64.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include <asm-generic/div64.h> | ||
diff --git a/include/asm-x86/elf.h b/include/asm-x86/elf.h index ed6bb6e546b9..ec42a4d2e83b 100644 --- a/include/asm-x86/elf.h +++ b/include/asm-x86/elf.h | |||
@@ -1,13 +1,290 @@ | |||
1 | #ifdef __KERNEL__ | 1 | #ifndef _ASM_X86_ELF_H |
2 | # ifdef CONFIG_X86_32 | 2 | #define _ASM_X86_ELF_H |
3 | # include "elf_32.h" | 3 | |
4 | # else | 4 | /* |
5 | # include "elf_64.h" | 5 | * ELF register definitions.. |
6 | # endif | 6 | */ |
7 | |||
8 | #include <asm/ptrace.h> | ||
9 | #include <asm/user.h> | ||
10 | #include <asm/auxvec.h> | ||
11 | |||
12 | typedef unsigned long elf_greg_t; | ||
13 | |||
14 | #define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) | ||
15 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | ||
16 | |||
17 | typedef struct user_i387_struct elf_fpregset_t; | ||
18 | |||
19 | #ifdef __i386__ | ||
20 | |||
21 | typedef struct user_fxsr_struct elf_fpxregset_t; | ||
22 | |||
23 | #define R_386_NONE 0 | ||
24 | #define R_386_32 1 | ||
25 | #define R_386_PC32 2 | ||
26 | #define R_386_GOT32 3 | ||
27 | #define R_386_PLT32 4 | ||
28 | #define R_386_COPY 5 | ||
29 | #define R_386_GLOB_DAT 6 | ||
30 | #define R_386_JMP_SLOT 7 | ||
31 | #define R_386_RELATIVE 8 | ||
32 | #define R_386_GOTOFF 9 | ||
33 | #define R_386_GOTPC 10 | ||
34 | #define R_386_NUM 11 | ||
35 | |||
36 | /* | ||
37 | * These are used to set parameters in the core dumps. | ||
38 | */ | ||
39 | #define ELF_CLASS ELFCLASS32 | ||
40 | #define ELF_DATA ELFDATA2LSB | ||
41 | #define ELF_ARCH EM_386 | ||
42 | |||
7 | #else | 43 | #else |
8 | # ifdef __i386__ | 44 | |
9 | # include "elf_32.h" | 45 | /* x86-64 relocation types */ |
10 | # else | 46 | #define R_X86_64_NONE 0 /* No reloc */ |
11 | # include "elf_64.h" | 47 | #define R_X86_64_64 1 /* Direct 64 bit */ |
12 | # endif | 48 | #define R_X86_64_PC32 2 /* PC relative 32 bit signed */ |
49 | #define R_X86_64_GOT32 3 /* 32 bit GOT entry */ | ||
50 | #define R_X86_64_PLT32 4 /* 32 bit PLT address */ | ||
51 | #define R_X86_64_COPY 5 /* Copy symbol at runtime */ | ||
52 | #define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ | ||
53 | #define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ | ||
54 | #define R_X86_64_RELATIVE 8 /* Adjust by program base */ | ||
55 | #define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative | ||
56 | offset to GOT */ | ||
57 | #define R_X86_64_32 10 /* Direct 32 bit zero extended */ | ||
58 | #define R_X86_64_32S 11 /* Direct 32 bit sign extended */ | ||
59 | #define R_X86_64_16 12 /* Direct 16 bit zero extended */ | ||
60 | #define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ | ||
61 | #define R_X86_64_8 14 /* Direct 8 bit sign extended */ | ||
62 | #define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ | ||
63 | |||
64 | #define R_X86_64_NUM 16 | ||
65 | |||
66 | /* | ||
67 | * These are used to set parameters in the core dumps. | ||
68 | */ | ||
69 | #define ELF_CLASS ELFCLASS64 | ||
70 | #define ELF_DATA ELFDATA2LSB | ||
71 | #define ELF_ARCH EM_X86_64 | ||
72 | |||
73 | #endif | ||
74 | |||
75 | #ifdef __KERNEL__ | ||
76 | |||
77 | #ifdef CONFIG_X86_32 | ||
78 | #include <asm/processor.h> | ||
79 | #include <asm/system.h> /* for savesegment */ | ||
80 | #include <asm/desc.h> | ||
81 | |||
82 | /* | ||
83 | * This is used to ensure we don't load something for the wrong architecture. | ||
84 | */ | ||
85 | #define elf_check_arch(x) \ | ||
86 | (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486)) | ||
87 | |||
88 | /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edx | ||
89 | contains a pointer to a function which might be registered using `atexit'. | ||
90 | This provides a mean for the dynamic linker to call DT_FINI functions for | ||
91 | shared libraries that have been loaded before the code runs. | ||
92 | |||
93 | A value of 0 tells we have no such handler. | ||
94 | |||
95 | We might as well make sure everything else is cleared too (except for %esp), | ||
96 | just to make things more deterministic. | ||
97 | */ | ||
98 | #define ELF_PLAT_INIT(_r, load_addr) do { \ | ||
99 | _r->ebx = 0; _r->ecx = 0; _r->edx = 0; \ | ||
100 | _r->esi = 0; _r->edi = 0; _r->ebp = 0; \ | ||
101 | _r->eax = 0; \ | ||
102 | } while (0) | ||
103 | |||
104 | /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is | ||
105 | now struct_user_regs, they are different) */ | ||
106 | |||
107 | #define ELF_CORE_COPY_REGS(pr_reg, regs) \ | ||
108 | pr_reg[0] = regs->ebx; \ | ||
109 | pr_reg[1] = regs->ecx; \ | ||
110 | pr_reg[2] = regs->edx; \ | ||
111 | pr_reg[3] = regs->esi; \ | ||
112 | pr_reg[4] = regs->edi; \ | ||
113 | pr_reg[5] = regs->ebp; \ | ||
114 | pr_reg[6] = regs->eax; \ | ||
115 | pr_reg[7] = regs->xds & 0xffff; \ | ||
116 | pr_reg[8] = regs->xes & 0xffff; \ | ||
117 | pr_reg[9] = regs->xfs & 0xffff; \ | ||
118 | savesegment(gs,pr_reg[10]); \ | ||
119 | pr_reg[11] = regs->orig_eax; \ | ||
120 | pr_reg[12] = regs->eip; \ | ||
121 | pr_reg[13] = regs->xcs & 0xffff; \ | ||
122 | pr_reg[14] = regs->eflags; \ | ||
123 | pr_reg[15] = regs->esp; \ | ||
124 | pr_reg[16] = regs->xss & 0xffff; | ||
125 | |||
126 | #define ELF_PLATFORM (utsname()->machine) | ||
127 | #define set_personality_64bit() do { } while (0) | ||
128 | extern unsigned int vdso_enabled; | ||
129 | |||
130 | #else /* CONFIG_X86_32 */ | ||
131 | |||
132 | #include <asm/processor.h> | ||
133 | |||
134 | /* | ||
135 | * This is used to ensure we don't load something for the wrong architecture. | ||
136 | */ | ||
137 | #define elf_check_arch(x) \ | ||
138 | ((x)->e_machine == EM_X86_64) | ||
139 | |||
140 | #define ELF_PLAT_INIT(_r, load_addr) do { \ | ||
141 | struct task_struct *cur = current; \ | ||
142 | (_r)->rbx = 0; (_r)->rcx = 0; (_r)->rdx = 0; \ | ||
143 | (_r)->rsi = 0; (_r)->rdi = 0; (_r)->rbp = 0; \ | ||
144 | (_r)->rax = 0; \ | ||
145 | (_r)->r8 = 0; \ | ||
146 | (_r)->r9 = 0; \ | ||
147 | (_r)->r10 = 0; \ | ||
148 | (_r)->r11 = 0; \ | ||
149 | (_r)->r12 = 0; \ | ||
150 | (_r)->r13 = 0; \ | ||
151 | (_r)->r14 = 0; \ | ||
152 | (_r)->r15 = 0; \ | ||
153 | cur->thread.fs = 0; cur->thread.gs = 0; \ | ||
154 | cur->thread.fsindex = 0; cur->thread.gsindex = 0; \ | ||
155 | cur->thread.ds = 0; cur->thread.es = 0; \ | ||
156 | clear_thread_flag(TIF_IA32); \ | ||
157 | } while (0) | ||
158 | |||
159 | /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is | ||
160 | now struct_user_regs, they are different). Assumes current is the process | ||
161 | getting dumped. */ | ||
162 | |||
163 | #define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ | ||
164 | unsigned v; \ | ||
165 | (pr_reg)[0] = (regs)->r15; \ | ||
166 | (pr_reg)[1] = (regs)->r14; \ | ||
167 | (pr_reg)[2] = (regs)->r13; \ | ||
168 | (pr_reg)[3] = (regs)->r12; \ | ||
169 | (pr_reg)[4] = (regs)->rbp; \ | ||
170 | (pr_reg)[5] = (regs)->rbx; \ | ||
171 | (pr_reg)[6] = (regs)->r11; \ | ||
172 | (pr_reg)[7] = (regs)->r10; \ | ||
173 | (pr_reg)[8] = (regs)->r9; \ | ||
174 | (pr_reg)[9] = (regs)->r8; \ | ||
175 | (pr_reg)[10] = (regs)->rax; \ | ||
176 | (pr_reg)[11] = (regs)->rcx; \ | ||
177 | (pr_reg)[12] = (regs)->rdx; \ | ||
178 | (pr_reg)[13] = (regs)->rsi; \ | ||
179 | (pr_reg)[14] = (regs)->rdi; \ | ||
180 | (pr_reg)[15] = (regs)->orig_rax; \ | ||
181 | (pr_reg)[16] = (regs)->rip; \ | ||
182 | (pr_reg)[17] = (regs)->cs; \ | ||
183 | (pr_reg)[18] = (regs)->eflags; \ | ||
184 | (pr_reg)[19] = (regs)->rsp; \ | ||
185 | (pr_reg)[20] = (regs)->ss; \ | ||
186 | (pr_reg)[21] = current->thread.fs; \ | ||
187 | (pr_reg)[22] = current->thread.gs; \ | ||
188 | asm("movl %%ds,%0" : "=r" (v)); (pr_reg)[23] = v; \ | ||
189 | asm("movl %%es,%0" : "=r" (v)); (pr_reg)[24] = v; \ | ||
190 | asm("movl %%fs,%0" : "=r" (v)); (pr_reg)[25] = v; \ | ||
191 | asm("movl %%gs,%0" : "=r" (v)); (pr_reg)[26] = v; \ | ||
192 | } while(0); | ||
193 | |||
194 | /* I'm not sure if we can use '-' here */ | ||
195 | #define ELF_PLATFORM ("x86_64") | ||
196 | extern void set_personality_64bit(void); | ||
197 | extern int vdso_enabled; | ||
198 | |||
199 | #endif /* !CONFIG_X86_32 */ | ||
200 | |||
201 | #define USE_ELF_CORE_DUMP | ||
202 | #define ELF_EXEC_PAGESIZE 4096 | ||
203 | |||
204 | /* This is the location that an ET_DYN program is loaded if exec'ed. Typical | ||
205 | use of this is to invoke "./ld.so someprog" to test out a new version of | ||
206 | the loader. We need to make sure that it is out of the way of the program | ||
207 | that it will "exec", and that there is sufficient room for the brk. */ | ||
208 | |||
209 | #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) | ||
210 | |||
211 | /* This yields a mask that user programs can use to figure out what | ||
212 | instruction set this CPU supports. This could be done in user space, | ||
213 | but it's not easy, and we've already done it here. */ | ||
214 | |||
215 | #define ELF_HWCAP (boot_cpu_data.x86_capability[0]) | ||
216 | |||
217 | /* This yields a string that ld.so will use to load implementation | ||
218 | specific libraries for optimization. This is more specific in | ||
219 | intent than poking at uname or /proc/cpuinfo. | ||
220 | |||
221 | For the moment, we have only optimizations for the Intel generations, | ||
222 | but that could change... */ | ||
223 | |||
224 | #define SET_PERSONALITY(ex, ibcs2) set_personality_64bit() | ||
225 | |||
226 | /* | ||
227 | * An executable for which elf_read_implies_exec() returns TRUE will | ||
228 | * have the READ_IMPLIES_EXEC personality flag set automatically. | ||
229 | */ | ||
230 | #define elf_read_implies_exec(ex, executable_stack) \ | ||
231 | (executable_stack != EXSTACK_DISABLE_X) | ||
232 | |||
233 | struct task_struct; | ||
234 | |||
235 | extern int dump_task_regs (struct task_struct *, elf_gregset_t *); | ||
236 | extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *); | ||
237 | |||
238 | #define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs) | ||
239 | #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs) | ||
240 | |||
241 | #ifdef CONFIG_X86_32 | ||
242 | extern int dump_task_extended_fpu (struct task_struct *, | ||
243 | struct user_fxsr_struct *); | ||
244 | #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) \ | ||
245 | dump_task_extended_fpu(tsk, elf_xfpregs) | ||
246 | #define ELF_CORE_XFPREG_TYPE NT_PRXFPREG | ||
247 | |||
248 | #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO)) | ||
249 | #define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso) | ||
250 | #define VDSO_PRELINK 0 | ||
251 | |||
252 | #define VDSO_SYM(x) \ | ||
253 | (VDSO_CURRENT_BASE + (unsigned long)(x) - VDSO_PRELINK) | ||
254 | |||
255 | #define VDSO_HIGH_EHDR ((const struct elfhdr *) VDSO_HIGH_BASE) | ||
256 | #define VDSO_EHDR ((const struct elfhdr *) VDSO_CURRENT_BASE) | ||
257 | |||
258 | extern void __kernel_vsyscall; | ||
259 | |||
260 | #define VDSO_ENTRY VDSO_SYM(&__kernel_vsyscall) | ||
261 | |||
262 | /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ | ||
263 | |||
264 | #define ARCH_DLINFO \ | ||
265 | do if (vdso_enabled) { \ | ||
266 | NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ | ||
267 | NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \ | ||
268 | } while (0) | ||
269 | |||
270 | #else /* CONFIG_X86_32 */ | ||
271 | |||
272 | /* 1GB for 64bit, 8MB for 32bit */ | ||
273 | #define STACK_RND_MASK (test_thread_flag(TIF_IA32) ? 0x7ff : 0x3fffff) | ||
274 | |||
275 | #define ARCH_DLINFO \ | ||
276 | do if (vdso_enabled) { \ | ||
277 | NEW_AUX_ENT(AT_SYSINFO_EHDR,(unsigned long)current->mm->context.vdso);\ | ||
278 | } while (0) | ||
279 | |||
280 | #endif /* !CONFIG_X86_32 */ | ||
281 | |||
282 | struct linux_binprm; | ||
283 | |||
284 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 | ||
285 | extern int arch_setup_additional_pages(struct linux_binprm *bprm, | ||
286 | int executable_stack); | ||
287 | |||
288 | #endif /* __KERNEL__ */ | ||
289 | |||
13 | #endif | 290 | #endif |
diff --git a/include/asm-x86/elf_32.h b/include/asm-x86/elf_32.h deleted file mode 100644 index b3f694eaaf37..000000000000 --- a/include/asm-x86/elf_32.h +++ /dev/null | |||
@@ -1,165 +0,0 @@ | |||
1 | #ifndef __ASMi386_ELF_H | ||
2 | #define __ASMi386_ELF_H | ||
3 | |||
4 | /* | ||
5 | * ELF register definitions.. | ||
6 | */ | ||
7 | |||
8 | #include <asm/ptrace.h> | ||
9 | #include <asm/user.h> | ||
10 | #include <asm/auxvec.h> | ||
11 | |||
12 | #define R_386_NONE 0 | ||
13 | #define R_386_32 1 | ||
14 | #define R_386_PC32 2 | ||
15 | #define R_386_GOT32 3 | ||
16 | #define R_386_PLT32 4 | ||
17 | #define R_386_COPY 5 | ||
18 | #define R_386_GLOB_DAT 6 | ||
19 | #define R_386_JMP_SLOT 7 | ||
20 | #define R_386_RELATIVE 8 | ||
21 | #define R_386_GOTOFF 9 | ||
22 | #define R_386_GOTPC 10 | ||
23 | #define R_386_NUM 11 | ||
24 | |||
25 | typedef unsigned long elf_greg_t; | ||
26 | |||
27 | #define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) | ||
28 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | ||
29 | |||
30 | typedef struct user_i387_struct elf_fpregset_t; | ||
31 | typedef struct user_fxsr_struct elf_fpxregset_t; | ||
32 | |||
33 | /* | ||
34 | * This is used to ensure we don't load something for the wrong architecture. | ||
35 | */ | ||
36 | #define elf_check_arch(x) \ | ||
37 | (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486)) | ||
38 | |||
39 | /* | ||
40 | * These are used to set parameters in the core dumps. | ||
41 | */ | ||
42 | #define ELF_CLASS ELFCLASS32 | ||
43 | #define ELF_DATA ELFDATA2LSB | ||
44 | #define ELF_ARCH EM_386 | ||
45 | |||
46 | #ifdef __KERNEL__ | ||
47 | |||
48 | #include <asm/processor.h> | ||
49 | #include <asm/system.h> /* for savesegment */ | ||
50 | #include <asm/desc.h> | ||
51 | |||
52 | /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edx | ||
53 | contains a pointer to a function which might be registered using `atexit'. | ||
54 | This provides a mean for the dynamic linker to call DT_FINI functions for | ||
55 | shared libraries that have been loaded before the code runs. | ||
56 | |||
57 | A value of 0 tells we have no such handler. | ||
58 | |||
59 | We might as well make sure everything else is cleared too (except for %esp), | ||
60 | just to make things more deterministic. | ||
61 | */ | ||
62 | #define ELF_PLAT_INIT(_r, load_addr) do { \ | ||
63 | _r->ebx = 0; _r->ecx = 0; _r->edx = 0; \ | ||
64 | _r->esi = 0; _r->edi = 0; _r->ebp = 0; \ | ||
65 | _r->eax = 0; \ | ||
66 | } while (0) | ||
67 | |||
68 | #define USE_ELF_CORE_DUMP | ||
69 | #define ELF_EXEC_PAGESIZE 4096 | ||
70 | |||
71 | /* This is the location that an ET_DYN program is loaded if exec'ed. Typical | ||
72 | use of this is to invoke "./ld.so someprog" to test out a new version of | ||
73 | the loader. We need to make sure that it is out of the way of the program | ||
74 | that it will "exec", and that there is sufficient room for the brk. */ | ||
75 | |||
76 | #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) | ||
77 | |||
78 | /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is | ||
79 | now struct_user_regs, they are different) */ | ||
80 | |||
81 | #define ELF_CORE_COPY_REGS(pr_reg, regs) \ | ||
82 | pr_reg[0] = regs->ebx; \ | ||
83 | pr_reg[1] = regs->ecx; \ | ||
84 | pr_reg[2] = regs->edx; \ | ||
85 | pr_reg[3] = regs->esi; \ | ||
86 | pr_reg[4] = regs->edi; \ | ||
87 | pr_reg[5] = regs->ebp; \ | ||
88 | pr_reg[6] = regs->eax; \ | ||
89 | pr_reg[7] = regs->xds & 0xffff; \ | ||
90 | pr_reg[8] = regs->xes & 0xffff; \ | ||
91 | pr_reg[9] = regs->xfs & 0xffff; \ | ||
92 | savesegment(gs,pr_reg[10]); \ | ||
93 | pr_reg[11] = regs->orig_eax; \ | ||
94 | pr_reg[12] = regs->eip; \ | ||
95 | pr_reg[13] = regs->xcs & 0xffff; \ | ||
96 | pr_reg[14] = regs->eflags; \ | ||
97 | pr_reg[15] = regs->esp; \ | ||
98 | pr_reg[16] = regs->xss & 0xffff; | ||
99 | |||
100 | /* This yields a mask that user programs can use to figure out what | ||
101 | instruction set this CPU supports. This could be done in user space, | ||
102 | but it's not easy, and we've already done it here. */ | ||
103 | |||
104 | #define ELF_HWCAP (boot_cpu_data.x86_capability[0]) | ||
105 | |||
106 | /* This yields a string that ld.so will use to load implementation | ||
107 | specific libraries for optimization. This is more specific in | ||
108 | intent than poking at uname or /proc/cpuinfo. | ||
109 | |||
110 | For the moment, we have only optimizations for the Intel generations, | ||
111 | but that could change... */ | ||
112 | |||
113 | #define ELF_PLATFORM (utsname()->machine) | ||
114 | |||
115 | #define SET_PERSONALITY(ex, ibcs2) do { } while (0) | ||
116 | |||
117 | /* | ||
118 | * An executable for which elf_read_implies_exec() returns TRUE will | ||
119 | * have the READ_IMPLIES_EXEC personality flag set automatically. | ||
120 | */ | ||
121 | #define elf_read_implies_exec(ex, executable_stack) (executable_stack != EXSTACK_DISABLE_X) | ||
122 | |||
123 | struct task_struct; | ||
124 | |||
125 | extern int dump_task_regs (struct task_struct *, elf_gregset_t *); | ||
126 | extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *); | ||
127 | extern int dump_task_extended_fpu (struct task_struct *, struct user_fxsr_struct *); | ||
128 | |||
129 | #define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs) | ||
130 | #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs) | ||
131 | #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs) | ||
132 | #define ELF_CORE_XFPREG_TYPE NT_PRXFPREG | ||
133 | |||
134 | #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO)) | ||
135 | #define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso) | ||
136 | #define VDSO_PRELINK 0 | ||
137 | |||
138 | #define VDSO_SYM(x) \ | ||
139 | (VDSO_CURRENT_BASE + (unsigned long)(x) - VDSO_PRELINK) | ||
140 | |||
141 | #define VDSO_HIGH_EHDR ((const struct elfhdr *) VDSO_HIGH_BASE) | ||
142 | #define VDSO_EHDR ((const struct elfhdr *) VDSO_CURRENT_BASE) | ||
143 | |||
144 | extern void __kernel_vsyscall; | ||
145 | |||
146 | #define VDSO_ENTRY VDSO_SYM(&__kernel_vsyscall) | ||
147 | |||
148 | struct linux_binprm; | ||
149 | |||
150 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES | ||
151 | extern int arch_setup_additional_pages(struct linux_binprm *bprm, | ||
152 | int executable_stack); | ||
153 | |||
154 | extern unsigned int vdso_enabled; | ||
155 | |||
156 | /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ | ||
157 | #define ARCH_DLINFO \ | ||
158 | do if (vdso_enabled) { \ | ||
159 | NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ | ||
160 | NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \ | ||
161 | } while (0) | ||
162 | |||
163 | #endif | ||
164 | |||
165 | #endif | ||
diff --git a/include/asm-x86/elf_64.h b/include/asm-x86/elf_64.h deleted file mode 100644 index b4fbe47f6ccd..000000000000 --- a/include/asm-x86/elf_64.h +++ /dev/null | |||
@@ -1,180 +0,0 @@ | |||
1 | #ifndef __ASM_X86_64_ELF_H | ||
2 | #define __ASM_X86_64_ELF_H | ||
3 | |||
4 | /* | ||
5 | * ELF register definitions.. | ||
6 | */ | ||
7 | |||
8 | #include <asm/ptrace.h> | ||
9 | #include <asm/user.h> | ||
10 | |||
11 | /* x86-64 relocation types */ | ||
12 | #define R_X86_64_NONE 0 /* No reloc */ | ||
13 | #define R_X86_64_64 1 /* Direct 64 bit */ | ||
14 | #define R_X86_64_PC32 2 /* PC relative 32 bit signed */ | ||
15 | #define R_X86_64_GOT32 3 /* 32 bit GOT entry */ | ||
16 | #define R_X86_64_PLT32 4 /* 32 bit PLT address */ | ||
17 | #define R_X86_64_COPY 5 /* Copy symbol at runtime */ | ||
18 | #define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ | ||
19 | #define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ | ||
20 | #define R_X86_64_RELATIVE 8 /* Adjust by program base */ | ||
21 | #define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative | ||
22 | offset to GOT */ | ||
23 | #define R_X86_64_32 10 /* Direct 32 bit zero extended */ | ||
24 | #define R_X86_64_32S 11 /* Direct 32 bit sign extended */ | ||
25 | #define R_X86_64_16 12 /* Direct 16 bit zero extended */ | ||
26 | #define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ | ||
27 | #define R_X86_64_8 14 /* Direct 8 bit sign extended */ | ||
28 | #define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ | ||
29 | |||
30 | #define R_X86_64_NUM 16 | ||
31 | |||
32 | typedef unsigned long elf_greg_t; | ||
33 | |||
34 | #define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) | ||
35 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | ||
36 | |||
37 | typedef struct user_i387_struct elf_fpregset_t; | ||
38 | |||
39 | /* | ||
40 | * These are used to set parameters in the core dumps. | ||
41 | */ | ||
42 | #define ELF_CLASS ELFCLASS64 | ||
43 | #define ELF_DATA ELFDATA2LSB | ||
44 | #define ELF_ARCH EM_X86_64 | ||
45 | |||
46 | #ifdef __KERNEL__ | ||
47 | #include <asm/processor.h> | ||
48 | |||
49 | /* | ||
50 | * This is used to ensure we don't load something for the wrong architecture. | ||
51 | */ | ||
52 | #define elf_check_arch(x) \ | ||
53 | ((x)->e_machine == EM_X86_64) | ||
54 | |||
55 | |||
56 | /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edx | ||
57 | contains a pointer to a function which might be registered using `atexit'. | ||
58 | This provides a mean for the dynamic linker to call DT_FINI functions for | ||
59 | shared libraries that have been loaded before the code runs. | ||
60 | |||
61 | A value of 0 tells we have no such handler. | ||
62 | |||
63 | We might as well make sure everything else is cleared too (except for %esp), | ||
64 | just to make things more deterministic. | ||
65 | */ | ||
66 | #define ELF_PLAT_INIT(_r, load_addr) do { \ | ||
67 | struct task_struct *cur = current; \ | ||
68 | (_r)->rbx = 0; (_r)->rcx = 0; (_r)->rdx = 0; \ | ||
69 | (_r)->rsi = 0; (_r)->rdi = 0; (_r)->rbp = 0; \ | ||
70 | (_r)->rax = 0; \ | ||
71 | (_r)->r8 = 0; \ | ||
72 | (_r)->r9 = 0; \ | ||
73 | (_r)->r10 = 0; \ | ||
74 | (_r)->r11 = 0; \ | ||
75 | (_r)->r12 = 0; \ | ||
76 | (_r)->r13 = 0; \ | ||
77 | (_r)->r14 = 0; \ | ||
78 | (_r)->r15 = 0; \ | ||
79 | cur->thread.fs = 0; cur->thread.gs = 0; \ | ||
80 | cur->thread.fsindex = 0; cur->thread.gsindex = 0; \ | ||
81 | cur->thread.ds = 0; cur->thread.es = 0; \ | ||
82 | clear_thread_flag(TIF_IA32); \ | ||
83 | } while (0) | ||
84 | |||
85 | #define USE_ELF_CORE_DUMP | ||
86 | #define ELF_EXEC_PAGESIZE 4096 | ||
87 | |||
88 | /* This is the location that an ET_DYN program is loaded if exec'ed. Typical | ||
89 | use of this is to invoke "./ld.so someprog" to test out a new version of | ||
90 | the loader. We need to make sure that it is out of the way of the program | ||
91 | that it will "exec", and that there is sufficient room for the brk. */ | ||
92 | |||
93 | #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) | ||
94 | |||
95 | /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is | ||
96 | now struct_user_regs, they are different). Assumes current is the process | ||
97 | getting dumped. */ | ||
98 | |||
99 | #define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ | ||
100 | unsigned v; \ | ||
101 | (pr_reg)[0] = (regs)->r15; \ | ||
102 | (pr_reg)[1] = (regs)->r14; \ | ||
103 | (pr_reg)[2] = (regs)->r13; \ | ||
104 | (pr_reg)[3] = (regs)->r12; \ | ||
105 | (pr_reg)[4] = (regs)->rbp; \ | ||
106 | (pr_reg)[5] = (regs)->rbx; \ | ||
107 | (pr_reg)[6] = (regs)->r11; \ | ||
108 | (pr_reg)[7] = (regs)->r10; \ | ||
109 | (pr_reg)[8] = (regs)->r9; \ | ||
110 | (pr_reg)[9] = (regs)->r8; \ | ||
111 | (pr_reg)[10] = (regs)->rax; \ | ||
112 | (pr_reg)[11] = (regs)->rcx; \ | ||
113 | (pr_reg)[12] = (regs)->rdx; \ | ||
114 | (pr_reg)[13] = (regs)->rsi; \ | ||
115 | (pr_reg)[14] = (regs)->rdi; \ | ||
116 | (pr_reg)[15] = (regs)->orig_rax; \ | ||
117 | (pr_reg)[16] = (regs)->rip; \ | ||
118 | (pr_reg)[17] = (regs)->cs; \ | ||
119 | (pr_reg)[18] = (regs)->eflags; \ | ||
120 | (pr_reg)[19] = (regs)->rsp; \ | ||
121 | (pr_reg)[20] = (regs)->ss; \ | ||
122 | (pr_reg)[21] = current->thread.fs; \ | ||
123 | (pr_reg)[22] = current->thread.gs; \ | ||
124 | asm("movl %%ds,%0" : "=r" (v)); (pr_reg)[23] = v; \ | ||
125 | asm("movl %%es,%0" : "=r" (v)); (pr_reg)[24] = v; \ | ||
126 | asm("movl %%fs,%0" : "=r" (v)); (pr_reg)[25] = v; \ | ||
127 | asm("movl %%gs,%0" : "=r" (v)); (pr_reg)[26] = v; \ | ||
128 | } while(0); | ||
129 | |||
130 | /* This yields a mask that user programs can use to figure out what | ||
131 | instruction set this CPU supports. This could be done in user space, | ||
132 | but it's not easy, and we've already done it here. */ | ||
133 | |||
134 | #define ELF_HWCAP (boot_cpu_data.x86_capability[0]) | ||
135 | |||
136 | /* This yields a string that ld.so will use to load implementation | ||
137 | specific libraries for optimization. This is more specific in | ||
138 | intent than poking at uname or /proc/cpuinfo. | ||
139 | |||
140 | For the moment, we have only optimizations for the Intel generations, | ||
141 | but that could change... */ | ||
142 | |||
143 | /* I'm not sure if we can use '-' here */ | ||
144 | #define ELF_PLATFORM ("x86_64") | ||
145 | |||
146 | extern void set_personality_64bit(void); | ||
147 | #define SET_PERSONALITY(ex, ibcs2) set_personality_64bit() | ||
148 | /* | ||
149 | * An executable for which elf_read_implies_exec() returns TRUE will | ||
150 | * have the READ_IMPLIES_EXEC personality flag set automatically. | ||
151 | */ | ||
152 | #define elf_read_implies_exec(ex, executable_stack) (executable_stack != EXSTACK_DISABLE_X) | ||
153 | |||
154 | struct task_struct; | ||
155 | |||
156 | extern int dump_task_regs (struct task_struct *, elf_gregset_t *); | ||
157 | extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *); | ||
158 | |||
159 | #define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs) | ||
160 | #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs) | ||
161 | |||
162 | /* 1GB for 64bit, 8MB for 32bit */ | ||
163 | #define STACK_RND_MASK (test_thread_flag(TIF_IA32) ? 0x7ff : 0x3fffff) | ||
164 | |||
165 | |||
166 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 | ||
167 | struct linux_binprm; | ||
168 | extern int arch_setup_additional_pages(struct linux_binprm *bprm, | ||
169 | int executable_stack); | ||
170 | |||
171 | extern int vdso_enabled; | ||
172 | |||
173 | #define ARCH_DLINFO \ | ||
174 | do if (vdso_enabled) { \ | ||
175 | NEW_AUX_ENT(AT_SYSINFO_EHDR,(unsigned long)current->mm->context.vdso);\ | ||
176 | } while (0) | ||
177 | |||
178 | #endif | ||
179 | |||
180 | #endif | ||
diff --git a/include/asm-x86/mmu.h b/include/asm-x86/mmu.h index 9c628cd70e23..3f922c8e1c88 100644 --- a/include/asm-x86/mmu.h +++ b/include/asm-x86/mmu.h | |||
@@ -1,5 +1,23 @@ | |||
1 | #ifdef CONFIG_X86_32 | 1 | #ifndef _ASM_X86_MMU_H |
2 | # include "mmu_32.h" | 2 | #define _ASM_X86_MMU_H |
3 | #else | 3 | |
4 | # include "mmu_64.h" | 4 | #include <linux/spinlock.h> |
5 | #include <linux/mutex.h> | ||
6 | |||
7 | /* | ||
8 | * The x86 doesn't have a mmu context, but | ||
9 | * we put the segment information here. | ||
10 | * | ||
11 | * cpu_vm_mask is used to optimize ldt flushing. | ||
12 | */ | ||
13 | typedef struct { | ||
14 | void *ldt; | ||
15 | #ifdef CONFIG_X86_64 | ||
16 | rwlock_t ldtlock; | ||
5 | #endif | 17 | #endif |
18 | int size; | ||
19 | struct mutex lock; | ||
20 | void *vdso; | ||
21 | } mm_context_t; | ||
22 | |||
23 | #endif /* _ASM_X86_MMU_H */ | ||
diff --git a/include/asm-x86/mmu_32.h b/include/asm-x86/mmu_32.h deleted file mode 100644 index 5e249c51ef56..000000000000 --- a/include/asm-x86/mmu_32.h +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | #ifndef __i386_MMU_H | ||
2 | #define __i386_MMU_H | ||
3 | |||
4 | #include <linux/mutex.h> | ||
5 | /* | ||
6 | * The i386 doesn't have a mmu context, but | ||
7 | * we put the segment information here. | ||
8 | * | ||
9 | * cpu_vm_mask is used to optimize ldt flushing. | ||
10 | */ | ||
11 | typedef struct { | ||
12 | int size; | ||
13 | struct mutex lock; | ||
14 | void *ldt; | ||
15 | void *vdso; | ||
16 | } mm_context_t; | ||
17 | |||
18 | #endif | ||
diff --git a/include/asm-x86/mmu_64.h b/include/asm-x86/mmu_64.h deleted file mode 100644 index 024357c27222..000000000000 --- a/include/asm-x86/mmu_64.h +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | #ifndef __x86_64_MMU_H | ||
2 | #define __x86_64_MMU_H | ||
3 | |||
4 | #include <linux/spinlock.h> | ||
5 | #include <linux/mutex.h> | ||
6 | |||
7 | /* | ||
8 | * The x86_64 doesn't have a mmu context, but | ||
9 | * we put the segment information here. | ||
10 | * | ||
11 | * cpu_vm_mask is used to optimize ldt flushing. | ||
12 | */ | ||
13 | typedef struct { | ||
14 | void *ldt; | ||
15 | rwlock_t ldtlock; | ||
16 | int size; | ||
17 | struct mutex lock; | ||
18 | void *vdso; | ||
19 | } mm_context_t; | ||
20 | |||
21 | #endif | ||
diff --git a/include/asm-x86/msgbuf.h b/include/asm-x86/msgbuf.h index 154f7d64e862..7e4e9481f51c 100644 --- a/include/asm-x86/msgbuf.h +++ b/include/asm-x86/msgbuf.h | |||
@@ -1,13 +1,39 @@ | |||
1 | #ifdef __KERNEL__ | 1 | #ifndef _ASM_X86_MSGBUF_H |
2 | # ifdef CONFIG_X86_32 | 2 | #define _ASM_X86_MSGBUF_H |
3 | # include "msgbuf_32.h" | 3 | |
4 | # else | 4 | /* |
5 | # include "msgbuf_64.h" | 5 | * The msqid64_ds structure for i386 architecture. |
6 | # endif | 6 | * Note extra padding because this structure is passed back and forth |
7 | #else | 7 | * between kernel and user space. |
8 | # ifdef __i386__ | 8 | * |
9 | # include "msgbuf_32.h" | 9 | * Pad space on i386 is left for: |
10 | # else | 10 | * - 64-bit time_t to solve y2038 problem |
11 | # include "msgbuf_64.h" | 11 | * - 2 miscellaneous 32-bit values |
12 | # endif | 12 | * |
13 | * Pad space on x8664 is left for: | ||
14 | * - 2 miscellaneous 64-bit values | ||
15 | */ | ||
16 | struct msqid64_ds { | ||
17 | struct ipc64_perm msg_perm; | ||
18 | __kernel_time_t msg_stime; /* last msgsnd time */ | ||
19 | #ifdef __i386__ | ||
20 | unsigned long __unused1; | ||
13 | #endif | 21 | #endif |
22 | __kernel_time_t msg_rtime; /* last msgrcv time */ | ||
23 | #ifdef __i386__ | ||
24 | unsigned long __unused2; | ||
25 | #endif | ||
26 | __kernel_time_t msg_ctime; /* last change time */ | ||
27 | #ifdef __i386__ | ||
28 | unsigned long __unused3; | ||
29 | #endif | ||
30 | unsigned long msg_cbytes; /* current number of bytes on queue */ | ||
31 | unsigned long msg_qnum; /* number of messages in queue */ | ||
32 | unsigned long msg_qbytes; /* max number of bytes on queue */ | ||
33 | __kernel_pid_t msg_lspid; /* pid of last msgsnd */ | ||
34 | __kernel_pid_t msg_lrpid; /* last receive pid */ | ||
35 | unsigned long __unused4; | ||
36 | unsigned long __unused5; | ||
37 | }; | ||
38 | |||
39 | #endif /* _ASM_X86_MSGBUF_H */ | ||
diff --git a/include/asm-x86/msgbuf_32.h b/include/asm-x86/msgbuf_32.h deleted file mode 100644 index b8d659c157ae..000000000000 --- a/include/asm-x86/msgbuf_32.h +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | #ifndef _I386_MSGBUF_H | ||
2 | #define _I386_MSGBUF_H | ||
3 | |||
4 | /* | ||
5 | * The msqid64_ds structure for i386 architecture. | ||
6 | * Note extra padding because this structure is passed back and forth | ||
7 | * between kernel and user space. | ||
8 | * | ||
9 | * Pad space is left for: | ||
10 | * - 64-bit time_t to solve y2038 problem | ||
11 | * - 2 miscellaneous 32-bit values | ||
12 | */ | ||
13 | |||
14 | struct msqid64_ds { | ||
15 | struct ipc64_perm msg_perm; | ||
16 | __kernel_time_t msg_stime; /* last msgsnd time */ | ||
17 | unsigned long __unused1; | ||
18 | __kernel_time_t msg_rtime; /* last msgrcv time */ | ||
19 | unsigned long __unused2; | ||
20 | __kernel_time_t msg_ctime; /* last change time */ | ||
21 | unsigned long __unused3; | ||
22 | unsigned long msg_cbytes; /* current number of bytes on queue */ | ||
23 | unsigned long msg_qnum; /* number of messages in queue */ | ||
24 | unsigned long msg_qbytes; /* max number of bytes on queue */ | ||
25 | __kernel_pid_t msg_lspid; /* pid of last msgsnd */ | ||
26 | __kernel_pid_t msg_lrpid; /* last receive pid */ | ||
27 | unsigned long __unused4; | ||
28 | unsigned long __unused5; | ||
29 | }; | ||
30 | |||
31 | #endif /* _I386_MSGBUF_H */ | ||
diff --git a/include/asm-x86/msgbuf_64.h b/include/asm-x86/msgbuf_64.h deleted file mode 100644 index cd6f95dd54da..000000000000 --- a/include/asm-x86/msgbuf_64.h +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | #ifndef _X8664_MSGBUF_H | ||
2 | #define _X8664_MSGBUF_H | ||
3 | |||
4 | /* | ||
5 | * The msqid64_ds structure for x86-64 architecture. | ||
6 | * Note extra padding because this structure is passed back and forth | ||
7 | * between kernel and user space. | ||
8 | * | ||
9 | * Pad space is left for: | ||
10 | * - 2 miscellaneous 64-bit values | ||
11 | */ | ||
12 | |||
13 | struct msqid64_ds { | ||
14 | struct ipc64_perm msg_perm; | ||
15 | __kernel_time_t msg_stime; /* last msgsnd time */ | ||
16 | __kernel_time_t msg_rtime; /* last msgrcv time */ | ||
17 | __kernel_time_t msg_ctime; /* last change time */ | ||
18 | unsigned long msg_cbytes; /* current number of bytes on queue */ | ||
19 | unsigned long msg_qnum; /* number of messages in queue */ | ||
20 | unsigned long msg_qbytes; /* max number of bytes on queue */ | ||
21 | __kernel_pid_t msg_lspid; /* pid of last msgsnd */ | ||
22 | __kernel_pid_t msg_lrpid; /* last receive pid */ | ||
23 | unsigned long __unused4; | ||
24 | unsigned long __unused5; | ||
25 | }; | ||
26 | |||
27 | #endif | ||
diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index 2f87ce007002..ba4b31432120 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h | |||
@@ -1,13 +1,350 @@ | |||
1 | #ifndef __ASM_X86_MSR_H_ | ||
2 | #define __ASM_X86_MSR_H_ | ||
3 | |||
4 | #include <asm/msr-index.h> | ||
5 | |||
6 | #ifdef __i386__ | ||
7 | |||
1 | #ifdef __KERNEL__ | 8 | #ifdef __KERNEL__ |
2 | # ifdef CONFIG_X86_32 | 9 | #ifndef __ASSEMBLY__ |
3 | # include "msr_32.h" | 10 | |
4 | # else | 11 | #include <asm/errno.h> |
5 | # include "msr_64.h" | 12 | |
6 | # endif | 13 | static inline unsigned long long native_read_msr(unsigned int msr) |
14 | { | ||
15 | unsigned long long val; | ||
16 | |||
17 | asm volatile("rdmsr" : "=A" (val) : "c" (msr)); | ||
18 | return val; | ||
19 | } | ||
20 | |||
21 | static inline unsigned long long native_read_msr_safe(unsigned int msr, | ||
22 | int *err) | ||
23 | { | ||
24 | unsigned long long val; | ||
25 | |||
26 | asm volatile("2: rdmsr ; xorl %0,%0\n" | ||
27 | "1:\n\t" | ||
28 | ".section .fixup,\"ax\"\n\t" | ||
29 | "3: movl %3,%0 ; jmp 1b\n\t" | ||
30 | ".previous\n\t" | ||
31 | ".section __ex_table,\"a\"\n" | ||
32 | " .align 4\n\t" | ||
33 | " .long 2b,3b\n\t" | ||
34 | ".previous" | ||
35 | : "=r" (*err), "=A" (val) | ||
36 | : "c" (msr), "i" (-EFAULT)); | ||
37 | |||
38 | return val; | ||
39 | } | ||
40 | |||
41 | static inline void native_write_msr(unsigned int msr, unsigned long long val) | ||
42 | { | ||
43 | asm volatile("wrmsr" : : "c" (msr), "A"(val)); | ||
44 | } | ||
45 | |||
46 | static inline int native_write_msr_safe(unsigned int msr, | ||
47 | unsigned long long val) | ||
48 | { | ||
49 | int err; | ||
50 | asm volatile("2: wrmsr ; xorl %0,%0\n" | ||
51 | "1:\n\t" | ||
52 | ".section .fixup,\"ax\"\n\t" | ||
53 | "3: movl %4,%0 ; jmp 1b\n\t" | ||
54 | ".previous\n\t" | ||
55 | ".section __ex_table,\"a\"\n" | ||
56 | " .align 4\n\t" | ||
57 | " .long 2b,3b\n\t" | ||
58 | ".previous" | ||
59 | : "=a" (err) | ||
60 | : "c" (msr), "0" ((u32)val), "d" ((u32)(val>>32)), | ||
61 | "i" (-EFAULT)); | ||
62 | return err; | ||
63 | } | ||
64 | |||
65 | static inline unsigned long long native_read_tsc(void) | ||
66 | { | ||
67 | unsigned long long val; | ||
68 | asm volatile("rdtsc" : "=A" (val)); | ||
69 | return val; | ||
70 | } | ||
71 | |||
72 | static inline unsigned long long native_read_pmc(void) | ||
73 | { | ||
74 | unsigned long long val; | ||
75 | asm volatile("rdpmc" : "=A" (val)); | ||
76 | return val; | ||
77 | } | ||
78 | |||
79 | #ifdef CONFIG_PARAVIRT | ||
80 | #include <asm/paravirt.h> | ||
7 | #else | 81 | #else |
8 | # ifdef __i386__ | 82 | #include <linux/errno.h> |
9 | # include "msr_32.h" | 83 | /* |
10 | # else | 84 | * Access to machine-specific registers (available on 586 and better only) |
11 | # include "msr_64.h" | 85 | * Note: the rd* operations modify the parameters directly (without using |
12 | # endif | 86 | * pointer indirection), this allows gcc to optimize better |
87 | */ | ||
88 | |||
89 | #define rdmsr(msr,val1,val2) \ | ||
90 | do { \ | ||
91 | u64 __val = native_read_msr(msr); \ | ||
92 | (val1) = (u32)__val; \ | ||
93 | (val2) = (u32)(__val >> 32); \ | ||
94 | } while(0) | ||
95 | |||
96 | static inline void wrmsr(u32 __msr, u32 __low, u32 __high) | ||
97 | { | ||
98 | native_write_msr(__msr, ((u64)__high << 32) | __low); | ||
99 | } | ||
100 | |||
101 | #define rdmsrl(msr,val) \ | ||
102 | ((val) = native_read_msr(msr)) | ||
103 | |||
104 | #define wrmsrl(msr,val) native_write_msr(msr, val) | ||
105 | |||
106 | /* wrmsr with exception handling */ | ||
107 | static inline int wrmsr_safe(u32 __msr, u32 __low, u32 __high) | ||
108 | { | ||
109 | return native_write_msr_safe(__msr, ((u64)__high << 32) | __low); | ||
110 | } | ||
111 | |||
112 | /* rdmsr with exception handling */ | ||
113 | #define rdmsr_safe(msr,p1,p2) \ | ||
114 | ({ \ | ||
115 | int __err; \ | ||
116 | u64 __val = native_read_msr_safe(msr, &__err); \ | ||
117 | (*p1) = (u32)__val; \ | ||
118 | (*p2) = (u32)(__val >> 32); \ | ||
119 | __err; \ | ||
120 | }) | ||
121 | |||
122 | #define rdtscl(low) \ | ||
123 | ((low) = (u32)native_read_tsc()) | ||
124 | |||
125 | #define rdtscll(val) \ | ||
126 | ((val) = native_read_tsc()) | ||
127 | |||
128 | #define write_tsc(val1,val2) wrmsr(0x10, val1, val2) | ||
129 | |||
130 | #define rdpmc(counter,low,high) \ | ||
131 | do { \ | ||
132 | u64 _l = native_read_pmc(); \ | ||
133 | (low) = (u32)_l; \ | ||
134 | (high) = (u32)(_l >> 32); \ | ||
135 | } while(0) | ||
136 | #endif /* !CONFIG_PARAVIRT */ | ||
137 | |||
138 | #ifdef CONFIG_SMP | ||
139 | void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); | ||
140 | void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); | ||
141 | int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); | ||
142 | int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); | ||
143 | #else /* CONFIG_SMP */ | ||
144 | static inline void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) | ||
145 | { | ||
146 | rdmsr(msr_no, *l, *h); | ||
147 | } | ||
148 | static inline void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) | ||
149 | { | ||
150 | wrmsr(msr_no, l, h); | ||
151 | } | ||
152 | static inline int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) | ||
153 | { | ||
154 | return rdmsr_safe(msr_no, l, h); | ||
155 | } | ||
156 | static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) | ||
157 | { | ||
158 | return wrmsr_safe(msr_no, l, h); | ||
159 | } | ||
160 | #endif /* CONFIG_SMP */ | ||
161 | #endif /* ! __ASSEMBLY__ */ | ||
162 | #endif /* __KERNEL__ */ | ||
163 | |||
164 | #else /* __i386__ */ | ||
165 | |||
166 | #ifndef __ASSEMBLY__ | ||
167 | #include <linux/errno.h> | ||
168 | /* | ||
169 | * Access to machine-specific registers (available on 586 and better only) | ||
170 | * Note: the rd* operations modify the parameters directly (without using | ||
171 | * pointer indirection), this allows gcc to optimize better | ||
172 | */ | ||
173 | |||
174 | #define rdmsr(msr,val1,val2) \ | ||
175 | __asm__ __volatile__("rdmsr" \ | ||
176 | : "=a" (val1), "=d" (val2) \ | ||
177 | : "c" (msr)) | ||
178 | |||
179 | |||
180 | #define rdmsrl(msr,val) do { unsigned long a__,b__; \ | ||
181 | __asm__ __volatile__("rdmsr" \ | ||
182 | : "=a" (a__), "=d" (b__) \ | ||
183 | : "c" (msr)); \ | ||
184 | val = a__ | (b__<<32); \ | ||
185 | } while(0) | ||
186 | |||
187 | #define wrmsr(msr,val1,val2) \ | ||
188 | __asm__ __volatile__("wrmsr" \ | ||
189 | : /* no outputs */ \ | ||
190 | : "c" (msr), "a" (val1), "d" (val2)) | ||
191 | |||
192 | #define wrmsrl(msr,val) wrmsr(msr,(__u32)((__u64)(val)),((__u64)(val))>>32) | ||
193 | |||
194 | /* wrmsr with exception handling */ | ||
195 | #define wrmsr_safe(msr,a,b) ({ int ret__; \ | ||
196 | asm volatile("2: wrmsr ; xorl %0,%0\n" \ | ||
197 | "1:\n\t" \ | ||
198 | ".section .fixup,\"ax\"\n\t" \ | ||
199 | "3: movl %4,%0 ; jmp 1b\n\t" \ | ||
200 | ".previous\n\t" \ | ||
201 | ".section __ex_table,\"a\"\n" \ | ||
202 | " .align 8\n\t" \ | ||
203 | " .quad 2b,3b\n\t" \ | ||
204 | ".previous" \ | ||
205 | : "=a" (ret__) \ | ||
206 | : "c" (msr), "0" (a), "d" (b), "i" (-EFAULT)); \ | ||
207 | ret__; }) | ||
208 | |||
209 | #define checking_wrmsrl(msr,val) wrmsr_safe(msr,(u32)(val),(u32)((val)>>32)) | ||
210 | |||
211 | #define rdmsr_safe(msr,a,b) \ | ||
212 | ({ int ret__; \ | ||
213 | asm volatile ("1: rdmsr\n" \ | ||
214 | "2:\n" \ | ||
215 | ".section .fixup,\"ax\"\n" \ | ||
216 | "3: movl %4,%0\n" \ | ||
217 | " jmp 2b\n" \ | ||
218 | ".previous\n" \ | ||
219 | ".section __ex_table,\"a\"\n" \ | ||
220 | " .align 8\n" \ | ||
221 | " .quad 1b,3b\n" \ | ||
222 | ".previous":"=&bDS" (ret__), "=a"(*(a)), "=d"(*(b)) \ | ||
223 | :"c"(msr), "i"(-EIO), "0"(0)); \ | ||
224 | ret__; }) | ||
225 | |||
226 | #define rdtsc(low,high) \ | ||
227 | __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) | ||
228 | |||
229 | #define rdtscl(low) \ | ||
230 | __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx") | ||
231 | |||
232 | #define rdtscp(low,high,aux) \ | ||
233 | asm volatile (".byte 0x0f,0x01,0xf9" : "=a" (low), "=d" (high), "=c" (aux)) | ||
234 | |||
235 | #define rdtscll(val) do { \ | ||
236 | unsigned int __a,__d; \ | ||
237 | asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \ | ||
238 | (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \ | ||
239 | } while(0) | ||
240 | |||
241 | #define rdtscpll(val, aux) do { \ | ||
242 | unsigned long __a, __d; \ | ||
243 | asm volatile (".byte 0x0f,0x01,0xf9" : "=a" (__a), "=d" (__d), "=c" (aux)); \ | ||
244 | (val) = (__d << 32) | __a; \ | ||
245 | } while (0) | ||
246 | |||
247 | #define write_tsc(val1,val2) wrmsr(0x10, val1, val2) | ||
248 | |||
249 | #define write_rdtscp_aux(val) wrmsr(0xc0000103, val, 0) | ||
250 | |||
251 | #define rdpmc(counter,low,high) \ | ||
252 | __asm__ __volatile__("rdpmc" \ | ||
253 | : "=a" (low), "=d" (high) \ | ||
254 | : "c" (counter)) | ||
255 | |||
256 | static inline void cpuid(int op, unsigned int *eax, unsigned int *ebx, | ||
257 | unsigned int *ecx, unsigned int *edx) | ||
258 | { | ||
259 | __asm__("cpuid" | ||
260 | : "=a" (*eax), | ||
261 | "=b" (*ebx), | ||
262 | "=c" (*ecx), | ||
263 | "=d" (*edx) | ||
264 | : "0" (op)); | ||
265 | } | ||
266 | |||
267 | /* Some CPUID calls want 'count' to be placed in ecx */ | ||
268 | static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx, | ||
269 | int *edx) | ||
270 | { | ||
271 | __asm__("cpuid" | ||
272 | : "=a" (*eax), | ||
273 | "=b" (*ebx), | ||
274 | "=c" (*ecx), | ||
275 | "=d" (*edx) | ||
276 | : "0" (op), "c" (count)); | ||
277 | } | ||
278 | |||
279 | /* | ||
280 | * CPUID functions returning a single datum | ||
281 | */ | ||
282 | static inline unsigned int cpuid_eax(unsigned int op) | ||
283 | { | ||
284 | unsigned int eax; | ||
285 | |||
286 | __asm__("cpuid" | ||
287 | : "=a" (eax) | ||
288 | : "0" (op) | ||
289 | : "bx", "cx", "dx"); | ||
290 | return eax; | ||
291 | } | ||
292 | static inline unsigned int cpuid_ebx(unsigned int op) | ||
293 | { | ||
294 | unsigned int eax, ebx; | ||
295 | |||
296 | __asm__("cpuid" | ||
297 | : "=a" (eax), "=b" (ebx) | ||
298 | : "0" (op) | ||
299 | : "cx", "dx" ); | ||
300 | return ebx; | ||
301 | } | ||
302 | static inline unsigned int cpuid_ecx(unsigned int op) | ||
303 | { | ||
304 | unsigned int eax, ecx; | ||
305 | |||
306 | __asm__("cpuid" | ||
307 | : "=a" (eax), "=c" (ecx) | ||
308 | : "0" (op) | ||
309 | : "bx", "dx" ); | ||
310 | return ecx; | ||
311 | } | ||
312 | static inline unsigned int cpuid_edx(unsigned int op) | ||
313 | { | ||
314 | unsigned int eax, edx; | ||
315 | |||
316 | __asm__("cpuid" | ||
317 | : "=a" (eax), "=d" (edx) | ||
318 | : "0" (op) | ||
319 | : "bx", "cx"); | ||
320 | return edx; | ||
321 | } | ||
322 | |||
323 | #ifdef CONFIG_SMP | ||
324 | void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); | ||
325 | void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); | ||
326 | int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); | ||
327 | int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); | ||
328 | #else /* CONFIG_SMP */ | ||
329 | static inline void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) | ||
330 | { | ||
331 | rdmsr(msr_no, *l, *h); | ||
332 | } | ||
333 | static inline void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) | ||
334 | { | ||
335 | wrmsr(msr_no, l, h); | ||
336 | } | ||
337 | static inline int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) | ||
338 | { | ||
339 | return rdmsr_safe(msr_no, l, h); | ||
340 | } | ||
341 | static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) | ||
342 | { | ||
343 | return wrmsr_safe(msr_no, l, h); | ||
344 | } | ||
345 | #endif /* CONFIG_SMP */ | ||
346 | #endif /* __ASSEMBLY__ */ | ||
347 | |||
348 | #endif /* !__i386__ */ | ||
349 | |||
13 | #endif | 350 | #endif |
diff --git a/include/asm-x86/msr_32.h b/include/asm-x86/msr_32.h deleted file mode 100644 index df21ea049369..000000000000 --- a/include/asm-x86/msr_32.h +++ /dev/null | |||
@@ -1,161 +0,0 @@ | |||
1 | #ifndef __ASM_MSR_H | ||
2 | #define __ASM_MSR_H | ||
3 | |||
4 | #include <asm/msr-index.h> | ||
5 | |||
6 | #ifdef __KERNEL__ | ||
7 | #ifndef __ASSEMBLY__ | ||
8 | |||
9 | #include <asm/errno.h> | ||
10 | |||
11 | static inline unsigned long long native_read_msr(unsigned int msr) | ||
12 | { | ||
13 | unsigned long long val; | ||
14 | |||
15 | asm volatile("rdmsr" : "=A" (val) : "c" (msr)); | ||
16 | return val; | ||
17 | } | ||
18 | |||
19 | static inline unsigned long long native_read_msr_safe(unsigned int msr, | ||
20 | int *err) | ||
21 | { | ||
22 | unsigned long long val; | ||
23 | |||
24 | asm volatile("2: rdmsr ; xorl %0,%0\n" | ||
25 | "1:\n\t" | ||
26 | ".section .fixup,\"ax\"\n\t" | ||
27 | "3: movl %3,%0 ; jmp 1b\n\t" | ||
28 | ".previous\n\t" | ||
29 | ".section __ex_table,\"a\"\n" | ||
30 | " .align 4\n\t" | ||
31 | " .long 2b,3b\n\t" | ||
32 | ".previous" | ||
33 | : "=r" (*err), "=A" (val) | ||
34 | : "c" (msr), "i" (-EFAULT)); | ||
35 | |||
36 | return val; | ||
37 | } | ||
38 | |||
39 | static inline void native_write_msr(unsigned int msr, unsigned long long val) | ||
40 | { | ||
41 | asm volatile("wrmsr" : : "c" (msr), "A"(val)); | ||
42 | } | ||
43 | |||
44 | static inline int native_write_msr_safe(unsigned int msr, | ||
45 | unsigned long long val) | ||
46 | { | ||
47 | int err; | ||
48 | asm volatile("2: wrmsr ; xorl %0,%0\n" | ||
49 | "1:\n\t" | ||
50 | ".section .fixup,\"ax\"\n\t" | ||
51 | "3: movl %4,%0 ; jmp 1b\n\t" | ||
52 | ".previous\n\t" | ||
53 | ".section __ex_table,\"a\"\n" | ||
54 | " .align 4\n\t" | ||
55 | " .long 2b,3b\n\t" | ||
56 | ".previous" | ||
57 | : "=a" (err) | ||
58 | : "c" (msr), "0" ((u32)val), "d" ((u32)(val>>32)), | ||
59 | "i" (-EFAULT)); | ||
60 | return err; | ||
61 | } | ||
62 | |||
63 | static inline unsigned long long native_read_tsc(void) | ||
64 | { | ||
65 | unsigned long long val; | ||
66 | asm volatile("rdtsc" : "=A" (val)); | ||
67 | return val; | ||
68 | } | ||
69 | |||
70 | static inline unsigned long long native_read_pmc(void) | ||
71 | { | ||
72 | unsigned long long val; | ||
73 | asm volatile("rdpmc" : "=A" (val)); | ||
74 | return val; | ||
75 | } | ||
76 | |||
77 | #ifdef CONFIG_PARAVIRT | ||
78 | #include <asm/paravirt.h> | ||
79 | #else | ||
80 | #include <linux/errno.h> | ||
81 | /* | ||
82 | * Access to machine-specific registers (available on 586 and better only) | ||
83 | * Note: the rd* operations modify the parameters directly (without using | ||
84 | * pointer indirection), this allows gcc to optimize better | ||
85 | */ | ||
86 | |||
87 | #define rdmsr(msr,val1,val2) \ | ||
88 | do { \ | ||
89 | u64 __val = native_read_msr(msr); \ | ||
90 | (val1) = (u32)__val; \ | ||
91 | (val2) = (u32)(__val >> 32); \ | ||
92 | } while(0) | ||
93 | |||
94 | static inline void wrmsr(u32 __msr, u32 __low, u32 __high) | ||
95 | { | ||
96 | native_write_msr(__msr, ((u64)__high << 32) | __low); | ||
97 | } | ||
98 | |||
99 | #define rdmsrl(msr,val) \ | ||
100 | ((val) = native_read_msr(msr)) | ||
101 | |||
102 | #define wrmsrl(msr,val) native_write_msr(msr, val) | ||
103 | |||
104 | /* wrmsr with exception handling */ | ||
105 | static inline int wrmsr_safe(u32 __msr, u32 __low, u32 __high) | ||
106 | { | ||
107 | return native_write_msr_safe(__msr, ((u64)__high << 32) | __low); | ||
108 | } | ||
109 | |||
110 | /* rdmsr with exception handling */ | ||
111 | #define rdmsr_safe(msr,p1,p2) \ | ||
112 | ({ \ | ||
113 | int __err; \ | ||
114 | u64 __val = native_read_msr_safe(msr, &__err); \ | ||
115 | (*p1) = (u32)__val; \ | ||
116 | (*p2) = (u32)(__val >> 32); \ | ||
117 | __err; \ | ||
118 | }) | ||
119 | |||
120 | #define rdtscl(low) \ | ||
121 | ((low) = (u32)native_read_tsc()) | ||
122 | |||
123 | #define rdtscll(val) \ | ||
124 | ((val) = native_read_tsc()) | ||
125 | |||
126 | #define write_tsc(val1,val2) wrmsr(0x10, val1, val2) | ||
127 | |||
128 | #define rdpmc(counter,low,high) \ | ||
129 | do { \ | ||
130 | u64 _l = native_read_pmc(); \ | ||
131 | (low) = (u32)_l; \ | ||
132 | (high) = (u32)(_l >> 32); \ | ||
133 | } while(0) | ||
134 | #endif /* !CONFIG_PARAVIRT */ | ||
135 | |||
136 | #ifdef CONFIG_SMP | ||
137 | void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); | ||
138 | void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); | ||
139 | int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); | ||
140 | int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); | ||
141 | #else /* CONFIG_SMP */ | ||
142 | static inline void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) | ||
143 | { | ||
144 | rdmsr(msr_no, *l, *h); | ||
145 | } | ||
146 | static inline void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) | ||
147 | { | ||
148 | wrmsr(msr_no, l, h); | ||
149 | } | ||
150 | static inline int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) | ||
151 | { | ||
152 | return rdmsr_safe(msr_no, l, h); | ||
153 | } | ||
154 | static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) | ||
155 | { | ||
156 | return wrmsr_safe(msr_no, l, h); | ||
157 | } | ||
158 | #endif /* CONFIG_SMP */ | ||
159 | #endif | ||
160 | #endif | ||
161 | #endif /* __ASM_MSR_H */ | ||
diff --git a/include/asm-x86/msr_64.h b/include/asm-x86/msr_64.h deleted file mode 100644 index d5c55b80da54..000000000000 --- a/include/asm-x86/msr_64.h +++ /dev/null | |||
@@ -1,187 +0,0 @@ | |||
1 | #ifndef X86_64_MSR_H | ||
2 | #define X86_64_MSR_H 1 | ||
3 | |||
4 | #include <asm/msr-index.h> | ||
5 | |||
6 | #ifndef __ASSEMBLY__ | ||
7 | #include <linux/errno.h> | ||
8 | /* | ||
9 | * Access to machine-specific registers (available on 586 and better only) | ||
10 | * Note: the rd* operations modify the parameters directly (without using | ||
11 | * pointer indirection), this allows gcc to optimize better | ||
12 | */ | ||
13 | |||
14 | #define rdmsr(msr,val1,val2) \ | ||
15 | __asm__ __volatile__("rdmsr" \ | ||
16 | : "=a" (val1), "=d" (val2) \ | ||
17 | : "c" (msr)) | ||
18 | |||
19 | |||
20 | #define rdmsrl(msr,val) do { unsigned long a__,b__; \ | ||
21 | __asm__ __volatile__("rdmsr" \ | ||
22 | : "=a" (a__), "=d" (b__) \ | ||
23 | : "c" (msr)); \ | ||
24 | val = a__ | (b__<<32); \ | ||
25 | } while(0) | ||
26 | |||
27 | #define wrmsr(msr,val1,val2) \ | ||
28 | __asm__ __volatile__("wrmsr" \ | ||
29 | : /* no outputs */ \ | ||
30 | : "c" (msr), "a" (val1), "d" (val2)) | ||
31 | |||
32 | #define wrmsrl(msr,val) wrmsr(msr,(__u32)((__u64)(val)),((__u64)(val))>>32) | ||
33 | |||
34 | /* wrmsr with exception handling */ | ||
35 | #define wrmsr_safe(msr,a,b) ({ int ret__; \ | ||
36 | asm volatile("2: wrmsr ; xorl %0,%0\n" \ | ||
37 | "1:\n\t" \ | ||
38 | ".section .fixup,\"ax\"\n\t" \ | ||
39 | "3: movl %4,%0 ; jmp 1b\n\t" \ | ||
40 | ".previous\n\t" \ | ||
41 | ".section __ex_table,\"a\"\n" \ | ||
42 | " .align 8\n\t" \ | ||
43 | " .quad 2b,3b\n\t" \ | ||
44 | ".previous" \ | ||
45 | : "=a" (ret__) \ | ||
46 | : "c" (msr), "0" (a), "d" (b), "i" (-EFAULT)); \ | ||
47 | ret__; }) | ||
48 | |||
49 | #define checking_wrmsrl(msr,val) wrmsr_safe(msr,(u32)(val),(u32)((val)>>32)) | ||
50 | |||
51 | #define rdmsr_safe(msr,a,b) \ | ||
52 | ({ int ret__; \ | ||
53 | asm volatile ("1: rdmsr\n" \ | ||
54 | "2:\n" \ | ||
55 | ".section .fixup,\"ax\"\n" \ | ||
56 | "3: movl %4,%0\n" \ | ||
57 | " jmp 2b\n" \ | ||
58 | ".previous\n" \ | ||
59 | ".section __ex_table,\"a\"\n" \ | ||
60 | " .align 8\n" \ | ||
61 | " .quad 1b,3b\n" \ | ||
62 | ".previous":"=&bDS" (ret__), "=a"(*(a)), "=d"(*(b))\ | ||
63 | :"c"(msr), "i"(-EIO), "0"(0)); \ | ||
64 | ret__; }) | ||
65 | |||
66 | #define rdtsc(low,high) \ | ||
67 | __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) | ||
68 | |||
69 | #define rdtscl(low) \ | ||
70 | __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx") | ||
71 | |||
72 | #define rdtscp(low,high,aux) \ | ||
73 | asm volatile (".byte 0x0f,0x01,0xf9" : "=a" (low), "=d" (high), "=c" (aux)) | ||
74 | |||
75 | #define rdtscll(val) do { \ | ||
76 | unsigned int __a,__d; \ | ||
77 | asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \ | ||
78 | (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \ | ||
79 | } while(0) | ||
80 | |||
81 | #define rdtscpll(val, aux) do { \ | ||
82 | unsigned long __a, __d; \ | ||
83 | asm volatile (".byte 0x0f,0x01,0xf9" : "=a" (__a), "=d" (__d), "=c" (aux)); \ | ||
84 | (val) = (__d << 32) | __a; \ | ||
85 | } while (0) | ||
86 | |||
87 | #define write_tsc(val1,val2) wrmsr(0x10, val1, val2) | ||
88 | |||
89 | #define write_rdtscp_aux(val) wrmsr(0xc0000103, val, 0) | ||
90 | |||
91 | #define rdpmc(counter,low,high) \ | ||
92 | __asm__ __volatile__("rdpmc" \ | ||
93 | : "=a" (low), "=d" (high) \ | ||
94 | : "c" (counter)) | ||
95 | |||
96 | static inline void cpuid(int op, unsigned int *eax, unsigned int *ebx, | ||
97 | unsigned int *ecx, unsigned int *edx) | ||
98 | { | ||
99 | __asm__("cpuid" | ||
100 | : "=a" (*eax), | ||
101 | "=b" (*ebx), | ||
102 | "=c" (*ecx), | ||
103 | "=d" (*edx) | ||
104 | : "0" (op)); | ||
105 | } | ||
106 | |||
107 | /* Some CPUID calls want 'count' to be placed in ecx */ | ||
108 | static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx, | ||
109 | int *edx) | ||
110 | { | ||
111 | __asm__("cpuid" | ||
112 | : "=a" (*eax), | ||
113 | "=b" (*ebx), | ||
114 | "=c" (*ecx), | ||
115 | "=d" (*edx) | ||
116 | : "0" (op), "c" (count)); | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * CPUID functions returning a single datum | ||
121 | */ | ||
122 | static inline unsigned int cpuid_eax(unsigned int op) | ||
123 | { | ||
124 | unsigned int eax; | ||
125 | |||
126 | __asm__("cpuid" | ||
127 | : "=a" (eax) | ||
128 | : "0" (op) | ||
129 | : "bx", "cx", "dx"); | ||
130 | return eax; | ||
131 | } | ||
132 | static inline unsigned int cpuid_ebx(unsigned int op) | ||
133 | { | ||
134 | unsigned int eax, ebx; | ||
135 | |||
136 | __asm__("cpuid" | ||
137 | : "=a" (eax), "=b" (ebx) | ||
138 | : "0" (op) | ||
139 | : "cx", "dx" ); | ||
140 | return ebx; | ||
141 | } | ||
142 | static inline unsigned int cpuid_ecx(unsigned int op) | ||
143 | { | ||
144 | unsigned int eax, ecx; | ||
145 | |||
146 | __asm__("cpuid" | ||
147 | : "=a" (eax), "=c" (ecx) | ||
148 | : "0" (op) | ||
149 | : "bx", "dx" ); | ||
150 | return ecx; | ||
151 | } | ||
152 | static inline unsigned int cpuid_edx(unsigned int op) | ||
153 | { | ||
154 | unsigned int eax, edx; | ||
155 | |||
156 | __asm__("cpuid" | ||
157 | : "=a" (eax), "=d" (edx) | ||
158 | : "0" (op) | ||
159 | : "bx", "cx"); | ||
160 | return edx; | ||
161 | } | ||
162 | |||
163 | #ifdef CONFIG_SMP | ||
164 | void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); | ||
165 | void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); | ||
166 | int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); | ||
167 | int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); | ||
168 | #else /* CONFIG_SMP */ | ||
169 | static inline void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) | ||
170 | { | ||
171 | rdmsr(msr_no, *l, *h); | ||
172 | } | ||
173 | static inline void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) | ||
174 | { | ||
175 | wrmsr(msr_no, l, h); | ||
176 | } | ||
177 | static inline int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) | ||
178 | { | ||
179 | return rdmsr_safe(msr_no, l, h); | ||
180 | } | ||
181 | static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) | ||
182 | { | ||
183 | return wrmsr_safe(msr_no, l, h); | ||
184 | } | ||
185 | #endif /* CONFIG_SMP */ | ||
186 | #endif /* __ASSEMBLY__ */ | ||
187 | #endif /* X86_64_MSR_H */ | ||
diff --git a/include/asm-x86/mtrr.h b/include/asm-x86/mtrr.h index 34f633b3e00c..e8320e4e6ca2 100644 --- a/include/asm-x86/mtrr.h +++ b/include/asm-x86/mtrr.h | |||
@@ -1,13 +1,164 @@ | |||
1 | /* Generic MTRR (Memory Type Range Register) ioctls. | ||
2 | |||
3 | Copyright (C) 1997-1999 Richard Gooch | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | |||
19 | Richard Gooch may be reached by email at rgooch@atnf.csiro.au | ||
20 | The postal address is: | ||
21 | Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia. | ||
22 | */ | ||
23 | #ifndef _ASM_X86_MTRR_H | ||
24 | #define _ASM_X86_MTRR_H | ||
25 | |||
26 | #include <linux/ioctl.h> | ||
27 | #include <linux/errno.h> | ||
28 | |||
29 | #define MTRR_IOCTL_BASE 'M' | ||
30 | |||
31 | struct mtrr_sentry | ||
32 | { | ||
33 | unsigned long base; /* Base address */ | ||
34 | unsigned int size; /* Size of region */ | ||
35 | unsigned int type; /* Type of region */ | ||
36 | }; | ||
37 | |||
38 | /* Warning: this structure has a different order from i386 | ||
39 | on x86-64. The 32bit emulation code takes care of that. | ||
40 | But you need to use this for 64bit, otherwise your X server | ||
41 | will break. */ | ||
42 | |||
43 | #ifdef __i386__ | ||
44 | struct mtrr_gentry | ||
45 | { | ||
46 | unsigned int regnum; /* Register number */ | ||
47 | unsigned long base; /* Base address */ | ||
48 | unsigned int size; /* Size of region */ | ||
49 | unsigned int type; /* Type of region */ | ||
50 | }; | ||
51 | |||
52 | #else /* __i386__ */ | ||
53 | |||
54 | struct mtrr_gentry | ||
55 | { | ||
56 | unsigned long base; /* Base address */ | ||
57 | unsigned int size; /* Size of region */ | ||
58 | unsigned int regnum; /* Register number */ | ||
59 | unsigned int type; /* Type of region */ | ||
60 | }; | ||
61 | #endif /* !__i386__ */ | ||
62 | |||
63 | /* These are the various ioctls */ | ||
64 | #define MTRRIOC_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry) | ||
65 | #define MTRRIOC_SET_ENTRY _IOW(MTRR_IOCTL_BASE, 1, struct mtrr_sentry) | ||
66 | #define MTRRIOC_DEL_ENTRY _IOW(MTRR_IOCTL_BASE, 2, struct mtrr_sentry) | ||
67 | #define MTRRIOC_GET_ENTRY _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry) | ||
68 | #define MTRRIOC_KILL_ENTRY _IOW(MTRR_IOCTL_BASE, 4, struct mtrr_sentry) | ||
69 | #define MTRRIOC_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 5, struct mtrr_sentry) | ||
70 | #define MTRRIOC_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 6, struct mtrr_sentry) | ||
71 | #define MTRRIOC_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 7, struct mtrr_sentry) | ||
72 | #define MTRRIOC_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry) | ||
73 | #define MTRRIOC_KILL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 9, struct mtrr_sentry) | ||
74 | |||
75 | /* These are the region types */ | ||
76 | #define MTRR_TYPE_UNCACHABLE 0 | ||
77 | #define MTRR_TYPE_WRCOMB 1 | ||
78 | /*#define MTRR_TYPE_ 2*/ | ||
79 | /*#define MTRR_TYPE_ 3*/ | ||
80 | #define MTRR_TYPE_WRTHROUGH 4 | ||
81 | #define MTRR_TYPE_WRPROT 5 | ||
82 | #define MTRR_TYPE_WRBACK 6 | ||
83 | #define MTRR_NUM_TYPES 7 | ||
84 | |||
1 | #ifdef __KERNEL__ | 85 | #ifdef __KERNEL__ |
2 | # ifdef CONFIG_X86_32 | 86 | |
3 | # include "mtrr_32.h" | 87 | /* The following functions are for use by other drivers */ |
4 | # else | 88 | # ifdef CONFIG_MTRR |
5 | # include "mtrr_64.h" | 89 | extern void mtrr_save_fixed_ranges(void *); |
6 | # endif | 90 | extern void mtrr_save_state(void); |
7 | #else | 91 | extern int mtrr_add (unsigned long base, unsigned long size, |
8 | # ifdef __i386__ | 92 | unsigned int type, char increment); |
9 | # include "mtrr_32.h" | 93 | extern int mtrr_add_page (unsigned long base, unsigned long size, |
10 | # else | 94 | unsigned int type, char increment); |
11 | # include "mtrr_64.h" | 95 | extern int mtrr_del (int reg, unsigned long base, unsigned long size); |
12 | # endif | 96 | extern int mtrr_del_page (int reg, unsigned long base, unsigned long size); |
13 | #endif | 97 | extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi); |
98 | extern void mtrr_ap_init(void); | ||
99 | extern void mtrr_bp_init(void); | ||
100 | # else | ||
101 | #define mtrr_save_fixed_ranges(arg) do {} while (0) | ||
102 | #define mtrr_save_state() do {} while (0) | ||
103 | static __inline__ int mtrr_add (unsigned long base, unsigned long size, | ||
104 | unsigned int type, char increment) | ||
105 | { | ||
106 | return -ENODEV; | ||
107 | } | ||
108 | static __inline__ int mtrr_add_page (unsigned long base, unsigned long size, | ||
109 | unsigned int type, char increment) | ||
110 | { | ||
111 | return -ENODEV; | ||
112 | } | ||
113 | static __inline__ int mtrr_del (int reg, unsigned long base, | ||
114 | unsigned long size) | ||
115 | { | ||
116 | return -ENODEV; | ||
117 | } | ||
118 | static __inline__ int mtrr_del_page (int reg, unsigned long base, | ||
119 | unsigned long size) | ||
120 | { | ||
121 | return -ENODEV; | ||
122 | } | ||
123 | |||
124 | static __inline__ void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) {;} | ||
125 | |||
126 | #define mtrr_ap_init() do {} while (0) | ||
127 | #define mtrr_bp_init() do {} while (0) | ||
128 | # endif | ||
129 | |||
130 | #ifdef CONFIG_COMPAT | ||
131 | #include <linux/compat.h> | ||
132 | |||
133 | struct mtrr_sentry32 | ||
134 | { | ||
135 | compat_ulong_t base; /* Base address */ | ||
136 | compat_uint_t size; /* Size of region */ | ||
137 | compat_uint_t type; /* Type of region */ | ||
138 | }; | ||
139 | |||
140 | struct mtrr_gentry32 | ||
141 | { | ||
142 | compat_ulong_t regnum; /* Register number */ | ||
143 | compat_uint_t base; /* Base address */ | ||
144 | compat_uint_t size; /* Size of region */ | ||
145 | compat_uint_t type; /* Type of region */ | ||
146 | }; | ||
147 | |||
148 | #define MTRR_IOCTL_BASE 'M' | ||
149 | |||
150 | #define MTRRIOC32_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry32) | ||
151 | #define MTRRIOC32_SET_ENTRY _IOW(MTRR_IOCTL_BASE, 1, struct mtrr_sentry32) | ||
152 | #define MTRRIOC32_DEL_ENTRY _IOW(MTRR_IOCTL_BASE, 2, struct mtrr_sentry32) | ||
153 | #define MTRRIOC32_GET_ENTRY _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32) | ||
154 | #define MTRRIOC32_KILL_ENTRY _IOW(MTRR_IOCTL_BASE, 4, struct mtrr_sentry32) | ||
155 | #define MTRRIOC32_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 5, struct mtrr_sentry32) | ||
156 | #define MTRRIOC32_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 6, struct mtrr_sentry32) | ||
157 | #define MTRRIOC32_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 7, struct mtrr_sentry32) | ||
158 | #define MTRRIOC32_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32) | ||
159 | #define MTRRIOC32_KILL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 9, struct mtrr_sentry32) | ||
160 | #endif /* CONFIG_COMPAT */ | ||
161 | |||
162 | #endif /* __KERNEL__ */ | ||
163 | |||
164 | #endif /* _ASM_X86_MTRR_H */ | ||
diff --git a/include/asm-x86/mtrr_32.h b/include/asm-x86/mtrr_32.h deleted file mode 100644 index 7e9c7ccbdcfe..000000000000 --- a/include/asm-x86/mtrr_32.h +++ /dev/null | |||
@@ -1,115 +0,0 @@ | |||
1 | /* Generic MTRR (Memory Type Range Register) ioctls. | ||
2 | |||
3 | Copyright (C) 1997-1999 Richard Gooch | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | |||
19 | Richard Gooch may be reached by email at rgooch@atnf.csiro.au | ||
20 | The postal address is: | ||
21 | Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia. | ||
22 | */ | ||
23 | #ifndef _LINUX_MTRR_H | ||
24 | #define _LINUX_MTRR_H | ||
25 | |||
26 | #include <linux/ioctl.h> | ||
27 | #include <linux/errno.h> | ||
28 | |||
29 | #define MTRR_IOCTL_BASE 'M' | ||
30 | |||
31 | struct mtrr_sentry | ||
32 | { | ||
33 | unsigned long base; /* Base address */ | ||
34 | unsigned int size; /* Size of region */ | ||
35 | unsigned int type; /* Type of region */ | ||
36 | }; | ||
37 | |||
38 | struct mtrr_gentry | ||
39 | { | ||
40 | unsigned int regnum; /* Register number */ | ||
41 | unsigned long base; /* Base address */ | ||
42 | unsigned int size; /* Size of region */ | ||
43 | unsigned int type; /* Type of region */ | ||
44 | }; | ||
45 | |||
46 | /* These are the various ioctls */ | ||
47 | #define MTRRIOC_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry) | ||
48 | #define MTRRIOC_SET_ENTRY _IOW(MTRR_IOCTL_BASE, 1, struct mtrr_sentry) | ||
49 | #define MTRRIOC_DEL_ENTRY _IOW(MTRR_IOCTL_BASE, 2, struct mtrr_sentry) | ||
50 | #define MTRRIOC_GET_ENTRY _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry) | ||
51 | #define MTRRIOC_KILL_ENTRY _IOW(MTRR_IOCTL_BASE, 4, struct mtrr_sentry) | ||
52 | #define MTRRIOC_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 5, struct mtrr_sentry) | ||
53 | #define MTRRIOC_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 6, struct mtrr_sentry) | ||
54 | #define MTRRIOC_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 7, struct mtrr_sentry) | ||
55 | #define MTRRIOC_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry) | ||
56 | #define MTRRIOC_KILL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 9, struct mtrr_sentry) | ||
57 | |||
58 | /* These are the region types */ | ||
59 | #define MTRR_TYPE_UNCACHABLE 0 | ||
60 | #define MTRR_TYPE_WRCOMB 1 | ||
61 | /*#define MTRR_TYPE_ 2*/ | ||
62 | /*#define MTRR_TYPE_ 3*/ | ||
63 | #define MTRR_TYPE_WRTHROUGH 4 | ||
64 | #define MTRR_TYPE_WRPROT 5 | ||
65 | #define MTRR_TYPE_WRBACK 6 | ||
66 | #define MTRR_NUM_TYPES 7 | ||
67 | |||
68 | #ifdef __KERNEL__ | ||
69 | |||
70 | /* The following functions are for use by other drivers */ | ||
71 | # ifdef CONFIG_MTRR | ||
72 | extern void mtrr_save_fixed_ranges(void *); | ||
73 | extern void mtrr_save_state(void); | ||
74 | extern int mtrr_add (unsigned long base, unsigned long size, | ||
75 | unsigned int type, char increment); | ||
76 | extern int mtrr_add_page (unsigned long base, unsigned long size, | ||
77 | unsigned int type, char increment); | ||
78 | extern int mtrr_del (int reg, unsigned long base, unsigned long size); | ||
79 | extern int mtrr_del_page (int reg, unsigned long base, unsigned long size); | ||
80 | extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi); | ||
81 | extern void mtrr_ap_init(void); | ||
82 | extern void mtrr_bp_init(void); | ||
83 | # else | ||
84 | #define mtrr_save_fixed_ranges(arg) do {} while (0) | ||
85 | #define mtrr_save_state() do {} while (0) | ||
86 | static __inline__ int mtrr_add (unsigned long base, unsigned long size, | ||
87 | unsigned int type, char increment) | ||
88 | { | ||
89 | return -ENODEV; | ||
90 | } | ||
91 | static __inline__ int mtrr_add_page (unsigned long base, unsigned long size, | ||
92 | unsigned int type, char increment) | ||
93 | { | ||
94 | return -ENODEV; | ||
95 | } | ||
96 | static __inline__ int mtrr_del (int reg, unsigned long base, | ||
97 | unsigned long size) | ||
98 | { | ||
99 | return -ENODEV; | ||
100 | } | ||
101 | static __inline__ int mtrr_del_page (int reg, unsigned long base, | ||
102 | unsigned long size) | ||
103 | { | ||
104 | return -ENODEV; | ||
105 | } | ||
106 | |||
107 | static __inline__ void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) {;} | ||
108 | |||
109 | #define mtrr_ap_init() do {} while (0) | ||
110 | #define mtrr_bp_init() do {} while (0) | ||
111 | # endif | ||
112 | |||
113 | #endif | ||
114 | |||
115 | #endif /* _LINUX_MTRR_H */ | ||
diff --git a/include/asm-x86/mtrr_64.h b/include/asm-x86/mtrr_64.h deleted file mode 100644 index b557c486bef8..000000000000 --- a/include/asm-x86/mtrr_64.h +++ /dev/null | |||
@@ -1,152 +0,0 @@ | |||
1 | /* Generic MTRR (Memory Type Range Register) ioctls. | ||
2 | |||
3 | Copyright (C) 1997-1999 Richard Gooch | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | |||
19 | Richard Gooch may be reached by email at rgooch@atnf.csiro.au | ||
20 | The postal address is: | ||
21 | Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia. | ||
22 | */ | ||
23 | #ifndef _LINUX_MTRR_H | ||
24 | #define _LINUX_MTRR_H | ||
25 | |||
26 | #include <linux/ioctl.h> | ||
27 | |||
28 | #define MTRR_IOCTL_BASE 'M' | ||
29 | |||
30 | struct mtrr_sentry | ||
31 | { | ||
32 | unsigned long base; /* Base address */ | ||
33 | unsigned int size; /* Size of region */ | ||
34 | unsigned int type; /* Type of region */ | ||
35 | }; | ||
36 | |||
37 | /* Warning: this structure has a different order from i386 | ||
38 | on x86-64. The 32bit emulation code takes care of that. | ||
39 | But you need to use this for 64bit, otherwise your X server | ||
40 | will break. */ | ||
41 | struct mtrr_gentry | ||
42 | { | ||
43 | unsigned long base; /* Base address */ | ||
44 | unsigned int size; /* Size of region */ | ||
45 | unsigned int regnum; /* Register number */ | ||
46 | unsigned int type; /* Type of region */ | ||
47 | }; | ||
48 | |||
49 | /* These are the various ioctls */ | ||
50 | #define MTRRIOC_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry) | ||
51 | #define MTRRIOC_SET_ENTRY _IOW(MTRR_IOCTL_BASE, 1, struct mtrr_sentry) | ||
52 | #define MTRRIOC_DEL_ENTRY _IOW(MTRR_IOCTL_BASE, 2, struct mtrr_sentry) | ||
53 | #define MTRRIOC_GET_ENTRY _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry) | ||
54 | #define MTRRIOC_KILL_ENTRY _IOW(MTRR_IOCTL_BASE, 4, struct mtrr_sentry) | ||
55 | #define MTRRIOC_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 5, struct mtrr_sentry) | ||
56 | #define MTRRIOC_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 6, struct mtrr_sentry) | ||
57 | #define MTRRIOC_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 7, struct mtrr_sentry) | ||
58 | #define MTRRIOC_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry) | ||
59 | #define MTRRIOC_KILL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 9, struct mtrr_sentry) | ||
60 | |||
61 | /* These are the region types */ | ||
62 | #define MTRR_TYPE_UNCACHABLE 0 | ||
63 | #define MTRR_TYPE_WRCOMB 1 | ||
64 | /*#define MTRR_TYPE_ 2*/ | ||
65 | /*#define MTRR_TYPE_ 3*/ | ||
66 | #define MTRR_TYPE_WRTHROUGH 4 | ||
67 | #define MTRR_TYPE_WRPROT 5 | ||
68 | #define MTRR_TYPE_WRBACK 6 | ||
69 | #define MTRR_NUM_TYPES 7 | ||
70 | |||
71 | #ifdef __KERNEL__ | ||
72 | |||
73 | /* The following functions are for use by other drivers */ | ||
74 | # ifdef CONFIG_MTRR | ||
75 | extern int mtrr_add (unsigned long base, unsigned long size, | ||
76 | unsigned int type, char increment); | ||
77 | extern int mtrr_add_page (unsigned long base, unsigned long size, | ||
78 | unsigned int type, char increment); | ||
79 | extern int mtrr_del (int reg, unsigned long base, unsigned long size); | ||
80 | extern int mtrr_del_page (int reg, unsigned long base, unsigned long size); | ||
81 | # else | ||
82 | static __inline__ int mtrr_add (unsigned long base, unsigned long size, | ||
83 | unsigned int type, char increment) | ||
84 | { | ||
85 | return -ENODEV; | ||
86 | } | ||
87 | static __inline__ int mtrr_add_page (unsigned long base, unsigned long size, | ||
88 | unsigned int type, char increment) | ||
89 | { | ||
90 | return -ENODEV; | ||
91 | } | ||
92 | static __inline__ int mtrr_del (int reg, unsigned long base, | ||
93 | unsigned long size) | ||
94 | { | ||
95 | return -ENODEV; | ||
96 | } | ||
97 | static __inline__ int mtrr_del_page (int reg, unsigned long base, | ||
98 | unsigned long size) | ||
99 | { | ||
100 | return -ENODEV; | ||
101 | } | ||
102 | |||
103 | #endif /* CONFIG_MTRR */ | ||
104 | |||
105 | #ifdef CONFIG_COMPAT | ||
106 | #include <linux/compat.h> | ||
107 | |||
108 | struct mtrr_sentry32 | ||
109 | { | ||
110 | compat_ulong_t base; /* Base address */ | ||
111 | compat_uint_t size; /* Size of region */ | ||
112 | compat_uint_t type; /* Type of region */ | ||
113 | }; | ||
114 | |||
115 | struct mtrr_gentry32 | ||
116 | { | ||
117 | compat_ulong_t regnum; /* Register number */ | ||
118 | compat_uint_t base; /* Base address */ | ||
119 | compat_uint_t size; /* Size of region */ | ||
120 | compat_uint_t type; /* Type of region */ | ||
121 | }; | ||
122 | |||
123 | #define MTRR_IOCTL_BASE 'M' | ||
124 | |||
125 | #define MTRRIOC32_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry32) | ||
126 | #define MTRRIOC32_SET_ENTRY _IOW(MTRR_IOCTL_BASE, 1, struct mtrr_sentry32) | ||
127 | #define MTRRIOC32_DEL_ENTRY _IOW(MTRR_IOCTL_BASE, 2, struct mtrr_sentry32) | ||
128 | #define MTRRIOC32_GET_ENTRY _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32) | ||
129 | #define MTRRIOC32_KILL_ENTRY _IOW(MTRR_IOCTL_BASE, 4, struct mtrr_sentry32) | ||
130 | #define MTRRIOC32_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 5, struct mtrr_sentry32) | ||
131 | #define MTRRIOC32_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 6, struct mtrr_sentry32) | ||
132 | #define MTRRIOC32_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 7, struct mtrr_sentry32) | ||
133 | #define MTRRIOC32_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32) | ||
134 | #define MTRRIOC32_KILL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 9, struct mtrr_sentry32) | ||
135 | |||
136 | #endif /* CONFIG_COMPAT */ | ||
137 | |||
138 | #ifdef CONFIG_MTRR | ||
139 | extern void mtrr_ap_init(void); | ||
140 | extern void mtrr_bp_init(void); | ||
141 | extern void mtrr_save_fixed_ranges(void *); | ||
142 | extern void mtrr_save_state(void); | ||
143 | #else | ||
144 | #define mtrr_ap_init() do {} while (0) | ||
145 | #define mtrr_bp_init() do {} while (0) | ||
146 | #define mtrr_save_fixed_ranges(arg) do {} while (0) | ||
147 | #define mtrr_save_state() do {} while (0) | ||
148 | #endif | ||
149 | |||
150 | #endif /* __KERNEL__ */ | ||
151 | |||
152 | #endif /* _LINUX_MTRR_H */ | ||
diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index bc4d64a87689..213c97300cb3 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h | |||
@@ -1,13 +1,142 @@ | |||
1 | #ifndef _ASM_X86_PTRACE_H | ||
2 | #define _ASM_X86_PTRACE_H | ||
3 | |||
4 | #include <linux/compiler.h> /* For __user */ | ||
5 | #include <asm/ptrace-abi.h> | ||
6 | |||
7 | #ifndef __ASSEMBLY__ | ||
8 | |||
9 | #ifdef __i386__ | ||
10 | /* this struct defines the way the registers are stored on the | ||
11 | stack during a system call. */ | ||
12 | |||
13 | struct pt_regs { | ||
14 | long ebx; | ||
15 | long ecx; | ||
16 | long edx; | ||
17 | long esi; | ||
18 | long edi; | ||
19 | long ebp; | ||
20 | long eax; | ||
21 | int xds; | ||
22 | int xes; | ||
23 | int xfs; | ||
24 | /* int xgs; */ | ||
25 | long orig_eax; | ||
26 | long eip; | ||
27 | int xcs; | ||
28 | long eflags; | ||
29 | long esp; | ||
30 | int xss; | ||
31 | }; | ||
32 | |||
1 | #ifdef __KERNEL__ | 33 | #ifdef __KERNEL__ |
2 | # ifdef CONFIG_X86_32 | 34 | |
3 | # include "ptrace_32.h" | 35 | #include <asm/vm86.h> |
4 | # else | 36 | #include <asm/segment.h> |
5 | # include "ptrace_64.h" | 37 | |
6 | # endif | 38 | struct task_struct; |
7 | #else | 39 | extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code); |
8 | # ifdef __i386__ | 40 | |
9 | # include "ptrace_32.h" | 41 | /* |
10 | # else | 42 | * user_mode_vm(regs) determines whether a register set came from user mode. |
11 | # include "ptrace_64.h" | 43 | * This is true if V8086 mode was enabled OR if the register set was from |
12 | # endif | 44 | * protected mode with RPL-3 CS value. This tricky test checks that with |
45 | * one comparison. Many places in the kernel can bypass this full check | ||
46 | * if they have already ruled out V8086 mode, so user_mode(regs) can be used. | ||
47 | */ | ||
48 | static inline int user_mode(struct pt_regs *regs) | ||
49 | { | ||
50 | return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL; | ||
51 | } | ||
52 | static inline int user_mode_vm(struct pt_regs *regs) | ||
53 | { | ||
54 | return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL; | ||
55 | } | ||
56 | static inline int v8086_mode(struct pt_regs *regs) | ||
57 | { | ||
58 | return (regs->eflags & VM_MASK); | ||
59 | } | ||
60 | |||
61 | #define instruction_pointer(regs) ((regs)->eip) | ||
62 | #define frame_pointer(regs) ((regs)->ebp) | ||
63 | #define stack_pointer(regs) ((regs)->esp) | ||
64 | #define regs_return_value(regs) ((regs)->eax) | ||
65 | |||
66 | extern unsigned long profile_pc(struct pt_regs *regs); | ||
67 | #endif /* __KERNEL__ */ | ||
68 | |||
69 | #else /* __i386__ */ | ||
70 | |||
71 | struct pt_regs { | ||
72 | unsigned long r15; | ||
73 | unsigned long r14; | ||
74 | unsigned long r13; | ||
75 | unsigned long r12; | ||
76 | unsigned long rbp; | ||
77 | unsigned long rbx; | ||
78 | /* arguments: non interrupts/non tracing syscalls only save upto here*/ | ||
79 | unsigned long r11; | ||
80 | unsigned long r10; | ||
81 | unsigned long r9; | ||
82 | unsigned long r8; | ||
83 | unsigned long rax; | ||
84 | unsigned long rcx; | ||
85 | unsigned long rdx; | ||
86 | unsigned long rsi; | ||
87 | unsigned long rdi; | ||
88 | unsigned long orig_rax; | ||
89 | /* end of arguments */ | ||
90 | /* cpu exception frame or undefined */ | ||
91 | unsigned long rip; | ||
92 | unsigned long cs; | ||
93 | unsigned long eflags; | ||
94 | unsigned long rsp; | ||
95 | unsigned long ss; | ||
96 | /* top of stack page */ | ||
97 | }; | ||
98 | |||
99 | #ifdef __KERNEL__ | ||
100 | |||
101 | #define user_mode(regs) (!!((regs)->cs & 3)) | ||
102 | #define user_mode_vm(regs) user_mode(regs) | ||
103 | #define instruction_pointer(regs) ((regs)->rip) | ||
104 | #define frame_pointer(regs) ((regs)->rbp) | ||
105 | #define stack_pointer(regs) ((regs)->rsp) | ||
106 | #define regs_return_value(regs) ((regs)->rax) | ||
107 | |||
108 | extern unsigned long profile_pc(struct pt_regs *regs); | ||
109 | void signal_fault(struct pt_regs *regs, void __user *frame, char *where); | ||
110 | |||
111 | struct task_struct; | ||
112 | |||
113 | extern unsigned long | ||
114 | convert_rip_to_linear(struct task_struct *child, struct pt_regs *regs); | ||
115 | |||
116 | enum { | ||
117 | EF_CF = 0x00000001, | ||
118 | EF_PF = 0x00000004, | ||
119 | EF_AF = 0x00000010, | ||
120 | EF_ZF = 0x00000040, | ||
121 | EF_SF = 0x00000080, | ||
122 | EF_TF = 0x00000100, | ||
123 | EF_IE = 0x00000200, | ||
124 | EF_DF = 0x00000400, | ||
125 | EF_OF = 0x00000800, | ||
126 | EF_IOPL = 0x00003000, | ||
127 | EF_IOPL_RING0 = 0x00000000, | ||
128 | EF_IOPL_RING1 = 0x00001000, | ||
129 | EF_IOPL_RING2 = 0x00002000, | ||
130 | EF_NT = 0x00004000, /* nested task */ | ||
131 | EF_RF = 0x00010000, /* resume */ | ||
132 | EF_VM = 0x00020000, /* virtual mode */ | ||
133 | EF_AC = 0x00040000, /* alignment */ | ||
134 | EF_VIF = 0x00080000, /* virtual interrupt */ | ||
135 | EF_VIP = 0x00100000, /* virtual interrupt pending */ | ||
136 | EF_ID = 0x00200000, /* id */ | ||
137 | }; | ||
138 | #endif /* __KERNEL__ */ | ||
139 | #endif /* !__i386__ */ | ||
140 | #endif /* !__ASSEMBLY__ */ | ||
141 | |||
13 | #endif | 142 | #endif |
diff --git a/include/asm-x86/ptrace_32.h b/include/asm-x86/ptrace_32.h deleted file mode 100644 index 78d063dabe0a..000000000000 --- a/include/asm-x86/ptrace_32.h +++ /dev/null | |||
@@ -1,65 +0,0 @@ | |||
1 | #ifndef _I386_PTRACE_H | ||
2 | #define _I386_PTRACE_H | ||
3 | |||
4 | #include <asm/ptrace-abi.h> | ||
5 | |||
6 | /* this struct defines the way the registers are stored on the | ||
7 | stack during a system call. */ | ||
8 | |||
9 | struct pt_regs { | ||
10 | long ebx; | ||
11 | long ecx; | ||
12 | long edx; | ||
13 | long esi; | ||
14 | long edi; | ||
15 | long ebp; | ||
16 | long eax; | ||
17 | int xds; | ||
18 | int xes; | ||
19 | int xfs; | ||
20 | /* int xgs; */ | ||
21 | long orig_eax; | ||
22 | long eip; | ||
23 | int xcs; | ||
24 | long eflags; | ||
25 | long esp; | ||
26 | int xss; | ||
27 | }; | ||
28 | |||
29 | #ifdef __KERNEL__ | ||
30 | |||
31 | #include <asm/vm86.h> | ||
32 | #include <asm/segment.h> | ||
33 | |||
34 | struct task_struct; | ||
35 | extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code); | ||
36 | |||
37 | /* | ||
38 | * user_mode_vm(regs) determines whether a register set came from user mode. | ||
39 | * This is true if V8086 mode was enabled OR if the register set was from | ||
40 | * protected mode with RPL-3 CS value. This tricky test checks that with | ||
41 | * one comparison. Many places in the kernel can bypass this full check | ||
42 | * if they have already ruled out V8086 mode, so user_mode(regs) can be used. | ||
43 | */ | ||
44 | static inline int user_mode(struct pt_regs *regs) | ||
45 | { | ||
46 | return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL; | ||
47 | } | ||
48 | static inline int user_mode_vm(struct pt_regs *regs) | ||
49 | { | ||
50 | return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL; | ||
51 | } | ||
52 | static inline int v8086_mode(struct pt_regs *regs) | ||
53 | { | ||
54 | return (regs->eflags & VM_MASK); | ||
55 | } | ||
56 | |||
57 | #define instruction_pointer(regs) ((regs)->eip) | ||
58 | #define frame_pointer(regs) ((regs)->ebp) | ||
59 | #define stack_pointer(regs) ((regs)->esp) | ||
60 | #define regs_return_value(regs) ((regs)->eax) | ||
61 | |||
62 | extern unsigned long profile_pc(struct pt_regs *regs); | ||
63 | #endif /* __KERNEL__ */ | ||
64 | |||
65 | #endif | ||
diff --git a/include/asm-x86/ptrace_64.h b/include/asm-x86/ptrace_64.h deleted file mode 100644 index 7bfe61e1b705..000000000000 --- a/include/asm-x86/ptrace_64.h +++ /dev/null | |||
@@ -1,80 +0,0 @@ | |||
1 | #ifndef _X86_64_PTRACE_H | ||
2 | #define _X86_64_PTRACE_H | ||
3 | |||
4 | #include <linux/compiler.h> /* For __user */ | ||
5 | #include <asm/ptrace-abi.h> | ||
6 | |||
7 | #ifndef __ASSEMBLY__ | ||
8 | |||
9 | struct pt_regs { | ||
10 | unsigned long r15; | ||
11 | unsigned long r14; | ||
12 | unsigned long r13; | ||
13 | unsigned long r12; | ||
14 | unsigned long rbp; | ||
15 | unsigned long rbx; | ||
16 | /* arguments: non interrupts/non tracing syscalls only save upto here*/ | ||
17 | unsigned long r11; | ||
18 | unsigned long r10; | ||
19 | unsigned long r9; | ||
20 | unsigned long r8; | ||
21 | unsigned long rax; | ||
22 | unsigned long rcx; | ||
23 | unsigned long rdx; | ||
24 | unsigned long rsi; | ||
25 | unsigned long rdi; | ||
26 | unsigned long orig_rax; | ||
27 | /* end of arguments */ | ||
28 | /* cpu exception frame or undefined */ | ||
29 | unsigned long rip; | ||
30 | unsigned long cs; | ||
31 | unsigned long eflags; | ||
32 | unsigned long rsp; | ||
33 | unsigned long ss; | ||
34 | /* top of stack page */ | ||
35 | }; | ||
36 | |||
37 | #endif | ||
38 | |||
39 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) | ||
40 | #define user_mode(regs) (!!((regs)->cs & 3)) | ||
41 | #define user_mode_vm(regs) user_mode(regs) | ||
42 | #define instruction_pointer(regs) ((regs)->rip) | ||
43 | #define frame_pointer(regs) ((regs)->rbp) | ||
44 | #define stack_pointer(regs) ((regs)->rsp) | ||
45 | #define regs_return_value(regs) ((regs)->rax) | ||
46 | |||
47 | extern unsigned long profile_pc(struct pt_regs *regs); | ||
48 | void signal_fault(struct pt_regs *regs, void __user *frame, char *where); | ||
49 | |||
50 | struct task_struct; | ||
51 | |||
52 | extern unsigned long | ||
53 | convert_rip_to_linear(struct task_struct *child, struct pt_regs *regs); | ||
54 | |||
55 | enum { | ||
56 | EF_CF = 0x00000001, | ||
57 | EF_PF = 0x00000004, | ||
58 | EF_AF = 0x00000010, | ||
59 | EF_ZF = 0x00000040, | ||
60 | EF_SF = 0x00000080, | ||
61 | EF_TF = 0x00000100, | ||
62 | EF_IE = 0x00000200, | ||
63 | EF_DF = 0x00000400, | ||
64 | EF_OF = 0x00000800, | ||
65 | EF_IOPL = 0x00003000, | ||
66 | EF_IOPL_RING0 = 0x00000000, | ||
67 | EF_IOPL_RING1 = 0x00001000, | ||
68 | EF_IOPL_RING2 = 0x00002000, | ||
69 | EF_NT = 0x00004000, /* nested task */ | ||
70 | EF_RF = 0x00010000, /* resume */ | ||
71 | EF_VM = 0x00020000, /* virtual mode */ | ||
72 | EF_AC = 0x00040000, /* alignment */ | ||
73 | EF_VIF = 0x00080000, /* virtual interrupt */ | ||
74 | EF_VIP = 0x00100000, /* virtual interrupt pending */ | ||
75 | EF_ID = 0x00200000, /* id */ | ||
76 | }; | ||
77 | |||
78 | #endif | ||
79 | |||
80 | #endif | ||
diff --git a/include/asm-x86/required-features.h b/include/asm-x86/required-features.h index 8b64f3ea2b78..7400d3ad75c6 100644 --- a/include/asm-x86/required-features.h +++ b/include/asm-x86/required-features.h | |||
@@ -1,5 +1,72 @@ | |||
1 | #ifdef CONFIG_X86_32 | 1 | #ifndef _ASM_REQUIRED_FEATURES_H |
2 | # include "required-features_32.h" | 2 | #define _ASM_REQUIRED_FEATURES_H 1 |
3 | |||
4 | /* Define minimum CPUID feature set for kernel These bits are checked | ||
5 | really early to actually display a visible error message before the | ||
6 | kernel dies. Make sure to assign features to the proper mask! | ||
7 | |||
8 | Some requirements that are not in CPUID yet are also in the | ||
9 | CONFIG_X86_MINIMUM_CPU_FAMILY which is checked too. | ||
10 | |||
11 | The real information is in arch/x86/Kconfig.cpu, this just converts | ||
12 | the CONFIGs into a bitmask */ | ||
13 | |||
14 | #ifndef CONFIG_MATH_EMULATION | ||
15 | # define NEED_FPU (1<<(X86_FEATURE_FPU & 31)) | ||
3 | #else | 16 | #else |
4 | # include "required-features_64.h" | 17 | # define NEED_FPU 0 |
18 | #endif | ||
19 | |||
20 | #if defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64) | ||
21 | # define NEED_PAE (1<<(X86_FEATURE_PAE & 31)) | ||
22 | # define NEED_CX8 (1<<(X86_FEATURE_CX8 & 31)) | ||
23 | #else | ||
24 | # define NEED_PAE 0 | ||
25 | # define NEED_CX8 0 | ||
26 | #endif | ||
27 | |||
28 | #if defined(CONFIG_X86_CMOV) || defined(CONFIG_X86_64) | ||
29 | # define NEED_CMOV (1<<(X86_FEATURE_CMOV & 31)) | ||
30 | #else | ||
31 | # define NEED_CMOV 0 | ||
32 | #endif | ||
33 | |||
34 | #ifdef CONFIG_X86_USE_3DNOW | ||
35 | # define NEED_3DNOW (1<<(X86_FEATURE_3DNOW & 31)) | ||
36 | #else | ||
37 | # define NEED_3DNOW 0 | ||
38 | #endif | ||
39 | |||
40 | #ifdef CONFIG_X86_64 | ||
41 | #define NEED_PSE (1<<(X86_FEATURE_PSE & 31)) | ||
42 | #define NEED_MSR (1<<(X86_FEATURE_MSR & 31)) | ||
43 | #define NEED_PGE (1<<(X86_FEATURE_PGE & 31)) | ||
44 | #define NEED_FXSR (1<<(X86_FEATURE_FXSR & 31)) | ||
45 | #define NEED_XMM (1<<(X86_FEATURE_XMM & 31)) | ||
46 | #define NEED_XMM2 (1<<(X86_FEATURE_XMM2 & 31)) | ||
47 | #define NEED_LM (1<<(X86_FEATURE_LM & 31)) | ||
48 | #else | ||
49 | #define NEED_PSE 0 | ||
50 | #define NEED_MSR 0 | ||
51 | #define NEED_PGE 0 | ||
52 | #define NEED_FXSR 0 | ||
53 | #define NEED_XMM 0 | ||
54 | #define NEED_XMM2 0 | ||
55 | #define NEED_LM 0 | ||
56 | #endif | ||
57 | |||
58 | #define REQUIRED_MASK0 (NEED_FPU|NEED_PSE|NEED_MSR|NEED_PAE|\ | ||
59 | NEED_CX8|NEED_PGE|NEED_FXSR|NEED_CMOV|\ | ||
60 | NEED_XMM|NEED_XMM2) | ||
61 | #define SSE_MASK (NEED_XMM|NEED_XMM2) | ||
62 | |||
63 | #define REQUIRED_MASK1 (NEED_LM|NEED_3DNOW) | ||
64 | |||
65 | #define REQUIRED_MASK2 0 | ||
66 | #define REQUIRED_MASK3 0 | ||
67 | #define REQUIRED_MASK4 0 | ||
68 | #define REQUIRED_MASK5 0 | ||
69 | #define REQUIRED_MASK6 0 | ||
70 | #define REQUIRED_MASK7 0 | ||
71 | |||
5 | #endif | 72 | #endif |
diff --git a/include/asm-x86/required-features_32.h b/include/asm-x86/required-features_32.h deleted file mode 100644 index 618feb98f9f5..000000000000 --- a/include/asm-x86/required-features_32.h +++ /dev/null | |||
@@ -1,55 +0,0 @@ | |||
1 | #ifndef _ASM_REQUIRED_FEATURES_H | ||
2 | #define _ASM_REQUIRED_FEATURES_H 1 | ||
3 | |||
4 | /* Define minimum CPUID feature set for kernel These bits are checked | ||
5 | really early to actually display a visible error message before the | ||
6 | kernel dies. Make sure to assign features to the proper mask! | ||
7 | |||
8 | Some requirements that are not in CPUID yet are also in the | ||
9 | CONFIG_X86_MINIMUM_CPU_FAMILY which is checked too. | ||
10 | |||
11 | The real information is in arch/i386/Kconfig.cpu, this just converts | ||
12 | the CONFIGs into a bitmask */ | ||
13 | |||
14 | #ifndef CONFIG_MATH_EMULATION | ||
15 | # define NEED_FPU (1<<(X86_FEATURE_FPU & 31)) | ||
16 | #else | ||
17 | # define NEED_FPU 0 | ||
18 | #endif | ||
19 | |||
20 | #ifdef CONFIG_X86_PAE | ||
21 | # define NEED_PAE (1<<(X86_FEATURE_PAE & 31)) | ||
22 | #else | ||
23 | # define NEED_PAE 0 | ||
24 | #endif | ||
25 | |||
26 | #ifdef CONFIG_X86_CMOV | ||
27 | # define NEED_CMOV (1<<(X86_FEATURE_CMOV & 31)) | ||
28 | #else | ||
29 | # define NEED_CMOV 0 | ||
30 | #endif | ||
31 | |||
32 | #ifdef CONFIG_X86_PAE | ||
33 | # define NEED_CX8 (1<<(X86_FEATURE_CX8 & 31)) | ||
34 | #else | ||
35 | # define NEED_CX8 0 | ||
36 | #endif | ||
37 | |||
38 | #define REQUIRED_MASK0 (NEED_FPU|NEED_PAE|NEED_CMOV|NEED_CX8) | ||
39 | |||
40 | #ifdef CONFIG_X86_USE_3DNOW | ||
41 | # define NEED_3DNOW (1<<(X86_FEATURE_3DNOW & 31)) | ||
42 | #else | ||
43 | # define NEED_3DNOW 0 | ||
44 | #endif | ||
45 | |||
46 | #define REQUIRED_MASK1 (NEED_3DNOW) | ||
47 | |||
48 | #define REQUIRED_MASK2 0 | ||
49 | #define REQUIRED_MASK3 0 | ||
50 | #define REQUIRED_MASK4 0 | ||
51 | #define REQUIRED_MASK5 0 | ||
52 | #define REQUIRED_MASK6 0 | ||
53 | #define REQUIRED_MASK7 0 | ||
54 | |||
55 | #endif | ||
diff --git a/include/asm-x86/required-features_64.h b/include/asm-x86/required-features_64.h deleted file mode 100644 index e80d5761b00a..000000000000 --- a/include/asm-x86/required-features_64.h +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | #ifndef _ASM_REQUIRED_FEATURES_H | ||
2 | #define _ASM_REQUIRED_FEATURES_H 1 | ||
3 | |||
4 | /* Define minimum CPUID feature set for kernel These bits are checked | ||
5 | really early to actually display a visible error message before the | ||
6 | kernel dies. Make sure to assign features to the proper mask! | ||
7 | |||
8 | The real information is in arch/x86_64/Kconfig.cpu, this just converts | ||
9 | the CONFIGs into a bitmask */ | ||
10 | |||
11 | /* x86-64 baseline features */ | ||
12 | #define NEED_FPU (1<<(X86_FEATURE_FPU & 31)) | ||
13 | #define NEED_PSE (1<<(X86_FEATURE_PSE & 31)) | ||
14 | #define NEED_MSR (1<<(X86_FEATURE_MSR & 31)) | ||
15 | #define NEED_PAE (1<<(X86_FEATURE_PAE & 31)) | ||
16 | #define NEED_CX8 (1<<(X86_FEATURE_CX8 & 31)) | ||
17 | #define NEED_PGE (1<<(X86_FEATURE_PGE & 31)) | ||
18 | #define NEED_FXSR (1<<(X86_FEATURE_FXSR & 31)) | ||
19 | #define NEED_CMOV (1<<(X86_FEATURE_CMOV & 31)) | ||
20 | #define NEED_XMM (1<<(X86_FEATURE_XMM & 31)) | ||
21 | #define NEED_XMM2 (1<<(X86_FEATURE_XMM2 & 31)) | ||
22 | |||
23 | #define REQUIRED_MASK0 (NEED_FPU|NEED_PSE|NEED_MSR|NEED_PAE|\ | ||
24 | NEED_CX8|NEED_PGE|NEED_FXSR|NEED_CMOV|\ | ||
25 | NEED_XMM|NEED_XMM2) | ||
26 | #define SSE_MASK (NEED_XMM|NEED_XMM2) | ||
27 | |||
28 | /* x86-64 baseline features */ | ||
29 | #define NEED_LM (1<<(X86_FEATURE_LM & 31)) | ||
30 | |||
31 | #ifdef CONFIG_X86_USE_3DNOW | ||
32 | # define NEED_3DNOW (1<<(X86_FEATURE_3DNOW & 31)) | ||
33 | #else | ||
34 | # define NEED_3DNOW 0 | ||
35 | #endif | ||
36 | |||
37 | #define REQUIRED_MASK1 (NEED_LM|NEED_3DNOW) | ||
38 | |||
39 | #define REQUIRED_MASK2 0 | ||
40 | #define REQUIRED_MASK3 0 | ||
41 | #define REQUIRED_MASK4 0 | ||
42 | #define REQUIRED_MASK5 0 | ||
43 | #define REQUIRED_MASK6 0 | ||
44 | #define REQUIRED_MASK7 0 | ||
45 | |||
46 | #endif | ||
diff --git a/include/asm-x86/setup.h b/include/asm-x86/setup.h index 81c0d98bb1c8..24d786e07b49 100644 --- a/include/asm-x86/setup.h +++ b/include/asm-x86/setup.h | |||
@@ -1,13 +1,63 @@ | |||
1 | #ifndef _ASM_X86_SETUP_H | ||
2 | #define _ASM_X86_SETUP_H | ||
3 | |||
4 | #define COMMAND_LINE_SIZE 2048 | ||
5 | |||
1 | #ifdef __KERNEL__ | 6 | #ifdef __KERNEL__ |
2 | # ifdef CONFIG_X86_32 | 7 | |
3 | # include "setup_32.h" | 8 | #ifdef __i386__ |
4 | # else | 9 | |
5 | # include "setup_64.h" | 10 | #include <linux/pfn.h> |
6 | # endif | 11 | /* |
7 | #else | 12 | * Reserved space for vmalloc and iomap - defined in asm/page.h |
8 | # ifdef __i386__ | 13 | */ |
9 | # include "setup_32.h" | 14 | #define MAXMEM_PFN PFN_DOWN(MAXMEM) |
10 | # else | 15 | #define MAX_NONPAE_PFN (1 << 20) |
11 | # include "setup_64.h" | 16 | |
12 | # endif | 17 | #endif /* __i386__ */ |
18 | |||
19 | #define PARAM_SIZE 4096 /* sizeof(struct boot_params) */ | ||
20 | |||
21 | #define OLD_CL_MAGIC 0xA33F | ||
22 | #define OLD_CL_ADDRESS 0x020 /* Relative to real mode data */ | ||
23 | #define NEW_CL_POINTER 0x228 /* Relative to real mode data */ | ||
24 | |||
25 | #ifndef __ASSEMBLY__ | ||
26 | #include <asm/bootparam.h> | ||
27 | |||
28 | #ifndef _SETUP | ||
29 | |||
30 | /* | ||
31 | * This is set up by the setup-routine at boot-time | ||
32 | */ | ||
33 | extern struct boot_params boot_params; | ||
34 | |||
35 | #ifdef __i386__ | ||
36 | /* | ||
37 | * Do NOT EVER look at the BIOS memory size location. | ||
38 | * It does not work on many machines. | ||
39 | */ | ||
40 | #define LOWMEMSIZE() (0x9f000) | ||
41 | |||
42 | struct e820entry; | ||
43 | |||
44 | char * __init machine_specific_memory_setup(void); | ||
45 | char *memory_setup(void); | ||
46 | |||
47 | int __init copy_e820_map(struct e820entry * biosmap, int nr_map); | ||
48 | int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map); | ||
49 | void __init add_memory_region(unsigned long long start, | ||
50 | unsigned long long size, int type); | ||
51 | |||
52 | extern unsigned long init_pg_tables_end; | ||
53 | |||
54 | #ifndef CONFIG_PARAVIRT | ||
55 | #define paravirt_post_allocator_init() do {} while (0) | ||
13 | #endif | 56 | #endif |
57 | |||
58 | #endif /* __i386__ */ | ||
59 | #endif /* _SETUP */ | ||
60 | #endif /* __ASSEMBLY__ */ | ||
61 | #endif /* __KERNEL__ */ | ||
62 | |||
63 | #endif /* _ASM_X86_SETUP_H */ | ||
diff --git a/include/asm-x86/setup_32.h b/include/asm-x86/setup_32.h deleted file mode 100644 index 7a57ca8a1793..000000000000 --- a/include/asm-x86/setup_32.h +++ /dev/null | |||
@@ -1,63 +0,0 @@ | |||
1 | /* | ||
2 | * Just a place holder. We don't want to have to test x86 before | ||
3 | * we include stuff | ||
4 | */ | ||
5 | |||
6 | #ifndef _i386_SETUP_H | ||
7 | #define _i386_SETUP_H | ||
8 | |||
9 | #define COMMAND_LINE_SIZE 2048 | ||
10 | |||
11 | #ifdef __KERNEL__ | ||
12 | #include <linux/pfn.h> | ||
13 | |||
14 | /* | ||
15 | * Reserved space for vmalloc and iomap - defined in asm/page.h | ||
16 | */ | ||
17 | #define MAXMEM_PFN PFN_DOWN(MAXMEM) | ||
18 | #define MAX_NONPAE_PFN (1 << 20) | ||
19 | |||
20 | #define PARAM_SIZE 4096 | ||
21 | |||
22 | #define OLD_CL_MAGIC_ADDR 0x90020 | ||
23 | #define OLD_CL_MAGIC 0xA33F | ||
24 | #define OLD_CL_BASE_ADDR 0x90000 | ||
25 | #define OLD_CL_OFFSET 0x90022 | ||
26 | #define NEW_CL_POINTER 0x228 /* Relative to real mode data */ | ||
27 | |||
28 | #ifndef __ASSEMBLY__ | ||
29 | |||
30 | #include <asm/bootparam.h> | ||
31 | |||
32 | /* | ||
33 | * This is set up by the setup-routine at boot-time | ||
34 | */ | ||
35 | extern struct boot_params boot_params; | ||
36 | |||
37 | /* | ||
38 | * Do NOT EVER look at the BIOS memory size location. | ||
39 | * It does not work on many machines. | ||
40 | */ | ||
41 | #define LOWMEMSIZE() (0x9f000) | ||
42 | |||
43 | struct e820entry; | ||
44 | |||
45 | char * __init machine_specific_memory_setup(void); | ||
46 | char *memory_setup(void); | ||
47 | |||
48 | int __init copy_e820_map(struct e820entry * biosmap, int nr_map); | ||
49 | int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map); | ||
50 | void __init add_memory_region(unsigned long long start, | ||
51 | unsigned long long size, int type); | ||
52 | |||
53 | extern unsigned long init_pg_tables_end; | ||
54 | |||
55 | #ifndef CONFIG_PARAVIRT | ||
56 | #define paravirt_post_allocator_init() do {} while (0) | ||
57 | #endif | ||
58 | |||
59 | #endif /* __ASSEMBLY__ */ | ||
60 | |||
61 | #endif /* __KERNEL__ */ | ||
62 | |||
63 | #endif /* _i386_SETUP_H */ | ||
diff --git a/include/asm-x86/setup_64.h b/include/asm-x86/setup_64.h deleted file mode 100644 index a04aadcccf67..000000000000 --- a/include/asm-x86/setup_64.h +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | #ifndef _x8664_SETUP_H | ||
2 | #define _x8664_SETUP_H | ||
3 | |||
4 | #define COMMAND_LINE_SIZE 2048 | ||
5 | |||
6 | #ifdef __KERNEL__ | ||
7 | |||
8 | #ifndef __ASSEMBLY__ | ||
9 | #include <asm/bootparam.h> | ||
10 | |||
11 | /* | ||
12 | * This is set up by the setup-routine at boot-time | ||
13 | */ | ||
14 | extern struct boot_params boot_params; | ||
15 | |||
16 | #endif /* not __ASSEMBLY__ */ | ||
17 | #endif /* __KERNEL__ */ | ||
18 | |||
19 | #endif | ||
diff --git a/include/asm-x86/shmbuf.h b/include/asm-x86/shmbuf.h index e85f1cb11217..b51413b74971 100644 --- a/include/asm-x86/shmbuf.h +++ b/include/asm-x86/shmbuf.h | |||
@@ -1,13 +1,51 @@ | |||
1 | #ifdef __KERNEL__ | 1 | #ifndef _ASM_X86_SHMBUF_H |
2 | # ifdef CONFIG_X86_32 | 2 | #define _ASM_X86_SHMBUF_H |
3 | # include "shmbuf_32.h" | 3 | |
4 | # else | 4 | /* |
5 | # include "shmbuf_64.h" | 5 | * The shmid64_ds structure for x86 architecture. |
6 | # endif | 6 | * Note extra padding because this structure is passed back and forth |
7 | #else | 7 | * between kernel and user space. |
8 | # ifdef __i386__ | 8 | * |
9 | # include "shmbuf_32.h" | 9 | * Pad space on 32 bit is left for: |
10 | # else | 10 | * - 64-bit time_t to solve y2038 problem |
11 | # include "shmbuf_64.h" | 11 | * - 2 miscellaneous 32-bit values |
12 | # endif | 12 | * |
13 | * Pad space on 64 bit is left for: | ||
14 | * - 2 miscellaneous 64-bit values | ||
15 | */ | ||
16 | |||
17 | struct shmid64_ds { | ||
18 | struct ipc64_perm shm_perm; /* operation perms */ | ||
19 | size_t shm_segsz; /* size of segment (bytes) */ | ||
20 | __kernel_time_t shm_atime; /* last attach time */ | ||
21 | #ifdef __i386__ | ||
22 | unsigned long __unused1; | ||
13 | #endif | 23 | #endif |
24 | __kernel_time_t shm_dtime; /* last detach time */ | ||
25 | #ifdef __i386__ | ||
26 | unsigned long __unused2; | ||
27 | #endif | ||
28 | __kernel_time_t shm_ctime; /* last change time */ | ||
29 | #ifdef __i386__ | ||
30 | unsigned long __unused3; | ||
31 | #endif | ||
32 | __kernel_pid_t shm_cpid; /* pid of creator */ | ||
33 | __kernel_pid_t shm_lpid; /* pid of last operator */ | ||
34 | unsigned long shm_nattch; /* no. of current attaches */ | ||
35 | unsigned long __unused4; | ||
36 | unsigned long __unused5; | ||
37 | }; | ||
38 | |||
39 | struct shminfo64 { | ||
40 | unsigned long shmmax; | ||
41 | unsigned long shmmin; | ||
42 | unsigned long shmmni; | ||
43 | unsigned long shmseg; | ||
44 | unsigned long shmall; | ||
45 | unsigned long __unused1; | ||
46 | unsigned long __unused2; | ||
47 | unsigned long __unused3; | ||
48 | unsigned long __unused4; | ||
49 | }; | ||
50 | |||
51 | #endif /* _ASM_X86_SHMBUF_H */ | ||
diff --git a/include/asm-x86/shmbuf_32.h b/include/asm-x86/shmbuf_32.h deleted file mode 100644 index d1cdc3cb079b..000000000000 --- a/include/asm-x86/shmbuf_32.h +++ /dev/null | |||
@@ -1,42 +0,0 @@ | |||
1 | #ifndef _I386_SHMBUF_H | ||
2 | #define _I386_SHMBUF_H | ||
3 | |||
4 | /* | ||
5 | * The shmid64_ds structure for i386 architecture. | ||
6 | * Note extra padding because this structure is passed back and forth | ||
7 | * between kernel and user space. | ||
8 | * | ||
9 | * Pad space is left for: | ||
10 | * - 64-bit time_t to solve y2038 problem | ||
11 | * - 2 miscellaneous 32-bit values | ||
12 | */ | ||
13 | |||
14 | struct shmid64_ds { | ||
15 | struct ipc64_perm shm_perm; /* operation perms */ | ||
16 | size_t shm_segsz; /* size of segment (bytes) */ | ||
17 | __kernel_time_t shm_atime; /* last attach time */ | ||
18 | unsigned long __unused1; | ||
19 | __kernel_time_t shm_dtime; /* last detach time */ | ||
20 | unsigned long __unused2; | ||
21 | __kernel_time_t shm_ctime; /* last change time */ | ||
22 | unsigned long __unused3; | ||
23 | __kernel_pid_t shm_cpid; /* pid of creator */ | ||
24 | __kernel_pid_t shm_lpid; /* pid of last operator */ | ||
25 | unsigned long shm_nattch; /* no. of current attaches */ | ||
26 | unsigned long __unused4; | ||
27 | unsigned long __unused5; | ||
28 | }; | ||
29 | |||
30 | struct shminfo64 { | ||
31 | unsigned long shmmax; | ||
32 | unsigned long shmmin; | ||
33 | unsigned long shmmni; | ||
34 | unsigned long shmseg; | ||
35 | unsigned long shmall; | ||
36 | unsigned long __unused1; | ||
37 | unsigned long __unused2; | ||
38 | unsigned long __unused3; | ||
39 | unsigned long __unused4; | ||
40 | }; | ||
41 | |||
42 | #endif /* _I386_SHMBUF_H */ | ||
diff --git a/include/asm-x86/shmbuf_64.h b/include/asm-x86/shmbuf_64.h deleted file mode 100644 index 5a6d6dda7c48..000000000000 --- a/include/asm-x86/shmbuf_64.h +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | #ifndef _X8664_SHMBUF_H | ||
2 | #define _X8664_SHMBUF_H | ||
3 | |||
4 | /* | ||
5 | * The shmid64_ds structure for x8664 architecture. | ||
6 | * Note extra padding because this structure is passed back and forth | ||
7 | * between kernel and user space. | ||
8 | * | ||
9 | * Pad space is left for: | ||
10 | * - 2 miscellaneous 64-bit values | ||
11 | */ | ||
12 | |||
13 | struct shmid64_ds { | ||
14 | struct ipc64_perm shm_perm; /* operation perms */ | ||
15 | size_t shm_segsz; /* size of segment (bytes) */ | ||
16 | __kernel_time_t shm_atime; /* last attach time */ | ||
17 | __kernel_time_t shm_dtime; /* last detach time */ | ||
18 | __kernel_time_t shm_ctime; /* last change time */ | ||
19 | __kernel_pid_t shm_cpid; /* pid of creator */ | ||
20 | __kernel_pid_t shm_lpid; /* pid of last operator */ | ||
21 | unsigned long shm_nattch; /* no. of current attaches */ | ||
22 | unsigned long __unused4; | ||
23 | unsigned long __unused5; | ||
24 | }; | ||
25 | |||
26 | struct shminfo64 { | ||
27 | unsigned long shmmax; | ||
28 | unsigned long shmmin; | ||
29 | unsigned long shmmni; | ||
30 | unsigned long shmseg; | ||
31 | unsigned long shmall; | ||
32 | unsigned long __unused1; | ||
33 | unsigned long __unused2; | ||
34 | unsigned long __unused3; | ||
35 | unsigned long __unused4; | ||
36 | }; | ||
37 | |||
38 | #endif | ||
diff --git a/include/asm-x86/sigcontext.h b/include/asm-x86/sigcontext.h index 0d16ceff1599..c047f9dc3423 100644 --- a/include/asm-x86/sigcontext.h +++ b/include/asm-x86/sigcontext.h | |||
@@ -1,13 +1,138 @@ | |||
1 | #ifdef __KERNEL__ | 1 | #ifndef _ASM_X86_SIGCONTEXT_H |
2 | # ifdef CONFIG_X86_32 | 2 | #define _ASM_X86_SIGCONTEXT_H |
3 | # include "sigcontext_32.h" | 3 | |
4 | # else | 4 | #include <linux/compiler.h> |
5 | # include "sigcontext_64.h" | 5 | #include <asm/types.h> |
6 | # endif | 6 | |
7 | #else | 7 | #ifdef __i386__ |
8 | # ifdef __i386__ | 8 | /* |
9 | # include "sigcontext_32.h" | 9 | * As documented in the iBCS2 standard.. |
10 | # else | 10 | * |
11 | # include "sigcontext_64.h" | 11 | * The first part of "struct _fpstate" is just the normal i387 |
12 | # endif | 12 | * hardware setup, the extra "status" word is used to save the |
13 | * coprocessor status word before entering the handler. | ||
14 | * | ||
15 | * Pentium III FXSR, SSE support | ||
16 | * Gareth Hughes <gareth@valinux.com>, May 2000 | ||
17 | * | ||
18 | * The FPU state data structure has had to grow to accommodate the | ||
19 | * extended FPU state required by the Streaming SIMD Extensions. | ||
20 | * There is no documented standard to accomplish this at the moment. | ||
21 | */ | ||
22 | struct _fpreg { | ||
23 | unsigned short significand[4]; | ||
24 | unsigned short exponent; | ||
25 | }; | ||
26 | |||
27 | struct _fpxreg { | ||
28 | unsigned short significand[4]; | ||
29 | unsigned short exponent; | ||
30 | unsigned short padding[3]; | ||
31 | }; | ||
32 | |||
33 | struct _xmmreg { | ||
34 | unsigned long element[4]; | ||
35 | }; | ||
36 | |||
37 | struct _fpstate { | ||
38 | /* Regular FPU environment */ | ||
39 | unsigned long cw; | ||
40 | unsigned long sw; | ||
41 | unsigned long tag; | ||
42 | unsigned long ipoff; | ||
43 | unsigned long cssel; | ||
44 | unsigned long dataoff; | ||
45 | unsigned long datasel; | ||
46 | struct _fpreg _st[8]; | ||
47 | unsigned short status; | ||
48 | unsigned short magic; /* 0xffff = regular FPU data only */ | ||
49 | |||
50 | /* FXSR FPU environment */ | ||
51 | unsigned long _fxsr_env[6]; /* FXSR FPU env is ignored */ | ||
52 | unsigned long mxcsr; | ||
53 | unsigned long reserved; | ||
54 | struct _fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */ | ||
55 | struct _xmmreg _xmm[8]; | ||
56 | unsigned long padding[56]; | ||
57 | }; | ||
58 | |||
59 | #define X86_FXSR_MAGIC 0x0000 | ||
60 | |||
61 | struct sigcontext { | ||
62 | unsigned short gs, __gsh; | ||
63 | unsigned short fs, __fsh; | ||
64 | unsigned short es, __esh; | ||
65 | unsigned short ds, __dsh; | ||
66 | unsigned long edi; | ||
67 | unsigned long esi; | ||
68 | unsigned long ebp; | ||
69 | unsigned long esp; | ||
70 | unsigned long ebx; | ||
71 | unsigned long edx; | ||
72 | unsigned long ecx; | ||
73 | unsigned long eax; | ||
74 | unsigned long trapno; | ||
75 | unsigned long err; | ||
76 | unsigned long eip; | ||
77 | unsigned short cs, __csh; | ||
78 | unsigned long eflags; | ||
79 | unsigned long esp_at_signal; | ||
80 | unsigned short ss, __ssh; | ||
81 | struct _fpstate __user * fpstate; | ||
82 | unsigned long oldmask; | ||
83 | unsigned long cr2; | ||
84 | }; | ||
85 | |||
86 | #else /* __i386__ */ | ||
87 | |||
88 | /* FXSAVE frame */ | ||
89 | /* Note: reserved1/2 may someday contain valuable data. Always save/restore | ||
90 | them when you change signal frames. */ | ||
91 | struct _fpstate { | ||
92 | __u16 cwd; | ||
93 | __u16 swd; | ||
94 | __u16 twd; /* Note this is not the same as the 32bit/x87/FSAVE twd */ | ||
95 | __u16 fop; | ||
96 | __u64 rip; | ||
97 | __u64 rdp; | ||
98 | __u32 mxcsr; | ||
99 | __u32 mxcsr_mask; | ||
100 | __u32 st_space[32]; /* 8*16 bytes for each FP-reg */ | ||
101 | __u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg */ | ||
102 | __u32 reserved2[24]; | ||
103 | }; | ||
104 | |||
105 | struct sigcontext { | ||
106 | unsigned long r8; | ||
107 | unsigned long r9; | ||
108 | unsigned long r10; | ||
109 | unsigned long r11; | ||
110 | unsigned long r12; | ||
111 | unsigned long r13; | ||
112 | unsigned long r14; | ||
113 | unsigned long r15; | ||
114 | unsigned long rdi; | ||
115 | unsigned long rsi; | ||
116 | unsigned long rbp; | ||
117 | unsigned long rbx; | ||
118 | unsigned long rdx; | ||
119 | unsigned long rax; | ||
120 | unsigned long rcx; | ||
121 | unsigned long rsp; | ||
122 | unsigned long rip; | ||
123 | unsigned long eflags; /* RFLAGS */ | ||
124 | unsigned short cs; | ||
125 | unsigned short gs; | ||
126 | unsigned short fs; | ||
127 | unsigned short __pad0; | ||
128 | unsigned long err; | ||
129 | unsigned long trapno; | ||
130 | unsigned long oldmask; | ||
131 | unsigned long cr2; | ||
132 | struct _fpstate __user *fpstate; /* zero when no FPU context */ | ||
133 | unsigned long reserved1[8]; | ||
134 | }; | ||
135 | |||
136 | #endif /* !__i386__ */ | ||
137 | |||
13 | #endif | 138 | #endif |
diff --git a/include/asm-x86/sigcontext_32.h b/include/asm-x86/sigcontext_32.h deleted file mode 100644 index aaef089a7787..000000000000 --- a/include/asm-x86/sigcontext_32.h +++ /dev/null | |||
@@ -1,85 +0,0 @@ | |||
1 | #ifndef _ASMi386_SIGCONTEXT_H | ||
2 | #define _ASMi386_SIGCONTEXT_H | ||
3 | |||
4 | #include <linux/compiler.h> | ||
5 | |||
6 | /* | ||
7 | * As documented in the iBCS2 standard.. | ||
8 | * | ||
9 | * The first part of "struct _fpstate" is just the normal i387 | ||
10 | * hardware setup, the extra "status" word is used to save the | ||
11 | * coprocessor status word before entering the handler. | ||
12 | * | ||
13 | * Pentium III FXSR, SSE support | ||
14 | * Gareth Hughes <gareth@valinux.com>, May 2000 | ||
15 | * | ||
16 | * The FPU state data structure has had to grow to accommodate the | ||
17 | * extended FPU state required by the Streaming SIMD Extensions. | ||
18 | * There is no documented standard to accomplish this at the moment. | ||
19 | */ | ||
20 | struct _fpreg { | ||
21 | unsigned short significand[4]; | ||
22 | unsigned short exponent; | ||
23 | }; | ||
24 | |||
25 | struct _fpxreg { | ||
26 | unsigned short significand[4]; | ||
27 | unsigned short exponent; | ||
28 | unsigned short padding[3]; | ||
29 | }; | ||
30 | |||
31 | struct _xmmreg { | ||
32 | unsigned long element[4]; | ||
33 | }; | ||
34 | |||
35 | struct _fpstate { | ||
36 | /* Regular FPU environment */ | ||
37 | unsigned long cw; | ||
38 | unsigned long sw; | ||
39 | unsigned long tag; | ||
40 | unsigned long ipoff; | ||
41 | unsigned long cssel; | ||
42 | unsigned long dataoff; | ||
43 | unsigned long datasel; | ||
44 | struct _fpreg _st[8]; | ||
45 | unsigned short status; | ||
46 | unsigned short magic; /* 0xffff = regular FPU data only */ | ||
47 | |||
48 | /* FXSR FPU environment */ | ||
49 | unsigned long _fxsr_env[6]; /* FXSR FPU env is ignored */ | ||
50 | unsigned long mxcsr; | ||
51 | unsigned long reserved; | ||
52 | struct _fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */ | ||
53 | struct _xmmreg _xmm[8]; | ||
54 | unsigned long padding[56]; | ||
55 | }; | ||
56 | |||
57 | #define X86_FXSR_MAGIC 0x0000 | ||
58 | |||
59 | struct sigcontext { | ||
60 | unsigned short gs, __gsh; | ||
61 | unsigned short fs, __fsh; | ||
62 | unsigned short es, __esh; | ||
63 | unsigned short ds, __dsh; | ||
64 | unsigned long edi; | ||
65 | unsigned long esi; | ||
66 | unsigned long ebp; | ||
67 | unsigned long esp; | ||
68 | unsigned long ebx; | ||
69 | unsigned long edx; | ||
70 | unsigned long ecx; | ||
71 | unsigned long eax; | ||
72 | unsigned long trapno; | ||
73 | unsigned long err; | ||
74 | unsigned long eip; | ||
75 | unsigned short cs, __csh; | ||
76 | unsigned long eflags; | ||
77 | unsigned long esp_at_signal; | ||
78 | unsigned short ss, __ssh; | ||
79 | struct _fpstate __user * fpstate; | ||
80 | unsigned long oldmask; | ||
81 | unsigned long cr2; | ||
82 | }; | ||
83 | |||
84 | |||
85 | #endif | ||
diff --git a/include/asm-x86/sigcontext_64.h b/include/asm-x86/sigcontext_64.h deleted file mode 100644 index b4e40236666c..000000000000 --- a/include/asm-x86/sigcontext_64.h +++ /dev/null | |||
@@ -1,55 +0,0 @@ | |||
1 | #ifndef _ASM_X86_64_SIGCONTEXT_H | ||
2 | #define _ASM_X86_64_SIGCONTEXT_H | ||
3 | |||
4 | #include <asm/types.h> | ||
5 | #include <linux/compiler.h> | ||
6 | |||
7 | /* FXSAVE frame */ | ||
8 | /* Note: reserved1/2 may someday contain valuable data. Always save/restore | ||
9 | them when you change signal frames. */ | ||
10 | struct _fpstate { | ||
11 | __u16 cwd; | ||
12 | __u16 swd; | ||
13 | __u16 twd; /* Note this is not the same as the 32bit/x87/FSAVE twd */ | ||
14 | __u16 fop; | ||
15 | __u64 rip; | ||
16 | __u64 rdp; | ||
17 | __u32 mxcsr; | ||
18 | __u32 mxcsr_mask; | ||
19 | __u32 st_space[32]; /* 8*16 bytes for each FP-reg */ | ||
20 | __u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg */ | ||
21 | __u32 reserved2[24]; | ||
22 | }; | ||
23 | |||
24 | struct sigcontext { | ||
25 | unsigned long r8; | ||
26 | unsigned long r9; | ||
27 | unsigned long r10; | ||
28 | unsigned long r11; | ||
29 | unsigned long r12; | ||
30 | unsigned long r13; | ||
31 | unsigned long r14; | ||
32 | unsigned long r15; | ||
33 | unsigned long rdi; | ||
34 | unsigned long rsi; | ||
35 | unsigned long rbp; | ||
36 | unsigned long rbx; | ||
37 | unsigned long rdx; | ||
38 | unsigned long rax; | ||
39 | unsigned long rcx; | ||
40 | unsigned long rsp; | ||
41 | unsigned long rip; | ||
42 | unsigned long eflags; /* RFLAGS */ | ||
43 | unsigned short cs; | ||
44 | unsigned short gs; | ||
45 | unsigned short fs; | ||
46 | unsigned short __pad0; | ||
47 | unsigned long err; | ||
48 | unsigned long trapno; | ||
49 | unsigned long oldmask; | ||
50 | unsigned long cr2; | ||
51 | struct _fpstate __user *fpstate; /* zero when no FPU context */ | ||
52 | unsigned long reserved1[8]; | ||
53 | }; | ||
54 | |||
55 | #endif | ||
diff --git a/include/asm-x86/signal.h b/include/asm-x86/signal.h index bf5a63f457da..987a422a2c78 100644 --- a/include/asm-x86/signal.h +++ b/include/asm-x86/signal.h | |||
@@ -1,13 +1,266 @@ | |||
1 | #ifndef _ASM_X86_SIGNAL_H | ||
2 | #define _ASM_X86_SIGNAL_H | ||
3 | |||
4 | #ifndef __ASSEMBLY__ | ||
5 | #include <linux/types.h> | ||
6 | #include <linux/time.h> | ||
7 | #include <linux/compiler.h> | ||
8 | |||
9 | /* Avoid too many header ordering problems. */ | ||
10 | struct siginfo; | ||
11 | |||
1 | #ifdef __KERNEL__ | 12 | #ifdef __KERNEL__ |
2 | # ifdef CONFIG_X86_32 | 13 | #include <linux/linkage.h> |
3 | # include "signal_32.h" | 14 | |
4 | # else | 15 | /* Most things should be clean enough to redefine this at will, if care |
5 | # include "signal_64.h" | 16 | is taken to make libc match. */ |
6 | # endif | 17 | |
18 | #define _NSIG 64 | ||
19 | |||
20 | #ifdef __i386__ | ||
21 | # define _NSIG_BPW 32 | ||
7 | #else | 22 | #else |
8 | # ifdef __i386__ | 23 | # define _NSIG_BPW 64 |
9 | # include "signal_32.h" | 24 | #endif |
10 | # else | 25 | |
11 | # include "signal_64.h" | 26 | #define _NSIG_WORDS (_NSIG / _NSIG_BPW) |
12 | # endif | 27 | |
28 | typedef unsigned long old_sigset_t; /* at least 32 bits */ | ||
29 | |||
30 | typedef struct { | ||
31 | unsigned long sig[_NSIG_WORDS]; | ||
32 | } sigset_t; | ||
33 | |||
34 | #else | ||
35 | /* Here we must cater to libcs that poke about in kernel headers. */ | ||
36 | |||
37 | #define NSIG 32 | ||
38 | typedef unsigned long sigset_t; | ||
39 | |||
40 | #endif /* __KERNEL__ */ | ||
41 | #endif /* __ASSEMBLY__ */ | ||
42 | |||
43 | #define SIGHUP 1 | ||
44 | #define SIGINT 2 | ||
45 | #define SIGQUIT 3 | ||
46 | #define SIGILL 4 | ||
47 | #define SIGTRAP 5 | ||
48 | #define SIGABRT 6 | ||
49 | #define SIGIOT 6 | ||
50 | #define SIGBUS 7 | ||
51 | #define SIGFPE 8 | ||
52 | #define SIGKILL 9 | ||
53 | #define SIGUSR1 10 | ||
54 | #define SIGSEGV 11 | ||
55 | #define SIGUSR2 12 | ||
56 | #define SIGPIPE 13 | ||
57 | #define SIGALRM 14 | ||
58 | #define SIGTERM 15 | ||
59 | #define SIGSTKFLT 16 | ||
60 | #define SIGCHLD 17 | ||
61 | #define SIGCONT 18 | ||
62 | #define SIGSTOP 19 | ||
63 | #define SIGTSTP 20 | ||
64 | #define SIGTTIN 21 | ||
65 | #define SIGTTOU 22 | ||
66 | #define SIGURG 23 | ||
67 | #define SIGXCPU 24 | ||
68 | #define SIGXFSZ 25 | ||
69 | #define SIGVTALRM 26 | ||
70 | #define SIGPROF 27 | ||
71 | #define SIGWINCH 28 | ||
72 | #define SIGIO 29 | ||
73 | #define SIGPOLL SIGIO | ||
74 | /* | ||
75 | #define SIGLOST 29 | ||
76 | */ | ||
77 | #define SIGPWR 30 | ||
78 | #define SIGSYS 31 | ||
79 | #define SIGUNUSED 31 | ||
80 | |||
81 | /* These should not be considered constants from userland. */ | ||
82 | #define SIGRTMIN 32 | ||
83 | #define SIGRTMAX _NSIG | ||
84 | |||
85 | /* | ||
86 | * SA_FLAGS values: | ||
87 | * | ||
88 | * SA_ONSTACK indicates that a registered stack_t will be used. | ||
89 | * SA_RESTART flag to get restarting signals (which were the default long ago) | ||
90 | * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. | ||
91 | * SA_RESETHAND clears the handler when the signal is delivered. | ||
92 | * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. | ||
93 | * SA_NODEFER prevents the current signal from being masked in the handler. | ||
94 | * | ||
95 | * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single | ||
96 | * Unix names RESETHAND and NODEFER respectively. | ||
97 | */ | ||
98 | #define SA_NOCLDSTOP 0x00000001u | ||
99 | #define SA_NOCLDWAIT 0x00000002u | ||
100 | #define SA_SIGINFO 0x00000004u | ||
101 | #define SA_ONSTACK 0x08000000u | ||
102 | #define SA_RESTART 0x10000000u | ||
103 | #define SA_NODEFER 0x40000000u | ||
104 | #define SA_RESETHAND 0x80000000u | ||
105 | |||
106 | #define SA_NOMASK SA_NODEFER | ||
107 | #define SA_ONESHOT SA_RESETHAND | ||
108 | |||
109 | #define SA_RESTORER 0x04000000 | ||
110 | |||
111 | /* | ||
112 | * sigaltstack controls | ||
113 | */ | ||
114 | #define SS_ONSTACK 1 | ||
115 | #define SS_DISABLE 2 | ||
116 | |||
117 | #define MINSIGSTKSZ 2048 | ||
118 | #define SIGSTKSZ 8192 | ||
119 | |||
120 | #include <asm-generic/signal.h> | ||
121 | |||
122 | #ifndef __ASSEMBLY__ | ||
123 | |||
124 | #ifdef __i386__ | ||
125 | # ifdef __KERNEL__ | ||
126 | struct old_sigaction { | ||
127 | __sighandler_t sa_handler; | ||
128 | old_sigset_t sa_mask; | ||
129 | unsigned long sa_flags; | ||
130 | __sigrestore_t sa_restorer; | ||
131 | }; | ||
132 | |||
133 | struct sigaction { | ||
134 | __sighandler_t sa_handler; | ||
135 | unsigned long sa_flags; | ||
136 | __sigrestore_t sa_restorer; | ||
137 | sigset_t sa_mask; /* mask last for extensibility */ | ||
138 | }; | ||
139 | |||
140 | struct k_sigaction { | ||
141 | struct sigaction sa; | ||
142 | }; | ||
143 | # else /* __KERNEL__ */ | ||
144 | /* Here we must cater to libcs that poke about in kernel headers. */ | ||
145 | |||
146 | struct sigaction { | ||
147 | union { | ||
148 | __sighandler_t _sa_handler; | ||
149 | void (*_sa_sigaction)(int, struct siginfo *, void *); | ||
150 | } _u; | ||
151 | sigset_t sa_mask; | ||
152 | unsigned long sa_flags; | ||
153 | void (*sa_restorer)(void); | ||
154 | }; | ||
155 | |||
156 | #define sa_handler _u._sa_handler | ||
157 | #define sa_sigaction _u._sa_sigaction | ||
158 | |||
159 | # endif /* ! __KERNEL__ */ | ||
160 | #else /* __i386__ */ | ||
161 | |||
162 | struct sigaction { | ||
163 | __sighandler_t sa_handler; | ||
164 | unsigned long sa_flags; | ||
165 | __sigrestore_t sa_restorer; | ||
166 | sigset_t sa_mask; /* mask last for extensibility */ | ||
167 | }; | ||
168 | |||
169 | struct k_sigaction { | ||
170 | struct sigaction sa; | ||
171 | }; | ||
172 | |||
173 | #endif /* !__i386__ */ | ||
174 | |||
175 | typedef struct sigaltstack { | ||
176 | void __user *ss_sp; | ||
177 | int ss_flags; | ||
178 | size_t ss_size; | ||
179 | } stack_t; | ||
180 | |||
181 | #ifdef __KERNEL__ | ||
182 | #include <asm/sigcontext.h> | ||
183 | |||
184 | #ifdef __386__ | ||
185 | |||
186 | #define __HAVE_ARCH_SIG_BITOPS | ||
187 | |||
188 | #define sigaddset(set,sig) \ | ||
189 | (__builtin_constantp(sig) ? \ | ||
190 | __const_sigaddset((set),(sig)) : \ | ||
191 | __gen_sigaddset((set),(sig))) | ||
192 | |||
193 | static __inline__ void __gen_sigaddset(sigset_t *set, int _sig) | ||
194 | { | ||
195 | __asm__("btsl %1,%0" : "+m"(*set) : "Ir"(_sig - 1) : "cc"); | ||
196 | } | ||
197 | |||
198 | static __inline__ void __const_sigaddset(sigset_t *set, int _sig) | ||
199 | { | ||
200 | unsigned long sig = _sig - 1; | ||
201 | set->sig[sig / _NSIG_BPW] |= 1 << (sig % _NSIG_BPW); | ||
202 | } | ||
203 | |||
204 | #define sigdelset(set,sig) \ | ||
205 | (__builtin_constant_p(sig) ? \ | ||
206 | __const_sigdelset((set),(sig)) : \ | ||
207 | __gen_sigdelset((set),(sig))) | ||
208 | |||
209 | |||
210 | static __inline__ void __gen_sigdelset(sigset_t *set, int _sig) | ||
211 | { | ||
212 | __asm__("btrl %1,%0" : "+m"(*set) : "Ir"(_sig - 1) : "cc"); | ||
213 | } | ||
214 | |||
215 | static __inline__ void __const_sigdelset(sigset_t *set, int _sig) | ||
216 | { | ||
217 | unsigned long sig = _sig - 1; | ||
218 | set->sig[sig / _NSIG_BPW] &= ~(1 << (sig % _NSIG_BPW)); | ||
219 | } | ||
220 | |||
221 | static __inline__ int __const_sigismember(sigset_t *set, int _sig) | ||
222 | { | ||
223 | unsigned long sig = _sig - 1; | ||
224 | return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW)); | ||
225 | } | ||
226 | |||
227 | static __inline__ int __gen_sigismember(sigset_t *set, int _sig) | ||
228 | { | ||
229 | int ret; | ||
230 | __asm__("btl %2,%1\n\tsbbl %0,%0" | ||
231 | : "=r"(ret) : "m"(*set), "Ir"(_sig-1) : "cc"); | ||
232 | return ret; | ||
233 | } | ||
234 | |||
235 | #define sigismember(set,sig) \ | ||
236 | (__builtin_constant_p(sig) ? \ | ||
237 | __const_sigismember((set),(sig)) : \ | ||
238 | __gen_sigismember((set),(sig))) | ||
239 | |||
240 | static __inline__ int sigfindinword(unsigned long word) | ||
241 | { | ||
242 | __asm__("bsfl %1,%0" : "=r"(word) : "rm"(word) : "cc"); | ||
243 | return word; | ||
244 | } | ||
245 | |||
246 | struct pt_regs; | ||
247 | |||
248 | #define ptrace_signal_deliver(regs, cookie) \ | ||
249 | do { \ | ||
250 | if (current->ptrace & PT_DTRACE) { \ | ||
251 | current->ptrace &= ~PT_DTRACE; \ | ||
252 | (regs)->eflags &= ~TF_MASK; \ | ||
253 | } \ | ||
254 | } while (0) | ||
255 | |||
256 | #else /* __i386__ */ | ||
257 | |||
258 | #undef __HAVE_ARCH_SIG_BITOPS | ||
259 | |||
260 | #define ptrace_signal_deliver(regs, cookie) do { } while (0) | ||
261 | |||
262 | #endif /* !__i386__ */ | ||
263 | #endif /* __KERNEL__ */ | ||
264 | #endif /* __ASSEMBLY__ */ | ||
265 | |||
13 | #endif | 266 | #endif |
diff --git a/include/asm-x86/signal_32.h b/include/asm-x86/signal_32.h deleted file mode 100644 index c3e8adec5918..000000000000 --- a/include/asm-x86/signal_32.h +++ /dev/null | |||
@@ -1,232 +0,0 @@ | |||
1 | #ifndef _ASMi386_SIGNAL_H | ||
2 | #define _ASMi386_SIGNAL_H | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | #include <linux/time.h> | ||
6 | #include <linux/compiler.h> | ||
7 | |||
8 | /* Avoid too many header ordering problems. */ | ||
9 | struct siginfo; | ||
10 | |||
11 | #ifdef __KERNEL__ | ||
12 | |||
13 | #include <linux/linkage.h> | ||
14 | |||
15 | /* Most things should be clean enough to redefine this at will, if care | ||
16 | is taken to make libc match. */ | ||
17 | |||
18 | #define _NSIG 64 | ||
19 | #define _NSIG_BPW 32 | ||
20 | #define _NSIG_WORDS (_NSIG / _NSIG_BPW) | ||
21 | |||
22 | typedef unsigned long old_sigset_t; /* at least 32 bits */ | ||
23 | |||
24 | typedef struct { | ||
25 | unsigned long sig[_NSIG_WORDS]; | ||
26 | } sigset_t; | ||
27 | |||
28 | #else | ||
29 | /* Here we must cater to libcs that poke about in kernel headers. */ | ||
30 | |||
31 | #define NSIG 32 | ||
32 | typedef unsigned long sigset_t; | ||
33 | |||
34 | #endif /* __KERNEL__ */ | ||
35 | |||
36 | #define SIGHUP 1 | ||
37 | #define SIGINT 2 | ||
38 | #define SIGQUIT 3 | ||
39 | #define SIGILL 4 | ||
40 | #define SIGTRAP 5 | ||
41 | #define SIGABRT 6 | ||
42 | #define SIGIOT 6 | ||
43 | #define SIGBUS 7 | ||
44 | #define SIGFPE 8 | ||
45 | #define SIGKILL 9 | ||
46 | #define SIGUSR1 10 | ||
47 | #define SIGSEGV 11 | ||
48 | #define SIGUSR2 12 | ||
49 | #define SIGPIPE 13 | ||
50 | #define SIGALRM 14 | ||
51 | #define SIGTERM 15 | ||
52 | #define SIGSTKFLT 16 | ||
53 | #define SIGCHLD 17 | ||
54 | #define SIGCONT 18 | ||
55 | #define SIGSTOP 19 | ||
56 | #define SIGTSTP 20 | ||
57 | #define SIGTTIN 21 | ||
58 | #define SIGTTOU 22 | ||
59 | #define SIGURG 23 | ||
60 | #define SIGXCPU 24 | ||
61 | #define SIGXFSZ 25 | ||
62 | #define SIGVTALRM 26 | ||
63 | #define SIGPROF 27 | ||
64 | #define SIGWINCH 28 | ||
65 | #define SIGIO 29 | ||
66 | #define SIGPOLL SIGIO | ||
67 | /* | ||
68 | #define SIGLOST 29 | ||
69 | */ | ||
70 | #define SIGPWR 30 | ||
71 | #define SIGSYS 31 | ||
72 | #define SIGUNUSED 31 | ||
73 | |||
74 | /* These should not be considered constants from userland. */ | ||
75 | #define SIGRTMIN 32 | ||
76 | #define SIGRTMAX _NSIG | ||
77 | |||
78 | /* | ||
79 | * SA_FLAGS values: | ||
80 | * | ||
81 | * SA_ONSTACK indicates that a registered stack_t will be used. | ||
82 | * SA_RESTART flag to get restarting signals (which were the default long ago) | ||
83 | * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. | ||
84 | * SA_RESETHAND clears the handler when the signal is delivered. | ||
85 | * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. | ||
86 | * SA_NODEFER prevents the current signal from being masked in the handler. | ||
87 | * | ||
88 | * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single | ||
89 | * Unix names RESETHAND and NODEFER respectively. | ||
90 | */ | ||
91 | #define SA_NOCLDSTOP 0x00000001u | ||
92 | #define SA_NOCLDWAIT 0x00000002u | ||
93 | #define SA_SIGINFO 0x00000004u | ||
94 | #define SA_ONSTACK 0x08000000u | ||
95 | #define SA_RESTART 0x10000000u | ||
96 | #define SA_NODEFER 0x40000000u | ||
97 | #define SA_RESETHAND 0x80000000u | ||
98 | |||
99 | #define SA_NOMASK SA_NODEFER | ||
100 | #define SA_ONESHOT SA_RESETHAND | ||
101 | |||
102 | #define SA_RESTORER 0x04000000 | ||
103 | |||
104 | /* | ||
105 | * sigaltstack controls | ||
106 | */ | ||
107 | #define SS_ONSTACK 1 | ||
108 | #define SS_DISABLE 2 | ||
109 | |||
110 | #define MINSIGSTKSZ 2048 | ||
111 | #define SIGSTKSZ 8192 | ||
112 | |||
113 | #include <asm-generic/signal.h> | ||
114 | |||
115 | #ifdef __KERNEL__ | ||
116 | struct old_sigaction { | ||
117 | __sighandler_t sa_handler; | ||
118 | old_sigset_t sa_mask; | ||
119 | unsigned long sa_flags; | ||
120 | __sigrestore_t sa_restorer; | ||
121 | }; | ||
122 | |||
123 | struct sigaction { | ||
124 | __sighandler_t sa_handler; | ||
125 | unsigned long sa_flags; | ||
126 | __sigrestore_t sa_restorer; | ||
127 | sigset_t sa_mask; /* mask last for extensibility */ | ||
128 | }; | ||
129 | |||
130 | struct k_sigaction { | ||
131 | struct sigaction sa; | ||
132 | }; | ||
133 | #else | ||
134 | /* Here we must cater to libcs that poke about in kernel headers. */ | ||
135 | |||
136 | struct sigaction { | ||
137 | union { | ||
138 | __sighandler_t _sa_handler; | ||
139 | void (*_sa_sigaction)(int, struct siginfo *, void *); | ||
140 | } _u; | ||
141 | sigset_t sa_mask; | ||
142 | unsigned long sa_flags; | ||
143 | void (*sa_restorer)(void); | ||
144 | }; | ||
145 | |||
146 | #define sa_handler _u._sa_handler | ||
147 | #define sa_sigaction _u._sa_sigaction | ||
148 | |||
149 | #endif /* __KERNEL__ */ | ||
150 | |||
151 | typedef struct sigaltstack { | ||
152 | void __user *ss_sp; | ||
153 | int ss_flags; | ||
154 | size_t ss_size; | ||
155 | } stack_t; | ||
156 | |||
157 | #ifdef __KERNEL__ | ||
158 | #include <asm/sigcontext.h> | ||
159 | |||
160 | #define __HAVE_ARCH_SIG_BITOPS | ||
161 | |||
162 | #define sigaddset(set,sig) \ | ||
163 | (__builtin_constant_p(sig) ? \ | ||
164 | __const_sigaddset((set),(sig)) : \ | ||
165 | __gen_sigaddset((set),(sig))) | ||
166 | |||
167 | static __inline__ void __gen_sigaddset(sigset_t *set, int _sig) | ||
168 | { | ||
169 | __asm__("btsl %1,%0" : "+m"(*set) : "Ir"(_sig - 1) : "cc"); | ||
170 | } | ||
171 | |||
172 | static __inline__ void __const_sigaddset(sigset_t *set, int _sig) | ||
173 | { | ||
174 | unsigned long sig = _sig - 1; | ||
175 | set->sig[sig / _NSIG_BPW] |= 1 << (sig % _NSIG_BPW); | ||
176 | } | ||
177 | |||
178 | #define sigdelset(set,sig) \ | ||
179 | (__builtin_constant_p(sig) ? \ | ||
180 | __const_sigdelset((set),(sig)) : \ | ||
181 | __gen_sigdelset((set),(sig))) | ||
182 | |||
183 | |||
184 | static __inline__ void __gen_sigdelset(sigset_t *set, int _sig) | ||
185 | { | ||
186 | __asm__("btrl %1,%0" : "+m"(*set) : "Ir"(_sig - 1) : "cc"); | ||
187 | } | ||
188 | |||
189 | static __inline__ void __const_sigdelset(sigset_t *set, int _sig) | ||
190 | { | ||
191 | unsigned long sig = _sig - 1; | ||
192 | set->sig[sig / _NSIG_BPW] &= ~(1 << (sig % _NSIG_BPW)); | ||
193 | } | ||
194 | |||
195 | static __inline__ int __const_sigismember(sigset_t *set, int _sig) | ||
196 | { | ||
197 | unsigned long sig = _sig - 1; | ||
198 | return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW)); | ||
199 | } | ||
200 | |||
201 | static __inline__ int __gen_sigismember(sigset_t *set, int _sig) | ||
202 | { | ||
203 | int ret; | ||
204 | __asm__("btl %2,%1\n\tsbbl %0,%0" | ||
205 | : "=r"(ret) : "m"(*set), "Ir"(_sig-1) : "cc"); | ||
206 | return ret; | ||
207 | } | ||
208 | |||
209 | #define sigismember(set,sig) \ | ||
210 | (__builtin_constant_p(sig) ? \ | ||
211 | __const_sigismember((set),(sig)) : \ | ||
212 | __gen_sigismember((set),(sig))) | ||
213 | |||
214 | static __inline__ int sigfindinword(unsigned long word) | ||
215 | { | ||
216 | __asm__("bsfl %1,%0" : "=r"(word) : "rm"(word) : "cc"); | ||
217 | return word; | ||
218 | } | ||
219 | |||
220 | struct pt_regs; | ||
221 | |||
222 | #define ptrace_signal_deliver(regs, cookie) \ | ||
223 | do { \ | ||
224 | if (current->ptrace & PT_DTRACE) { \ | ||
225 | current->ptrace &= ~PT_DTRACE; \ | ||
226 | (regs)->eflags &= ~TF_MASK; \ | ||
227 | } \ | ||
228 | } while (0) | ||
229 | |||
230 | #endif /* __KERNEL__ */ | ||
231 | |||
232 | #endif | ||
diff --git a/include/asm-x86/signal_64.h b/include/asm-x86/signal_64.h deleted file mode 100644 index 4581f978b299..000000000000 --- a/include/asm-x86/signal_64.h +++ /dev/null | |||
@@ -1,181 +0,0 @@ | |||
1 | #ifndef _ASMx8664_SIGNAL_H | ||
2 | #define _ASMx8664_SIGNAL_H | ||
3 | |||
4 | #ifndef __ASSEMBLY__ | ||
5 | #include <linux/types.h> | ||
6 | #include <linux/time.h> | ||
7 | |||
8 | /* Avoid too many header ordering problems. */ | ||
9 | struct siginfo; | ||
10 | |||
11 | #ifdef __KERNEL__ | ||
12 | #include <linux/linkage.h> | ||
13 | /* Most things should be clean enough to redefine this at will, if care | ||
14 | is taken to make libc match. */ | ||
15 | |||
16 | #define _NSIG 64 | ||
17 | #define _NSIG_BPW 64 | ||
18 | #define _NSIG_WORDS (_NSIG / _NSIG_BPW) | ||
19 | |||
20 | typedef unsigned long old_sigset_t; /* at least 32 bits */ | ||
21 | |||
22 | typedef struct { | ||
23 | unsigned long sig[_NSIG_WORDS]; | ||
24 | } sigset_t; | ||
25 | |||
26 | |||
27 | #else | ||
28 | /* Here we must cater to libcs that poke about in kernel headers. */ | ||
29 | |||
30 | #define NSIG 32 | ||
31 | typedef unsigned long sigset_t; | ||
32 | |||
33 | #endif /* __KERNEL__ */ | ||
34 | #endif | ||
35 | |||
36 | #define SIGHUP 1 | ||
37 | #define SIGINT 2 | ||
38 | #define SIGQUIT 3 | ||
39 | #define SIGILL 4 | ||
40 | #define SIGTRAP 5 | ||
41 | #define SIGABRT 6 | ||
42 | #define SIGIOT 6 | ||
43 | #define SIGBUS 7 | ||
44 | #define SIGFPE 8 | ||
45 | #define SIGKILL 9 | ||
46 | #define SIGUSR1 10 | ||
47 | #define SIGSEGV 11 | ||
48 | #define SIGUSR2 12 | ||
49 | #define SIGPIPE 13 | ||
50 | #define SIGALRM 14 | ||
51 | #define SIGTERM 15 | ||
52 | #define SIGSTKFLT 16 | ||
53 | #define SIGCHLD 17 | ||
54 | #define SIGCONT 18 | ||
55 | #define SIGSTOP 19 | ||
56 | #define SIGTSTP 20 | ||
57 | #define SIGTTIN 21 | ||
58 | #define SIGTTOU 22 | ||
59 | #define SIGURG 23 | ||
60 | #define SIGXCPU 24 | ||
61 | #define SIGXFSZ 25 | ||
62 | #define SIGVTALRM 26 | ||
63 | #define SIGPROF 27 | ||
64 | #define SIGWINCH 28 | ||
65 | #define SIGIO 29 | ||
66 | #define SIGPOLL SIGIO | ||
67 | /* | ||
68 | #define SIGLOST 29 | ||
69 | */ | ||
70 | #define SIGPWR 30 | ||
71 | #define SIGSYS 31 | ||
72 | #define SIGUNUSED 31 | ||
73 | |||
74 | /* These should not be considered constants from userland. */ | ||
75 | #define SIGRTMIN 32 | ||
76 | #define SIGRTMAX _NSIG | ||
77 | |||
78 | /* | ||
79 | * SA_FLAGS values: | ||
80 | * | ||
81 | * SA_ONSTACK indicates that a registered stack_t will be used. | ||
82 | * SA_RESTART flag to get restarting signals (which were the default long ago) | ||
83 | * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. | ||
84 | * SA_RESETHAND clears the handler when the signal is delivered. | ||
85 | * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. | ||
86 | * SA_NODEFER prevents the current signal from being masked in the handler. | ||
87 | * | ||
88 | * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single | ||
89 | * Unix names RESETHAND and NODEFER respectively. | ||
90 | */ | ||
91 | #define SA_NOCLDSTOP 0x00000001 | ||
92 | #define SA_NOCLDWAIT 0x00000002 | ||
93 | #define SA_SIGINFO 0x00000004 | ||
94 | #define SA_ONSTACK 0x08000000 | ||
95 | #define SA_RESTART 0x10000000 | ||
96 | #define SA_NODEFER 0x40000000 | ||
97 | #define SA_RESETHAND 0x80000000 | ||
98 | |||
99 | #define SA_NOMASK SA_NODEFER | ||
100 | #define SA_ONESHOT SA_RESETHAND | ||
101 | |||
102 | #define SA_RESTORER 0x04000000 | ||
103 | |||
104 | /* | ||
105 | * sigaltstack controls | ||
106 | */ | ||
107 | #define SS_ONSTACK 1 | ||
108 | #define SS_DISABLE 2 | ||
109 | |||
110 | #define MINSIGSTKSZ 2048 | ||
111 | #define SIGSTKSZ 8192 | ||
112 | |||
113 | #include <asm-generic/signal.h> | ||
114 | |||
115 | #ifndef __ASSEMBLY__ | ||
116 | |||
117 | struct sigaction { | ||
118 | __sighandler_t sa_handler; | ||
119 | unsigned long sa_flags; | ||
120 | __sigrestore_t sa_restorer; | ||
121 | sigset_t sa_mask; /* mask last for extensibility */ | ||
122 | }; | ||
123 | |||
124 | struct k_sigaction { | ||
125 | struct sigaction sa; | ||
126 | }; | ||
127 | |||
128 | typedef struct sigaltstack { | ||
129 | void __user *ss_sp; | ||
130 | int ss_flags; | ||
131 | size_t ss_size; | ||
132 | } stack_t; | ||
133 | |||
134 | #ifdef __KERNEL__ | ||
135 | #include <asm/sigcontext.h> | ||
136 | |||
137 | #undef __HAVE_ARCH_SIG_BITOPS | ||
138 | #if 0 | ||
139 | |||
140 | static inline void sigaddset(sigset_t *set, int _sig) | ||
141 | { | ||
142 | __asm__("btsq %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); | ||
143 | } | ||
144 | |||
145 | static inline void sigdelset(sigset_t *set, int _sig) | ||
146 | { | ||
147 | __asm__("btrq %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); | ||
148 | } | ||
149 | |||
150 | static inline int __const_sigismember(sigset_t *set, int _sig) | ||
151 | { | ||
152 | unsigned long sig = _sig - 1; | ||
153 | return 1 & (set->sig[sig / _NSIG_BPW] >> (sig & ~(_NSIG_BPW-1))); | ||
154 | } | ||
155 | |||
156 | static inline int __gen_sigismember(sigset_t *set, int _sig) | ||
157 | { | ||
158 | int ret; | ||
159 | __asm__("btq %2,%1\n\tsbbq %0,%0" | ||
160 | : "=r"(ret) : "m"(*set), "Ir"(_sig-1) : "cc"); | ||
161 | return ret; | ||
162 | } | ||
163 | |||
164 | #define sigismember(set,sig) \ | ||
165 | (__builtin_constant_p(sig) ? \ | ||
166 | __const_sigismember((set),(sig)) : \ | ||
167 | __gen_sigismember((set),(sig))) | ||
168 | |||
169 | static inline int sigfindinword(unsigned long word) | ||
170 | { | ||
171 | __asm__("bsfq %1,%0" : "=r"(word) : "rm"(word) : "cc"); | ||
172 | return word; | ||
173 | } | ||
174 | #endif | ||
175 | #endif | ||
176 | |||
177 | #define ptrace_signal_deliver(regs, cookie) do { } while (0) | ||
178 | |||
179 | #endif /* __KERNEL__ */ | ||
180 | |||
181 | #endif | ||
diff --git a/include/asm-x86/smp_64.h b/include/asm-x86/smp_64.h index 6f0e0273b646..ab612b0ff270 100644 --- a/include/asm-x86/smp_64.h +++ b/include/asm-x86/smp_64.h | |||
@@ -76,6 +76,8 @@ extern unsigned __cpuinitdata disabled_cpus; | |||
76 | 76 | ||
77 | #endif /* CONFIG_SMP */ | 77 | #endif /* CONFIG_SMP */ |
78 | 78 | ||
79 | #define safe_smp_processor_id() smp_processor_id() | ||
80 | |||
79 | static inline int hard_smp_processor_id(void) | 81 | static inline int hard_smp_processor_id(void) |
80 | { | 82 | { |
81 | /* we don't want to mark this access volatile - bad code generation */ | 83 | /* we don't want to mark this access volatile - bad code generation */ |
diff --git a/include/asm-x86/stat.h b/include/asm-x86/stat.h index 3ff6b50ef833..5c22dcb5d17e 100644 --- a/include/asm-x86/stat.h +++ b/include/asm-x86/stat.h | |||
@@ -1,13 +1,114 @@ | |||
1 | #ifdef __KERNEL__ | 1 | #ifndef _ASM_X86_STAT_H |
2 | # ifdef CONFIG_X86_32 | 2 | #define _ASM_X86_STAT_H |
3 | # include "stat_32.h" | 3 | |
4 | # else | 4 | #define STAT_HAVE_NSEC 1 |
5 | # include "stat_64.h" | 5 | |
6 | # endif | 6 | #ifdef __i386__ |
7 | struct stat { | ||
8 | unsigned long st_dev; | ||
9 | unsigned long st_ino; | ||
10 | unsigned short st_mode; | ||
11 | unsigned short st_nlink; | ||
12 | unsigned short st_uid; | ||
13 | unsigned short st_gid; | ||
14 | unsigned long st_rdev; | ||
15 | unsigned long st_size; | ||
16 | unsigned long st_blksize; | ||
17 | unsigned long st_blocks; | ||
18 | unsigned long st_atime; | ||
19 | unsigned long st_atime_nsec; | ||
20 | unsigned long st_mtime; | ||
21 | unsigned long st_mtime_nsec; | ||
22 | unsigned long st_ctime; | ||
23 | unsigned long st_ctime_nsec; | ||
24 | unsigned long __unused4; | ||
25 | unsigned long __unused5; | ||
26 | }; | ||
27 | |||
28 | #define STAT64_HAS_BROKEN_ST_INO 1 | ||
29 | |||
30 | /* This matches struct stat64 in glibc2.1, hence the absolutely | ||
31 | * insane amounts of padding around dev_t's. | ||
32 | */ | ||
33 | struct stat64 { | ||
34 | unsigned long long st_dev; | ||
35 | unsigned char __pad0[4]; | ||
36 | |||
37 | unsigned long __st_ino; | ||
38 | |||
39 | unsigned int st_mode; | ||
40 | unsigned int st_nlink; | ||
41 | |||
42 | unsigned long st_uid; | ||
43 | unsigned long st_gid; | ||
44 | |||
45 | unsigned long long st_rdev; | ||
46 | unsigned char __pad3[4]; | ||
47 | |||
48 | long long st_size; | ||
49 | unsigned long st_blksize; | ||
50 | |||
51 | /* Number 512-byte blocks allocated. */ | ||
52 | unsigned long long st_blocks; | ||
53 | |||
54 | unsigned long st_atime; | ||
55 | unsigned long st_atime_nsec; | ||
56 | |||
57 | unsigned long st_mtime; | ||
58 | unsigned int st_mtime_nsec; | ||
59 | |||
60 | unsigned long st_ctime; | ||
61 | unsigned long st_ctime_nsec; | ||
62 | |||
63 | unsigned long long st_ino; | ||
64 | }; | ||
65 | |||
66 | #else /* __i386__ */ | ||
67 | |||
68 | struct stat { | ||
69 | unsigned long st_dev; | ||
70 | unsigned long st_ino; | ||
71 | unsigned long st_nlink; | ||
72 | |||
73 | unsigned int st_mode; | ||
74 | unsigned int st_uid; | ||
75 | unsigned int st_gid; | ||
76 | unsigned int __pad0; | ||
77 | unsigned long st_rdev; | ||
78 | long st_size; | ||
79 | long st_blksize; | ||
80 | long st_blocks; /* Number 512-byte blocks allocated. */ | ||
81 | |||
82 | unsigned long st_atime; | ||
83 | unsigned long st_atime_nsec; | ||
84 | unsigned long st_mtime; | ||
85 | unsigned long st_mtime_nsec; | ||
86 | unsigned long st_ctime; | ||
87 | unsigned long st_ctime_nsec; | ||
88 | long __unused[3]; | ||
89 | }; | ||
90 | #endif | ||
91 | |||
92 | /* for 32bit emulation and 32 bit kernels */ | ||
93 | struct __old_kernel_stat { | ||
94 | unsigned short st_dev; | ||
95 | unsigned short st_ino; | ||
96 | unsigned short st_mode; | ||
97 | unsigned short st_nlink; | ||
98 | unsigned short st_uid; | ||
99 | unsigned short st_gid; | ||
100 | unsigned short st_rdev; | ||
101 | #ifdef __i386__ | ||
102 | unsigned long st_size; | ||
103 | unsigned long st_atime; | ||
104 | unsigned long st_mtime; | ||
105 | unsigned long st_ctime; | ||
7 | #else | 106 | #else |
8 | # ifdef __i386__ | 107 | unsigned int st_size; |
9 | # include "stat_32.h" | 108 | unsigned int st_atime; |
10 | # else | 109 | unsigned int st_mtime; |
11 | # include "stat_64.h" | 110 | unsigned int st_ctime; |
12 | # endif | 111 | #endif |
112 | }; | ||
113 | |||
13 | #endif | 114 | #endif |
diff --git a/include/asm-x86/stat_32.h b/include/asm-x86/stat_32.h deleted file mode 100644 index 67eae78323ba..000000000000 --- a/include/asm-x86/stat_32.h +++ /dev/null | |||
@@ -1,77 +0,0 @@ | |||
1 | #ifndef _I386_STAT_H | ||
2 | #define _I386_STAT_H | ||
3 | |||
4 | struct __old_kernel_stat { | ||
5 | unsigned short st_dev; | ||
6 | unsigned short st_ino; | ||
7 | unsigned short st_mode; | ||
8 | unsigned short st_nlink; | ||
9 | unsigned short st_uid; | ||
10 | unsigned short st_gid; | ||
11 | unsigned short st_rdev; | ||
12 | unsigned long st_size; | ||
13 | unsigned long st_atime; | ||
14 | unsigned long st_mtime; | ||
15 | unsigned long st_ctime; | ||
16 | }; | ||
17 | |||
18 | struct stat { | ||
19 | unsigned long st_dev; | ||
20 | unsigned long st_ino; | ||
21 | unsigned short st_mode; | ||
22 | unsigned short st_nlink; | ||
23 | unsigned short st_uid; | ||
24 | unsigned short st_gid; | ||
25 | unsigned long st_rdev; | ||
26 | unsigned long st_size; | ||
27 | unsigned long st_blksize; | ||
28 | unsigned long st_blocks; | ||
29 | unsigned long st_atime; | ||
30 | unsigned long st_atime_nsec; | ||
31 | unsigned long st_mtime; | ||
32 | unsigned long st_mtime_nsec; | ||
33 | unsigned long st_ctime; | ||
34 | unsigned long st_ctime_nsec; | ||
35 | unsigned long __unused4; | ||
36 | unsigned long __unused5; | ||
37 | }; | ||
38 | |||
39 | /* This matches struct stat64 in glibc2.1, hence the absolutely | ||
40 | * insane amounts of padding around dev_t's. | ||
41 | */ | ||
42 | struct stat64 { | ||
43 | unsigned long long st_dev; | ||
44 | unsigned char __pad0[4]; | ||
45 | |||
46 | #define STAT64_HAS_BROKEN_ST_INO 1 | ||
47 | unsigned long __st_ino; | ||
48 | |||
49 | unsigned int st_mode; | ||
50 | unsigned int st_nlink; | ||
51 | |||
52 | unsigned long st_uid; | ||
53 | unsigned long st_gid; | ||
54 | |||
55 | unsigned long long st_rdev; | ||
56 | unsigned char __pad3[4]; | ||
57 | |||
58 | long long st_size; | ||
59 | unsigned long st_blksize; | ||
60 | |||
61 | unsigned long long st_blocks; /* Number 512-byte blocks allocated. */ | ||
62 | |||
63 | unsigned long st_atime; | ||
64 | unsigned long st_atime_nsec; | ||
65 | |||
66 | unsigned long st_mtime; | ||
67 | unsigned int st_mtime_nsec; | ||
68 | |||
69 | unsigned long st_ctime; | ||
70 | unsigned long st_ctime_nsec; | ||
71 | |||
72 | unsigned long long st_ino; | ||
73 | }; | ||
74 | |||
75 | #define STAT_HAVE_NSEC 1 | ||
76 | |||
77 | #endif | ||
diff --git a/include/asm-x86/stat_64.h b/include/asm-x86/stat_64.h deleted file mode 100644 index fd9f00d560f8..000000000000 --- a/include/asm-x86/stat_64.h +++ /dev/null | |||
@@ -1,44 +0,0 @@ | |||
1 | #ifndef _ASM_X86_64_STAT_H | ||
2 | #define _ASM_X86_64_STAT_H | ||
3 | |||
4 | #define STAT_HAVE_NSEC 1 | ||
5 | |||
6 | struct stat { | ||
7 | unsigned long st_dev; | ||
8 | unsigned long st_ino; | ||
9 | unsigned long st_nlink; | ||
10 | |||
11 | unsigned int st_mode; | ||
12 | unsigned int st_uid; | ||
13 | unsigned int st_gid; | ||
14 | unsigned int __pad0; | ||
15 | unsigned long st_rdev; | ||
16 | long st_size; | ||
17 | long st_blksize; | ||
18 | long st_blocks; /* Number 512-byte blocks allocated. */ | ||
19 | |||
20 | unsigned long st_atime; | ||
21 | unsigned long st_atime_nsec; | ||
22 | unsigned long st_mtime; | ||
23 | unsigned long st_mtime_nsec; | ||
24 | unsigned long st_ctime; | ||
25 | unsigned long st_ctime_nsec; | ||
26 | long __unused[3]; | ||
27 | }; | ||
28 | |||
29 | /* For 32bit emulation */ | ||
30 | struct __old_kernel_stat { | ||
31 | unsigned short st_dev; | ||
32 | unsigned short st_ino; | ||
33 | unsigned short st_mode; | ||
34 | unsigned short st_nlink; | ||
35 | unsigned short st_uid; | ||
36 | unsigned short st_gid; | ||
37 | unsigned short st_rdev; | ||
38 | unsigned int st_size; | ||
39 | unsigned int st_atime; | ||
40 | unsigned int st_mtime; | ||
41 | unsigned int st_ctime; | ||
42 | }; | ||
43 | |||
44 | #endif | ||
diff --git a/include/asm-x86/statfs.h b/include/asm-x86/statfs.h index 327fb5d7a148..7c651aa97252 100644 --- a/include/asm-x86/statfs.h +++ b/include/asm-x86/statfs.h | |||
@@ -1,13 +1,63 @@ | |||
1 | #ifdef __KERNEL__ | 1 | #ifndef _ASM_X86_STATFS_H |
2 | # ifdef CONFIG_X86_32 | 2 | #define _ASM_X86_STATFS_H |
3 | # include "statfs_32.h" | 3 | |
4 | # else | 4 | #ifdef __i386__ |
5 | # include "statfs_64.h" | 5 | #include <asm-generic/statfs.h> |
6 | # endif | ||
7 | #else | 6 | #else |
8 | # ifdef __i386__ | 7 | |
9 | # include "statfs_32.h" | 8 | #ifndef __KERNEL_STRICT_NAMES |
10 | # else | 9 | |
11 | # include "statfs_64.h" | 10 | #include <linux/types.h> |
12 | # endif | 11 | |
12 | typedef __kernel_fsid_t fsid_t; | ||
13 | |||
14 | #endif | ||
15 | |||
16 | /* | ||
17 | * This is ugly -- we're already 64-bit clean, so just duplicate the | ||
18 | * definitions. | ||
19 | */ | ||
20 | struct statfs { | ||
21 | long f_type; | ||
22 | long f_bsize; | ||
23 | long f_blocks; | ||
24 | long f_bfree; | ||
25 | long f_bavail; | ||
26 | long f_files; | ||
27 | long f_ffree; | ||
28 | __kernel_fsid_t f_fsid; | ||
29 | long f_namelen; | ||
30 | long f_frsize; | ||
31 | long f_spare[5]; | ||
32 | }; | ||
33 | |||
34 | struct statfs64 { | ||
35 | long f_type; | ||
36 | long f_bsize; | ||
37 | long f_blocks; | ||
38 | long f_bfree; | ||
39 | long f_bavail; | ||
40 | long f_files; | ||
41 | long f_ffree; | ||
42 | __kernel_fsid_t f_fsid; | ||
43 | long f_namelen; | ||
44 | long f_frsize; | ||
45 | long f_spare[5]; | ||
46 | }; | ||
47 | |||
48 | struct compat_statfs64 { | ||
49 | __u32 f_type; | ||
50 | __u32 f_bsize; | ||
51 | __u64 f_blocks; | ||
52 | __u64 f_bfree; | ||
53 | __u64 f_bavail; | ||
54 | __u64 f_files; | ||
55 | __u64 f_ffree; | ||
56 | __kernel_fsid_t f_fsid; | ||
57 | __u32 f_namelen; | ||
58 | __u32 f_frsize; | ||
59 | __u32 f_spare[5]; | ||
60 | } __attribute__((packed)); | ||
61 | |||
62 | #endif /* !__i386__ */ | ||
13 | #endif | 63 | #endif |
diff --git a/include/asm-x86/statfs_32.h b/include/asm-x86/statfs_32.h deleted file mode 100644 index 24972c175132..000000000000 --- a/include/asm-x86/statfs_32.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef _I386_STATFS_H | ||
2 | #define _I386_STATFS_H | ||
3 | |||
4 | #include <asm-generic/statfs.h> | ||
5 | |||
6 | #endif | ||
diff --git a/include/asm-x86/statfs_64.h b/include/asm-x86/statfs_64.h deleted file mode 100644 index b3f4718af30b..000000000000 --- a/include/asm-x86/statfs_64.h +++ /dev/null | |||
@@ -1,58 +0,0 @@ | |||
1 | #ifndef _X86_64_STATFS_H | ||
2 | #define _X86_64_STATFS_H | ||
3 | |||
4 | #ifndef __KERNEL_STRICT_NAMES | ||
5 | |||
6 | #include <linux/types.h> | ||
7 | |||
8 | typedef __kernel_fsid_t fsid_t; | ||
9 | |||
10 | #endif | ||
11 | |||
12 | /* | ||
13 | * This is ugly -- we're already 64-bit clean, so just duplicate the | ||
14 | * definitions. | ||
15 | */ | ||
16 | struct statfs { | ||
17 | long f_type; | ||
18 | long f_bsize; | ||
19 | long f_blocks; | ||
20 | long f_bfree; | ||
21 | long f_bavail; | ||
22 | long f_files; | ||
23 | long f_ffree; | ||
24 | __kernel_fsid_t f_fsid; | ||
25 | long f_namelen; | ||
26 | long f_frsize; | ||
27 | long f_spare[5]; | ||
28 | }; | ||
29 | |||
30 | struct statfs64 { | ||
31 | long f_type; | ||
32 | long f_bsize; | ||
33 | long f_blocks; | ||
34 | long f_bfree; | ||
35 | long f_bavail; | ||
36 | long f_files; | ||
37 | long f_ffree; | ||
38 | __kernel_fsid_t f_fsid; | ||
39 | long f_namelen; | ||
40 | long f_frsize; | ||
41 | long f_spare[5]; | ||
42 | }; | ||
43 | |||
44 | struct compat_statfs64 { | ||
45 | __u32 f_type; | ||
46 | __u32 f_bsize; | ||
47 | __u64 f_blocks; | ||
48 | __u64 f_bfree; | ||
49 | __u64 f_bavail; | ||
50 | __u64 f_files; | ||
51 | __u64 f_ffree; | ||
52 | __kernel_fsid_t f_fsid; | ||
53 | __u32 f_namelen; | ||
54 | __u32 f_frsize; | ||
55 | __u32 f_spare[5]; | ||
56 | } __attribute__((packed)); | ||
57 | |||
58 | #endif | ||
diff --git a/include/asm-x86/suspend_64.h b/include/asm-x86/suspend_64.h index 9440a7a1b99a..c505a76bcf6e 100644 --- a/include/asm-x86/suspend_64.h +++ b/include/asm-x86/suspend_64.h | |||
@@ -3,6 +3,9 @@ | |||
3 | * Based on code | 3 | * Based on code |
4 | * Copyright 2001 Patrick Mochel <mochel@osdl.org> | 4 | * Copyright 2001 Patrick Mochel <mochel@osdl.org> |
5 | */ | 5 | */ |
6 | #ifndef __ASM_X86_64_SUSPEND_H | ||
7 | #define __ASM_X86_64_SUSPEND_H | ||
8 | |||
6 | #include <asm/desc.h> | 9 | #include <asm/desc.h> |
7 | #include <asm/i387.h> | 10 | #include <asm/i387.h> |
8 | 11 | ||
@@ -12,8 +15,9 @@ arch_prepare_suspend(void) | |||
12 | return 0; | 15 | return 0; |
13 | } | 16 | } |
14 | 17 | ||
15 | /* Image of the saved processor state. If you touch this, fix acpi_wakeup.S. */ | 18 | /* Image of the saved processor state. If you touch this, fix acpi/wakeup.S. */ |
16 | struct saved_context { | 19 | struct saved_context { |
20 | struct pt_regs regs; | ||
17 | u16 ds, es, fs, gs, ss; | 21 | u16 ds, es, fs, gs, ss; |
18 | unsigned long gs_base, gs_kernel_base, fs_base; | 22 | unsigned long gs_base, gs_kernel_base, fs_base; |
19 | unsigned long cr0, cr2, cr3, cr4, cr8; | 23 | unsigned long cr0, cr2, cr3, cr4, cr8; |
@@ -29,29 +33,16 @@ struct saved_context { | |||
29 | unsigned long tr; | 33 | unsigned long tr; |
30 | unsigned long safety; | 34 | unsigned long safety; |
31 | unsigned long return_address; | 35 | unsigned long return_address; |
32 | unsigned long eflags; | ||
33 | } __attribute__((packed)); | 36 | } __attribute__((packed)); |
34 | 37 | ||
35 | /* We'll access these from assembly, so we'd better have them outside struct */ | ||
36 | extern unsigned long saved_context_eax, saved_context_ebx, saved_context_ecx, saved_context_edx; | ||
37 | extern unsigned long saved_context_esp, saved_context_ebp, saved_context_esi, saved_context_edi; | ||
38 | extern unsigned long saved_context_r08, saved_context_r09, saved_context_r10, saved_context_r11; | ||
39 | extern unsigned long saved_context_r12, saved_context_r13, saved_context_r14, saved_context_r15; | ||
40 | extern unsigned long saved_context_eflags; | ||
41 | |||
42 | #define loaddebug(thread,register) \ | 38 | #define loaddebug(thread,register) \ |
43 | set_debugreg((thread)->debugreg##register, register) | 39 | set_debugreg((thread)->debugreg##register, register) |
44 | 40 | ||
45 | extern void fix_processor_context(void); | 41 | extern void fix_processor_context(void); |
46 | 42 | ||
47 | extern unsigned long saved_rip; | ||
48 | extern unsigned long saved_rsp; | ||
49 | extern unsigned long saved_rbp; | ||
50 | extern unsigned long saved_rbx; | ||
51 | extern unsigned long saved_rsi; | ||
52 | extern unsigned long saved_rdi; | ||
53 | |||
54 | /* routines for saving/restoring kernel state */ | 43 | /* routines for saving/restoring kernel state */ |
55 | extern int acpi_save_state_mem(void); | 44 | extern int acpi_save_state_mem(void); |
56 | extern char core_restore_code; | 45 | extern char core_restore_code; |
57 | extern char restore_registers; | 46 | extern char restore_registers; |
47 | |||
48 | #endif /* __ASM_X86_64_SUSPEND_H */ | ||
diff --git a/include/linux/ata.h b/include/linux/ata.h index a4f373f8b798..8263a7b74d34 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h | |||
@@ -178,8 +178,8 @@ enum { | |||
178 | ATA_CMD_PACKET = 0xA0, | 178 | ATA_CMD_PACKET = 0xA0, |
179 | ATA_CMD_VERIFY = 0x40, | 179 | ATA_CMD_VERIFY = 0x40, |
180 | ATA_CMD_VERIFY_EXT = 0x42, | 180 | ATA_CMD_VERIFY_EXT = 0x42, |
181 | ATA_CMD_STANDBYNOW1 = 0xE0, | 181 | ATA_CMD_STANDBYNOW1 = 0xE0, |
182 | ATA_CMD_IDLEIMMEDIATE = 0xE1, | 182 | ATA_CMD_IDLEIMMEDIATE = 0xE1, |
183 | ATA_CMD_INIT_DEV_PARAMS = 0x91, | 183 | ATA_CMD_INIT_DEV_PARAMS = 0x91, |
184 | ATA_CMD_READ_NATIVE_MAX = 0xF8, | 184 | ATA_CMD_READ_NATIVE_MAX = 0xF8, |
185 | ATA_CMD_READ_NATIVE_MAX_EXT = 0x27, | 185 | ATA_CMD_READ_NATIVE_MAX_EXT = 0x27, |
@@ -458,7 +458,7 @@ static inline int ata_id_wcache_enabled(const u16 *id) | |||
458 | * ATA-3 introduces word 80 and accurate reporting | 458 | * ATA-3 introduces word 80 and accurate reporting |
459 | * | 459 | * |
460 | * The practical impact of this is that ata_id_major_version cannot | 460 | * The practical impact of this is that ata_id_major_version cannot |
461 | * reliably report on drives below ATA3. | 461 | * reliably report on drives below ATA3. |
462 | */ | 462 | */ |
463 | 463 | ||
464 | static inline unsigned int ata_id_major_version(const u16 *id) | 464 | static inline unsigned int ata_id_major_version(const u16 *id) |
diff --git a/include/linux/libata.h b/include/linux/libata.h index bc3b6fc7b98d..6fd24e03622e 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -326,7 +326,7 @@ enum { | |||
326 | ATA_HORKAGE_SKIP_PM = (1 << 5), /* Skip PM operations */ | 326 | ATA_HORKAGE_SKIP_PM = (1 << 5), /* Skip PM operations */ |
327 | ATA_HORKAGE_HPA_SIZE = (1 << 6), /* native size off by one */ | 327 | ATA_HORKAGE_HPA_SIZE = (1 << 6), /* native size off by one */ |
328 | 328 | ||
329 | /* DMA mask for user DMA control: User visible values; DO NOT | 329 | /* DMA mask for user DMA control: User visible values; DO NOT |
330 | renumber */ | 330 | renumber */ |
331 | ATA_DMA_MASK_ATA = (1 << 0), /* DMA on ATA Disk */ | 331 | ATA_DMA_MASK_ATA = (1 << 0), /* DMA on ATA Disk */ |
332 | ATA_DMA_MASK_ATAPI = (1 << 1), /* DMA on ATAPI */ | 332 | ATA_DMA_MASK_ATAPI = (1 << 1), /* DMA on ATAPI */ |
@@ -717,7 +717,7 @@ struct ata_timing { | |||
717 | unsigned short udma; /* t2CYCTYP/2 */ | 717 | unsigned short udma; /* t2CYCTYP/2 */ |
718 | }; | 718 | }; |
719 | 719 | ||
720 | #define FIT(v,vmin,vmax) max_t(short,min_t(short,v,vmax),vmin) | 720 | #define FIT(v, vmin, vmax) max_t(short, min_t(short, v, vmax), vmin) |
721 | 721 | ||
722 | extern const unsigned long sata_deb_timing_normal[]; | 722 | extern const unsigned long sata_deb_timing_normal[]; |
723 | extern const unsigned long sata_deb_timing_hotplug[]; | 723 | extern const unsigned long sata_deb_timing_hotplug[]; |
@@ -816,14 +816,14 @@ extern void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf); | |||
816 | extern void ata_tf_to_fis(const struct ata_taskfile *tf, | 816 | extern void ata_tf_to_fis(const struct ata_taskfile *tf, |
817 | u8 pmp, int is_cmd, u8 *fis); | 817 | u8 pmp, int is_cmd, u8 *fis); |
818 | extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); | 818 | extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); |
819 | extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device); | 819 | extern void ata_noop_dev_select(struct ata_port *ap, unsigned int device); |
820 | extern void ata_std_dev_select (struct ata_port *ap, unsigned int device); | 820 | extern void ata_std_dev_select(struct ata_port *ap, unsigned int device); |
821 | extern u8 ata_check_status(struct ata_port *ap); | 821 | extern u8 ata_check_status(struct ata_port *ap); |
822 | extern u8 ata_altstatus(struct ata_port *ap); | 822 | extern u8 ata_altstatus(struct ata_port *ap); |
823 | extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf); | 823 | extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf); |
824 | extern int ata_port_start (struct ata_port *ap); | 824 | extern int ata_port_start(struct ata_port *ap); |
825 | extern int ata_sff_port_start (struct ata_port *ap); | 825 | extern int ata_sff_port_start(struct ata_port *ap); |
826 | extern irqreturn_t ata_interrupt (int irq, void *dev_instance); | 826 | extern irqreturn_t ata_interrupt(int irq, void *dev_instance); |
827 | extern void ata_data_xfer(struct ata_device *adev, unsigned char *buf, | 827 | extern void ata_data_xfer(struct ata_device *adev, unsigned char *buf, |
828 | unsigned int buflen, int write_data); | 828 | unsigned int buflen, int write_data); |
829 | extern void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf, | 829 | extern void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf, |
@@ -844,8 +844,8 @@ extern void ata_id_string(const u16 *id, unsigned char *s, | |||
844 | extern void ata_id_c_string(const u16 *id, unsigned char *s, | 844 | extern void ata_id_c_string(const u16 *id, unsigned char *s, |
845 | unsigned int ofs, unsigned int len); | 845 | unsigned int ofs, unsigned int len); |
846 | extern void ata_id_to_dma_mode(struct ata_device *dev, u8 unknown); | 846 | extern void ata_id_to_dma_mode(struct ata_device *dev, u8 unknown); |
847 | extern void ata_bmdma_setup (struct ata_queued_cmd *qc); | 847 | extern void ata_bmdma_setup(struct ata_queued_cmd *qc); |
848 | extern void ata_bmdma_start (struct ata_queued_cmd *qc); | 848 | extern void ata_bmdma_start(struct ata_queued_cmd *qc); |
849 | extern void ata_bmdma_stop(struct ata_queued_cmd *qc); | 849 | extern void ata_bmdma_stop(struct ata_queued_cmd *qc); |
850 | extern u8 ata_bmdma_status(struct ata_port *ap); | 850 | extern u8 ata_bmdma_status(struct ata_port *ap); |
851 | extern void ata_bmdma_irq_clear(struct ata_port *ap); | 851 | extern void ata_bmdma_irq_clear(struct ata_port *ap); |
@@ -920,9 +920,9 @@ static inline int ata_acpi_cbl_80wire(struct ata_port *ap) { return 0; } | |||
920 | #ifdef CONFIG_PCI | 920 | #ifdef CONFIG_PCI |
921 | struct pci_dev; | 921 | struct pci_dev; |
922 | 922 | ||
923 | extern int ata_pci_init_one (struct pci_dev *pdev, | 923 | extern int ata_pci_init_one(struct pci_dev *pdev, |
924 | const struct ata_port_info * const * ppi); | 924 | const struct ata_port_info * const * ppi); |
925 | extern void ata_pci_remove_one (struct pci_dev *pdev); | 925 | extern void ata_pci_remove_one(struct pci_dev *pdev); |
926 | #ifdef CONFIG_PM | 926 | #ifdef CONFIG_PM |
927 | extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg); | 927 | extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg); |
928 | extern int __must_check ata_pci_device_do_resume(struct pci_dev *pdev); | 928 | extern int __must_check ata_pci_device_do_resume(struct pci_dev *pdev); |
diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h index 44224ba4dd90..d21b8913ceb3 100644 --- a/include/scsi/scsi_eh.h +++ b/include/scsi/scsi_eh.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef _SCSI_SCSI_EH_H | 1 | #ifndef _SCSI_SCSI_EH_H |
2 | #define _SCSI_SCSI_EH_H | 2 | #define _SCSI_SCSI_EH_H |
3 | 3 | ||
4 | #include <linux/scatterlist.h> | ||
5 | |||
4 | #include <scsi/scsi_cmnd.h> | 6 | #include <scsi/scsi_cmnd.h> |
5 | struct scsi_device; | 7 | struct scsi_device; |
6 | struct Scsi_Host; | 8 | struct Scsi_Host; |