diff options
153 files changed, 2956 insertions, 2408 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 3b6ff3b4ad20..2fadf794483d 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -1052,9 +1052,9 @@ config MTRR | |||
1052 | See <file:Documentation/mtrr.txt> for more information. | 1052 | See <file:Documentation/mtrr.txt> for more information. |
1053 | 1053 | ||
1054 | config X86_PAT | 1054 | config X86_PAT |
1055 | def_bool y | 1055 | bool |
1056 | prompt "x86 PAT support" | 1056 | prompt "x86 PAT support" |
1057 | depends on MTRR && NONPROMISC_DEVMEM | 1057 | depends on MTRR |
1058 | help | 1058 | help |
1059 | Use PAT attributes to setup page level cache control. | 1059 | Use PAT attributes to setup page level cache control. |
1060 | 1060 | ||
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index 57072f2716f9..4da3cdb9c1b1 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu | |||
@@ -21,8 +21,8 @@ config M386 | |||
21 | 21 | ||
22 | Here are the settings recommended for greatest speed: | 22 | Here are the settings recommended for greatest speed: |
23 | - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI | 23 | - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI |
24 | 486DLC/DLC2, UMC 486SX-S and NexGen Nx586. Only "386" kernels | 24 | 486DLC/DLC2, and UMC 486SX-S. Only "386" kernels will run on a 386 |
25 | will run on a 386 class machine. | 25 | class machine. |
26 | - "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or | 26 | - "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or |
27 | SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S. | 27 | SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S. |
28 | - "586" for generic Pentium CPUs lacking the TSC | 28 | - "586" for generic Pentium CPUs lacking the TSC |
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index 05e155d3fb6c..bbed3a26ce55 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c | |||
@@ -499,11 +499,6 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, | |||
499 | regs->cs = __USER32_CS; | 499 | regs->cs = __USER32_CS; |
500 | regs->ss = __USER32_DS; | 500 | regs->ss = __USER32_DS; |
501 | 501 | ||
502 | set_fs(USER_DS); | ||
503 | regs->flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_DF); | ||
504 | if (test_thread_flag(TIF_SINGLESTEP)) | ||
505 | ptrace_notify(SIGTRAP); | ||
506 | |||
507 | #if DEBUG_SIG | 502 | #if DEBUG_SIG |
508 | printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n", | 503 | printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n", |
509 | current->comm, current->pid, frame, regs->ip, frame->pretcode); | 504 | current->comm, current->pid, frame, regs->ip, frame->pretcode); |
@@ -599,11 +594,6 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
599 | regs->cs = __USER32_CS; | 594 | regs->cs = __USER32_CS; |
600 | regs->ss = __USER32_DS; | 595 | regs->ss = __USER32_DS; |
601 | 596 | ||
602 | set_fs(USER_DS); | ||
603 | regs->flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_DF); | ||
604 | if (test_thread_flag(TIF_SINGLESTEP)) | ||
605 | ptrace_notify(SIGTRAP); | ||
606 | |||
607 | #if DEBUG_SIG | 597 | #if DEBUG_SIG |
608 | printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n", | 598 | printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n", |
609 | current->comm, current->pid, frame, regs->ip, frame->pretcode); | 599 | current->comm, current->pid, frame, regs->ip, frame->pretcode); |
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index ae7158bce4d6..b5e329da166c 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S | |||
@@ -430,7 +430,7 @@ ia32_sys_call_table: | |||
430 | .quad sys_setuid16 | 430 | .quad sys_setuid16 |
431 | .quad sys_getuid16 | 431 | .quad sys_getuid16 |
432 | .quad compat_sys_stime /* stime */ /* 25 */ | 432 | .quad compat_sys_stime /* stime */ /* 25 */ |
433 | .quad sys32_ptrace /* ptrace */ | 433 | .quad compat_sys_ptrace /* ptrace */ |
434 | .quad sys_alarm | 434 | .quad sys_alarm |
435 | .quad sys_fstat /* (old)fstat */ | 435 | .quad sys_fstat /* (old)fstat */ |
436 | .quad sys_pause | 436 | .quad sys_pause |
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 057ccf1d5ad4..977ed5cdeaa3 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -697,10 +697,6 @@ static int __init acpi_parse_hpet(struct acpi_table_header *table) | |||
697 | #define HPET_RESOURCE_NAME_SIZE 9 | 697 | #define HPET_RESOURCE_NAME_SIZE 9 |
698 | hpet_res = alloc_bootmem(sizeof(*hpet_res) + HPET_RESOURCE_NAME_SIZE); | 698 | hpet_res = alloc_bootmem(sizeof(*hpet_res) + HPET_RESOURCE_NAME_SIZE); |
699 | 699 | ||
700 | if (!hpet_res) | ||
701 | return 0; | ||
702 | |||
703 | memset(hpet_res, 0, sizeof(*hpet_res)); | ||
704 | hpet_res->name = (void *)&hpet_res[1]; | 700 | hpet_res->name = (void *)&hpet_res[1]; |
705 | hpet_res->flags = IORESOURCE_MEM; | 701 | hpet_res->flags = IORESOURCE_MEM; |
706 | snprintf((char *)hpet_res->name, HPET_RESOURCE_NAME_SIZE, "HPET %u", | 702 | snprintf((char *)hpet_res->name, HPET_RESOURCE_NAME_SIZE, "HPET %u", |
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c index 8317401170b8..4b99b1bdeb6c 100644 --- a/arch/x86/kernel/apic_32.c +++ b/arch/x86/kernel/apic_32.c | |||
@@ -451,7 +451,8 @@ void __init setup_boot_APIC_clock(void) | |||
451 | } | 451 | } |
452 | 452 | ||
453 | /* Calculate the scaled math multiplication factor */ | 453 | /* Calculate the scaled math multiplication factor */ |
454 | lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS, 32); | 454 | lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS, |
455 | lapic_clockevent.shift); | ||
455 | lapic_clockevent.max_delta_ns = | 456 | lapic_clockevent.max_delta_ns = |
456 | clockevent_delta2ns(0x7FFFFF, &lapic_clockevent); | 457 | clockevent_delta2ns(0x7FFFFF, &lapic_clockevent); |
457 | lapic_clockevent.min_delta_ns = | 458 | lapic_clockevent.min_delta_ns = |
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c index bf83157337e4..5910020c3f24 100644 --- a/arch/x86/kernel/apic_64.c +++ b/arch/x86/kernel/apic_64.c | |||
@@ -360,7 +360,8 @@ static void __init calibrate_APIC_clock(void) | |||
360 | result / 1000 / 1000, result / 1000 % 1000); | 360 | result / 1000 / 1000, result / 1000 % 1000); |
361 | 361 | ||
362 | /* Calculate the scaled math multiplication factor */ | 362 | /* Calculate the scaled math multiplication factor */ |
363 | lapic_clockevent.mult = div_sc(result, NSEC_PER_SEC, 32); | 363 | lapic_clockevent.mult = div_sc(result, NSEC_PER_SEC, |
364 | lapic_clockevent.shift); | ||
364 | lapic_clockevent.max_delta_ns = | 365 | lapic_clockevent.max_delta_ns = |
365 | clockevent_delta2ns(0x7FFFFF, &lapic_clockevent); | 366 | clockevent_delta2ns(0x7FFFFF, &lapic_clockevent); |
366 | lapic_clockevent.min_delta_ns = | 367 | lapic_clockevent.min_delta_ns = |
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index ee7c45235e54..a0c6f8190887 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile | |||
@@ -11,7 +11,6 @@ obj-$(CONFIG_X86_32) += cyrix.o | |||
11 | obj-$(CONFIG_X86_32) += centaur.o | 11 | obj-$(CONFIG_X86_32) += centaur.o |
12 | obj-$(CONFIG_X86_32) += transmeta.o | 12 | obj-$(CONFIG_X86_32) += transmeta.o |
13 | obj-$(CONFIG_X86_32) += intel.o | 13 | obj-$(CONFIG_X86_32) += intel.o |
14 | obj-$(CONFIG_X86_32) += nexgen.o | ||
15 | obj-$(CONFIG_X86_32) += umc.o | 14 | obj-$(CONFIG_X86_32) += umc.o |
16 | 15 | ||
17 | obj-$(CONFIG_X86_MCE) += mcheck/ | 16 | obj-$(CONFIG_X86_MCE) += mcheck/ |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 0173065dc3b7..245866828294 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -343,10 +343,4 @@ static struct cpu_dev amd_cpu_dev __cpuinitdata = { | |||
343 | .c_size_cache = amd_size_cache, | 343 | .c_size_cache = amd_size_cache, |
344 | }; | 344 | }; |
345 | 345 | ||
346 | int __init amd_init_cpu(void) | ||
347 | { | ||
348 | cpu_devs[X86_VENDOR_AMD] = &amd_cpu_dev; | ||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | cpu_vendor_dev_register(X86_VENDOR_AMD, &amd_cpu_dev); | 346 | cpu_vendor_dev_register(X86_VENDOR_AMD, &amd_cpu_dev); |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 9a699ed03598..e07e8c068ae0 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c | |||
@@ -49,7 +49,7 @@ static int banks; | |||
49 | static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL }; | 49 | static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL }; |
50 | static unsigned long notify_user; | 50 | static unsigned long notify_user; |
51 | static int rip_msr; | 51 | static int rip_msr; |
52 | static int mce_bootlog = 1; | 52 | static int mce_bootlog = -1; |
53 | static atomic_t mce_events; | 53 | static atomic_t mce_events; |
54 | 54 | ||
55 | static char trigger[128]; | 55 | static char trigger[128]; |
@@ -471,13 +471,15 @@ static void mce_init(void *dummy) | |||
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) { |
475 | /* disable GART TBL walk error reporting, which trips off | 475 | if(c->x86 == 15) |
476 | incorrectly with the IOMMU & 3ware & Cerberus. */ | 476 | /* disable GART TBL walk error reporting, which trips off |
477 | clear_bit(10, &bank[4]); | 477 | incorrectly with the IOMMU & 3ware & Cerberus. */ |
478 | /* Lots of broken BIOS around that don't clear them | 478 | clear_bit(10, &bank[4]); |
479 | by default and leave crap in there. Don't log. */ | 479 | if(c->x86 <= 17 && mce_bootlog < 0) |
480 | mce_bootlog = 0; | 480 | /* Lots of broken BIOS around that don't clear them |
481 | by default and leave crap in there. Don't log. */ | ||
482 | mce_bootlog = 0; | ||
481 | } | 483 | } |
482 | 484 | ||
483 | } | 485 | } |
diff --git a/arch/x86/kernel/cpu/nexgen.c b/arch/x86/kernel/cpu/nexgen.c deleted file mode 100644 index 5d5e1c134123..000000000000 --- a/arch/x86/kernel/cpu/nexgen.c +++ /dev/null | |||
@@ -1,59 +0,0 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/init.h> | ||
3 | #include <linux/string.h> | ||
4 | #include <asm/processor.h> | ||
5 | |||
6 | #include "cpu.h" | ||
7 | |||
8 | /* | ||
9 | * Detect a NexGen CPU running without BIOS hypercode new enough | ||
10 | * to have CPUID. (Thanks to Herbert Oppmann) | ||
11 | */ | ||
12 | |||
13 | static int __cpuinit deep_magic_nexgen_probe(void) | ||
14 | { | ||
15 | int ret; | ||
16 | |||
17 | __asm__ __volatile__ ( | ||
18 | " movw $0x5555, %%ax\n" | ||
19 | " xorw %%dx,%%dx\n" | ||
20 | " movw $2, %%cx\n" | ||
21 | " divw %%cx\n" | ||
22 | " movl $0, %%eax\n" | ||
23 | " jnz 1f\n" | ||
24 | " movl $1, %%eax\n" | ||
25 | "1:\n" | ||
26 | : "=a" (ret) : : "cx", "dx"); | ||
27 | return ret; | ||
28 | } | ||
29 | |||
30 | static void __cpuinit init_nexgen(struct cpuinfo_x86 *c) | ||
31 | { | ||
32 | c->x86_cache_size = 256; /* A few had 1 MB... */ | ||
33 | } | ||
34 | |||
35 | static void __cpuinit nexgen_identify(struct cpuinfo_x86 *c) | ||
36 | { | ||
37 | /* Detect NexGen with old hypercode */ | ||
38 | if (deep_magic_nexgen_probe()) | ||
39 | strcpy(c->x86_vendor_id, "NexGenDriven"); | ||
40 | } | ||
41 | |||
42 | static struct cpu_dev nexgen_cpu_dev __cpuinitdata = { | ||
43 | .c_vendor = "Nexgen", | ||
44 | .c_ident = { "NexGenDriven" }, | ||
45 | .c_models = { | ||
46 | { .vendor = X86_VENDOR_NEXGEN, | ||
47 | .family = 5, | ||
48 | .model_names = { [1] = "Nx586" } | ||
49 | }, | ||
50 | }, | ||
51 | .c_init = init_nexgen, | ||
52 | .c_identify = nexgen_identify, | ||
53 | }; | ||
54 | |||
55 | int __init nexgen_init_cpu(void) | ||
56 | { | ||
57 | cpu_devs[X86_VENDOR_NEXGEN] = &nexgen_cpu_dev; | ||
58 | return 0; | ||
59 | } | ||
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c index b943e10ad814..f9ae93adffe5 100644 --- a/arch/x86/kernel/cpu/perfctr-watchdog.c +++ b/arch/x86/kernel/cpu/perfctr-watchdog.c | |||
@@ -614,16 +614,6 @@ static struct wd_ops intel_arch_wd_ops __read_mostly = { | |||
614 | .evntsel = MSR_ARCH_PERFMON_EVENTSEL1, | 614 | .evntsel = MSR_ARCH_PERFMON_EVENTSEL1, |
615 | }; | 615 | }; |
616 | 616 | ||
617 | static struct wd_ops coreduo_wd_ops = { | ||
618 | .reserve = single_msr_reserve, | ||
619 | .unreserve = single_msr_unreserve, | ||
620 | .setup = setup_intel_arch_watchdog, | ||
621 | .rearm = p6_rearm, | ||
622 | .stop = single_msr_stop_watchdog, | ||
623 | .perfctr = MSR_ARCH_PERFMON_PERFCTR0, | ||
624 | .evntsel = MSR_ARCH_PERFMON_EVENTSEL0, | ||
625 | }; | ||
626 | |||
627 | static void probe_nmi_watchdog(void) | 617 | static void probe_nmi_watchdog(void) |
628 | { | 618 | { |
629 | switch (boot_cpu_data.x86_vendor) { | 619 | switch (boot_cpu_data.x86_vendor) { |
@@ -637,8 +627,8 @@ static void probe_nmi_watchdog(void) | |||
637 | /* Work around Core Duo (Yonah) errata AE49 where perfctr1 | 627 | /* Work around Core Duo (Yonah) errata AE49 where perfctr1 |
638 | doesn't have a working enable bit. */ | 628 | doesn't have a working enable bit. */ |
639 | if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 14) { | 629 | if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 14) { |
640 | wd_ops = &coreduo_wd_ops; | 630 | intel_arch_wd_ops.perfctr = MSR_ARCH_PERFMON_PERFCTR0; |
641 | break; | 631 | intel_arch_wd_ops.evntsel = MSR_ARCH_PERFMON_EVENTSEL0; |
642 | } | 632 | } |
643 | if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { | 633 | if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { |
644 | wd_ops = &intel_arch_wd_ops; | 634 | wd_ops = &intel_arch_wd_ops; |
diff --git a/arch/x86/kernel/genapic_64.c b/arch/x86/kernel/genapic_64.c index 9546ef408b92..021624c83583 100644 --- a/arch/x86/kernel/genapic_64.c +++ b/arch/x86/kernel/genapic_64.c | |||
@@ -51,7 +51,7 @@ void __init setup_apic_routing(void) | |||
51 | else | 51 | else |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | if (cpus_weight(cpu_possible_map) <= 8) | 54 | if (num_possible_cpus() <= 8) |
55 | genapic = &apic_flat; | 55 | genapic = &apic_flat; |
56 | else | 56 | else |
57 | genapic = &apic_physflat; | 57 | genapic = &apic_physflat; |
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 993c76773256..d31d6b72d60d 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/sections.h> | 22 | #include <asm/sections.h> |
23 | #include <asm/kdebug.h> | 23 | #include <asm/kdebug.h> |
24 | #include <asm/e820.h> | 24 | #include <asm/e820.h> |
25 | #include <asm/bios_ebda.h> | ||
25 | 26 | ||
26 | static void __init zap_identity_mappings(void) | 27 | static void __init zap_identity_mappings(void) |
27 | { | 28 | { |
@@ -49,7 +50,6 @@ static void __init copy_bootdata(char *real_mode_data) | |||
49 | } | 50 | } |
50 | } | 51 | } |
51 | 52 | ||
52 | #define BIOS_EBDA_SEGMENT 0x40E | ||
53 | #define BIOS_LOWMEM_KILOBYTES 0x413 | 53 | #define BIOS_LOWMEM_KILOBYTES 0x413 |
54 | 54 | ||
55 | /* | 55 | /* |
@@ -80,8 +80,7 @@ static void __init reserve_ebda_region(void) | |||
80 | lowmem <<= 10; | 80 | lowmem <<= 10; |
81 | 81 | ||
82 | /* start of EBDA area */ | 82 | /* start of EBDA area */ |
83 | ebda_addr = *(unsigned short *)__va(BIOS_EBDA_SEGMENT); | 83 | ebda_addr = get_bios_ebda(); |
84 | ebda_addr <<= 4; | ||
85 | 84 | ||
86 | /* Fixup: bios puts an EBDA in the top 64K segment */ | 85 | /* Fixup: bios puts an EBDA in the top 64K segment */ |
87 | /* of conventional memory, but does not adjust lowmem. */ | 86 | /* of conventional memory, but does not adjust lowmem. */ |
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 36652ea1a265..9007f9ea64ee 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -218,7 +218,7 @@ static void hpet_legacy_clockevent_register(void) | |||
218 | hpet_freq = 1000000000000000ULL; | 218 | hpet_freq = 1000000000000000ULL; |
219 | do_div(hpet_freq, hpet_period); | 219 | do_div(hpet_freq, hpet_period); |
220 | hpet_clockevent.mult = div_sc((unsigned long) hpet_freq, | 220 | hpet_clockevent.mult = div_sc((unsigned long) hpet_freq, |
221 | NSEC_PER_SEC, 32); | 221 | NSEC_PER_SEC, hpet_clockevent.shift); |
222 | /* Calculate the min / max delta */ | 222 | /* Calculate the min / max delta */ |
223 | hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, | 223 | hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, |
224 | &hpet_clockevent); | 224 | &hpet_clockevent); |
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c index 8540abe86ade..c1b5e3ece1f2 100644 --- a/arch/x86/kernel/i8253.c +++ b/arch/x86/kernel/i8253.c | |||
@@ -115,7 +115,8 @@ void __init setup_pit_timer(void) | |||
115 | * IO_APIC has been initialized. | 115 | * IO_APIC has been initialized. |
116 | */ | 116 | */ |
117 | pit_clockevent.cpumask = cpumask_of_cpu(smp_processor_id()); | 117 | pit_clockevent.cpumask = cpumask_of_cpu(smp_processor_id()); |
118 | pit_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, 32); | 118 | pit_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, |
119 | pit_clockevent.shift); | ||
119 | pit_clockevent.max_delta_ns = | 120 | pit_clockevent.max_delta_ns = |
120 | clockevent_delta2ns(0x7FFF, &pit_clockevent); | 121 | clockevent_delta2ns(0x7FFF, &pit_clockevent); |
121 | pit_clockevent.min_delta_ns = | 122 | pit_clockevent.min_delta_ns = |
@@ -224,7 +225,8 @@ static int __init init_pit_clocksource(void) | |||
224 | pit_clockevent.mode != CLOCK_EVT_MODE_PERIODIC) | 225 | pit_clockevent.mode != CLOCK_EVT_MODE_PERIODIC) |
225 | return 0; | 226 | return 0; |
226 | 227 | ||
227 | clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, 20); | 228 | clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, |
229 | clocksource_pit.shift); | ||
228 | return clocksource_register(&clocksource_pit); | 230 | return clocksource_register(&clocksource_pit); |
229 | } | 231 | } |
230 | arch_initcall(init_pit_clocksource); | 232 | arch_initcall(init_pit_clocksource); |
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c index 2e2f42074e18..696b8e4e66bb 100644 --- a/arch/x86/kernel/io_apic_32.c +++ b/arch/x86/kernel/io_apic_32.c | |||
@@ -2068,7 +2068,7 @@ static void __init setup_nmi(void) | |||
2068 | * cycles as some i82489DX-based boards have glue logic that keeps the | 2068 | * cycles as some i82489DX-based boards have glue logic that keeps the |
2069 | * 8259A interrupt line asserted until INTA. --macro | 2069 | * 8259A interrupt line asserted until INTA. --macro |
2070 | */ | 2070 | */ |
2071 | static inline void unlock_ExtINT_logic(void) | 2071 | static inline void __init unlock_ExtINT_logic(void) |
2072 | { | 2072 | { |
2073 | int apic, pin, i; | 2073 | int apic, pin, i; |
2074 | struct IO_APIC_route_entry entry0, entry1; | 2074 | struct IO_APIC_route_entry entry0, entry1; |
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c index 9ba11d07920f..ef1a8dfcc529 100644 --- a/arch/x86/kernel/io_apic_64.c +++ b/arch/x86/kernel/io_apic_64.c | |||
@@ -1599,7 +1599,7 @@ static void __init setup_nmi(void) | |||
1599 | * cycles as some i82489DX-based boards have glue logic that keeps the | 1599 | * cycles as some i82489DX-based boards have glue logic that keeps the |
1600 | * 8259A interrupt line asserted until INTA. --macro | 1600 | * 8259A interrupt line asserted until INTA. --macro |
1601 | */ | 1601 | */ |
1602 | static inline void unlock_ExtINT_logic(void) | 1602 | static inline void __init unlock_ExtINT_logic(void) |
1603 | { | 1603 | { |
1604 | int apic, pin, i; | 1604 | int apic, pin, i; |
1605 | struct IO_APIC_route_entry entry0, entry1; | 1605 | struct IO_APIC_route_entry entry0, entry1; |
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index 6ea67b76a214..00bda7bcda63 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c | |||
@@ -134,7 +134,7 @@ unsigned int do_IRQ(struct pt_regs *regs) | |||
134 | : "=a" (arg1), "=d" (arg2), "=b" (bx) | 134 | : "=a" (arg1), "=d" (arg2), "=b" (bx) |
135 | : "0" (irq), "1" (desc), "2" (isp), | 135 | : "0" (irq), "1" (desc), "2" (isp), |
136 | "D" (desc->handle_irq) | 136 | "D" (desc->handle_irq) |
137 | : "memory", "cc" | 137 | : "memory", "cc", "ecx" |
138 | ); | 138 | ); |
139 | } else | 139 | } else |
140 | #endif | 140 | #endif |
diff --git a/arch/x86/kernel/mfgpt_32.c b/arch/x86/kernel/mfgpt_32.c index b402c0f3f192..cfc2648d25ff 100644 --- a/arch/x86/kernel/mfgpt_32.c +++ b/arch/x86/kernel/mfgpt_32.c | |||
@@ -364,7 +364,8 @@ int __init mfgpt_timer_setup(void) | |||
364 | geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP, val); | 364 | geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP, val); |
365 | 365 | ||
366 | /* Set up the clock event */ | 366 | /* Set up the clock event */ |
367 | mfgpt_clockevent.mult = div_sc(MFGPT_HZ, NSEC_PER_SEC, 32); | 367 | mfgpt_clockevent.mult = div_sc(MFGPT_HZ, NSEC_PER_SEC, |
368 | mfgpt_clockevent.shift); | ||
368 | mfgpt_clockevent.min_delta_ns = clockevent_delta2ns(0xF, | 369 | mfgpt_clockevent.min_delta_ns = clockevent_delta2ns(0xF, |
369 | &mfgpt_clockevent); | 370 | &mfgpt_clockevent); |
370 | mfgpt_clockevent.max_delta_ns = clockevent_delta2ns(0xFFFE, | 371 | mfgpt_clockevent.max_delta_ns = clockevent_delta2ns(0xFFFE, |
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 70744e344fa1..3e2c54dc8b29 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c | |||
@@ -686,13 +686,11 @@ void __init get_smp_config(void) | |||
686 | static int __init smp_scan_config(unsigned long base, unsigned long length, | 686 | static int __init smp_scan_config(unsigned long base, unsigned long length, |
687 | unsigned reserve) | 687 | unsigned reserve) |
688 | { | 688 | { |
689 | extern void __bad_mpf_size(void); | ||
690 | unsigned int *bp = phys_to_virt(base); | 689 | unsigned int *bp = phys_to_virt(base); |
691 | struct intel_mp_floating *mpf; | 690 | struct intel_mp_floating *mpf; |
692 | 691 | ||
693 | Dprintk("Scan SMP from %p for %ld bytes.\n", bp, length); | 692 | Dprintk("Scan SMP from %p for %ld bytes.\n", bp, length); |
694 | if (sizeof(*mpf) != 16) | 693 | BUILD_BUG_ON(sizeof(*mpf) != 16); |
695 | __bad_mpf_size(); | ||
696 | 694 | ||
697 | while (length > 0) { | 695 | while (length > 0) { |
698 | mpf = (struct intel_mp_floating *)bp; | 696 | mpf = (struct intel_mp_floating *)bp; |
@@ -801,7 +799,6 @@ void __init find_smp_config(void) | |||
801 | #ifdef CONFIG_X86_IO_APIC | 799 | #ifdef CONFIG_X86_IO_APIC |
802 | 800 | ||
803 | #define MP_ISA_BUS 0 | 801 | #define MP_ISA_BUS 0 |
804 | #define MP_MAX_IOAPIC_PIN 127 | ||
805 | 802 | ||
806 | extern struct mp_ioapic_routing mp_ioapic_routing[MAX_IO_APICS]; | 803 | extern struct mp_ioapic_routing mp_ioapic_routing[MAX_IO_APICS]; |
807 | 804 | ||
@@ -820,7 +817,7 @@ static int mp_find_ioapic(int gsi) | |||
820 | return -1; | 817 | return -1; |
821 | } | 818 | } |
822 | 819 | ||
823 | static u8 uniq_ioapic_id(u8 id) | 820 | static u8 __init uniq_ioapic_id(u8 id) |
824 | { | 821 | { |
825 | #ifdef CONFIG_X86_32 | 822 | #ifdef CONFIG_X86_32 |
826 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && | 823 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && |
@@ -909,14 +906,7 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) | |||
909 | intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid; /* APIC ID */ | 906 | intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid; /* APIC ID */ |
910 | intsrc.mpc_dstirq = pin; /* INTIN# */ | 907 | intsrc.mpc_dstirq = pin; /* INTIN# */ |
911 | 908 | ||
912 | Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, %d-%d\n", | 909 | MP_intsrc_info(&intsrc); |
913 | intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, | ||
914 | (intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, | ||
915 | intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, intsrc.mpc_dstirq); | ||
916 | |||
917 | mp_irqs[mp_irq_entries] = intsrc; | ||
918 | if (++mp_irq_entries == MAX_IRQ_SOURCES) | ||
919 | panic("Max # of irq sources exceeded!\n"); | ||
920 | } | 910 | } |
921 | 911 | ||
922 | int es7000_plat; | 912 | int es7000_plat; |
@@ -985,23 +975,14 @@ void __init mp_config_acpi_legacy_irqs(void) | |||
985 | intsrc.mpc_srcbusirq = i; /* Identity mapped */ | 975 | intsrc.mpc_srcbusirq = i; /* Identity mapped */ |
986 | intsrc.mpc_dstirq = i; | 976 | intsrc.mpc_dstirq = i; |
987 | 977 | ||
988 | Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, " | 978 | MP_intsrc_info(&intsrc); |
989 | "%d-%d\n", intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, | ||
990 | (intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, | ||
991 | intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, | ||
992 | intsrc.mpc_dstirq); | ||
993 | |||
994 | mp_irqs[mp_irq_entries] = intsrc; | ||
995 | if (++mp_irq_entries == MAX_IRQ_SOURCES) | ||
996 | panic("Max # of irq sources exceeded!\n"); | ||
997 | } | 979 | } |
998 | } | 980 | } |
999 | 981 | ||
1000 | int mp_register_gsi(u32 gsi, int triggering, int polarity) | 982 | int mp_register_gsi(u32 gsi, int triggering, int polarity) |
1001 | { | 983 | { |
1002 | int ioapic = -1; | 984 | int ioapic; |
1003 | int ioapic_pin = 0; | 985 | int ioapic_pin; |
1004 | int idx, bit = 0; | ||
1005 | #ifdef CONFIG_X86_32 | 986 | #ifdef CONFIG_X86_32 |
1006 | #define MAX_GSI_NUM 4096 | 987 | #define MAX_GSI_NUM 4096 |
1007 | #define IRQ_COMPRESSION_START 64 | 988 | #define IRQ_COMPRESSION_START 64 |
@@ -1041,15 +1022,13 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) | |||
1041 | * with redundant pin->gsi mappings (but unique PCI devices); | 1022 | * with redundant pin->gsi mappings (but unique PCI devices); |
1042 | * we only program the IOAPIC on the first. | 1023 | * we only program the IOAPIC on the first. |
1043 | */ | 1024 | */ |
1044 | bit = ioapic_pin % 32; | 1025 | if (ioapic_pin > MP_MAX_IOAPIC_PIN) { |
1045 | idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); | ||
1046 | if (idx > 3) { | ||
1047 | printk(KERN_ERR "Invalid reference to IOAPIC pin " | 1026 | printk(KERN_ERR "Invalid reference to IOAPIC pin " |
1048 | "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, | 1027 | "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, |
1049 | ioapic_pin); | 1028 | ioapic_pin); |
1050 | return gsi; | 1029 | return gsi; |
1051 | } | 1030 | } |
1052 | if ((1 << bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { | 1031 | if (test_bit(ioapic_pin, mp_ioapic_routing[ioapic].pin_programmed)) { |
1053 | Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", | 1032 | Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", |
1054 | mp_ioapic_routing[ioapic].apic_id, ioapic_pin); | 1033 | mp_ioapic_routing[ioapic].apic_id, ioapic_pin); |
1055 | #ifdef CONFIG_X86_32 | 1034 | #ifdef CONFIG_X86_32 |
@@ -1059,7 +1038,7 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) | |||
1059 | #endif | 1038 | #endif |
1060 | } | 1039 | } |
1061 | 1040 | ||
1062 | mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1 << bit); | 1041 | set_bit(ioapic_pin, mp_ioapic_routing[ioapic].pin_programmed); |
1063 | #ifdef CONFIG_X86_32 | 1042 | #ifdef CONFIG_X86_32 |
1064 | /* | 1043 | /* |
1065 | * For GSI >= 64, use IRQ compression | 1044 | * For GSI >= 64, use IRQ compression |
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 2edee22e9c30..e28ec497e142 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <asm/system.h> | 43 | #include <asm/system.h> |
44 | #include <asm/dma.h> | 44 | #include <asm/dma.h> |
45 | #include <asm/rio.h> | 45 | #include <asm/rio.h> |
46 | #include <asm/bios_ebda.h> | ||
46 | 47 | ||
47 | #ifdef CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT | 48 | #ifdef CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT |
48 | int use_calgary __read_mostly = 1; | 49 | int use_calgary __read_mostly = 1; |
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 559c1b027417..fb03ef380f0e 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
@@ -1207,97 +1207,16 @@ static int genregs32_set(struct task_struct *target, | |||
1207 | return ret; | 1207 | return ret; |
1208 | } | 1208 | } |
1209 | 1209 | ||
1210 | static long ptrace32_siginfo(unsigned request, u32 pid, u32 addr, u32 data) | 1210 | long compat_arch_ptrace(struct task_struct *child, compat_long_t request, |
1211 | compat_ulong_t caddr, compat_ulong_t cdata) | ||
1211 | { | 1212 | { |
1212 | siginfo_t __user *si = compat_alloc_user_space(sizeof(siginfo_t)); | 1213 | unsigned long addr = caddr; |
1213 | compat_siginfo_t __user *si32 = compat_ptr(data); | 1214 | unsigned long data = cdata; |
1214 | siginfo_t ssi; | ||
1215 | int ret; | ||
1216 | |||
1217 | if (request == PTRACE_SETSIGINFO) { | ||
1218 | memset(&ssi, 0, sizeof(siginfo_t)); | ||
1219 | ret = copy_siginfo_from_user32(&ssi, si32); | ||
1220 | if (ret) | ||
1221 | return ret; | ||
1222 | if (copy_to_user(si, &ssi, sizeof(siginfo_t))) | ||
1223 | return -EFAULT; | ||
1224 | } | ||
1225 | ret = sys_ptrace(request, pid, addr, (unsigned long)si); | ||
1226 | if (ret) | ||
1227 | return ret; | ||
1228 | if (request == PTRACE_GETSIGINFO) { | ||
1229 | if (copy_from_user(&ssi, si, sizeof(siginfo_t))) | ||
1230 | return -EFAULT; | ||
1231 | ret = copy_siginfo_to_user32(si32, &ssi); | ||
1232 | } | ||
1233 | return ret; | ||
1234 | } | ||
1235 | |||
1236 | asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) | ||
1237 | { | ||
1238 | struct task_struct *child; | ||
1239 | struct pt_regs *childregs; | ||
1240 | void __user *datap = compat_ptr(data); | 1215 | void __user *datap = compat_ptr(data); |
1241 | int ret; | 1216 | int ret; |
1242 | __u32 val; | 1217 | __u32 val; |
1243 | 1218 | ||
1244 | switch (request) { | 1219 | switch (request) { |
1245 | case PTRACE_TRACEME: | ||
1246 | case PTRACE_ATTACH: | ||
1247 | case PTRACE_KILL: | ||
1248 | case PTRACE_CONT: | ||
1249 | case PTRACE_SINGLESTEP: | ||
1250 | case PTRACE_SINGLEBLOCK: | ||
1251 | case PTRACE_DETACH: | ||
1252 | case PTRACE_SYSCALL: | ||
1253 | case PTRACE_OLDSETOPTIONS: | ||
1254 | case PTRACE_SETOPTIONS: | ||
1255 | case PTRACE_SET_THREAD_AREA: | ||
1256 | case PTRACE_GET_THREAD_AREA: | ||
1257 | #ifdef X86_BTS | ||
1258 | case PTRACE_BTS_CONFIG: | ||
1259 | case PTRACE_BTS_STATUS: | ||
1260 | case PTRACE_BTS_SIZE: | ||
1261 | case PTRACE_BTS_GET: | ||
1262 | case PTRACE_BTS_CLEAR: | ||
1263 | case PTRACE_BTS_DRAIN: | ||
1264 | #endif | ||
1265 | return sys_ptrace(request, pid, addr, data); | ||
1266 | |||
1267 | default: | ||
1268 | return -EINVAL; | ||
1269 | |||
1270 | case PTRACE_PEEKTEXT: | ||
1271 | case PTRACE_PEEKDATA: | ||
1272 | case PTRACE_POKEDATA: | ||
1273 | case PTRACE_POKETEXT: | ||
1274 | case PTRACE_POKEUSR: | ||
1275 | case PTRACE_PEEKUSR: | ||
1276 | case PTRACE_GETREGS: | ||
1277 | case PTRACE_SETREGS: | ||
1278 | case PTRACE_SETFPREGS: | ||
1279 | case PTRACE_GETFPREGS: | ||
1280 | case PTRACE_SETFPXREGS: | ||
1281 | case PTRACE_GETFPXREGS: | ||
1282 | case PTRACE_GETEVENTMSG: | ||
1283 | break; | ||
1284 | |||
1285 | case PTRACE_SETSIGINFO: | ||
1286 | case PTRACE_GETSIGINFO: | ||
1287 | return ptrace32_siginfo(request, pid, addr, data); | ||
1288 | } | ||
1289 | |||
1290 | child = ptrace_get_task_struct(pid); | ||
1291 | if (IS_ERR(child)) | ||
1292 | return PTR_ERR(child); | ||
1293 | |||
1294 | ret = ptrace_check_attach(child, request == PTRACE_KILL); | ||
1295 | if (ret < 0) | ||
1296 | goto out; | ||
1297 | |||
1298 | childregs = task_pt_regs(child); | ||
1299 | |||
1300 | switch (request) { | ||
1301 | case PTRACE_PEEKUSR: | 1220 | case PTRACE_PEEKUSR: |
1302 | ret = getreg32(child, addr, &val); | 1221 | ret = getreg32(child, addr, &val); |
1303 | if (ret == 0) | 1222 | if (ret == 0) |
@@ -1343,12 +1262,14 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) | |||
1343 | sizeof(struct user32_fxsr_struct), | 1262 | sizeof(struct user32_fxsr_struct), |
1344 | datap); | 1263 | datap); |
1345 | 1264 | ||
1265 | case PTRACE_GET_THREAD_AREA: | ||
1266 | case PTRACE_SET_THREAD_AREA: | ||
1267 | return arch_ptrace(child, request, addr, data); | ||
1268 | |||
1346 | default: | 1269 | default: |
1347 | return compat_ptrace_request(child, request, addr, data); | 1270 | return compat_ptrace_request(child, request, addr, data); |
1348 | } | 1271 | } |
1349 | 1272 | ||
1350 | out: | ||
1351 | put_task_struct(child); | ||
1352 | return ret; | 1273 | return ret; |
1353 | } | 1274 | } |
1354 | 1275 | ||
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 455d3c80960b..44cc9b933932 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c | |||
@@ -389,7 +389,6 @@ unsigned long __init find_max_low_pfn(void) | |||
389 | return max_low_pfn; | 389 | return max_low_pfn; |
390 | } | 390 | } |
391 | 391 | ||
392 | #define BIOS_EBDA_SEGMENT 0x40E | ||
393 | #define BIOS_LOWMEM_KILOBYTES 0x413 | 392 | #define BIOS_LOWMEM_KILOBYTES 0x413 |
394 | 393 | ||
395 | /* | 394 | /* |
@@ -420,8 +419,7 @@ static void __init reserve_ebda_region(void) | |||
420 | lowmem <<= 10; | 419 | lowmem <<= 10; |
421 | 420 | ||
422 | /* start of EBDA area */ | 421 | /* start of EBDA area */ |
423 | ebda_addr = *(unsigned short *)__va(BIOS_EBDA_SEGMENT); | 422 | ebda_addr = get_bios_ebda(); |
424 | ebda_addr <<= 4; | ||
425 | 423 | ||
426 | /* Fixup: bios puts an EBDA in the top 64K segment */ | 424 | /* Fixup: bios puts an EBDA in the top 64K segment */ |
427 | /* of conventional memory, but does not adjust lowmem. */ | 425 | /* of conventional memory, but does not adjust lowmem. */ |
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index c2ec3dcb6b99..17bdf2343095 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c | |||
@@ -116,7 +116,7 @@ extern int root_mountflags; | |||
116 | 116 | ||
117 | char __initdata command_line[COMMAND_LINE_SIZE]; | 117 | char __initdata command_line[COMMAND_LINE_SIZE]; |
118 | 118 | ||
119 | struct resource standard_io_resources[] = { | 119 | static struct resource standard_io_resources[] = { |
120 | { .name = "dma1", .start = 0x00, .end = 0x1f, | 120 | { .name = "dma1", .start = 0x00, .end = 0x1f, |
121 | .flags = IORESOURCE_BUSY | IORESOURCE_IO }, | 121 | .flags = IORESOURCE_BUSY | IORESOURCE_IO }, |
122 | { .name = "pic1", .start = 0x20, .end = 0x21, | 122 | { .name = "pic1", .start = 0x20, .end = 0x21, |
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c index f1b117930837..8e05e7f7bd40 100644 --- a/arch/x86/kernel/signal_32.c +++ b/arch/x86/kernel/signal_32.c | |||
@@ -413,16 +413,6 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
413 | regs->ss = __USER_DS; | 413 | regs->ss = __USER_DS; |
414 | regs->cs = __USER_CS; | 414 | regs->cs = __USER_CS; |
415 | 415 | ||
416 | /* | ||
417 | * Clear TF when entering the signal handler, but | ||
418 | * notify any tracer that was single-stepping it. | ||
419 | * The tracer may want to single-step inside the | ||
420 | * handler too. | ||
421 | */ | ||
422 | regs->flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_DF); | ||
423 | if (test_thread_flag(TIF_SINGLESTEP)) | ||
424 | ptrace_notify(SIGTRAP); | ||
425 | |||
426 | return 0; | 416 | return 0; |
427 | 417 | ||
428 | give_sigsegv: | 418 | give_sigsegv: |
@@ -501,16 +491,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
501 | regs->ss = __USER_DS; | 491 | regs->ss = __USER_DS; |
502 | regs->cs = __USER_CS; | 492 | regs->cs = __USER_CS; |
503 | 493 | ||
504 | /* | ||
505 | * Clear TF when entering the signal handler, but | ||
506 | * notify any tracer that was single-stepping it. | ||
507 | * The tracer may want to single-step inside the | ||
508 | * handler too. | ||
509 | */ | ||
510 | regs->flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_DF); | ||
511 | if (test_thread_flag(TIF_SINGLESTEP)) | ||
512 | ptrace_notify(SIGTRAP); | ||
513 | |||
514 | return 0; | 494 | return 0; |
515 | 495 | ||
516 | give_sigsegv: | 496 | give_sigsegv: |
@@ -566,6 +546,21 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
566 | if (ret) | 546 | if (ret) |
567 | return ret; | 547 | return ret; |
568 | 548 | ||
549 | /* | ||
550 | * Clear the direction flag as per the ABI for function entry. | ||
551 | */ | ||
552 | regs->flags &= ~X86_EFLAGS_DF; | ||
553 | |||
554 | /* | ||
555 | * Clear TF when entering the signal handler, but | ||
556 | * notify any tracer that was single-stepping it. | ||
557 | * The tracer may want to single-step inside the | ||
558 | * handler too. | ||
559 | */ | ||
560 | regs->flags &= ~X86_EFLAGS_TF; | ||
561 | if (test_thread_flag(TIF_SINGLESTEP)) | ||
562 | ptrace_notify(SIGTRAP); | ||
563 | |||
569 | spin_lock_irq(¤t->sighand->siglock); | 564 | spin_lock_irq(¤t->sighand->siglock); |
570 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); | 565 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); |
571 | if (!(ka->sa.sa_flags & SA_NODEFER)) | 566 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c index 827179c5b32a..ccb2a4560c2d 100644 --- a/arch/x86/kernel/signal_64.c +++ b/arch/x86/kernel/signal_64.c | |||
@@ -285,14 +285,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
285 | even if the handler happens to be interrupting 32-bit code. */ | 285 | even if the handler happens to be interrupting 32-bit code. */ |
286 | regs->cs = __USER_CS; | 286 | regs->cs = __USER_CS; |
287 | 287 | ||
288 | /* This, by contrast, has nothing to do with segment registers - | ||
289 | see include/asm-x86_64/uaccess.h for details. */ | ||
290 | set_fs(USER_DS); | ||
291 | |||
292 | regs->flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_DF); | ||
293 | if (test_thread_flag(TIF_SINGLESTEP)) | ||
294 | ptrace_notify(SIGTRAP); | ||
295 | |||
296 | return 0; | 288 | return 0; |
297 | 289 | ||
298 | give_sigsegv: | 290 | give_sigsegv: |
@@ -380,6 +372,28 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
380 | ret = setup_rt_frame(sig, ka, info, oldset, regs); | 372 | ret = setup_rt_frame(sig, ka, info, oldset, regs); |
381 | 373 | ||
382 | if (ret == 0) { | 374 | if (ret == 0) { |
375 | /* | ||
376 | * This has nothing to do with segment registers, | ||
377 | * despite the name. This magic affects uaccess.h | ||
378 | * macros' behavior. Reset it to the normal setting. | ||
379 | */ | ||
380 | set_fs(USER_DS); | ||
381 | |||
382 | /* | ||
383 | * Clear the direction flag as per the ABI for function entry. | ||
384 | */ | ||
385 | regs->flags &= ~X86_EFLAGS_DF; | ||
386 | |||
387 | /* | ||
388 | * Clear TF when entering the signal handler, but | ||
389 | * notify any tracer that was single-stepping it. | ||
390 | * The tracer may want to single-step inside the | ||
391 | * handler too. | ||
392 | */ | ||
393 | regs->flags &= ~X86_EFLAGS_TF; | ||
394 | if (test_thread_flag(TIF_SINGLESTEP)) | ||
395 | ptrace_notify(SIGTRAP); | ||
396 | |||
383 | spin_lock_irq(¤t->sighand->siglock); | 397 | spin_lock_irq(¤t->sighand->siglock); |
384 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 398 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
385 | if (!(ka->sa.sa_flags & SA_NODEFER)) | 399 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index eef79e84145f..04c662ba18f1 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -1058,7 +1058,7 @@ int __cpuinit native_cpu_up(unsigned int cpu) | |||
1058 | check_tsc_sync_source(cpu); | 1058 | check_tsc_sync_source(cpu); |
1059 | local_irq_restore(flags); | 1059 | local_irq_restore(flags); |
1060 | 1060 | ||
1061 | while (!cpu_isset(cpu, cpu_online_map)) { | 1061 | while (!cpu_online(cpu)) { |
1062 | cpu_relax(); | 1062 | cpu_relax(); |
1063 | touch_nmi_watchdog(); | 1063 | touch_nmi_watchdog(); |
1064 | } | 1064 | } |
@@ -1168,7 +1168,7 @@ static void __init smp_cpu_index_default(void) | |||
1168 | int i; | 1168 | int i; |
1169 | struct cpuinfo_x86 *c; | 1169 | struct cpuinfo_x86 *c; |
1170 | 1170 | ||
1171 | for_each_cpu_mask(i, cpu_possible_map) { | 1171 | for_each_possible_cpu(i) { |
1172 | c = &cpu_data(i); | 1172 | c = &cpu_data(i); |
1173 | /* mark all to hotplug */ | 1173 | /* mark all to hotplug */ |
1174 | c->cpu_index = NR_CPUS; | 1174 | c->cpu_index = NR_CPUS; |
diff --git a/arch/x86/kernel/summit_32.c b/arch/x86/kernel/summit_32.c index 6878a9c2df5d..ae751094eba9 100644 --- a/arch/x86/kernel/summit_32.c +++ b/arch/x86/kernel/summit_32.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <asm/io.h> | 31 | #include <asm/io.h> |
32 | #include <asm/bios_ebda.h> | ||
32 | #include <asm/mach-summit/mach_mpparse.h> | 33 | #include <asm/mach-summit/mach_mpparse.h> |
33 | 34 | ||
34 | static struct rio_table_hdr *rio_table_hdr __initdata; | 35 | static struct rio_table_hdr *rio_table_hdr __initdata; |
@@ -140,8 +141,8 @@ void __init setup_summit(void) | |||
140 | int i, next_wpeg, next_bus = 0; | 141 | int i, next_wpeg, next_bus = 0; |
141 | 142 | ||
142 | /* The pointer to the EBDA is stored in the word @ phys 0x40E(40:0E) */ | 143 | /* The pointer to the EBDA is stored in the word @ phys 0x40E(40:0E) */ |
143 | ptr = *(unsigned short *)phys_to_virt(0x40Eul); | 144 | ptr = get_bios_ebda(); |
144 | ptr = (unsigned long)phys_to_virt(ptr << 4); | 145 | ptr = (unsigned long)phys_to_virt(ptr); |
145 | 146 | ||
146 | rio_table_hdr = NULL; | 147 | rio_table_hdr = NULL; |
147 | offset = 0x180; | 148 | offset = 0x180; |
diff --git a/arch/x86/kernel/tlb_64.c b/arch/x86/kernel/tlb_64.c index df224a8774cb..a1f07d793202 100644 --- a/arch/x86/kernel/tlb_64.c +++ b/arch/x86/kernel/tlb_64.c | |||
@@ -195,9 +195,9 @@ static int __cpuinit init_smp_flush(void) | |||
195 | { | 195 | { |
196 | int i; | 196 | int i; |
197 | 197 | ||
198 | for_each_cpu_mask(i, cpu_possible_map) { | 198 | for_each_possible_cpu(i) |
199 | spin_lock_init(&per_cpu(flush_state, i).tlbstate_lock); | 199 | spin_lock_init(&per_cpu(flush_state, i).tlbstate_lock); |
200 | } | 200 | |
201 | return 0; | 201 | return 0; |
202 | } | 202 | } |
203 | core_initcall(init_smp_flush); | 203 | core_initcall(init_smp_flush); |
diff --git a/arch/x86/kernel/trampoline_32.S b/arch/x86/kernel/trampoline_32.S index 64580679861e..d8ccc3c6552f 100644 --- a/arch/x86/kernel/trampoline_32.S +++ b/arch/x86/kernel/trampoline_32.S | |||
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | /* We can free up trampoline after bootup if cpu hotplug is not supported. */ | 34 | /* We can free up trampoline after bootup if cpu hotplug is not supported. */ |
35 | #ifndef CONFIG_HOTPLUG_CPU | 35 | #ifndef CONFIG_HOTPLUG_CPU |
36 | .section ".init.data","aw",@progbits | 36 | .section ".cpuinit.data","aw",@progbits |
37 | #else | 37 | #else |
38 | .section .rodata,"a",@progbits | 38 | .section .rodata,"a",@progbits |
39 | #endif | 39 | #endif |
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index 471e694d6713..bde6f63e15d5 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c | |||
@@ -602,7 +602,7 @@ DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) | |||
602 | DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) | 602 | DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) |
603 | DO_ERROR(12, SIGBUS, "stack segment", stack_segment) | 603 | DO_ERROR(12, SIGBUS, "stack segment", stack_segment) |
604 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0) | 604 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0) |
605 | DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0, 1) | 605 | DO_ERROR_INFO(32, SIGILL, "iret exception", iret_error, ILL_BADSTK, 0, 1) |
606 | 606 | ||
607 | void __kprobes do_general_protection(struct pt_regs *regs, long error_code) | 607 | void __kprobes do_general_protection(struct pt_regs *regs, long error_code) |
608 | { | 608 | { |
diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c index 6e2c4efce0ef..8acbf0cdf1a5 100644 --- a/arch/x86/mach-voyager/voyager_smp.c +++ b/arch/x86/mach-voyager/voyager_smp.c | |||
@@ -113,7 +113,7 @@ static inline void send_QIC_CPI(__u32 cpuset, __u8 cpi) | |||
113 | for_each_online_cpu(cpu) { | 113 | for_each_online_cpu(cpu) { |
114 | if (cpuset & (1 << cpu)) { | 114 | if (cpuset & (1 << cpu)) { |
115 | #ifdef VOYAGER_DEBUG | 115 | #ifdef VOYAGER_DEBUG |
116 | if (!cpu_isset(cpu, cpu_online_map)) | 116 | if (!cpu_online(cpu)) |
117 | VDEBUG(("CPU%d sending cpi %d to CPU%d not in " | 117 | VDEBUG(("CPU%d sending cpi %d to CPU%d not in " |
118 | "cpu_online_map\n", | 118 | "cpu_online_map\n", |
119 | hard_smp_processor_id(), cpi, cpu)); | 119 | hard_smp_processor_id(), cpi, cpu)); |
@@ -683,9 +683,9 @@ void __init smp_boot_cpus(void) | |||
683 | * Code added from smpboot.c */ | 683 | * Code added from smpboot.c */ |
684 | { | 684 | { |
685 | unsigned long bogosum = 0; | 685 | unsigned long bogosum = 0; |
686 | for (i = 0; i < NR_CPUS; i++) | 686 | |
687 | if (cpu_isset(i, cpu_online_map)) | 687 | for_each_online_cpu(i) |
688 | bogosum += cpu_data(i).loops_per_jiffy; | 688 | bogosum += cpu_data(i).loops_per_jiffy; |
689 | printk(KERN_INFO "Total of %d processors activated " | 689 | printk(KERN_INFO "Total of %d processors activated " |
690 | "(%lu.%02lu BogoMIPS).\n", | 690 | "(%lu.%02lu BogoMIPS).\n", |
691 | cpucount + 1, bogosum / (500000 / HZ), | 691 | cpucount + 1, bogosum / (500000 / HZ), |
@@ -1838,7 +1838,7 @@ static int __cpuinit voyager_cpu_up(unsigned int cpu) | |||
1838 | return -EIO; | 1838 | return -EIO; |
1839 | /* Unleash the CPU! */ | 1839 | /* Unleash the CPU! */ |
1840 | cpu_set(cpu, smp_commenced_mask); | 1840 | cpu_set(cpu, smp_commenced_mask); |
1841 | while (!cpu_isset(cpu, cpu_online_map)) | 1841 | while (!cpu_online(cpu)) |
1842 | mb(); | 1842 | mb(); |
1843 | return 0; | 1843 | return 0; |
1844 | } | 1844 | } |
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index baf7c4f643c8..4a4761892951 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c | |||
@@ -566,9 +566,9 @@ void __init paging_init(void) | |||
566 | 566 | ||
567 | /* | 567 | /* |
568 | * Test if the WP bit works in supervisor mode. It isn't supported on 386's | 568 | * Test if the WP bit works in supervisor mode. It isn't supported on 386's |
569 | * and also on some strange 486's (NexGen etc.). All 586+'s are OK. This | 569 | * and also on some strange 486's. All 586+'s are OK. This used to involve |
570 | * used to involve black magic jumps to work around some nasty CPU bugs, | 570 | * black magic jumps to work around some nasty CPU bugs, but fortunately the |
571 | * but fortunately the switch to using exceptions got rid of all that. | 571 | * switch to using exceptions got rid of all that. |
572 | */ | 572 | */ |
573 | static void __init test_wp_bit(void) | 573 | static void __init test_wp_bit(void) |
574 | { | 574 | { |
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 92dd3dbf3ffb..94e69000f982 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c | |||
@@ -193,7 +193,7 @@ void __init xen_smp_prepare_cpus(unsigned int max_cpus) | |||
193 | 193 | ||
194 | /* Restrict the possible_map according to max_cpus. */ | 194 | /* Restrict the possible_map according to max_cpus. */ |
195 | while ((num_possible_cpus() > 1) && (num_possible_cpus() > max_cpus)) { | 195 | while ((num_possible_cpus() > 1) && (num_possible_cpus() > max_cpus)) { |
196 | for (cpu = NR_CPUS-1; !cpu_isset(cpu, cpu_possible_map); cpu--) | 196 | for (cpu = NR_CPUS - 1; !cpu_possible(cpu); cpu--) |
197 | continue; | 197 | continue; |
198 | cpu_clear(cpu, cpu_possible_map); | 198 | cpu_clear(cpu, cpu_possible_map); |
199 | } | 199 | } |
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index d28669992147..96bdb9296b07 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c | |||
@@ -436,8 +436,9 @@ static int __devinit agp_amdk7_probe(struct pci_dev *pdev, | |||
436 | system controller may experience noise due to strong drive strengths | 436 | system controller may experience noise due to strong drive strengths |
437 | */ | 437 | */ |
438 | if (agp_bridge->dev->device == PCI_DEVICE_ID_AMD_FE_GATE_7006) { | 438 | if (agp_bridge->dev->device == PCI_DEVICE_ID_AMD_FE_GATE_7006) { |
439 | u8 cap_ptr=0; | ||
440 | struct pci_dev *gfxcard=NULL; | 439 | struct pci_dev *gfxcard=NULL; |
440 | |||
441 | cap_ptr = 0; | ||
441 | while (!cap_ptr) { | 442 | while (!cap_ptr) { |
442 | gfxcard = pci_get_class(PCI_CLASS_DISPLAY_VGA<<8, gfxcard); | 443 | gfxcard = pci_get_class(PCI_CLASS_DISPLAY_VGA<<8, gfxcard); |
443 | if (!gfxcard) { | 444 | if (!gfxcard) { |
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c index 55d7a82bd071..857b26227d87 100644 --- a/drivers/char/agp/frontend.c +++ b/drivers/char/agp/frontend.c | |||
@@ -967,7 +967,7 @@ int agpioc_chipset_flush_wrap(struct agp_file_private *priv) | |||
967 | return 0; | 967 | return 0; |
968 | } | 968 | } |
969 | 969 | ||
970 | static int agp_ioctl(struct inode *inode, struct file *file, | 970 | static long agp_ioctl(struct file *file, |
971 | unsigned int cmd, unsigned long arg) | 971 | unsigned int cmd, unsigned long arg) |
972 | { | 972 | { |
973 | struct agp_file_private *curr_priv = file->private_data; | 973 | struct agp_file_private *curr_priv = file->private_data; |
@@ -1058,7 +1058,7 @@ static const struct file_operations agp_fops = | |||
1058 | .llseek = no_llseek, | 1058 | .llseek = no_llseek, |
1059 | .read = agp_read, | 1059 | .read = agp_read, |
1060 | .write = agp_write, | 1060 | .write = agp_write, |
1061 | .ioctl = agp_ioctl, | 1061 | .unlocked_ioctl = agp_ioctl, |
1062 | #ifdef CONFIG_COMPAT | 1062 | #ifdef CONFIG_COMPAT |
1063 | .compat_ioctl = compat_agp_ioctl, | 1063 | .compat_ioctl = compat_agp_ioctl, |
1064 | #endif | 1064 | #endif |
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c index 141f4dfa0a11..b710426bab3e 100644 --- a/drivers/char/drm/ati_pcigart.c +++ b/drivers/char/drm/ati_pcigart.c | |||
@@ -167,13 +167,6 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga | |||
167 | page_base += ATI_PCIGART_PAGE_SIZE; | 167 | page_base += ATI_PCIGART_PAGE_SIZE; |
168 | } | 168 | } |
169 | } | 169 | } |
170 | |||
171 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) | ||
172 | dma_sync_single_for_device(&dev->pdev->dev, | ||
173 | bus_address, | ||
174 | max_pages * sizeof(u32), | ||
175 | PCI_DMA_TODEVICE); | ||
176 | |||
177 | ret = 1; | 170 | ret = 1; |
178 | 171 | ||
179 | #if defined(__i386__) || defined(__x86_64__) | 172 | #if defined(__i386__) || defined(__x86_64__) |
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h index 3a05c6d5ebe1..6874f31ca8ca 100644 --- a/drivers/char/drm/drm.h +++ b/drivers/char/drm/drm.h | |||
@@ -471,6 +471,7 @@ struct drm_irq_busid { | |||
471 | enum drm_vblank_seq_type { | 471 | enum drm_vblank_seq_type { |
472 | _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ | 472 | _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ |
473 | _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ | 473 | _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ |
474 | _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ | ||
474 | _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ | 475 | _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ |
475 | _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ | 476 | _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ |
476 | _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ | 477 | _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ |
@@ -503,6 +504,21 @@ union drm_wait_vblank { | |||
503 | struct drm_wait_vblank_reply reply; | 504 | struct drm_wait_vblank_reply reply; |
504 | }; | 505 | }; |
505 | 506 | ||
507 | enum drm_modeset_ctl_cmd { | ||
508 | _DRM_PRE_MODESET = 1, | ||
509 | _DRM_POST_MODESET = 2, | ||
510 | }; | ||
511 | |||
512 | /** | ||
513 | * DRM_IOCTL_MODESET_CTL ioctl argument type | ||
514 | * | ||
515 | * \sa drmModesetCtl(). | ||
516 | */ | ||
517 | struct drm_modeset_ctl { | ||
518 | unsigned long arg; | ||
519 | enum drm_modeset_ctl_cmd cmd; | ||
520 | }; | ||
521 | |||
506 | /** | 522 | /** |
507 | * DRM_IOCTL_AGP_ENABLE ioctl argument type. | 523 | * DRM_IOCTL_AGP_ENABLE ioctl argument type. |
508 | * | 524 | * |
@@ -587,6 +603,7 @@ struct drm_set_version { | |||
587 | #define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client) | 603 | #define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client) |
588 | #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats) | 604 | #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats) |
589 | #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version) | 605 | #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version) |
606 | #define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl) | ||
590 | 607 | ||
591 | #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) | 608 | #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) |
592 | #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) | 609 | #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) |
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 6540948d5176..ecee3547a13f 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -100,10 +100,8 @@ struct drm_device; | |||
100 | #define DRIVER_HAVE_DMA 0x20 | 100 | #define DRIVER_HAVE_DMA 0x20 |
101 | #define DRIVER_HAVE_IRQ 0x40 | 101 | #define DRIVER_HAVE_IRQ 0x40 |
102 | #define DRIVER_IRQ_SHARED 0x80 | 102 | #define DRIVER_IRQ_SHARED 0x80 |
103 | #define DRIVER_IRQ_VBL 0x100 | ||
104 | #define DRIVER_DMA_QUEUE 0x200 | 103 | #define DRIVER_DMA_QUEUE 0x200 |
105 | #define DRIVER_FB_DMA 0x400 | 104 | #define DRIVER_FB_DMA 0x400 |
106 | #define DRIVER_IRQ_VBL2 0x800 | ||
107 | 105 | ||
108 | /***********************************************************************/ | 106 | /***********************************************************************/ |
109 | /** \name Begin the DRM... */ | 107 | /** \name Begin the DRM... */ |
@@ -379,13 +377,12 @@ struct drm_buf_entry { | |||
379 | struct drm_file { | 377 | struct drm_file { |
380 | int authenticated; | 378 | int authenticated; |
381 | int master; | 379 | int master; |
382 | int minor; | ||
383 | pid_t pid; | 380 | pid_t pid; |
384 | uid_t uid; | 381 | uid_t uid; |
385 | drm_magic_t magic; | 382 | drm_magic_t magic; |
386 | unsigned long ioctl_count; | 383 | unsigned long ioctl_count; |
387 | struct list_head lhead; | 384 | struct list_head lhead; |
388 | struct drm_head *head; | 385 | struct drm_minor *minor; |
389 | int remove_auth_on_close; | 386 | int remove_auth_on_close; |
390 | unsigned long lock_count; | 387 | unsigned long lock_count; |
391 | struct file *filp; | 388 | struct file *filp; |
@@ -580,10 +577,52 @@ struct drm_driver { | |||
580 | int (*context_dtor) (struct drm_device *dev, int context); | 577 | int (*context_dtor) (struct drm_device *dev, int context); |
581 | int (*kernel_context_switch) (struct drm_device *dev, int old, | 578 | int (*kernel_context_switch) (struct drm_device *dev, int old, |
582 | int new); | 579 | int new); |
583 | void (*kernel_context_switch_unlock) (struct drm_device *dev); | 580 | void (*kernel_context_switch_unlock) (struct drm_device * dev); |
584 | int (*vblank_wait) (struct drm_device *dev, unsigned int *sequence); | 581 | /** |
585 | int (*vblank_wait2) (struct drm_device *dev, unsigned int *sequence); | 582 | * get_vblank_counter - get raw hardware vblank counter |
586 | int (*dri_library_name) (struct drm_device *dev, char *buf); | 583 | * @dev: DRM device |
584 | * @crtc: counter to fetch | ||
585 | * | ||
586 | * Driver callback for fetching a raw hardware vblank counter | ||
587 | * for @crtc. If a device doesn't have a hardware counter, the | ||
588 | * driver can simply return the value of drm_vblank_count and | ||
589 | * make the enable_vblank() and disable_vblank() hooks into no-ops, | ||
590 | * leaving interrupts enabled at all times. | ||
591 | * | ||
592 | * Wraparound handling and loss of events due to modesetting is dealt | ||
593 | * with in the DRM core code. | ||
594 | * | ||
595 | * RETURNS | ||
596 | * Raw vblank counter value. | ||
597 | */ | ||
598 | u32 (*get_vblank_counter) (struct drm_device *dev, int crtc); | ||
599 | |||
600 | /** | ||
601 | * enable_vblank - enable vblank interrupt events | ||
602 | * @dev: DRM device | ||
603 | * @crtc: which irq to enable | ||
604 | * | ||
605 | * Enable vblank interrupts for @crtc. If the device doesn't have | ||
606 | * a hardware vblank counter, this routine should be a no-op, since | ||
607 | * interrupts will have to stay on to keep the count accurate. | ||
608 | * | ||
609 | * RETURNS | ||
610 | * Zero on success, appropriate errno if the given @crtc's vblank | ||
611 | * interrupt cannot be enabled. | ||
612 | */ | ||
613 | int (*enable_vblank) (struct drm_device *dev, int crtc); | ||
614 | |||
615 | /** | ||
616 | * disable_vblank - disable vblank interrupt events | ||
617 | * @dev: DRM device | ||
618 | * @crtc: which irq to enable | ||
619 | * | ||
620 | * Disable vblank interrupts for @crtc. If the device doesn't have | ||
621 | * a hardware vblank counter, this routine should be a no-op, since | ||
622 | * interrupts will have to stay on to keep the count accurate. | ||
623 | */ | ||
624 | void (*disable_vblank) (struct drm_device *dev, int crtc); | ||
625 | int (*dri_library_name) (struct drm_device *dev, char * buf); | ||
587 | 626 | ||
588 | /** | 627 | /** |
589 | * Called by \c drm_device_is_agp. Typically used to determine if a | 628 | * Called by \c drm_device_is_agp. Typically used to determine if a |
@@ -602,7 +641,7 @@ struct drm_driver { | |||
602 | 641 | ||
603 | irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); | 642 | irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); |
604 | void (*irq_preinstall) (struct drm_device *dev); | 643 | void (*irq_preinstall) (struct drm_device *dev); |
605 | void (*irq_postinstall) (struct drm_device *dev); | 644 | int (*irq_postinstall) (struct drm_device *dev); |
606 | void (*irq_uninstall) (struct drm_device *dev); | 645 | void (*irq_uninstall) (struct drm_device *dev); |
607 | void (*reclaim_buffers) (struct drm_device *dev, | 646 | void (*reclaim_buffers) (struct drm_device *dev, |
608 | struct drm_file * file_priv); | 647 | struct drm_file * file_priv); |
@@ -630,16 +669,19 @@ struct drm_driver { | |||
630 | struct pci_driver pci_driver; | 669 | struct pci_driver pci_driver; |
631 | }; | 670 | }; |
632 | 671 | ||
672 | #define DRM_MINOR_UNASSIGNED 0 | ||
673 | #define DRM_MINOR_LEGACY 1 | ||
674 | |||
633 | /** | 675 | /** |
634 | * DRM head structure. This structure represent a video head on a card | 676 | * DRM minor structure. This structure represents a drm minor number. |
635 | * that may contain multiple heads. Embed one per head of these in the | ||
636 | * private drm_device structure. | ||
637 | */ | 677 | */ |
638 | struct drm_head { | 678 | struct drm_minor { |
639 | int minor; /**< Minor device number */ | 679 | int index; /**< Minor device number */ |
680 | int type; /**< Control or render */ | ||
681 | dev_t device; /**< Device number for mknod */ | ||
682 | struct device kdev; /**< Linux device */ | ||
640 | struct drm_device *dev; | 683 | struct drm_device *dev; |
641 | struct proc_dir_entry *dev_root; /**< proc directory entry */ | 684 | struct proc_dir_entry *dev_root; /**< proc directory entry */ |
642 | dev_t device; /**< Device number for mknod */ | ||
643 | }; | 685 | }; |
644 | 686 | ||
645 | /** | 687 | /** |
@@ -647,7 +689,6 @@ struct drm_head { | |||
647 | * may contain multiple heads. | 689 | * may contain multiple heads. |
648 | */ | 690 | */ |
649 | struct drm_device { | 691 | struct drm_device { |
650 | struct device dev; /**< Linux device */ | ||
651 | char *unique; /**< Unique identifier: e.g., busid */ | 692 | char *unique; /**< Unique identifier: e.g., busid */ |
652 | int unique_len; /**< Length of unique field */ | 693 | int unique_len; /**< Length of unique field */ |
653 | char *devname; /**< For /proc/interrupts */ | 694 | char *devname; /**< For /proc/interrupts */ |
@@ -729,13 +770,21 @@ struct drm_device { | |||
729 | /** \name VBLANK IRQ support */ | 770 | /** \name VBLANK IRQ support */ |
730 | /*@{ */ | 771 | /*@{ */ |
731 | 772 | ||
732 | wait_queue_head_t vbl_queue; /**< VBLANK wait queue */ | 773 | wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */ |
733 | atomic_t vbl_received; | 774 | atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */ |
734 | atomic_t vbl_received2; /**< number of secondary VBLANK interrupts */ | ||
735 | spinlock_t vbl_lock; | 775 | spinlock_t vbl_lock; |
736 | struct list_head vbl_sigs; /**< signal list to send on VBLANK */ | 776 | struct list_head *vbl_sigs; /**< signal list to send on VBLANK */ |
737 | struct list_head vbl_sigs2; /**< signals to send on secondary VBLANK */ | 777 | atomic_t vbl_signal_pending; /* number of signals pending on all crtcs*/ |
738 | unsigned int vbl_pending; | 778 | atomic_t *vblank_refcount; /* number of users of vblank interrupts per crtc */ |
779 | u32 *last_vblank; /* protected by dev->vbl_lock, used */ | ||
780 | /* for wraparound handling */ | ||
781 | u32 *vblank_offset; /* used to track how many vblanks */ | ||
782 | int *vblank_enabled; /* so we don't call enable more than | ||
783 | once per disable */ | ||
784 | u32 *vblank_premodeset; /* were lost during modeset */ | ||
785 | struct timer_list vblank_disable_timer; | ||
786 | |||
787 | unsigned long max_vblank_count; /**< size of vblank counter register */ | ||
739 | spinlock_t tasklet_lock; /**< For drm_locked_tasklet */ | 788 | spinlock_t tasklet_lock; /**< For drm_locked_tasklet */ |
740 | void (*locked_tasklet_func)(struct drm_device *dev); | 789 | void (*locked_tasklet_func)(struct drm_device *dev); |
741 | 790 | ||
@@ -755,6 +804,7 @@ struct drm_device { | |||
755 | #ifdef __alpha__ | 804 | #ifdef __alpha__ |
756 | struct pci_controller *hose; | 805 | struct pci_controller *hose; |
757 | #endif | 806 | #endif |
807 | int num_crtcs; /**< Number of CRTCs on this device */ | ||
758 | struct drm_sg_mem *sg; /**< Scatter gather memory */ | 808 | struct drm_sg_mem *sg; /**< Scatter gather memory */ |
759 | void *dev_private; /**< device private data */ | 809 | void *dev_private; /**< device private data */ |
760 | struct drm_sigdata sigdata; /**< For block_all_signals */ | 810 | struct drm_sigdata sigdata; /**< For block_all_signals */ |
@@ -763,7 +813,7 @@ struct drm_device { | |||
763 | struct drm_driver *driver; | 813 | struct drm_driver *driver; |
764 | drm_local_map_t *agp_buffer_map; | 814 | drm_local_map_t *agp_buffer_map; |
765 | unsigned int agp_buffer_token; | 815 | unsigned int agp_buffer_token; |
766 | struct drm_head primary; /**< primary screen head */ | 816 | struct drm_minor *primary; /**< render type primary screen head */ |
767 | 817 | ||
768 | /** \name Drawable information */ | 818 | /** \name Drawable information */ |
769 | /*@{ */ | 819 | /*@{ */ |
@@ -989,11 +1039,19 @@ extern void drm_driver_irq_preinstall(struct drm_device *dev); | |||
989 | extern void drm_driver_irq_postinstall(struct drm_device *dev); | 1039 | extern void drm_driver_irq_postinstall(struct drm_device *dev); |
990 | extern void drm_driver_irq_uninstall(struct drm_device *dev); | 1040 | extern void drm_driver_irq_uninstall(struct drm_device *dev); |
991 | 1041 | ||
992 | extern int drm_wait_vblank(struct drm_device *dev, void *data, | 1042 | extern int drm_vblank_init(struct drm_device *dev, int num_crtcs); |
993 | struct drm_file *file_priv); | 1043 | extern int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *filp); |
994 | extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq); | 1044 | extern int drm_vblank_wait(struct drm_device * dev, unsigned int *vbl_seq); |
995 | extern void drm_vbl_send_signals(struct drm_device *dev); | ||
996 | extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*)); | 1045 | extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*)); |
1046 | extern u32 drm_vblank_count(struct drm_device *dev, int crtc); | ||
1047 | extern void drm_update_vblank_count(struct drm_device *dev, int crtc); | ||
1048 | extern void drm_handle_vblank(struct drm_device *dev, int crtc); | ||
1049 | extern int drm_vblank_get(struct drm_device *dev, int crtc); | ||
1050 | extern void drm_vblank_put(struct drm_device *dev, int crtc); | ||
1051 | |||
1052 | /* Modesetting support */ | ||
1053 | extern int drm_modeset_ctl(struct drm_device *dev, void *data, | ||
1054 | struct drm_file *file_priv); | ||
997 | 1055 | ||
998 | /* AGP/GART support (drm_agpsupport.h) */ | 1056 | /* AGP/GART support (drm_agpsupport.h) */ |
999 | extern struct drm_agp_head *drm_agp_init(struct drm_device *dev); | 1057 | extern struct drm_agp_head *drm_agp_init(struct drm_device *dev); |
@@ -1030,23 +1088,20 @@ extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle); | |||
1030 | extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | 1088 | extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, |
1031 | struct drm_driver *driver); | 1089 | struct drm_driver *driver); |
1032 | extern int drm_put_dev(struct drm_device *dev); | 1090 | extern int drm_put_dev(struct drm_device *dev); |
1033 | extern int drm_put_head(struct drm_head *head); | 1091 | extern int drm_put_minor(struct drm_minor **minor); |
1034 | extern unsigned int drm_debug; | 1092 | extern unsigned int drm_debug; |
1035 | extern unsigned int drm_cards_limit; | 1093 | |
1036 | extern struct drm_head **drm_heads; | ||
1037 | extern struct class *drm_class; | 1094 | extern struct class *drm_class; |
1038 | extern struct proc_dir_entry *drm_proc_root; | 1095 | extern struct proc_dir_entry *drm_proc_root; |
1039 | 1096 | ||
1097 | extern struct idr drm_minors_idr; | ||
1098 | |||
1040 | extern drm_local_map_t *drm_getsarea(struct drm_device *dev); | 1099 | extern drm_local_map_t *drm_getsarea(struct drm_device *dev); |
1041 | 1100 | ||
1042 | /* Proc support (drm_proc.h) */ | 1101 | /* Proc support (drm_proc.h) */ |
1043 | extern int drm_proc_init(struct drm_device *dev, | 1102 | extern int drm_proc_init(struct drm_minor *minor, int minor_id, |
1044 | int minor, | 1103 | struct proc_dir_entry *root); |
1045 | struct proc_dir_entry *root, | 1104 | extern int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root); |
1046 | struct proc_dir_entry **dev_root); | ||
1047 | extern int drm_proc_cleanup(int minor, | ||
1048 | struct proc_dir_entry *root, | ||
1049 | struct proc_dir_entry *dev_root); | ||
1050 | 1105 | ||
1051 | /* Scatter Gather Support (drm_scatter.h) */ | 1106 | /* Scatter Gather Support (drm_scatter.h) */ |
1052 | extern void drm_sg_cleanup(struct drm_sg_mem * entry); | 1107 | extern void drm_sg_cleanup(struct drm_sg_mem * entry); |
@@ -1071,8 +1126,8 @@ extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah); | |||
1071 | struct drm_sysfs_class; | 1126 | struct drm_sysfs_class; |
1072 | extern struct class *drm_sysfs_create(struct module *owner, char *name); | 1127 | extern struct class *drm_sysfs_create(struct module *owner, char *name); |
1073 | extern void drm_sysfs_destroy(void); | 1128 | extern void drm_sysfs_destroy(void); |
1074 | extern int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head); | 1129 | extern int drm_sysfs_device_add(struct drm_minor *minor); |
1075 | extern void drm_sysfs_device_remove(struct drm_device *dev); | 1130 | extern void drm_sysfs_device_remove(struct drm_minor *minor); |
1076 | 1131 | ||
1077 | /* | 1132 | /* |
1078 | * Basic memory manager support (drm_mm.c) | 1133 | * Basic memory manager support (drm_mm.c) |
diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c index 9468c7889ff1..aefa5ac4c0b1 100644 --- a/drivers/char/drm/drm_agpsupport.c +++ b/drivers/char/drm/drm_agpsupport.c | |||
@@ -122,7 +122,7 @@ EXPORT_SYMBOL(drm_agp_acquire); | |||
122 | int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, | 122 | int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, |
123 | struct drm_file *file_priv) | 123 | struct drm_file *file_priv) |
124 | { | 124 | { |
125 | return drm_agp_acquire((struct drm_device *) file_priv->head->dev); | 125 | return drm_agp_acquire((struct drm_device *) file_priv->minor->dev); |
126 | } | 126 | } |
127 | 127 | ||
128 | /** | 128 | /** |
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c index 0e7af53c87de..fc54140551a7 100644 --- a/drivers/char/drm/drm_drv.c +++ b/drivers/char/drm/drm_drv.c | |||
@@ -313,35 +313,36 @@ static void drm_cleanup(struct drm_device * dev) | |||
313 | drm_ht_remove(&dev->map_hash); | 313 | drm_ht_remove(&dev->map_hash); |
314 | drm_ctxbitmap_cleanup(dev); | 314 | drm_ctxbitmap_cleanup(dev); |
315 | 315 | ||
316 | drm_put_head(&dev->primary); | 316 | drm_put_minor(&dev->primary); |
317 | if (drm_put_dev(dev)) | 317 | if (drm_put_dev(dev)) |
318 | DRM_ERROR("Cannot unload module\n"); | 318 | DRM_ERROR("Cannot unload module\n"); |
319 | } | 319 | } |
320 | 320 | ||
321 | void drm_exit(struct drm_driver *driver) | 321 | int drm_minors_cleanup(int id, void *ptr, void *data) |
322 | { | 322 | { |
323 | int i; | 323 | struct drm_minor *minor = ptr; |
324 | struct drm_device *dev = NULL; | 324 | struct drm_device *dev; |
325 | struct drm_head *head; | 325 | struct drm_driver *driver = data; |
326 | |||
327 | dev = minor->dev; | ||
328 | if (minor->dev->driver != driver) | ||
329 | return 0; | ||
330 | |||
331 | if (minor->type != DRM_MINOR_LEGACY) | ||
332 | return 0; | ||
326 | 333 | ||
334 | if (dev) | ||
335 | pci_dev_put(dev->pdev); | ||
336 | drm_cleanup(dev); | ||
337 | return 1; | ||
338 | } | ||
339 | |||
340 | void drm_exit(struct drm_driver *driver) | ||
341 | { | ||
327 | DRM_DEBUG("\n"); | 342 | DRM_DEBUG("\n"); |
328 | 343 | ||
329 | for (i = 0; i < drm_cards_limit; i++) { | 344 | idr_for_each(&drm_minors_idr, &drm_minors_cleanup, driver); |
330 | head = drm_heads[i]; | 345 | |
331 | if (!head) | ||
332 | continue; | ||
333 | if (!head->dev) | ||
334 | continue; | ||
335 | if (head->dev->driver != driver) | ||
336 | continue; | ||
337 | dev = head->dev; | ||
338 | if (dev) { | ||
339 | /* release the pci driver */ | ||
340 | if (dev->pdev) | ||
341 | pci_dev_put(dev->pdev); | ||
342 | drm_cleanup(dev); | ||
343 | } | ||
344 | } | ||
345 | DRM_INFO("Module unloaded\n"); | 346 | DRM_INFO("Module unloaded\n"); |
346 | } | 347 | } |
347 | 348 | ||
@@ -357,13 +358,7 @@ static int __init drm_core_init(void) | |||
357 | { | 358 | { |
358 | int ret = -ENOMEM; | 359 | int ret = -ENOMEM; |
359 | 360 | ||
360 | drm_cards_limit = | 361 | idr_init(&drm_minors_idr); |
361 | (drm_cards_limit < | ||
362 | DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1); | ||
363 | drm_heads = | ||
364 | drm_calloc(drm_cards_limit, sizeof(*drm_heads), DRM_MEM_STUB); | ||
365 | if (!drm_heads) | ||
366 | goto err_p1; | ||
367 | 362 | ||
368 | if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) | 363 | if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) |
369 | goto err_p1; | 364 | goto err_p1; |
@@ -391,7 +386,8 @@ err_p3: | |||
391 | drm_sysfs_destroy(); | 386 | drm_sysfs_destroy(); |
392 | err_p2: | 387 | err_p2: |
393 | unregister_chrdev(DRM_MAJOR, "drm"); | 388 | unregister_chrdev(DRM_MAJOR, "drm"); |
394 | drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB); | 389 | |
390 | idr_destroy(&drm_minors_idr); | ||
395 | err_p1: | 391 | err_p1: |
396 | return ret; | 392 | return ret; |
397 | } | 393 | } |
@@ -403,7 +399,7 @@ static void __exit drm_core_exit(void) | |||
403 | 399 | ||
404 | unregister_chrdev(DRM_MAJOR, "drm"); | 400 | unregister_chrdev(DRM_MAJOR, "drm"); |
405 | 401 | ||
406 | drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB); | 402 | idr_destroy(&drm_minors_idr); |
407 | } | 403 | } |
408 | 404 | ||
409 | module_init(drm_core_init); | 405 | module_init(drm_core_init); |
@@ -452,7 +448,7 @@ int drm_ioctl(struct inode *inode, struct file *filp, | |||
452 | unsigned int cmd, unsigned long arg) | 448 | unsigned int cmd, unsigned long arg) |
453 | { | 449 | { |
454 | struct drm_file *file_priv = filp->private_data; | 450 | struct drm_file *file_priv = filp->private_data; |
455 | struct drm_device *dev = file_priv->head->dev; | 451 | struct drm_device *dev = file_priv->minor->dev; |
456 | struct drm_ioctl_desc *ioctl; | 452 | struct drm_ioctl_desc *ioctl; |
457 | drm_ioctl_t *func; | 453 | drm_ioctl_t *func; |
458 | unsigned int nr = DRM_IOCTL_NR(cmd); | 454 | unsigned int nr = DRM_IOCTL_NR(cmd); |
@@ -465,7 +461,7 @@ int drm_ioctl(struct inode *inode, struct file *filp, | |||
465 | 461 | ||
466 | DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", | 462 | DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", |
467 | task_pid_nr(current), cmd, nr, | 463 | task_pid_nr(current), cmd, nr, |
468 | (long)old_encode_dev(file_priv->head->device), | 464 | (long)old_encode_dev(file_priv->minor->device), |
469 | file_priv->authenticated); | 465 | file_priv->authenticated); |
470 | 466 | ||
471 | if ((nr >= DRM_CORE_IOCTL_COUNT) && | 467 | if ((nr >= DRM_CORE_IOCTL_COUNT) && |
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c index f09d4b5002b0..68f0da801ed8 100644 --- a/drivers/char/drm/drm_fops.c +++ b/drivers/char/drm/drm_fops.c | |||
@@ -129,16 +129,15 @@ static int drm_setup(struct drm_device * dev) | |||
129 | int drm_open(struct inode *inode, struct file *filp) | 129 | int drm_open(struct inode *inode, struct file *filp) |
130 | { | 130 | { |
131 | struct drm_device *dev = NULL; | 131 | struct drm_device *dev = NULL; |
132 | int minor = iminor(inode); | 132 | int minor_id = iminor(inode); |
133 | struct drm_minor *minor; | ||
133 | int retcode = 0; | 134 | int retcode = 0; |
134 | 135 | ||
135 | if (!((minor >= 0) && (minor < drm_cards_limit))) | 136 | minor = idr_find(&drm_minors_idr, minor_id); |
137 | if (!minor) | ||
136 | return -ENODEV; | 138 | return -ENODEV; |
137 | 139 | ||
138 | if (!drm_heads[minor]) | 140 | if (!(dev = minor->dev)) |
139 | return -ENODEV; | ||
140 | |||
141 | if (!(dev = drm_heads[minor]->dev)) | ||
142 | return -ENODEV; | 141 | return -ENODEV; |
143 | 142 | ||
144 | retcode = drm_open_helper(inode, filp, dev); | 143 | retcode = drm_open_helper(inode, filp, dev); |
@@ -168,19 +167,18 @@ EXPORT_SYMBOL(drm_open); | |||
168 | int drm_stub_open(struct inode *inode, struct file *filp) | 167 | int drm_stub_open(struct inode *inode, struct file *filp) |
169 | { | 168 | { |
170 | struct drm_device *dev = NULL; | 169 | struct drm_device *dev = NULL; |
171 | int minor = iminor(inode); | 170 | struct drm_minor *minor; |
171 | int minor_id = iminor(inode); | ||
172 | int err = -ENODEV; | 172 | int err = -ENODEV; |
173 | const struct file_operations *old_fops; | 173 | const struct file_operations *old_fops; |
174 | 174 | ||
175 | DRM_DEBUG("\n"); | 175 | DRM_DEBUG("\n"); |
176 | 176 | ||
177 | if (!((minor >= 0) && (minor < drm_cards_limit))) | 177 | minor = idr_find(&drm_minors_idr, minor_id); |
178 | return -ENODEV; | 178 | if (!minor) |
179 | |||
180 | if (!drm_heads[minor]) | ||
181 | return -ENODEV; | 179 | return -ENODEV; |
182 | 180 | ||
183 | if (!(dev = drm_heads[minor]->dev)) | 181 | if (!(dev = minor->dev)) |
184 | return -ENODEV; | 182 | return -ENODEV; |
185 | 183 | ||
186 | old_fops = filp->f_op; | 184 | old_fops = filp->f_op; |
@@ -225,7 +223,7 @@ static int drm_cpu_valid(void) | |||
225 | static int drm_open_helper(struct inode *inode, struct file *filp, | 223 | static int drm_open_helper(struct inode *inode, struct file *filp, |
226 | struct drm_device * dev) | 224 | struct drm_device * dev) |
227 | { | 225 | { |
228 | int minor = iminor(inode); | 226 | int minor_id = iminor(inode); |
229 | struct drm_file *priv; | 227 | struct drm_file *priv; |
230 | int ret; | 228 | int ret; |
231 | 229 | ||
@@ -234,7 +232,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
234 | if (!drm_cpu_valid()) | 232 | if (!drm_cpu_valid()) |
235 | return -EINVAL; | 233 | return -EINVAL; |
236 | 234 | ||
237 | DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor); | 235 | DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor_id); |
238 | 236 | ||
239 | priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES); | 237 | priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES); |
240 | if (!priv) | 238 | if (!priv) |
@@ -245,8 +243,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
245 | priv->filp = filp; | 243 | priv->filp = filp; |
246 | priv->uid = current->euid; | 244 | priv->uid = current->euid; |
247 | priv->pid = task_pid_nr(current); | 245 | priv->pid = task_pid_nr(current); |
248 | priv->minor = minor; | 246 | priv->minor = idr_find(&drm_minors_idr, minor_id); |
249 | priv->head = drm_heads[minor]; | ||
250 | priv->ioctl_count = 0; | 247 | priv->ioctl_count = 0; |
251 | /* for compatibility root is always authenticated */ | 248 | /* for compatibility root is always authenticated */ |
252 | priv->authenticated = capable(CAP_SYS_ADMIN); | 249 | priv->authenticated = capable(CAP_SYS_ADMIN); |
@@ -297,11 +294,11 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
297 | int drm_fasync(int fd, struct file *filp, int on) | 294 | int drm_fasync(int fd, struct file *filp, int on) |
298 | { | 295 | { |
299 | struct drm_file *priv = filp->private_data; | 296 | struct drm_file *priv = filp->private_data; |
300 | struct drm_device *dev = priv->head->dev; | 297 | struct drm_device *dev = priv->minor->dev; |
301 | int retcode; | 298 | int retcode; |
302 | 299 | ||
303 | DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, | 300 | DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, |
304 | (long)old_encode_dev(priv->head->device)); | 301 | (long)old_encode_dev(priv->minor->device)); |
305 | retcode = fasync_helper(fd, filp, on, &dev->buf_async); | 302 | retcode = fasync_helper(fd, filp, on, &dev->buf_async); |
306 | if (retcode < 0) | 303 | if (retcode < 0) |
307 | return retcode; | 304 | return retcode; |
@@ -324,7 +321,7 @@ EXPORT_SYMBOL(drm_fasync); | |||
324 | int drm_release(struct inode *inode, struct file *filp) | 321 | int drm_release(struct inode *inode, struct file *filp) |
325 | { | 322 | { |
326 | struct drm_file *file_priv = filp->private_data; | 323 | struct drm_file *file_priv = filp->private_data; |
327 | struct drm_device *dev = file_priv->head->dev; | 324 | struct drm_device *dev = file_priv->minor->dev; |
328 | int retcode = 0; | 325 | int retcode = 0; |
329 | unsigned long irqflags; | 326 | unsigned long irqflags; |
330 | 327 | ||
@@ -341,14 +338,14 @@ int drm_release(struct inode *inode, struct file *filp) | |||
341 | 338 | ||
342 | DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", | 339 | DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", |
343 | task_pid_nr(current), | 340 | task_pid_nr(current), |
344 | (long)old_encode_dev(file_priv->head->device), | 341 | (long)old_encode_dev(file_priv->minor->device), |
345 | dev->open_count); | 342 | dev->open_count); |
346 | 343 | ||
347 | if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) { | 344 | if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) { |
348 | if (drm_i_have_hw_lock(dev, file_priv)) { | 345 | if (drm_i_have_hw_lock(dev, file_priv)) { |
349 | dev->driver->reclaim_buffers_locked(dev, file_priv); | 346 | dev->driver->reclaim_buffers_locked(dev, file_priv); |
350 | } else { | 347 | } else { |
351 | unsigned long _end=jiffies + 3*DRM_HZ; | 348 | unsigned long endtime = jiffies + 3 * DRM_HZ; |
352 | int locked = 0; | 349 | int locked = 0; |
353 | 350 | ||
354 | drm_idlelock_take(&dev->lock); | 351 | drm_idlelock_take(&dev->lock); |
@@ -366,7 +363,7 @@ int drm_release(struct inode *inode, struct file *filp) | |||
366 | if (locked) | 363 | if (locked) |
367 | break; | 364 | break; |
368 | schedule(); | 365 | schedule(); |
369 | } while (!time_after_eq(jiffies, _end)); | 366 | } while (!time_after_eq(jiffies, endtime)); |
370 | 367 | ||
371 | if (!locked) { | 368 | if (!locked) { |
372 | DRM_ERROR("reclaim_buffers_locked() deadlock. Please rework this\n" | 369 | DRM_ERROR("reclaim_buffers_locked() deadlock. Please rework this\n" |
diff --git a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c index 089c015c01d1..286f9d61e7d5 100644 --- a/drivers/char/drm/drm_irq.c +++ b/drivers/char/drm/drm_irq.c | |||
@@ -71,6 +71,117 @@ int drm_irq_by_busid(struct drm_device *dev, void *data, | |||
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
73 | 73 | ||
74 | static void vblank_disable_fn(unsigned long arg) | ||
75 | { | ||
76 | struct drm_device *dev = (struct drm_device *)arg; | ||
77 | unsigned long irqflags; | ||
78 | int i; | ||
79 | |||
80 | for (i = 0; i < dev->num_crtcs; i++) { | ||
81 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | ||
82 | if (atomic_read(&dev->vblank_refcount[i]) == 0 && | ||
83 | dev->vblank_enabled[i]) { | ||
84 | dev->driver->disable_vblank(dev, i); | ||
85 | dev->vblank_enabled[i] = 0; | ||
86 | } | ||
87 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | static void drm_vblank_cleanup(struct drm_device *dev) | ||
92 | { | ||
93 | /* Bail if the driver didn't call drm_vblank_init() */ | ||
94 | if (dev->num_crtcs == 0) | ||
95 | return; | ||
96 | |||
97 | del_timer(&dev->vblank_disable_timer); | ||
98 | |||
99 | vblank_disable_fn((unsigned long)dev); | ||
100 | |||
101 | drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs, | ||
102 | DRM_MEM_DRIVER); | ||
103 | drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs, | ||
104 | DRM_MEM_DRIVER); | ||
105 | drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) * | ||
106 | dev->num_crtcs, DRM_MEM_DRIVER); | ||
107 | drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) * | ||
108 | dev->num_crtcs, DRM_MEM_DRIVER); | ||
109 | drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) * | ||
110 | dev->num_crtcs, DRM_MEM_DRIVER); | ||
111 | drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs, | ||
112 | DRM_MEM_DRIVER); | ||
113 | drm_free(dev->vblank_premodeset, sizeof(*dev->vblank_premodeset) * | ||
114 | dev->num_crtcs, DRM_MEM_DRIVER); | ||
115 | drm_free(dev->vblank_offset, sizeof(*dev->vblank_offset) * dev->num_crtcs, | ||
116 | DRM_MEM_DRIVER); | ||
117 | |||
118 | dev->num_crtcs = 0; | ||
119 | } | ||
120 | |||
121 | int drm_vblank_init(struct drm_device *dev, int num_crtcs) | ||
122 | { | ||
123 | int i, ret = -ENOMEM; | ||
124 | |||
125 | setup_timer(&dev->vblank_disable_timer, vblank_disable_fn, | ||
126 | (unsigned long)dev); | ||
127 | spin_lock_init(&dev->vbl_lock); | ||
128 | atomic_set(&dev->vbl_signal_pending, 0); | ||
129 | dev->num_crtcs = num_crtcs; | ||
130 | |||
131 | dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs, | ||
132 | DRM_MEM_DRIVER); | ||
133 | if (!dev->vbl_queue) | ||
134 | goto err; | ||
135 | |||
136 | dev->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs, | ||
137 | DRM_MEM_DRIVER); | ||
138 | if (!dev->vbl_sigs) | ||
139 | goto err; | ||
140 | |||
141 | dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs, | ||
142 | DRM_MEM_DRIVER); | ||
143 | if (!dev->_vblank_count) | ||
144 | goto err; | ||
145 | |||
146 | dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs, | ||
147 | DRM_MEM_DRIVER); | ||
148 | if (!dev->vblank_refcount) | ||
149 | goto err; | ||
150 | |||
151 | dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int), | ||
152 | DRM_MEM_DRIVER); | ||
153 | if (!dev->vblank_enabled) | ||
154 | goto err; | ||
155 | |||
156 | dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER); | ||
157 | if (!dev->last_vblank) | ||
158 | goto err; | ||
159 | |||
160 | dev->vblank_premodeset = drm_calloc(num_crtcs, sizeof(u32), | ||
161 | DRM_MEM_DRIVER); | ||
162 | if (!dev->vblank_premodeset) | ||
163 | goto err; | ||
164 | |||
165 | dev->vblank_offset = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER); | ||
166 | if (!dev->vblank_offset) | ||
167 | goto err; | ||
168 | |||
169 | /* Zero per-crtc vblank stuff */ | ||
170 | for (i = 0; i < num_crtcs; i++) { | ||
171 | init_waitqueue_head(&dev->vbl_queue[i]); | ||
172 | INIT_LIST_HEAD(&dev->vbl_sigs[i]); | ||
173 | atomic_set(&dev->_vblank_count[i], 0); | ||
174 | atomic_set(&dev->vblank_refcount[i], 0); | ||
175 | } | ||
176 | |||
177 | return 0; | ||
178 | |||
179 | err: | ||
180 | drm_vblank_cleanup(dev); | ||
181 | return ret; | ||
182 | } | ||
183 | EXPORT_SYMBOL(drm_vblank_init); | ||
184 | |||
74 | /** | 185 | /** |
75 | * Install IRQ handler. | 186 | * Install IRQ handler. |
76 | * | 187 | * |
@@ -109,17 +220,6 @@ static int drm_irq_install(struct drm_device * dev) | |||
109 | 220 | ||
110 | DRM_DEBUG("irq=%d\n", dev->irq); | 221 | DRM_DEBUG("irq=%d\n", dev->irq); |
111 | 222 | ||
112 | if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) { | ||
113 | init_waitqueue_head(&dev->vbl_queue); | ||
114 | |||
115 | spin_lock_init(&dev->vbl_lock); | ||
116 | |||
117 | INIT_LIST_HEAD(&dev->vbl_sigs); | ||
118 | INIT_LIST_HEAD(&dev->vbl_sigs2); | ||
119 | |||
120 | dev->vbl_pending = 0; | ||
121 | } | ||
122 | |||
123 | /* Before installing handler */ | 223 | /* Before installing handler */ |
124 | dev->driver->irq_preinstall(dev); | 224 | dev->driver->irq_preinstall(dev); |
125 | 225 | ||
@@ -137,9 +237,14 @@ static int drm_irq_install(struct drm_device * dev) | |||
137 | } | 237 | } |
138 | 238 | ||
139 | /* After installing handler */ | 239 | /* After installing handler */ |
140 | dev->driver->irq_postinstall(dev); | 240 | ret = dev->driver->irq_postinstall(dev); |
241 | if (ret < 0) { | ||
242 | mutex_lock(&dev->struct_mutex); | ||
243 | dev->irq_enabled = 0; | ||
244 | mutex_unlock(&dev->struct_mutex); | ||
245 | } | ||
141 | 246 | ||
142 | return 0; | 247 | return ret; |
143 | } | 248 | } |
144 | 249 | ||
145 | /** | 250 | /** |
@@ -170,6 +275,8 @@ int drm_irq_uninstall(struct drm_device * dev) | |||
170 | 275 | ||
171 | free_irq(dev->irq, dev); | 276 | free_irq(dev->irq, dev); |
172 | 277 | ||
278 | drm_vblank_cleanup(dev); | ||
279 | |||
173 | dev->locked_tasklet_func = NULL; | 280 | dev->locked_tasklet_func = NULL; |
174 | 281 | ||
175 | return 0; | 282 | return 0; |
@@ -214,6 +321,148 @@ int drm_control(struct drm_device *dev, void *data, | |||
214 | } | 321 | } |
215 | 322 | ||
216 | /** | 323 | /** |
324 | * drm_vblank_count - retrieve "cooked" vblank counter value | ||
325 | * @dev: DRM device | ||
326 | * @crtc: which counter to retrieve | ||
327 | * | ||
328 | * Fetches the "cooked" vblank count value that represents the number of | ||
329 | * vblank events since the system was booted, including lost events due to | ||
330 | * modesetting activity. | ||
331 | */ | ||
332 | u32 drm_vblank_count(struct drm_device *dev, int crtc) | ||
333 | { | ||
334 | return atomic_read(&dev->_vblank_count[crtc]) + | ||
335 | dev->vblank_offset[crtc]; | ||
336 | } | ||
337 | EXPORT_SYMBOL(drm_vblank_count); | ||
338 | |||
339 | /** | ||
340 | * drm_update_vblank_count - update the master vblank counter | ||
341 | * @dev: DRM device | ||
342 | * @crtc: counter to update | ||
343 | * | ||
344 | * Call back into the driver to update the appropriate vblank counter | ||
345 | * (specified by @crtc). Deal with wraparound, if it occurred, and | ||
346 | * update the last read value so we can deal with wraparound on the next | ||
347 | * call if necessary. | ||
348 | */ | ||
349 | void drm_update_vblank_count(struct drm_device *dev, int crtc) | ||
350 | { | ||
351 | unsigned long irqflags; | ||
352 | u32 cur_vblank, diff; | ||
353 | |||
354 | /* | ||
355 | * Interrupts were disabled prior to this call, so deal with counter | ||
356 | * wrap if needed. | ||
357 | * NOTE! It's possible we lost a full dev->max_vblank_count events | ||
358 | * here if the register is small or we had vblank interrupts off for | ||
359 | * a long time. | ||
360 | */ | ||
361 | cur_vblank = dev->driver->get_vblank_counter(dev, crtc); | ||
362 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | ||
363 | if (cur_vblank < dev->last_vblank[crtc]) { | ||
364 | diff = dev->max_vblank_count - | ||
365 | dev->last_vblank[crtc]; | ||
366 | diff += cur_vblank; | ||
367 | } else { | ||
368 | diff = cur_vblank - dev->last_vblank[crtc]; | ||
369 | } | ||
370 | dev->last_vblank[crtc] = cur_vblank; | ||
371 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
372 | |||
373 | atomic_add(diff, &dev->_vblank_count[crtc]); | ||
374 | } | ||
375 | EXPORT_SYMBOL(drm_update_vblank_count); | ||
376 | |||
377 | /** | ||
378 | * drm_vblank_get - get a reference count on vblank events | ||
379 | * @dev: DRM device | ||
380 | * @crtc: which CRTC to own | ||
381 | * | ||
382 | * Acquire a reference count on vblank events to avoid having them disabled | ||
383 | * while in use. Note callers will probably want to update the master counter | ||
384 | * using drm_update_vblank_count() above before calling this routine so that | ||
385 | * wakeups occur on the right vblank event. | ||
386 | * | ||
387 | * RETURNS | ||
388 | * Zero on success, nonzero on failure. | ||
389 | */ | ||
390 | int drm_vblank_get(struct drm_device *dev, int crtc) | ||
391 | { | ||
392 | unsigned long irqflags; | ||
393 | int ret = 0; | ||
394 | |||
395 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | ||
396 | /* Going from 0->1 means we have to enable interrupts again */ | ||
397 | if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 && | ||
398 | !dev->vblank_enabled[crtc]) { | ||
399 | ret = dev->driver->enable_vblank(dev, crtc); | ||
400 | if (ret) | ||
401 | atomic_dec(&dev->vblank_refcount[crtc]); | ||
402 | else | ||
403 | dev->vblank_enabled[crtc] = 1; | ||
404 | } | ||
405 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
406 | |||
407 | return ret; | ||
408 | } | ||
409 | EXPORT_SYMBOL(drm_vblank_get); | ||
410 | |||
411 | /** | ||
412 | * drm_vblank_put - give up ownership of vblank events | ||
413 | * @dev: DRM device | ||
414 | * @crtc: which counter to give up | ||
415 | * | ||
416 | * Release ownership of a given vblank counter, turning off interrupts | ||
417 | * if possible. | ||
418 | */ | ||
419 | void drm_vblank_put(struct drm_device *dev, int crtc) | ||
420 | { | ||
421 | /* Last user schedules interrupt disable */ | ||
422 | if (atomic_dec_and_test(&dev->vblank_refcount[crtc])) | ||
423 | mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ); | ||
424 | } | ||
425 | EXPORT_SYMBOL(drm_vblank_put); | ||
426 | |||
427 | /** | ||
428 | * drm_modeset_ctl - handle vblank event counter changes across mode switch | ||
429 | * @DRM_IOCTL_ARGS: standard ioctl arguments | ||
430 | * | ||
431 | * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET | ||
432 | * ioctls around modesetting so that any lost vblank events are accounted for. | ||
433 | */ | ||
434 | int drm_modeset_ctl(struct drm_device *dev, void *data, | ||
435 | struct drm_file *file_priv) | ||
436 | { | ||
437 | struct drm_modeset_ctl *modeset = data; | ||
438 | int crtc, ret = 0; | ||
439 | u32 new; | ||
440 | |||
441 | crtc = modeset->arg; | ||
442 | if (crtc >= dev->num_crtcs) { | ||
443 | ret = -EINVAL; | ||
444 | goto out; | ||
445 | } | ||
446 | |||
447 | switch (modeset->cmd) { | ||
448 | case _DRM_PRE_MODESET: | ||
449 | dev->vblank_premodeset[crtc] = | ||
450 | dev->driver->get_vblank_counter(dev, crtc); | ||
451 | break; | ||
452 | case _DRM_POST_MODESET: | ||
453 | new = dev->driver->get_vblank_counter(dev, crtc); | ||
454 | dev->vblank_offset[crtc] = dev->vblank_premodeset[crtc] - new; | ||
455 | break; | ||
456 | default: | ||
457 | ret = -EINVAL; | ||
458 | break; | ||
459 | } | ||
460 | |||
461 | out: | ||
462 | return ret; | ||
463 | } | ||
464 | |||
465 | /** | ||
217 | * Wait for VBLANK. | 466 | * Wait for VBLANK. |
218 | * | 467 | * |
219 | * \param inode device inode. | 468 | * \param inode device inode. |
@@ -232,12 +481,13 @@ int drm_control(struct drm_device *dev, void *data, | |||
232 | * | 481 | * |
233 | * If a signal is not requested, then calls vblank_wait(). | 482 | * If a signal is not requested, then calls vblank_wait(). |
234 | */ | 483 | */ |
235 | int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv) | 484 | int drm_wait_vblank(struct drm_device *dev, void *data, |
485 | struct drm_file *file_priv) | ||
236 | { | 486 | { |
237 | union drm_wait_vblank *vblwait = data; | 487 | union drm_wait_vblank *vblwait = data; |
238 | struct timeval now; | 488 | struct timeval now; |
239 | int ret = 0; | 489 | int ret = 0; |
240 | unsigned int flags, seq; | 490 | unsigned int flags, seq, crtc; |
241 | 491 | ||
242 | if ((!dev->irq) || (!dev->irq_enabled)) | 492 | if ((!dev->irq) || (!dev->irq_enabled)) |
243 | return -EINVAL; | 493 | return -EINVAL; |
@@ -251,13 +501,13 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
251 | } | 501 | } |
252 | 502 | ||
253 | flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; | 503 | flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; |
504 | crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; | ||
254 | 505 | ||
255 | if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ? | 506 | if (crtc >= dev->num_crtcs) |
256 | DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL)) | ||
257 | return -EINVAL; | 507 | return -EINVAL; |
258 | 508 | ||
259 | seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2 | 509 | drm_update_vblank_count(dev, crtc); |
260 | : &dev->vbl_received); | 510 | seq = drm_vblank_count(dev, crtc); |
261 | 511 | ||
262 | switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { | 512 | switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { |
263 | case _DRM_VBLANK_RELATIVE: | 513 | case _DRM_VBLANK_RELATIVE: |
@@ -276,8 +526,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
276 | 526 | ||
277 | if (flags & _DRM_VBLANK_SIGNAL) { | 527 | if (flags & _DRM_VBLANK_SIGNAL) { |
278 | unsigned long irqflags; | 528 | unsigned long irqflags; |
279 | struct list_head *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY) | 529 | struct list_head *vbl_sigs = &dev->vbl_sigs[crtc]; |
280 | ? &dev->vbl_sigs2 : &dev->vbl_sigs; | ||
281 | struct drm_vbl_sig *vbl_sig; | 530 | struct drm_vbl_sig *vbl_sig; |
282 | 531 | ||
283 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | 532 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
@@ -298,22 +547,26 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
298 | } | 547 | } |
299 | } | 548 | } |
300 | 549 | ||
301 | if (dev->vbl_pending >= 100) { | 550 | if (atomic_read(&dev->vbl_signal_pending) >= 100) { |
302 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | 551 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); |
303 | return -EBUSY; | 552 | return -EBUSY; |
304 | } | 553 | } |
305 | 554 | ||
306 | dev->vbl_pending++; | ||
307 | |||
308 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | 555 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); |
309 | 556 | ||
310 | if (! | 557 | vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig), |
311 | (vbl_sig = | 558 | DRM_MEM_DRIVER); |
312 | drm_alloc(sizeof(struct drm_vbl_sig), DRM_MEM_DRIVER))) { | 559 | if (!vbl_sig) |
313 | return -ENOMEM; | 560 | return -ENOMEM; |
561 | |||
562 | ret = drm_vblank_get(dev, crtc); | ||
563 | if (ret) { | ||
564 | drm_free(vbl_sig, sizeof(struct drm_vbl_sig), | ||
565 | DRM_MEM_DRIVER); | ||
566 | return ret; | ||
314 | } | 567 | } |
315 | 568 | ||
316 | memset((void *)vbl_sig, 0, sizeof(*vbl_sig)); | 569 | atomic_inc(&dev->vbl_signal_pending); |
317 | 570 | ||
318 | vbl_sig->sequence = vblwait->request.sequence; | 571 | vbl_sig->sequence = vblwait->request.sequence; |
319 | vbl_sig->info.si_signo = vblwait->request.signal; | 572 | vbl_sig->info.si_signo = vblwait->request.signal; |
@@ -327,17 +580,20 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
327 | 580 | ||
328 | vblwait->reply.sequence = seq; | 581 | vblwait->reply.sequence = seq; |
329 | } else { | 582 | } else { |
330 | if (flags & _DRM_VBLANK_SECONDARY) { | 583 | unsigned long cur_vblank; |
331 | if (dev->driver->vblank_wait2) | 584 | |
332 | ret = dev->driver->vblank_wait2(dev, &vblwait->request.sequence); | 585 | ret = drm_vblank_get(dev, crtc); |
333 | } else if (dev->driver->vblank_wait) | 586 | if (ret) |
334 | ret = | 587 | return ret; |
335 | dev->driver->vblank_wait(dev, | 588 | DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ, |
336 | &vblwait->request.sequence); | 589 | (((cur_vblank = drm_vblank_count(dev, crtc)) |
337 | 590 | - vblwait->request.sequence) <= (1 << 23))); | |
591 | drm_vblank_put(dev, crtc); | ||
338 | do_gettimeofday(&now); | 592 | do_gettimeofday(&now); |
593 | |||
339 | vblwait->reply.tval_sec = now.tv_sec; | 594 | vblwait->reply.tval_sec = now.tv_sec; |
340 | vblwait->reply.tval_usec = now.tv_usec; | 595 | vblwait->reply.tval_usec = now.tv_usec; |
596 | vblwait->reply.sequence = cur_vblank; | ||
341 | } | 597 | } |
342 | 598 | ||
343 | done: | 599 | done: |
@@ -348,44 +604,57 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
348 | * Send the VBLANK signals. | 604 | * Send the VBLANK signals. |
349 | * | 605 | * |
350 | * \param dev DRM device. | 606 | * \param dev DRM device. |
607 | * \param crtc CRTC where the vblank event occurred | ||
351 | * | 608 | * |
352 | * Sends a signal for each task in drm_device::vbl_sigs and empties the list. | 609 | * Sends a signal for each task in drm_device::vbl_sigs and empties the list. |
353 | * | 610 | * |
354 | * If a signal is not requested, then calls vblank_wait(). | 611 | * If a signal is not requested, then calls vblank_wait(). |
355 | */ | 612 | */ |
356 | void drm_vbl_send_signals(struct drm_device * dev) | 613 | static void drm_vbl_send_signals(struct drm_device * dev, int crtc) |
357 | { | 614 | { |
615 | struct drm_vbl_sig *vbl_sig, *tmp; | ||
616 | struct list_head *vbl_sigs; | ||
617 | unsigned int vbl_seq; | ||
358 | unsigned long flags; | 618 | unsigned long flags; |
359 | int i; | ||
360 | 619 | ||
361 | spin_lock_irqsave(&dev->vbl_lock, flags); | 620 | spin_lock_irqsave(&dev->vbl_lock, flags); |
362 | 621 | ||
363 | for (i = 0; i < 2; i++) { | 622 | vbl_sigs = &dev->vbl_sigs[crtc]; |
364 | struct drm_vbl_sig *vbl_sig, *tmp; | 623 | vbl_seq = drm_vblank_count(dev, crtc); |
365 | struct list_head *vbl_sigs = i ? &dev->vbl_sigs2 : &dev->vbl_sigs; | ||
366 | unsigned int vbl_seq = atomic_read(i ? &dev->vbl_received2 : | ||
367 | &dev->vbl_received); | ||
368 | 624 | ||
369 | list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) { | 625 | list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) { |
370 | if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) { | 626 | if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) { |
371 | vbl_sig->info.si_code = vbl_seq; | 627 | vbl_sig->info.si_code = vbl_seq; |
372 | send_sig_info(vbl_sig->info.si_signo, | 628 | send_sig_info(vbl_sig->info.si_signo, |
373 | &vbl_sig->info, vbl_sig->task); | 629 | &vbl_sig->info, vbl_sig->task); |
374 | 630 | ||
375 | list_del(&vbl_sig->head); | 631 | list_del(&vbl_sig->head); |
376 | 632 | ||
377 | drm_free(vbl_sig, sizeof(*vbl_sig), | 633 | drm_free(vbl_sig, sizeof(*vbl_sig), |
378 | DRM_MEM_DRIVER); | 634 | DRM_MEM_DRIVER); |
379 | 635 | atomic_dec(&dev->vbl_signal_pending); | |
380 | dev->vbl_pending--; | 636 | drm_vblank_put(dev, crtc); |
381 | } | 637 | } |
382 | } | ||
383 | } | 638 | } |
384 | 639 | ||
385 | spin_unlock_irqrestore(&dev->vbl_lock, flags); | 640 | spin_unlock_irqrestore(&dev->vbl_lock, flags); |
386 | } | 641 | } |
387 | 642 | ||
388 | EXPORT_SYMBOL(drm_vbl_send_signals); | 643 | /** |
644 | * drm_handle_vblank - handle a vblank event | ||
645 | * @dev: DRM device | ||
646 | * @crtc: where this event occurred | ||
647 | * | ||
648 | * Drivers should call this routine in their vblank interrupt handlers to | ||
649 | * update the vblank counter and send any signals that may be pending. | ||
650 | */ | ||
651 | void drm_handle_vblank(struct drm_device *dev, int crtc) | ||
652 | { | ||
653 | drm_update_vblank_count(dev, crtc); | ||
654 | DRM_WAKEUP(&dev->vbl_queue[crtc]); | ||
655 | drm_vbl_send_signals(dev, crtc); | ||
656 | } | ||
657 | EXPORT_SYMBOL(drm_handle_vblank); | ||
389 | 658 | ||
390 | /** | 659 | /** |
391 | * Tasklet wrapper function. | 660 | * Tasklet wrapper function. |
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c index d9b560fe9bbe..93b1e0475c93 100644 --- a/drivers/char/drm/drm_proc.c +++ b/drivers/char/drm/drm_proc.c | |||
@@ -87,34 +87,35 @@ static struct drm_proc_list { | |||
87 | * "/proc/dri/%minor%/", and each entry in proc_list as | 87 | * "/proc/dri/%minor%/", and each entry in proc_list as |
88 | * "/proc/dri/%minor%/%name%". | 88 | * "/proc/dri/%minor%/%name%". |
89 | */ | 89 | */ |
90 | int drm_proc_init(struct drm_device * dev, int minor, | 90 | int drm_proc_init(struct drm_minor *minor, int minor_id, |
91 | struct proc_dir_entry *root, struct proc_dir_entry **dev_root) | 91 | struct proc_dir_entry *root) |
92 | { | 92 | { |
93 | struct proc_dir_entry *ent; | 93 | struct proc_dir_entry *ent; |
94 | int i, j; | 94 | int i, j; |
95 | char name[64]; | 95 | char name[64]; |
96 | 96 | ||
97 | sprintf(name, "%d", minor); | 97 | sprintf(name, "%d", minor_id); |
98 | *dev_root = proc_mkdir(name, root); | 98 | minor->dev_root = proc_mkdir(name, root); |
99 | if (!*dev_root) { | 99 | if (!minor->dev_root) { |
100 | DRM_ERROR("Cannot create /proc/dri/%s\n", name); | 100 | DRM_ERROR("Cannot create /proc/dri/%s\n", name); |
101 | return -1; | 101 | return -1; |
102 | } | 102 | } |
103 | 103 | ||
104 | for (i = 0; i < DRM_PROC_ENTRIES; i++) { | 104 | for (i = 0; i < DRM_PROC_ENTRIES; i++) { |
105 | ent = create_proc_entry(drm_proc_list[i].name, | 105 | ent = create_proc_entry(drm_proc_list[i].name, |
106 | S_IFREG | S_IRUGO, *dev_root); | 106 | S_IFREG | S_IRUGO, minor->dev_root); |
107 | if (!ent) { | 107 | if (!ent) { |
108 | DRM_ERROR("Cannot create /proc/dri/%s/%s\n", | 108 | DRM_ERROR("Cannot create /proc/dri/%s/%s\n", |
109 | name, drm_proc_list[i].name); | 109 | name, drm_proc_list[i].name); |
110 | for (j = 0; j < i; j++) | 110 | for (j = 0; j < i; j++) |
111 | remove_proc_entry(drm_proc_list[i].name, | 111 | remove_proc_entry(drm_proc_list[i].name, |
112 | *dev_root); | 112 | minor->dev_root); |
113 | remove_proc_entry(name, root); | 113 | remove_proc_entry(name, root); |
114 | minor->dev_root = NULL; | ||
114 | return -1; | 115 | return -1; |
115 | } | 116 | } |
116 | ent->read_proc = drm_proc_list[i].f; | 117 | ent->read_proc = drm_proc_list[i].f; |
117 | ent->data = dev; | 118 | ent->data = minor; |
118 | } | 119 | } |
119 | 120 | ||
120 | return 0; | 121 | return 0; |
@@ -130,18 +131,17 @@ int drm_proc_init(struct drm_device * dev, int minor, | |||
130 | * | 131 | * |
131 | * Remove all proc entries created by proc_init(). | 132 | * Remove all proc entries created by proc_init(). |
132 | */ | 133 | */ |
133 | int drm_proc_cleanup(int minor, struct proc_dir_entry *root, | 134 | int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) |
134 | struct proc_dir_entry *dev_root) | ||
135 | { | 135 | { |
136 | int i; | 136 | int i; |
137 | char name[64]; | 137 | char name[64]; |
138 | 138 | ||
139 | if (!root || !dev_root) | 139 | if (!root || !minor->dev_root) |
140 | return 0; | 140 | return 0; |
141 | 141 | ||
142 | for (i = 0; i < DRM_PROC_ENTRIES; i++) | 142 | for (i = 0; i < DRM_PROC_ENTRIES; i++) |
143 | remove_proc_entry(drm_proc_list[i].name, dev_root); | 143 | remove_proc_entry(drm_proc_list[i].name, minor->dev_root); |
144 | sprintf(name, "%d", minor); | 144 | sprintf(name, "%d", minor->index); |
145 | remove_proc_entry(name, root); | 145 | remove_proc_entry(name, root); |
146 | 146 | ||
147 | return 0; | 147 | return 0; |
@@ -163,7 +163,8 @@ int drm_proc_cleanup(int minor, struct proc_dir_entry *root, | |||
163 | static int drm_name_info(char *buf, char **start, off_t offset, int request, | 163 | static int drm_name_info(char *buf, char **start, off_t offset, int request, |
164 | int *eof, void *data) | 164 | int *eof, void *data) |
165 | { | 165 | { |
166 | struct drm_device *dev = (struct drm_device *) data; | 166 | struct drm_minor *minor = (struct drm_minor *) data; |
167 | struct drm_device *dev = minor->dev; | ||
167 | int len = 0; | 168 | int len = 0; |
168 | 169 | ||
169 | if (offset > DRM_PROC_LIMIT) { | 170 | if (offset > DRM_PROC_LIMIT) { |
@@ -205,7 +206,8 @@ static int drm_name_info(char *buf, char **start, off_t offset, int request, | |||
205 | static int drm__vm_info(char *buf, char **start, off_t offset, int request, | 206 | static int drm__vm_info(char *buf, char **start, off_t offset, int request, |
206 | int *eof, void *data) | 207 | int *eof, void *data) |
207 | { | 208 | { |
208 | struct drm_device *dev = (struct drm_device *) data; | 209 | struct drm_minor *minor = (struct drm_minor *) data; |
210 | struct drm_device *dev = minor->dev; | ||
209 | int len = 0; | 211 | int len = 0; |
210 | struct drm_map *map; | 212 | struct drm_map *map; |
211 | struct drm_map_list *r_list; | 213 | struct drm_map_list *r_list; |
@@ -261,7 +263,8 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request, | |||
261 | static int drm_vm_info(char *buf, char **start, off_t offset, int request, | 263 | static int drm_vm_info(char *buf, char **start, off_t offset, int request, |
262 | int *eof, void *data) | 264 | int *eof, void *data) |
263 | { | 265 | { |
264 | struct drm_device *dev = (struct drm_device *) data; | 266 | struct drm_minor *minor = (struct drm_minor *) data; |
267 | struct drm_device *dev = minor->dev; | ||
265 | int ret; | 268 | int ret; |
266 | 269 | ||
267 | mutex_lock(&dev->struct_mutex); | 270 | mutex_lock(&dev->struct_mutex); |
@@ -284,7 +287,8 @@ static int drm_vm_info(char *buf, char **start, off_t offset, int request, | |||
284 | static int drm__queues_info(char *buf, char **start, off_t offset, | 287 | static int drm__queues_info(char *buf, char **start, off_t offset, |
285 | int request, int *eof, void *data) | 288 | int request, int *eof, void *data) |
286 | { | 289 | { |
287 | struct drm_device *dev = (struct drm_device *) data; | 290 | struct drm_minor *minor = (struct drm_minor *) data; |
291 | struct drm_device *dev = minor->dev; | ||
288 | int len = 0; | 292 | int len = 0; |
289 | int i; | 293 | int i; |
290 | struct drm_queue *q; | 294 | struct drm_queue *q; |
@@ -334,7 +338,8 @@ static int drm__queues_info(char *buf, char **start, off_t offset, | |||
334 | static int drm_queues_info(char *buf, char **start, off_t offset, int request, | 338 | static int drm_queues_info(char *buf, char **start, off_t offset, int request, |
335 | int *eof, void *data) | 339 | int *eof, void *data) |
336 | { | 340 | { |
337 | struct drm_device *dev = (struct drm_device *) data; | 341 | struct drm_minor *minor = (struct drm_minor *) data; |
342 | struct drm_device *dev = minor->dev; | ||
338 | int ret; | 343 | int ret; |
339 | 344 | ||
340 | mutex_lock(&dev->struct_mutex); | 345 | mutex_lock(&dev->struct_mutex); |
@@ -357,7 +362,8 @@ static int drm_queues_info(char *buf, char **start, off_t offset, int request, | |||
357 | static int drm__bufs_info(char *buf, char **start, off_t offset, int request, | 362 | static int drm__bufs_info(char *buf, char **start, off_t offset, int request, |
358 | int *eof, void *data) | 363 | int *eof, void *data) |
359 | { | 364 | { |
360 | struct drm_device *dev = (struct drm_device *) data; | 365 | struct drm_minor *minor = (struct drm_minor *) data; |
366 | struct drm_device *dev = minor->dev; | ||
361 | int len = 0; | 367 | int len = 0; |
362 | struct drm_device_dma *dma = dev->dma; | 368 | struct drm_device_dma *dma = dev->dma; |
363 | int i; | 369 | int i; |
@@ -406,7 +412,8 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request, | |||
406 | static int drm_bufs_info(char *buf, char **start, off_t offset, int request, | 412 | static int drm_bufs_info(char *buf, char **start, off_t offset, int request, |
407 | int *eof, void *data) | 413 | int *eof, void *data) |
408 | { | 414 | { |
409 | struct drm_device *dev = (struct drm_device *) data; | 415 | struct drm_minor *minor = (struct drm_minor *) data; |
416 | struct drm_device *dev = minor->dev; | ||
410 | int ret; | 417 | int ret; |
411 | 418 | ||
412 | mutex_lock(&dev->struct_mutex); | 419 | mutex_lock(&dev->struct_mutex); |
@@ -429,7 +436,8 @@ static int drm_bufs_info(char *buf, char **start, off_t offset, int request, | |||
429 | static int drm__clients_info(char *buf, char **start, off_t offset, | 436 | static int drm__clients_info(char *buf, char **start, off_t offset, |
430 | int request, int *eof, void *data) | 437 | int request, int *eof, void *data) |
431 | { | 438 | { |
432 | struct drm_device *dev = (struct drm_device *) data; | 439 | struct drm_minor *minor = (struct drm_minor *) data; |
440 | struct drm_device *dev = minor->dev; | ||
433 | int len = 0; | 441 | int len = 0; |
434 | struct drm_file *priv; | 442 | struct drm_file *priv; |
435 | 443 | ||
@@ -445,7 +453,7 @@ static int drm__clients_info(char *buf, char **start, off_t offset, | |||
445 | list_for_each_entry(priv, &dev->filelist, lhead) { | 453 | list_for_each_entry(priv, &dev->filelist, lhead) { |
446 | DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n", | 454 | DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n", |
447 | priv->authenticated ? 'y' : 'n', | 455 | priv->authenticated ? 'y' : 'n', |
448 | priv->minor, | 456 | priv->minor->index, |
449 | priv->pid, | 457 | priv->pid, |
450 | priv->uid, priv->magic, priv->ioctl_count); | 458 | priv->uid, priv->magic, priv->ioctl_count); |
451 | } | 459 | } |
@@ -462,7 +470,8 @@ static int drm__clients_info(char *buf, char **start, off_t offset, | |||
462 | static int drm_clients_info(char *buf, char **start, off_t offset, | 470 | static int drm_clients_info(char *buf, char **start, off_t offset, |
463 | int request, int *eof, void *data) | 471 | int request, int *eof, void *data) |
464 | { | 472 | { |
465 | struct drm_device *dev = (struct drm_device *) data; | 473 | struct drm_minor *minor = (struct drm_minor *) data; |
474 | struct drm_device *dev = minor->dev; | ||
466 | int ret; | 475 | int ret; |
467 | 476 | ||
468 | mutex_lock(&dev->struct_mutex); | 477 | mutex_lock(&dev->struct_mutex); |
@@ -476,7 +485,8 @@ static int drm_clients_info(char *buf, char **start, off_t offset, | |||
476 | static int drm__vma_info(char *buf, char **start, off_t offset, int request, | 485 | static int drm__vma_info(char *buf, char **start, off_t offset, int request, |
477 | int *eof, void *data) | 486 | int *eof, void *data) |
478 | { | 487 | { |
479 | struct drm_device *dev = (struct drm_device *) data; | 488 | struct drm_minor *minor = (struct drm_minor *) data; |
489 | struct drm_device *dev = minor->dev; | ||
480 | int len = 0; | 490 | int len = 0; |
481 | struct drm_vma_entry *pt; | 491 | struct drm_vma_entry *pt; |
482 | struct vm_area_struct *vma; | 492 | struct vm_area_struct *vma; |
@@ -535,7 +545,8 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request, | |||
535 | static int drm_vma_info(char *buf, char **start, off_t offset, int request, | 545 | static int drm_vma_info(char *buf, char **start, off_t offset, int request, |
536 | int *eof, void *data) | 546 | int *eof, void *data) |
537 | { | 547 | { |
538 | struct drm_device *dev = (struct drm_device *) data; | 548 | struct drm_minor *minor = (struct drm_minor *) data; |
549 | struct drm_device *dev = minor->dev; | ||
539 | int ret; | 550 | int ret; |
540 | 551 | ||
541 | mutex_lock(&dev->struct_mutex); | 552 | mutex_lock(&dev->struct_mutex); |
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c index d93a217f856a..c2f584f3b46c 100644 --- a/drivers/char/drm/drm_stub.c +++ b/drivers/char/drm/drm_stub.c | |||
@@ -36,23 +36,49 @@ | |||
36 | #include "drmP.h" | 36 | #include "drmP.h" |
37 | #include "drm_core.h" | 37 | #include "drm_core.h" |
38 | 38 | ||
39 | unsigned int drm_cards_limit = 16; /* Enough for one machine */ | ||
40 | unsigned int drm_debug = 0; /* 1 to enable debug output */ | 39 | unsigned int drm_debug = 0; /* 1 to enable debug output */ |
41 | EXPORT_SYMBOL(drm_debug); | 40 | EXPORT_SYMBOL(drm_debug); |
42 | 41 | ||
43 | MODULE_AUTHOR(CORE_AUTHOR); | 42 | MODULE_AUTHOR(CORE_AUTHOR); |
44 | MODULE_DESCRIPTION(CORE_DESC); | 43 | MODULE_DESCRIPTION(CORE_DESC); |
45 | MODULE_LICENSE("GPL and additional rights"); | 44 | MODULE_LICENSE("GPL and additional rights"); |
46 | MODULE_PARM_DESC(cards_limit, "Maximum number of graphics cards"); | ||
47 | MODULE_PARM_DESC(debug, "Enable debug output"); | 45 | MODULE_PARM_DESC(debug, "Enable debug output"); |
48 | 46 | ||
49 | module_param_named(cards_limit, drm_cards_limit, int, 0444); | ||
50 | module_param_named(debug, drm_debug, int, 0600); | 47 | module_param_named(debug, drm_debug, int, 0600); |
51 | 48 | ||
52 | struct drm_head **drm_heads; | 49 | struct idr drm_minors_idr; |
50 | |||
53 | struct class *drm_class; | 51 | struct class *drm_class; |
54 | struct proc_dir_entry *drm_proc_root; | 52 | struct proc_dir_entry *drm_proc_root; |
55 | 53 | ||
54 | static int drm_minor_get_id(struct drm_device *dev, int type) | ||
55 | { | ||
56 | int new_id; | ||
57 | int ret; | ||
58 | int base = 0, limit = 63; | ||
59 | |||
60 | again: | ||
61 | if (idr_pre_get(&drm_minors_idr, GFP_KERNEL) == 0) { | ||
62 | DRM_ERROR("Out of memory expanding drawable idr\n"); | ||
63 | return -ENOMEM; | ||
64 | } | ||
65 | mutex_lock(&dev->struct_mutex); | ||
66 | ret = idr_get_new_above(&drm_minors_idr, NULL, | ||
67 | base, &new_id); | ||
68 | mutex_unlock(&dev->struct_mutex); | ||
69 | if (ret == -EAGAIN) { | ||
70 | goto again; | ||
71 | } else if (ret) { | ||
72 | return ret; | ||
73 | } | ||
74 | |||
75 | if (new_id >= limit) { | ||
76 | idr_remove(&drm_minors_idr, new_id); | ||
77 | return -EINVAL; | ||
78 | } | ||
79 | return new_id; | ||
80 | } | ||
81 | |||
56 | static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, | 82 | static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, |
57 | const struct pci_device_id *ent, | 83 | const struct pci_device_id *ent, |
58 | struct drm_driver *driver) | 84 | struct drm_driver *driver) |
@@ -145,48 +171,60 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, | |||
145 | * create the proc init entry via proc_init(). This routines assigns | 171 | * create the proc init entry via proc_init(). This routines assigns |
146 | * minor numbers to secondary heads of multi-headed cards | 172 | * minor numbers to secondary heads of multi-headed cards |
147 | */ | 173 | */ |
148 | static int drm_get_head(struct drm_device * dev, struct drm_head * head) | 174 | static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type) |
149 | { | 175 | { |
150 | struct drm_head **heads = drm_heads; | 176 | struct drm_minor *new_minor; |
151 | int ret; | 177 | int ret; |
152 | int minor; | 178 | int minor_id; |
153 | 179 | ||
154 | DRM_DEBUG("\n"); | 180 | DRM_DEBUG("\n"); |
155 | 181 | ||
156 | for (minor = 0; minor < drm_cards_limit; minor++, heads++) { | 182 | minor_id = drm_minor_get_id(dev, type); |
157 | if (!*heads) { | 183 | if (minor_id < 0) |
158 | 184 | return minor_id; | |
159 | *head = (struct drm_head) { | 185 | |
160 | .dev = dev,.device = | 186 | new_minor = kzalloc(sizeof(struct drm_minor), GFP_KERNEL); |
161 | MKDEV(DRM_MAJOR, minor),.minor = minor,}; | 187 | if (!new_minor) { |
162 | 188 | ret = -ENOMEM; | |
163 | if ((ret = | 189 | goto err_idr; |
164 | drm_proc_init(dev, minor, drm_proc_root, | 190 | } |
165 | &head->dev_root))) { | 191 | |
166 | printk(KERN_ERR | 192 | new_minor->type = type; |
167 | "DRM: Failed to initialize /proc/dri.\n"); | 193 | new_minor->device = MKDEV(DRM_MAJOR, minor_id); |
168 | goto err_g1; | 194 | new_minor->dev = dev; |
169 | } | 195 | new_minor->index = minor_id; |
170 | 196 | ||
171 | ret = drm_sysfs_device_add(dev, head); | 197 | idr_replace(&drm_minors_idr, new_minor, minor_id); |
172 | if (ret) { | 198 | |
173 | printk(KERN_ERR | 199 | if (type == DRM_MINOR_LEGACY) { |
174 | "DRM: Error sysfs_device_add.\n"); | 200 | ret = drm_proc_init(new_minor, minor_id, drm_proc_root); |
175 | goto err_g2; | 201 | if (ret) { |
176 | } | 202 | DRM_ERROR("DRM: Failed to initialize /proc/dri.\n"); |
177 | *heads = head; | 203 | goto err_mem; |
178 | |||
179 | DRM_DEBUG("new minor assigned %d\n", minor); | ||
180 | return 0; | ||
181 | } | 204 | } |
205 | } else | ||
206 | new_minor->dev_root = NULL; | ||
207 | |||
208 | ret = drm_sysfs_device_add(new_minor); | ||
209 | if (ret) { | ||
210 | printk(KERN_ERR | ||
211 | "DRM: Error sysfs_device_add.\n"); | ||
212 | goto err_g2; | ||
182 | } | 213 | } |
183 | DRM_ERROR("out of minors\n"); | 214 | *minor = new_minor; |
184 | return -ENOMEM; | 215 | |
185 | err_g2: | 216 | DRM_DEBUG("new minor assigned %d\n", minor_id); |
186 | drm_proc_cleanup(minor, drm_proc_root, head->dev_root); | 217 | return 0; |
187 | err_g1: | 218 | |
188 | *head = (struct drm_head) { | 219 | |
189 | .dev = NULL}; | 220 | err_g2: |
221 | if (new_minor->type == DRM_MINOR_LEGACY) | ||
222 | drm_proc_cleanup(new_minor, drm_proc_root); | ||
223 | err_mem: | ||
224 | kfree(new_minor); | ||
225 | err_idr: | ||
226 | idr_remove(&drm_minors_idr, minor_id); | ||
227 | *minor = NULL; | ||
190 | return ret; | 228 | return ret; |
191 | } | 229 | } |
192 | 230 | ||
@@ -222,12 +260,12 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | |||
222 | printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); | 260 | printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); |
223 | goto err_g2; | 261 | goto err_g2; |
224 | } | 262 | } |
225 | if ((ret = drm_get_head(dev, &dev->primary))) | 263 | if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) |
226 | goto err_g2; | 264 | goto err_g2; |
227 | 265 | ||
228 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", | 266 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", |
229 | driver->name, driver->major, driver->minor, driver->patchlevel, | 267 | driver->name, driver->major, driver->minor, driver->patchlevel, |
230 | driver->date, dev->primary.minor); | 268 | driver->date, dev->primary->index); |
231 | 269 | ||
232 | return 0; | 270 | return 0; |
233 | 271 | ||
@@ -276,18 +314,18 @@ int drm_put_dev(struct drm_device * dev) | |||
276 | * last minor released. | 314 | * last minor released. |
277 | * | 315 | * |
278 | */ | 316 | */ |
279 | int drm_put_head(struct drm_head * head) | 317 | int drm_put_minor(struct drm_minor **minor_p) |
280 | { | 318 | { |
281 | int minor = head->minor; | 319 | struct drm_minor *minor = *minor_p; |
282 | 320 | DRM_DEBUG("release secondary minor %d\n", minor->index); | |
283 | DRM_DEBUG("release secondary minor %d\n", minor); | ||
284 | |||
285 | drm_proc_cleanup(minor, drm_proc_root, head->dev_root); | ||
286 | drm_sysfs_device_remove(head->dev); | ||
287 | 321 | ||
288 | *head = (struct drm_head) {.dev = NULL}; | 322 | if (minor->type == DRM_MINOR_LEGACY) |
323 | drm_proc_cleanup(minor, drm_proc_root); | ||
324 | drm_sysfs_device_remove(minor); | ||
289 | 325 | ||
290 | drm_heads[minor] = NULL; | 326 | idr_remove(&drm_minors_idr, minor->index); |
291 | 327 | ||
328 | kfree(minor); | ||
329 | *minor_p = NULL; | ||
292 | return 0; | 330 | return 0; |
293 | } | 331 | } |
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c index 05ed5043254f..7a1d9a782ddb 100644 --- a/drivers/char/drm/drm_sysfs.c +++ b/drivers/char/drm/drm_sysfs.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include "drm_core.h" | 19 | #include "drm_core.h" |
20 | #include "drmP.h" | 20 | #include "drmP.h" |
21 | 21 | ||
22 | #define to_drm_device(d) container_of(d, struct drm_device, dev) | 22 | #define to_drm_minor(d) container_of(d, struct drm_minor, kdev) |
23 | 23 | ||
24 | /** | 24 | /** |
25 | * drm_sysfs_suspend - DRM class suspend hook | 25 | * drm_sysfs_suspend - DRM class suspend hook |
@@ -31,7 +31,8 @@ | |||
31 | */ | 31 | */ |
32 | static int drm_sysfs_suspend(struct device *dev, pm_message_t state) | 32 | static int drm_sysfs_suspend(struct device *dev, pm_message_t state) |
33 | { | 33 | { |
34 | struct drm_device *drm_dev = to_drm_device(dev); | 34 | struct drm_minor *drm_minor = to_drm_minor(dev); |
35 | struct drm_device *drm_dev = drm_minor->dev; | ||
35 | 36 | ||
36 | printk(KERN_ERR "%s\n", __FUNCTION__); | 37 | printk(KERN_ERR "%s\n", __FUNCTION__); |
37 | 38 | ||
@@ -50,7 +51,8 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state) | |||
50 | */ | 51 | */ |
51 | static int drm_sysfs_resume(struct device *dev) | 52 | static int drm_sysfs_resume(struct device *dev) |
52 | { | 53 | { |
53 | struct drm_device *drm_dev = to_drm_device(dev); | 54 | struct drm_minor *drm_minor = to_drm_minor(dev); |
55 | struct drm_device *drm_dev = drm_minor->dev; | ||
54 | 56 | ||
55 | if (drm_dev->driver->resume) | 57 | if (drm_dev->driver->resume) |
56 | return drm_dev->driver->resume(drm_dev); | 58 | return drm_dev->driver->resume(drm_dev); |
@@ -120,10 +122,11 @@ void drm_sysfs_destroy(void) | |||
120 | static ssize_t show_dri(struct device *device, struct device_attribute *attr, | 122 | static ssize_t show_dri(struct device *device, struct device_attribute *attr, |
121 | char *buf) | 123 | char *buf) |
122 | { | 124 | { |
123 | struct drm_device *dev = to_drm_device(device); | 125 | struct drm_minor *drm_minor = to_drm_minor(device); |
124 | if (dev->driver->dri_library_name) | 126 | struct drm_device *drm_dev = drm_minor->dev; |
125 | return dev->driver->dri_library_name(dev, buf); | 127 | if (drm_dev->driver->dri_library_name) |
126 | return snprintf(buf, PAGE_SIZE, "%s\n", dev->driver->pci_driver.name); | 128 | return drm_dev->driver->dri_library_name(drm_dev, buf); |
129 | return snprintf(buf, PAGE_SIZE, "%s\n", drm_dev->driver->pci_driver.name); | ||
127 | } | 130 | } |
128 | 131 | ||
129 | static struct device_attribute device_attrs[] = { | 132 | static struct device_attribute device_attrs[] = { |
@@ -152,25 +155,28 @@ static void drm_sysfs_device_release(struct device *dev) | |||
152 | * as the parent for the Linux device, and make sure it has a file containing | 155 | * as the parent for the Linux device, and make sure it has a file containing |
153 | * the driver we're using (for userspace compatibility). | 156 | * the driver we're using (for userspace compatibility). |
154 | */ | 157 | */ |
155 | int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head) | 158 | int drm_sysfs_device_add(struct drm_minor *minor) |
156 | { | 159 | { |
157 | int err; | 160 | int err; |
158 | int i, j; | 161 | int i, j; |
162 | char *minor_str; | ||
159 | 163 | ||
160 | dev->dev.parent = &dev->pdev->dev; | 164 | minor->kdev.parent = &minor->dev->pdev->dev; |
161 | dev->dev.class = drm_class; | 165 | minor->kdev.class = drm_class; |
162 | dev->dev.release = drm_sysfs_device_release; | 166 | minor->kdev.release = drm_sysfs_device_release; |
163 | dev->dev.devt = head->device; | 167 | minor->kdev.devt = minor->device; |
164 | snprintf(dev->dev.bus_id, BUS_ID_SIZE, "card%d", head->minor); | 168 | minor_str = "card%d"; |
165 | 169 | ||
166 | err = device_register(&dev->dev); | 170 | snprintf(minor->kdev.bus_id, BUS_ID_SIZE, minor_str, minor->index); |
171 | |||
172 | err = device_register(&minor->kdev); | ||
167 | if (err) { | 173 | if (err) { |
168 | DRM_ERROR("device add failed: %d\n", err); | 174 | DRM_ERROR("device add failed: %d\n", err); |
169 | goto err_out; | 175 | goto err_out; |
170 | } | 176 | } |
171 | 177 | ||
172 | for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { | 178 | for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { |
173 | err = device_create_file(&dev->dev, &device_attrs[i]); | 179 | err = device_create_file(&minor->kdev, &device_attrs[i]); |
174 | if (err) | 180 | if (err) |
175 | goto err_out_files; | 181 | goto err_out_files; |
176 | } | 182 | } |
@@ -180,8 +186,8 @@ int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head) | |||
180 | err_out_files: | 186 | err_out_files: |
181 | if (i > 0) | 187 | if (i > 0) |
182 | for (j = 0; j < i; j++) | 188 | for (j = 0; j < i; j++) |
183 | device_remove_file(&dev->dev, &device_attrs[i]); | 189 | device_remove_file(&minor->kdev, &device_attrs[i]); |
184 | device_unregister(&dev->dev); | 190 | device_unregister(&minor->kdev); |
185 | err_out: | 191 | err_out: |
186 | 192 | ||
187 | return err; | 193 | return err; |
@@ -194,11 +200,11 @@ err_out: | |||
194 | * This call unregisters and cleans up a class device that was created with a | 200 | * This call unregisters and cleans up a class device that was created with a |
195 | * call to drm_sysfs_device_add() | 201 | * call to drm_sysfs_device_add() |
196 | */ | 202 | */ |
197 | void drm_sysfs_device_remove(struct drm_device *dev) | 203 | void drm_sysfs_device_remove(struct drm_minor *minor) |
198 | { | 204 | { |
199 | int i; | 205 | int i; |
200 | 206 | ||
201 | for (i = 0; i < ARRAY_SIZE(device_attrs); i++) | 207 | for (i = 0; i < ARRAY_SIZE(device_attrs); i++) |
202 | device_remove_file(&dev->dev, &device_attrs[i]); | 208 | device_remove_file(&minor->kdev, &device_attrs[i]); |
203 | device_unregister(&dev->dev); | 209 | device_unregister(&minor->kdev); |
204 | } | 210 | } |
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c index 945df72a51a9..c234c6f24a8d 100644 --- a/drivers/char/drm/drm_vm.c +++ b/drivers/char/drm/drm_vm.c | |||
@@ -90,7 +90,7 @@ static pgprot_t drm_dma_prot(uint32_t map_type, struct vm_area_struct *vma) | |||
90 | static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | 90 | static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
91 | { | 91 | { |
92 | struct drm_file *priv = vma->vm_file->private_data; | 92 | struct drm_file *priv = vma->vm_file->private_data; |
93 | struct drm_device *dev = priv->head->dev; | 93 | struct drm_device *dev = priv->minor->dev; |
94 | struct drm_map *map = NULL; | 94 | struct drm_map *map = NULL; |
95 | struct drm_map_list *r_list; | 95 | struct drm_map_list *r_list; |
96 | struct drm_hash_item *hash; | 96 | struct drm_hash_item *hash; |
@@ -207,7 +207,7 @@ static int drm_do_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
207 | static void drm_vm_shm_close(struct vm_area_struct *vma) | 207 | static void drm_vm_shm_close(struct vm_area_struct *vma) |
208 | { | 208 | { |
209 | struct drm_file *priv = vma->vm_file->private_data; | 209 | struct drm_file *priv = vma->vm_file->private_data; |
210 | struct drm_device *dev = priv->head->dev; | 210 | struct drm_device *dev = priv->minor->dev; |
211 | struct drm_vma_entry *pt, *temp; | 211 | struct drm_vma_entry *pt, *temp; |
212 | struct drm_map *map; | 212 | struct drm_map *map; |
213 | struct drm_map_list *r_list; | 213 | struct drm_map_list *r_list; |
@@ -286,7 +286,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) | |||
286 | static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | 286 | static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
287 | { | 287 | { |
288 | struct drm_file *priv = vma->vm_file->private_data; | 288 | struct drm_file *priv = vma->vm_file->private_data; |
289 | struct drm_device *dev = priv->head->dev; | 289 | struct drm_device *dev = priv->minor->dev; |
290 | struct drm_device_dma *dma = dev->dma; | 290 | struct drm_device_dma *dma = dev->dma; |
291 | unsigned long offset; | 291 | unsigned long offset; |
292 | unsigned long page_nr; | 292 | unsigned long page_nr; |
@@ -321,7 +321,7 @@ static int drm_do_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
321 | { | 321 | { |
322 | struct drm_map *map = (struct drm_map *) vma->vm_private_data; | 322 | struct drm_map *map = (struct drm_map *) vma->vm_private_data; |
323 | struct drm_file *priv = vma->vm_file->private_data; | 323 | struct drm_file *priv = vma->vm_file->private_data; |
324 | struct drm_device *dev = priv->head->dev; | 324 | struct drm_device *dev = priv->minor->dev; |
325 | struct drm_sg_mem *entry = dev->sg; | 325 | struct drm_sg_mem *entry = dev->sg; |
326 | unsigned long offset; | 326 | unsigned long offset; |
327 | unsigned long map_offset; | 327 | unsigned long map_offset; |
@@ -402,7 +402,7 @@ static struct vm_operations_struct drm_vm_sg_ops = { | |||
402 | static void drm_vm_open_locked(struct vm_area_struct *vma) | 402 | static void drm_vm_open_locked(struct vm_area_struct *vma) |
403 | { | 403 | { |
404 | struct drm_file *priv = vma->vm_file->private_data; | 404 | struct drm_file *priv = vma->vm_file->private_data; |
405 | struct drm_device *dev = priv->head->dev; | 405 | struct drm_device *dev = priv->minor->dev; |
406 | struct drm_vma_entry *vma_entry; | 406 | struct drm_vma_entry *vma_entry; |
407 | 407 | ||
408 | DRM_DEBUG("0x%08lx,0x%08lx\n", | 408 | DRM_DEBUG("0x%08lx,0x%08lx\n", |
@@ -420,7 +420,7 @@ static void drm_vm_open_locked(struct vm_area_struct *vma) | |||
420 | static void drm_vm_open(struct vm_area_struct *vma) | 420 | static void drm_vm_open(struct vm_area_struct *vma) |
421 | { | 421 | { |
422 | struct drm_file *priv = vma->vm_file->private_data; | 422 | struct drm_file *priv = vma->vm_file->private_data; |
423 | struct drm_device *dev = priv->head->dev; | 423 | struct drm_device *dev = priv->minor->dev; |
424 | 424 | ||
425 | mutex_lock(&dev->struct_mutex); | 425 | mutex_lock(&dev->struct_mutex); |
426 | drm_vm_open_locked(vma); | 426 | drm_vm_open_locked(vma); |
@@ -438,7 +438,7 @@ static void drm_vm_open(struct vm_area_struct *vma) | |||
438 | static void drm_vm_close(struct vm_area_struct *vma) | 438 | static void drm_vm_close(struct vm_area_struct *vma) |
439 | { | 439 | { |
440 | struct drm_file *priv = vma->vm_file->private_data; | 440 | struct drm_file *priv = vma->vm_file->private_data; |
441 | struct drm_device *dev = priv->head->dev; | 441 | struct drm_device *dev = priv->minor->dev; |
442 | struct drm_vma_entry *pt, *temp; | 442 | struct drm_vma_entry *pt, *temp; |
443 | 443 | ||
444 | DRM_DEBUG("0x%08lx,0x%08lx\n", | 444 | DRM_DEBUG("0x%08lx,0x%08lx\n", |
@@ -473,7 +473,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) | |||
473 | struct drm_device_dma *dma; | 473 | struct drm_device_dma *dma; |
474 | unsigned long length = vma->vm_end - vma->vm_start; | 474 | unsigned long length = vma->vm_end - vma->vm_start; |
475 | 475 | ||
476 | dev = priv->head->dev; | 476 | dev = priv->minor->dev; |
477 | dma = dev->dma; | 477 | dma = dev->dma; |
478 | DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", | 478 | DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", |
479 | vma->vm_start, vma->vm_end, vma->vm_pgoff); | 479 | vma->vm_start, vma->vm_end, vma->vm_pgoff); |
@@ -543,7 +543,7 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs); | |||
543 | static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) | 543 | static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) |
544 | { | 544 | { |
545 | struct drm_file *priv = filp->private_data; | 545 | struct drm_file *priv = filp->private_data; |
546 | struct drm_device *dev = priv->head->dev; | 546 | struct drm_device *dev = priv->minor->dev; |
547 | struct drm_map *map = NULL; | 547 | struct drm_map *map = NULL; |
548 | unsigned long offset = 0; | 548 | unsigned long offset = 0; |
549 | struct drm_hash_item *hash; | 549 | struct drm_hash_item *hash; |
@@ -640,12 +640,12 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) | |||
640 | /* Don't let this area swap. Change when | 640 | /* Don't let this area swap. Change when |
641 | DRM_KERNEL advisory is supported. */ | 641 | DRM_KERNEL advisory is supported. */ |
642 | vma->vm_flags |= VM_RESERVED; | 642 | vma->vm_flags |= VM_RESERVED; |
643 | vma->vm_page_prot = drm_dma_prot(map->type, vma); | ||
644 | break; | 643 | break; |
645 | case _DRM_SCATTER_GATHER: | 644 | case _DRM_SCATTER_GATHER: |
646 | vma->vm_ops = &drm_vm_sg_ops; | 645 | vma->vm_ops = &drm_vm_sg_ops; |
647 | vma->vm_private_data = (void *)map; | 646 | vma->vm_private_data = (void *)map; |
648 | vma->vm_flags |= VM_RESERVED; | 647 | vma->vm_flags |= VM_RESERVED; |
648 | vma->vm_page_prot = drm_dma_prot(map->type, vma); | ||
649 | break; | 649 | break; |
650 | default: | 650 | default: |
651 | return -EINVAL; /* This should never happen. */ | 651 | return -EINVAL; /* This should never happen. */ |
@@ -661,7 +661,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) | |||
661 | int drm_mmap(struct file *filp, struct vm_area_struct *vma) | 661 | int drm_mmap(struct file *filp, struct vm_area_struct *vma) |
662 | { | 662 | { |
663 | struct drm_file *priv = filp->private_data; | 663 | struct drm_file *priv = filp->private_data; |
664 | struct drm_device *dev = priv->head->dev; | 664 | struct drm_device *dev = priv->minor->dev; |
665 | int ret; | 665 | int ret; |
666 | 666 | ||
667 | mutex_lock(&dev->struct_mutex); | 667 | mutex_lock(&dev->struct_mutex); |
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c index 8d7ea81c4b66..e5de8ea41544 100644 --- a/drivers/char/drm/i810_dma.c +++ b/drivers/char/drm/i810_dma.c | |||
@@ -94,7 +94,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) | |||
94 | drm_i810_buf_priv_t *buf_priv; | 94 | drm_i810_buf_priv_t *buf_priv; |
95 | 95 | ||
96 | lock_kernel(); | 96 | lock_kernel(); |
97 | dev = priv->head->dev; | 97 | dev = priv->minor->dev; |
98 | dev_priv = dev->dev_private; | 98 | dev_priv = dev->dev_private; |
99 | buf = dev_priv->mmap_buffer; | 99 | buf = dev_priv->mmap_buffer; |
100 | buf_priv = buf->dev_private; | 100 | buf_priv = buf->dev_private; |
@@ -122,7 +122,7 @@ static const struct file_operations i810_buffer_fops = { | |||
122 | 122 | ||
123 | static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) | 123 | static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) |
124 | { | 124 | { |
125 | struct drm_device *dev = file_priv->head->dev; | 125 | struct drm_device *dev = file_priv->minor->dev; |
126 | drm_i810_buf_priv_t *buf_priv = buf->dev_private; | 126 | drm_i810_buf_priv_t *buf_priv = buf->dev_private; |
127 | drm_i810_private_t *dev_priv = dev->dev_private; | 127 | drm_i810_private_t *dev_priv = dev->dev_private; |
128 | const struct file_operations *old_fops; | 128 | const struct file_operations *old_fops; |
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c index 9df08105f4f3..60c9376be486 100644 --- a/drivers/char/drm/i830_dma.c +++ b/drivers/char/drm/i830_dma.c | |||
@@ -96,7 +96,7 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) | |||
96 | drm_i830_buf_priv_t *buf_priv; | 96 | drm_i830_buf_priv_t *buf_priv; |
97 | 97 | ||
98 | lock_kernel(); | 98 | lock_kernel(); |
99 | dev = priv->head->dev; | 99 | dev = priv->minor->dev; |
100 | dev_priv = dev->dev_private; | 100 | dev_priv = dev->dev_private; |
101 | buf = dev_priv->mmap_buffer; | 101 | buf = dev_priv->mmap_buffer; |
102 | buf_priv = buf->dev_private; | 102 | buf_priv = buf->dev_private; |
@@ -124,7 +124,7 @@ static const struct file_operations i830_buffer_fops = { | |||
124 | 124 | ||
125 | static int i830_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) | 125 | static int i830_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) |
126 | { | 126 | { |
127 | struct drm_device *dev = file_priv->head->dev; | 127 | struct drm_device *dev = file_priv->minor->dev; |
128 | drm_i830_buf_priv_t *buf_priv = buf->dev_private; | 128 | drm_i830_buf_priv_t *buf_priv = buf->dev_private; |
129 | drm_i830_private_t *dev_priv = dev->dev_private; | 129 | drm_i830_private_t *dev_priv = dev->dev_private; |
130 | const struct file_operations *old_fops; | 130 | const struct file_operations *old_fops; |
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index a043bb12301a..ef7bf143a80c 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c | |||
@@ -415,10 +415,13 @@ static void i915_emit_breadcrumb(struct drm_device *dev) | |||
415 | drm_i915_private_t *dev_priv = dev->dev_private; | 415 | drm_i915_private_t *dev_priv = dev->dev_private; |
416 | RING_LOCALS; | 416 | RING_LOCALS; |
417 | 417 | ||
418 | dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; | 418 | if (++dev_priv->counter > BREADCRUMB_MASK) { |
419 | dev_priv->counter = 1; | ||
420 | DRM_DEBUG("Breadcrumb counter wrapped around\n"); | ||
421 | } | ||
419 | 422 | ||
420 | if (dev_priv->counter > 0x7FFFFFFFUL) | 423 | if (dev_priv->sarea_priv) |
421 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; | 424 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter; |
422 | 425 | ||
423 | BEGIN_LP_RING(4); | 426 | BEGIN_LP_RING(4); |
424 | OUT_RING(CMD_STORE_DWORD_IDX); | 427 | OUT_RING(CMD_STORE_DWORD_IDX); |
@@ -428,6 +431,26 @@ static void i915_emit_breadcrumb(struct drm_device *dev) | |||
428 | ADVANCE_LP_RING(); | 431 | ADVANCE_LP_RING(); |
429 | } | 432 | } |
430 | 433 | ||
434 | int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush) | ||
435 | { | ||
436 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
437 | uint32_t flush_cmd = CMD_MI_FLUSH; | ||
438 | RING_LOCALS; | ||
439 | |||
440 | flush_cmd |= flush; | ||
441 | |||
442 | i915_kernel_lost_context(dev); | ||
443 | |||
444 | BEGIN_LP_RING(4); | ||
445 | OUT_RING(flush_cmd); | ||
446 | OUT_RING(0); | ||
447 | OUT_RING(0); | ||
448 | OUT_RING(0); | ||
449 | ADVANCE_LP_RING(); | ||
450 | |||
451 | return 0; | ||
452 | } | ||
453 | |||
431 | static int i915_dispatch_cmdbuffer(struct drm_device * dev, | 454 | static int i915_dispatch_cmdbuffer(struct drm_device * dev, |
432 | drm_i915_cmdbuffer_t * cmd) | 455 | drm_i915_cmdbuffer_t * cmd) |
433 | { | 456 | { |
@@ -511,52 +534,74 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, | |||
511 | return 0; | 534 | return 0; |
512 | } | 535 | } |
513 | 536 | ||
514 | static int i915_dispatch_flip(struct drm_device * dev) | 537 | static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync) |
515 | { | 538 | { |
516 | drm_i915_private_t *dev_priv = dev->dev_private; | 539 | drm_i915_private_t *dev_priv = dev->dev_private; |
540 | u32 num_pages, current_page, next_page, dspbase; | ||
541 | int shift = 2 * plane, x, y; | ||
517 | RING_LOCALS; | 542 | RING_LOCALS; |
518 | 543 | ||
519 | DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", | 544 | /* Calculate display base offset */ |
520 | __FUNCTION__, | 545 | num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2; |
521 | dev_priv->current_page, | 546 | current_page = (dev_priv->sarea_priv->pf_current_page >> shift) & 0x3; |
522 | dev_priv->sarea_priv->pf_current_page); | 547 | next_page = (current_page + 1) % num_pages; |
523 | 548 | ||
524 | i915_kernel_lost_context(dev); | 549 | switch (next_page) { |
525 | 550 | default: | |
526 | BEGIN_LP_RING(2); | 551 | case 0: |
527 | OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); | 552 | dspbase = dev_priv->sarea_priv->front_offset; |
528 | OUT_RING(0); | 553 | break; |
529 | ADVANCE_LP_RING(); | 554 | case 1: |
555 | dspbase = dev_priv->sarea_priv->back_offset; | ||
556 | break; | ||
557 | case 2: | ||
558 | dspbase = dev_priv->sarea_priv->third_offset; | ||
559 | break; | ||
560 | } | ||
530 | 561 | ||
531 | BEGIN_LP_RING(6); | 562 | if (plane == 0) { |
532 | OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); | 563 | x = dev_priv->sarea_priv->planeA_x; |
533 | OUT_RING(0); | 564 | y = dev_priv->sarea_priv->planeA_y; |
534 | if (dev_priv->current_page == 0) { | ||
535 | OUT_RING(dev_priv->back_offset); | ||
536 | dev_priv->current_page = 1; | ||
537 | } else { | 565 | } else { |
538 | OUT_RING(dev_priv->front_offset); | 566 | x = dev_priv->sarea_priv->planeB_x; |
539 | dev_priv->current_page = 0; | 567 | y = dev_priv->sarea_priv->planeB_y; |
540 | } | 568 | } |
541 | OUT_RING(0); | ||
542 | ADVANCE_LP_RING(); | ||
543 | 569 | ||
544 | BEGIN_LP_RING(2); | 570 | dspbase += (y * dev_priv->sarea_priv->pitch + x) * dev_priv->cpp; |
545 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); | ||
546 | OUT_RING(0); | ||
547 | ADVANCE_LP_RING(); | ||
548 | 571 | ||
549 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; | 572 | DRM_DEBUG("plane=%d current_page=%d dspbase=0x%x\n", plane, current_page, |
573 | dspbase); | ||
550 | 574 | ||
551 | BEGIN_LP_RING(4); | 575 | BEGIN_LP_RING(4); |
552 | OUT_RING(CMD_STORE_DWORD_IDX); | 576 | OUT_RING(sync ? 0 : |
553 | OUT_RING(20); | 577 | (MI_WAIT_FOR_EVENT | (plane ? MI_WAIT_FOR_PLANE_B_FLIP : |
554 | OUT_RING(dev_priv->counter); | 578 | MI_WAIT_FOR_PLANE_A_FLIP))); |
555 | OUT_RING(0); | 579 | OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | (sync ? 0 : ASYNC_FLIP) | |
580 | (plane ? DISPLAY_PLANE_B : DISPLAY_PLANE_A)); | ||
581 | OUT_RING(dev_priv->sarea_priv->pitch * dev_priv->cpp); | ||
582 | OUT_RING(dspbase); | ||
556 | ADVANCE_LP_RING(); | 583 | ADVANCE_LP_RING(); |
557 | 584 | ||
558 | dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; | 585 | dev_priv->sarea_priv->pf_current_page &= ~(0x3 << shift); |
559 | return 0; | 586 | dev_priv->sarea_priv->pf_current_page |= next_page << shift; |
587 | } | ||
588 | |||
589 | void i915_dispatch_flip(struct drm_device * dev, int planes, int sync) | ||
590 | { | ||
591 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
592 | int i; | ||
593 | |||
594 | DRM_DEBUG("planes=0x%x pfCurrentPage=%d\n", | ||
595 | planes, dev_priv->sarea_priv->pf_current_page); | ||
596 | |||
597 | i915_emit_mi_flush(dev, MI_READ_FLUSH | MI_EXE_FLUSH); | ||
598 | |||
599 | for (i = 0; i < 2; i++) | ||
600 | if (planes & (1 << i)) | ||
601 | i915_do_dispatch_flip(dev, i, sync); | ||
602 | |||
603 | i915_emit_breadcrumb(dev); | ||
604 | |||
560 | } | 605 | } |
561 | 606 | ||
562 | static int i915_quiescent(struct drm_device * dev) | 607 | static int i915_quiescent(struct drm_device * dev) |
@@ -579,7 +624,6 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, | |||
579 | struct drm_file *file_priv) | 624 | struct drm_file *file_priv) |
580 | { | 625 | { |
581 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 626 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
582 | u32 *hw_status = dev_priv->hw_status_page; | ||
583 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) | 627 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) |
584 | dev_priv->sarea_priv; | 628 | dev_priv->sarea_priv; |
585 | drm_i915_batchbuffer_t *batch = data; | 629 | drm_i915_batchbuffer_t *batch = data; |
@@ -602,7 +646,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, | |||
602 | 646 | ||
603 | ret = i915_dispatch_batchbuffer(dev, batch); | 647 | ret = i915_dispatch_batchbuffer(dev, batch); |
604 | 648 | ||
605 | sarea_priv->last_dispatch = (int)hw_status[5]; | 649 | sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); |
606 | return ret; | 650 | return ret; |
607 | } | 651 | } |
608 | 652 | ||
@@ -610,7 +654,6 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
610 | struct drm_file *file_priv) | 654 | struct drm_file *file_priv) |
611 | { | 655 | { |
612 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 656 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
613 | u32 *hw_status = dev_priv->hw_status_page; | ||
614 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) | 657 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) |
615 | dev_priv->sarea_priv; | 658 | dev_priv->sarea_priv; |
616 | drm_i915_cmdbuffer_t *cmdbuf = data; | 659 | drm_i915_cmdbuffer_t *cmdbuf = data; |
@@ -635,18 +678,51 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
635 | return ret; | 678 | return ret; |
636 | } | 679 | } |
637 | 680 | ||
638 | sarea_priv->last_dispatch = (int)hw_status[5]; | 681 | sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); |
682 | return 0; | ||
683 | } | ||
684 | |||
685 | static int i915_do_cleanup_pageflip(struct drm_device * dev) | ||
686 | { | ||
687 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
688 | int i, planes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2; | ||
689 | |||
690 | DRM_DEBUG("\n"); | ||
691 | |||
692 | for (i = 0, planes = 0; i < 2; i++) | ||
693 | if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) { | ||
694 | dev_priv->sarea_priv->pf_current_page = | ||
695 | (dev_priv->sarea_priv->pf_current_page & | ||
696 | ~(0x3 << (2 * i))) | ((num_pages - 1) << (2 * i)); | ||
697 | |||
698 | planes |= 1 << i; | ||
699 | } | ||
700 | |||
701 | if (planes) | ||
702 | i915_dispatch_flip(dev, planes, 0); | ||
703 | |||
639 | return 0; | 704 | return 0; |
640 | } | 705 | } |
641 | 706 | ||
642 | static int i915_flip_bufs(struct drm_device *dev, void *data, | 707 | static int i915_flip_bufs(struct drm_device *dev, void *data, |
643 | struct drm_file *file_priv) | 708 | struct drm_file *file_priv) |
644 | { | 709 | { |
645 | DRM_DEBUG("%s\n", __FUNCTION__); | 710 | drm_i915_flip_t *param = data; |
711 | |||
712 | DRM_DEBUG("\n"); | ||
646 | 713 | ||
647 | LOCK_TEST_WITH_RETURN(dev, file_priv); | 714 | LOCK_TEST_WITH_RETURN(dev, file_priv); |
648 | 715 | ||
649 | return i915_dispatch_flip(dev); | 716 | /* This is really planes */ |
717 | if (param->pipes & ~0x3) { | ||
718 | DRM_ERROR("Invalid planes 0x%x, only <= 0x3 is valid\n", | ||
719 | param->pipes); | ||
720 | return -EINVAL; | ||
721 | } | ||
722 | |||
723 | i915_dispatch_flip(dev, param->pipes, 0); | ||
724 | |||
725 | return 0; | ||
650 | } | 726 | } |
651 | 727 | ||
652 | static int i915_getparam(struct drm_device *dev, void *data, | 728 | static int i915_getparam(struct drm_device *dev, void *data, |
@@ -807,6 +883,8 @@ void i915_driver_lastclose(struct drm_device * dev) | |||
807 | if (!dev_priv) | 883 | if (!dev_priv) |
808 | return; | 884 | return; |
809 | 885 | ||
886 | if (drm_getsarea(dev) && dev_priv->sarea_priv) | ||
887 | i915_do_cleanup_pageflip(dev); | ||
810 | if (dev_priv->agp_heap) | 888 | if (dev_priv->agp_heap) |
811 | i915_mem_takedown(&(dev_priv->agp_heap)); | 889 | i915_mem_takedown(&(dev_priv->agp_heap)); |
812 | 890 | ||
diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h index 05c66cf03a9e..0431c00e2289 100644 --- a/drivers/char/drm/i915_drm.h +++ b/drivers/char/drm/i915_drm.h | |||
@@ -105,14 +105,29 @@ typedef struct _drm_i915_sarea { | |||
105 | unsigned int rotated_tiled; | 105 | unsigned int rotated_tiled; |
106 | unsigned int rotated2_tiled; | 106 | unsigned int rotated2_tiled; |
107 | 107 | ||
108 | int pipeA_x; | 108 | int planeA_x; |
109 | int pipeA_y; | 109 | int planeA_y; |
110 | int pipeA_w; | 110 | int planeA_w; |
111 | int pipeA_h; | 111 | int planeA_h; |
112 | int pipeB_x; | 112 | int planeB_x; |
113 | int pipeB_y; | 113 | int planeB_y; |
114 | int pipeB_w; | 114 | int planeB_w; |
115 | int pipeB_h; | 115 | int planeB_h; |
116 | |||
117 | /* Triple buffering */ | ||
118 | drm_handle_t third_handle; | ||
119 | int third_offset; | ||
120 | int third_size; | ||
121 | unsigned int third_tiled; | ||
122 | |||
123 | /* buffer object handles for the static buffers. May change | ||
124 | * over the lifetime of the client, though it doesn't in our current | ||
125 | * implementation. | ||
126 | */ | ||
127 | unsigned int front_bo_handle; | ||
128 | unsigned int back_bo_handle; | ||
129 | unsigned int third_bo_handle; | ||
130 | unsigned int depth_bo_handle; | ||
116 | } drm_i915_sarea_t; | 131 | } drm_i915_sarea_t; |
117 | 132 | ||
118 | /* Flags for perf_boxes | 133 | /* Flags for perf_boxes |
@@ -146,7 +161,7 @@ typedef struct _drm_i915_sarea { | |||
146 | 161 | ||
147 | #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) | 162 | #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) |
148 | #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) | 163 | #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) |
149 | #define DRM_IOCTL_I915_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLIP) | 164 | #define DRM_IOCTL_I915_FLIP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FLIP, drm_i915_flip_t) |
150 | #define DRM_IOCTL_I915_BATCHBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t) | 165 | #define DRM_IOCTL_I915_BATCHBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t) |
151 | #define DRM_IOCTL_I915_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t) | 166 | #define DRM_IOCTL_I915_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t) |
152 | #define DRM_IOCTL_I915_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t) | 167 | #define DRM_IOCTL_I915_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t) |
@@ -161,6 +176,18 @@ typedef struct _drm_i915_sarea { | |||
161 | #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) | 176 | #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) |
162 | #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) | 177 | #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) |
163 | 178 | ||
179 | /* Asynchronous page flipping: | ||
180 | */ | ||
181 | typedef struct drm_i915_flip { | ||
182 | /* | ||
183 | * This is really talking about planes, and we could rename it | ||
184 | * except for the fact that some of the duplicated i915_drm.h files | ||
185 | * out there check for HAVE_I915_FLIP and so might pick up this | ||
186 | * version. | ||
187 | */ | ||
188 | int pipes; | ||
189 | } drm_i915_flip_t; | ||
190 | |||
164 | /* Allow drivers to submit batchbuffers directly to hardware, relying | 191 | /* Allow drivers to submit batchbuffers directly to hardware, relying |
165 | * on the security mechanisms provided by hardware. | 192 | * on the security mechanisms provided by hardware. |
166 | */ | 193 | */ |
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c index b2b451dc4460..bb8f1b2fb383 100644 --- a/drivers/char/drm/i915_drv.c +++ b/drivers/char/drm/i915_drv.c | |||
@@ -533,8 +533,7 @@ static struct drm_driver driver = { | |||
533 | */ | 533 | */ |
534 | .driver_features = | 534 | .driver_features = |
535 | DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ | 535 | DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ |
536 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL | | 536 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, |
537 | DRIVER_IRQ_VBL2, | ||
538 | .load = i915_driver_load, | 537 | .load = i915_driver_load, |
539 | .unload = i915_driver_unload, | 538 | .unload = i915_driver_unload, |
540 | .lastclose = i915_driver_lastclose, | 539 | .lastclose = i915_driver_lastclose, |
@@ -542,8 +541,9 @@ static struct drm_driver driver = { | |||
542 | .suspend = i915_suspend, | 541 | .suspend = i915_suspend, |
543 | .resume = i915_resume, | 542 | .resume = i915_resume, |
544 | .device_is_agp = i915_driver_device_is_agp, | 543 | .device_is_agp = i915_driver_device_is_agp, |
545 | .vblank_wait = i915_driver_vblank_wait, | 544 | .get_vblank_counter = i915_get_vblank_counter, |
546 | .vblank_wait2 = i915_driver_vblank_wait2, | 545 | .enable_vblank = i915_enable_vblank, |
546 | .disable_vblank = i915_disable_vblank, | ||
547 | .irq_preinstall = i915_driver_irq_preinstall, | 547 | .irq_preinstall = i915_driver_irq_preinstall, |
548 | .irq_postinstall = i915_driver_irq_postinstall, | 548 | .irq_postinstall = i915_driver_irq_postinstall, |
549 | .irq_uninstall = i915_driver_irq_uninstall, | 549 | .irq_uninstall = i915_driver_irq_uninstall, |
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index 675d88bda066..c614d78b3dfd 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h | |||
@@ -76,8 +76,9 @@ struct mem_block { | |||
76 | typedef struct _drm_i915_vbl_swap { | 76 | typedef struct _drm_i915_vbl_swap { |
77 | struct list_head head; | 77 | struct list_head head; |
78 | drm_drawable_t drw_id; | 78 | drm_drawable_t drw_id; |
79 | unsigned int pipe; | 79 | unsigned int plane; |
80 | unsigned int sequence; | 80 | unsigned int sequence; |
81 | int flip; | ||
81 | } drm_i915_vbl_swap_t; | 82 | } drm_i915_vbl_swap_t; |
82 | 83 | ||
83 | typedef struct drm_i915_private { | 84 | typedef struct drm_i915_private { |
@@ -90,7 +91,7 @@ typedef struct drm_i915_private { | |||
90 | drm_dma_handle_t *status_page_dmah; | 91 | drm_dma_handle_t *status_page_dmah; |
91 | void *hw_status_page; | 92 | void *hw_status_page; |
92 | dma_addr_t dma_status_page; | 93 | dma_addr_t dma_status_page; |
93 | unsigned long counter; | 94 | uint32_t counter; |
94 | unsigned int status_gfx_addr; | 95 | unsigned int status_gfx_addr; |
95 | drm_local_map_t hws_map; | 96 | drm_local_map_t hws_map; |
96 | 97 | ||
@@ -103,13 +104,18 @@ typedef struct drm_i915_private { | |||
103 | 104 | ||
104 | wait_queue_head_t irq_queue; | 105 | wait_queue_head_t irq_queue; |
105 | atomic_t irq_received; | 106 | atomic_t irq_received; |
106 | atomic_t irq_emitted; | 107 | atomic_t irq_emited; |
107 | 108 | ||
108 | int tex_lru_log_granularity; | 109 | int tex_lru_log_granularity; |
109 | int allow_batchbuffer; | 110 | int allow_batchbuffer; |
110 | struct mem_block *agp_heap; | 111 | struct mem_block *agp_heap; |
111 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; | 112 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; |
112 | int vblank_pipe; | 113 | int vblank_pipe; |
114 | spinlock_t user_irq_lock; | ||
115 | int user_irq_refcount; | ||
116 | int fence_irq_on; | ||
117 | uint32_t irq_enable_reg; | ||
118 | int irq_enabled; | ||
113 | 119 | ||
114 | spinlock_t swaps_lock; | 120 | spinlock_t swaps_lock; |
115 | drm_i915_vbl_swap_t vbl_swaps; | 121 | drm_i915_vbl_swap_t vbl_swaps; |
@@ -216,7 +222,7 @@ extern void i915_driver_preclose(struct drm_device *dev, | |||
216 | extern int i915_driver_device_is_agp(struct drm_device * dev); | 222 | extern int i915_driver_device_is_agp(struct drm_device * dev); |
217 | extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, | 223 | extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, |
218 | unsigned long arg); | 224 | unsigned long arg); |
219 | 225 | extern void i915_dispatch_flip(struct drm_device * dev, int pipes, int sync); | |
220 | /* i915_irq.c */ | 226 | /* i915_irq.c */ |
221 | extern int i915_irq_emit(struct drm_device *dev, void *data, | 227 | extern int i915_irq_emit(struct drm_device *dev, void *data, |
222 | struct drm_file *file_priv); | 228 | struct drm_file *file_priv); |
@@ -227,7 +233,7 @@ extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequenc | |||
227 | extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence); | 233 | extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence); |
228 | extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); | 234 | extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); |
229 | extern void i915_driver_irq_preinstall(struct drm_device * dev); | 235 | extern void i915_driver_irq_preinstall(struct drm_device * dev); |
230 | extern void i915_driver_irq_postinstall(struct drm_device * dev); | 236 | extern int i915_driver_irq_postinstall(struct drm_device * dev); |
231 | extern void i915_driver_irq_uninstall(struct drm_device * dev); | 237 | extern void i915_driver_irq_uninstall(struct drm_device * dev); |
232 | extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, | 238 | extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, |
233 | struct drm_file *file_priv); | 239 | struct drm_file *file_priv); |
@@ -235,6 +241,9 @@ extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, | |||
235 | struct drm_file *file_priv); | 241 | struct drm_file *file_priv); |
236 | extern int i915_vblank_swap(struct drm_device *dev, void *data, | 242 | extern int i915_vblank_swap(struct drm_device *dev, void *data, |
237 | struct drm_file *file_priv); | 243 | struct drm_file *file_priv); |
244 | extern int i915_enable_vblank(struct drm_device *dev, int crtc); | ||
245 | extern void i915_disable_vblank(struct drm_device *dev, int crtc); | ||
246 | extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc); | ||
238 | 247 | ||
239 | /* i915_mem.c */ | 248 | /* i915_mem.c */ |
240 | extern int i915_mem_alloc(struct drm_device *dev, void *data, | 249 | extern int i915_mem_alloc(struct drm_device *dev, void *data, |
@@ -379,21 +388,91 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
379 | 388 | ||
380 | /* Interrupt bits: | 389 | /* Interrupt bits: |
381 | */ | 390 | */ |
382 | #define USER_INT_FLAG (1<<1) | 391 | #define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18) |
383 | #define VSYNC_PIPEB_FLAG (1<<5) | 392 | #define I915_DISPLAY_PORT_INTERRUPT (1<<17) |
384 | #define VSYNC_PIPEA_FLAG (1<<7) | 393 | #define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15) |
385 | #define HWB_OOM_FLAG (1<<13) /* binner out of memory */ | 394 | #define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14) |
395 | #define I915_HWB_OOM_INTERRUPT (1<<13) /* binner out of memory */ | ||
396 | #define I915_SYNC_STATUS_INTERRUPT (1<<12) | ||
397 | #define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11) | ||
398 | #define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10) | ||
399 | #define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9) | ||
400 | #define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8) | ||
401 | #define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7) | ||
402 | #define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6) | ||
403 | #define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5) | ||
404 | #define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4) | ||
405 | #define I915_DEBUG_INTERRUPT (1<<2) | ||
406 | #define I915_USER_INTERRUPT (1<<1) | ||
407 | |||
386 | 408 | ||
387 | #define I915REG_HWSTAM 0x02098 | 409 | #define I915REG_HWSTAM 0x02098 |
388 | #define I915REG_INT_IDENTITY_R 0x020a4 | 410 | #define I915REG_INT_IDENTITY_R 0x020a4 |
389 | #define I915REG_INT_MASK_R 0x020a8 | 411 | #define I915REG_INT_MASK_R 0x020a8 |
390 | #define I915REG_INT_ENABLE_R 0x020a0 | 412 | #define I915REG_INT_ENABLE_R 0x020a0 |
413 | #define I915REG_INSTPM 0x020c0 | ||
414 | |||
415 | #define PIPEADSL 0x70000 | ||
416 | #define PIPEBDSL 0x71000 | ||
391 | 417 | ||
392 | #define I915REG_PIPEASTAT 0x70024 | 418 | #define I915REG_PIPEASTAT 0x70024 |
393 | #define I915REG_PIPEBSTAT 0x71024 | 419 | #define I915REG_PIPEBSTAT 0x71024 |
420 | /* | ||
421 | * The two pipe frame counter registers are not synchronized, so | ||
422 | * reading a stable value is somewhat tricky. The following code | ||
423 | * should work: | ||
424 | * | ||
425 | * do { | ||
426 | * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> | ||
427 | * PIPE_FRAME_HIGH_SHIFT; | ||
428 | * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >> | ||
429 | * PIPE_FRAME_LOW_SHIFT); | ||
430 | * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> | ||
431 | * PIPE_FRAME_HIGH_SHIFT); | ||
432 | * } while (high1 != high2); | ||
433 | * frame = (high1 << 8) | low1; | ||
434 | */ | ||
435 | #define PIPEAFRAMEHIGH 0x70040 | ||
436 | #define PIPEBFRAMEHIGH 0x71040 | ||
437 | #define PIPE_FRAME_HIGH_MASK 0x0000ffff | ||
438 | #define PIPE_FRAME_HIGH_SHIFT 0 | ||
439 | #define PIPEAFRAMEPIXEL 0x70044 | ||
440 | #define PIPEBFRAMEPIXEL 0x71044 | ||
394 | 441 | ||
395 | #define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) | 442 | #define PIPE_FRAME_LOW_MASK 0xff000000 |
396 | #define I915_VBLANK_CLEAR (1UL<<1) | 443 | #define PIPE_FRAME_LOW_SHIFT 24 |
444 | /* | ||
445 | * Pixel within the current frame is counted in the PIPEAFRAMEPIXEL register | ||
446 | * and is 24 bits wide. | ||
447 | */ | ||
448 | #define PIPE_PIXEL_MASK 0x00ffffff | ||
449 | #define PIPE_PIXEL_SHIFT 0 | ||
450 | |||
451 | #define I915_FIFO_UNDERRUN_STATUS (1UL<<31) | ||
452 | #define I915_CRC_ERROR_ENABLE (1UL<<29) | ||
453 | #define I915_CRC_DONE_ENABLE (1UL<<28) | ||
454 | #define I915_GMBUS_EVENT_ENABLE (1UL<<27) | ||
455 | #define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25) | ||
456 | #define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24) | ||
457 | #define I915_DPST_EVENT_ENABLE (1UL<<23) | ||
458 | #define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22) | ||
459 | #define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21) | ||
460 | #define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20) | ||
461 | #define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */ | ||
462 | #define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) | ||
463 | #define I915_OVERLAY_UPDATED_ENABLE (1UL<<16) | ||
464 | #define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13) | ||
465 | #define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12) | ||
466 | #define I915_GMBUS_INTERRUPT_STATUS (1UL<<11) | ||
467 | #define I915_VSYNC_INTERRUPT_STATUS (1UL<<9) | ||
468 | #define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8) | ||
469 | #define I915_DPST_EVENT_STATUS (1UL<<7) | ||
470 | #define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6) | ||
471 | #define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5) | ||
472 | #define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4) | ||
473 | #define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ | ||
474 | #define I915_VBLANK_INTERRUPT_STATUS (1UL<<1) | ||
475 | #define I915_OVERLAY_UPDATED_STATUS (1UL<<0) | ||
397 | 476 | ||
398 | #define SRX_INDEX 0x3c4 | 477 | #define SRX_INDEX 0x3c4 |
399 | #define SRX_DATA 0x3c5 | 478 | #define SRX_DATA 0x3c5 |
@@ -566,6 +645,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
566 | #define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) | 645 | #define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) |
567 | #define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) | 646 | #define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) |
568 | #define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) | 647 | #define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) |
648 | #define XY_SRC_COPY_BLT_SRC_TILED (1<<15) | ||
649 | #define XY_SRC_COPY_BLT_DST_TILED (1<<11) | ||
569 | 650 | ||
570 | #define MI_BATCH_BUFFER ((0x30<<23)|1) | 651 | #define MI_BATCH_BUFFER ((0x30<<23)|1) |
571 | #define MI_BATCH_BUFFER_START (0x31<<23) | 652 | #define MI_BATCH_BUFFER_START (0x31<<23) |
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c index 92653b38e64c..023ce66ef3ab 100644 --- a/drivers/char/drm/i915_irq.c +++ b/drivers/char/drm/i915_irq.c | |||
@@ -38,6 +38,109 @@ | |||
38 | #define MAX_NOPID ((u32)~0) | 38 | #define MAX_NOPID ((u32)~0) |
39 | 39 | ||
40 | /** | 40 | /** |
41 | * i915_get_pipe - return the the pipe associated with a given plane | ||
42 | * @dev: DRM device | ||
43 | * @plane: plane to look for | ||
44 | * | ||
45 | * The Intel Mesa & 2D drivers call the vblank routines with a plane number | ||
46 | * rather than a pipe number, since they may not always be equal. This routine | ||
47 | * maps the given @plane back to a pipe number. | ||
48 | */ | ||
49 | static int | ||
50 | i915_get_pipe(struct drm_device *dev, int plane) | ||
51 | { | ||
52 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
53 | u32 dspcntr; | ||
54 | |||
55 | dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR); | ||
56 | |||
57 | return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0; | ||
58 | } | ||
59 | |||
60 | /** | ||
61 | * i915_get_plane - return the the plane associated with a given pipe | ||
62 | * @dev: DRM device | ||
63 | * @pipe: pipe to look for | ||
64 | * | ||
65 | * The Intel Mesa & 2D drivers call the vblank routines with a plane number | ||
66 | * rather than a plane number, since they may not always be equal. This routine | ||
67 | * maps the given @pipe back to a plane number. | ||
68 | */ | ||
69 | static int | ||
70 | i915_get_plane(struct drm_device *dev, int pipe) | ||
71 | { | ||
72 | if (i915_get_pipe(dev, 0) == pipe) | ||
73 | return 0; | ||
74 | return 1; | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * i915_pipe_enabled - check if a pipe is enabled | ||
79 | * @dev: DRM device | ||
80 | * @pipe: pipe to check | ||
81 | * | ||
82 | * Reading certain registers when the pipe is disabled can hang the chip. | ||
83 | * Use this routine to make sure the PLL is running and the pipe is active | ||
84 | * before reading such registers if unsure. | ||
85 | */ | ||
86 | static int | ||
87 | i915_pipe_enabled(struct drm_device *dev, int pipe) | ||
88 | { | ||
89 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
90 | unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF; | ||
91 | |||
92 | if (I915_READ(pipeconf) & PIPEACONF_ENABLE) | ||
93 | return 1; | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | /** | ||
99 | * Emit a synchronous flip. | ||
100 | * | ||
101 | * This function must be called with the drawable spinlock held. | ||
102 | */ | ||
103 | static void | ||
104 | i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw, | ||
105 | int plane) | ||
106 | { | ||
107 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
108 | drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; | ||
109 | u16 x1, y1, x2, y2; | ||
110 | int pf_planes = 1 << plane; | ||
111 | |||
112 | /* If the window is visible on the other plane, we have to flip on that | ||
113 | * plane as well. | ||
114 | */ | ||
115 | if (plane == 1) { | ||
116 | x1 = sarea_priv->planeA_x; | ||
117 | y1 = sarea_priv->planeA_y; | ||
118 | x2 = x1 + sarea_priv->planeA_w; | ||
119 | y2 = y1 + sarea_priv->planeA_h; | ||
120 | } else { | ||
121 | x1 = sarea_priv->planeB_x; | ||
122 | y1 = sarea_priv->planeB_y; | ||
123 | x2 = x1 + sarea_priv->planeB_w; | ||
124 | y2 = y1 + sarea_priv->planeB_h; | ||
125 | } | ||
126 | |||
127 | if (x2 > 0 && y2 > 0) { | ||
128 | int i, num_rects = drw->num_rects; | ||
129 | struct drm_clip_rect *rect = drw->rects; | ||
130 | |||
131 | for (i = 0; i < num_rects; i++) | ||
132 | if (!(rect[i].x1 >= x2 || rect[i].y1 >= y2 || | ||
133 | rect[i].x2 <= x1 || rect[i].y2 <= y1)) { | ||
134 | pf_planes = 0x3; | ||
135 | |||
136 | break; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | i915_dispatch_flip(dev, pf_planes, 1); | ||
141 | } | ||
142 | |||
143 | /** | ||
41 | * Emit blits for scheduled buffer swaps. | 144 | * Emit blits for scheduled buffer swaps. |
42 | * | 145 | * |
43 | * This function will be called with the HW lock held. | 146 | * This function will be called with the HW lock held. |
@@ -45,40 +148,59 @@ | |||
45 | static void i915_vblank_tasklet(struct drm_device *dev) | 148 | static void i915_vblank_tasklet(struct drm_device *dev) |
46 | { | 149 | { |
47 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 150 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
48 | unsigned long irqflags; | ||
49 | struct list_head *list, *tmp, hits, *hit; | 151 | struct list_head *list, *tmp, hits, *hit; |
50 | int nhits, nrects, slice[2], upper[2], lower[2], i; | 152 | int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages; |
51 | unsigned counter[2] = { atomic_read(&dev->vbl_received), | 153 | unsigned counter[2]; |
52 | atomic_read(&dev->vbl_received2) }; | ||
53 | struct drm_drawable_info *drw; | 154 | struct drm_drawable_info *drw; |
54 | drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; | 155 | drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; |
55 | u32 cpp = dev_priv->cpp; | 156 | u32 cpp = dev_priv->cpp, offsets[3]; |
56 | u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | | 157 | u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | |
57 | XY_SRC_COPY_BLT_WRITE_ALPHA | | 158 | XY_SRC_COPY_BLT_WRITE_ALPHA | |
58 | XY_SRC_COPY_BLT_WRITE_RGB) | 159 | XY_SRC_COPY_BLT_WRITE_RGB) |
59 | : XY_SRC_COPY_BLT_CMD; | 160 | : XY_SRC_COPY_BLT_CMD; |
60 | u32 pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) | | 161 | u32 src_pitch = sarea_priv->pitch * cpp; |
61 | (cpp << 23) | (1 << 24); | 162 | u32 dst_pitch = sarea_priv->pitch * cpp; |
163 | /* COPY rop (0xcc), map cpp to magic color depth constants */ | ||
164 | u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24); | ||
62 | RING_LOCALS; | 165 | RING_LOCALS; |
63 | 166 | ||
167 | if (sarea_priv->front_tiled) { | ||
168 | cmd |= XY_SRC_COPY_BLT_DST_TILED; | ||
169 | dst_pitch >>= 2; | ||
170 | } | ||
171 | if (sarea_priv->back_tiled) { | ||
172 | cmd |= XY_SRC_COPY_BLT_SRC_TILED; | ||
173 | src_pitch >>= 2; | ||
174 | } | ||
175 | |||
176 | counter[0] = drm_vblank_count(dev, 0); | ||
177 | counter[1] = drm_vblank_count(dev, 1); | ||
178 | |||
64 | DRM_DEBUG("\n"); | 179 | DRM_DEBUG("\n"); |
65 | 180 | ||
66 | INIT_LIST_HEAD(&hits); | 181 | INIT_LIST_HEAD(&hits); |
67 | 182 | ||
68 | nhits = nrects = 0; | 183 | nhits = nrects = 0; |
69 | 184 | ||
70 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); | 185 | /* No irqsave/restore necessary. This tasklet may be run in an |
186 | * interrupt context or normal context, but we don't have to worry | ||
187 | * about getting interrupted by something acquiring the lock, because | ||
188 | * we are the interrupt context thing that acquires the lock. | ||
189 | */ | ||
190 | spin_lock(&dev_priv->swaps_lock); | ||
71 | 191 | ||
72 | /* Find buffer swaps scheduled for this vertical blank */ | 192 | /* Find buffer swaps scheduled for this vertical blank */ |
73 | list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { | 193 | list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { |
74 | drm_i915_vbl_swap_t *vbl_swap = | 194 | drm_i915_vbl_swap_t *vbl_swap = |
75 | list_entry(list, drm_i915_vbl_swap_t, head); | 195 | list_entry(list, drm_i915_vbl_swap_t, head); |
196 | int pipe = i915_get_pipe(dev, vbl_swap->plane); | ||
76 | 197 | ||
77 | if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23)) | 198 | if ((counter[pipe] - vbl_swap->sequence) > (1<<23)) |
78 | continue; | 199 | continue; |
79 | 200 | ||
80 | list_del(list); | 201 | list_del(list); |
81 | dev_priv->swaps_pending--; | 202 | dev_priv->swaps_pending--; |
203 | drm_vblank_put(dev, pipe); | ||
82 | 204 | ||
83 | spin_unlock(&dev_priv->swaps_lock); | 205 | spin_unlock(&dev_priv->swaps_lock); |
84 | spin_lock(&dev->drw_lock); | 206 | spin_lock(&dev->drw_lock); |
@@ -116,33 +238,23 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
116 | spin_lock(&dev_priv->swaps_lock); | 238 | spin_lock(&dev_priv->swaps_lock); |
117 | } | 239 | } |
118 | 240 | ||
119 | if (nhits == 0) { | ||
120 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); | ||
121 | return; | ||
122 | } | ||
123 | |||
124 | spin_unlock(&dev_priv->swaps_lock); | 241 | spin_unlock(&dev_priv->swaps_lock); |
125 | 242 | ||
126 | i915_kernel_lost_context(dev); | 243 | if (nhits == 0) |
127 | 244 | return; | |
128 | BEGIN_LP_RING(6); | ||
129 | |||
130 | OUT_RING(GFX_OP_DRAWRECT_INFO); | ||
131 | OUT_RING(0); | ||
132 | OUT_RING(0); | ||
133 | OUT_RING(sarea_priv->width | sarea_priv->height << 16); | ||
134 | OUT_RING(sarea_priv->width | sarea_priv->height << 16); | ||
135 | OUT_RING(0); | ||
136 | |||
137 | ADVANCE_LP_RING(); | ||
138 | 245 | ||
139 | sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT; | 246 | i915_kernel_lost_context(dev); |
140 | 247 | ||
141 | upper[0] = upper[1] = 0; | 248 | upper[0] = upper[1] = 0; |
142 | slice[0] = max(sarea_priv->pipeA_h / nhits, 1); | 249 | slice[0] = max(sarea_priv->planeA_h / nhits, 1); |
143 | slice[1] = max(sarea_priv->pipeB_h / nhits, 1); | 250 | slice[1] = max(sarea_priv->planeB_h / nhits, 1); |
144 | lower[0] = sarea_priv->pipeA_y + slice[0]; | 251 | lower[0] = sarea_priv->planeA_y + slice[0]; |
145 | lower[1] = sarea_priv->pipeB_y + slice[0]; | 252 | lower[1] = sarea_priv->planeB_y + slice[0]; |
253 | |||
254 | offsets[0] = sarea_priv->front_offset; | ||
255 | offsets[1] = sarea_priv->back_offset; | ||
256 | offsets[2] = sarea_priv->third_offset; | ||
257 | num_pages = sarea_priv->third_handle ? 3 : 2; | ||
146 | 258 | ||
147 | spin_lock(&dev->drw_lock); | 259 | spin_lock(&dev->drw_lock); |
148 | 260 | ||
@@ -154,6 +266,8 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
154 | for (i = 0; i++ < nhits; | 266 | for (i = 0; i++ < nhits; |
155 | upper[0] = lower[0], lower[0] += slice[0], | 267 | upper[0] = lower[0], lower[0] += slice[0], |
156 | upper[1] = lower[1], lower[1] += slice[1]) { | 268 | upper[1] = lower[1], lower[1] += slice[1]) { |
269 | int init_drawrect = 1; | ||
270 | |||
157 | if (i == nhits) | 271 | if (i == nhits) |
158 | lower[0] = lower[1] = sarea_priv->height; | 272 | lower[0] = lower[1] = sarea_priv->height; |
159 | 273 | ||
@@ -161,7 +275,7 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
161 | drm_i915_vbl_swap_t *swap_hit = | 275 | drm_i915_vbl_swap_t *swap_hit = |
162 | list_entry(hit, drm_i915_vbl_swap_t, head); | 276 | list_entry(hit, drm_i915_vbl_swap_t, head); |
163 | struct drm_clip_rect *rect; | 277 | struct drm_clip_rect *rect; |
164 | int num_rects, pipe; | 278 | int num_rects, plane, front, back; |
165 | unsigned short top, bottom; | 279 | unsigned short top, bottom; |
166 | 280 | ||
167 | drw = drm_get_drawable_info(dev, swap_hit->drw_id); | 281 | drw = drm_get_drawable_info(dev, swap_hit->drw_id); |
@@ -169,10 +283,50 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
169 | if (!drw) | 283 | if (!drw) |
170 | continue; | 284 | continue; |
171 | 285 | ||
286 | plane = swap_hit->plane; | ||
287 | |||
288 | if (swap_hit->flip) { | ||
289 | i915_dispatch_vsync_flip(dev, drw, plane); | ||
290 | continue; | ||
291 | } | ||
292 | |||
293 | if (init_drawrect) { | ||
294 | int width = sarea_priv->width; | ||
295 | int height = sarea_priv->height; | ||
296 | if (IS_I965G(dev)) { | ||
297 | BEGIN_LP_RING(4); | ||
298 | |||
299 | OUT_RING(GFX_OP_DRAWRECT_INFO_I965); | ||
300 | OUT_RING(0); | ||
301 | OUT_RING(((width - 1) & 0xffff) | ((height - 1) << 16)); | ||
302 | OUT_RING(0); | ||
303 | |||
304 | ADVANCE_LP_RING(); | ||
305 | } else { | ||
306 | BEGIN_LP_RING(6); | ||
307 | |||
308 | OUT_RING(GFX_OP_DRAWRECT_INFO); | ||
309 | OUT_RING(0); | ||
310 | OUT_RING(0); | ||
311 | OUT_RING(((width - 1) & 0xffff) | ((height - 1) << 16)); | ||
312 | OUT_RING(0); | ||
313 | OUT_RING(0); | ||
314 | |||
315 | ADVANCE_LP_RING(); | ||
316 | } | ||
317 | |||
318 | sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT; | ||
319 | |||
320 | init_drawrect = 0; | ||
321 | } | ||
322 | |||
172 | rect = drw->rects; | 323 | rect = drw->rects; |
173 | pipe = swap_hit->pipe; | 324 | top = upper[plane]; |
174 | top = upper[pipe]; | 325 | bottom = lower[plane]; |
175 | bottom = lower[pipe]; | 326 | |
327 | front = (dev_priv->sarea_priv->pf_current_page >> | ||
328 | (2 * plane)) & 0x3; | ||
329 | back = (front + 1) % num_pages; | ||
176 | 330 | ||
177 | for (num_rects = drw->num_rects; num_rects--; rect++) { | 331 | for (num_rects = drw->num_rects; num_rects--; rect++) { |
178 | int y1 = max(rect->y1, top); | 332 | int y1 = max(rect->y1, top); |
@@ -184,20 +338,20 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
184 | BEGIN_LP_RING(8); | 338 | BEGIN_LP_RING(8); |
185 | 339 | ||
186 | OUT_RING(cmd); | 340 | OUT_RING(cmd); |
187 | OUT_RING(pitchropcpp); | 341 | OUT_RING(ropcpp | dst_pitch); |
188 | OUT_RING((y1 << 16) | rect->x1); | 342 | OUT_RING((y1 << 16) | rect->x1); |
189 | OUT_RING((y2 << 16) | rect->x2); | 343 | OUT_RING((y2 << 16) | rect->x2); |
190 | OUT_RING(sarea_priv->front_offset); | 344 | OUT_RING(offsets[front]); |
191 | OUT_RING((y1 << 16) | rect->x1); | 345 | OUT_RING((y1 << 16) | rect->x1); |
192 | OUT_RING(pitchropcpp & 0xffff); | 346 | OUT_RING(src_pitch); |
193 | OUT_RING(sarea_priv->back_offset); | 347 | OUT_RING(offsets[back]); |
194 | 348 | ||
195 | ADVANCE_LP_RING(); | 349 | ADVANCE_LP_RING(); |
196 | } | 350 | } |
197 | } | 351 | } |
198 | } | 352 | } |
199 | 353 | ||
200 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | 354 | spin_unlock(&dev->drw_lock); |
201 | 355 | ||
202 | list_for_each_safe(hit, tmp, &hits) { | 356 | list_for_each_safe(hit, tmp, &hits) { |
203 | drm_i915_vbl_swap_t *swap_hit = | 357 | drm_i915_vbl_swap_t *swap_hit = |
@@ -209,67 +363,112 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
209 | } | 363 | } |
210 | } | 364 | } |
211 | 365 | ||
366 | u32 i915_get_vblank_counter(struct drm_device *dev, int plane) | ||
367 | { | ||
368 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
369 | unsigned long high_frame; | ||
370 | unsigned long low_frame; | ||
371 | u32 high1, high2, low, count; | ||
372 | int pipe; | ||
373 | |||
374 | pipe = i915_get_pipe(dev, plane); | ||
375 | high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH; | ||
376 | low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; | ||
377 | |||
378 | if (!i915_pipe_enabled(dev, pipe)) { | ||
379 | printk(KERN_ERR "trying to get vblank count for disabled " | ||
380 | "pipe %d\n", pipe); | ||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | /* | ||
385 | * High & low register fields aren't synchronized, so make sure | ||
386 | * we get a low value that's stable across two reads of the high | ||
387 | * register. | ||
388 | */ | ||
389 | do { | ||
390 | high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> | ||
391 | PIPE_FRAME_HIGH_SHIFT); | ||
392 | low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >> | ||
393 | PIPE_FRAME_LOW_SHIFT); | ||
394 | high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> | ||
395 | PIPE_FRAME_HIGH_SHIFT); | ||
396 | } while (high1 != high2); | ||
397 | |||
398 | count = (high1 << 8) | low; | ||
399 | |||
400 | /* count may be reset by other driver(e.g. 2D driver), | ||
401 | we have no way to know if it is wrapped or resetted | ||
402 | when count is zero. do a rough guess. | ||
403 | */ | ||
404 | if (count == 0 && dev->last_vblank[pipe] < dev->max_vblank_count/2) | ||
405 | dev->last_vblank[pipe] = 0; | ||
406 | |||
407 | return count; | ||
408 | } | ||
409 | |||
212 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | 410 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) |
213 | { | 411 | { |
214 | struct drm_device *dev = (struct drm_device *) arg; | 412 | struct drm_device *dev = (struct drm_device *) arg; |
215 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 413 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
216 | u16 temp; | 414 | u32 iir; |
217 | u32 pipea_stats, pipeb_stats; | 415 | u32 pipea_stats, pipeb_stats; |
218 | 416 | int vblank = 0; | |
219 | pipea_stats = I915_READ(I915REG_PIPEASTAT); | 417 | |
220 | pipeb_stats = I915_READ(I915REG_PIPEBSTAT); | 418 | iir = I915_READ(I915REG_INT_IDENTITY_R); |
221 | 419 | if (iir == 0) { | |
222 | temp = I915_READ16(I915REG_INT_IDENTITY_R); | 420 | DRM_DEBUG ("iir 0x%08x im 0x%08x ie 0x%08x pipea 0x%08x pipeb 0x%08x\n", |
223 | 421 | iir, | |
224 | temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG); | 422 | I915_READ(I915REG_INT_MASK_R), |
225 | 423 | I915_READ(I915REG_INT_ENABLE_R), | |
226 | DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp); | 424 | I915_READ(I915REG_PIPEASTAT), |
227 | 425 | I915_READ(I915REG_PIPEBSTAT)); | |
228 | if (temp == 0) | ||
229 | return IRQ_NONE; | 426 | return IRQ_NONE; |
427 | } | ||
230 | 428 | ||
231 | I915_WRITE16(I915REG_INT_IDENTITY_R, temp); | 429 | /* |
232 | (void) I915_READ16(I915REG_INT_IDENTITY_R); | 430 | * Clear the PIPE(A|B)STAT regs before the IIR otherwise |
233 | DRM_READMEMORYBARRIER(); | 431 | * we may get extra interrupts. |
234 | 432 | */ | |
235 | dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); | 433 | if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) { |
434 | pipea_stats = I915_READ(I915REG_PIPEASTAT); | ||
435 | if (pipea_stats & (I915_START_VBLANK_INTERRUPT_STATUS| | ||
436 | I915_VBLANK_INTERRUPT_STATUS)) | ||
437 | { | ||
438 | vblank++; | ||
439 | drm_handle_vblank(dev, i915_get_plane(dev, 0)); | ||
440 | } | ||
441 | I915_WRITE(I915REG_PIPEASTAT, pipea_stats); | ||
442 | } | ||
443 | if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) { | ||
444 | pipeb_stats = I915_READ(I915REG_PIPEBSTAT); | ||
445 | if (pipeb_stats & (I915_START_VBLANK_INTERRUPT_STATUS| | ||
446 | I915_VBLANK_INTERRUPT_STATUS)) | ||
447 | { | ||
448 | vblank++; | ||
449 | drm_handle_vblank(dev, i915_get_plane(dev, 1)); | ||
450 | } | ||
451 | I915_WRITE(I915REG_PIPEBSTAT, pipeb_stats); | ||
452 | } | ||
236 | 453 | ||
237 | if (temp & USER_INT_FLAG) | 454 | if (dev_priv->sarea_priv) |
238 | DRM_WAKEUP(&dev_priv->irq_queue); | 455 | dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); |
239 | 456 | ||
240 | if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) { | 457 | I915_WRITE(I915REG_INT_IDENTITY_R, iir); |
241 | int vblank_pipe = dev_priv->vblank_pipe; | 458 | (void) I915_READ(I915REG_INT_IDENTITY_R); /* Flush posted write */ |
242 | |||
243 | if ((vblank_pipe & | ||
244 | (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) | ||
245 | == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) { | ||
246 | if (temp & VSYNC_PIPEA_FLAG) | ||
247 | atomic_inc(&dev->vbl_received); | ||
248 | if (temp & VSYNC_PIPEB_FLAG) | ||
249 | atomic_inc(&dev->vbl_received2); | ||
250 | } else if (((temp & VSYNC_PIPEA_FLAG) && | ||
251 | (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) || | ||
252 | ((temp & VSYNC_PIPEB_FLAG) && | ||
253 | (vblank_pipe & DRM_I915_VBLANK_PIPE_B))) | ||
254 | atomic_inc(&dev->vbl_received); | ||
255 | |||
256 | DRM_WAKEUP(&dev->vbl_queue); | ||
257 | drm_vbl_send_signals(dev); | ||
258 | 459 | ||
460 | if (iir & I915_USER_INTERRUPT) { | ||
461 | DRM_WAKEUP(&dev_priv->irq_queue); | ||
462 | } | ||
463 | if (vblank) { | ||
259 | if (dev_priv->swaps_pending > 0) | 464 | if (dev_priv->swaps_pending > 0) |
260 | drm_locked_tasklet(dev, i915_vblank_tasklet); | 465 | drm_locked_tasklet(dev, i915_vblank_tasklet); |
261 | I915_WRITE(I915REG_PIPEASTAT, | ||
262 | pipea_stats|I915_VBLANK_INTERRUPT_ENABLE| | ||
263 | I915_VBLANK_CLEAR); | ||
264 | I915_WRITE(I915REG_PIPEBSTAT, | ||
265 | pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE| | ||
266 | I915_VBLANK_CLEAR); | ||
267 | } | 466 | } |
268 | 467 | ||
269 | return IRQ_HANDLED; | 468 | return IRQ_HANDLED; |
270 | } | 469 | } |
271 | 470 | ||
272 | static int i915_emit_irq(struct drm_device * dev) | 471 | static int i915_emit_irq(struct drm_device *dev) |
273 | { | 472 | { |
274 | drm_i915_private_t *dev_priv = dev->dev_private; | 473 | drm_i915_private_t *dev_priv = dev->dev_private; |
275 | RING_LOCALS; | 474 | RING_LOCALS; |
@@ -316,42 +515,12 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) | |||
316 | READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); | 515 | READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); |
317 | } | 516 | } |
318 | 517 | ||
319 | dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); | 518 | if (dev_priv->sarea_priv) |
320 | return ret; | 519 | dev_priv->sarea_priv->last_dispatch = |
321 | } | 520 | READ_BREADCRUMB(dev_priv); |
322 | |||
323 | static int i915_driver_vblank_do_wait(struct drm_device *dev, unsigned int *sequence, | ||
324 | atomic_t *counter) | ||
325 | { | ||
326 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
327 | unsigned int cur_vblank; | ||
328 | int ret = 0; | ||
329 | |||
330 | if (!dev_priv) { | ||
331 | DRM_ERROR("called with no initialization\n"); | ||
332 | return -EINVAL; | ||
333 | } | ||
334 | |||
335 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, | ||
336 | (((cur_vblank = atomic_read(counter)) | ||
337 | - *sequence) <= (1<<23))); | ||
338 | |||
339 | *sequence = cur_vblank; | ||
340 | |||
341 | return ret; | 521 | return ret; |
342 | } | 522 | } |
343 | 523 | ||
344 | |||
345 | int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence) | ||
346 | { | ||
347 | return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received); | ||
348 | } | ||
349 | |||
350 | int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence) | ||
351 | { | ||
352 | return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2); | ||
353 | } | ||
354 | |||
355 | /* Needs the lock as it touches the ring. | 524 | /* Needs the lock as it touches the ring. |
356 | */ | 525 | */ |
357 | int i915_irq_emit(struct drm_device *dev, void *data, | 526 | int i915_irq_emit(struct drm_device *dev, void *data, |
@@ -394,18 +563,96 @@ int i915_irq_wait(struct drm_device *dev, void *data, | |||
394 | return i915_wait_irq(dev, irqwait->irq_seq); | 563 | return i915_wait_irq(dev, irqwait->irq_seq); |
395 | } | 564 | } |
396 | 565 | ||
566 | int i915_enable_vblank(struct drm_device *dev, int plane) | ||
567 | { | ||
568 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
569 | int pipe = i915_get_pipe(dev, plane); | ||
570 | u32 pipestat_reg = 0; | ||
571 | u32 pipestat; | ||
572 | |||
573 | switch (pipe) { | ||
574 | case 0: | ||
575 | pipestat_reg = I915REG_PIPEASTAT; | ||
576 | dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; | ||
577 | break; | ||
578 | case 1: | ||
579 | pipestat_reg = I915REG_PIPEBSTAT; | ||
580 | dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; | ||
581 | break; | ||
582 | default: | ||
583 | DRM_ERROR("tried to enable vblank on non-existent pipe %d\n", | ||
584 | pipe); | ||
585 | break; | ||
586 | } | ||
587 | |||
588 | if (pipestat_reg) | ||
589 | { | ||
590 | pipestat = I915_READ (pipestat_reg); | ||
591 | /* | ||
592 | * Older chips didn't have the start vblank interrupt, | ||
593 | * but | ||
594 | */ | ||
595 | if (IS_I965G (dev)) | ||
596 | pipestat |= I915_START_VBLANK_INTERRUPT_ENABLE; | ||
597 | else | ||
598 | pipestat |= I915_VBLANK_INTERRUPT_ENABLE; | ||
599 | /* | ||
600 | * Clear any pending status | ||
601 | */ | ||
602 | pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS | | ||
603 | I915_VBLANK_INTERRUPT_STATUS); | ||
604 | I915_WRITE(pipestat_reg, pipestat); | ||
605 | } | ||
606 | I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); | ||
607 | |||
608 | return 0; | ||
609 | } | ||
610 | |||
611 | void i915_disable_vblank(struct drm_device *dev, int plane) | ||
612 | { | ||
613 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
614 | int pipe = i915_get_pipe(dev, plane); | ||
615 | u32 pipestat_reg = 0; | ||
616 | u32 pipestat; | ||
617 | |||
618 | switch (pipe) { | ||
619 | case 0: | ||
620 | pipestat_reg = I915REG_PIPEASTAT; | ||
621 | dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; | ||
622 | break; | ||
623 | case 1: | ||
624 | pipestat_reg = I915REG_PIPEBSTAT; | ||
625 | dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; | ||
626 | break; | ||
627 | default: | ||
628 | DRM_ERROR("tried to disable vblank on non-existent pipe %d\n", | ||
629 | pipe); | ||
630 | break; | ||
631 | } | ||
632 | |||
633 | I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); | ||
634 | if (pipestat_reg) | ||
635 | { | ||
636 | pipestat = I915_READ (pipestat_reg); | ||
637 | pipestat &= ~(I915_START_VBLANK_INTERRUPT_ENABLE | | ||
638 | I915_VBLANK_INTERRUPT_ENABLE); | ||
639 | /* | ||
640 | * Clear any pending status | ||
641 | */ | ||
642 | pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS | | ||
643 | I915_VBLANK_INTERRUPT_STATUS); | ||
644 | I915_WRITE(pipestat_reg, pipestat); | ||
645 | } | ||
646 | } | ||
647 | |||
397 | static void i915_enable_interrupt (struct drm_device *dev) | 648 | static void i915_enable_interrupt (struct drm_device *dev) |
398 | { | 649 | { |
399 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 650 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
400 | u16 flag; | ||
401 | 651 | ||
402 | flag = 0; | 652 | dev_priv->irq_enable_reg |= I915_USER_INTERRUPT; |
403 | if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A) | ||
404 | flag |= VSYNC_PIPEA_FLAG; | ||
405 | if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B) | ||
406 | flag |= VSYNC_PIPEB_FLAG; | ||
407 | 653 | ||
408 | I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag); | 654 | I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); |
655 | dev_priv->irq_enabled = 1; | ||
409 | } | 656 | } |
410 | 657 | ||
411 | /* Set the vblank monitor pipe | 658 | /* Set the vblank monitor pipe |
@@ -428,8 +675,6 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data, | |||
428 | 675 | ||
429 | dev_priv->vblank_pipe = pipe->pipe; | 676 | dev_priv->vblank_pipe = pipe->pipe; |
430 | 677 | ||
431 | i915_enable_interrupt (dev); | ||
432 | |||
433 | return 0; | 678 | return 0; |
434 | } | 679 | } |
435 | 680 | ||
@@ -447,9 +692,9 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data, | |||
447 | 692 | ||
448 | flag = I915_READ(I915REG_INT_ENABLE_R); | 693 | flag = I915_READ(I915REG_INT_ENABLE_R); |
449 | pipe->pipe = 0; | 694 | pipe->pipe = 0; |
450 | if (flag & VSYNC_PIPEA_FLAG) | 695 | if (flag & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) |
451 | pipe->pipe |= DRM_I915_VBLANK_PIPE_A; | 696 | pipe->pipe |= DRM_I915_VBLANK_PIPE_A; |
452 | if (flag & VSYNC_PIPEB_FLAG) | 697 | if (flag & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) |
453 | pipe->pipe |= DRM_I915_VBLANK_PIPE_B; | 698 | pipe->pipe |= DRM_I915_VBLANK_PIPE_B; |
454 | 699 | ||
455 | return 0; | 700 | return 0; |
@@ -464,27 +709,30 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
464 | drm_i915_private_t *dev_priv = dev->dev_private; | 709 | drm_i915_private_t *dev_priv = dev->dev_private; |
465 | drm_i915_vblank_swap_t *swap = data; | 710 | drm_i915_vblank_swap_t *swap = data; |
466 | drm_i915_vbl_swap_t *vbl_swap; | 711 | drm_i915_vbl_swap_t *vbl_swap; |
467 | unsigned int pipe, seqtype, curseq; | 712 | unsigned int pipe, seqtype, curseq, plane; |
468 | unsigned long irqflags; | 713 | unsigned long irqflags; |
469 | struct list_head *list; | 714 | struct list_head *list; |
715 | int ret; | ||
470 | 716 | ||
471 | if (!dev_priv) { | 717 | if (!dev_priv) { |
472 | DRM_ERROR("%s called with no initialization\n", __func__); | 718 | DRM_ERROR("%s called with no initialization\n", __func__); |
473 | return -EINVAL; | 719 | return -EINVAL; |
474 | } | 720 | } |
475 | 721 | ||
476 | if (dev_priv->sarea_priv->rotation) { | 722 | if (!dev_priv->sarea_priv || dev_priv->sarea_priv->rotation) { |
477 | DRM_DEBUG("Rotation not supported\n"); | 723 | DRM_DEBUG("Rotation not supported\n"); |
478 | return -EINVAL; | 724 | return -EINVAL; |
479 | } | 725 | } |
480 | 726 | ||
481 | if (swap->seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE | | 727 | if (swap->seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE | |
482 | _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS)) { | 728 | _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS | |
729 | _DRM_VBLANK_FLIP)) { | ||
483 | DRM_ERROR("Invalid sequence type 0x%x\n", swap->seqtype); | 730 | DRM_ERROR("Invalid sequence type 0x%x\n", swap->seqtype); |
484 | return -EINVAL; | 731 | return -EINVAL; |
485 | } | 732 | } |
486 | 733 | ||
487 | pipe = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; | 734 | plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; |
735 | pipe = i915_get_pipe(dev, plane); | ||
488 | 736 | ||
489 | seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE); | 737 | seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE); |
490 | 738 | ||
@@ -495,6 +743,11 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
495 | 743 | ||
496 | spin_lock_irqsave(&dev->drw_lock, irqflags); | 744 | spin_lock_irqsave(&dev->drw_lock, irqflags); |
497 | 745 | ||
746 | /* It makes no sense to schedule a swap for a drawable that doesn't have | ||
747 | * valid information at this point. E.g. this could mean that the X | ||
748 | * server is too old to push drawable information to the DRM, in which | ||
749 | * case all such swaps would become ineffective. | ||
750 | */ | ||
498 | if (!drm_get_drawable_info(dev, swap->drawable)) { | 751 | if (!drm_get_drawable_info(dev, swap->drawable)) { |
499 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | 752 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); |
500 | DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable); | 753 | DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable); |
@@ -503,7 +756,8 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
503 | 756 | ||
504 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | 757 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); |
505 | 758 | ||
506 | curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received); | 759 | drm_update_vblank_count(dev, pipe); |
760 | curseq = drm_vblank_count(dev, pipe); | ||
507 | 761 | ||
508 | if (seqtype == _DRM_VBLANK_RELATIVE) | 762 | if (seqtype == _DRM_VBLANK_RELATIVE) |
509 | swap->sequence += curseq; | 763 | swap->sequence += curseq; |
@@ -517,14 +771,43 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
517 | } | 771 | } |
518 | } | 772 | } |
519 | 773 | ||
774 | if (swap->seqtype & _DRM_VBLANK_FLIP) { | ||
775 | swap->sequence--; | ||
776 | |||
777 | if ((curseq - swap->sequence) <= (1<<23)) { | ||
778 | struct drm_drawable_info *drw; | ||
779 | |||
780 | LOCK_TEST_WITH_RETURN(dev, file_priv); | ||
781 | |||
782 | spin_lock_irqsave(&dev->drw_lock, irqflags); | ||
783 | |||
784 | drw = drm_get_drawable_info(dev, swap->drawable); | ||
785 | |||
786 | if (!drw) { | ||
787 | spin_unlock_irqrestore(&dev->drw_lock, | ||
788 | irqflags); | ||
789 | DRM_DEBUG("Invalid drawable ID %d\n", | ||
790 | swap->drawable); | ||
791 | return -EINVAL; | ||
792 | } | ||
793 | |||
794 | i915_dispatch_vsync_flip(dev, drw, plane); | ||
795 | |||
796 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | ||
797 | |||
798 | return 0; | ||
799 | } | ||
800 | } | ||
801 | |||
520 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); | 802 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); |
521 | 803 | ||
522 | list_for_each(list, &dev_priv->vbl_swaps.head) { | 804 | list_for_each(list, &dev_priv->vbl_swaps.head) { |
523 | vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); | 805 | vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); |
524 | 806 | ||
525 | if (vbl_swap->drw_id == swap->drawable && | 807 | if (vbl_swap->drw_id == swap->drawable && |
526 | vbl_swap->pipe == pipe && | 808 | vbl_swap->plane == plane && |
527 | vbl_swap->sequence == swap->sequence) { | 809 | vbl_swap->sequence == swap->sequence) { |
810 | vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP); | ||
528 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); | 811 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); |
529 | DRM_DEBUG("Already scheduled\n"); | 812 | DRM_DEBUG("Already scheduled\n"); |
530 | return 0; | 813 | return 0; |
@@ -547,9 +830,19 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
547 | 830 | ||
548 | DRM_DEBUG("\n"); | 831 | DRM_DEBUG("\n"); |
549 | 832 | ||
833 | ret = drm_vblank_get(dev, pipe); | ||
834 | if (ret) { | ||
835 | drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER); | ||
836 | return ret; | ||
837 | } | ||
838 | |||
550 | vbl_swap->drw_id = swap->drawable; | 839 | vbl_swap->drw_id = swap->drawable; |
551 | vbl_swap->pipe = pipe; | 840 | vbl_swap->plane = plane; |
552 | vbl_swap->sequence = swap->sequence; | 841 | vbl_swap->sequence = swap->sequence; |
842 | vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP); | ||
843 | |||
844 | if (vbl_swap->flip) | ||
845 | swap->sequence++; | ||
553 | 846 | ||
554 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); | 847 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); |
555 | 848 | ||
@@ -567,37 +860,57 @@ void i915_driver_irq_preinstall(struct drm_device * dev) | |||
567 | { | 860 | { |
568 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 861 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
569 | 862 | ||
570 | I915_WRITE16(I915REG_HWSTAM, 0xfffe); | 863 | I915_WRITE16(I915REG_HWSTAM, 0xeffe); |
571 | I915_WRITE16(I915REG_INT_MASK_R, 0x0); | 864 | I915_WRITE16(I915REG_INT_MASK_R, 0x0); |
572 | I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); | 865 | I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); |
573 | } | 866 | } |
574 | 867 | ||
575 | void i915_driver_irq_postinstall(struct drm_device * dev) | 868 | int i915_driver_irq_postinstall(struct drm_device * dev) |
576 | { | 869 | { |
577 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 870 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
871 | int ret, num_pipes = 2; | ||
578 | 872 | ||
579 | spin_lock_init(&dev_priv->swaps_lock); | 873 | spin_lock_init(&dev_priv->swaps_lock); |
580 | INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); | 874 | INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); |
581 | dev_priv->swaps_pending = 0; | 875 | dev_priv->swaps_pending = 0; |
582 | 876 | ||
583 | if (!dev_priv->vblank_pipe) | 877 | dev_priv->user_irq_refcount = 0; |
584 | dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A; | 878 | dev_priv->irq_enable_reg = 0; |
879 | |||
880 | ret = drm_vblank_init(dev, num_pipes); | ||
881 | if (ret) | ||
882 | return ret; | ||
883 | |||
884 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ | ||
885 | |||
585 | i915_enable_interrupt(dev); | 886 | i915_enable_interrupt(dev); |
586 | DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); | 887 | DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); |
888 | |||
889 | /* | ||
890 | * Initialize the hardware status page IRQ location. | ||
891 | */ | ||
892 | |||
893 | I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21)); | ||
894 | return 0; | ||
587 | } | 895 | } |
588 | 896 | ||
589 | void i915_driver_irq_uninstall(struct drm_device * dev) | 897 | void i915_driver_irq_uninstall(struct drm_device * dev) |
590 | { | 898 | { |
591 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 899 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
592 | u16 temp; | 900 | u32 temp; |
593 | 901 | ||
594 | if (!dev_priv) | 902 | if (!dev_priv) |
595 | return; | 903 | return; |
596 | 904 | ||
597 | I915_WRITE16(I915REG_HWSTAM, 0xffff); | 905 | dev_priv->irq_enabled = 0; |
598 | I915_WRITE16(I915REG_INT_MASK_R, 0xffff); | 906 | I915_WRITE(I915REG_HWSTAM, 0xffffffff); |
599 | I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); | 907 | I915_WRITE(I915REG_INT_MASK_R, 0xffffffff); |
600 | 908 | I915_WRITE(I915REG_INT_ENABLE_R, 0x0); | |
601 | temp = I915_READ16(I915REG_INT_IDENTITY_R); | 909 | |
602 | I915_WRITE16(I915REG_INT_IDENTITY_R, temp); | 910 | temp = I915_READ(I915REG_PIPEASTAT); |
911 | I915_WRITE(I915REG_PIPEASTAT, temp); | ||
912 | temp = I915_READ(I915REG_PIPEBSTAT); | ||
913 | I915_WRITE(I915REG_PIPEBSTAT, temp); | ||
914 | temp = I915_READ(I915REG_INT_IDENTITY_R); | ||
915 | I915_WRITE(I915REG_INT_IDENTITY_R, temp); | ||
603 | } | 916 | } |
diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c index 5572939fc7d1..6b3790939e76 100644 --- a/drivers/char/drm/mga_drv.c +++ b/drivers/char/drm/mga_drv.c | |||
@@ -45,15 +45,16 @@ static struct pci_device_id pciidlist[] = { | |||
45 | static struct drm_driver driver = { | 45 | static struct drm_driver driver = { |
46 | .driver_features = | 46 | .driver_features = |
47 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | | 47 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | |
48 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | | 48 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, |
49 | DRIVER_IRQ_VBL, | ||
50 | .dev_priv_size = sizeof(drm_mga_buf_priv_t), | 49 | .dev_priv_size = sizeof(drm_mga_buf_priv_t), |
51 | .load = mga_driver_load, | 50 | .load = mga_driver_load, |
52 | .unload = mga_driver_unload, | 51 | .unload = mga_driver_unload, |
53 | .lastclose = mga_driver_lastclose, | 52 | .lastclose = mga_driver_lastclose, |
54 | .dma_quiescent = mga_driver_dma_quiescent, | 53 | .dma_quiescent = mga_driver_dma_quiescent, |
55 | .device_is_agp = mga_driver_device_is_agp, | 54 | .device_is_agp = mga_driver_device_is_agp, |
56 | .vblank_wait = mga_driver_vblank_wait, | 55 | .get_vblank_counter = mga_get_vblank_counter, |
56 | .enable_vblank = mga_enable_vblank, | ||
57 | .disable_vblank = mga_disable_vblank, | ||
57 | .irq_preinstall = mga_driver_irq_preinstall, | 58 | .irq_preinstall = mga_driver_irq_preinstall, |
58 | .irq_postinstall = mga_driver_irq_postinstall, | 59 | .irq_postinstall = mga_driver_irq_postinstall, |
59 | .irq_uninstall = mga_driver_irq_uninstall, | 60 | .irq_uninstall = mga_driver_irq_uninstall, |
diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h index f6ebd24bd587..8f7291f36363 100644 --- a/drivers/char/drm/mga_drv.h +++ b/drivers/char/drm/mga_drv.h | |||
@@ -120,6 +120,7 @@ typedef struct drm_mga_private { | |||
120 | u32 clear_cmd; | 120 | u32 clear_cmd; |
121 | u32 maccess; | 121 | u32 maccess; |
122 | 122 | ||
123 | atomic_t vbl_received; /**< Number of vblanks received. */ | ||
123 | wait_queue_head_t fence_queue; | 124 | wait_queue_head_t fence_queue; |
124 | atomic_t last_fence_retired; | 125 | atomic_t last_fence_retired; |
125 | u32 next_fence_to_post; | 126 | u32 next_fence_to_post; |
@@ -181,11 +182,14 @@ extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv); | |||
181 | extern int mga_warp_init(drm_mga_private_t * dev_priv); | 182 | extern int mga_warp_init(drm_mga_private_t * dev_priv); |
182 | 183 | ||
183 | /* mga_irq.c */ | 184 | /* mga_irq.c */ |
185 | extern int mga_enable_vblank(struct drm_device *dev, int crtc); | ||
186 | extern void mga_disable_vblank(struct drm_device *dev, int crtc); | ||
187 | extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc); | ||
184 | extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence); | 188 | extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence); |
185 | extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); | 189 | extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); |
186 | extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); | 190 | extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); |
187 | extern void mga_driver_irq_preinstall(struct drm_device * dev); | 191 | extern void mga_driver_irq_preinstall(struct drm_device * dev); |
188 | extern void mga_driver_irq_postinstall(struct drm_device * dev); | 192 | extern int mga_driver_irq_postinstall(struct drm_device * dev); |
189 | extern void mga_driver_irq_uninstall(struct drm_device * dev); | 193 | extern void mga_driver_irq_uninstall(struct drm_device * dev); |
190 | extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, | 194 | extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, |
191 | unsigned long arg); | 195 | unsigned long arg); |
diff --git a/drivers/char/drm/mga_irq.c b/drivers/char/drm/mga_irq.c index 9302cb8f0f83..06852fb4b278 100644 --- a/drivers/char/drm/mga_irq.c +++ b/drivers/char/drm/mga_irq.c | |||
@@ -35,6 +35,20 @@ | |||
35 | #include "mga_drm.h" | 35 | #include "mga_drm.h" |
36 | #include "mga_drv.h" | 36 | #include "mga_drv.h" |
37 | 37 | ||
38 | u32 mga_get_vblank_counter(struct drm_device *dev, int crtc) | ||
39 | { | ||
40 | const drm_mga_private_t *const dev_priv = | ||
41 | (drm_mga_private_t *) dev->dev_private; | ||
42 | |||
43 | if (crtc != 0) { | ||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | |||
48 | return atomic_read(&dev_priv->vbl_received); | ||
49 | } | ||
50 | |||
51 | |||
38 | irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) | 52 | irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) |
39 | { | 53 | { |
40 | struct drm_device *dev = (struct drm_device *) arg; | 54 | struct drm_device *dev = (struct drm_device *) arg; |
@@ -47,9 +61,8 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) | |||
47 | /* VBLANK interrupt */ | 61 | /* VBLANK interrupt */ |
48 | if (status & MGA_VLINEPEN) { | 62 | if (status & MGA_VLINEPEN) { |
49 | MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); | 63 | MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); |
50 | atomic_inc(&dev->vbl_received); | 64 | atomic_inc(&dev_priv->vbl_received); |
51 | DRM_WAKEUP(&dev->vbl_queue); | 65 | drm_handle_vblank(dev, 0); |
52 | drm_vbl_send_signals(dev); | ||
53 | handled = 1; | 66 | handled = 1; |
54 | } | 67 | } |
55 | 68 | ||
@@ -78,22 +91,34 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) | |||
78 | return IRQ_NONE; | 91 | return IRQ_NONE; |
79 | } | 92 | } |
80 | 93 | ||
81 | int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) | 94 | int mga_enable_vblank(struct drm_device *dev, int crtc) |
82 | { | 95 | { |
83 | unsigned int cur_vblank; | 96 | drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; |
84 | int ret = 0; | ||
85 | 97 | ||
86 | /* Assume that the user has missed the current sequence number | 98 | if (crtc != 0) { |
87 | * by about a day rather than she wants to wait for years | 99 | DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", |
88 | * using vertical blanks... | 100 | crtc); |
89 | */ | 101 | return 0; |
90 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, | 102 | } |
91 | (((cur_vblank = atomic_read(&dev->vbl_received)) | ||
92 | - *sequence) <= (1 << 23))); | ||
93 | 103 | ||
94 | *sequence = cur_vblank; | 104 | MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); |
105 | return 0; | ||
106 | } | ||
95 | 107 | ||
96 | return ret; | 108 | |
109 | void mga_disable_vblank(struct drm_device *dev, int crtc) | ||
110 | { | ||
111 | if (crtc != 0) { | ||
112 | DRM_ERROR("tried to disable vblank on non-existent crtc %d\n", | ||
113 | crtc); | ||
114 | } | ||
115 | |||
116 | /* Do *NOT* disable the vertical refresh interrupt. MGA doesn't have | ||
117 | * a nice hardware counter that tracks the number of refreshes when | ||
118 | * the interrupt is disabled, and the kernel doesn't know the refresh | ||
119 | * rate to calculate an estimate. | ||
120 | */ | ||
121 | /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */ | ||
97 | } | 122 | } |
98 | 123 | ||
99 | int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) | 124 | int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) |
@@ -125,14 +150,22 @@ void mga_driver_irq_preinstall(struct drm_device * dev) | |||
125 | MGA_WRITE(MGA_ICLEAR, ~0); | 150 | MGA_WRITE(MGA_ICLEAR, ~0); |
126 | } | 151 | } |
127 | 152 | ||
128 | void mga_driver_irq_postinstall(struct drm_device * dev) | 153 | int mga_driver_irq_postinstall(struct drm_device * dev) |
129 | { | 154 | { |
130 | drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; | 155 | drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; |
156 | int ret; | ||
157 | |||
158 | ret = drm_vblank_init(dev, 1); | ||
159 | if (ret) | ||
160 | return ret; | ||
131 | 161 | ||
132 | DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); | 162 | DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); |
133 | 163 | ||
134 | /* Turn on vertical blank interrupt and soft trap interrupt. */ | 164 | /* Turn on soft trap interrupt. Vertical blank interrupts are enabled |
135 | MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); | 165 | * in mga_enable_vblank. |
166 | */ | ||
167 | MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN); | ||
168 | return 0; | ||
136 | } | 169 | } |
137 | 170 | ||
138 | void mga_driver_irq_uninstall(struct drm_device * dev) | 171 | void mga_driver_irq_uninstall(struct drm_device * dev) |
diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c index 6108e7587e12..2888aa01ebc7 100644 --- a/drivers/char/drm/r128_drv.c +++ b/drivers/char/drm/r128_drv.c | |||
@@ -43,12 +43,13 @@ static struct pci_device_id pciidlist[] = { | |||
43 | static struct drm_driver driver = { | 43 | static struct drm_driver driver = { |
44 | .driver_features = | 44 | .driver_features = |
45 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | | 45 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | |
46 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | | 46 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, |
47 | DRIVER_IRQ_VBL, | ||
48 | .dev_priv_size = sizeof(drm_r128_buf_priv_t), | 47 | .dev_priv_size = sizeof(drm_r128_buf_priv_t), |
49 | .preclose = r128_driver_preclose, | 48 | .preclose = r128_driver_preclose, |
50 | .lastclose = r128_driver_lastclose, | 49 | .lastclose = r128_driver_lastclose, |
51 | .vblank_wait = r128_driver_vblank_wait, | 50 | .get_vblank_counter = r128_get_vblank_counter, |
51 | .enable_vblank = r128_enable_vblank, | ||
52 | .disable_vblank = r128_disable_vblank, | ||
52 | .irq_preinstall = r128_driver_irq_preinstall, | 53 | .irq_preinstall = r128_driver_irq_preinstall, |
53 | .irq_postinstall = r128_driver_irq_postinstall, | 54 | .irq_postinstall = r128_driver_irq_postinstall, |
54 | .irq_uninstall = r128_driver_irq_uninstall, | 55 | .irq_uninstall = r128_driver_irq_uninstall, |
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h index 011105e51ac6..80af9e09e75d 100644 --- a/drivers/char/drm/r128_drv.h +++ b/drivers/char/drm/r128_drv.h | |||
@@ -97,6 +97,8 @@ typedef struct drm_r128_private { | |||
97 | u32 crtc_offset; | 97 | u32 crtc_offset; |
98 | u32 crtc_offset_cntl; | 98 | u32 crtc_offset_cntl; |
99 | 99 | ||
100 | atomic_t vbl_received; | ||
101 | |||
100 | u32 color_fmt; | 102 | u32 color_fmt; |
101 | unsigned int front_offset; | 103 | unsigned int front_offset; |
102 | unsigned int front_pitch; | 104 | unsigned int front_pitch; |
@@ -149,11 +151,12 @@ extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n); | |||
149 | extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); | 151 | extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); |
150 | extern int r128_do_cleanup_cce(struct drm_device * dev); | 152 | extern int r128_do_cleanup_cce(struct drm_device * dev); |
151 | 153 | ||
152 | extern int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); | 154 | extern int r128_enable_vblank(struct drm_device *dev, int crtc); |
153 | 155 | extern void r128_disable_vblank(struct drm_device *dev, int crtc); | |
156 | extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc); | ||
154 | extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); | 157 | extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); |
155 | extern void r128_driver_irq_preinstall(struct drm_device * dev); | 158 | extern void r128_driver_irq_preinstall(struct drm_device * dev); |
156 | extern void r128_driver_irq_postinstall(struct drm_device * dev); | 159 | extern int r128_driver_irq_postinstall(struct drm_device * dev); |
157 | extern void r128_driver_irq_uninstall(struct drm_device * dev); | 160 | extern void r128_driver_irq_uninstall(struct drm_device * dev); |
158 | extern void r128_driver_lastclose(struct drm_device * dev); | 161 | extern void r128_driver_lastclose(struct drm_device * dev); |
159 | extern void r128_driver_preclose(struct drm_device * dev, | 162 | extern void r128_driver_preclose(struct drm_device * dev, |
diff --git a/drivers/char/drm/r128_irq.c b/drivers/char/drm/r128_irq.c index c76fdca7662d..5b95bd898f95 100644 --- a/drivers/char/drm/r128_irq.c +++ b/drivers/char/drm/r128_irq.c | |||
@@ -35,6 +35,16 @@ | |||
35 | #include "r128_drm.h" | 35 | #include "r128_drm.h" |
36 | #include "r128_drv.h" | 36 | #include "r128_drv.h" |
37 | 37 | ||
38 | u32 r128_get_vblank_counter(struct drm_device *dev, int crtc) | ||
39 | { | ||
40 | const drm_r128_private_t *dev_priv = dev->dev_private; | ||
41 | |||
42 | if (crtc != 0) | ||
43 | return 0; | ||
44 | |||
45 | return atomic_read(&dev_priv->vbl_received); | ||
46 | } | ||
47 | |||
38 | irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) | 48 | irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) |
39 | { | 49 | { |
40 | struct drm_device *dev = (struct drm_device *) arg; | 50 | struct drm_device *dev = (struct drm_device *) arg; |
@@ -46,30 +56,38 @@ irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) | |||
46 | /* VBLANK interrupt */ | 56 | /* VBLANK interrupt */ |
47 | if (status & R128_CRTC_VBLANK_INT) { | 57 | if (status & R128_CRTC_VBLANK_INT) { |
48 | R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); | 58 | R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); |
49 | atomic_inc(&dev->vbl_received); | 59 | atomic_inc(&dev_priv->vbl_received); |
50 | DRM_WAKEUP(&dev->vbl_queue); | 60 | drm_handle_vblank(dev, 0); |
51 | drm_vbl_send_signals(dev); | ||
52 | return IRQ_HANDLED; | 61 | return IRQ_HANDLED; |
53 | } | 62 | } |
54 | return IRQ_NONE; | 63 | return IRQ_NONE; |
55 | } | 64 | } |
56 | 65 | ||
57 | int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) | 66 | int r128_enable_vblank(struct drm_device *dev, int crtc) |
58 | { | 67 | { |
59 | unsigned int cur_vblank; | 68 | drm_r128_private_t *dev_priv = dev->dev_private; |
60 | int ret = 0; | ||
61 | 69 | ||
62 | /* Assume that the user has missed the current sequence number | 70 | if (crtc != 0) { |
63 | * by about a day rather than she wants to wait for years | 71 | DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); |
64 | * using vertical blanks... | 72 | return -EINVAL; |
65 | */ | 73 | } |
66 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, | ||
67 | (((cur_vblank = atomic_read(&dev->vbl_received)) | ||
68 | - *sequence) <= (1 << 23))); | ||
69 | 74 | ||
70 | *sequence = cur_vblank; | 75 | R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); |
76 | return 0; | ||
77 | } | ||
78 | |||
79 | void r128_disable_vblank(struct drm_device *dev, int crtc) | ||
80 | { | ||
81 | if (crtc != 0) | ||
82 | DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); | ||
71 | 83 | ||
72 | return ret; | 84 | /* |
85 | * FIXME: implement proper interrupt disable by using the vblank | ||
86 | * counter register (if available) | ||
87 | * | ||
88 | * R128_WRITE(R128_GEN_INT_CNTL, | ||
89 | * R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN); | ||
90 | */ | ||
73 | } | 91 | } |
74 | 92 | ||
75 | void r128_driver_irq_preinstall(struct drm_device * dev) | 93 | void r128_driver_irq_preinstall(struct drm_device * dev) |
@@ -82,12 +100,9 @@ void r128_driver_irq_preinstall(struct drm_device * dev) | |||
82 | R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); | 100 | R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); |
83 | } | 101 | } |
84 | 102 | ||
85 | void r128_driver_irq_postinstall(struct drm_device * dev) | 103 | int r128_driver_irq_postinstall(struct drm_device * dev) |
86 | { | 104 | { |
87 | drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; | 105 | return drm_vblank_init(dev, 1); |
88 | |||
89 | /* Turn on VBL interrupt */ | ||
90 | R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); | ||
91 | } | 106 | } |
92 | 107 | ||
93 | void r128_driver_irq_uninstall(struct drm_device * dev) | 108 | void r128_driver_irq_uninstall(struct drm_device * dev) |
diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c index 349ac3d3b848..a2610319624d 100644 --- a/drivers/char/drm/radeon_drv.c +++ b/drivers/char/drm/radeon_drv.c | |||
@@ -59,8 +59,7 @@ static struct pci_device_id pciidlist[] = { | |||
59 | static struct drm_driver driver = { | 59 | static struct drm_driver driver = { |
60 | .driver_features = | 60 | .driver_features = |
61 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | | 61 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | |
62 | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | | 62 | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED, |
63 | DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2, | ||
64 | .dev_priv_size = sizeof(drm_radeon_buf_priv_t), | 63 | .dev_priv_size = sizeof(drm_radeon_buf_priv_t), |
65 | .load = radeon_driver_load, | 64 | .load = radeon_driver_load, |
66 | .firstopen = radeon_driver_firstopen, | 65 | .firstopen = radeon_driver_firstopen, |
@@ -69,8 +68,9 @@ static struct drm_driver driver = { | |||
69 | .postclose = radeon_driver_postclose, | 68 | .postclose = radeon_driver_postclose, |
70 | .lastclose = radeon_driver_lastclose, | 69 | .lastclose = radeon_driver_lastclose, |
71 | .unload = radeon_driver_unload, | 70 | .unload = radeon_driver_unload, |
72 | .vblank_wait = radeon_driver_vblank_wait, | 71 | .get_vblank_counter = radeon_get_vblank_counter, |
73 | .vblank_wait2 = radeon_driver_vblank_wait2, | 72 | .enable_vblank = radeon_enable_vblank, |
73 | .disable_vblank = radeon_disable_vblank, | ||
74 | .dri_library_name = dri_library_name, | 74 | .dri_library_name = dri_library_name, |
75 | .irq_preinstall = radeon_driver_irq_preinstall, | 75 | .irq_preinstall = radeon_driver_irq_preinstall, |
76 | .irq_postinstall = radeon_driver_irq_postinstall, | 76 | .irq_postinstall = radeon_driver_irq_postinstall, |
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index 173ae620223a..b791420bd3d9 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h | |||
@@ -304,6 +304,9 @@ typedef struct drm_radeon_private { | |||
304 | 304 | ||
305 | u32 scratch_ages[5]; | 305 | u32 scratch_ages[5]; |
306 | 306 | ||
307 | unsigned int crtc_last_cnt; | ||
308 | unsigned int crtc2_last_cnt; | ||
309 | |||
307 | /* starting from here on, data is preserved accross an open */ | 310 | /* starting from here on, data is preserved accross an open */ |
308 | uint32_t flags; /* see radeon_chip_flags */ | 311 | uint32_t flags; /* see radeon_chip_flags */ |
309 | unsigned long fb_aper_offset; | 312 | unsigned long fb_aper_offset; |
@@ -374,13 +377,13 @@ extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file * | |||
374 | extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); | 377 | extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); |
375 | 378 | ||
376 | extern void radeon_do_release(struct drm_device * dev); | 379 | extern void radeon_do_release(struct drm_device * dev); |
377 | extern int radeon_driver_vblank_wait(struct drm_device * dev, | 380 | extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc); |
378 | unsigned int *sequence); | 381 | extern int radeon_enable_vblank(struct drm_device *dev, int crtc); |
379 | extern int radeon_driver_vblank_wait2(struct drm_device * dev, | 382 | extern void radeon_disable_vblank(struct drm_device *dev, int crtc); |
380 | unsigned int *sequence); | 383 | extern void radeon_do_release(struct drm_device * dev); |
381 | extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); | 384 | extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); |
382 | extern void radeon_driver_irq_preinstall(struct drm_device * dev); | 385 | extern void radeon_driver_irq_preinstall(struct drm_device * dev); |
383 | extern void radeon_driver_irq_postinstall(struct drm_device * dev); | 386 | extern int radeon_driver_irq_postinstall(struct drm_device * dev); |
384 | extern void radeon_driver_irq_uninstall(struct drm_device * dev); | 387 | extern void radeon_driver_irq_uninstall(struct drm_device * dev); |
385 | extern int radeon_vblank_crtc_get(struct drm_device *dev); | 388 | extern int radeon_vblank_crtc_get(struct drm_device *dev); |
386 | extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value); | 389 | extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value); |
@@ -558,6 +561,12 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev, | |||
558 | ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \ | 561 | ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \ |
559 | : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) | 562 | : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) |
560 | 563 | ||
564 | #define RADEON_CRTC_CRNT_FRAME 0x0214 | ||
565 | #define RADEON_CRTC2_CRNT_FRAME 0x0314 | ||
566 | |||
567 | #define RADEON_CRTC_STATUS 0x005c | ||
568 | #define RADEON_CRTC2_STATUS 0x03fc | ||
569 | |||
561 | #define RADEON_GEN_INT_CNTL 0x0040 | 570 | #define RADEON_GEN_INT_CNTL 0x0040 |
562 | # define RADEON_CRTC_VBLANK_MASK (1 << 0) | 571 | # define RADEON_CRTC_VBLANK_MASK (1 << 0) |
563 | # define RADEON_CRTC2_VBLANK_MASK (1 << 9) | 572 | # define RADEON_CRTC2_VBLANK_MASK (1 << 9) |
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c index 009af3814b6f..507d6b747a13 100644 --- a/drivers/char/drm/radeon_irq.c +++ b/drivers/char/drm/radeon_irq.c | |||
@@ -35,12 +35,61 @@ | |||
35 | #include "radeon_drm.h" | 35 | #include "radeon_drm.h" |
36 | #include "radeon_drv.h" | 36 | #include "radeon_drv.h" |
37 | 37 | ||
38 | static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv, | 38 | static void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state) |
39 | u32 mask) | ||
40 | { | 39 | { |
41 | u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask; | 40 | drm_radeon_private_t *dev_priv = dev->dev_private; |
41 | |||
42 | if (state) | ||
43 | dev_priv->irq_enable_reg |= mask; | ||
44 | else | ||
45 | dev_priv->irq_enable_reg &= ~mask; | ||
46 | |||
47 | RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); | ||
48 | } | ||
49 | |||
50 | int radeon_enable_vblank(struct drm_device *dev, int crtc) | ||
51 | { | ||
52 | switch (crtc) { | ||
53 | case 0: | ||
54 | radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1); | ||
55 | break; | ||
56 | case 1: | ||
57 | radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1); | ||
58 | break; | ||
59 | default: | ||
60 | DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", | ||
61 | crtc); | ||
62 | return EINVAL; | ||
63 | } | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | void radeon_disable_vblank(struct drm_device *dev, int crtc) | ||
69 | { | ||
70 | switch (crtc) { | ||
71 | case 0: | ||
72 | radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0); | ||
73 | break; | ||
74 | case 1: | ||
75 | radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0); | ||
76 | break; | ||
77 | default: | ||
78 | DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", | ||
79 | crtc); | ||
80 | break; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv) | ||
85 | { | ||
86 | u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & | ||
87 | (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT | | ||
88 | RADEON_CRTC2_VBLANK_STAT); | ||
89 | |||
42 | if (irqs) | 90 | if (irqs) |
43 | RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); | 91 | RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); |
92 | |||
44 | return irqs; | 93 | return irqs; |
45 | } | 94 | } |
46 | 95 | ||
@@ -72,39 +121,21 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) | |||
72 | /* Only consider the bits we're interested in - others could be used | 121 | /* Only consider the bits we're interested in - others could be used |
73 | * outside the DRM | 122 | * outside the DRM |
74 | */ | 123 | */ |
75 | stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | | 124 | stat = radeon_acknowledge_irqs(dev_priv); |
76 | RADEON_CRTC_VBLANK_STAT | | ||
77 | RADEON_CRTC2_VBLANK_STAT)); | ||
78 | if (!stat) | 125 | if (!stat) |
79 | return IRQ_NONE; | 126 | return IRQ_NONE; |
80 | 127 | ||
81 | stat &= dev_priv->irq_enable_reg; | 128 | stat &= dev_priv->irq_enable_reg; |
82 | 129 | ||
83 | /* SW interrupt */ | 130 | /* SW interrupt */ |
84 | if (stat & RADEON_SW_INT_TEST) { | 131 | if (stat & RADEON_SW_INT_TEST) |
85 | DRM_WAKEUP(&dev_priv->swi_queue); | 132 | DRM_WAKEUP(&dev_priv->swi_queue); |
86 | } | ||
87 | 133 | ||
88 | /* VBLANK interrupt */ | 134 | /* VBLANK interrupt */ |
89 | if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) { | 135 | if (stat & RADEON_CRTC_VBLANK_STAT) |
90 | int vblank_crtc = dev_priv->vblank_crtc; | 136 | drm_handle_vblank(dev, 0); |
91 | 137 | if (stat & RADEON_CRTC2_VBLANK_STAT) | |
92 | if ((vblank_crtc & | 138 | drm_handle_vblank(dev, 1); |
93 | (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) == | ||
94 | (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { | ||
95 | if (stat & RADEON_CRTC_VBLANK_STAT) | ||
96 | atomic_inc(&dev->vbl_received); | ||
97 | if (stat & RADEON_CRTC2_VBLANK_STAT) | ||
98 | atomic_inc(&dev->vbl_received2); | ||
99 | } else if (((stat & RADEON_CRTC_VBLANK_STAT) && | ||
100 | (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) || | ||
101 | ((stat & RADEON_CRTC2_VBLANK_STAT) && | ||
102 | (vblank_crtc & DRM_RADEON_VBLANK_CRTC2))) | ||
103 | atomic_inc(&dev->vbl_received); | ||
104 | |||
105 | DRM_WAKEUP(&dev->vbl_queue); | ||
106 | drm_vbl_send_signals(dev); | ||
107 | } | ||
108 | 139 | ||
109 | return IRQ_HANDLED; | 140 | return IRQ_HANDLED; |
110 | } | 141 | } |
@@ -144,54 +175,27 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr) | |||
144 | return ret; | 175 | return ret; |
145 | } | 176 | } |
146 | 177 | ||
147 | static int radeon_driver_vblank_do_wait(struct drm_device * dev, | 178 | u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc) |
148 | unsigned int *sequence, int crtc) | ||
149 | { | 179 | { |
150 | drm_radeon_private_t *dev_priv = | 180 | drm_radeon_private_t *dev_priv = dev->dev_private; |
151 | (drm_radeon_private_t *) dev->dev_private; | 181 | u32 crtc_cnt_reg, crtc_status_reg; |
152 | unsigned int cur_vblank; | 182 | |
153 | int ret = 0; | ||
154 | int ack = 0; | ||
155 | atomic_t *counter; | ||
156 | if (!dev_priv) { | 183 | if (!dev_priv) { |
157 | DRM_ERROR("called with no initialization\n"); | 184 | DRM_ERROR("called with no initialization\n"); |
158 | return -EINVAL; | 185 | return -EINVAL; |
159 | } | 186 | } |
160 | 187 | ||
161 | if (crtc == DRM_RADEON_VBLANK_CRTC1) { | 188 | if (crtc == 0) { |
162 | counter = &dev->vbl_received; | 189 | crtc_cnt_reg = RADEON_CRTC_CRNT_FRAME; |
163 | ack |= RADEON_CRTC_VBLANK_STAT; | 190 | crtc_status_reg = RADEON_CRTC_STATUS; |
164 | } else if (crtc == DRM_RADEON_VBLANK_CRTC2) { | 191 | } else if (crtc == 1) { |
165 | counter = &dev->vbl_received2; | 192 | crtc_cnt_reg = RADEON_CRTC2_CRNT_FRAME; |
166 | ack |= RADEON_CRTC2_VBLANK_STAT; | 193 | crtc_status_reg = RADEON_CRTC2_STATUS; |
167 | } else | 194 | } else { |
168 | return -EINVAL; | 195 | return -EINVAL; |
196 | } | ||
169 | 197 | ||
170 | radeon_acknowledge_irqs(dev_priv, ack); | 198 | return RADEON_READ(crtc_cnt_reg) + (RADEON_READ(crtc_status_reg) & 1); |
171 | |||
172 | dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; | ||
173 | |||
174 | /* Assume that the user has missed the current sequence number | ||
175 | * by about a day rather than she wants to wait for years | ||
176 | * using vertical blanks... | ||
177 | */ | ||
178 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, | ||
179 | (((cur_vblank = atomic_read(counter)) | ||
180 | - *sequence) <= (1 << 23))); | ||
181 | |||
182 | *sequence = cur_vblank; | ||
183 | |||
184 | return ret; | ||
185 | } | ||
186 | |||
187 | int radeon_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence) | ||
188 | { | ||
189 | return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1); | ||
190 | } | ||
191 | |||
192 | int radeon_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence) | ||
193 | { | ||
194 | return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2); | ||
195 | } | 199 | } |
196 | 200 | ||
197 | /* Needs the lock as it touches the ring. | 201 | /* Needs the lock as it touches the ring. |
@@ -234,21 +238,6 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
234 | return radeon_wait_irq(dev, irqwait->irq_seq); | 238 | return radeon_wait_irq(dev, irqwait->irq_seq); |
235 | } | 239 | } |
236 | 240 | ||
237 | static void radeon_enable_interrupt(struct drm_device *dev) | ||
238 | { | ||
239 | drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; | ||
240 | |||
241 | dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE; | ||
242 | if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1) | ||
243 | dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK; | ||
244 | |||
245 | if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2) | ||
246 | dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK; | ||
247 | |||
248 | RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); | ||
249 | dev_priv->irq_enabled = 1; | ||
250 | } | ||
251 | |||
252 | /* drm_dma.h hooks | 241 | /* drm_dma.h hooks |
253 | */ | 242 | */ |
254 | void radeon_driver_irq_preinstall(struct drm_device * dev) | 243 | void radeon_driver_irq_preinstall(struct drm_device * dev) |
@@ -260,20 +249,27 @@ void radeon_driver_irq_preinstall(struct drm_device * dev) | |||
260 | RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); | 249 | RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); |
261 | 250 | ||
262 | /* Clear bits if they're already high */ | 251 | /* Clear bits if they're already high */ |
263 | radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | | 252 | radeon_acknowledge_irqs(dev_priv); |
264 | RADEON_CRTC_VBLANK_STAT | | ||
265 | RADEON_CRTC2_VBLANK_STAT)); | ||
266 | } | 253 | } |
267 | 254 | ||
268 | void radeon_driver_irq_postinstall(struct drm_device * dev) | 255 | int radeon_driver_irq_postinstall(struct drm_device * dev) |
269 | { | 256 | { |
270 | drm_radeon_private_t *dev_priv = | 257 | drm_radeon_private_t *dev_priv = |
271 | (drm_radeon_private_t *) dev->dev_private; | 258 | (drm_radeon_private_t *) dev->dev_private; |
259 | int ret; | ||
272 | 260 | ||
273 | atomic_set(&dev_priv->swi_emitted, 0); | 261 | atomic_set(&dev_priv->swi_emitted, 0); |
274 | DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); | 262 | DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); |
275 | 263 | ||
276 | radeon_enable_interrupt(dev); | 264 | ret = drm_vblank_init(dev, 2); |
265 | if (ret) | ||
266 | return ret; | ||
267 | |||
268 | dev->max_vblank_count = 0x001fffff; | ||
269 | |||
270 | radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); | ||
271 | |||
272 | return 0; | ||
277 | } | 273 | } |
278 | 274 | ||
279 | void radeon_driver_irq_uninstall(struct drm_device * dev) | 275 | void radeon_driver_irq_uninstall(struct drm_device * dev) |
@@ -315,6 +311,5 @@ int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value) | |||
315 | return -EINVAL; | 311 | return -EINVAL; |
316 | } | 312 | } |
317 | dev_priv->vblank_crtc = (unsigned int)value; | 313 | dev_priv->vblank_crtc = (unsigned int)value; |
318 | radeon_enable_interrupt(dev); | ||
319 | return 0; | 314 | return 0; |
320 | } | 315 | } |
diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c index 80c01cdfa37d..37870a4a3dc7 100644 --- a/drivers/char/drm/via_drv.c +++ b/drivers/char/drm/via_drv.c | |||
@@ -40,11 +40,13 @@ static struct pci_device_id pciidlist[] = { | |||
40 | static struct drm_driver driver = { | 40 | static struct drm_driver driver = { |
41 | .driver_features = | 41 | .driver_features = |
42 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | | 42 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | |
43 | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, | 43 | DRIVER_IRQ_SHARED, |
44 | .load = via_driver_load, | 44 | .load = via_driver_load, |
45 | .unload = via_driver_unload, | 45 | .unload = via_driver_unload, |
46 | .context_dtor = via_final_context, | 46 | .context_dtor = via_final_context, |
47 | .vblank_wait = via_driver_vblank_wait, | 47 | .get_vblank_counter = via_get_vblank_counter, |
48 | .enable_vblank = via_enable_vblank, | ||
49 | .disable_vblank = via_disable_vblank, | ||
48 | .irq_preinstall = via_driver_irq_preinstall, | 50 | .irq_preinstall = via_driver_irq_preinstall, |
49 | .irq_postinstall = via_driver_irq_postinstall, | 51 | .irq_postinstall = via_driver_irq_postinstall, |
50 | .irq_uninstall = via_driver_irq_uninstall, | 52 | .irq_uninstall = via_driver_irq_uninstall, |
diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h index 2daae81874cd..fe67030e39ac 100644 --- a/drivers/char/drm/via_drv.h +++ b/drivers/char/drm/via_drv.h | |||
@@ -75,6 +75,7 @@ typedef struct drm_via_private { | |||
75 | struct timeval last_vblank; | 75 | struct timeval last_vblank; |
76 | int last_vblank_valid; | 76 | int last_vblank_valid; |
77 | unsigned usec_per_vblank; | 77 | unsigned usec_per_vblank; |
78 | atomic_t vbl_received; | ||
78 | drm_via_state_t hc_state; | 79 | drm_via_state_t hc_state; |
79 | char pci_buf[VIA_PCI_BUF_SIZE]; | 80 | char pci_buf[VIA_PCI_BUF_SIZE]; |
80 | const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; | 81 | const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; |
@@ -130,11 +131,13 @@ extern int via_init_context(struct drm_device * dev, int context); | |||
130 | extern int via_final_context(struct drm_device * dev, int context); | 131 | extern int via_final_context(struct drm_device * dev, int context); |
131 | 132 | ||
132 | extern int via_do_cleanup_map(struct drm_device * dev); | 133 | extern int via_do_cleanup_map(struct drm_device * dev); |
133 | extern int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); | 134 | extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc); |
135 | extern int via_enable_vblank(struct drm_device *dev, int crtc); | ||
136 | extern void via_disable_vblank(struct drm_device *dev, int crtc); | ||
134 | 137 | ||
135 | extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); | 138 | extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); |
136 | extern void via_driver_irq_preinstall(struct drm_device * dev); | 139 | extern void via_driver_irq_preinstall(struct drm_device * dev); |
137 | extern void via_driver_irq_postinstall(struct drm_device * dev); | 140 | extern int via_driver_irq_postinstall(struct drm_device * dev); |
138 | extern void via_driver_irq_uninstall(struct drm_device * dev); | 141 | extern void via_driver_irq_uninstall(struct drm_device * dev); |
139 | 142 | ||
140 | extern int via_dma_cleanup(struct drm_device * dev); | 143 | extern int via_dma_cleanup(struct drm_device * dev); |
diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c index c6bb978a1106..f1ab6fc7c07e 100644 --- a/drivers/char/drm/via_irq.c +++ b/drivers/char/drm/via_irq.c | |||
@@ -92,8 +92,17 @@ static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1}; | |||
92 | static unsigned time_diff(struct timeval *now, struct timeval *then) | 92 | static unsigned time_diff(struct timeval *now, struct timeval *then) |
93 | { | 93 | { |
94 | return (now->tv_usec >= then->tv_usec) ? | 94 | return (now->tv_usec >= then->tv_usec) ? |
95 | now->tv_usec - then->tv_usec : | 95 | now->tv_usec - then->tv_usec : |
96 | 1000000 - (then->tv_usec - now->tv_usec); | 96 | 1000000 - (then->tv_usec - now->tv_usec); |
97 | } | ||
98 | |||
99 | u32 via_get_vblank_counter(struct drm_device *dev, int crtc) | ||
100 | { | ||
101 | drm_via_private_t *dev_priv = dev->dev_private; | ||
102 | if (crtc != 0) | ||
103 | return 0; | ||
104 | |||
105 | return atomic_read(&dev_priv->vbl_received); | ||
97 | } | 106 | } |
98 | 107 | ||
99 | irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) | 108 | irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) |
@@ -108,8 +117,8 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) | |||
108 | 117 | ||
109 | status = VIA_READ(VIA_REG_INTERRUPT); | 118 | status = VIA_READ(VIA_REG_INTERRUPT); |
110 | if (status & VIA_IRQ_VBLANK_PENDING) { | 119 | if (status & VIA_IRQ_VBLANK_PENDING) { |
111 | atomic_inc(&dev->vbl_received); | 120 | atomic_inc(&dev_priv->vbl_received); |
112 | if (!(atomic_read(&dev->vbl_received) & 0x0F)) { | 121 | if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) { |
113 | do_gettimeofday(&cur_vblank); | 122 | do_gettimeofday(&cur_vblank); |
114 | if (dev_priv->last_vblank_valid) { | 123 | if (dev_priv->last_vblank_valid) { |
115 | dev_priv->usec_per_vblank = | 124 | dev_priv->usec_per_vblank = |
@@ -119,12 +128,11 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) | |||
119 | dev_priv->last_vblank = cur_vblank; | 128 | dev_priv->last_vblank = cur_vblank; |
120 | dev_priv->last_vblank_valid = 1; | 129 | dev_priv->last_vblank_valid = 1; |
121 | } | 130 | } |
122 | if (!(atomic_read(&dev->vbl_received) & 0xFF)) { | 131 | if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) { |
123 | DRM_DEBUG("US per vblank is: %u\n", | 132 | DRM_DEBUG("US per vblank is: %u\n", |
124 | dev_priv->usec_per_vblank); | 133 | dev_priv->usec_per_vblank); |
125 | } | 134 | } |
126 | DRM_WAKEUP(&dev->vbl_queue); | 135 | drm_handle_vblank(dev, 0); |
127 | drm_vbl_send_signals(dev); | ||
128 | handled = 1; | 136 | handled = 1; |
129 | } | 137 | } |
130 | 138 | ||
@@ -163,31 +171,34 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv) | |||
163 | } | 171 | } |
164 | } | 172 | } |
165 | 173 | ||
166 | int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) | 174 | int via_enable_vblank(struct drm_device *dev, int crtc) |
167 | { | 175 | { |
168 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; | 176 | drm_via_private_t *dev_priv = dev->dev_private; |
169 | unsigned int cur_vblank; | 177 | u32 status; |
170 | int ret = 0; | ||
171 | 178 | ||
172 | DRM_DEBUG("\n"); | 179 | if (crtc != 0) { |
173 | if (!dev_priv) { | 180 | DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); |
174 | DRM_ERROR("called with no initialization\n"); | ||
175 | return -EINVAL; | 181 | return -EINVAL; |
176 | } | 182 | } |
177 | 183 | ||
178 | viadrv_acknowledge_irqs(dev_priv); | 184 | status = VIA_READ(VIA_REG_INTERRUPT); |
185 | VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE); | ||
179 | 186 | ||
180 | /* Assume that the user has missed the current sequence number | 187 | VIA_WRITE8(0x83d4, 0x11); |
181 | * by about a day rather than she wants to wait for years | 188 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); |
182 | * using vertical blanks... | ||
183 | */ | ||
184 | 189 | ||
185 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, | 190 | return 0; |
186 | (((cur_vblank = atomic_read(&dev->vbl_received)) - | 191 | } |
187 | *sequence) <= (1 << 23))); | ||
188 | 192 | ||
189 | *sequence = cur_vblank; | 193 | void via_disable_vblank(struct drm_device *dev, int crtc) |
190 | return ret; | 194 | { |
195 | drm_via_private_t *dev_priv = dev->dev_private; | ||
196 | |||
197 | VIA_WRITE8(0x83d4, 0x11); | ||
198 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30); | ||
199 | |||
200 | if (crtc != 0) | ||
201 | DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); | ||
191 | } | 202 | } |
192 | 203 | ||
193 | static int | 204 | static int |
@@ -292,23 +303,25 @@ void via_driver_irq_preinstall(struct drm_device * dev) | |||
292 | } | 303 | } |
293 | } | 304 | } |
294 | 305 | ||
295 | void via_driver_irq_postinstall(struct drm_device * dev) | 306 | int via_driver_irq_postinstall(struct drm_device * dev) |
296 | { | 307 | { |
297 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; | 308 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; |
298 | u32 status; | 309 | u32 status; |
299 | 310 | ||
300 | DRM_DEBUG("\n"); | 311 | DRM_DEBUG("via_driver_irq_postinstall\n"); |
301 | if (dev_priv) { | 312 | if (!dev_priv) |
302 | status = VIA_READ(VIA_REG_INTERRUPT); | 313 | return -EINVAL; |
303 | VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL | ||
304 | | dev_priv->irq_enable_mask); | ||
305 | 314 | ||
306 | /* Some magic, oh for some data sheets ! */ | 315 | drm_vblank_init(dev, 1); |
316 | status = VIA_READ(VIA_REG_INTERRUPT); | ||
317 | VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL | ||
318 | | dev_priv->irq_enable_mask); | ||
307 | 319 | ||
308 | VIA_WRITE8(0x83d4, 0x11); | 320 | /* Some magic, oh for some data sheets ! */ |
309 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); | 321 | VIA_WRITE8(0x83d4, 0x11); |
322 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); | ||
310 | 323 | ||
311 | } | 324 | return 0; |
312 | } | 325 | } |
313 | 326 | ||
314 | void via_driver_irq_uninstall(struct drm_device * dev) | 327 | void via_driver_irq_uninstall(struct drm_device * dev) |
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 87532034d105..3f9e10001e19 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
@@ -1031,7 +1031,7 @@ comment "Other IDE chipsets support" | |||
1031 | comment "Note: most of these also require special kernel boot parameters" | 1031 | comment "Note: most of these also require special kernel boot parameters" |
1032 | 1032 | ||
1033 | config BLK_DEV_4DRIVES | 1033 | config BLK_DEV_4DRIVES |
1034 | bool "Generic 4 drives/port support" | 1034 | tristate "Generic 4 drives/port support" |
1035 | help | 1035 | help |
1036 | Certain older chipsets, including the Tekram 690CD, use a single set | 1036 | Certain older chipsets, including the Tekram 690CD, use a single set |
1037 | of I/O ports at 0x1f0 to control up to four drives, instead of the | 1037 | of I/O ports at 0x1f0 to control up to four drives, instead of the |
diff --git a/drivers/ide/arm/bast-ide.c b/drivers/ide/arm/bast-ide.c index ec46c44b061c..a80b9574865e 100644 --- a/drivers/ide/arm/bast-ide.c +++ b/drivers/ide/arm/bast-ide.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <asm/arch/bast-map.h> | 21 | #include <asm/arch/bast-map.h> |
22 | #include <asm/arch/bast-irq.h> | 22 | #include <asm/arch/bast-irq.h> |
23 | 23 | ||
24 | #define DRV_NAME "bast-ide" | ||
25 | |||
24 | static int __init bastide_register(unsigned int base, unsigned int aux, int irq) | 26 | static int __init bastide_register(unsigned int base, unsigned int aux, int irq) |
25 | { | 27 | { |
26 | ide_hwif_t *hwif; | 28 | ide_hwif_t *hwif; |
@@ -41,7 +43,7 @@ static int __init bastide_register(unsigned int base, unsigned int aux, int irq) | |||
41 | hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20); | 43 | hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20); |
42 | hw.irq = irq; | 44 | hw.irq = irq; |
43 | 45 | ||
44 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 46 | hwif = ide_find_port(); |
45 | if (hwif == NULL) | 47 | if (hwif == NULL) |
46 | goto out; | 48 | goto out; |
47 | 49 | ||
@@ -53,6 +55,7 @@ static int __init bastide_register(unsigned int base, unsigned int aux, int irq) | |||
53 | ide_init_port_data(hwif, i); | 55 | ide_init_port_data(hwif, i); |
54 | 56 | ||
55 | ide_init_port_hw(hwif, &hw); | 57 | ide_init_port_hw(hwif, &hw); |
58 | hwif->mmio = 1; | ||
56 | hwif->quirkproc = NULL; | 59 | hwif->quirkproc = NULL; |
57 | 60 | ||
58 | idx[0] = i; | 61 | idx[0] = i; |
@@ -64,6 +67,8 @@ out: | |||
64 | 67 | ||
65 | static int __init bastide_init(void) | 68 | static int __init bastide_init(void) |
66 | { | 69 | { |
70 | unsigned long base = BAST_VA_IDEPRI + BAST_IDE_CS; | ||
71 | |||
67 | /* we can treat the VR1000 and the BAST the same */ | 72 | /* we can treat the VR1000 and the BAST the same */ |
68 | 73 | ||
69 | if (!(machine_is_bast() || machine_is_vr1000())) | 74 | if (!(machine_is_bast() || machine_is_vr1000())) |
@@ -71,6 +76,11 @@ static int __init bastide_init(void) | |||
71 | 76 | ||
72 | printk("BAST: IDE driver, (c) 2003-2004 Simtec Electronics\n"); | 77 | printk("BAST: IDE driver, (c) 2003-2004 Simtec Electronics\n"); |
73 | 78 | ||
79 | if (!request_mem_region(base, 0x400000, DRV_NAME)) { | ||
80 | printk(KERN_ERR "%s: resources busy\n", DRV_NAME); | ||
81 | return -EBUSY; | ||
82 | } | ||
83 | |||
74 | bastide_register(BAST_VA_IDEPRI, BAST_VA_IDEPRIAUX, IRQ_IDE0); | 84 | bastide_register(BAST_VA_IDEPRI, BAST_VA_IDEPRIAUX, IRQ_IDE0); |
75 | bastide_register(BAST_VA_IDESEC, BAST_VA_IDESECAUX, IRQ_IDE1); | 85 | bastide_register(BAST_VA_IDESEC, BAST_VA_IDESECAUX, IRQ_IDE1); |
76 | 86 | ||
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index e816b0ffcfe6..fd12bbe93f11 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c | |||
@@ -400,7 +400,7 @@ icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *e | |||
400 | unsigned long port = (unsigned long)base + info->dataoffset; | 400 | unsigned long port = (unsigned long)base + info->dataoffset; |
401 | ide_hwif_t *hwif; | 401 | ide_hwif_t *hwif; |
402 | 402 | ||
403 | hwif = ide_find_port(port); | 403 | hwif = ide_find_port(); |
404 | if (hwif) { | 404 | if (hwif) { |
405 | int i; | 405 | int i; |
406 | 406 | ||
diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/arm/ide_arm.c index be9ff7334c52..82643df7c49a 100644 --- a/drivers/ide/arm/ide_arm.c +++ b/drivers/ide/arm/ide_arm.c | |||
@@ -34,7 +34,7 @@ static int __init ide_arm_init(void) | |||
34 | ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206); | 34 | ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206); |
35 | hw.irq = IDE_ARM_IRQ; | 35 | hw.irq = IDE_ARM_IRQ; |
36 | 36 | ||
37 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 37 | hwif = ide_find_port(); |
38 | if (hwif) { | 38 | if (hwif) { |
39 | ide_init_port_hw(hwif, &hw); | 39 | ide_init_port_hw(hwif, &hw); |
40 | idx[0] = hwif->index; | 40 | idx[0] = hwif->index; |
diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c index 420fcb78a7cd..666df779a5f4 100644 --- a/drivers/ide/arm/palm_bk3710.c +++ b/drivers/ide/arm/palm_bk3710.c | |||
@@ -96,11 +96,11 @@ static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev, | |||
96 | u16 val16; | 96 | u16 val16; |
97 | 97 | ||
98 | /* DMA Data Setup */ | 98 | /* DMA Data Setup */ |
99 | t0 = (palm_bk3710_udmatimings[mode].cycletime + ide_palm_clk - 1) | 99 | t0 = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].cycletime, |
100 | / ide_palm_clk - 1; | 100 | ide_palm_clk) - 1; |
101 | tenv = (20 + ide_palm_clk - 1) / ide_palm_clk - 1; | 101 | tenv = DIV_ROUND_UP(20, ide_palm_clk) - 1; |
102 | trp = (palm_bk3710_udmatimings[mode].rptime + ide_palm_clk - 1) | 102 | trp = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].rptime, |
103 | / ide_palm_clk - 1; | 103 | ide_palm_clk) - 1; |
104 | 104 | ||
105 | /* udmatim Register */ | 105 | /* udmatim Register */ |
106 | val16 = readw(base + BK3710_UDMATIM) & (dev ? 0xFF0F : 0xFFF0); | 106 | val16 = readw(base + BK3710_UDMATIM) & (dev ? 0xFF0F : 0xFFF0); |
@@ -141,8 +141,8 @@ static void palm_bk3710_setdmamode(void __iomem *base, unsigned int dev, | |||
141 | cycletime = max_t(int, t->cycle, min_cycle); | 141 | cycletime = max_t(int, t->cycle, min_cycle); |
142 | 142 | ||
143 | /* DMA Data Setup */ | 143 | /* DMA Data Setup */ |
144 | t0 = (cycletime + ide_palm_clk - 1) / ide_palm_clk; | 144 | t0 = DIV_ROUND_UP(cycletime, ide_palm_clk); |
145 | td = (t->active + ide_palm_clk - 1) / ide_palm_clk; | 145 | td = DIV_ROUND_UP(t->active, ide_palm_clk); |
146 | tkw = t0 - td - 1; | 146 | tkw = t0 - td - 1; |
147 | td -= 1; | 147 | td -= 1; |
148 | 148 | ||
@@ -168,9 +168,9 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate, | |||
168 | struct ide_timing *t; | 168 | struct ide_timing *t; |
169 | 169 | ||
170 | /* PIO Data Setup */ | 170 | /* PIO Data Setup */ |
171 | t0 = (cycletime + ide_palm_clk - 1) / ide_palm_clk; | 171 | t0 = DIV_ROUND_UP(cycletime, ide_palm_clk); |
172 | t2 = (ide_timing_find_mode(XFER_PIO_0 + mode)->active + | 172 | t2 = DIV_ROUND_UP(ide_timing_find_mode(XFER_PIO_0 + mode)->active, |
173 | ide_palm_clk - 1) / ide_palm_clk; | 173 | ide_palm_clk); |
174 | 174 | ||
175 | t2i = t0 - t2 - 1; | 175 | t2i = t0 - t2 - 1; |
176 | t2 -= 1; | 176 | t2 -= 1; |
@@ -192,8 +192,8 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate, | |||
192 | 192 | ||
193 | /* TASKFILE Setup */ | 193 | /* TASKFILE Setup */ |
194 | t = ide_timing_find_mode(XFER_PIO_0 + mode); | 194 | t = ide_timing_find_mode(XFER_PIO_0 + mode); |
195 | t0 = (t->cyc8b + ide_palm_clk - 1) / ide_palm_clk; | 195 | t0 = DIV_ROUND_UP(t->cyc8b, ide_palm_clk); |
196 | t2 = (t->act8b + ide_palm_clk - 1) / ide_palm_clk; | 196 | t2 = DIV_ROUND_UP(t->act8b, ide_palm_clk); |
197 | 197 | ||
198 | t2i = t0 - t2 - 1; | 198 | t2i = t0 - t2 - 1; |
199 | t2 -= 1; | 199 | t2 -= 1; |
@@ -378,7 +378,7 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev) | |||
378 | hw.irq = irq->start; | 378 | hw.irq = irq->start; |
379 | hw.chipset = ide_palm3710; | 379 | hw.chipset = ide_palm3710; |
380 | 380 | ||
381 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 381 | hwif = ide_find_port(); |
382 | if (hwif == NULL) | 382 | if (hwif == NULL) |
383 | goto out; | 383 | goto out; |
384 | 384 | ||
diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c index b30adcf321c3..2c3d0ec91dc3 100644 --- a/drivers/ide/arm/rapide.c +++ b/drivers/ide/arm/rapide.c | |||
@@ -44,7 +44,7 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
44 | goto release; | 44 | goto release; |
45 | } | 45 | } |
46 | 46 | ||
47 | hwif = ide_find_port((unsigned long)base); | 47 | hwif = ide_find_port(); |
48 | if (hwif) { | 48 | if (hwif) { |
49 | memset(&hw, 0, sizeof(hw)); | 49 | memset(&hw, 0, sizeof(hw)); |
50 | rapide_setup_ports(&hw, base, base + 0x818, 1 << 6, ec->irq); | 50 | rapide_setup_ports(&hw, base, base + 0x818, 1 << 6, ec->irq); |
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c index 31266d278095..790a7759d455 100644 --- a/drivers/ide/cris/ide-cris.c +++ b/drivers/ide/cris/ide-cris.c | |||
@@ -804,7 +804,7 @@ static int __init init_e100_ide(void) | |||
804 | 804 | ||
805 | cris_setup_ports(&hw, cris_ide_base_address(h)); | 805 | cris_setup_ports(&hw, cris_ide_base_address(h)); |
806 | 806 | ||
807 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 807 | hwif = ide_find_port(); |
808 | if (hwif == NULL) | 808 | if (hwif == NULL) |
809 | continue; | 809 | continue; |
810 | ide_init_port_data(hwif, hwif->index); | 810 | ide_init_port_data(hwif, hwif->index); |
diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index 4108ec4ffa7f..92b02b96d7db 100644 --- a/drivers/ide/h8300/ide-h8300.c +++ b/drivers/ide/h8300/ide-h8300.c | |||
@@ -99,8 +99,7 @@ static int __init h8300_ide_init(void) | |||
99 | 99 | ||
100 | hw_setup(&hw); | 100 | hw_setup(&hw); |
101 | 101 | ||
102 | /* register if */ | 102 | hwif = ide_find_port(); |
103 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | ||
104 | if (hwif == NULL) { | 103 | if (hwif == NULL) { |
105 | printk(KERN_ERR "ide-h8300: IDE I/F register failed\n"); | 104 | printk(KERN_ERR "ide-h8300: IDE I/F register failed\n"); |
106 | return -ENOENT; | 105 | return -ENOENT; |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index fe5aefbf8339..1afd95ad4653 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -13,8 +13,8 @@ | |||
13 | * | 13 | * |
14 | * Suggestions are welcome. Patches that work are more welcome though. ;-) | 14 | * Suggestions are welcome. Patches that work are more welcome though. ;-) |
15 | * For those wishing to work on this driver, please be sure you download | 15 | * For those wishing to work on this driver, please be sure you download |
16 | * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI | 16 | * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI |
17 | * (SFF-8020i rev 2.6) standards. These documents can be obtained by | 17 | * (SFF-8020i rev 2.6) standards. These documents can be obtained by |
18 | * anonymous ftp from: | 18 | * anonymous ftp from: |
19 | * ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps | 19 | * ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps |
20 | * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf | 20 | * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf |
@@ -51,7 +51,7 @@ | |||
51 | 51 | ||
52 | static DEFINE_MUTEX(idecd_ref_mutex); | 52 | static DEFINE_MUTEX(idecd_ref_mutex); |
53 | 53 | ||
54 | #define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref) | 54 | #define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref) |
55 | 55 | ||
56 | #define ide_cd_g(disk) \ | 56 | #define ide_cd_g(disk) \ |
57 | container_of((disk)->private_data, struct cdrom_info, driver) | 57 | container_of((disk)->private_data, struct cdrom_info, driver) |
@@ -83,13 +83,12 @@ static void ide_cd_put(struct cdrom_info *cd) | |||
83 | 83 | ||
84 | /* Mark that we've seen a media change, and invalidate our internal | 84 | /* Mark that we've seen a media change, and invalidate our internal |
85 | buffers. */ | 85 | buffers. */ |
86 | static void cdrom_saw_media_change (ide_drive_t *drive) | 86 | static void cdrom_saw_media_change(ide_drive_t *drive) |
87 | { | 87 | { |
88 | struct cdrom_info *cd = drive->driver_data; | 88 | struct cdrom_info *cd = drive->driver_data; |
89 | 89 | ||
90 | cd->cd_flags |= IDE_CD_FLAG_MEDIA_CHANGED; | 90 | cd->cd_flags |= IDE_CD_FLAG_MEDIA_CHANGED; |
91 | cd->cd_flags &= ~IDE_CD_FLAG_TOC_VALID; | 91 | cd->cd_flags &= ~IDE_CD_FLAG_TOC_VALID; |
92 | cd->nsectors_buffered = 0; | ||
93 | } | 92 | } |
94 | 93 | ||
95 | static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, | 94 | static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, |
@@ -101,38 +100,39 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, | |||
101 | return 0; | 100 | return 0; |
102 | 101 | ||
103 | switch (sense->sense_key) { | 102 | switch (sense->sense_key) { |
104 | case NO_SENSE: case RECOVERED_ERROR: | 103 | case NO_SENSE: |
105 | break; | 104 | case RECOVERED_ERROR: |
106 | case NOT_READY: | 105 | break; |
107 | /* | 106 | case NOT_READY: |
108 | * don't care about tray state messages for | 107 | /* |
109 | * e.g. capacity commands or in-progress or | 108 | * don't care about tray state messages for |
110 | * becoming ready | 109 | * e.g. capacity commands or in-progress or |
111 | */ | 110 | * becoming ready |
112 | if (sense->asc == 0x3a || sense->asc == 0x04) | 111 | */ |
113 | break; | 112 | if (sense->asc == 0x3a || sense->asc == 0x04) |
114 | log = 1; | ||
115 | break; | ||
116 | case ILLEGAL_REQUEST: | ||
117 | /* | ||
118 | * don't log START_STOP unit with LoEj set, since | ||
119 | * we cannot reliably check if drive can auto-close | ||
120 | */ | ||
121 | if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24) | ||
122 | break; | ||
123 | log = 1; | ||
124 | break; | ||
125 | case UNIT_ATTENTION: | ||
126 | /* | ||
127 | * Make good and sure we've seen this potential media | ||
128 | * change. Some drives (i.e. Creative) fail to present | ||
129 | * the correct sense key in the error register. | ||
130 | */ | ||
131 | cdrom_saw_media_change(drive); | ||
132 | break; | 113 | break; |
133 | default: | 114 | log = 1; |
134 | log = 1; | 115 | break; |
116 | case ILLEGAL_REQUEST: | ||
117 | /* | ||
118 | * don't log START_STOP unit with LoEj set, since | ||
119 | * we cannot reliably check if drive can auto-close | ||
120 | */ | ||
121 | if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24) | ||
135 | break; | 122 | break; |
123 | log = 1; | ||
124 | break; | ||
125 | case UNIT_ATTENTION: | ||
126 | /* | ||
127 | * Make good and sure we've seen this potential media | ||
128 | * change. Some drives (i.e. Creative) fail to present | ||
129 | * the correct sense key in the error register. | ||
130 | */ | ||
131 | cdrom_saw_media_change(drive); | ||
132 | break; | ||
133 | default: | ||
134 | log = 1; | ||
135 | break; | ||
136 | } | 136 | } |
137 | return log; | 137 | return log; |
138 | } | 138 | } |
@@ -159,8 +159,8 @@ void cdrom_analyze_sense_data(ide_drive_t *drive, | |||
159 | if (sense->sense_key == 0x05 && sense->asc == 0x24) | 159 | if (sense->sense_key == 0x05 && sense->asc == 0x24) |
160 | return; | 160 | return; |
161 | 161 | ||
162 | if (sense->error_code == 0x70) { /* Current Error */ | 162 | if (sense->error_code == 0x70) { /* Current Error */ |
163 | switch(sense->sense_key) { | 163 | switch (sense->sense_key) { |
164 | case MEDIUM_ERROR: | 164 | case MEDIUM_ERROR: |
165 | case VOLUME_OVERFLOW: | 165 | case VOLUME_OVERFLOW: |
166 | case ILLEGAL_REQUEST: | 166 | case ILLEGAL_REQUEST: |
@@ -179,7 +179,7 @@ void cdrom_analyze_sense_data(ide_drive_t *drive, | |||
179 | bio_sectors = 4; | 179 | bio_sectors = 4; |
180 | if (drive->queue->hardsect_size == 2048) | 180 | if (drive->queue->hardsect_size == 2048) |
181 | sector <<= 2; /* Device sector size is 2K */ | 181 | sector <<= 2; /* Device sector size is 2K */ |
182 | sector &= ~(bio_sectors -1); | 182 | sector &= ~(bio_sectors - 1); |
183 | valid = (sector - failed_command->sector) << 9; | 183 | valid = (sector - failed_command->sector) << 9; |
184 | 184 | ||
185 | if (valid < 0) | 185 | if (valid < 0) |
@@ -188,8 +188,8 @@ void cdrom_analyze_sense_data(ide_drive_t *drive, | |||
188 | drive->probed_capacity - sector < 4 * 75) { | 188 | drive->probed_capacity - sector < 4 * 75) { |
189 | set_capacity(info->disk, sector); | 189 | set_capacity(info->disk, sector); |
190 | } | 190 | } |
191 | } | 191 | } |
192 | } | 192 | } |
193 | 193 | ||
194 | ide_cd_log_error(drive->name, failed_command, sense); | 194 | ide_cd_log_error(drive->name, failed_command, sense); |
195 | } | 195 | } |
@@ -230,7 +230,7 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, | |||
230 | (void) ide_do_drive_cmd(drive, rq, ide_preempt); | 230 | (void) ide_do_drive_cmd(drive, rq, ide_preempt); |
231 | } | 231 | } |
232 | 232 | ||
233 | static void cdrom_end_request (ide_drive_t *drive, int uptodate) | 233 | static void cdrom_end_request(ide_drive_t *drive, int uptodate) |
234 | { | 234 | { |
235 | struct request *rq = HWGROUP(drive)->rq; | 235 | struct request *rq = HWGROUP(drive)->rq; |
236 | int nsectors = rq->hard_cur_sectors; | 236 | int nsectors = rq->hard_cur_sectors; |
@@ -293,7 +293,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | |||
293 | { | 293 | { |
294 | struct request *rq = HWGROUP(drive)->rq; | 294 | struct request *rq = HWGROUP(drive)->rq; |
295 | int stat, err, sense_key; | 295 | int stat, err, sense_key; |
296 | 296 | ||
297 | /* Check for errors. */ | 297 | /* Check for errors. */ |
298 | stat = ide_read_status(drive); | 298 | stat = ide_read_status(drive); |
299 | 299 | ||
@@ -334,26 +334,26 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | |||
334 | 334 | ||
335 | /* Check for tray open. */ | 335 | /* Check for tray open. */ |
336 | if (sense_key == NOT_READY) { | 336 | if (sense_key == NOT_READY) { |
337 | cdrom_saw_media_change (drive); | 337 | cdrom_saw_media_change(drive); |
338 | } else if (sense_key == UNIT_ATTENTION) { | 338 | } else if (sense_key == UNIT_ATTENTION) { |
339 | /* Check for media change. */ | 339 | /* Check for media change. */ |
340 | cdrom_saw_media_change (drive); | 340 | cdrom_saw_media_change(drive); |
341 | /*printk("%s: media changed\n",drive->name);*/ | 341 | /*printk("%s: media changed\n",drive->name);*/ |
342 | return 0; | 342 | return 0; |
343 | } else if ((sense_key == ILLEGAL_REQUEST) && | 343 | } else if (sense_key == ILLEGAL_REQUEST && |
344 | (rq->cmd[0] == GPCMD_START_STOP_UNIT)) { | 344 | rq->cmd[0] == GPCMD_START_STOP_UNIT) { |
345 | /* | 345 | /* |
346 | * Don't print error message for this condition-- | 346 | * Don't print error message for this condition-- |
347 | * SFF8090i indicates that 5/24/00 is the correct | 347 | * SFF8090i indicates that 5/24/00 is the correct |
348 | * response to a request to close the tray if the | 348 | * response to a request to close the tray if the |
349 | * drive doesn't have that capability. | 349 | * drive doesn't have that capability. |
350 | * cdrom_log_sense() knows this! | 350 | * cdrom_log_sense() knows this! |
351 | */ | 351 | */ |
352 | } else if (!(rq->cmd_flags & REQ_QUIET)) { | 352 | } else if (!(rq->cmd_flags & REQ_QUIET)) { |
353 | /* Otherwise, print an error. */ | 353 | /* Otherwise, print an error. */ |
354 | ide_dump_status(drive, "packet command error", stat); | 354 | ide_dump_status(drive, "packet command error", stat); |
355 | } | 355 | } |
356 | 356 | ||
357 | rq->cmd_flags |= REQ_FAILED; | 357 | rq->cmd_flags |= REQ_FAILED; |
358 | 358 | ||
359 | /* | 359 | /* |
@@ -374,10 +374,10 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | |||
374 | if (sense_key == NOT_READY) { | 374 | if (sense_key == NOT_READY) { |
375 | /* Tray open. */ | 375 | /* Tray open. */ |
376 | if (rq_data_dir(rq) == READ) { | 376 | if (rq_data_dir(rq) == READ) { |
377 | cdrom_saw_media_change (drive); | 377 | cdrom_saw_media_change(drive); |
378 | 378 | ||
379 | /* Fail the request. */ | 379 | /* Fail the request. */ |
380 | printk ("%s: tray open\n", drive->name); | 380 | printk("%s: tray open\n", drive->name); |
381 | do_end_request = 1; | 381 | do_end_request = 1; |
382 | } else { | 382 | } else { |
383 | struct cdrom_info *info = drive->driver_data; | 383 | struct cdrom_info *info = drive->driver_data; |
@@ -399,7 +399,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | |||
399 | */ | 399 | */ |
400 | spin_lock_irqsave(&ide_lock, flags); | 400 | spin_lock_irqsave(&ide_lock, flags); |
401 | blk_plug_device(drive->queue); | 401 | blk_plug_device(drive->queue); |
402 | spin_unlock_irqrestore(&ide_lock,flags); | 402 | spin_unlock_irqrestore(&ide_lock, flags); |
403 | return 1; | 403 | return 1; |
404 | } | 404 | } |
405 | } | 405 | } |
@@ -407,25 +407,31 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | |||
407 | /* Media change. */ | 407 | /* Media change. */ |
408 | cdrom_saw_media_change (drive); | 408 | cdrom_saw_media_change (drive); |
409 | 409 | ||
410 | /* Arrange to retry the request. | 410 | /* |
411 | But be sure to give up if we've retried | 411 | * Arrange to retry the request. |
412 | too many times. */ | 412 | * But be sure to give up if we've retried |
413 | * too many times. | ||
414 | */ | ||
413 | if (++rq->errors > ERROR_MAX) | 415 | if (++rq->errors > ERROR_MAX) |
414 | do_end_request = 1; | 416 | do_end_request = 1; |
415 | } else if (sense_key == ILLEGAL_REQUEST || | 417 | } else if (sense_key == ILLEGAL_REQUEST || |
416 | sense_key == DATA_PROTECT) { | 418 | sense_key == DATA_PROTECT) { |
417 | /* No point in retrying after an illegal | 419 | /* |
418 | request or data protect error.*/ | 420 | * No point in retrying after an illegal |
419 | ide_dump_status_no_sense (drive, "command error", stat); | 421 | * request or data protect error. |
422 | */ | ||
423 | ide_dump_status_no_sense(drive, "command error", stat); | ||
420 | do_end_request = 1; | 424 | do_end_request = 1; |
421 | } else if (sense_key == MEDIUM_ERROR) { | 425 | } else if (sense_key == MEDIUM_ERROR) { |
422 | /* No point in re-trying a zillion times on a bad | 426 | /* |
423 | * sector... If we got here the error is not correctable */ | 427 | * No point in re-trying a zillion times on a bad |
424 | ide_dump_status_no_sense (drive, "media error (bad sector)", stat); | 428 | * sector... If we got here the error is not correctable |
429 | */ | ||
430 | ide_dump_status_no_sense(drive, "media error (bad sector)", stat); | ||
425 | do_end_request = 1; | 431 | do_end_request = 1; |
426 | } else if (sense_key == BLANK_CHECK) { | 432 | } else if (sense_key == BLANK_CHECK) { |
427 | /* Disk appears blank ?? */ | 433 | /* Disk appears blank ?? */ |
428 | ide_dump_status_no_sense (drive, "media error (blank)", stat); | 434 | ide_dump_status_no_sense(drive, "media error (blank)", stat); |
429 | do_end_request = 1; | 435 | do_end_request = 1; |
430 | } else if ((err & ~ABRT_ERR) != 0) { | 436 | } else if ((err & ~ABRT_ERR) != 0) { |
431 | /* Go to the default handler | 437 | /* Go to the default handler |
@@ -486,18 +492,18 @@ static int cdrom_timer_expiry(ide_drive_t *drive) | |||
486 | * ide_timer_expiry keep polling us for these. | 492 | * ide_timer_expiry keep polling us for these. |
487 | */ | 493 | */ |
488 | switch (rq->cmd[0]) { | 494 | switch (rq->cmd[0]) { |
489 | case GPCMD_BLANK: | 495 | case GPCMD_BLANK: |
490 | case GPCMD_FORMAT_UNIT: | 496 | case GPCMD_FORMAT_UNIT: |
491 | case GPCMD_RESERVE_RZONE_TRACK: | 497 | case GPCMD_RESERVE_RZONE_TRACK: |
492 | case GPCMD_CLOSE_TRACK: | 498 | case GPCMD_CLOSE_TRACK: |
493 | case GPCMD_FLUSH_CACHE: | 499 | case GPCMD_FLUSH_CACHE: |
494 | wait = ATAPI_WAIT_PC; | 500 | wait = ATAPI_WAIT_PC; |
495 | break; | 501 | break; |
496 | default: | 502 | default: |
497 | if (!(rq->cmd_flags & REQ_QUIET)) | 503 | if (!(rq->cmd_flags & REQ_QUIET)) |
498 | printk(KERN_INFO "ide-cd: cmd 0x%x timed out\n", rq->cmd[0]); | 504 | printk(KERN_INFO "ide-cd: cmd 0x%x timed out\n", rq->cmd[0]); |
499 | wait = 0; | 505 | wait = 0; |
500 | break; | 506 | break; |
501 | } | 507 | } |
502 | return wait; | 508 | return wait; |
503 | } | 509 | } |
@@ -557,7 +563,7 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, | |||
557 | HANDLER is the interrupt handler to call when the command completes | 563 | HANDLER is the interrupt handler to call when the command completes |
558 | or there's data ready. */ | 564 | or there's data ready. */ |
559 | #define ATAPI_MIN_CDB_BYTES 12 | 565 | #define ATAPI_MIN_CDB_BYTES 12 |
560 | static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive, | 566 | static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, |
561 | struct request *rq, | 567 | struct request *rq, |
562 | ide_handler_t *handler) | 568 | ide_handler_t *handler) |
563 | { | 569 | { |
@@ -626,47 +632,6 @@ static void ide_cd_drain_data(ide_drive_t *drive, int nsects) | |||
626 | } | 632 | } |
627 | 633 | ||
628 | /* | 634 | /* |
629 | * Buffer up to SECTORS_TO_TRANSFER sectors from the drive in our sector | ||
630 | * buffer. Once the first sector is added, any subsequent sectors are | ||
631 | * assumed to be continuous (until the buffer is cleared). For the first | ||
632 | * sector added, SECTOR is its sector number. (SECTOR is then ignored until | ||
633 | * the buffer is cleared.) | ||
634 | */ | ||
635 | static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector, | ||
636 | int sectors_to_transfer) | ||
637 | { | ||
638 | struct cdrom_info *info = drive->driver_data; | ||
639 | |||
640 | /* Number of sectors to read into the buffer. */ | ||
641 | int sectors_to_buffer = min_t(int, sectors_to_transfer, | ||
642 | (SECTOR_BUFFER_SIZE >> SECTOR_BITS) - | ||
643 | info->nsectors_buffered); | ||
644 | |||
645 | char *dest; | ||
646 | |||
647 | /* If we couldn't get a buffer, don't try to buffer anything... */ | ||
648 | if (info->buffer == NULL) | ||
649 | sectors_to_buffer = 0; | ||
650 | |||
651 | /* If this is the first sector in the buffer, remember its number. */ | ||
652 | if (info->nsectors_buffered == 0) | ||
653 | info->sector_buffered = sector; | ||
654 | |||
655 | /* Read the data into the buffer. */ | ||
656 | dest = info->buffer + info->nsectors_buffered * SECTOR_SIZE; | ||
657 | while (sectors_to_buffer > 0) { | ||
658 | HWIF(drive)->atapi_input_bytes(drive, dest, SECTOR_SIZE); | ||
659 | --sectors_to_buffer; | ||
660 | --sectors_to_transfer; | ||
661 | ++info->nsectors_buffered; | ||
662 | dest += SECTOR_SIZE; | ||
663 | } | ||
664 | |||
665 | /* Throw away any remaining data. */ | ||
666 | ide_cd_drain_data(drive, sectors_to_transfer); | ||
667 | } | ||
668 | |||
669 | /* | ||
670 | * Check the contents of the interrupt reason register from the cdrom | 635 | * Check the contents of the interrupt reason register from the cdrom |
671 | * and attempt to recover if there are problems. Returns 0 if everything's | 636 | * and attempt to recover if there are problems. Returns 0 if everything's |
672 | * ok; nonzero if the request has been terminated. | 637 | * ok; nonzero if the request has been terminated. |
@@ -686,7 +651,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, | |||
686 | 651 | ||
687 | /* Whoops... */ | 652 | /* Whoops... */ |
688 | printk(KERN_ERR "%s: %s: wrong transfer direction!\n", | 653 | printk(KERN_ERR "%s: %s: wrong transfer direction!\n", |
689 | drive->name, __FUNCTION__); | 654 | drive->name, __func__); |
690 | 655 | ||
691 | xf = rw ? hwif->atapi_output_bytes : hwif->atapi_input_bytes; | 656 | xf = rw ? hwif->atapi_output_bytes : hwif->atapi_input_bytes; |
692 | ide_cd_pad_transfer(drive, xf, len); | 657 | ide_cd_pad_transfer(drive, xf, len); |
@@ -699,7 +664,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, | |||
699 | } else { | 664 | } else { |
700 | /* Drive wants a command packet, or invalid ireason... */ | 665 | /* Drive wants a command packet, or invalid ireason... */ |
701 | printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n", | 666 | printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n", |
702 | drive->name, __FUNCTION__, ireason); | 667 | drive->name, __func__, ireason); |
703 | } | 668 | } |
704 | 669 | ||
705 | if (rq->cmd_type == REQ_TYPE_ATA_PC) | 670 | if (rq->cmd_type == REQ_TYPE_ATA_PC) |
@@ -721,7 +686,7 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len) | |||
721 | return 0; | 686 | return 0; |
722 | 687 | ||
723 | printk(KERN_ERR "%s: %s: Bad transfer size %d\n", | 688 | printk(KERN_ERR "%s: %s: Bad transfer size %d\n", |
724 | drive->name, __FUNCTION__, len); | 689 | drive->name, __func__, len); |
725 | 690 | ||
726 | if (cd->cd_flags & IDE_CD_FLAG_LIMIT_NFRAMES) | 691 | if (cd->cd_flags & IDE_CD_FLAG_LIMIT_NFRAMES) |
727 | printk(KERN_ERR " This drive is not supported by " | 692 | printk(KERN_ERR " This drive is not supported by " |
@@ -734,65 +699,6 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len) | |||
734 | return 1; | 699 | return 1; |
735 | } | 700 | } |
736 | 701 | ||
737 | /* | ||
738 | * Try to satisfy some of the current read request from our cached data. | ||
739 | * Returns nonzero if the request has been completed, zero otherwise. | ||
740 | */ | ||
741 | static int cdrom_read_from_buffer (ide_drive_t *drive) | ||
742 | { | ||
743 | struct cdrom_info *info = drive->driver_data; | ||
744 | struct request *rq = HWGROUP(drive)->rq; | ||
745 | unsigned short sectors_per_frame; | ||
746 | |||
747 | sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS; | ||
748 | |||
749 | /* Can't do anything if there's no buffer. */ | ||
750 | if (info->buffer == NULL) return 0; | ||
751 | |||
752 | /* Loop while this request needs data and the next block is present | ||
753 | in our cache. */ | ||
754 | while (rq->nr_sectors > 0 && | ||
755 | rq->sector >= info->sector_buffered && | ||
756 | rq->sector < info->sector_buffered + info->nsectors_buffered) { | ||
757 | if (rq->current_nr_sectors == 0) | ||
758 | cdrom_end_request(drive, 1); | ||
759 | |||
760 | memcpy (rq->buffer, | ||
761 | info->buffer + | ||
762 | (rq->sector - info->sector_buffered) * SECTOR_SIZE, | ||
763 | SECTOR_SIZE); | ||
764 | rq->buffer += SECTOR_SIZE; | ||
765 | --rq->current_nr_sectors; | ||
766 | --rq->nr_sectors; | ||
767 | ++rq->sector; | ||
768 | } | ||
769 | |||
770 | /* If we've satisfied the current request, | ||
771 | terminate it successfully. */ | ||
772 | if (rq->nr_sectors == 0) { | ||
773 | cdrom_end_request(drive, 1); | ||
774 | return -1; | ||
775 | } | ||
776 | |||
777 | /* Move on to the next buffer if needed. */ | ||
778 | if (rq->current_nr_sectors == 0) | ||
779 | cdrom_end_request(drive, 1); | ||
780 | |||
781 | /* If this condition does not hold, then the kluge i use to | ||
782 | represent the number of sectors to skip at the start of a transfer | ||
783 | will fail. I think that this will never happen, but let's be | ||
784 | paranoid and check. */ | ||
785 | if (rq->current_nr_sectors < bio_cur_sectors(rq->bio) && | ||
786 | (rq->sector & (sectors_per_frame - 1))) { | ||
787 | printk(KERN_ERR "%s: cdrom_read_from_buffer: buffer botch (%ld)\n", | ||
788 | drive->name, (long)rq->sector); | ||
789 | cdrom_end_request(drive, 0); | ||
790 | return -1; | ||
791 | } | ||
792 | |||
793 | return 0; | ||
794 | } | ||
795 | |||
796 | static ide_startstop_t cdrom_newpc_intr(ide_drive_t *); | 702 | static ide_startstop_t cdrom_newpc_intr(ide_drive_t *); |
797 | 703 | ||
798 | /* | 704 | /* |
@@ -825,7 +731,7 @@ static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive) | |||
825 | if (rq->current_nr_sectors != | 731 | if (rq->current_nr_sectors != |
826 | bio_cur_sectors(rq->bio)) { | 732 | bio_cur_sectors(rq->bio)) { |
827 | printk(KERN_ERR "%s: %s: buffer botch (%u)\n", | 733 | printk(KERN_ERR "%s: %s: buffer botch (%u)\n", |
828 | drive->name, __FUNCTION__, | 734 | drive->name, __func__, |
829 | rq->current_nr_sectors); | 735 | rq->current_nr_sectors); |
830 | cdrom_end_request(drive, 0); | 736 | cdrom_end_request(drive, 0); |
831 | return ide_stopped; | 737 | return ide_stopped; |
@@ -849,7 +755,7 @@ static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive) | |||
849 | #define IDECD_SEEK_TIMER (5 * WAIT_MIN_SLEEP) /* 100 ms */ | 755 | #define IDECD_SEEK_TIMER (5 * WAIT_MIN_SLEEP) /* 100 ms */ |
850 | #define IDECD_SEEK_TIMEOUT (2 * WAIT_CMD) /* 20 sec */ | 756 | #define IDECD_SEEK_TIMEOUT (2 * WAIT_CMD) /* 20 sec */ |
851 | 757 | ||
852 | static ide_startstop_t cdrom_seek_intr (ide_drive_t *drive) | 758 | static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive) |
853 | { | 759 | { |
854 | struct cdrom_info *info = drive->driver_data; | 760 | struct cdrom_info *info = drive->driver_data; |
855 | int stat; | 761 | int stat; |
@@ -866,14 +772,14 @@ static ide_startstop_t cdrom_seek_intr (ide_drive_t *drive) | |||
866 | * this condition is far too common, to bother | 772 | * this condition is far too common, to bother |
867 | * users about it | 773 | * users about it |
868 | */ | 774 | */ |
869 | /* printk("%s: disabled DSC seek overlap\n", drive->name);*/ | 775 | /* printk("%s: disabled DSC seek overlap\n", drive->name);*/ |
870 | drive->dsc_overlap = 0; | 776 | drive->dsc_overlap = 0; |
871 | } | 777 | } |
872 | } | 778 | } |
873 | return ide_stopped; | 779 | return ide_stopped; |
874 | } | 780 | } |
875 | 781 | ||
876 | static ide_startstop_t cdrom_start_seek_continuation (ide_drive_t *drive) | 782 | static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive) |
877 | { | 783 | { |
878 | struct request *rq = HWGROUP(drive)->rq; | 784 | struct request *rq = HWGROUP(drive)->rq; |
879 | sector_t frame = rq->sector; | 785 | sector_t frame = rq->sector; |
@@ -888,7 +794,7 @@ static ide_startstop_t cdrom_start_seek_continuation (ide_drive_t *drive) | |||
888 | return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr); | 794 | return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr); |
889 | } | 795 | } |
890 | 796 | ||
891 | static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block) | 797 | static ide_startstop_t cdrom_start_seek(ide_drive_t *drive, unsigned int block) |
892 | { | 798 | { |
893 | struct cdrom_info *info = drive->driver_data; | 799 | struct cdrom_info *info = drive->driver_data; |
894 | 800 | ||
@@ -897,9 +803,11 @@ static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block) | |||
897 | return cdrom_start_packet_command(drive, 0, cdrom_start_seek_continuation); | 803 | return cdrom_start_packet_command(drive, 0, cdrom_start_seek_continuation); |
898 | } | 804 | } |
899 | 805 | ||
900 | /* Fix up a possibly partially-processed request so that we can | 806 | /* |
901 | start it over entirely, or even put it back on the request queue. */ | 807 | * Fix up a possibly partially-processed request so that we can |
902 | static void restore_request (struct request *rq) | 808 | * start it over entirely, or even put it back on the request queue. |
809 | */ | ||
810 | static void restore_request(struct request *rq) | ||
903 | { | 811 | { |
904 | if (rq->buffer != bio_data(rq->bio)) { | 812 | if (rq->buffer != bio_data(rq->bio)) { |
905 | sector_t n = (rq->buffer - (char *) bio_data(rq->bio)) / SECTOR_SIZE; | 813 | sector_t n = (rq->buffer - (char *) bio_data(rq->bio)) / SECTOR_SIZE; |
@@ -950,7 +858,7 @@ int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq) | |||
950 | error = ide_do_drive_cmd(drive, rq, ide_wait); | 858 | error = ide_do_drive_cmd(drive, rq, ide_wait); |
951 | time = jiffies - time; | 859 | time = jiffies - time; |
952 | 860 | ||
953 | /* FIXME: we should probably abort/retry or something | 861 | /* FIXME: we should probably abort/retry or something |
954 | * in case of failure */ | 862 | * in case of failure */ |
955 | if (rq->cmd_flags & REQ_FAILED) { | 863 | if (rq->cmd_flags & REQ_FAILED) { |
956 | /* The request failed. Retry if it was due to a unit | 864 | /* The request failed. Retry if it was due to a unit |
@@ -1057,7 +965,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
1057 | if (rq->current_nr_sectors > 0) { | 965 | if (rq->current_nr_sectors > 0) { |
1058 | printk(KERN_ERR "%s: %s: data underrun " | 966 | printk(KERN_ERR "%s: %s: data underrun " |
1059 | "(%d blocks)\n", | 967 | "(%d blocks)\n", |
1060 | drive->name, __FUNCTION__, | 968 | drive->name, __func__, |
1061 | rq->current_nr_sectors); | 969 | rq->current_nr_sectors); |
1062 | if (!write) | 970 | if (!write) |
1063 | rq->cmd_flags |= REQ_FAILED; | 971 | rq->cmd_flags |= REQ_FAILED; |
@@ -1134,11 +1042,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
1134 | if (!ptr) { | 1042 | if (!ptr) { |
1135 | if (blk_fs_request(rq) && !write) | 1043 | if (blk_fs_request(rq) && !write) |
1136 | /* | 1044 | /* |
1137 | * If the buffers are full, cache the rest | 1045 | * If the buffers are full, pipe the rest into |
1138 | * of the data in our internal buffer. | 1046 | * oblivion. */ |
1139 | */ | 1047 | ide_cd_drain_data(drive, thislen >> 9); |
1140 | cdrom_buffer_sectors(drive, rq->sector, | ||
1141 | thislen >> 9); | ||
1142 | else { | 1048 | else { |
1143 | printk(KERN_ERR "%s: confused, missing data\n", | 1049 | printk(KERN_ERR "%s: confused, missing data\n", |
1144 | drive->name); | 1050 | drive->name); |
@@ -1243,10 +1149,6 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) | |||
1243 | * weirdness which might be present in the request packet. | 1149 | * weirdness which might be present in the request packet. |
1244 | */ | 1150 | */ |
1245 | restore_request(rq); | 1151 | restore_request(rq); |
1246 | |||
1247 | /* Satisfy whatever we can of this request from our cache. */ | ||
1248 | if (cdrom_read_from_buffer(drive)) | ||
1249 | return ide_stopped; | ||
1250 | } | 1152 | } |
1251 | 1153 | ||
1252 | /* | 1154 | /* |
@@ -1262,9 +1164,6 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) | |||
1262 | } else | 1164 | } else |
1263 | cd->dma = drive->using_dma; | 1165 | cd->dma = drive->using_dma; |
1264 | 1166 | ||
1265 | /* Clear the local sector buffer. */ | ||
1266 | cd->nsectors_buffered = 0; | ||
1267 | |||
1268 | if (write) | 1167 | if (write) |
1269 | cd->devinfo.media_written = 1; | 1168 | cd->devinfo.media_written = 1; |
1270 | 1169 | ||
@@ -1320,7 +1219,7 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) | |||
1320 | * cdrom driver request routine. | 1219 | * cdrom driver request routine. |
1321 | */ | 1220 | */ |
1322 | static ide_startstop_t | 1221 | static ide_startstop_t |
1323 | ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block) | 1222 | ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq, sector_t block) |
1324 | { | 1223 | { |
1325 | ide_startstop_t action; | 1224 | ide_startstop_t action; |
1326 | struct cdrom_info *info = drive->driver_data; | 1225 | struct cdrom_info *info = drive->driver_data; |
@@ -1335,13 +1234,13 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block) | |||
1335 | ide_stall_queue(drive, IDECD_SEEK_TIMER); | 1234 | ide_stall_queue(drive, IDECD_SEEK_TIMER); |
1336 | return ide_stopped; | 1235 | return ide_stopped; |
1337 | } | 1236 | } |
1338 | printk (KERN_ERR "%s: DSC timeout\n", drive->name); | 1237 | printk(KERN_ERR "%s: DSC timeout\n", drive->name); |
1339 | } | 1238 | } |
1340 | info->cd_flags &= ~IDE_CD_FLAG_SEEKING; | 1239 | info->cd_flags &= ~IDE_CD_FLAG_SEEKING; |
1341 | } | 1240 | } |
1342 | if ((rq_data_dir(rq) == READ) && IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap) { | 1241 | if ((rq_data_dir(rq) == READ) && IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap) |
1343 | action = cdrom_start_seek(drive, block); | 1242 | action = cdrom_start_seek(drive, block); |
1344 | } else | 1243 | else |
1345 | action = cdrom_start_rw(drive, rq); | 1244 | action = cdrom_start_rw(drive, rq); |
1346 | info->last_block = block; | 1245 | info->last_block = block; |
1347 | return action; | 1246 | return action; |
@@ -1374,7 +1273,7 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block) | |||
1374 | */ | 1273 | */ |
1375 | 1274 | ||
1376 | static | 1275 | static |
1377 | void msf_from_bcd (struct atapi_msf *msf) | 1276 | void msf_from_bcd(struct atapi_msf *msf) |
1378 | { | 1277 | { |
1379 | msf->minute = BCD2BIN(msf->minute); | 1278 | msf->minute = BCD2BIN(msf->minute); |
1380 | msf->second = BCD2BIN(msf->second); | 1279 | msf->second = BCD2BIN(msf->second); |
@@ -1474,7 +1373,7 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense) | |||
1474 | /* Try to allocate space. */ | 1373 | /* Try to allocate space. */ |
1475 | toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL); | 1374 | toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL); |
1476 | if (toc == NULL) { | 1375 | if (toc == NULL) { |
1477 | printk (KERN_ERR "%s: No cdrom TOC buffer!\n", drive->name); | 1376 | printk(KERN_ERR "%s: No cdrom TOC buffer!\n", drive->name); |
1478 | return -ENOMEM; | 1377 | return -ENOMEM; |
1479 | } | 1378 | } |
1480 | info->toc = toc; | 1379 | info->toc = toc; |
@@ -1569,9 +1468,9 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense) | |||
1569 | toc->ent[i].track = BCD2BIN(toc->ent[i].track); | 1468 | toc->ent[i].track = BCD2BIN(toc->ent[i].track); |
1570 | msf_from_bcd(&toc->ent[i].addr.msf); | 1469 | msf_from_bcd(&toc->ent[i].addr.msf); |
1571 | } | 1470 | } |
1572 | toc->ent[i].addr.lba = msf_to_lba (toc->ent[i].addr.msf.minute, | 1471 | toc->ent[i].addr.lba = msf_to_lba(toc->ent[i].addr.msf.minute, |
1573 | toc->ent[i].addr.msf.second, | 1472 | toc->ent[i].addr.msf.second, |
1574 | toc->ent[i].addr.msf.frame); | 1473 | toc->ent[i].addr.msf.frame); |
1575 | } | 1474 | } |
1576 | 1475 | ||
1577 | /* Read the multisession information. */ | 1476 | /* Read the multisession information. */ |
@@ -1595,9 +1494,9 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense) | |||
1595 | if (stat) | 1494 | if (stat) |
1596 | return stat; | 1495 | return stat; |
1597 | 1496 | ||
1598 | msf_from_bcd (&ms_tmp.ent.addr.msf); | 1497 | msf_from_bcd(&ms_tmp.ent.addr.msf); |
1599 | toc->last_session_lba = msf_to_lba(ms_tmp.ent.addr.msf.minute, | 1498 | toc->last_session_lba = msf_to_lba(ms_tmp.ent.addr.msf.minute, |
1600 | ms_tmp.ent.addr.msf.second, | 1499 | ms_tmp.ent.addr.msf.second, |
1601 | ms_tmp.ent.addr.msf.frame); | 1500 | ms_tmp.ent.addr.msf.frame); |
1602 | } | 1501 | } |
1603 | 1502 | ||
@@ -1679,7 +1578,7 @@ static struct cdrom_device_ops ide_cdrom_dops = { | |||
1679 | .generic_packet = ide_cdrom_packet, | 1578 | .generic_packet = ide_cdrom_packet, |
1680 | }; | 1579 | }; |
1681 | 1580 | ||
1682 | static int ide_cdrom_register (ide_drive_t *drive, int nslots) | 1581 | static int ide_cdrom_register(ide_drive_t *drive, int nslots) |
1683 | { | 1582 | { |
1684 | struct cdrom_info *info = drive->driver_data; | 1583 | struct cdrom_info *info = drive->driver_data; |
1685 | struct cdrom_device_info *devinfo = &info->devinfo; | 1584 | struct cdrom_device_info *devinfo = &info->devinfo; |
@@ -1698,7 +1597,7 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots) | |||
1698 | } | 1597 | } |
1699 | 1598 | ||
1700 | static | 1599 | static |
1701 | int ide_cdrom_probe_capabilities (ide_drive_t *drive) | 1600 | int ide_cdrom_probe_capabilities(ide_drive_t *drive) |
1702 | { | 1601 | { |
1703 | struct cdrom_info *cd = drive->driver_data; | 1602 | struct cdrom_info *cd = drive->driver_data; |
1704 | struct cdrom_device_info *cdi = &cd->devinfo; | 1603 | struct cdrom_device_info *cdi = &cd->devinfo; |
@@ -1870,7 +1769,7 @@ static int ide_cdrom_prep_pc(struct request *rq) | |||
1870 | rq->errors = ILLEGAL_REQUEST; | 1769 | rq->errors = ILLEGAL_REQUEST; |
1871 | return BLKPREP_KILL; | 1770 | return BLKPREP_KILL; |
1872 | } | 1771 | } |
1873 | 1772 | ||
1874 | return BLKPREP_OK; | 1773 | return BLKPREP_OK; |
1875 | } | 1774 | } |
1876 | 1775 | ||
@@ -1948,7 +1847,7 @@ static unsigned int ide_cd_flags(struct hd_driveid *id) | |||
1948 | } | 1847 | } |
1949 | 1848 | ||
1950 | static | 1849 | static |
1951 | int ide_cdrom_setup (ide_drive_t *drive) | 1850 | int ide_cdrom_setup(ide_drive_t *drive) |
1952 | { | 1851 | { |
1953 | struct cdrom_info *cd = drive->driver_data; | 1852 | struct cdrom_info *cd = drive->driver_data; |
1954 | struct cdrom_device_info *cdi = &cd->devinfo; | 1853 | struct cdrom_device_info *cdi = &cd->devinfo; |
@@ -1979,7 +1878,7 @@ int ide_cdrom_setup (ide_drive_t *drive) | |||
1979 | else if (cd->cd_flags & IDE_CD_FLAG_SANYO_3CD) | 1878 | else if (cd->cd_flags & IDE_CD_FLAG_SANYO_3CD) |
1980 | cdi->sanyo_slot = 3; /* 3 => use CD in slot 0 */ | 1879 | cdi->sanyo_slot = 3; /* 3 => use CD in slot 0 */ |
1981 | 1880 | ||
1982 | nslots = ide_cdrom_probe_capabilities (drive); | 1881 | nslots = ide_cdrom_probe_capabilities(drive); |
1983 | 1882 | ||
1984 | /* | 1883 | /* |
1985 | * set correct block size | 1884 | * set correct block size |
@@ -1991,7 +1890,7 @@ int ide_cdrom_setup (ide_drive_t *drive) | |||
1991 | drive->dsc_overlap = (drive->next != drive); | 1890 | drive->dsc_overlap = (drive->next != drive); |
1992 | 1891 | ||
1993 | if (ide_cdrom_register(drive, nslots)) { | 1892 | if (ide_cdrom_register(drive, nslots)) { |
1994 | printk (KERN_ERR "%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name); | 1893 | printk(KERN_ERR "%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name); |
1995 | cd->devinfo.handle = NULL; | 1894 | cd->devinfo.handle = NULL; |
1996 | return 1; | 1895 | return 1; |
1997 | } | 1896 | } |
@@ -1999,19 +1898,6 @@ int ide_cdrom_setup (ide_drive_t *drive) | |||
1999 | return 0; | 1898 | return 0; |
2000 | } | 1899 | } |
2001 | 1900 | ||
2002 | #ifdef CONFIG_IDE_PROC_FS | ||
2003 | static | ||
2004 | sector_t ide_cdrom_capacity (ide_drive_t *drive) | ||
2005 | { | ||
2006 | unsigned long capacity, sectors_per_frame; | ||
2007 | |||
2008 | if (cdrom_read_capacity(drive, &capacity, §ors_per_frame, NULL)) | ||
2009 | return 0; | ||
2010 | |||
2011 | return capacity * sectors_per_frame; | ||
2012 | } | ||
2013 | #endif | ||
2014 | |||
2015 | static void ide_cd_remove(ide_drive_t *drive) | 1901 | static void ide_cd_remove(ide_drive_t *drive) |
2016 | { | 1902 | { |
2017 | struct cdrom_info *info = drive->driver_data; | 1903 | struct cdrom_info *info = drive->driver_data; |
@@ -2030,7 +1916,6 @@ static void ide_cd_release(struct kref *kref) | |||
2030 | ide_drive_t *drive = info->drive; | 1916 | ide_drive_t *drive = info->drive; |
2031 | struct gendisk *g = info->disk; | 1917 | struct gendisk *g = info->disk; |
2032 | 1918 | ||
2033 | kfree(info->buffer); | ||
2034 | kfree(info->toc); | 1919 | kfree(info->toc); |
2035 | if (devinfo->handle == drive) | 1920 | if (devinfo->handle == drive) |
2036 | unregister_cdrom(devinfo); | 1921 | unregister_cdrom(devinfo); |
@@ -2045,14 +1930,24 @@ static void ide_cd_release(struct kref *kref) | |||
2045 | static int ide_cd_probe(ide_drive_t *); | 1930 | static int ide_cd_probe(ide_drive_t *); |
2046 | 1931 | ||
2047 | #ifdef CONFIG_IDE_PROC_FS | 1932 | #ifdef CONFIG_IDE_PROC_FS |
1933 | static sector_t ide_cdrom_capacity(ide_drive_t *drive) | ||
1934 | { | ||
1935 | unsigned long capacity, sectors_per_frame; | ||
1936 | |||
1937 | if (cdrom_read_capacity(drive, &capacity, §ors_per_frame, NULL)) | ||
1938 | return 0; | ||
1939 | |||
1940 | return capacity * sectors_per_frame; | ||
1941 | } | ||
1942 | |||
2048 | static int proc_idecd_read_capacity | 1943 | static int proc_idecd_read_capacity |
2049 | (char *page, char **start, off_t off, int count, int *eof, void *data) | 1944 | (char *page, char **start, off_t off, int count, int *eof, void *data) |
2050 | { | 1945 | { |
2051 | ide_drive_t *drive = data; | 1946 | ide_drive_t *drive = data; |
2052 | int len; | 1947 | int len; |
2053 | 1948 | ||
2054 | len = sprintf(page,"%llu\n", (long long)ide_cdrom_capacity(drive)); | 1949 | len = sprintf(page, "%llu\n", (long long)ide_cdrom_capacity(drive)); |
2055 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | 1950 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
2056 | } | 1951 | } |
2057 | 1952 | ||
2058 | static ide_proc_entry_t idecd_proc[] = { | 1953 | static ide_proc_entry_t idecd_proc[] = { |
@@ -2081,20 +1976,17 @@ static ide_driver_t ide_cdrom_driver = { | |||
2081 | #endif | 1976 | #endif |
2082 | }; | 1977 | }; |
2083 | 1978 | ||
2084 | static int idecd_open(struct inode * inode, struct file * file) | 1979 | static int idecd_open(struct inode *inode, struct file *file) |
2085 | { | 1980 | { |
2086 | struct gendisk *disk = inode->i_bdev->bd_disk; | 1981 | struct gendisk *disk = inode->i_bdev->bd_disk; |
2087 | struct cdrom_info *info; | 1982 | struct cdrom_info *info; |
2088 | int rc = -ENOMEM; | 1983 | int rc = -ENOMEM; |
2089 | 1984 | ||
2090 | if (!(info = ide_cd_get(disk))) | 1985 | info = ide_cd_get(disk); |
1986 | if (!info) | ||
2091 | return -ENXIO; | 1987 | return -ENXIO; |
2092 | 1988 | ||
2093 | if (!info->buffer) | 1989 | rc = cdrom_open(&info->devinfo, inode, file); |
2094 | info->buffer = kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL|__GFP_REPEAT); | ||
2095 | |||
2096 | if (info->buffer) | ||
2097 | rc = cdrom_open(&info->devinfo, inode, file); | ||
2098 | 1990 | ||
2099 | if (rc < 0) | 1991 | if (rc < 0) |
2100 | ide_cd_put(info); | 1992 | ide_cd_put(info); |
@@ -2102,12 +1994,12 @@ static int idecd_open(struct inode * inode, struct file * file) | |||
2102 | return rc; | 1994 | return rc; |
2103 | } | 1995 | } |
2104 | 1996 | ||
2105 | static int idecd_release(struct inode * inode, struct file * file) | 1997 | static int idecd_release(struct inode *inode, struct file *file) |
2106 | { | 1998 | { |
2107 | struct gendisk *disk = inode->i_bdev->bd_disk; | 1999 | struct gendisk *disk = inode->i_bdev->bd_disk; |
2108 | struct cdrom_info *info = ide_cd_g(disk); | 2000 | struct cdrom_info *info = ide_cd_g(disk); |
2109 | 2001 | ||
2110 | cdrom_release (&info->devinfo, file); | 2002 | cdrom_release(&info->devinfo, file); |
2111 | 2003 | ||
2112 | ide_cd_put(info); | 2004 | ide_cd_put(info); |
2113 | 2005 | ||
@@ -2139,7 +2031,7 @@ static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg) | |||
2139 | struct packet_command cgc; | 2031 | struct packet_command cgc; |
2140 | char buffer[16]; | 2032 | char buffer[16]; |
2141 | int stat; | 2033 | int stat; |
2142 | char spindown; | 2034 | char spindown; |
2143 | 2035 | ||
2144 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN); | 2036 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN); |
2145 | 2037 | ||
@@ -2148,12 +2040,12 @@ static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg) | |||
2148 | return stat; | 2040 | return stat; |
2149 | 2041 | ||
2150 | spindown = buffer[11] & 0x0f; | 2042 | spindown = buffer[11] & 0x0f; |
2151 | if (copy_to_user((void __user *)arg, &spindown, sizeof (char))) | 2043 | if (copy_to_user((void __user *)arg, &spindown, sizeof(char))) |
2152 | return -EFAULT; | 2044 | return -EFAULT; |
2153 | return 0; | 2045 | return 0; |
2154 | } | 2046 | } |
2155 | 2047 | ||
2156 | static int idecd_ioctl (struct inode *inode, struct file *file, | 2048 | static int idecd_ioctl(struct inode *inode, struct file *file, |
2157 | unsigned int cmd, unsigned long arg) | 2049 | unsigned int cmd, unsigned long arg) |
2158 | { | 2050 | { |
2159 | struct block_device *bdev = inode->i_bdev; | 2051 | struct block_device *bdev = inode->i_bdev; |
@@ -2161,13 +2053,13 @@ static int idecd_ioctl (struct inode *inode, struct file *file, | |||
2161 | int err; | 2053 | int err; |
2162 | 2054 | ||
2163 | switch (cmd) { | 2055 | switch (cmd) { |
2164 | case CDROMSETSPINDOWN: | 2056 | case CDROMSETSPINDOWN: |
2165 | return idecd_set_spindown(&info->devinfo, arg); | 2057 | return idecd_set_spindown(&info->devinfo, arg); |
2166 | case CDROMGETSPINDOWN: | 2058 | case CDROMGETSPINDOWN: |
2167 | return idecd_get_spindown(&info->devinfo, arg); | 2059 | return idecd_get_spindown(&info->devinfo, arg); |
2168 | default: | 2060 | default: |
2169 | break; | 2061 | break; |
2170 | } | 2062 | } |
2171 | 2063 | ||
2172 | err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg); | 2064 | err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg); |
2173 | if (err == -EINVAL) | 2065 | if (err == -EINVAL) |
@@ -2193,16 +2085,16 @@ static int idecd_revalidate_disk(struct gendisk *disk) | |||
2193 | } | 2085 | } |
2194 | 2086 | ||
2195 | static struct block_device_operations idecd_ops = { | 2087 | static struct block_device_operations idecd_ops = { |
2196 | .owner = THIS_MODULE, | 2088 | .owner = THIS_MODULE, |
2197 | .open = idecd_open, | 2089 | .open = idecd_open, |
2198 | .release = idecd_release, | 2090 | .release = idecd_release, |
2199 | .ioctl = idecd_ioctl, | 2091 | .ioctl = idecd_ioctl, |
2200 | .media_changed = idecd_media_changed, | 2092 | .media_changed = idecd_media_changed, |
2201 | .revalidate_disk= idecd_revalidate_disk | 2093 | .revalidate_disk = idecd_revalidate_disk |
2202 | }; | 2094 | }; |
2203 | 2095 | ||
2204 | /* options */ | 2096 | /* options */ |
2205 | static char *ignore = NULL; | 2097 | static char *ignore; |
2206 | 2098 | ||
2207 | module_param(ignore, charp, 0400); | 2099 | module_param(ignore, charp, 0400); |
2208 | MODULE_DESCRIPTION("ATAPI CD-ROM Driver"); | 2100 | MODULE_DESCRIPTION("ATAPI CD-ROM Driver"); |
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index 22e3751a681e..a58801c4484d 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h | |||
@@ -119,10 +119,6 @@ struct cdrom_info { | |||
119 | 119 | ||
120 | struct atapi_toc *toc; | 120 | struct atapi_toc *toc; |
121 | 121 | ||
122 | unsigned long sector_buffered; | ||
123 | unsigned long nsectors_buffered; | ||
124 | unsigned char *buffer; | ||
125 | |||
126 | /* The result of the last successful request sense command | 122 | /* The result of the last successful request sense command |
127 | on this device. */ | 123 | on this device. */ |
128 | struct request_sense sense_data; | 124 | struct request_sense sense_data; |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 39501d130256..8e08d083fce9 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -16,8 +16,6 @@ | |||
16 | 16 | ||
17 | #define IDEDISK_VERSION "1.18" | 17 | #define IDEDISK_VERSION "1.18" |
18 | 18 | ||
19 | //#define DEBUG | ||
20 | |||
21 | #include <linux/module.h> | 19 | #include <linux/module.h> |
22 | #include <linux/types.h> | 20 | #include <linux/types.h> |
23 | #include <linux/string.h> | 21 | #include <linux/string.h> |
@@ -88,7 +86,7 @@ static void ide_disk_put(struct ide_disk_obj *idkp) | |||
88 | * | 86 | * |
89 | * It is called only once for each drive. | 87 | * It is called only once for each drive. |
90 | */ | 88 | */ |
91 | static int lba_capacity_is_ok (struct hd_driveid *id) | 89 | static int lba_capacity_is_ok(struct hd_driveid *id) |
92 | { | 90 | { |
93 | unsigned long lba_sects, chs_sects, head, tail; | 91 | unsigned long lba_sects, chs_sects, head, tail; |
94 | 92 | ||
@@ -176,7 +174,8 @@ static void ide_tf_set_cmd(ide_drive_t *drive, ide_task_t *task, u8 dma) | |||
176 | * __ide_do_rw_disk() issues READ and WRITE commands to a disk, | 174 | * __ide_do_rw_disk() issues READ and WRITE commands to a disk, |
177 | * using LBA if supported, or CHS otherwise, to address sectors. | 175 | * using LBA if supported, or CHS otherwise, to address sectors. |
178 | */ | 176 | */ |
179 | static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, sector_t block) | 177 | static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, |
178 | sector_t block) | ||
180 | { | 179 | { |
181 | ide_hwif_t *hwif = HWIF(drive); | 180 | ide_hwif_t *hwif = HWIF(drive); |
182 | unsigned int dma = drive->using_dma; | 181 | unsigned int dma = drive->using_dma; |
@@ -228,7 +227,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
228 | tf->device = (block >> 8) & 0xf; | 227 | tf->device = (block >> 8) & 0xf; |
229 | } | 228 | } |
230 | } else { | 229 | } else { |
231 | unsigned int sect,head,cyl,track; | 230 | unsigned int sect, head, cyl, track; |
231 | |||
232 | track = (int)block / drive->sect; | 232 | track = (int)block / drive->sect; |
233 | sect = (int)block % drive->sect + 1; | 233 | sect = (int)block % drive->sect + 1; |
234 | head = track % drive->head; | 234 | head = track % drive->head; |
@@ -271,7 +271,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
271 | * 1073741822 == 549756 MB or 48bit addressing fake drive | 271 | * 1073741822 == 549756 MB or 48bit addressing fake drive |
272 | */ | 272 | */ |
273 | 273 | ||
274 | static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block) | 274 | static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq, |
275 | sector_t block) | ||
275 | { | 276 | { |
276 | ide_hwif_t *hwif = HWIF(drive); | 277 | ide_hwif_t *hwif = HWIF(drive); |
277 | 278 | ||
@@ -452,7 +453,7 @@ static void idedisk_check_hpa(ide_drive_t *drive) | |||
452 | * in above order (i.e., if value of higher priority is available, | 453 | * in above order (i.e., if value of higher priority is available, |
453 | * reset will be ignored). | 454 | * reset will be ignored). |
454 | */ | 455 | */ |
455 | static void init_idedisk_capacity (ide_drive_t *drive) | 456 | static void init_idedisk_capacity(ide_drive_t *drive) |
456 | { | 457 | { |
457 | struct hd_driveid *id = drive->id; | 458 | struct hd_driveid *id = drive->id; |
458 | /* | 459 | /* |
@@ -479,7 +480,7 @@ static void init_idedisk_capacity (ide_drive_t *drive) | |||
479 | } | 480 | } |
480 | } | 481 | } |
481 | 482 | ||
482 | static sector_t idedisk_capacity (ide_drive_t *drive) | 483 | static sector_t idedisk_capacity(ide_drive_t *drive) |
483 | { | 484 | { |
484 | return drive->capacity64 - drive->sect0; | 485 | return drive->capacity64 - drive->sect0; |
485 | } | 486 | } |
@@ -524,10 +525,11 @@ static int proc_idedisk_read_cache | |||
524 | int len; | 525 | int len; |
525 | 526 | ||
526 | if (drive->id_read) | 527 | if (drive->id_read) |
527 | len = sprintf(out,"%i\n", drive->id->buf_size / 2); | 528 | len = sprintf(out, "%i\n", drive->id->buf_size / 2); |
528 | else | 529 | else |
529 | len = sprintf(out,"(none)\n"); | 530 | len = sprintf(out, "(none)\n"); |
530 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | 531 | |
532 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); | ||
531 | } | 533 | } |
532 | 534 | ||
533 | static int proc_idedisk_read_capacity | 535 | static int proc_idedisk_read_capacity |
@@ -536,54 +538,52 @@ static int proc_idedisk_read_capacity | |||
536 | ide_drive_t*drive = (ide_drive_t *)data; | 538 | ide_drive_t*drive = (ide_drive_t *)data; |
537 | int len; | 539 | int len; |
538 | 540 | ||
539 | len = sprintf(page,"%llu\n", (long long)idedisk_capacity(drive)); | 541 | len = sprintf(page, "%llu\n", (long long)idedisk_capacity(drive)); |
540 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | 542 | |
543 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); | ||
541 | } | 544 | } |
542 | 545 | ||
543 | static int proc_idedisk_read_smart_thresholds | 546 | static int proc_idedisk_read_smart(char *page, char **start, off_t off, |
544 | (char *page, char **start, off_t off, int count, int *eof, void *data) | 547 | int count, int *eof, void *data, u8 sub_cmd) |
545 | { | 548 | { |
546 | ide_drive_t *drive = (ide_drive_t *)data; | 549 | ide_drive_t *drive = (ide_drive_t *)data; |
547 | int len = 0, i = 0; | 550 | int len = 0, i = 0; |
548 | 551 | ||
549 | if (get_smart_data(drive, page, SMART_READ_THRESHOLDS) == 0) { | 552 | if (get_smart_data(drive, page, sub_cmd) == 0) { |
550 | unsigned short *val = (unsigned short *) page; | 553 | unsigned short *val = (unsigned short *) page; |
551 | char *out = ((char *)val) + (SECTOR_WORDS * 4); | 554 | char *out = ((char *)val) + (SECTOR_WORDS * 4); |
552 | page = out; | 555 | page = out; |
553 | do { | 556 | do { |
554 | out += sprintf(out, "%04x%c", le16_to_cpu(*val), (++i & 7) ? ' ' : '\n'); | 557 | out += sprintf(out, "%04x%c", le16_to_cpu(*val), |
558 | (++i & 7) ? ' ' : '\n'); | ||
555 | val += 1; | 559 | val += 1; |
556 | } while (i < (SECTOR_WORDS * 2)); | 560 | } while (i < (SECTOR_WORDS * 2)); |
557 | len = out - page; | 561 | len = out - page; |
558 | } | 562 | } |
559 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | 563 | |
564 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); | ||
560 | } | 565 | } |
561 | 566 | ||
562 | static int proc_idedisk_read_smart_values | 567 | static int proc_idedisk_read_sv |
563 | (char *page, char **start, off_t off, int count, int *eof, void *data) | 568 | (char *page, char **start, off_t off, int count, int *eof, void *data) |
564 | { | 569 | { |
565 | ide_drive_t *drive = (ide_drive_t *)data; | 570 | return proc_idedisk_read_smart(page, start, off, count, eof, data, |
566 | int len = 0, i = 0; | 571 | SMART_READ_VALUES); |
572 | } | ||
567 | 573 | ||
568 | if (get_smart_data(drive, page, SMART_READ_VALUES) == 0) { | 574 | static int proc_idedisk_read_st |
569 | unsigned short *val = (unsigned short *) page; | 575 | (char *page, char **start, off_t off, int count, int *eof, void *data) |
570 | char *out = ((char *)val) + (SECTOR_WORDS * 4); | 576 | { |
571 | page = out; | 577 | return proc_idedisk_read_smart(page, start, off, count, eof, data, |
572 | do { | 578 | SMART_READ_THRESHOLDS); |
573 | out += sprintf(out, "%04x%c", le16_to_cpu(*val), (++i & 7) ? ' ' : '\n'); | ||
574 | val += 1; | ||
575 | } while (i < (SECTOR_WORDS * 2)); | ||
576 | len = out - page; | ||
577 | } | ||
578 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | ||
579 | } | 579 | } |
580 | 580 | ||
581 | static ide_proc_entry_t idedisk_proc[] = { | 581 | static ide_proc_entry_t idedisk_proc[] = { |
582 | { "cache", S_IFREG|S_IRUGO, proc_idedisk_read_cache, NULL }, | 582 | { "cache", S_IFREG|S_IRUGO, proc_idedisk_read_cache, NULL }, |
583 | { "capacity", S_IFREG|S_IRUGO, proc_idedisk_read_capacity, NULL }, | 583 | { "capacity", S_IFREG|S_IRUGO, proc_idedisk_read_capacity, NULL }, |
584 | { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL }, | 584 | { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL }, |
585 | { "smart_values", S_IFREG|S_IRUSR, proc_idedisk_read_smart_values, NULL }, | 585 | { "smart_values", S_IFREG|S_IRUSR, proc_idedisk_read_sv, NULL }, |
586 | { "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_smart_thresholds, NULL }, | 586 | { "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_st, NULL }, |
587 | { NULL, 0, NULL, NULL } | 587 | { NULL, 0, NULL, NULL } |
588 | }; | 588 | }; |
589 | #endif /* CONFIG_IDE_PROC_FS */ | 589 | #endif /* CONFIG_IDE_PROC_FS */ |
@@ -625,12 +625,13 @@ static int set_multcount(ide_drive_t *drive, int arg) | |||
625 | if (drive->special.b.set_multmode) | 625 | if (drive->special.b.set_multmode) |
626 | return -EBUSY; | 626 | return -EBUSY; |
627 | 627 | ||
628 | ide_init_drive_cmd (&rq); | 628 | ide_init_drive_cmd(&rq); |
629 | rq.cmd_type = REQ_TYPE_ATA_TASKFILE; | 629 | rq.cmd_type = REQ_TYPE_ATA_TASKFILE; |
630 | 630 | ||
631 | drive->mult_req = arg; | 631 | drive->mult_req = arg; |
632 | drive->special.b.set_multmode = 1; | 632 | drive->special.b.set_multmode = 1; |
633 | (void) ide_do_drive_cmd (drive, &rq, ide_wait); | 633 | (void)ide_do_drive_cmd(drive, &rq, ide_wait); |
634 | |||
634 | return (drive->mult_count == arg) ? 0 : -EIO; | 635 | return (drive->mult_count == arg) ? 0 : -EIO; |
635 | } | 636 | } |
636 | 637 | ||
@@ -706,7 +707,7 @@ static int write_cache(ide_drive_t *drive, int arg) | |||
706 | return err; | 707 | return err; |
707 | } | 708 | } |
708 | 709 | ||
709 | static int do_idedisk_flushcache (ide_drive_t *drive) | 710 | static int do_idedisk_flushcache(ide_drive_t *drive) |
710 | { | 711 | { |
711 | ide_task_t args; | 712 | ide_task_t args; |
712 | 713 | ||
@@ -719,7 +720,7 @@ static int do_idedisk_flushcache (ide_drive_t *drive) | |||
719 | return ide_no_data_taskfile(drive, &args); | 720 | return ide_no_data_taskfile(drive, &args); |
720 | } | 721 | } |
721 | 722 | ||
722 | static int set_acoustic (ide_drive_t *drive, int arg) | 723 | static int set_acoustic(ide_drive_t *drive, int arg) |
723 | { | 724 | { |
724 | ide_task_t args; | 725 | ide_task_t args; |
725 | 726 | ||
@@ -753,7 +754,7 @@ static int set_lba_addressing(ide_drive_t *drive, int arg) | |||
753 | return 0; | 754 | return 0; |
754 | 755 | ||
755 | if (!idedisk_supports_lba48(drive->id)) | 756 | if (!idedisk_supports_lba48(drive->id)) |
756 | return -EIO; | 757 | return -EIO; |
757 | drive->addressing = arg; | 758 | drive->addressing = arg; |
758 | return 0; | 759 | return 0; |
759 | } | 760 | } |
@@ -763,23 +764,35 @@ static void idedisk_add_settings(ide_drive_t *drive) | |||
763 | { | 764 | { |
764 | struct hd_driveid *id = drive->id; | 765 | struct hd_driveid *id = drive->id; |
765 | 766 | ||
766 | ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, &drive->bios_cyl, NULL); | 767 | ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, |
767 | ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL); | 768 | &drive->bios_cyl, NULL); |
768 | ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL); | 769 | ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, |
769 | ide_add_setting(drive, "address", SETTING_RW, TYPE_BYTE, 0, 2, 1, 1, &drive->addressing, set_lba_addressing); | 770 | &drive->bios_head, NULL); |
770 | ide_add_setting(drive, "multcount", SETTING_RW, TYPE_BYTE, 0, id->max_multsect, 1, 1, &drive->mult_count, set_multcount); | 771 | ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, |
771 | ide_add_setting(drive, "nowerr", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->nowerr, set_nowerr); | 772 | &drive->bios_sect, NULL); |
772 | ide_add_setting(drive, "lun", SETTING_RW, TYPE_INT, 0, 7, 1, 1, &drive->lun, NULL); | 773 | ide_add_setting(drive, "address", SETTING_RW, TYPE_BYTE, 0, 2, 1, 1, |
773 | ide_add_setting(drive, "wcache", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->wcache, write_cache); | 774 | &drive->addressing, set_lba_addressing); |
774 | ide_add_setting(drive, "acoustic", SETTING_RW, TYPE_BYTE, 0, 254, 1, 1, &drive->acoustic, set_acoustic); | 775 | ide_add_setting(drive, "multcount", SETTING_RW, TYPE_BYTE, 0, |
775 | ide_add_setting(drive, "failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, &drive->failures, NULL); | 776 | id->max_multsect, 1, 1, &drive->mult_count, |
776 | ide_add_setting(drive, "max_failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, &drive->max_failures, NULL); | 777 | set_multcount); |
778 | ide_add_setting(drive, "nowerr", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, | ||
779 | &drive->nowerr, set_nowerr); | ||
780 | ide_add_setting(drive, "lun", SETTING_RW, TYPE_INT, 0, 7, 1, 1, | ||
781 | &drive->lun, NULL); | ||
782 | ide_add_setting(drive, "wcache", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, | ||
783 | &drive->wcache, write_cache); | ||
784 | ide_add_setting(drive, "acoustic", SETTING_RW, TYPE_BYTE, 0, 254, 1, 1, | ||
785 | &drive->acoustic, set_acoustic); | ||
786 | ide_add_setting(drive, "failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, | ||
787 | &drive->failures, NULL); | ||
788 | ide_add_setting(drive, "max_failures", SETTING_RW, TYPE_INT, 0, 65535, | ||
789 | 1, 1, &drive->max_failures, NULL); | ||
777 | } | 790 | } |
778 | #else | 791 | #else |
779 | static inline void idedisk_add_settings(ide_drive_t *drive) { ; } | 792 | static inline void idedisk_add_settings(ide_drive_t *drive) { ; } |
780 | #endif | 793 | #endif |
781 | 794 | ||
782 | static void idedisk_setup (ide_drive_t *drive) | 795 | static void idedisk_setup(ide_drive_t *drive) |
783 | { | 796 | { |
784 | ide_hwif_t *hwif = drive->hwif; | 797 | ide_hwif_t *hwif = drive->hwif; |
785 | struct hd_driveid *id = drive->id; | 798 | struct hd_driveid *id = drive->id; |
@@ -792,11 +805,10 @@ static void idedisk_setup (ide_drive_t *drive) | |||
792 | 805 | ||
793 | if (drive->removable) { | 806 | if (drive->removable) { |
794 | /* | 807 | /* |
795 | * Removable disks (eg. SYQUEST); ignore 'WD' drives | 808 | * Removable disks (eg. SYQUEST); ignore 'WD' drives |
796 | */ | 809 | */ |
797 | if (id->model[0] != 'W' || id->model[1] != 'D') { | 810 | if (id->model[0] != 'W' || id->model[1] != 'D') |
798 | drive->doorlocking = 1; | 811 | drive->doorlocking = 1; |
799 | } | ||
800 | } | 812 | } |
801 | 813 | ||
802 | (void)set_lba_addressing(drive, 1); | 814 | (void)set_lba_addressing(drive, 1); |
@@ -810,10 +822,11 @@ static void idedisk_setup (ide_drive_t *drive) | |||
810 | blk_queue_max_sectors(drive->queue, max_s); | 822 | blk_queue_max_sectors(drive->queue, max_s); |
811 | } | 823 | } |
812 | 824 | ||
813 | printk(KERN_INFO "%s: max request size: %dKiB\n", drive->name, drive->queue->max_sectors / 2); | 825 | printk(KERN_INFO "%s: max request size: %dKiB\n", drive->name, |
826 | drive->queue->max_sectors / 2); | ||
814 | 827 | ||
815 | /* calculate drive capacity, and select LBA if possible */ | 828 | /* calculate drive capacity, and select LBA if possible */ |
816 | init_idedisk_capacity (drive); | 829 | init_idedisk_capacity(drive); |
817 | 830 | ||
818 | /* limit drive capacity to 137GB if LBA48 cannot be used */ | 831 | /* limit drive capacity to 137GB if LBA48 cannot be used */ |
819 | if (drive->addressing == 0 && drive->capacity64 > 1ULL << 28) { | 832 | if (drive->addressing == 0 && drive->capacity64 > 1ULL << 28) { |
@@ -826,9 +839,9 @@ static void idedisk_setup (ide_drive_t *drive) | |||
826 | 839 | ||
827 | if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && drive->addressing) { | 840 | if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && drive->addressing) { |
828 | if (drive->capacity64 > 1ULL << 28) { | 841 | if (drive->capacity64 > 1ULL << 28) { |
829 | printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode will" | 842 | printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode" |
830 | " be used for accessing sectors > %u\n", | 843 | " will be used for accessing sectors " |
831 | drive->name, 1 << 28); | 844 | "> %u\n", drive->name, 1 << 28); |
832 | } else | 845 | } else |
833 | drive->addressing = 0; | 846 | drive->addressing = 0; |
834 | } | 847 | } |
@@ -837,7 +850,8 @@ static void idedisk_setup (ide_drive_t *drive) | |||
837 | * if possible, give fdisk access to more of the drive, | 850 | * if possible, give fdisk access to more of the drive, |
838 | * by correcting bios_cyls: | 851 | * by correcting bios_cyls: |
839 | */ | 852 | */ |
840 | capacity = idedisk_capacity (drive); | 853 | capacity = idedisk_capacity(drive); |
854 | |||
841 | if (!drive->forced_geom) { | 855 | if (!drive->forced_geom) { |
842 | 856 | ||
843 | if (idedisk_supports_lba48(drive->id)) { | 857 | if (idedisk_supports_lba48(drive->id)) { |
@@ -993,7 +1007,8 @@ static int idedisk_open(struct inode *inode, struct file *filp) | |||
993 | struct ide_disk_obj *idkp; | 1007 | struct ide_disk_obj *idkp; |
994 | ide_drive_t *drive; | 1008 | ide_drive_t *drive; |
995 | 1009 | ||
996 | if (!(idkp = ide_disk_get(disk))) | 1010 | idkp = ide_disk_get(disk); |
1011 | if (idkp == NULL) | ||
997 | return -ENXIO; | 1012 | return -ENXIO; |
998 | 1013 | ||
999 | drive = idkp->drive; | 1014 | drive = idkp->drive; |
@@ -1115,13 +1130,13 @@ static int idedisk_revalidate_disk(struct gendisk *disk) | |||
1115 | } | 1130 | } |
1116 | 1131 | ||
1117 | static struct block_device_operations idedisk_ops = { | 1132 | static struct block_device_operations idedisk_ops = { |
1118 | .owner = THIS_MODULE, | 1133 | .owner = THIS_MODULE, |
1119 | .open = idedisk_open, | 1134 | .open = idedisk_open, |
1120 | .release = idedisk_release, | 1135 | .release = idedisk_release, |
1121 | .ioctl = idedisk_ioctl, | 1136 | .ioctl = idedisk_ioctl, |
1122 | .getgeo = idedisk_getgeo, | 1137 | .getgeo = idedisk_getgeo, |
1123 | .media_changed = idedisk_media_changed, | 1138 | .media_changed = idedisk_media_changed, |
1124 | .revalidate_disk= idedisk_revalidate_disk | 1139 | .revalidate_disk = idedisk_revalidate_disk |
1125 | }; | 1140 | }; |
1126 | 1141 | ||
1127 | MODULE_DESCRIPTION("ATA DISK Driver"); | 1142 | MODULE_DESCRIPTION("ATA DISK Driver"); |
@@ -1184,7 +1199,7 @@ failed: | |||
1184 | return -ENODEV; | 1199 | return -ENODEV; |
1185 | } | 1200 | } |
1186 | 1201 | ||
1187 | static void __exit idedisk_exit (void) | 1202 | static void __exit idedisk_exit(void) |
1188 | { | 1203 | { |
1189 | driver_unregister(&idedisk_driver.gen_driver); | 1204 | driver_unregister(&idedisk_driver.gen_driver); |
1190 | } | 1205 | } |
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index d61e5788d310..8757e5ef6c95 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
@@ -703,17 +703,8 @@ static int ide_tune_dma(ide_drive_t *drive) | |||
703 | 703 | ||
704 | speed = ide_max_dma_mode(drive); | 704 | speed = ide_max_dma_mode(drive); |
705 | 705 | ||
706 | if (!speed) { | 706 | if (!speed) |
707 | /* is this really correct/needed? */ | 707 | return 0; |
708 | if ((hwif->host_flags & IDE_HFLAG_CY82C693) && | ||
709 | ide_dma_good_drive(drive)) | ||
710 | return 1; | ||
711 | else | ||
712 | return 0; | ||
713 | } | ||
714 | |||
715 | if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE) | ||
716 | return 1; | ||
717 | 708 | ||
718 | if (ide_set_dma_mode(drive, speed)) | 709 | if (ide_set_dma_mode(drive, speed)) |
719 | return 0; | 710 | return 0; |
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 5f133dfb541c..ed19a8bbd2d2 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -396,7 +396,7 @@ static void idefloppy_retry_pc(ide_drive_t *drive) | |||
396 | } | 396 | } |
397 | 397 | ||
398 | /* The usual interrupt handler called during a packet command. */ | 398 | /* The usual interrupt handler called during a packet command. */ |
399 | static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) | 399 | static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) |
400 | { | 400 | { |
401 | idefloppy_floppy_t *floppy = drive->driver_data; | 401 | idefloppy_floppy_t *floppy = drive->driver_data; |
402 | ide_hwif_t *hwif = drive->hwif; | 402 | ide_hwif_t *hwif = drive->hwif; |
@@ -1596,13 +1596,13 @@ static int idefloppy_revalidate_disk(struct gendisk *disk) | |||
1596 | } | 1596 | } |
1597 | 1597 | ||
1598 | static struct block_device_operations idefloppy_ops = { | 1598 | static struct block_device_operations idefloppy_ops = { |
1599 | .owner = THIS_MODULE, | 1599 | .owner = THIS_MODULE, |
1600 | .open = idefloppy_open, | 1600 | .open = idefloppy_open, |
1601 | .release = idefloppy_release, | 1601 | .release = idefloppy_release, |
1602 | .ioctl = idefloppy_ioctl, | 1602 | .ioctl = idefloppy_ioctl, |
1603 | .getgeo = idefloppy_getgeo, | 1603 | .getgeo = idefloppy_getgeo, |
1604 | .media_changed = idefloppy_media_changed, | 1604 | .media_changed = idefloppy_media_changed, |
1605 | .revalidate_disk= idefloppy_revalidate_disk | 1605 | .revalidate_disk = idefloppy_revalidate_disk |
1606 | }; | 1606 | }; |
1607 | 1607 | ||
1608 | static int ide_floppy_probe(ide_drive_t *drive) | 1608 | static int ide_floppy_probe(ide_drive_t *drive) |
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c index 25fda0a3263f..19f63e393d18 100644 --- a/drivers/ide/ide-generic.c +++ b/drivers/ide/ide-generic.c | |||
@@ -33,7 +33,7 @@ static ssize_t store_add(struct class *cls, const char *buf, size_t n) | |||
33 | if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3) | 33 | if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3) |
34 | return -EINVAL; | 34 | return -EINVAL; |
35 | 35 | ||
36 | hwif = ide_find_port(base); | 36 | hwif = ide_find_port(); |
37 | if (hwif == NULL) | 37 | if (hwif == NULL) |
38 | return -ENOENT; | 38 | return -ENOENT; |
39 | 39 | ||
@@ -90,11 +90,21 @@ static int __init ide_generic_init(void) | |||
90 | int i; | 90 | int i; |
91 | 91 | ||
92 | for (i = 0; i < MAX_HWIFS; i++) { | 92 | for (i = 0; i < MAX_HWIFS; i++) { |
93 | ide_hwif_t *hwif = &ide_hwifs[i]; | 93 | ide_hwif_t *hwif; |
94 | unsigned long io_addr = ide_default_io_base(i); | 94 | unsigned long io_addr = ide_default_io_base(i); |
95 | hw_regs_t hw; | 95 | hw_regs_t hw; |
96 | 96 | ||
97 | if (hwif->chipset == ide_unknown && io_addr) { | 97 | if (io_addr) { |
98 | /* | ||
99 | * Skip probing if the corresponding | ||
100 | * slot is already occupied. | ||
101 | */ | ||
102 | hwif = ide_find_port(); | ||
103 | if (hwif == NULL || hwif->index != i) { | ||
104 | idx[i] = 0xff; | ||
105 | continue; | ||
106 | } | ||
107 | |||
98 | memset(&hw, 0, sizeof(hw)); | 108 | memset(&hw, 0, sizeof(hw)); |
99 | ide_std_init_ports(&hw, io_addr, io_addr + 0x206); | 109 | ide_std_init_ports(&hw, io_addr, io_addr + 0x206); |
100 | hw.irq = ide_default_irq(io_addr); | 110 | hw.irq = ide_default_irq(io_addr); |
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 31e5afadb7e9..51d181ee9cf7 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -726,10 +726,6 @@ static ide_startstop_t do_special (ide_drive_t *drive) | |||
726 | s->b.set_tune = 0; | 726 | s->b.set_tune = 0; |
727 | 727 | ||
728 | if (set_pio_mode_abuse(drive->hwif, req_pio)) { | 728 | if (set_pio_mode_abuse(drive->hwif, req_pio)) { |
729 | |||
730 | if (hwif->set_pio_mode == NULL) | ||
731 | return ide_stopped; | ||
732 | |||
733 | /* | 729 | /* |
734 | * take ide_lock for drive->[no_]unmask/[no_]io_32bit | 730 | * take ide_lock for drive->[no_]unmask/[no_]io_32bit |
735 | */ | 731 | */ |
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 7031a8dcf692..c859de77aa8f 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c | |||
@@ -274,16 +274,6 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode) | |||
274 | if (overridden) | 274 | if (overridden) |
275 | printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n", | 275 | printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n", |
276 | drive->name); | 276 | drive->name); |
277 | |||
278 | /* | ||
279 | * Conservative "downgrade" for all pre-ATA2 drives | ||
280 | */ | ||
281 | if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_DOWNGRADE) == 0 && | ||
282 | pio_mode && pio_mode < 4) { | ||
283 | pio_mode--; | ||
284 | printk(KERN_INFO "%s: applying conservative " | ||
285 | "PIO \"downgrade\"\n", drive->name); | ||
286 | } | ||
287 | } | 277 | } |
288 | 278 | ||
289 | if (pio_mode > max_mode) | 279 | if (pio_mode > max_mode) |
@@ -300,7 +290,8 @@ void ide_set_pio(ide_drive_t *drive, u8 req_pio) | |||
300 | ide_hwif_t *hwif = drive->hwif; | 290 | ide_hwif_t *hwif = drive->hwif; |
301 | u8 host_pio, pio; | 291 | u8 host_pio, pio; |
302 | 292 | ||
303 | if (hwif->set_pio_mode == NULL) | 293 | if (hwif->set_pio_mode == NULL || |
294 | (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)) | ||
304 | return; | 295 | return; |
305 | 296 | ||
306 | BUG_ON(hwif->pio_mask == 0x00); | 297 | BUG_ON(hwif->pio_mask == 0x00); |
@@ -353,6 +344,9 @@ int ide_set_pio_mode(ide_drive_t *drive, const u8 mode) | |||
353 | { | 344 | { |
354 | ide_hwif_t *hwif = drive->hwif; | 345 | ide_hwif_t *hwif = drive->hwif; |
355 | 346 | ||
347 | if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE) | ||
348 | return 0; | ||
349 | |||
356 | if (hwif->set_pio_mode == NULL) | 350 | if (hwif->set_pio_mode == NULL) |
357 | return -1; | 351 | return -1; |
358 | 352 | ||
@@ -380,6 +374,9 @@ int ide_set_dma_mode(ide_drive_t *drive, const u8 mode) | |||
380 | { | 374 | { |
381 | ide_hwif_t *hwif = drive->hwif; | 375 | ide_hwif_t *hwif = drive->hwif; |
382 | 376 | ||
377 | if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE) | ||
378 | return 0; | ||
379 | |||
383 | if (hwif->set_dma_mode == NULL) | 380 | if (hwif->set_dma_mode == NULL) |
384 | return -1; | 381 | return -1; |
385 | 382 | ||
@@ -410,7 +407,8 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) | |||
410 | { | 407 | { |
411 | ide_hwif_t *hwif = drive->hwif; | 408 | ide_hwif_t *hwif = drive->hwif; |
412 | 409 | ||
413 | if (hwif->set_dma_mode == NULL) | 410 | if (hwif->set_dma_mode == NULL || |
411 | (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)) | ||
414 | return -1; | 412 | return -1; |
415 | 413 | ||
416 | rate = ide_rate_filter(drive, rate); | 414 | rate = ide_rate_filter(drive, rate); |
diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c index 34c2ad36ce54..8a178a55a027 100644 --- a/drivers/ide/ide-pnp.c +++ b/drivers/ide/ide-pnp.c | |||
@@ -11,7 +11,7 @@ | |||
11 | * | 11 | * |
12 | * You should have received a copy of the GNU General Public License | 12 | * You should have received a copy of the GNU General Public License |
13 | * (for example /usr/src/linux/COPYING); if not, write to the Free | 13 | * (for example /usr/src/linux/COPYING); if not, write to the Free |
14 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 14 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
@@ -20,12 +20,12 @@ | |||
20 | 20 | ||
21 | /* Add your devices here :)) */ | 21 | /* Add your devices here :)) */ |
22 | static struct pnp_device_id idepnp_devices[] = { | 22 | static struct pnp_device_id idepnp_devices[] = { |
23 | /* Generic ESDI/IDE/ATA compatible hard disk controller */ | 23 | /* Generic ESDI/IDE/ATA compatible hard disk controller */ |
24 | {.id = "PNP0600", .driver_data = 0}, | 24 | {.id = "PNP0600", .driver_data = 0}, |
25 | {.id = ""} | 25 | {.id = ""} |
26 | }; | 26 | }; |
27 | 27 | ||
28 | static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id) | 28 | static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) |
29 | { | 29 | { |
30 | hw_regs_t hw; | 30 | hw_regs_t hw; |
31 | ide_hwif_t *hwif; | 31 | ide_hwif_t *hwif; |
@@ -38,7 +38,7 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id | |||
38 | pnp_port_start(dev, 1)); | 38 | pnp_port_start(dev, 1)); |
39 | hw.irq = pnp_irq(dev, 0); | 39 | hw.irq = pnp_irq(dev, 0); |
40 | 40 | ||
41 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 41 | hwif = ide_find_port(); |
42 | if (hwif) { | 42 | if (hwif) { |
43 | u8 index = hwif->index; | 43 | u8 index = hwif->index; |
44 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; | 44 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; |
@@ -47,7 +47,7 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id | |||
47 | ide_init_port_hw(hwif, &hw); | 47 | ide_init_port_hw(hwif, &hw); |
48 | 48 | ||
49 | printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index); | 49 | printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index); |
50 | pnp_set_drvdata(dev,hwif); | 50 | pnp_set_drvdata(dev, hwif); |
51 | 51 | ||
52 | ide_device_add(idx, NULL); | 52 | ide_device_add(idx, NULL); |
53 | 53 | ||
@@ -57,7 +57,7 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id | |||
57 | return -1; | 57 | return -1; |
58 | } | 58 | } |
59 | 59 | ||
60 | static void idepnp_remove(struct pnp_dev * dev) | 60 | static void idepnp_remove(struct pnp_dev *dev) |
61 | { | 61 | { |
62 | ide_hwif_t *hwif = pnp_get_drvdata(dev); | 62 | ide_hwif_t *hwif = pnp_get_drvdata(dev); |
63 | 63 | ||
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 6a196c27b0aa..875429728021 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -1444,6 +1444,54 @@ static int ide_sysfs_register_port(ide_hwif_t *hwif) | |||
1444 | return rc; | 1444 | return rc; |
1445 | } | 1445 | } |
1446 | 1446 | ||
1447 | /** | ||
1448 | * ide_find_port_slot - find free ide_hwifs[] slot | ||
1449 | * @d: IDE port info | ||
1450 | * | ||
1451 | * Return the new hwif. If we are out of free slots return NULL. | ||
1452 | */ | ||
1453 | |||
1454 | ide_hwif_t *ide_find_port_slot(const struct ide_port_info *d) | ||
1455 | { | ||
1456 | ide_hwif_t *hwif; | ||
1457 | int i; | ||
1458 | u8 bootable = (d && (d->host_flags & IDE_HFLAG_NON_BOOTABLE)) ? 0 : 1; | ||
1459 | |||
1460 | /* | ||
1461 | * Claim an unassigned slot. | ||
1462 | * | ||
1463 | * Give preference to claiming other slots before claiming ide0/ide1, | ||
1464 | * just in case there's another interface yet-to-be-scanned | ||
1465 | * which uses ports 0x1f0/0x170 (the ide0/ide1 defaults). | ||
1466 | * | ||
1467 | * Unless there is a bootable card that does not use the standard | ||
1468 | * ports 0x1f0/0x170 (the ide0/ide1 defaults). | ||
1469 | */ | ||
1470 | if (bootable) { | ||
1471 | i = (d && (d->host_flags & IDE_HFLAG_QD_2ND_PORT)) ? 1 : 0; | ||
1472 | |||
1473 | for (; i < MAX_HWIFS; i++) { | ||
1474 | hwif = &ide_hwifs[i]; | ||
1475 | if (hwif->chipset == ide_unknown) | ||
1476 | return hwif; | ||
1477 | } | ||
1478 | } else { | ||
1479 | for (i = 2; i < MAX_HWIFS; i++) { | ||
1480 | hwif = &ide_hwifs[i]; | ||
1481 | if (hwif->chipset == ide_unknown) | ||
1482 | return hwif; | ||
1483 | } | ||
1484 | for (i = 0; i < 2 && i < MAX_HWIFS; i++) { | ||
1485 | hwif = &ide_hwifs[i]; | ||
1486 | if (hwif->chipset == ide_unknown) | ||
1487 | return hwif; | ||
1488 | } | ||
1489 | } | ||
1490 | |||
1491 | return NULL; | ||
1492 | } | ||
1493 | EXPORT_SYMBOL_GPL(ide_find_port_slot); | ||
1494 | |||
1447 | int ide_device_add_all(u8 *idx, const struct ide_port_info *d) | 1495 | int ide_device_add_all(u8 *idx, const struct ide_port_info *d) |
1448 | { | 1496 | { |
1449 | ide_hwif_t *hwif, *mate = NULL; | 1497 | ide_hwif_t *hwif, *mate = NULL; |
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index edd7f186dc4d..5d3562b45039 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c | |||
@@ -47,28 +47,28 @@ static int proc_ide_read_imodel | |||
47 | const char *name; | 47 | const char *name; |
48 | 48 | ||
49 | switch (hwif->chipset) { | 49 | switch (hwif->chipset) { |
50 | case ide_generic: name = "generic"; break; | 50 | case ide_generic: name = "generic"; break; |
51 | case ide_pci: name = "pci"; break; | 51 | case ide_pci: name = "pci"; break; |
52 | case ide_cmd640: name = "cmd640"; break; | 52 | case ide_cmd640: name = "cmd640"; break; |
53 | case ide_dtc2278: name = "dtc2278"; break; | 53 | case ide_dtc2278: name = "dtc2278"; break; |
54 | case ide_ali14xx: name = "ali14xx"; break; | 54 | case ide_ali14xx: name = "ali14xx"; break; |
55 | case ide_qd65xx: name = "qd65xx"; break; | 55 | case ide_qd65xx: name = "qd65xx"; break; |
56 | case ide_umc8672: name = "umc8672"; break; | 56 | case ide_umc8672: name = "umc8672"; break; |
57 | case ide_ht6560b: name = "ht6560b"; break; | 57 | case ide_ht6560b: name = "ht6560b"; break; |
58 | case ide_rz1000: name = "rz1000"; break; | 58 | case ide_rz1000: name = "rz1000"; break; |
59 | case ide_trm290: name = "trm290"; break; | 59 | case ide_trm290: name = "trm290"; break; |
60 | case ide_cmd646: name = "cmd646"; break; | 60 | case ide_cmd646: name = "cmd646"; break; |
61 | case ide_cy82c693: name = "cy82c693"; break; | 61 | case ide_cy82c693: name = "cy82c693"; break; |
62 | case ide_4drives: name = "4drives"; break; | 62 | case ide_4drives: name = "4drives"; break; |
63 | case ide_pmac: name = "mac-io"; break; | 63 | case ide_pmac: name = "mac-io"; break; |
64 | case ide_au1xxx: name = "au1xxx"; break; | 64 | case ide_au1xxx: name = "au1xxx"; break; |
65 | case ide_palm3710: name = "palm3710"; break; | 65 | case ide_palm3710: name = "palm3710"; break; |
66 | case ide_etrax100: name = "etrax100"; break; | 66 | case ide_etrax100: name = "etrax100"; break; |
67 | case ide_acorn: name = "acorn"; break; | 67 | case ide_acorn: name = "acorn"; break; |
68 | default: name = "(unknown)"; break; | 68 | default: name = "(unknown)"; break; |
69 | } | 69 | } |
70 | len = sprintf(page, "%s\n", name); | 70 | len = sprintf(page, "%s\n", name); |
71 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | 71 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
72 | } | 72 | } |
73 | 73 | ||
74 | static int proc_ide_read_mate | 74 | static int proc_ide_read_mate |
@@ -81,7 +81,7 @@ static int proc_ide_read_mate | |||
81 | len = sprintf(page, "%s\n", hwif->mate->name); | 81 | len = sprintf(page, "%s\n", hwif->mate->name); |
82 | else | 82 | else |
83 | len = sprintf(page, "(none)\n"); | 83 | len = sprintf(page, "(none)\n"); |
84 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | 84 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
85 | } | 85 | } |
86 | 86 | ||
87 | static int proc_ide_read_channel | 87 | static int proc_ide_read_channel |
@@ -93,7 +93,7 @@ static int proc_ide_read_channel | |||
93 | page[0] = hwif->channel ? '1' : '0'; | 93 | page[0] = hwif->channel ? '1' : '0'; |
94 | page[1] = '\n'; | 94 | page[1] = '\n'; |
95 | len = 2; | 95 | len = 2; |
96 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | 96 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
97 | } | 97 | } |
98 | 98 | ||
99 | static int proc_ide_read_identify | 99 | static int proc_ide_read_identify |
@@ -120,7 +120,7 @@ static int proc_ide_read_identify | |||
120 | len = out - page; | 120 | len = out - page; |
121 | } | 121 | } |
122 | } | 122 | } |
123 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | 123 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
124 | } | 124 | } |
125 | 125 | ||
126 | /** | 126 | /** |
@@ -197,7 +197,7 @@ EXPORT_SYMBOL(ide_add_setting); | |||
197 | * The caller must hold the setting semaphore. | 197 | * The caller must hold the setting semaphore. |
198 | */ | 198 | */ |
199 | 199 | ||
200 | static void __ide_remove_setting (ide_drive_t *drive, char *name) | 200 | static void __ide_remove_setting(ide_drive_t *drive, char *name) |
201 | { | 201 | { |
202 | ide_settings_t **p, *setting; | 202 | ide_settings_t **p, *setting; |
203 | 203 | ||
@@ -205,7 +205,8 @@ static void __ide_remove_setting (ide_drive_t *drive, char *name) | |||
205 | 205 | ||
206 | while ((*p) && strcmp((*p)->name, name)) | 206 | while ((*p) && strcmp((*p)->name, name)) |
207 | p = &((*p)->next); | 207 | p = &((*p)->next); |
208 | if ((setting = (*p)) == NULL) | 208 | setting = (*p); |
209 | if (setting == NULL) | ||
209 | return; | 210 | return; |
210 | 211 | ||
211 | (*p) = setting->next; | 212 | (*p) = setting->next; |
@@ -223,7 +224,7 @@ static void __ide_remove_setting (ide_drive_t *drive, char *name) | |||
223 | * caller must hold ide_setting_mtx. | 224 | * caller must hold ide_setting_mtx. |
224 | */ | 225 | */ |
225 | 226 | ||
226 | static void auto_remove_settings (ide_drive_t *drive) | 227 | static void auto_remove_settings(ide_drive_t *drive) |
227 | { | 228 | { |
228 | ide_settings_t *setting; | 229 | ide_settings_t *setting; |
229 | repeat: | 230 | repeat: |
@@ -279,16 +280,16 @@ static int ide_read_setting(ide_drive_t *drive, ide_settings_t *setting) | |||
279 | 280 | ||
280 | if ((setting->rw & SETTING_READ)) { | 281 | if ((setting->rw & SETTING_READ)) { |
281 | spin_lock_irqsave(&ide_lock, flags); | 282 | spin_lock_irqsave(&ide_lock, flags); |
282 | switch(setting->data_type) { | 283 | switch (setting->data_type) { |
283 | case TYPE_BYTE: | 284 | case TYPE_BYTE: |
284 | val = *((u8 *) setting->data); | 285 | val = *((u8 *) setting->data); |
285 | break; | 286 | break; |
286 | case TYPE_SHORT: | 287 | case TYPE_SHORT: |
287 | val = *((u16 *) setting->data); | 288 | val = *((u16 *) setting->data); |
288 | break; | 289 | break; |
289 | case TYPE_INT: | 290 | case TYPE_INT: |
290 | val = *((u32 *) setting->data); | 291 | val = *((u32 *) setting->data); |
291 | break; | 292 | break; |
292 | } | 293 | } |
293 | spin_unlock_irqrestore(&ide_lock, flags); | 294 | spin_unlock_irqrestore(&ide_lock, flags); |
294 | } | 295 | } |
@@ -326,15 +327,15 @@ static int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int va | |||
326 | if (ide_spin_wait_hwgroup(drive)) | 327 | if (ide_spin_wait_hwgroup(drive)) |
327 | return -EBUSY; | 328 | return -EBUSY; |
328 | switch (setting->data_type) { | 329 | switch (setting->data_type) { |
329 | case TYPE_BYTE: | 330 | case TYPE_BYTE: |
330 | *((u8 *) setting->data) = val; | 331 | *((u8 *) setting->data) = val; |
331 | break; | 332 | break; |
332 | case TYPE_SHORT: | 333 | case TYPE_SHORT: |
333 | *((u16 *) setting->data) = val; | 334 | *((u16 *) setting->data) = val; |
334 | break; | 335 | break; |
335 | case TYPE_INT: | 336 | case TYPE_INT: |
336 | *((u32 *) setting->data) = val; | 337 | *((u32 *) setting->data) = val; |
337 | break; | 338 | break; |
338 | } | 339 | } |
339 | spin_unlock_irq(&ide_lock); | 340 | spin_unlock_irq(&ide_lock); |
340 | return 0; | 341 | return 0; |
@@ -390,7 +391,7 @@ void ide_add_generic_settings (ide_drive_t *drive) | |||
390 | 391 | ||
391 | static void proc_ide_settings_warn(void) | 392 | static void proc_ide_settings_warn(void) |
392 | { | 393 | { |
393 | static int warned = 0; | 394 | static int warned; |
394 | 395 | ||
395 | if (warned) | 396 | if (warned) |
396 | return; | 397 | return; |
@@ -413,11 +414,12 @@ static int proc_ide_read_settings | |||
413 | mutex_lock(&ide_setting_mtx); | 414 | mutex_lock(&ide_setting_mtx); |
414 | out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n"); | 415 | out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n"); |
415 | out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n"); | 416 | out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n"); |
416 | while(setting) { | 417 | while (setting) { |
417 | mul_factor = setting->mul_factor; | 418 | mul_factor = setting->mul_factor; |
418 | div_factor = setting->div_factor; | 419 | div_factor = setting->div_factor; |
419 | out += sprintf(out, "%-24s", setting->name); | 420 | out += sprintf(out, "%-24s", setting->name); |
420 | if ((rc = ide_read_setting(drive, setting)) >= 0) | 421 | rc = ide_read_setting(drive, setting); |
422 | if (rc >= 0) | ||
421 | out += sprintf(out, "%-16d", rc * mul_factor / div_factor); | 423 | out += sprintf(out, "%-16d", rc * mul_factor / div_factor); |
422 | else | 424 | else |
423 | out += sprintf(out, "%-16s", "write-only"); | 425 | out += sprintf(out, "%-16s", "write-only"); |
@@ -431,7 +433,7 @@ static int proc_ide_read_settings | |||
431 | } | 433 | } |
432 | len = out - page; | 434 | len = out - page; |
433 | mutex_unlock(&ide_setting_mtx); | 435 | mutex_unlock(&ide_setting_mtx); |
434 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | 436 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
435 | } | 437 | } |
436 | 438 | ||
437 | #define MAX_LEN 30 | 439 | #define MAX_LEN 30 |
@@ -512,8 +514,7 @@ static int proc_ide_write_settings(struct file *file, const char __user *buffer, | |||
512 | 514 | ||
513 | mutex_lock(&ide_setting_mtx); | 515 | mutex_lock(&ide_setting_mtx); |
514 | setting = ide_find_setting_by_name(drive, name); | 516 | setting = ide_find_setting_by_name(drive, name); |
515 | if (!setting) | 517 | if (!setting) { |
516 | { | ||
517 | mutex_unlock(&ide_setting_mtx); | 518 | mutex_unlock(&ide_setting_mtx); |
518 | goto parse_error; | 519 | goto parse_error; |
519 | } | 520 | } |
@@ -533,8 +534,8 @@ parse_error: | |||
533 | int proc_ide_read_capacity | 534 | int proc_ide_read_capacity |
534 | (char *page, char **start, off_t off, int count, int *eof, void *data) | 535 | (char *page, char **start, off_t off, int count, int *eof, void *data) |
535 | { | 536 | { |
536 | int len = sprintf(page,"%llu\n", (long long)0x7fffffff); | 537 | int len = sprintf(page, "%llu\n", (long long)0x7fffffff); |
537 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | 538 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
538 | } | 539 | } |
539 | 540 | ||
540 | EXPORT_SYMBOL_GPL(proc_ide_read_capacity); | 541 | EXPORT_SYMBOL_GPL(proc_ide_read_capacity); |
@@ -546,13 +547,13 @@ int proc_ide_read_geometry | |||
546 | char *out = page; | 547 | char *out = page; |
547 | int len; | 548 | int len; |
548 | 549 | ||
549 | out += sprintf(out,"physical %d/%d/%d\n", | 550 | out += sprintf(out, "physical %d/%d/%d\n", |
550 | drive->cyl, drive->head, drive->sect); | 551 | drive->cyl, drive->head, drive->sect); |
551 | out += sprintf(out,"logical %d/%d/%d\n", | 552 | out += sprintf(out, "logical %d/%d/%d\n", |
552 | drive->bios_cyl, drive->bios_head, drive->bios_sect); | 553 | drive->bios_cyl, drive->bios_head, drive->bios_sect); |
553 | 554 | ||
554 | len = out - page; | 555 | len = out - page; |
555 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | 556 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
556 | } | 557 | } |
557 | 558 | ||
558 | EXPORT_SYMBOL(proc_ide_read_geometry); | 559 | EXPORT_SYMBOL(proc_ide_read_geometry); |
@@ -566,7 +567,7 @@ static int proc_ide_read_dmodel | |||
566 | 567 | ||
567 | len = sprintf(page, "%.40s\n", | 568 | len = sprintf(page, "%.40s\n", |
568 | (id && id->model[0]) ? (char *)id->model : "(none)"); | 569 | (id && id->model[0]) ? (char *)id->model : "(none)"); |
569 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | 570 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
570 | } | 571 | } |
571 | 572 | ||
572 | static int proc_ide_read_driver | 573 | static int proc_ide_read_driver |
@@ -583,7 +584,7 @@ static int proc_ide_read_driver | |||
583 | dev->driver->name, ide_drv->version); | 584 | dev->driver->name, ide_drv->version); |
584 | } else | 585 | } else |
585 | len = sprintf(page, "ide-default version 0.9.newide\n"); | 586 | len = sprintf(page, "ide-default version 0.9.newide\n"); |
586 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | 587 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
587 | } | 588 | } |
588 | 589 | ||
589 | static int ide_replace_subdriver(ide_drive_t *drive, const char *driver) | 590 | static int ide_replace_subdriver(ide_drive_t *drive, const char *driver) |
@@ -639,30 +640,26 @@ static int proc_ide_read_media | |||
639 | int len; | 640 | int len; |
640 | 641 | ||
641 | switch (drive->media) { | 642 | switch (drive->media) { |
642 | case ide_disk: media = "disk\n"; | 643 | case ide_disk: media = "disk\n"; break; |
643 | break; | 644 | case ide_cdrom: media = "cdrom\n"; break; |
644 | case ide_cdrom: media = "cdrom\n"; | 645 | case ide_tape: media = "tape\n"; break; |
645 | break; | 646 | case ide_floppy: media = "floppy\n"; break; |
646 | case ide_tape: media = "tape\n"; | 647 | case ide_optical: media = "optical\n"; break; |
647 | break; | 648 | default: media = "UNKNOWN\n"; break; |
648 | case ide_floppy:media = "floppy\n"; | ||
649 | break; | ||
650 | case ide_optical:media = "optical\n"; | ||
651 | break; | ||
652 | default: media = "UNKNOWN\n"; | ||
653 | break; | ||
654 | } | 649 | } |
655 | strcpy(page,media); | 650 | strcpy(page, media); |
656 | len = strlen(media); | 651 | len = strlen(media); |
657 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | 652 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
658 | } | 653 | } |
659 | 654 | ||
660 | static ide_proc_entry_t generic_drive_entries[] = { | 655 | static ide_proc_entry_t generic_drive_entries[] = { |
661 | { "driver", S_IFREG|S_IRUGO, proc_ide_read_driver, proc_ide_write_driver }, | 656 | { "driver", S_IFREG|S_IRUGO, proc_ide_read_driver, |
662 | { "identify", S_IFREG|S_IRUSR, proc_ide_read_identify, NULL }, | 657 | proc_ide_write_driver }, |
663 | { "media", S_IFREG|S_IRUGO, proc_ide_read_media, NULL }, | 658 | { "identify", S_IFREG|S_IRUSR, proc_ide_read_identify, NULL }, |
664 | { "model", S_IFREG|S_IRUGO, proc_ide_read_dmodel, NULL }, | 659 | { "media", S_IFREG|S_IRUGO, proc_ide_read_media, NULL }, |
665 | { "settings", S_IFREG|S_IRUSR|S_IWUSR,proc_ide_read_settings, proc_ide_write_settings }, | 660 | { "model", S_IFREG|S_IRUGO, proc_ide_read_dmodel, NULL }, |
661 | { "settings", S_IFREG|S_IRUSR|S_IWUSR, proc_ide_read_settings, | ||
662 | proc_ide_write_settings }, | ||
666 | { NULL, 0, NULL, NULL } | 663 | { NULL, 0, NULL, NULL } |
667 | }; | 664 | }; |
668 | 665 | ||
@@ -734,7 +731,6 @@ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) | |||
734 | spin_unlock_irqrestore(&ide_lock, flags); | 731 | spin_unlock_irqrestore(&ide_lock, flags); |
735 | mutex_unlock(&ide_setting_mtx); | 732 | mutex_unlock(&ide_setting_mtx); |
736 | } | 733 | } |
737 | |||
738 | EXPORT_SYMBOL(ide_proc_unregister_driver); | 734 | EXPORT_SYMBOL(ide_proc_unregister_driver); |
739 | 735 | ||
740 | void ide_proc_port_register_devices(ide_hwif_t *hwif) | 736 | void ide_proc_port_register_devices(ide_hwif_t *hwif) |
@@ -755,7 +751,7 @@ void ide_proc_port_register_devices(ide_hwif_t *hwif) | |||
755 | drive->proc = proc_mkdir(drive->name, parent); | 751 | drive->proc = proc_mkdir(drive->name, parent); |
756 | if (drive->proc) | 752 | if (drive->proc) |
757 | ide_add_proc_entries(drive->proc, generic_drive_entries, drive); | 753 | ide_add_proc_entries(drive->proc, generic_drive_entries, drive); |
758 | sprintf(name,"ide%d/%s", (drive->name[2]-'a')/2, drive->name); | 754 | sprintf(name, "ide%d/%s", (drive->name[2]-'a')/2, drive->name); |
759 | ent = proc_symlink(drive->name, proc_ide_root, name); | 755 | ent = proc_symlink(drive->name, proc_ide_root, name); |
760 | if (!ent) return; | 756 | if (!ent) return; |
761 | } | 757 | } |
@@ -795,7 +791,6 @@ void ide_pci_create_host_proc(const char *name, get_info_t *get_info) | |||
795 | { | 791 | { |
796 | create_proc_info_entry(name, 0, proc_ide_root, get_info); | 792 | create_proc_info_entry(name, 0, proc_ide_root, get_info); |
797 | } | 793 | } |
798 | |||
799 | EXPORT_SYMBOL_GPL(ide_pci_create_host_proc); | 794 | EXPORT_SYMBOL_GPL(ide_pci_create_host_proc); |
800 | #endif | 795 | #endif |
801 | 796 | ||
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 917c72dcd33d..d868ca44d033 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -100,13 +100,8 @@ int ide_noacpitfs = 1; | |||
100 | int ide_noacpionboot = 1; | 100 | int ide_noacpionboot = 1; |
101 | #endif | 101 | #endif |
102 | 102 | ||
103 | /* | ||
104 | * This is declared extern in ide.h, for access by other IDE modules: | ||
105 | */ | ||
106 | ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */ | 103 | ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */ |
107 | 104 | ||
108 | EXPORT_SYMBOL(ide_hwifs); | ||
109 | |||
110 | static void ide_port_init_devices_data(ide_hwif_t *); | 105 | static void ide_port_init_devices_data(ide_hwif_t *); |
111 | 106 | ||
112 | /* | 107 | /* |
@@ -232,30 +227,6 @@ static int ide_system_bus_speed(void) | |||
232 | return pci_dev_present(pci_default) ? 33 : 50; | 227 | return pci_dev_present(pci_default) ? 33 : 50; |
233 | } | 228 | } |
234 | 229 | ||
235 | ide_hwif_t * ide_find_port(unsigned long base) | ||
236 | { | ||
237 | ide_hwif_t *hwif; | ||
238 | int i; | ||
239 | |||
240 | for (i = 0; i < MAX_HWIFS; i++) { | ||
241 | hwif = &ide_hwifs[i]; | ||
242 | if (hwif->io_ports[IDE_DATA_OFFSET] == base) | ||
243 | goto found; | ||
244 | } | ||
245 | |||
246 | for (i = 0; i < MAX_HWIFS; i++) { | ||
247 | hwif = &ide_hwifs[i]; | ||
248 | if (hwif->chipset == ide_unknown) | ||
249 | goto found; | ||
250 | } | ||
251 | |||
252 | hwif = NULL; | ||
253 | found: | ||
254 | return hwif; | ||
255 | } | ||
256 | |||
257 | EXPORT_SYMBOL_GPL(ide_find_port); | ||
258 | |||
259 | static struct resource* hwif_request_region(ide_hwif_t *hwif, | 230 | static struct resource* hwif_request_region(ide_hwif_t *hwif, |
260 | unsigned long addr, int num) | 231 | unsigned long addr, int num) |
261 | { | 232 | { |
@@ -280,29 +251,21 @@ static struct resource* hwif_request_region(ide_hwif_t *hwif, | |||
280 | int ide_hwif_request_regions(ide_hwif_t *hwif) | 251 | int ide_hwif_request_regions(ide_hwif_t *hwif) |
281 | { | 252 | { |
282 | unsigned long addr; | 253 | unsigned long addr; |
283 | unsigned int i; | ||
284 | 254 | ||
285 | if (hwif->mmio) | 255 | if (hwif->mmio) |
286 | return 0; | 256 | return 0; |
257 | |||
287 | addr = hwif->io_ports[IDE_CONTROL_OFFSET]; | 258 | addr = hwif->io_ports[IDE_CONTROL_OFFSET]; |
259 | |||
288 | if (addr && !hwif_request_region(hwif, addr, 1)) | 260 | if (addr && !hwif_request_region(hwif, addr, 1)) |
289 | goto control_region_busy; | 261 | goto control_region_busy; |
290 | hwif->straight8 = 0; | 262 | |
291 | addr = hwif->io_ports[IDE_DATA_OFFSET]; | 263 | addr = hwif->io_ports[IDE_DATA_OFFSET]; |
292 | if ((addr | 7) == hwif->io_ports[IDE_STATUS_OFFSET]) { | 264 | BUG_ON((addr | 7) != hwif->io_ports[IDE_STATUS_OFFSET]); |
293 | if (!hwif_request_region(hwif, addr, 8)) | 265 | |
294 | goto data_region_busy; | 266 | if (!hwif_request_region(hwif, addr, 8)) |
295 | hwif->straight8 = 1; | 267 | goto data_region_busy; |
296 | return 0; | 268 | |
297 | } | ||
298 | for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { | ||
299 | addr = hwif->io_ports[i]; | ||
300 | if (!hwif_request_region(hwif, addr, 1)) { | ||
301 | while (--i) | ||
302 | release_region(addr, 1); | ||
303 | goto data_region_busy; | ||
304 | } | ||
305 | } | ||
306 | return 0; | 269 | return 0; |
307 | 270 | ||
308 | data_region_busy: | 271 | data_region_busy: |
@@ -328,19 +291,13 @@ control_region_busy: | |||
328 | 291 | ||
329 | void ide_hwif_release_regions(ide_hwif_t *hwif) | 292 | void ide_hwif_release_regions(ide_hwif_t *hwif) |
330 | { | 293 | { |
331 | u32 i = 0; | ||
332 | |||
333 | if (hwif->mmio) | 294 | if (hwif->mmio) |
334 | return; | 295 | return; |
296 | |||
335 | if (hwif->io_ports[IDE_CONTROL_OFFSET]) | 297 | if (hwif->io_ports[IDE_CONTROL_OFFSET]) |
336 | release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1); | 298 | release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1); |
337 | if (hwif->straight8) { | 299 | |
338 | release_region(hwif->io_ports[IDE_DATA_OFFSET], 8); | 300 | release_region(hwif->io_ports[IDE_DATA_OFFSET], 8); |
339 | return; | ||
340 | } | ||
341 | for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) | ||
342 | if (hwif->io_ports[i]) | ||
343 | release_region(hwif->io_ports[i], 1); | ||
344 | } | 301 | } |
345 | 302 | ||
346 | void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) | 303 | void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) |
@@ -627,11 +584,13 @@ out: | |||
627 | int set_pio_mode(ide_drive_t *drive, int arg) | 584 | int set_pio_mode(ide_drive_t *drive, int arg) |
628 | { | 585 | { |
629 | struct request rq; | 586 | struct request rq; |
587 | ide_hwif_t *hwif = drive->hwif; | ||
630 | 588 | ||
631 | if (arg < 0 || arg > 255) | 589 | if (arg < 0 || arg > 255) |
632 | return -EINVAL; | 590 | return -EINVAL; |
633 | 591 | ||
634 | if (drive->hwif->set_pio_mode == NULL) | 592 | if (hwif->set_pio_mode == NULL || |
593 | (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)) | ||
635 | return -ENOSYS; | 594 | return -ENOSYS; |
636 | 595 | ||
637 | if (drive->special.b.set_tune) | 596 | if (drive->special.b.set_tune) |
diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c index bc8b1f8de614..33bb7b87be5d 100644 --- a/drivers/ide/legacy/ali14xx.c +++ b/drivers/ide/legacy/ali14xx.c | |||
@@ -86,7 +86,7 @@ static u8 regOff; /* output to base port to close registers */ | |||
86 | /* | 86 | /* |
87 | * Read a controller register. | 87 | * Read a controller register. |
88 | */ | 88 | */ |
89 | static inline u8 inReg (u8 reg) | 89 | static inline u8 inReg(u8 reg) |
90 | { | 90 | { |
91 | outb_p(reg, regPort); | 91 | outb_p(reg, regPort); |
92 | return inb(dataPort); | 92 | return inb(dataPort); |
@@ -95,7 +95,7 @@ static inline u8 inReg (u8 reg) | |||
95 | /* | 95 | /* |
96 | * Write a controller register. | 96 | * Write a controller register. |
97 | */ | 97 | */ |
98 | static void outReg (u8 data, u8 reg) | 98 | static void outReg(u8 data, u8 reg) |
99 | { | 99 | { |
100 | outb_p(reg, regPort); | 100 | outb_p(reg, regPort); |
101 | outb_p(data, dataPort); | 101 | outb_p(data, dataPort); |
@@ -143,7 +143,7 @@ static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
143 | /* | 143 | /* |
144 | * Auto-detect the IDE controller port. | 144 | * Auto-detect the IDE controller port. |
145 | */ | 145 | */ |
146 | static int __init findPort (void) | 146 | static int __init findPort(void) |
147 | { | 147 | { |
148 | int i; | 148 | int i; |
149 | u8 t; | 149 | u8 t; |
@@ -175,7 +175,8 @@ static int __init findPort (void) | |||
175 | /* | 175 | /* |
176 | * Initialize controller registers with default values. | 176 | * Initialize controller registers with default values. |
177 | */ | 177 | */ |
178 | static int __init initRegisters (void) { | 178 | static int __init initRegisters(void) |
179 | { | ||
179 | const RegInitializer *p; | 180 | const RegInitializer *p; |
180 | u8 t; | 181 | u8 t; |
181 | unsigned long flags; | 182 | unsigned long flags; |
@@ -199,7 +200,8 @@ static const struct ide_port_info ali14xx_port_info = { | |||
199 | 200 | ||
200 | static int __init ali14xx_probe(void) | 201 | static int __init ali14xx_probe(void) |
201 | { | 202 | { |
202 | static u8 idx[4] = { 0, 1, 0xff, 0xff }; | 203 | ide_hwif_t *hwif, *mate; |
204 | static u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | ||
203 | hw_regs_t hw[2]; | 205 | hw_regs_t hw[2]; |
204 | 206 | ||
205 | printk(KERN_DEBUG "ali14xx: base=0x%03x, regOn=0x%02x.\n", | 207 | printk(KERN_DEBUG "ali14xx: base=0x%03x, regOn=0x%02x.\n", |
@@ -219,18 +221,26 @@ static int __init ali14xx_probe(void) | |||
219 | ide_std_init_ports(&hw[1], 0x170, 0x376); | 221 | ide_std_init_ports(&hw[1], 0x170, 0x376); |
220 | hw[1].irq = 15; | 222 | hw[1].irq = 15; |
221 | 223 | ||
222 | ide_init_port_hw(&ide_hwifs[0], &hw[0]); | 224 | hwif = ide_find_port(); |
223 | ide_init_port_hw(&ide_hwifs[1], &hw[1]); | 225 | if (hwif) { |
226 | ide_init_port_hw(hwif, &hw[0]); | ||
227 | hwif->set_pio_mode = &ali14xx_set_pio_mode; | ||
228 | idx[0] = hwif->index; | ||
229 | } | ||
224 | 230 | ||
225 | ide_hwifs[0].set_pio_mode = &ali14xx_set_pio_mode; | 231 | mate = ide_find_port(); |
226 | ide_hwifs[1].set_pio_mode = &ali14xx_set_pio_mode; | 232 | if (mate) { |
233 | ide_init_port_hw(mate, &hw[1]); | ||
234 | mate->set_pio_mode = &ali14xx_set_pio_mode; | ||
235 | idx[1] = mate->index; | ||
236 | } | ||
227 | 237 | ||
228 | ide_device_add(idx, &ali14xx_port_info); | 238 | ide_device_add(idx, &ali14xx_port_info); |
229 | 239 | ||
230 | return 0; | 240 | return 0; |
231 | } | 241 | } |
232 | 242 | ||
233 | int probe_ali14xx = 0; | 243 | int probe_ali14xx; |
234 | 244 | ||
235 | module_param_named(probe, probe_ali14xx, bool, 0); | 245 | module_param_named(probe, probe_ali14xx, bool, 0); |
236 | MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets"); | 246 | MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets"); |
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c index fdd3791e465f..6956eb8f2d5f 100644 --- a/drivers/ide/legacy/buddha.c +++ b/drivers/ide/legacy/buddha.c | |||
@@ -221,7 +221,7 @@ fail_base2: | |||
221 | 221 | ||
222 | buddha_setup_ports(&hw, base, ctl, irq_port, ack_intr); | 222 | buddha_setup_ports(&hw, base, ctl, irq_port, ack_intr); |
223 | 223 | ||
224 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 224 | hwif = ide_find_port(); |
225 | if (hwif) { | 225 | if (hwif) { |
226 | u8 index = hwif->index; | 226 | u8 index = hwif->index; |
227 | 227 | ||
diff --git a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c index 5f69cd2ea6f7..9c6b3249a004 100644 --- a/drivers/ide/legacy/dtc2278.c +++ b/drivers/ide/legacy/dtc2278.c | |||
@@ -102,15 +102,9 @@ static int __init dtc2278_probe(void) | |||
102 | { | 102 | { |
103 | unsigned long flags; | 103 | unsigned long flags; |
104 | ide_hwif_t *hwif, *mate; | 104 | ide_hwif_t *hwif, *mate; |
105 | static u8 idx[4] = { 0, 1, 0xff, 0xff }; | 105 | static u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
106 | hw_regs_t hw[2]; | 106 | hw_regs_t hw[2]; |
107 | 107 | ||
108 | hwif = &ide_hwifs[0]; | ||
109 | mate = &ide_hwifs[1]; | ||
110 | |||
111 | if (hwif->chipset != ide_unknown || mate->chipset != ide_unknown) | ||
112 | return 1; | ||
113 | |||
114 | local_irq_save(flags); | 108 | local_irq_save(flags); |
115 | /* | 109 | /* |
116 | * This enables the second interface | 110 | * This enables the second interface |
@@ -137,10 +131,18 @@ static int __init dtc2278_probe(void) | |||
137 | ide_std_init_ports(&hw[1], 0x170, 0x376); | 131 | ide_std_init_ports(&hw[1], 0x170, 0x376); |
138 | hw[1].irq = 15; | 132 | hw[1].irq = 15; |
139 | 133 | ||
140 | ide_init_port_hw(hwif, &hw[0]); | 134 | hwif = ide_find_port(); |
141 | ide_init_port_hw(mate, &hw[1]); | 135 | if (hwif) { |
136 | ide_init_port_hw(hwif, &hw[0]); | ||
137 | hwif->set_pio_mode = dtc2278_set_pio_mode; | ||
138 | idx[0] = hwif->index; | ||
139 | } | ||
142 | 140 | ||
143 | hwif->set_pio_mode = &dtc2278_set_pio_mode; | 141 | mate = ide_find_port(); |
142 | if (mate) { | ||
143 | ide_init_port_hw(mate, &hw[1]); | ||
144 | idx[1] = mate->index; | ||
145 | } | ||
144 | 146 | ||
145 | ide_device_add(idx, &dtc2278_port_info); | 147 | ide_device_add(idx, &dtc2278_port_info); |
146 | 148 | ||
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c index e950afa5939c..8c9c9f7f54ca 100644 --- a/drivers/ide/legacy/falconide.c +++ b/drivers/ide/legacy/falconide.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/atariints.h> | 22 | #include <asm/atariints.h> |
23 | #include <asm/atari_stdma.h> | 23 | #include <asm/atari_stdma.h> |
24 | 24 | ||
25 | #define DRV_NAME "falconide" | ||
25 | 26 | ||
26 | /* | 27 | /* |
27 | * Base of the IDE interface | 28 | * Base of the IDE interface |
@@ -74,15 +75,21 @@ static int __init falconide_init(void) | |||
74 | 75 | ||
75 | printk(KERN_INFO "ide: Falcon IDE controller\n"); | 76 | printk(KERN_INFO "ide: Falcon IDE controller\n"); |
76 | 77 | ||
78 | if (!request_mem_region(ATA_HD_BASE, 0x40, DRV_NAME)) { | ||
79 | printk(KERN_ERR "%s: resources busy\n", DRV_NAME); | ||
80 | return -EBUSY; | ||
81 | } | ||
82 | |||
77 | falconide_setup_ports(&hw); | 83 | falconide_setup_ports(&hw); |
78 | 84 | ||
79 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 85 | hwif = ide_find_port(); |
80 | if (hwif) { | 86 | if (hwif) { |
81 | u8 index = hwif->index; | 87 | u8 index = hwif->index; |
82 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; | 88 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; |
83 | 89 | ||
84 | ide_init_port_data(hwif, index); | 90 | ide_init_port_data(hwif, index); |
85 | ide_init_port_hw(hwif, &hw); | 91 | ide_init_port_hw(hwif, &hw); |
92 | hwif->mmio = 1; | ||
86 | 93 | ||
87 | ide_get_lock(NULL, NULL); | 94 | ide_get_lock(NULL, NULL); |
88 | ide_device_add(idx, NULL); | 95 | ide_device_add(idx, NULL); |
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c index e3b4638cc883..fcc8d52bf2a1 100644 --- a/drivers/ide/legacy/gayle.c +++ b/drivers/ide/legacy/gayle.c | |||
@@ -175,7 +175,7 @@ found: | |||
175 | 175 | ||
176 | gayle_setup_ports(&hw, base, ctrlport, irqport, ack_intr); | 176 | gayle_setup_ports(&hw, base, ctrlport, irqport, ack_intr); |
177 | 177 | ||
178 | hwif = ide_find_port(base); | 178 | hwif = ide_find_port(); |
179 | if (hwif) { | 179 | if (hwif) { |
180 | u8 index = hwif->index; | 180 | u8 index = hwif->index; |
181 | 181 | ||
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c index 0b0d86731927..abdedf56643e 100644 --- a/drivers/ide/legacy/hd.c +++ b/drivers/ide/legacy/hd.c | |||
@@ -122,12 +122,12 @@ static int hd_error; | |||
122 | * This struct defines the HD's and their types. | 122 | * This struct defines the HD's and their types. |
123 | */ | 123 | */ |
124 | struct hd_i_struct { | 124 | struct hd_i_struct { |
125 | unsigned int head,sect,cyl,wpcom,lzone,ctl; | 125 | unsigned int head, sect, cyl, wpcom, lzone, ctl; |
126 | int unit; | 126 | int unit; |
127 | int recalibrate; | 127 | int recalibrate; |
128 | int special_op; | 128 | int special_op; |
129 | }; | 129 | }; |
130 | 130 | ||
131 | #ifdef HD_TYPE | 131 | #ifdef HD_TYPE |
132 | static struct hd_i_struct hd_info[] = { HD_TYPE }; | 132 | static struct hd_i_struct hd_info[] = { HD_TYPE }; |
133 | static int NR_HD = ARRAY_SIZE(hd_info); | 133 | static int NR_HD = ARRAY_SIZE(hd_info); |
@@ -168,7 +168,7 @@ unsigned long read_timer(void) | |||
168 | 168 | ||
169 | spin_lock_irqsave(&i8253_lock, flags); | 169 | spin_lock_irqsave(&i8253_lock, flags); |
170 | t = jiffies * 11932; | 170 | t = jiffies * 11932; |
171 | outb_p(0, 0x43); | 171 | outb_p(0, 0x43); |
172 | i = inb_p(0x40); | 172 | i = inb_p(0x40); |
173 | i |= inb(0x40) << 8; | 173 | i |= inb(0x40) << 8; |
174 | spin_unlock_irqrestore(&i8253_lock, flags); | 174 | spin_unlock_irqrestore(&i8253_lock, flags); |
@@ -183,7 +183,7 @@ static void __init hd_setup(char *str, int *ints) | |||
183 | if (ints[0] != 3) | 183 | if (ints[0] != 3) |
184 | return; | 184 | return; |
185 | if (hd_info[0].head != 0) | 185 | if (hd_info[0].head != 0) |
186 | hdind=1; | 186 | hdind = 1; |
187 | hd_info[hdind].head = ints[2]; | 187 | hd_info[hdind].head = ints[2]; |
188 | hd_info[hdind].sect = ints[3]; | 188 | hd_info[hdind].sect = ints[3]; |
189 | hd_info[hdind].cyl = ints[1]; | 189 | hd_info[hdind].cyl = ints[1]; |
@@ -193,7 +193,7 @@ static void __init hd_setup(char *str, int *ints) | |||
193 | NR_HD = hdind+1; | 193 | NR_HD = hdind+1; |
194 | } | 194 | } |
195 | 195 | ||
196 | static void dump_status (const char *msg, unsigned int stat) | 196 | static void dump_status(const char *msg, unsigned int stat) |
197 | { | 197 | { |
198 | char *name = "hd?"; | 198 | char *name = "hd?"; |
199 | if (CURRENT) | 199 | if (CURRENT) |
@@ -291,7 +291,6 @@ static int controller_ready(unsigned int drive, unsigned int head) | |||
291 | return 0; | 291 | return 0; |
292 | } | 292 | } |
293 | 293 | ||
294 | |||
295 | static void hd_out(struct hd_i_struct *disk, | 294 | static void hd_out(struct hd_i_struct *disk, |
296 | unsigned int nsect, | 295 | unsigned int nsect, |
297 | unsigned int sect, | 296 | unsigned int sect, |
@@ -313,15 +312,15 @@ static void hd_out(struct hd_i_struct *disk, | |||
313 | return; | 312 | return; |
314 | } | 313 | } |
315 | SET_HANDLER(intr_addr); | 314 | SET_HANDLER(intr_addr); |
316 | outb_p(disk->ctl,HD_CMD); | 315 | outb_p(disk->ctl, HD_CMD); |
317 | port=HD_DATA; | 316 | port = HD_DATA; |
318 | outb_p(disk->wpcom>>2,++port); | 317 | outb_p(disk->wpcom >> 2, ++port); |
319 | outb_p(nsect,++port); | 318 | outb_p(nsect, ++port); |
320 | outb_p(sect,++port); | 319 | outb_p(sect, ++port); |
321 | outb_p(cyl,++port); | 320 | outb_p(cyl, ++port); |
322 | outb_p(cyl>>8,++port); | 321 | outb_p(cyl >> 8, ++port); |
323 | outb_p(0xA0|(disk->unit<<4)|head,++port); | 322 | outb_p(0xA0 | (disk->unit << 4) | head, ++port); |
324 | outb_p(cmd,++port); | 323 | outb_p(cmd, ++port); |
325 | } | 324 | } |
326 | 325 | ||
327 | static void hd_request (void); | 326 | static void hd_request (void); |
@@ -344,14 +343,14 @@ static void reset_controller(void) | |||
344 | { | 343 | { |
345 | int i; | 344 | int i; |
346 | 345 | ||
347 | outb_p(4,HD_CMD); | 346 | outb_p(4, HD_CMD); |
348 | for(i = 0; i < 1000; i++) barrier(); | 347 | for (i = 0; i < 1000; i++) barrier(); |
349 | outb_p(hd_info[0].ctl & 0x0f,HD_CMD); | 348 | outb_p(hd_info[0].ctl & 0x0f, HD_CMD); |
350 | for(i = 0; i < 1000; i++) barrier(); | 349 | for (i = 0; i < 1000; i++) barrier(); |
351 | if (drive_busy()) | 350 | if (drive_busy()) |
352 | printk("hd: controller still busy\n"); | 351 | printk("hd: controller still busy\n"); |
353 | else if ((hd_error = inb(HD_ERROR)) != 1) | 352 | else if ((hd_error = inb(HD_ERROR)) != 1) |
354 | printk("hd: controller reset failed: %02x\n",hd_error); | 353 | printk("hd: controller reset failed: %02x\n", hd_error); |
355 | } | 354 | } |
356 | 355 | ||
357 | static void reset_hd(void) | 356 | static void reset_hd(void) |
@@ -371,8 +370,8 @@ repeat: | |||
371 | if (++i < NR_HD) { | 370 | if (++i < NR_HD) { |
372 | struct hd_i_struct *disk = &hd_info[i]; | 371 | struct hd_i_struct *disk = &hd_info[i]; |
373 | disk->special_op = disk->recalibrate = 1; | 372 | disk->special_op = disk->recalibrate = 1; |
374 | hd_out(disk,disk->sect,disk->sect,disk->head-1, | 373 | hd_out(disk, disk->sect, disk->sect, disk->head-1, |
375 | disk->cyl,WIN_SPECIFY,&reset_hd); | 374 | disk->cyl, WIN_SPECIFY, &reset_hd); |
376 | if (reset) | 375 | if (reset) |
377 | goto repeat; | 376 | goto repeat; |
378 | } else | 377 | } else |
@@ -393,7 +392,7 @@ static void unexpected_hd_interrupt(void) | |||
393 | unsigned int stat = inb_p(HD_STATUS); | 392 | unsigned int stat = inb_p(HD_STATUS); |
394 | 393 | ||
395 | if (stat & (BUSY_STAT|DRQ_STAT|ECC_STAT|ERR_STAT)) { | 394 | if (stat & (BUSY_STAT|DRQ_STAT|ECC_STAT|ERR_STAT)) { |
396 | dump_status ("unexpected interrupt", stat); | 395 | dump_status("unexpected interrupt", stat); |
397 | SET_TIMER; | 396 | SET_TIMER; |
398 | } | 397 | } |
399 | } | 398 | } |
@@ -453,7 +452,7 @@ static void read_intr(void) | |||
453 | return; | 452 | return; |
454 | ok_to_read: | 453 | ok_to_read: |
455 | req = CURRENT; | 454 | req = CURRENT; |
456 | insw(HD_DATA,req->buffer,256); | 455 | insw(HD_DATA, req->buffer, 256); |
457 | req->sector++; | 456 | req->sector++; |
458 | req->buffer += 512; | 457 | req->buffer += 512; |
459 | req->errors = 0; | 458 | req->errors = 0; |
@@ -507,7 +506,7 @@ ok_to_write: | |||
507 | end_request(req, 1); | 506 | end_request(req, 1); |
508 | if (i > 0) { | 507 | if (i > 0) { |
509 | SET_HANDLER(&write_intr); | 508 | SET_HANDLER(&write_intr); |
510 | outsw(HD_DATA,req->buffer,256); | 509 | outsw(HD_DATA, req->buffer, 256); |
511 | local_irq_enable(); | 510 | local_irq_enable(); |
512 | } else { | 511 | } else { |
513 | #if (HD_DELAY > 0) | 512 | #if (HD_DELAY > 0) |
@@ -560,11 +559,11 @@ static int do_special_op(struct hd_i_struct *disk, struct request *req) | |||
560 | { | 559 | { |
561 | if (disk->recalibrate) { | 560 | if (disk->recalibrate) { |
562 | disk->recalibrate = 0; | 561 | disk->recalibrate = 0; |
563 | hd_out(disk,disk->sect,0,0,0,WIN_RESTORE,&recal_intr); | 562 | hd_out(disk, disk->sect, 0, 0, 0, WIN_RESTORE, &recal_intr); |
564 | return reset; | 563 | return reset; |
565 | } | 564 | } |
566 | if (disk->head > 16) { | 565 | if (disk->head > 16) { |
567 | printk ("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name); | 566 | printk("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name); |
568 | end_request(req, 0); | 567 | end_request(req, 0); |
569 | } | 568 | } |
570 | disk->special_op = 0; | 569 | disk->special_op = 0; |
@@ -633,19 +632,21 @@ repeat: | |||
633 | if (blk_fs_request(req)) { | 632 | if (blk_fs_request(req)) { |
634 | switch (rq_data_dir(req)) { | 633 | switch (rq_data_dir(req)) { |
635 | case READ: | 634 | case READ: |
636 | hd_out(disk,nsect,sec,head,cyl,WIN_READ,&read_intr); | 635 | hd_out(disk, nsect, sec, head, cyl, WIN_READ, |
636 | &read_intr); | ||
637 | if (reset) | 637 | if (reset) |
638 | goto repeat; | 638 | goto repeat; |
639 | break; | 639 | break; |
640 | case WRITE: | 640 | case WRITE: |
641 | hd_out(disk,nsect,sec,head,cyl,WIN_WRITE,&write_intr); | 641 | hd_out(disk, nsect, sec, head, cyl, WIN_WRITE, |
642 | &write_intr); | ||
642 | if (reset) | 643 | if (reset) |
643 | goto repeat; | 644 | goto repeat; |
644 | if (wait_DRQ()) { | 645 | if (wait_DRQ()) { |
645 | bad_rw_intr(); | 646 | bad_rw_intr(); |
646 | goto repeat; | 647 | goto repeat; |
647 | } | 648 | } |
648 | outsw(HD_DATA,req->buffer,256); | 649 | outsw(HD_DATA, req->buffer, 256); |
649 | break; | 650 | break; |
650 | default: | 651 | default: |
651 | printk("unknown hd-command\n"); | 652 | printk("unknown hd-command\n"); |
@@ -655,7 +656,7 @@ repeat: | |||
655 | } | 656 | } |
656 | } | 657 | } |
657 | 658 | ||
658 | static void do_hd_request (struct request_queue * q) | 659 | static void do_hd_request(struct request_queue *q) |
659 | { | 660 | { |
660 | disable_irq(HD_IRQ); | 661 | disable_irq(HD_IRQ); |
661 | hd_request(); | 662 | hd_request(); |
@@ -708,12 +709,12 @@ static int __init hd_init(void) | |||
708 | { | 709 | { |
709 | int drive; | 710 | int drive; |
710 | 711 | ||
711 | if (register_blkdev(MAJOR_NR,"hd")) | 712 | if (register_blkdev(MAJOR_NR, "hd")) |
712 | return -1; | 713 | return -1; |
713 | 714 | ||
714 | hd_queue = blk_init_queue(do_hd_request, &hd_lock); | 715 | hd_queue = blk_init_queue(do_hd_request, &hd_lock); |
715 | if (!hd_queue) { | 716 | if (!hd_queue) { |
716 | unregister_blkdev(MAJOR_NR,"hd"); | 717 | unregister_blkdev(MAJOR_NR, "hd"); |
717 | return -ENOMEM; | 718 | return -ENOMEM; |
718 | } | 719 | } |
719 | 720 | ||
@@ -742,7 +743,7 @@ static int __init hd_init(void) | |||
742 | goto out; | 743 | goto out; |
743 | } | 744 | } |
744 | 745 | ||
745 | for (drive=0 ; drive < NR_HD ; drive++) { | 746 | for (drive = 0 ; drive < NR_HD ; drive++) { |
746 | struct gendisk *disk = alloc_disk(64); | 747 | struct gendisk *disk = alloc_disk(64); |
747 | struct hd_i_struct *p = &hd_info[drive]; | 748 | struct hd_i_struct *p = &hd_info[drive]; |
748 | if (!disk) | 749 | if (!disk) |
@@ -756,7 +757,7 @@ static int __init hd_init(void) | |||
756 | disk->queue = hd_queue; | 757 | disk->queue = hd_queue; |
757 | p->unit = drive; | 758 | p->unit = drive; |
758 | hd_gendisk[drive] = disk; | 759 | hd_gendisk[drive] = disk; |
759 | printk ("%s: %luMB, CHS=%d/%d/%d\n", | 760 | printk("%s: %luMB, CHS=%d/%d/%d\n", |
760 | disk->disk_name, (unsigned long)get_capacity(disk)/2048, | 761 | disk->disk_name, (unsigned long)get_capacity(disk)/2048, |
761 | p->cyl, p->head, p->sect); | 762 | p->cyl, p->head, p->sect); |
762 | } | 763 | } |
@@ -776,7 +777,7 @@ static int __init hd_init(void) | |||
776 | } | 777 | } |
777 | 778 | ||
778 | /* Let them fly */ | 779 | /* Let them fly */ |
779 | for(drive=0; drive < NR_HD; drive++) | 780 | for (drive = 0; drive < NR_HD; drive++) |
780 | add_disk(hd_gendisk[drive]); | 781 | add_disk(hd_gendisk[drive]); |
781 | 782 | ||
782 | return 0; | 783 | return 0; |
@@ -791,7 +792,7 @@ out1: | |||
791 | NR_HD = 0; | 792 | NR_HD = 0; |
792 | out: | 793 | out: |
793 | del_timer(&device_timer); | 794 | del_timer(&device_timer); |
794 | unregister_blkdev(MAJOR_NR,"hd"); | 795 | unregister_blkdev(MAJOR_NR, "hd"); |
795 | blk_cleanup_queue(hd_queue); | 796 | blk_cleanup_queue(hd_queue); |
796 | return -1; | 797 | return -1; |
797 | Enomem: | 798 | Enomem: |
@@ -800,7 +801,8 @@ Enomem: | |||
800 | goto out; | 801 | goto out; |
801 | } | 802 | } |
802 | 803 | ||
803 | static int __init parse_hd_setup (char *line) { | 804 | static int __init parse_hd_setup(char *line) |
805 | { | ||
804 | int ints[6]; | 806 | int ints[6]; |
805 | 807 | ||
806 | (void) get_options(line, ARRAY_SIZE(ints), ints); | 808 | (void) get_options(line, ARRAY_SIZE(ints), ints); |
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c index 88fe9070c9c3..60f52f5158c9 100644 --- a/drivers/ide/legacy/ht6560b.c +++ b/drivers/ide/legacy/ht6560b.c | |||
@@ -35,6 +35,7 @@ | |||
35 | * Try: http://www.maf.iki.fi/~maf/ht6560b/ | 35 | * Try: http://www.maf.iki.fi/~maf/ht6560b/ |
36 | */ | 36 | */ |
37 | 37 | ||
38 | #define DRV_NAME "ht6560b" | ||
38 | #define HT6560B_VERSION "v0.08" | 39 | #define HT6560B_VERSION "v0.08" |
39 | 40 | ||
40 | #include <linux/module.h> | 41 | #include <linux/module.h> |
@@ -339,16 +340,13 @@ static const struct ide_port_info ht6560b_port_info __initdata = { | |||
339 | static int __init ht6560b_init(void) | 340 | static int __init ht6560b_init(void) |
340 | { | 341 | { |
341 | ide_hwif_t *hwif, *mate; | 342 | ide_hwif_t *hwif, *mate; |
342 | static u8 idx[4] = { 0, 1, 0xff, 0xff }; | 343 | static u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
343 | hw_regs_t hw[2]; | 344 | hw_regs_t hw[2]; |
344 | 345 | ||
345 | if (probe_ht6560b == 0) | 346 | if (probe_ht6560b == 0) |
346 | return -ENODEV; | 347 | return -ENODEV; |
347 | 348 | ||
348 | hwif = &ide_hwifs[0]; | 349 | if (!request_region(HT_CONFIG_PORT, 1, DRV_NAME)) { |
349 | mate = &ide_hwifs[1]; | ||
350 | |||
351 | if (!request_region(HT_CONFIG_PORT, 1, hwif->name)) { | ||
352 | printk(KERN_NOTICE "%s: HT_CONFIG_PORT not found\n", | 350 | printk(KERN_NOTICE "%s: HT_CONFIG_PORT not found\n", |
353 | __FUNCTION__); | 351 | __FUNCTION__); |
354 | return -ENODEV; | 352 | return -ENODEV; |
@@ -367,17 +365,23 @@ static int __init ht6560b_init(void) | |||
367 | ide_std_init_ports(&hw[1], 0x170, 0x376); | 365 | ide_std_init_ports(&hw[1], 0x170, 0x376); |
368 | hw[1].irq = 15; | 366 | hw[1].irq = 15; |
369 | 367 | ||
370 | ide_init_port_hw(hwif, &hw[0]); | 368 | hwif = ide_find_port(); |
371 | ide_init_port_hw(mate, &hw[1]); | 369 | if (hwif) { |
372 | 370 | ide_init_port_hw(hwif, &hw[0]); | |
373 | hwif->selectproc = &ht6560b_selectproc; | 371 | hwif->selectproc = ht6560b_selectproc; |
374 | hwif->set_pio_mode = &ht6560b_set_pio_mode; | 372 | hwif->set_pio_mode = ht6560b_set_pio_mode; |
375 | 373 | hwif->port_init_devs = ht6560b_port_init_devs; | |
376 | mate->selectproc = &ht6560b_selectproc; | 374 | idx[0] = hwif->index; |
377 | mate->set_pio_mode = &ht6560b_set_pio_mode; | 375 | } |
378 | 376 | ||
379 | hwif->port_init_devs = ht6560b_port_init_devs; | 377 | mate = ide_find_port(); |
380 | mate->port_init_devs = ht6560b_port_init_devs; | 378 | if (mate) { |
379 | ide_init_port_hw(mate, &hw[1]); | ||
380 | mate->selectproc = ht6560b_selectproc; | ||
381 | mate->set_pio_mode = ht6560b_set_pio_mode; | ||
382 | mate->port_init_devs = ht6560b_port_init_devs; | ||
383 | idx[1] = mate->index; | ||
384 | } | ||
381 | 385 | ||
382 | ide_device_add(idx, &ht6560b_port_info); | 386 | ide_device_add(idx, &ht6560b_port_info); |
383 | 387 | ||
diff --git a/drivers/ide/legacy/ide-4drives.c b/drivers/ide/legacy/ide-4drives.c index ecd7f3553554..c352f12348af 100644 --- a/drivers/ide/legacy/ide-4drives.c +++ b/drivers/ide/legacy/ide-4drives.c | |||
@@ -4,7 +4,7 @@ | |||
4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
5 | #include <linux/ide.h> | 5 | #include <linux/ide.h> |
6 | 6 | ||
7 | int probe_4drives = 0; | 7 | int probe_4drives; |
8 | 8 | ||
9 | module_param_named(probe, probe_4drives, bool, 0); | 9 | module_param_named(probe, probe_4drives, bool, 0); |
10 | MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port"); | 10 | MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port"); |
@@ -12,31 +12,37 @@ MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port"); | |||
12 | static int __init ide_4drives_init(void) | 12 | static int __init ide_4drives_init(void) |
13 | { | 13 | { |
14 | ide_hwif_t *hwif, *mate; | 14 | ide_hwif_t *hwif, *mate; |
15 | u8 idx[4] = { 0, 1, 0xff, 0xff }; | 15 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
16 | hw_regs_t hw; | 16 | hw_regs_t hw; |
17 | 17 | ||
18 | if (probe_4drives == 0) | 18 | if (probe_4drives == 0) |
19 | return -ENODEV; | 19 | return -ENODEV; |
20 | 20 | ||
21 | hwif = &ide_hwifs[0]; | ||
22 | mate = &ide_hwifs[1]; | ||
23 | |||
24 | memset(&hw, 0, sizeof(hw)); | 21 | memset(&hw, 0, sizeof(hw)); |
25 | 22 | ||
26 | ide_std_init_ports(&hw, 0x1f0, 0x3f6); | 23 | ide_std_init_ports(&hw, 0x1f0, 0x3f6); |
27 | hw.irq = 14; | 24 | hw.irq = 14; |
28 | hw.chipset = ide_4drives; | 25 | hw.chipset = ide_4drives; |
29 | 26 | ||
30 | ide_init_port_hw(hwif, &hw); | 27 | hwif = ide_find_port(); |
31 | ide_init_port_hw(mate, &hw); | 28 | if (hwif) { |
32 | 29 | ide_init_port_hw(hwif, &hw); | |
33 | mate->drives[0].select.all ^= 0x20; | 30 | idx[0] = hwif->index; |
34 | mate->drives[1].select.all ^= 0x20; | 31 | } |
35 | 32 | ||
36 | hwif->mate = mate; | 33 | mate = ide_find_port(); |
37 | mate->mate = hwif; | 34 | if (mate) { |
38 | 35 | ide_init_port_hw(mate, &hw); | |
39 | hwif->serialized = mate->serialized = 1; | 36 | mate->drives[0].select.all ^= 0x20; |
37 | mate->drives[1].select.all ^= 0x20; | ||
38 | idx[1] = mate->index; | ||
39 | |||
40 | if (hwif) { | ||
41 | hwif->mate = mate; | ||
42 | mate->mate = hwif; | ||
43 | hwif->serialized = mate->serialized = 1; | ||
44 | } | ||
45 | } | ||
40 | 46 | ||
41 | ide_device_add(idx, NULL); | 47 | ide_device_add(idx, NULL); |
42 | 48 | ||
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 9a23b94f2939..b97b8d51b3eb 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c | |||
@@ -156,7 +156,7 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq | |||
156 | hw.chipset = ide_pci; | 156 | hw.chipset = ide_pci; |
157 | hw.dev = &handle->dev; | 157 | hw.dev = &handle->dev; |
158 | 158 | ||
159 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 159 | hwif = ide_find_port(); |
160 | if (hwif == NULL) | 160 | if (hwif == NULL) |
161 | return -1; | 161 | return -1; |
162 | 162 | ||
diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c index 361b1bb544bf..bf240775531e 100644 --- a/drivers/ide/legacy/ide_platform.c +++ b/drivers/ide/legacy/ide_platform.c | |||
@@ -89,7 +89,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) | |||
89 | res_alt->start, res_alt->end - res_alt->start + 1); | 89 | res_alt->start, res_alt->end - res_alt->start + 1); |
90 | } | 90 | } |
91 | 91 | ||
92 | hwif = ide_find_port((unsigned long)base); | 92 | hwif = ide_find_port(); |
93 | if (!hwif) { | 93 | if (!hwif) { |
94 | ret = -ENODEV; | 94 | ret = -ENODEV; |
95 | goto out; | 95 | goto out; |
@@ -100,11 +100,10 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) | |||
100 | hw.dev = &pdev->dev; | 100 | hw.dev = &pdev->dev; |
101 | 101 | ||
102 | ide_init_port_hw(hwif, &hw); | 102 | ide_init_port_hw(hwif, &hw); |
103 | hwif->mmio = 1; | ||
103 | 104 | ||
104 | if (mmio) { | 105 | if (mmio) |
105 | hwif->mmio = 1; | ||
106 | default_hwif_mmiops(hwif); | 106 | default_hwif_mmiops(hwif); |
107 | } | ||
108 | 107 | ||
109 | idx[0] = hwif->index; | 108 | idx[0] = hwif->index; |
110 | 109 | ||
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c index eaf5dbe58bc2..7429b80cb089 100644 --- a/drivers/ide/legacy/macide.c +++ b/drivers/ide/legacy/macide.c | |||
@@ -120,7 +120,7 @@ static int __init macide_init(void) | |||
120 | 120 | ||
121 | macide_setup_ports(&hw, base, irq, ack_intr); | 121 | macide_setup_ports(&hw, base, irq, ack_intr); |
122 | 122 | ||
123 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 123 | hwif = ide_find_port(); |
124 | if (hwif) { | 124 | if (hwif) { |
125 | u8 index = hwif->index; | 125 | u8 index = hwif->index; |
126 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; | 126 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; |
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c index 2da28759686e..fcbff0eced1b 100644 --- a/drivers/ide/legacy/q40ide.c +++ b/drivers/ide/legacy/q40ide.c | |||
@@ -137,7 +137,7 @@ static int __init q40ide_init(void) | |||
137 | // m68kide_iops, | 137 | // m68kide_iops, |
138 | q40ide_default_irq(pcide_bases[i])); | 138 | q40ide_default_irq(pcide_bases[i])); |
139 | 139 | ||
140 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 140 | hwif = ide_find_port(); |
141 | if (hwif) { | 141 | if (hwif) { |
142 | ide_init_port_data(hwif, hwif->index); | 142 | ide_init_port_data(hwif, hwif->index); |
143 | ide_init_port_hw(hwif, &hw); | 143 | ide_init_port_hw(hwif, &hw); |
diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c index 7016bdf4fcc1..6e820c7c5c6b 100644 --- a/drivers/ide/legacy/qd65xx.c +++ b/drivers/ide/legacy/qd65xx.c | |||
@@ -88,12 +88,12 @@ | |||
88 | static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */ | 88 | static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */ |
89 | 89 | ||
90 | /* | 90 | /* |
91 | * qd_select: | 91 | * qd65xx_select: |
92 | * | 92 | * |
93 | * This routine is invoked from ide.c to prepare for access to a given drive. | 93 | * This routine is invoked to prepare for access to a given drive. |
94 | */ | 94 | */ |
95 | 95 | ||
96 | static void qd_select (ide_drive_t *drive) | 96 | static void qd65xx_select(ide_drive_t *drive) |
97 | { | 97 | { |
98 | u8 index = (( (QD_TIMREG(drive)) & 0x80 ) >> 7) | | 98 | u8 index = (( (QD_TIMREG(drive)) & 0x80 ) >> 7) | |
99 | (QD_TIMREG(drive) & 0x02); | 99 | (QD_TIMREG(drive) & 0x02); |
@@ -168,36 +168,15 @@ static int qd_find_disk_type (ide_drive_t *drive, | |||
168 | } | 168 | } |
169 | 169 | ||
170 | /* | 170 | /* |
171 | * qd_timing_ok: | ||
172 | * | ||
173 | * check whether timings don't conflict | ||
174 | */ | ||
175 | |||
176 | static int qd_timing_ok (ide_drive_t drives[]) | ||
177 | { | ||
178 | return (IDE_IMPLY(drives[0].present && drives[1].present, | ||
179 | IDE_IMPLY(QD_TIMREG(drives) == QD_TIMREG(drives+1), | ||
180 | QD_TIMING(drives) == QD_TIMING(drives+1)))); | ||
181 | /* if same timing register, must be same timing */ | ||
182 | } | ||
183 | |||
184 | /* | ||
185 | * qd_set_timing: | 171 | * qd_set_timing: |
186 | * | 172 | * |
187 | * records the timing, and enables selectproc as needed | 173 | * records the timing |
188 | */ | 174 | */ |
189 | 175 | ||
190 | static void qd_set_timing (ide_drive_t *drive, u8 timing) | 176 | static void qd_set_timing (ide_drive_t *drive, u8 timing) |
191 | { | 177 | { |
192 | ide_hwif_t *hwif = HWIF(drive); | ||
193 | |||
194 | drive->drive_data &= 0xff00; | 178 | drive->drive_data &= 0xff00; |
195 | drive->drive_data |= timing; | 179 | drive->drive_data |= timing; |
196 | if (qd_timing_ok(hwif->drives)) { | ||
197 | qd_select(drive); /* selects once */ | ||
198 | hwif->selectproc = NULL; | ||
199 | } else | ||
200 | hwif->selectproc = &qd_select; | ||
201 | 180 | ||
202 | printk(KERN_DEBUG "%s: %#x\n", drive->name, timing); | 181 | printk(KERN_DEBUG "%s: %#x\n", drive->name, timing); |
203 | } | 182 | } |
@@ -225,10 +204,11 @@ static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
225 | 204 | ||
226 | static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio) | 205 | static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio) |
227 | { | 206 | { |
228 | int base = HWIF(drive)->select_data; | 207 | ide_hwif_t *hwif = drive->hwif; |
229 | unsigned int cycle_time; | 208 | unsigned int cycle_time; |
230 | int active_time = 175; | 209 | int active_time = 175; |
231 | int recovery_time = 415; /* worst case values from the dos driver */ | 210 | int recovery_time = 415; /* worst case values from the dos driver */ |
211 | u8 base = (hwif->config_data & 0xff00) >> 8; | ||
232 | 212 | ||
233 | if (drive->id && !qd_find_disk_type(drive, &active_time, &recovery_time)) { | 213 | if (drive->id && !qd_find_disk_type(drive, &active_time, &recovery_time)) { |
234 | cycle_time = ide_pio_cycle_time(drive, pio); | 214 | cycle_time = ide_pio_cycle_time(drive, pio); |
@@ -299,21 +279,10 @@ static int __init qd_testreg(int port) | |||
299 | return (readreg != QD_TESTVAL); | 279 | return (readreg != QD_TESTVAL); |
300 | } | 280 | } |
301 | 281 | ||
302 | /* | ||
303 | * qd_setup: | ||
304 | * | ||
305 | * called to setup an ata channel : adjusts attributes & links for tuning | ||
306 | */ | ||
307 | |||
308 | static void __init qd_setup(ide_hwif_t *hwif, int base, int config) | ||
309 | { | ||
310 | hwif->select_data = base; | ||
311 | hwif->config_data = config; | ||
312 | } | ||
313 | |||
314 | static void __init qd6500_port_init_devs(ide_hwif_t *hwif) | 282 | static void __init qd6500_port_init_devs(ide_hwif_t *hwif) |
315 | { | 283 | { |
316 | u8 base = hwif->select_data, config = QD_CONFIG(hwif); | 284 | u8 base = (hwif->config_data & 0xff00) >> 8; |
285 | u8 config = QD_CONFIG(hwif); | ||
317 | 286 | ||
318 | hwif->drives[0].drive_data = QD6500_DEF_DATA; | 287 | hwif->drives[0].drive_data = QD6500_DEF_DATA; |
319 | hwif->drives[1].drive_data = QD6500_DEF_DATA; | 288 | hwif->drives[1].drive_data = QD6500_DEF_DATA; |
@@ -322,9 +291,10 @@ static void __init qd6500_port_init_devs(ide_hwif_t *hwif) | |||
322 | static void __init qd6580_port_init_devs(ide_hwif_t *hwif) | 291 | static void __init qd6580_port_init_devs(ide_hwif_t *hwif) |
323 | { | 292 | { |
324 | u16 t1, t2; | 293 | u16 t1, t2; |
325 | u8 base = hwif->select_data, config = QD_CONFIG(hwif); | 294 | u8 base = (hwif->config_data & 0xff00) >> 8; |
295 | u8 config = QD_CONFIG(hwif); | ||
326 | 296 | ||
327 | if (QD_CONTROL(hwif) & QD_CONTR_SEC_DISABLED) { | 297 | if (hwif->host_flags & IDE_HFLAG_SINGLE) { |
328 | t1 = QD6580_DEF_DATA; | 298 | t1 = QD6580_DEF_DATA; |
329 | t2 = QD6580_DEF_DATA2; | 299 | t2 = QD6580_DEF_DATA2; |
330 | } else | 300 | } else |
@@ -355,14 +325,18 @@ static int __init qd_probe(int base) | |||
355 | u8 config, unit; | 325 | u8 config, unit; |
356 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | 326 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
357 | hw_regs_t hw[2]; | 327 | hw_regs_t hw[2]; |
328 | struct ide_port_info d = qd65xx_port_info; | ||
358 | 329 | ||
359 | config = inb(QD_CONFIG_PORT); | 330 | config = inb(QD_CONFIG_PORT); |
360 | 331 | ||
361 | if (! ((config & QD_CONFIG_BASEPORT) >> 1 == (base == 0xb0)) ) | 332 | if (! ((config & QD_CONFIG_BASEPORT) >> 1 == (base == 0xb0)) ) |
362 | return 1; | 333 | return -ENODEV; |
363 | 334 | ||
364 | unit = ! (config & QD_CONFIG_IDE_BASEPORT); | 335 | unit = ! (config & QD_CONFIG_IDE_BASEPORT); |
365 | 336 | ||
337 | if (unit) | ||
338 | d.host_flags |= IDE_HFLAG_QD_2ND_PORT; | ||
339 | |||
366 | memset(&hw, 0, sizeof(hw)); | 340 | memset(&hw, 0, sizeof(hw)); |
367 | 341 | ||
368 | ide_std_init_ports(&hw[0], 0x1f0, 0x3f6); | 342 | ide_std_init_ports(&hw[0], 0x1f0, 0x3f6); |
@@ -373,30 +347,37 @@ static int __init qd_probe(int base) | |||
373 | 347 | ||
374 | if ((config & 0xf0) == QD_CONFIG_QD6500) { | 348 | if ((config & 0xf0) == QD_CONFIG_QD6500) { |
375 | 349 | ||
376 | if (qd_testreg(base)) return 1; /* bad register */ | 350 | if (qd_testreg(base)) |
351 | return -ENODEV; /* bad register */ | ||
377 | 352 | ||
378 | /* qd6500 found */ | 353 | /* qd6500 found */ |
379 | 354 | ||
380 | hwif = &ide_hwifs[unit]; | ||
381 | printk(KERN_NOTICE "%s: qd6500 at %#x\n", hwif->name, base); | ||
382 | printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n", | ||
383 | config, QD_ID3); | ||
384 | |||
385 | if (config & QD_CONFIG_DISABLED) { | 355 | if (config & QD_CONFIG_DISABLED) { |
386 | printk(KERN_WARNING "qd6500 is disabled !\n"); | 356 | printk(KERN_WARNING "qd6500 is disabled !\n"); |
387 | return 1; | 357 | return -ENODEV; |
388 | } | 358 | } |
389 | 359 | ||
360 | printk(KERN_NOTICE "qd6500 at %#x\n", base); | ||
361 | printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n", | ||
362 | config, QD_ID3); | ||
363 | |||
364 | d.host_flags |= IDE_HFLAG_SINGLE; | ||
365 | |||
366 | hwif = ide_find_port_slot(&d); | ||
367 | if (hwif == NULL) | ||
368 | return -ENOENT; | ||
369 | |||
390 | ide_init_port_hw(hwif, &hw[unit]); | 370 | ide_init_port_hw(hwif, &hw[unit]); |
391 | 371 | ||
392 | qd_setup(hwif, base, config); | 372 | hwif->config_data = (base << 8) | config; |
393 | 373 | ||
394 | hwif->port_init_devs = qd6500_port_init_devs; | 374 | hwif->port_init_devs = qd6500_port_init_devs; |
395 | hwif->set_pio_mode = &qd6500_set_pio_mode; | 375 | hwif->set_pio_mode = qd6500_set_pio_mode; |
376 | hwif->selectproc = qd65xx_select; | ||
396 | 377 | ||
397 | idx[unit] = unit; | 378 | idx[unit] = hwif->index; |
398 | 379 | ||
399 | ide_device_add(idx, &qd65xx_port_info); | 380 | ide_device_add(idx, &d); |
400 | 381 | ||
401 | return 1; | 382 | return 1; |
402 | } | 383 | } |
@@ -406,8 +387,8 @@ static int __init qd_probe(int base) | |||
406 | 387 | ||
407 | u8 control; | 388 | u8 control; |
408 | 389 | ||
409 | if (qd_testreg(base) || qd_testreg(base+0x02)) return 1; | 390 | if (qd_testreg(base) || qd_testreg(base + 0x02)) |
410 | /* bad registers */ | 391 | return -ENODEV; /* bad registers */ |
411 | 392 | ||
412 | /* qd6580 found */ | 393 | /* qd6580 found */ |
413 | 394 | ||
@@ -422,46 +403,52 @@ static int __init qd_probe(int base) | |||
422 | if (control & QD_CONTR_SEC_DISABLED) { | 403 | if (control & QD_CONTR_SEC_DISABLED) { |
423 | /* secondary disabled */ | 404 | /* secondary disabled */ |
424 | 405 | ||
425 | hwif = &ide_hwifs[unit]; | 406 | printk(KERN_INFO "qd6580: single IDE board\n"); |
426 | printk(KERN_INFO "%s: qd6580: single IDE board\n", | 407 | |
427 | hwif->name); | 408 | d.host_flags |= IDE_HFLAG_SINGLE; |
409 | |||
410 | hwif = ide_find_port_slot(&d); | ||
411 | if (hwif == NULL) | ||
412 | return -ENOENT; | ||
428 | 413 | ||
429 | ide_init_port_hw(hwif, &hw[unit]); | 414 | ide_init_port_hw(hwif, &hw[unit]); |
430 | 415 | ||
431 | qd_setup(hwif, base, config | (control << 8)); | 416 | hwif->config_data = (base << 8) | config; |
432 | 417 | ||
433 | hwif->port_init_devs = qd6580_port_init_devs; | 418 | hwif->port_init_devs = qd6580_port_init_devs; |
434 | hwif->set_pio_mode = &qd6580_set_pio_mode; | 419 | hwif->set_pio_mode = qd6580_set_pio_mode; |
420 | hwif->selectproc = qd65xx_select; | ||
435 | 421 | ||
436 | idx[unit] = unit; | 422 | idx[unit] = hwif->index; |
437 | 423 | ||
438 | ide_device_add(idx, &qd65xx_port_info); | 424 | ide_device_add(idx, &d); |
439 | 425 | ||
440 | return 1; | 426 | return 1; |
441 | } else { | 427 | } else { |
442 | ide_hwif_t *mate; | 428 | ide_hwif_t *mate; |
443 | 429 | ||
444 | hwif = &ide_hwifs[0]; | ||
445 | mate = &ide_hwifs[1]; | ||
446 | /* secondary enabled */ | 430 | /* secondary enabled */ |
447 | printk(KERN_INFO "%s&%s: qd6580: dual IDE board\n", | 431 | printk(KERN_INFO "qd6580: dual IDE board\n"); |
448 | hwif->name, mate->name); | 432 | |
449 | 433 | hwif = ide_find_port(); | |
450 | ide_init_port_hw(hwif, &hw[0]); | 434 | if (hwif) { |
451 | ide_init_port_hw(mate, &hw[1]); | 435 | ide_init_port_hw(hwif, &hw[0]); |
452 | 436 | hwif->config_data = (base << 8) | config; | |
453 | qd_setup(hwif, base, config | (control << 8)); | 437 | hwif->port_init_devs = qd6580_port_init_devs; |
454 | 438 | hwif->set_pio_mode = qd6580_set_pio_mode; | |
455 | hwif->port_init_devs = qd6580_port_init_devs; | 439 | hwif->selectproc = qd65xx_select; |
456 | hwif->set_pio_mode = &qd6580_set_pio_mode; | 440 | idx[0] = hwif->index; |
457 | 441 | } | |
458 | qd_setup(mate, base, config | (control << 8)); | 442 | |
459 | 443 | mate = ide_find_port(); | |
460 | mate->port_init_devs = qd6580_port_init_devs; | 444 | if (mate) { |
461 | mate->set_pio_mode = &qd6580_set_pio_mode; | 445 | ide_init_port_hw(mate, &hw[1]); |
462 | 446 | mate->config_data = (base << 8) | config; | |
463 | idx[0] = 0; | 447 | mate->port_init_devs = qd6580_port_init_devs; |
464 | idx[1] = 1; | 448 | mate->set_pio_mode = qd6580_set_pio_mode; |
449 | mate->selectproc = qd65xx_select; | ||
450 | idx[1] = mate->index; | ||
451 | } | ||
465 | 452 | ||
466 | ide_device_add(idx, &qd65xx_port_info); | 453 | ide_device_add(idx, &qd65xx_port_info); |
467 | 454 | ||
@@ -469,7 +456,7 @@ static int __init qd_probe(int base) | |||
469 | } | 456 | } |
470 | } | 457 | } |
471 | /* no qd65xx found */ | 458 | /* no qd65xx found */ |
472 | return 1; | 459 | return -ENODEV; |
473 | } | 460 | } |
474 | 461 | ||
475 | int probe_qd65xx = 0; | 462 | int probe_qd65xx = 0; |
@@ -479,14 +466,18 @@ MODULE_PARM_DESC(probe, "probe for QD65xx chipsets"); | |||
479 | 466 | ||
480 | static int __init qd65xx_init(void) | 467 | static int __init qd65xx_init(void) |
481 | { | 468 | { |
469 | int rc1, rc2 = -ENODEV; | ||
470 | |||
482 | if (probe_qd65xx == 0) | 471 | if (probe_qd65xx == 0) |
483 | return -ENODEV; | 472 | return -ENODEV; |
484 | 473 | ||
485 | if (qd_probe(0x30)) | 474 | rc1 = qd_probe(0x30); |
486 | qd_probe(0xb0); | 475 | if (rc1) |
487 | if (ide_hwifs[0].chipset != ide_qd65xx && | 476 | rc2 = qd_probe(0xb0); |
488 | ide_hwifs[1].chipset != ide_qd65xx) | 477 | |
478 | if (rc1 < 0 && rc2 < 0) | ||
489 | return -ENODEV; | 479 | return -ENODEV; |
480 | |||
490 | return 0; | 481 | return 0; |
491 | } | 482 | } |
492 | 483 | ||
diff --git a/drivers/ide/legacy/qd65xx.h b/drivers/ide/legacy/qd65xx.h index 28dd50a15d55..c83dea85e621 100644 --- a/drivers/ide/legacy/qd65xx.h +++ b/drivers/ide/legacy/qd65xx.h | |||
@@ -30,7 +30,6 @@ | |||
30 | #define QD_ID3 ((config & QD_CONFIG_ID3)!=0) | 30 | #define QD_ID3 ((config & QD_CONFIG_ID3)!=0) |
31 | 31 | ||
32 | #define QD_CONFIG(hwif) ((hwif)->config_data & 0x00ff) | 32 | #define QD_CONFIG(hwif) ((hwif)->config_data & 0x00ff) |
33 | #define QD_CONTROL(hwif) (((hwif)->config_data & 0xff00) >> 8) | ||
34 | 33 | ||
35 | #define QD_TIMING(drive) (byte)(((drive)->drive_data) & 0x00ff) | 34 | #define QD_TIMING(drive) (byte)(((drive)->drive_data) & 0x00ff) |
36 | #define QD_TIMREG(drive) (byte)((((drive)->drive_data) & 0xff00) >> 8) | 35 | #define QD_TIMREG(drive) (byte)((((drive)->drive_data) & 0xff00) >> 8) |
diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c index bc1944811b99..4d90badd2bda 100644 --- a/drivers/ide/legacy/umc8672.c +++ b/drivers/ide/legacy/umc8672.c | |||
@@ -19,7 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * VLB Controller Support from | 22 | * VLB Controller Support from |
23 | * Wolfram Podien | 23 | * Wolfram Podien |
24 | * Rohoefe 3 | 24 | * Rohoefe 3 |
25 | * D28832 Achim | 25 | * D28832 Achim |
@@ -32,7 +32,7 @@ | |||
32 | * #define UMC_DRIVE0 11 | 32 | * #define UMC_DRIVE0 11 |
33 | * in the beginning of the driver, which sets the speed of drive 0 to 11 (there | 33 | * in the beginning of the driver, which sets the speed of drive 0 to 11 (there |
34 | * are some lines present). 0 - 11 are allowed speed values. These values are | 34 | * are some lines present). 0 - 11 are allowed speed values. These values are |
35 | * the results from the DOS speed test program supplied from UMC. 11 is the | 35 | * the results from the DOS speed test program supplied from UMC. 11 is the |
36 | * highest speed (about PIO mode 3) | 36 | * highest speed (about PIO mode 3) |
37 | */ | 37 | */ |
38 | #define REALLY_SLOW_IO /* some systems can safely undef this */ | 38 | #define REALLY_SLOW_IO /* some systems can safely undef this */ |
@@ -60,62 +60,62 @@ | |||
60 | #define UMC_DRIVE3 1 /* In case of crash reduce speed */ | 60 | #define UMC_DRIVE3 1 /* In case of crash reduce speed */ |
61 | 61 | ||
62 | static u8 current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3}; | 62 | static u8 current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3}; |
63 | static const u8 pio_to_umc [5] = {0,3,7,10,11}; /* rough guesses */ | 63 | static const u8 pio_to_umc [5] = {0, 3, 7, 10, 11}; /* rough guesses */ |
64 | 64 | ||
65 | /* 0 1 2 3 4 5 6 7 8 9 10 11 */ | 65 | /* 0 1 2 3 4 5 6 7 8 9 10 11 */ |
66 | static const u8 speedtab [3][12] = { | 66 | static const u8 speedtab [3][12] = { |
67 | {0xf, 0xb, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }, | 67 | {0x0f, 0x0b, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1}, |
68 | {0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }, | 68 | {0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1}, |
69 | {0xff,0xcb,0xc0,0x58,0x36,0x33,0x23,0x22,0x21,0x11,0x10,0x0}}; | 69 | {0xff, 0xcb, 0xc0, 0x58, 0x36, 0x33, 0x23, 0x22, 0x21, 0x11, 0x10, 0x0} |
70 | }; | ||
70 | 71 | ||
71 | static void out_umc (char port,char wert) | 72 | static void out_umc(char port, char wert) |
72 | { | 73 | { |
73 | outb_p(port,0x108); | 74 | outb_p(port, 0x108); |
74 | outb_p(wert,0x109); | 75 | outb_p(wert, 0x109); |
75 | } | 76 | } |
76 | 77 | ||
77 | static inline u8 in_umc (char port) | 78 | static inline u8 in_umc(char port) |
78 | { | 79 | { |
79 | outb_p(port,0x108); | 80 | outb_p(port, 0x108); |
80 | return inb_p(0x109); | 81 | return inb_p(0x109); |
81 | } | 82 | } |
82 | 83 | ||
83 | static void umc_set_speeds (u8 speeds[]) | 84 | static void umc_set_speeds(u8 speeds[]) |
84 | { | 85 | { |
85 | int i, tmp; | 86 | int i, tmp; |
86 | 87 | ||
87 | outb_p(0x5A,0x108); /* enable umc */ | 88 | outb_p(0x5A, 0x108); /* enable umc */ |
88 | 89 | ||
89 | out_umc (0xd7,(speedtab[0][speeds[2]] | (speedtab[0][speeds[3]]<<4))); | 90 | out_umc(0xd7, (speedtab[0][speeds[2]] | (speedtab[0][speeds[3]]<<4))); |
90 | out_umc (0xd6,(speedtab[0][speeds[0]] | (speedtab[0][speeds[1]]<<4))); | 91 | out_umc(0xd6, (speedtab[0][speeds[0]] | (speedtab[0][speeds[1]]<<4))); |
91 | tmp = 0; | 92 | tmp = 0; |
92 | for (i = 3; i >= 0; i--) { | 93 | for (i = 3; i >= 0; i--) |
93 | tmp = (tmp << 2) | speedtab[1][speeds[i]]; | 94 | tmp = (tmp << 2) | speedtab[1][speeds[i]]; |
95 | out_umc(0xdc, tmp); | ||
96 | for (i = 0; i < 4; i++) { | ||
97 | out_umc(0xd0 + i, speedtab[2][speeds[i]]); | ||
98 | out_umc(0xd8 + i, speedtab[2][speeds[i]]); | ||
94 | } | 99 | } |
95 | out_umc (0xdc,tmp); | 100 | outb_p(0xa5, 0x108); /* disable umc */ |
96 | for (i = 0;i < 4; i++) { | ||
97 | out_umc (0xd0+i,speedtab[2][speeds[i]]); | ||
98 | out_umc (0xd8+i,speedtab[2][speeds[i]]); | ||
99 | } | ||
100 | outb_p(0xa5,0x108); /* disable umc */ | ||
101 | 101 | ||
102 | printk ("umc8672: drive speeds [0 to 11]: %d %d %d %d\n", | 102 | printk("umc8672: drive speeds [0 to 11]: %d %d %d %d\n", |
103 | speeds[0], speeds[1], speeds[2], speeds[3]); | 103 | speeds[0], speeds[1], speeds[2], speeds[3]); |
104 | } | 104 | } |
105 | 105 | ||
106 | static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio) | 106 | static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio) |
107 | { | 107 | { |
108 | ide_hwif_t *hwif = drive->hwif; | ||
108 | unsigned long flags; | 109 | unsigned long flags; |
109 | ide_hwgroup_t *hwgroup = ide_hwifs[HWIF(drive)->index^1].hwgroup; | ||
110 | 110 | ||
111 | printk("%s: setting umc8672 to PIO mode%d (speed %d)\n", | 111 | printk("%s: setting umc8672 to PIO mode%d (speed %d)\n", |
112 | drive->name, pio, pio_to_umc[pio]); | 112 | drive->name, pio, pio_to_umc[pio]); |
113 | spin_lock_irqsave(&ide_lock, flags); | 113 | spin_lock_irqsave(&ide_lock, flags); |
114 | if (hwgroup && hwgroup->handler != NULL) { | 114 | if (hwif->mate && hwif->mate->hwgroup->handler) { |
115 | printk(KERN_ERR "umc8672: other interface is busy: exiting tune_umc()\n"); | 115 | printk(KERN_ERR "umc8672: other interface is busy: exiting tune_umc()\n"); |
116 | } else { | 116 | } else { |
117 | current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio]; | 117 | current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio]; |
118 | umc_set_speeds (current_speeds); | 118 | umc_set_speeds(current_speeds); |
119 | } | 119 | } |
120 | spin_unlock_irqrestore(&ide_lock, flags); | 120 | spin_unlock_irqrestore(&ide_lock, flags); |
121 | } | 121 | } |
@@ -128,8 +128,9 @@ static const struct ide_port_info umc8672_port_info __initdata = { | |||
128 | 128 | ||
129 | static int __init umc8672_probe(void) | 129 | static int __init umc8672_probe(void) |
130 | { | 130 | { |
131 | ide_hwif_t *hwif, *mate; | ||
131 | unsigned long flags; | 132 | unsigned long flags; |
132 | static u8 idx[4] = { 0, 1, 0xff, 0xff }; | 133 | static u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
133 | hw_regs_t hw[2]; | 134 | hw_regs_t hw[2]; |
134 | 135 | ||
135 | if (!request_region(0x108, 2, "umc8672")) { | 136 | if (!request_region(0x108, 2, "umc8672")) { |
@@ -137,16 +138,16 @@ static int __init umc8672_probe(void) | |||
137 | return 1; | 138 | return 1; |
138 | } | 139 | } |
139 | local_irq_save(flags); | 140 | local_irq_save(flags); |
140 | outb_p(0x5A,0x108); /* enable umc */ | 141 | outb_p(0x5A, 0x108); /* enable umc */ |
141 | if (in_umc (0xd5) != 0xa0) { | 142 | if (in_umc (0xd5) != 0xa0) { |
142 | local_irq_restore(flags); | 143 | local_irq_restore(flags); |
143 | printk(KERN_ERR "umc8672: not found\n"); | 144 | printk(KERN_ERR "umc8672: not found\n"); |
144 | release_region(0x108, 2); | 145 | release_region(0x108, 2); |
145 | return 1; | 146 | return 1; |
146 | } | 147 | } |
147 | outb_p(0xa5,0x108); /* disable umc */ | 148 | outb_p(0xa5, 0x108); /* disable umc */ |
148 | 149 | ||
149 | umc_set_speeds (current_speeds); | 150 | umc_set_speeds(current_speeds); |
150 | local_irq_restore(flags); | 151 | local_irq_restore(flags); |
151 | 152 | ||
152 | memset(&hw, 0, sizeof(hw)); | 153 | memset(&hw, 0, sizeof(hw)); |
@@ -157,18 +158,26 @@ static int __init umc8672_probe(void) | |||
157 | ide_std_init_ports(&hw[1], 0x170, 0x376); | 158 | ide_std_init_ports(&hw[1], 0x170, 0x376); |
158 | hw[1].irq = 15; | 159 | hw[1].irq = 15; |
159 | 160 | ||
160 | ide_init_port_hw(&ide_hwifs[0], &hw[0]); | 161 | hwif = ide_find_port(); |
161 | ide_init_port_hw(&ide_hwifs[1], &hw[1]); | 162 | if (hwif) { |
163 | ide_init_port_hw(hwif, &hw[0]); | ||
164 | hwif->set_pio_mode = umc_set_pio_mode; | ||
165 | idx[0] = hwif->index; | ||
166 | } | ||
162 | 167 | ||
163 | ide_hwifs[0].set_pio_mode = &umc_set_pio_mode; | 168 | mate = ide_find_port(); |
164 | ide_hwifs[1].set_pio_mode = &umc_set_pio_mode; | 169 | if (mate) { |
170 | ide_init_port_hw(mate, &hw[1]); | ||
171 | mate->set_pio_mode = umc_set_pio_mode; | ||
172 | idx[1] = mate->index; | ||
173 | } | ||
165 | 174 | ||
166 | ide_device_add(idx, &umc8672_port_info); | 175 | ide_device_add(idx, &umc8672_port_info); |
167 | 176 | ||
168 | return 0; | 177 | return 0; |
169 | } | 178 | } |
170 | 179 | ||
171 | int probe_umc8672 = 0; | 180 | int probe_umc8672; |
172 | 181 | ||
173 | module_param_named(probe, probe_umc8672, bool, 0); | 182 | module_param_named(probe, probe_umc8672, bool, 0); |
174 | MODULE_PARM_DESC(probe, "probe for UMC8672 chipset"); | 183 | MODULE_PARM_DESC(probe, "probe for UMC8672 chipset"); |
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index 9b628248f2f4..a8cd0035936d 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c | |||
@@ -599,9 +599,11 @@ static int au_ide_probe(struct device *dev) | |||
599 | goto out; | 599 | goto out; |
600 | } | 600 | } |
601 | 601 | ||
602 | /* FIXME: This might possibly break PCMCIA IDE devices */ | 602 | hwif = ide_find_port(); |
603 | 603 | if (hwif == NULL) { | |
604 | hwif = &ide_hwifs[pdev->id]; | 604 | ret = -ENOENT; |
605 | goto out; | ||
606 | } | ||
605 | 607 | ||
606 | memset(&hw, 0, sizeof(hw)); | 608 | memset(&hw, 0, sizeof(hw)); |
607 | auide_setup_ports(&hw, ahwif); | 609 | auide_setup_ports(&hw, ahwif); |
diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c index 956259fc09ba..bbe8d5853348 100644 --- a/drivers/ide/mips/swarm.c +++ b/drivers/ide/mips/swarm.c | |||
@@ -76,17 +76,12 @@ static int __devinit swarm_ide_probe(struct device *dev) | |||
76 | if (!SIBYTE_HAVE_IDE) | 76 | if (!SIBYTE_HAVE_IDE) |
77 | return -ENODEV; | 77 | return -ENODEV; |
78 | 78 | ||
79 | /* Find an empty slot. */ | 79 | hwif = ide_find_port(); |
80 | for (i = 0; i < MAX_HWIFS; i++) | 80 | if (hwif == NULL) { |
81 | if (!ide_hwifs[i].io_ports[IDE_DATA_OFFSET]) | ||
82 | break; | ||
83 | if (i >= MAX_HWIFS) { | ||
84 | printk(KERN_ERR DRV_NAME ": no free slot for interface\n"); | 81 | printk(KERN_ERR DRV_NAME ": no free slot for interface\n"); |
85 | return -ENOMEM; | 82 | return -ENOMEM; |
86 | } | 83 | } |
87 | 84 | ||
88 | hwif = ide_hwifs + i; | ||
89 | |||
90 | base = ioremap(A_IO_EXT_BASE, 0x800); | 85 | base = ioremap(A_IO_EXT_BASE, 0x800); |
91 | offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS)); | 86 | offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS)); |
92 | size = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS)); | 87 | size = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS)); |
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index cfb3265bc1a8..c9ba15afe97d 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c | |||
@@ -220,7 +220,8 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = { | |||
220 | .init_hwif = init_hwif_aec62xx, | 220 | .init_hwif = init_hwif_aec62xx, |
221 | .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, | 221 | .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, |
222 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | | 222 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | |
223 | IDE_HFLAG_ABUSE_SET_DMA_MODE, | 223 | IDE_HFLAG_ABUSE_SET_DMA_MODE | |
224 | IDE_HFLAG_NON_BOOTABLE, | ||
224 | .pio_mask = ATA_PIO4, | 225 | .pio_mask = ATA_PIO4, |
225 | .mwdma_mask = ATA_MWDMA2, | 226 | .mwdma_mask = ATA_MWDMA2, |
226 | .udma_mask = ATA_UDMA4, | 227 | .udma_mask = ATA_UDMA4, |
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index b3b6f514ce2d..3fa2d9f7b1b2 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c | |||
@@ -750,7 +750,6 @@ static const struct ide_port_info ali15x3_chipset __devinitdata = { | |||
750 | .init_chipset = init_chipset_ali15x3, | 750 | .init_chipset = init_chipset_ali15x3, |
751 | .init_hwif = init_hwif_ali15x3, | 751 | .init_hwif = init_hwif_ali15x3, |
752 | .init_dma = init_dma_ali15x3, | 752 | .init_dma = init_dma_ali15x3, |
753 | .host_flags = IDE_HFLAG_BOOTABLE, | ||
754 | .pio_mask = ATA_PIO5, | 753 | .pio_mask = ATA_PIO5, |
755 | .swdma_mask = ATA_SWDMA2, | 754 | .swdma_mask = ATA_SWDMA2, |
756 | .mwdma_mask = ATA_MWDMA2, | 755 | .mwdma_mask = ATA_MWDMA2, |
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 2ef890ce8097..ff684d312378 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c | |||
@@ -219,12 +219,10 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) | |||
219 | 219 | ||
220 | #define IDE_HFLAGS_AMD \ | 220 | #define IDE_HFLAGS_AMD \ |
221 | (IDE_HFLAG_PIO_NO_BLACKLIST | \ | 221 | (IDE_HFLAG_PIO_NO_BLACKLIST | \ |
222 | IDE_HFLAG_PIO_NO_DOWNGRADE | \ | ||
223 | IDE_HFLAG_ABUSE_SET_DMA_MODE | \ | 222 | IDE_HFLAG_ABUSE_SET_DMA_MODE | \ |
224 | IDE_HFLAG_POST_SET_MODE | \ | 223 | IDE_HFLAG_POST_SET_MODE | \ |
225 | IDE_HFLAG_IO_32BIT | \ | 224 | IDE_HFLAG_IO_32BIT | \ |
226 | IDE_HFLAG_UNMASK_IRQS | \ | 225 | IDE_HFLAG_UNMASK_IRQS) |
227 | IDE_HFLAG_BOOTABLE) | ||
228 | 226 | ||
229 | #define DECLARE_AMD_DEV(name_str, swdma, udma) \ | 227 | #define DECLARE_AMD_DEV(name_str, swdma, udma) \ |
230 | { \ | 228 | { \ |
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index 7e037c880cb0..91722f88b7bd 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c | |||
@@ -151,7 +151,7 @@ static const struct ide_port_info atiixp_pci_info[] __devinitdata = { | |||
151 | .name = "ATIIXP", | 151 | .name = "ATIIXP", |
152 | .init_hwif = init_hwif_atiixp, | 152 | .init_hwif = init_hwif_atiixp, |
153 | .enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}}, | 153 | .enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}}, |
154 | .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE, | 154 | .host_flags = IDE_HFLAG_LEGACY_IRQS, |
155 | .pio_mask = ATA_PIO4, | 155 | .pio_mask = ATA_PIO4, |
156 | .mwdma_mask = ATA_MWDMA2, | 156 | .mwdma_mask = ATA_MWDMA2, |
157 | .udma_mask = ATA_UDMA5, | 157 | .udma_mask = ATA_UDMA5, |
@@ -159,8 +159,7 @@ static const struct ide_port_info atiixp_pci_info[] __devinitdata = { | |||
159 | .name = "SB600_PATA", | 159 | .name = "SB600_PATA", |
160 | .init_hwif = init_hwif_atiixp, | 160 | .init_hwif = init_hwif_atiixp, |
161 | .enablebits = {{0x48,0x01,0x00}, {0x00,0x00,0x00}}, | 161 | .enablebits = {{0x48,0x01,0x00}, {0x00,0x00,0x00}}, |
162 | .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_LEGACY_IRQS | | 162 | .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_LEGACY_IRQS, |
163 | IDE_HFLAG_BOOTABLE, | ||
164 | .pio_mask = ATA_PIO4, | 163 | .pio_mask = ATA_PIO4, |
165 | .mwdma_mask = ATA_MWDMA2, | 164 | .mwdma_mask = ATA_MWDMA2, |
166 | .udma_mask = ATA_UDMA5, | 165 | .udma_mask = ATA_UDMA5, |
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c index a1cfe033a55f..b076dbfc43a7 100644 --- a/drivers/ide/pci/cmd640.c +++ b/drivers/ide/pci/cmd640.c | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | /* | 5 | /* |
6 | * Original authors: abramov@cecmow.enet.dec.com (Igor Abramov) | 6 | * Original authors: abramov@cecmow.enet.dec.com (Igor Abramov) |
7 | * mlord@pobox.com (Mark Lord) | 7 | * mlord@pobox.com (Mark Lord) |
8 | * | 8 | * |
9 | * See linux/MAINTAINERS for address of current maintainer. | 9 | * See linux/MAINTAINERS for address of current maintainer. |
10 | * | 10 | * |
@@ -98,7 +98,7 @@ | |||
98 | 98 | ||
99 | #define CMD640_PREFETCH_MASKS 1 | 99 | #define CMD640_PREFETCH_MASKS 1 |
100 | 100 | ||
101 | //#define CMD640_DUMP_REGS | 101 | /*#define CMD640_DUMP_REGS */ |
102 | 102 | ||
103 | #include <linux/types.h> | 103 | #include <linux/types.h> |
104 | #include <linux/kernel.h> | 104 | #include <linux/kernel.h> |
@@ -112,7 +112,7 @@ | |||
112 | /* | 112 | /* |
113 | * This flag is set in ide.c by the parameter: ide0=cmd640_vlb | 113 | * This flag is set in ide.c by the parameter: ide0=cmd640_vlb |
114 | */ | 114 | */ |
115 | int cmd640_vlb = 0; | 115 | int cmd640_vlb; |
116 | 116 | ||
117 | /* | 117 | /* |
118 | * CMD640 specific registers definition. | 118 | * CMD640 specific registers definition. |
@@ -185,7 +185,6 @@ static DEFINE_SPINLOCK(cmd640_lock); | |||
185 | * These are initialized to point at the devices we control | 185 | * These are initialized to point at the devices we control |
186 | */ | 186 | */ |
187 | static ide_hwif_t *cmd_hwif0, *cmd_hwif1; | 187 | static ide_hwif_t *cmd_hwif0, *cmd_hwif1; |
188 | static ide_drive_t *cmd_drives[4]; | ||
189 | 188 | ||
190 | /* | 189 | /* |
191 | * Interface to access cmd640x registers | 190 | * Interface to access cmd640x registers |
@@ -207,13 +206,13 @@ static unsigned int cmd640_chip_version; | |||
207 | 206 | ||
208 | /* PCI method 1 access */ | 207 | /* PCI method 1 access */ |
209 | 208 | ||
210 | static void put_cmd640_reg_pci1 (u16 reg, u8 val) | 209 | static void put_cmd640_reg_pci1(u16 reg, u8 val) |
211 | { | 210 | { |
212 | outl_p((reg & 0xfc) | cmd640_key, 0xcf8); | 211 | outl_p((reg & 0xfc) | cmd640_key, 0xcf8); |
213 | outb_p(val, (reg & 3) | 0xcfc); | 212 | outb_p(val, (reg & 3) | 0xcfc); |
214 | } | 213 | } |
215 | 214 | ||
216 | static u8 get_cmd640_reg_pci1 (u16 reg) | 215 | static u8 get_cmd640_reg_pci1(u16 reg) |
217 | { | 216 | { |
218 | outl_p((reg & 0xfc) | cmd640_key, 0xcf8); | 217 | outl_p((reg & 0xfc) | cmd640_key, 0xcf8); |
219 | return inb_p((reg & 3) | 0xcfc); | 218 | return inb_p((reg & 3) | 0xcfc); |
@@ -221,14 +220,14 @@ static u8 get_cmd640_reg_pci1 (u16 reg) | |||
221 | 220 | ||
222 | /* PCI method 2 access (from CMD datasheet) */ | 221 | /* PCI method 2 access (from CMD datasheet) */ |
223 | 222 | ||
224 | static void put_cmd640_reg_pci2 (u16 reg, u8 val) | 223 | static void put_cmd640_reg_pci2(u16 reg, u8 val) |
225 | { | 224 | { |
226 | outb_p(0x10, 0xcf8); | 225 | outb_p(0x10, 0xcf8); |
227 | outb_p(val, cmd640_key + reg); | 226 | outb_p(val, cmd640_key + reg); |
228 | outb_p(0, 0xcf8); | 227 | outb_p(0, 0xcf8); |
229 | } | 228 | } |
230 | 229 | ||
231 | static u8 get_cmd640_reg_pci2 (u16 reg) | 230 | static u8 get_cmd640_reg_pci2(u16 reg) |
232 | { | 231 | { |
233 | u8 b; | 232 | u8 b; |
234 | 233 | ||
@@ -240,13 +239,13 @@ static u8 get_cmd640_reg_pci2 (u16 reg) | |||
240 | 239 | ||
241 | /* VLB access */ | 240 | /* VLB access */ |
242 | 241 | ||
243 | static void put_cmd640_reg_vlb (u16 reg, u8 val) | 242 | static void put_cmd640_reg_vlb(u16 reg, u8 val) |
244 | { | 243 | { |
245 | outb_p(reg, cmd640_key); | 244 | outb_p(reg, cmd640_key); |
246 | outb_p(val, cmd640_key + 4); | 245 | outb_p(val, cmd640_key + 4); |
247 | } | 246 | } |
248 | 247 | ||
249 | static u8 get_cmd640_reg_vlb (u16 reg) | 248 | static u8 get_cmd640_reg_vlb(u16 reg) |
250 | { | 249 | { |
251 | outb_p(reg, cmd640_key); | 250 | outb_p(reg, cmd640_key); |
252 | return inb_p(cmd640_key + 4); | 251 | return inb_p(cmd640_key + 4); |
@@ -268,11 +267,11 @@ static void put_cmd640_reg(u16 reg, u8 val) | |||
268 | unsigned long flags; | 267 | unsigned long flags; |
269 | 268 | ||
270 | spin_lock_irqsave(&cmd640_lock, flags); | 269 | spin_lock_irqsave(&cmd640_lock, flags); |
271 | __put_cmd640_reg(reg,val); | 270 | __put_cmd640_reg(reg, val); |
272 | spin_unlock_irqrestore(&cmd640_lock, flags); | 271 | spin_unlock_irqrestore(&cmd640_lock, flags); |
273 | } | 272 | } |
274 | 273 | ||
275 | static int __init match_pci_cmd640_device (void) | 274 | static int __init match_pci_cmd640_device(void) |
276 | { | 275 | { |
277 | const u8 ven_dev[4] = {0x95, 0x10, 0x40, 0x06}; | 276 | const u8 ven_dev[4] = {0x95, 0x10, 0x40, 0x06}; |
278 | unsigned int i; | 277 | unsigned int i; |
@@ -292,7 +291,7 @@ static int __init match_pci_cmd640_device (void) | |||
292 | /* | 291 | /* |
293 | * Probe for CMD640x -- pci method 1 | 292 | * Probe for CMD640x -- pci method 1 |
294 | */ | 293 | */ |
295 | static int __init probe_for_cmd640_pci1 (void) | 294 | static int __init probe_for_cmd640_pci1(void) |
296 | { | 295 | { |
297 | __get_cmd640_reg = get_cmd640_reg_pci1; | 296 | __get_cmd640_reg = get_cmd640_reg_pci1; |
298 | __put_cmd640_reg = put_cmd640_reg_pci1; | 297 | __put_cmd640_reg = put_cmd640_reg_pci1; |
@@ -308,7 +307,7 @@ static int __init probe_for_cmd640_pci1 (void) | |||
308 | /* | 307 | /* |
309 | * Probe for CMD640x -- pci method 2 | 308 | * Probe for CMD640x -- pci method 2 |
310 | */ | 309 | */ |
311 | static int __init probe_for_cmd640_pci2 (void) | 310 | static int __init probe_for_cmd640_pci2(void) |
312 | { | 311 | { |
313 | __get_cmd640_reg = get_cmd640_reg_pci2; | 312 | __get_cmd640_reg = get_cmd640_reg_pci2; |
314 | __put_cmd640_reg = put_cmd640_reg_pci2; | 313 | __put_cmd640_reg = put_cmd640_reg_pci2; |
@@ -322,7 +321,7 @@ static int __init probe_for_cmd640_pci2 (void) | |||
322 | /* | 321 | /* |
323 | * Probe for CMD640x -- vlb | 322 | * Probe for CMD640x -- vlb |
324 | */ | 323 | */ |
325 | static int __init probe_for_cmd640_vlb (void) | 324 | static int __init probe_for_cmd640_vlb(void) |
326 | { | 325 | { |
327 | u8 b; | 326 | u8 b; |
328 | 327 | ||
@@ -343,7 +342,7 @@ static int __init probe_for_cmd640_vlb (void) | |||
343 | * Returns 1 if an IDE interface/drive exists at 0x170, | 342 | * Returns 1 if an IDE interface/drive exists at 0x170, |
344 | * Returns 0 otherwise. | 343 | * Returns 0 otherwise. |
345 | */ | 344 | */ |
346 | static int __init secondary_port_responding (void) | 345 | static int __init secondary_port_responding(void) |
347 | { | 346 | { |
348 | unsigned long flags; | 347 | unsigned long flags; |
349 | 348 | ||
@@ -367,7 +366,7 @@ static int __init secondary_port_responding (void) | |||
367 | /* | 366 | /* |
368 | * Dump out all cmd640 registers. May be called from ide.c | 367 | * Dump out all cmd640 registers. May be called from ide.c |
369 | */ | 368 | */ |
370 | static void cmd640_dump_regs (void) | 369 | static void cmd640_dump_regs(void) |
371 | { | 370 | { |
372 | unsigned int reg = cmd640_vlb ? 0x50 : 0x00; | 371 | unsigned int reg = cmd640_vlb ? 0x50 : 0x00; |
373 | 372 | ||
@@ -386,9 +385,8 @@ static void cmd640_dump_regs (void) | |||
386 | * Check whether prefetch is on for a drive, | 385 | * Check whether prefetch is on for a drive, |
387 | * and initialize the unmask flags for safe operation. | 386 | * and initialize the unmask flags for safe operation. |
388 | */ | 387 | */ |
389 | static void __init check_prefetch (unsigned int index) | 388 | static void __init check_prefetch(ide_drive_t *drive, unsigned int index) |
390 | { | 389 | { |
391 | ide_drive_t *drive = cmd_drives[index]; | ||
392 | u8 b = get_cmd640_reg(prefetch_regs[index]); | 390 | u8 b = get_cmd640_reg(prefetch_regs[index]); |
393 | 391 | ||
394 | if (b & prefetch_masks[index]) { /* is prefetch off? */ | 392 | if (b & prefetch_masks[index]) { /* is prefetch off? */ |
@@ -404,28 +402,13 @@ static void __init check_prefetch (unsigned int index) | |||
404 | } | 402 | } |
405 | } | 403 | } |
406 | 404 | ||
407 | /* | ||
408 | * Figure out which devices we control | ||
409 | */ | ||
410 | static void __init setup_device_ptrs (void) | ||
411 | { | ||
412 | cmd_hwif0 = &ide_hwifs[0]; | ||
413 | cmd_hwif1 = &ide_hwifs[1]; | ||
414 | |||
415 | cmd_drives[0] = &cmd_hwif0->drives[0]; | ||
416 | cmd_drives[1] = &cmd_hwif0->drives[1]; | ||
417 | cmd_drives[2] = &cmd_hwif1->drives[0]; | ||
418 | cmd_drives[3] = &cmd_hwif1->drives[1]; | ||
419 | } | ||
420 | |||
421 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED | 405 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED |
422 | 406 | ||
423 | /* | 407 | /* |
424 | * Sets prefetch mode for a drive. | 408 | * Sets prefetch mode for a drive. |
425 | */ | 409 | */ |
426 | static void set_prefetch_mode (unsigned int index, int mode) | 410 | static void set_prefetch_mode(ide_drive_t *drive, unsigned int index, int mode) |
427 | { | 411 | { |
428 | ide_drive_t *drive = cmd_drives[index]; | ||
429 | unsigned long flags; | 412 | unsigned long flags; |
430 | int reg = prefetch_regs[index]; | 413 | int reg = prefetch_regs[index]; |
431 | u8 b; | 414 | u8 b; |
@@ -452,7 +435,7 @@ static void set_prefetch_mode (unsigned int index, int mode) | |||
452 | /* | 435 | /* |
453 | * Dump out current drive clocks settings | 436 | * Dump out current drive clocks settings |
454 | */ | 437 | */ |
455 | static void display_clocks (unsigned int index) | 438 | static void display_clocks(unsigned int index) |
456 | { | 439 | { |
457 | u8 active_count, recovery_count; | 440 | u8 active_count, recovery_count; |
458 | 441 | ||
@@ -471,7 +454,7 @@ static void display_clocks (unsigned int index) | |||
471 | * Pack active and recovery counts into single byte representation | 454 | * Pack active and recovery counts into single byte representation |
472 | * used by controller | 455 | * used by controller |
473 | */ | 456 | */ |
474 | static inline u8 pack_nibbles (u8 upper, u8 lower) | 457 | static inline u8 pack_nibbles(u8 upper, u8 lower) |
475 | { | 458 | { |
476 | return ((upper & 0x0f) << 4) | (lower & 0x0f); | 459 | return ((upper & 0x0f) << 4) | (lower & 0x0f); |
477 | } | 460 | } |
@@ -479,7 +462,7 @@ static inline u8 pack_nibbles (u8 upper, u8 lower) | |||
479 | /* | 462 | /* |
480 | * This routine retrieves the initial drive timings from the chipset. | 463 | * This routine retrieves the initial drive timings from the chipset. |
481 | */ | 464 | */ |
482 | static void __init retrieve_drive_counts (unsigned int index) | 465 | static void __init retrieve_drive_counts(unsigned int index) |
483 | { | 466 | { |
484 | u8 b; | 467 | u8 b; |
485 | 468 | ||
@@ -488,10 +471,10 @@ static void __init retrieve_drive_counts (unsigned int index) | |||
488 | */ | 471 | */ |
489 | b = get_cmd640_reg(arttim_regs[index]) & ~0x3f; | 472 | b = get_cmd640_reg(arttim_regs[index]) & ~0x3f; |
490 | switch (b) { | 473 | switch (b) { |
491 | case 0x00: b = 4; break; | 474 | case 0x00: b = 4; break; |
492 | case 0x80: b = 3; break; | 475 | case 0x80: b = 3; break; |
493 | case 0x40: b = 2; break; | 476 | case 0x40: b = 2; break; |
494 | default: b = 5; break; | 477 | default: b = 5; break; |
495 | } | 478 | } |
496 | setup_counts[index] = b; | 479 | setup_counts[index] = b; |
497 | 480 | ||
@@ -508,7 +491,7 @@ static void __init retrieve_drive_counts (unsigned int index) | |||
508 | * This routine writes the prepared setup/active/recovery counts | 491 | * This routine writes the prepared setup/active/recovery counts |
509 | * for a drive into the cmd640 chipset registers to active them. | 492 | * for a drive into the cmd640 chipset registers to active them. |
510 | */ | 493 | */ |
511 | static void program_drive_counts (unsigned int index) | 494 | static void program_drive_counts(ide_drive_t *drive, unsigned int index) |
512 | { | 495 | { |
513 | unsigned long flags; | 496 | unsigned long flags; |
514 | u8 setup_count = setup_counts[index]; | 497 | u8 setup_count = setup_counts[index]; |
@@ -522,8 +505,11 @@ static void program_drive_counts (unsigned int index) | |||
522 | * so we merge the timings, using the slowest value for each timing. | 505 | * so we merge the timings, using the slowest value for each timing. |
523 | */ | 506 | */ |
524 | if (index > 1) { | 507 | if (index > 1) { |
525 | unsigned int mate; | 508 | ide_hwif_t *hwif = drive->hwif; |
526 | if (cmd_drives[mate = index ^ 1]->present) { | 509 | ide_drive_t *peer = &hwif->drives[!drive->select.b.unit]; |
510 | unsigned int mate = index ^ 1; | ||
511 | |||
512 | if (peer->present) { | ||
527 | if (setup_count < setup_counts[mate]) | 513 | if (setup_count < setup_counts[mate]) |
528 | setup_count = setup_counts[mate]; | 514 | setup_count = setup_counts[mate]; |
529 | if (active_count < active_counts[mate]) | 515 | if (active_count < active_counts[mate]) |
@@ -537,11 +523,11 @@ static void program_drive_counts (unsigned int index) | |||
537 | * Convert setup_count to internal chipset representation | 523 | * Convert setup_count to internal chipset representation |
538 | */ | 524 | */ |
539 | switch (setup_count) { | 525 | switch (setup_count) { |
540 | case 4: setup_count = 0x00; break; | 526 | case 4: setup_count = 0x00; break; |
541 | case 3: setup_count = 0x80; break; | 527 | case 3: setup_count = 0x80; break; |
542 | case 1: | 528 | case 1: |
543 | case 2: setup_count = 0x40; break; | 529 | case 2: setup_count = 0x40; break; |
544 | default: setup_count = 0xc0; /* case 5 */ | 530 | default: setup_count = 0xc0; /* case 5 */ |
545 | } | 531 | } |
546 | 532 | ||
547 | /* | 533 | /* |
@@ -562,7 +548,8 @@ static void program_drive_counts (unsigned int index) | |||
562 | /* | 548 | /* |
563 | * Set a specific pio_mode for a drive | 549 | * Set a specific pio_mode for a drive |
564 | */ | 550 | */ |
565 | static void cmd640_set_mode (unsigned int index, u8 pio_mode, unsigned int cycle_time) | 551 | static void cmd640_set_mode(ide_drive_t *drive, unsigned int index, |
552 | u8 pio_mode, unsigned int cycle_time) | ||
566 | { | 553 | { |
567 | int setup_time, active_time, recovery_time, clock_time; | 554 | int setup_time, active_time, recovery_time, clock_time; |
568 | u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count; | 555 | u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count; |
@@ -574,15 +561,15 @@ static void cmd640_set_mode (unsigned int index, u8 pio_mode, unsigned int cycle | |||
574 | active_time = ide_pio_timings[pio_mode].active_time; | 561 | active_time = ide_pio_timings[pio_mode].active_time; |
575 | recovery_time = cycle_time - (setup_time + active_time); | 562 | recovery_time = cycle_time - (setup_time + active_time); |
576 | clock_time = 1000 / bus_speed; | 563 | clock_time = 1000 / bus_speed; |
577 | cycle_count = (cycle_time + clock_time - 1) / clock_time; | 564 | cycle_count = DIV_ROUND_UP(cycle_time, clock_time); |
578 | 565 | ||
579 | setup_count = (setup_time + clock_time - 1) / clock_time; | 566 | setup_count = DIV_ROUND_UP(setup_time, clock_time); |
580 | 567 | ||
581 | active_count = (active_time + clock_time - 1) / clock_time; | 568 | active_count = DIV_ROUND_UP(active_time, clock_time); |
582 | if (active_count < 2) | 569 | if (active_count < 2) |
583 | active_count = 2; /* minimum allowed by cmd640 */ | 570 | active_count = 2; /* minimum allowed by cmd640 */ |
584 | 571 | ||
585 | recovery_count = (recovery_time + clock_time - 1) / clock_time; | 572 | recovery_count = DIV_ROUND_UP(recovery_time, clock_time); |
586 | recovery_count2 = cycle_count - (setup_count + active_count); | 573 | recovery_count2 = cycle_count - (setup_count + active_count); |
587 | if (recovery_count2 > recovery_count) | 574 | if (recovery_count2 > recovery_count) |
588 | recovery_count = recovery_count2; | 575 | recovery_count = recovery_count2; |
@@ -611,7 +598,7 @@ static void cmd640_set_mode (unsigned int index, u8 pio_mode, unsigned int cycle | |||
611 | * 1) this is the wrong place to do it (proper is do_special() in ide.c) | 598 | * 1) this is the wrong place to do it (proper is do_special() in ide.c) |
612 | * 2) in practice this is rarely, if ever, necessary | 599 | * 2) in practice this is rarely, if ever, necessary |
613 | */ | 600 | */ |
614 | program_drive_counts (index); | 601 | program_drive_counts(drive, index); |
615 | } | 602 | } |
616 | 603 | ||
617 | static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio) | 604 | static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio) |
@@ -619,32 +606,26 @@ static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
619 | unsigned int index = 0, cycle_time; | 606 | unsigned int index = 0, cycle_time; |
620 | u8 b; | 607 | u8 b; |
621 | 608 | ||
622 | while (drive != cmd_drives[index]) { | ||
623 | if (++index > 3) { | ||
624 | printk(KERN_ERR "%s: bad news in %s\n", | ||
625 | drive->name, __FUNCTION__); | ||
626 | return; | ||
627 | } | ||
628 | } | ||
629 | switch (pio) { | 609 | switch (pio) { |
630 | case 6: /* set fast-devsel off */ | 610 | case 6: /* set fast-devsel off */ |
631 | case 7: /* set fast-devsel on */ | 611 | case 7: /* set fast-devsel on */ |
632 | b = get_cmd640_reg(CNTRL) & ~0x27; | 612 | b = get_cmd640_reg(CNTRL) & ~0x27; |
633 | if (pio & 1) | 613 | if (pio & 1) |
634 | b |= 0x27; | 614 | b |= 0x27; |
635 | put_cmd640_reg(CNTRL, b); | 615 | put_cmd640_reg(CNTRL, b); |
636 | printk("%s: %sabled cmd640 fast host timing (devsel)\n", drive->name, (pio & 1) ? "en" : "dis"); | 616 | printk("%s: %sabled cmd640 fast host timing (devsel)\n", |
637 | return; | 617 | drive->name, (pio & 1) ? "en" : "dis"); |
638 | 618 | return; | |
639 | case 8: /* set prefetch off */ | 619 | case 8: /* set prefetch off */ |
640 | case 9: /* set prefetch on */ | 620 | case 9: /* set prefetch on */ |
641 | set_prefetch_mode(index, pio & 1); | 621 | set_prefetch_mode(drive, index, pio & 1); |
642 | printk("%s: %sabled cmd640 prefetch\n", drive->name, (pio & 1) ? "en" : "dis"); | 622 | printk("%s: %sabled cmd640 prefetch\n", |
643 | return; | 623 | drive->name, (pio & 1) ? "en" : "dis"); |
624 | return; | ||
644 | } | 625 | } |
645 | 626 | ||
646 | cycle_time = ide_pio_cycle_time(drive, pio); | 627 | cycle_time = ide_pio_cycle_time(drive, pio); |
647 | cmd640_set_mode(index, pio, cycle_time); | 628 | cmd640_set_mode(drive, index, pio, cycle_time); |
648 | 629 | ||
649 | printk("%s: selected cmd640 PIO mode%d (%dns)", | 630 | printk("%s: selected cmd640 PIO mode%d (%dns)", |
650 | drive->name, pio, cycle_time); | 631 | drive->name, pio, cycle_time); |
@@ -749,7 +730,7 @@ static int __init cmd640x_init(void) | |||
749 | cfr = get_cmd640_reg(CFR); | 730 | cfr = get_cmd640_reg(CFR); |
750 | cmd640_chip_version = cfr & CFR_DEVREV; | 731 | cmd640_chip_version = cfr & CFR_DEVREV; |
751 | if (cmd640_chip_version == 0) { | 732 | if (cmd640_chip_version == 0) { |
752 | printk ("ide: bad cmd640 revision: %d\n", cmd640_chip_version); | 733 | printk("ide: bad cmd640 revision: %d\n", cmd640_chip_version); |
753 | return 0; | 734 | return 0; |
754 | } | 735 | } |
755 | 736 | ||
@@ -764,17 +745,19 @@ static int __init cmd640x_init(void) | |||
764 | printk(KERN_INFO "cmd640: buggy cmd640%c interface on %s, config=0x%02x" | 745 | printk(KERN_INFO "cmd640: buggy cmd640%c interface on %s, config=0x%02x" |
765 | "\n", 'a' + cmd640_chip_version - 1, bus_type, cfr); | 746 | "\n", 'a' + cmd640_chip_version - 1, bus_type, cfr); |
766 | 747 | ||
748 | cmd_hwif0 = ide_find_port(); | ||
749 | |||
767 | /* | 750 | /* |
768 | * Initialize data for primary port | 751 | * Initialize data for primary port |
769 | */ | 752 | */ |
770 | setup_device_ptrs (); | 753 | if (cmd_hwif0) { |
771 | 754 | ide_init_port_hw(cmd_hwif0, &hw[0]); | |
772 | ide_init_port_hw(cmd_hwif0, &hw[0]); | ||
773 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED | 755 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED |
774 | cmd_hwif0->set_pio_mode = &cmd640_set_pio_mode; | 756 | cmd_hwif0->set_pio_mode = &cmd640_set_pio_mode; |
775 | #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ | 757 | #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ |
776 | 758 | ||
777 | idx[0] = cmd_hwif0->index; | 759 | idx[0] = cmd_hwif0->index; |
760 | } | ||
778 | 761 | ||
779 | /* | 762 | /* |
780 | * Ensure compatibility by always using the slowest timings | 763 | * Ensure compatibility by always using the slowest timings |
@@ -786,10 +769,13 @@ static int __init cmd640x_init(void) | |||
786 | put_cmd640_reg(CMDTIM, 0); | 769 | put_cmd640_reg(CMDTIM, 0); |
787 | put_cmd640_reg(BRST, 0x40); | 770 | put_cmd640_reg(BRST, 0x40); |
788 | 771 | ||
772 | cmd_hwif1 = ide_find_port(); | ||
773 | |||
789 | /* | 774 | /* |
790 | * Try to enable the secondary interface, if not already enabled | 775 | * Try to enable the secondary interface, if not already enabled |
791 | */ | 776 | */ |
792 | if (cmd_hwif1->drives[0].noprobe && cmd_hwif1->drives[1].noprobe) { | 777 | if (cmd_hwif1 && |
778 | cmd_hwif1->drives[0].noprobe && cmd_hwif1->drives[1].noprobe) { | ||
793 | port2 = "not probed"; | 779 | port2 = "not probed"; |
794 | } else { | 780 | } else { |
795 | b = get_cmd640_reg(CNTRL); | 781 | b = get_cmd640_reg(CNTRL); |
@@ -820,7 +806,7 @@ static int __init cmd640x_init(void) | |||
820 | /* | 806 | /* |
821 | * Initialize data for secondary cmd640 port, if enabled | 807 | * Initialize data for secondary cmd640 port, if enabled |
822 | */ | 808 | */ |
823 | if (second_port_cmd640) { | 809 | if (second_port_cmd640 && cmd_hwif1) { |
824 | ide_init_port_hw(cmd_hwif1, &hw[1]); | 810 | ide_init_port_hw(cmd_hwif1, &hw[1]); |
825 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED | 811 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED |
826 | cmd_hwif1->set_pio_mode = &cmd640_set_pio_mode; | 812 | cmd_hwif1->set_pio_mode = &cmd640_set_pio_mode; |
@@ -828,7 +814,7 @@ static int __init cmd640x_init(void) | |||
828 | 814 | ||
829 | idx[1] = cmd_hwif1->index; | 815 | idx[1] = cmd_hwif1->index; |
830 | } | 816 | } |
831 | printk(KERN_INFO "%s: %sserialized, secondary interface %s\n", cmd_hwif1->name, | 817 | printk(KERN_INFO "cmd640: %sserialized, secondary interface %s\n", |
832 | second_port_cmd640 ? "" : "not ", port2); | 818 | second_port_cmd640 ? "" : "not ", port2); |
833 | 819 | ||
834 | /* | 820 | /* |
@@ -836,18 +822,30 @@ static int __init cmd640x_init(void) | |||
836 | * Do not unnecessarily disturb any prior BIOS setup of these. | 822 | * Do not unnecessarily disturb any prior BIOS setup of these. |
837 | */ | 823 | */ |
838 | for (index = 0; index < (2 + (second_port_cmd640 << 1)); index++) { | 824 | for (index = 0; index < (2 + (second_port_cmd640 << 1)); index++) { |
839 | ide_drive_t *drive = cmd_drives[index]; | 825 | ide_drive_t *drive; |
826 | |||
827 | if (index > 1) { | ||
828 | if (cmd_hwif1 == NULL) | ||
829 | continue; | ||
830 | drive = &cmd_hwif1->drives[index & 1]; | ||
831 | } else { | ||
832 | if (cmd_hwif0 == NULL) | ||
833 | continue; | ||
834 | drive = &cmd_hwif0->drives[index & 1]; | ||
835 | } | ||
836 | |||
840 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED | 837 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED |
841 | if (drive->autotune || ((index > 1) && second_port_toggled)) { | 838 | if (drive->autotune || ((index > 1) && second_port_toggled)) { |
842 | /* | 839 | /* |
843 | * Reset timing to the slowest speed and turn off prefetch. | 840 | * Reset timing to the slowest speed and turn off |
844 | * This way, the drive identify code has a better chance. | 841 | * prefetch. This way, the drive identify code has |
842 | * a better chance. | ||
845 | */ | 843 | */ |
846 | setup_counts [index] = 4; /* max possible */ | 844 | setup_counts [index] = 4; /* max possible */ |
847 | active_counts [index] = 16; /* max possible */ | 845 | active_counts [index] = 16; /* max possible */ |
848 | recovery_counts [index] = 16; /* max possible */ | 846 | recovery_counts [index] = 16; /* max possible */ |
849 | program_drive_counts (index); | 847 | program_drive_counts(drive, index); |
850 | set_prefetch_mode (index, 0); | 848 | set_prefetch_mode(drive, index, 0); |
851 | printk("cmd640: drive%d timings/prefetch cleared\n", index); | 849 | printk("cmd640: drive%d timings/prefetch cleared\n", index); |
852 | } else { | 850 | } else { |
853 | /* | 851 | /* |
@@ -855,7 +853,7 @@ static int __init cmd640x_init(void) | |||
855 | * This preserves any prior BIOS setup. | 853 | * This preserves any prior BIOS setup. |
856 | */ | 854 | */ |
857 | retrieve_drive_counts (index); | 855 | retrieve_drive_counts (index); |
858 | check_prefetch (index); | 856 | check_prefetch(drive, index); |
859 | printk("cmd640: drive%d timings/prefetch(%s) preserved", | 857 | printk("cmd640: drive%d timings/prefetch(%s) preserved", |
860 | index, drive->no_io_32bit ? "off" : "on"); | 858 | index, drive->no_io_32bit ? "off" : "on"); |
861 | display_clocks(index); | 859 | display_clocks(index); |
@@ -864,7 +862,7 @@ static int __init cmd640x_init(void) | |||
864 | /* | 862 | /* |
865 | * Set the drive unmask flags to match the prefetch setting | 863 | * Set the drive unmask flags to match the prefetch setting |
866 | */ | 864 | */ |
867 | check_prefetch (index); | 865 | check_prefetch(drive, index); |
868 | printk("cmd640: drive%d timings/prefetch(%s) preserved\n", | 866 | printk("cmd640: drive%d timings/prefetch(%s) preserved\n", |
869 | index, drive->no_io_32bit ? "off" : "on"); | 867 | index, drive->no_io_32bit ? "off" : "on"); |
870 | #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ | 868 | #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ |
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index edabe6299efd..8baccfef237f 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c | |||
@@ -440,8 +440,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | |||
440 | .init_hwif = init_hwif_cmd64x, | 440 | .init_hwif = init_hwif_cmd64x, |
441 | .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, | 441 | .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, |
442 | .host_flags = IDE_HFLAG_CLEAR_SIMPLEX | | 442 | .host_flags = IDE_HFLAG_CLEAR_SIMPLEX | |
443 | IDE_HFLAG_ABUSE_PREFETCH | | 443 | IDE_HFLAG_ABUSE_PREFETCH, |
444 | IDE_HFLAG_BOOTABLE, | ||
445 | .pio_mask = ATA_PIO5, | 444 | .pio_mask = ATA_PIO5, |
446 | .mwdma_mask = ATA_MWDMA2, | 445 | .mwdma_mask = ATA_MWDMA2, |
447 | .udma_mask = 0x00, /* no udma */ | 446 | .udma_mask = 0x00, /* no udma */ |
@@ -451,7 +450,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | |||
451 | .init_hwif = init_hwif_cmd64x, | 450 | .init_hwif = init_hwif_cmd64x, |
452 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, | 451 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, |
453 | .chipset = ide_cmd646, | 452 | .chipset = ide_cmd646, |
454 | .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE, | 453 | .host_flags = IDE_HFLAG_ABUSE_PREFETCH, |
455 | .pio_mask = ATA_PIO5, | 454 | .pio_mask = ATA_PIO5, |
456 | .mwdma_mask = ATA_MWDMA2, | 455 | .mwdma_mask = ATA_MWDMA2, |
457 | .udma_mask = ATA_UDMA2, | 456 | .udma_mask = ATA_UDMA2, |
@@ -460,7 +459,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | |||
460 | .init_chipset = init_chipset_cmd64x, | 459 | .init_chipset = init_chipset_cmd64x, |
461 | .init_hwif = init_hwif_cmd64x, | 460 | .init_hwif = init_hwif_cmd64x, |
462 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, | 461 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, |
463 | .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE, | 462 | .host_flags = IDE_HFLAG_ABUSE_PREFETCH, |
464 | .pio_mask = ATA_PIO5, | 463 | .pio_mask = ATA_PIO5, |
465 | .mwdma_mask = ATA_MWDMA2, | 464 | .mwdma_mask = ATA_MWDMA2, |
466 | .udma_mask = ATA_UDMA4, | 465 | .udma_mask = ATA_UDMA4, |
@@ -469,7 +468,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | |||
469 | .init_chipset = init_chipset_cmd64x, | 468 | .init_chipset = init_chipset_cmd64x, |
470 | .init_hwif = init_hwif_cmd64x, | 469 | .init_hwif = init_hwif_cmd64x, |
471 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, | 470 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, |
472 | .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE, | 471 | .host_flags = IDE_HFLAG_ABUSE_PREFETCH, |
473 | .pio_mask = ATA_PIO5, | 472 | .pio_mask = ATA_PIO5, |
474 | .mwdma_mask = ATA_MWDMA2, | 473 | .mwdma_mask = ATA_MWDMA2, |
475 | .udma_mask = ATA_UDMA5, | 474 | .udma_mask = ATA_UDMA5, |
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c index 1c163e4ef03f..01b37ecb5a5a 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/pci/cs5520.c | |||
@@ -122,8 +122,7 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif) | |||
122 | IDE_HFLAG_CS5520 | \ | 122 | IDE_HFLAG_CS5520 | \ |
123 | IDE_HFLAG_VDMA | \ | 123 | IDE_HFLAG_VDMA | \ |
124 | IDE_HFLAG_NO_ATAPI_DMA | \ | 124 | IDE_HFLAG_NO_ATAPI_DMA | \ |
125 | IDE_HFLAG_ABUSE_SET_DMA_MODE |\ | 125 | IDE_HFLAG_ABUSE_SET_DMA_MODE, \ |
126 | IDE_HFLAG_BOOTABLE, \ | ||
127 | .pio_mask = ATA_PIO4, \ | 126 | .pio_mask = ATA_PIO4, \ |
128 | } | 127 | } |
129 | 128 | ||
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index 941a1344820b..56a369c2a78a 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c | |||
@@ -249,8 +249,7 @@ static const struct ide_port_info cs5530_chipset __devinitdata = { | |||
249 | .init_chipset = init_chipset_cs5530, | 249 | .init_chipset = init_chipset_cs5530, |
250 | .init_hwif = init_hwif_cs5530, | 250 | .init_hwif = init_hwif_cs5530, |
251 | .host_flags = IDE_HFLAG_SERIALIZE | | 251 | .host_flags = IDE_HFLAG_SERIALIZE | |
252 | IDE_HFLAG_POST_SET_MODE | | 252 | IDE_HFLAG_POST_SET_MODE, |
253 | IDE_HFLAG_BOOTABLE, | ||
254 | .pio_mask = ATA_PIO4, | 253 | .pio_mask = ATA_PIO4, |
255 | .mwdma_mask = ATA_MWDMA2, | 254 | .mwdma_mask = ATA_MWDMA2, |
256 | .udma_mask = ATA_UDMA2, | 255 | .udma_mask = ATA_UDMA2, |
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c index d7b5ea992e94..c9685f239c65 100644 --- a/drivers/ide/pci/cs5535.c +++ b/drivers/ide/pci/cs5535.c | |||
@@ -186,7 +186,7 @@ static const struct ide_port_info cs5535_chipset __devinitdata = { | |||
186 | .name = "CS5535", | 186 | .name = "CS5535", |
187 | .init_hwif = init_hwif_cs5535, | 187 | .init_hwif = init_hwif_cs5535, |
188 | .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE | | 188 | .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE | |
189 | IDE_HFLAG_ABUSE_SET_DMA_MODE | IDE_HFLAG_BOOTABLE, | 189 | IDE_HFLAG_ABUSE_SET_DMA_MODE, |
190 | .pio_mask = ATA_PIO4, | 190 | .pio_mask = ATA_PIO4, |
191 | .mwdma_mask = ATA_MWDMA2, | 191 | .mwdma_mask = ATA_MWDMA2, |
192 | .udma_mask = ATA_UDMA4, | 192 | .udma_mask = ATA_UDMA4, |
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c index 724cbacf4e5b..08eab7e7f051 100644 --- a/drivers/ide/pci/cy82c693.c +++ b/drivers/ide/pci/cy82c693.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * | 6 | * |
7 | * The CY82C693 chipset is used on Digital's PC-Alpha 164SX boards. | 7 | * The CY82C693 chipset is used on Digital's PC-Alpha 164SX boards. |
8 | * Writing the driver was quite simple, since most of the job is | 8 | * Writing the driver was quite simple, since most of the job is |
9 | * done by the generic pci-ide support. | 9 | * done by the generic pci-ide support. |
10 | * The hard part was finding the CY82C693's datasheet on Cypress's | 10 | * The hard part was finding the CY82C693's datasheet on Cypress's |
11 | * web page :-(. But Altavista solved this problem :-). | 11 | * web page :-(. But Altavista solved this problem :-). |
12 | * | 12 | * |
@@ -15,12 +15,12 @@ | |||
15 | * - I recently got a 16.8G IBM DTTA, so I was able to test it with | 15 | * - I recently got a 16.8G IBM DTTA, so I was able to test it with |
16 | * a large and fast disk - the results look great, so I'd say the | 16 | * a large and fast disk - the results look great, so I'd say the |
17 | * driver is working fine :-) | 17 | * driver is working fine :-) |
18 | * hdparm -t reports 8.17 MB/sec at about 6% CPU usage for the DTTA | 18 | * hdparm -t reports 8.17 MB/sec at about 6% CPU usage for the DTTA |
19 | * - this is my first linux driver, so there's probably a lot of room | 19 | * - this is my first linux driver, so there's probably a lot of room |
20 | * for optimizations and bug fixing, so feel free to do it. | 20 | * for optimizations and bug fixing, so feel free to do it. |
21 | * - use idebus=xx parameter to set PCI bus speed - needed to calc | 21 | * - use idebus=xx parameter to set PCI bus speed - needed to calc |
22 | * timings for PIO modes (default will be 40) | 22 | * timings for PIO modes (default will be 40) |
23 | * - if using PIO mode it's a good idea to set the PIO mode and | 23 | * - if using PIO mode it's a good idea to set the PIO mode and |
24 | * 32-bit I/O support (if possible), e.g. hdparm -p2 -c1 /dev/hda | 24 | * 32-bit I/O support (if possible), e.g. hdparm -p2 -c1 /dev/hda |
25 | * - I had some problems with my IBM DHEA with PIO modes < 2 | 25 | * - I had some problems with my IBM DHEA with PIO modes < 2 |
26 | * (lost interrupts) ????? | 26 | * (lost interrupts) ????? |
@@ -110,11 +110,11 @@ typedef struct pio_clocks_s { | |||
110 | * calc clocks using bus_speed | 110 | * calc clocks using bus_speed |
111 | * returns (rounded up) time in bus clocks for time in ns | 111 | * returns (rounded up) time in bus clocks for time in ns |
112 | */ | 112 | */ |
113 | static int calc_clk (int time, int bus_speed) | 113 | static int calc_clk(int time, int bus_speed) |
114 | { | 114 | { |
115 | int clocks; | 115 | int clocks; |
116 | 116 | ||
117 | clocks = (time*bus_speed+999)/1000 -1; | 117 | clocks = (time*bus_speed+999)/1000 - 1; |
118 | 118 | ||
119 | if (clocks < 0) | 119 | if (clocks < 0) |
120 | clocks = 0; | 120 | clocks = 0; |
@@ -132,8 +132,8 @@ static int calc_clk (int time, int bus_speed) | |||
132 | * NOTE: for mode 0,1 and 2 drives 8-bit IDE command control registers are used | 132 | * NOTE: for mode 0,1 and 2 drives 8-bit IDE command control registers are used |
133 | * for mode 3 and 4 drives 8 and 16-bit timings are the same | 133 | * for mode 3 and 4 drives 8 and 16-bit timings are the same |
134 | * | 134 | * |
135 | */ | 135 | */ |
136 | static void compute_clocks (u8 pio, pio_clocks_t *p_pclk) | 136 | static void compute_clocks(u8 pio, pio_clocks_t *p_pclk) |
137 | { | 137 | { |
138 | int clk1, clk2; | 138 | int clk1, clk2; |
139 | int bus_speed = system_bus_clock(); /* get speed of PCI bus */ | 139 | int bus_speed = system_bus_clock(); /* get speed of PCI bus */ |
@@ -158,7 +158,7 @@ static void compute_clocks (u8 pio, pio_clocks_t *p_pclk) | |||
158 | clk1 = (clk1<<4)|clk2; /* combine active and recovery clocks */ | 158 | clk1 = (clk1<<4)|clk2; /* combine active and recovery clocks */ |
159 | 159 | ||
160 | /* note: we use the same values for 16bit IOR and IOW | 160 | /* note: we use the same values for 16bit IOR and IOW |
161 | * those are all the same, since I don't have other | 161 | * those are all the same, since I don't have other |
162 | * timings than those from ide-lib.c | 162 | * timings than those from ide-lib.c |
163 | */ | 163 | */ |
164 | 164 | ||
@@ -186,7 +186,7 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode) | |||
186 | outb(index, CY82_INDEX_PORT); | 186 | outb(index, CY82_INDEX_PORT); |
187 | data = inb(CY82_DATA_PORT); | 187 | data = inb(CY82_DATA_PORT); |
188 | 188 | ||
189 | printk (KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n", | 189 | printk(KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n", |
190 | drive->name, HWIF(drive)->channel, drive->select.b.unit, | 190 | drive->name, HWIF(drive)->channel, drive->select.b.unit, |
191 | (data&0x3), ((data>>2)&1)); | 191 | (data&0x3), ((data>>2)&1)); |
192 | #endif /* CY82C693_DEBUG_LOGS */ | 192 | #endif /* CY82C693_DEBUG_LOGS */ |
@@ -202,7 +202,7 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode) | |||
202 | mode & 3, single); | 202 | mode & 3, single); |
203 | #endif /* CY82C693_DEBUG_INFO */ | 203 | #endif /* CY82C693_DEBUG_INFO */ |
204 | 204 | ||
205 | /* | 205 | /* |
206 | * note: below we set the value for Bus Master IDE TimeOut Register | 206 | * note: below we set the value for Bus Master IDE TimeOut Register |
207 | * I'm not absolutly sure what this does, but it solved my problem | 207 | * I'm not absolutly sure what this does, but it solved my problem |
208 | * with IDE DMA and sound, so I now can play sound and work with | 208 | * with IDE DMA and sound, so I now can play sound and work with |
@@ -216,8 +216,8 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode) | |||
216 | outb(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT); | 216 | outb(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT); |
217 | outb(data, CY82_DATA_PORT); | 217 | outb(data, CY82_DATA_PORT); |
218 | 218 | ||
219 | #if CY82C693_DEBUG_INFO | 219 | #if CY82C693_DEBUG_INFO |
220 | printk (KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n", | 220 | printk(KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n", |
221 | drive->name, data); | 221 | drive->name, data); |
222 | #endif /* CY82C693_DEBUG_INFO */ | 222 | #endif /* CY82C693_DEBUG_INFO */ |
223 | } | 223 | } |
@@ -242,14 +242,14 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
242 | 242 | ||
243 | #if CY82C693_DEBUG_LOGS | 243 | #if CY82C693_DEBUG_LOGS |
244 | /* for debug let's show the register values */ | 244 | /* for debug let's show the register values */ |
245 | 245 | ||
246 | if (drive->select.b.unit == 0) { | 246 | if (drive->select.b.unit == 0) { |
247 | /* | 247 | /* |
248 | * get master drive registers | 248 | * get master drive registers |
249 | * address setup control register | 249 | * address setup control register |
250 | * is 32 bit !!! | 250 | * is 32 bit !!! |
251 | */ | 251 | */ |
252 | pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); | 252 | pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); |
253 | addrCtrl &= 0x0F; | 253 | addrCtrl &= 0x0F; |
254 | 254 | ||
255 | /* now let's get the remaining registers */ | 255 | /* now let's get the remaining registers */ |
@@ -261,7 +261,7 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
261 | * set slave drive registers | 261 | * set slave drive registers |
262 | * address setup control register | 262 | * address setup control register |
263 | * is 32 bit !!! | 263 | * is 32 bit !!! |
264 | */ | 264 | */ |
265 | pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); | 265 | pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); |
266 | 266 | ||
267 | addrCtrl &= 0xF0; | 267 | addrCtrl &= 0xF0; |
@@ -288,9 +288,9 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
288 | * set master drive | 288 | * set master drive |
289 | * address setup control register | 289 | * address setup control register |
290 | * is 32 bit !!! | 290 | * is 32 bit !!! |
291 | */ | 291 | */ |
292 | pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); | 292 | pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); |
293 | 293 | ||
294 | addrCtrl &= (~0xF); | 294 | addrCtrl &= (~0xF); |
295 | addrCtrl |= (unsigned int)pclk.address_time; | 295 | addrCtrl |= (unsigned int)pclk.address_time; |
296 | pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl); | 296 | pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl); |
@@ -299,14 +299,14 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
299 | pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, pclk.time_16r); | 299 | pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, pclk.time_16r); |
300 | pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, pclk.time_16w); | 300 | pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, pclk.time_16w); |
301 | pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, pclk.time_8); | 301 | pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, pclk.time_8); |
302 | 302 | ||
303 | addrCtrl &= 0xF; | 303 | addrCtrl &= 0xF; |
304 | } else { | 304 | } else { |
305 | /* | 305 | /* |
306 | * set slave drive | 306 | * set slave drive |
307 | * address setup control register | 307 | * address setup control register |
308 | * is 32 bit !!! | 308 | * is 32 bit !!! |
309 | */ | 309 | */ |
310 | pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); | 310 | pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); |
311 | 311 | ||
312 | addrCtrl &= (~0xF0); | 312 | addrCtrl &= (~0xF0); |
@@ -320,7 +320,7 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
320 | 320 | ||
321 | addrCtrl >>= 4; | 321 | addrCtrl >>= 4; |
322 | addrCtrl &= 0xF; | 322 | addrCtrl &= 0xF; |
323 | } | 323 | } |
324 | 324 | ||
325 | #if CY82C693_DEBUG_INFO | 325 | #if CY82C693_DEBUG_INFO |
326 | printk(KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to " | 326 | printk(KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to " |
@@ -340,41 +340,41 @@ static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const c | |||
340 | 340 | ||
341 | #ifdef CY82C693_SETDMA_CLOCK | 341 | #ifdef CY82C693_SETDMA_CLOCK |
342 | u8 data = 0; | 342 | u8 data = 0; |
343 | #endif /* CY82C693_SETDMA_CLOCK */ | 343 | #endif /* CY82C693_SETDMA_CLOCK */ |
344 | 344 | ||
345 | /* write info about this verion of the driver */ | 345 | /* write info about this verion of the driver */ |
346 | printk(KERN_INFO CY82_VERSION "\n"); | 346 | printk(KERN_INFO CY82_VERSION "\n"); |
347 | 347 | ||
348 | #ifdef CY82C693_SETDMA_CLOCK | 348 | #ifdef CY82C693_SETDMA_CLOCK |
349 | /* okay let's set the DMA clock speed */ | 349 | /* okay let's set the DMA clock speed */ |
350 | 350 | ||
351 | outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT); | 351 | outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT); |
352 | data = inb(CY82_DATA_PORT); | 352 | data = inb(CY82_DATA_PORT); |
353 | 353 | ||
354 | #if CY82C693_DEBUG_INFO | 354 | #if CY82C693_DEBUG_INFO |
355 | printk(KERN_INFO "%s: Peripheral Configuration Register: 0x%X\n", | 355 | printk(KERN_INFO "%s: Peripheral Configuration Register: 0x%X\n", |
356 | name, data); | 356 | name, data); |
357 | #endif /* CY82C693_DEBUG_INFO */ | 357 | #endif /* CY82C693_DEBUG_INFO */ |
358 | 358 | ||
359 | /* | 359 | /* |
360 | * for some reason sometimes the DMA controller | 360 | * for some reason sometimes the DMA controller |
361 | * speed is set to ATCLK/2 ???? - we fix this here | 361 | * speed is set to ATCLK/2 ???? - we fix this here |
362 | * | 362 | * |
363 | * note: i don't know what causes this strange behaviour, | 363 | * note: i don't know what causes this strange behaviour, |
364 | * but even changing the dma speed doesn't solve it :-( | 364 | * but even changing the dma speed doesn't solve it :-( |
365 | * the ide performance is still only half the normal speed | 365 | * the ide performance is still only half the normal speed |
366 | * | 366 | * |
367 | * if anybody knows what goes wrong with my machine, please | 367 | * if anybody knows what goes wrong with my machine, please |
368 | * let me know - ASK | 368 | * let me know - ASK |
369 | */ | 369 | */ |
370 | 370 | ||
371 | data |= 0x03; | 371 | data |= 0x03; |
372 | 372 | ||
373 | outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT); | 373 | outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT); |
374 | outb(data, CY82_DATA_PORT); | 374 | outb(data, CY82_DATA_PORT); |
375 | 375 | ||
376 | #if CY82C693_DEBUG_INFO | 376 | #if CY82C693_DEBUG_INFO |
377 | printk (KERN_INFO "%s: New Peripheral Configuration Register: 0x%X\n", | 377 | printk(KERN_INFO "%s: New Peripheral Configuration Register: 0x%X\n", |
378 | name, data); | 378 | name, data); |
379 | #endif /* CY82C693_DEBUG_INFO */ | 379 | #endif /* CY82C693_DEBUG_INFO */ |
380 | 380 | ||
@@ -410,8 +410,7 @@ static const struct ide_port_info cy82c693_chipset __devinitdata = { | |||
410 | .init_iops = init_iops_cy82c693, | 410 | .init_iops = init_iops_cy82c693, |
411 | .init_hwif = init_hwif_cy82c693, | 411 | .init_hwif = init_hwif_cy82c693, |
412 | .chipset = ide_cy82c693, | 412 | .chipset = ide_cy82c693, |
413 | .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_CY82C693 | | 413 | .host_flags = IDE_HFLAG_SINGLE, |
414 | IDE_HFLAG_BOOTABLE, | ||
415 | .pio_mask = ATA_PIO4, | 414 | .pio_mask = ATA_PIO4, |
416 | .swdma_mask = ATA_SWDMA2, | 415 | .swdma_mask = ATA_SWDMA2, |
417 | .mwdma_mask = ATA_MWDMA2, | 416 | .mwdma_mask = ATA_MWDMA2, |
@@ -424,7 +423,7 @@ static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_dev | |||
424 | 423 | ||
425 | /* CY82C693 is more than only a IDE controller. | 424 | /* CY82C693 is more than only a IDE controller. |
426 | Function 1 is primary IDE channel, function 2 - secondary. */ | 425 | Function 1 is primary IDE channel, function 2 - secondary. */ |
427 | if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && | 426 | if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && |
428 | PCI_FUNC(dev->devfn) == 1) { | 427 | PCI_FUNC(dev->devfn) == 1) { |
429 | dev2 = pci_get_slot(dev->bus, dev->devfn + 1); | 428 | dev2 = pci_get_slot(dev->bus, dev->devfn + 1); |
430 | ret = ide_setup_pci_devices(dev, dev2, &cy82c693_chipset); | 429 | ret = ide_setup_pci_devices(dev, dev2, &cy82c693_chipset); |
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c index 961698d655eb..753b86fc6637 100644 --- a/drivers/ide/pci/delkin_cb.c +++ b/drivers/ide/pci/delkin_cb.c | |||
@@ -71,14 +71,13 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) | |||
71 | if (setup[i]) | 71 | if (setup[i]) |
72 | outb(setup[i], base + i); | 72 | outb(setup[i], base + i); |
73 | } | 73 | } |
74 | pci_release_regions(dev); /* IDE layer handles regions itself */ | ||
75 | 74 | ||
76 | memset(&hw, 0, sizeof(hw)); | 75 | memset(&hw, 0, sizeof(hw)); |
77 | ide_std_init_ports(&hw, base + 0x10, base + 0x1e); | 76 | ide_std_init_ports(&hw, base + 0x10, base + 0x1e); |
78 | hw.irq = dev->irq; | 77 | hw.irq = dev->irq; |
79 | hw.chipset = ide_pci; /* this enables IRQ sharing */ | 78 | hw.chipset = ide_pci; /* this enables IRQ sharing */ |
80 | 79 | ||
81 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 80 | hwif = ide_find_port(); |
82 | if (hwif == NULL) | 81 | if (hwif == NULL) |
83 | goto out_disable; | 82 | goto out_disable; |
84 | 83 | ||
@@ -90,6 +89,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) | |||
90 | ide_init_port_data(hwif, i); | 89 | ide_init_port_data(hwif, i); |
91 | 90 | ||
92 | ide_init_port_hw(hwif, &hw); | 91 | ide_init_port_hw(hwif, &hw); |
92 | hwif->mmio = 1; | ||
93 | hwif->quirkproc = &ide_undecoded_slave; | 93 | hwif->quirkproc = &ide_undecoded_slave; |
94 | 94 | ||
95 | idx[0] = i; | 95 | idx[0] = i; |
@@ -110,6 +110,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) | |||
110 | 110 | ||
111 | out_disable: | 111 | out_disable: |
112 | printk(KERN_ERR "delkin_cb: no IDE devices found\n"); | 112 | printk(KERN_ERR "delkin_cb: no IDE devices found\n"); |
113 | pci_release_regions(dev); | ||
113 | pci_disable_device(dev); | 114 | pci_disable_device(dev); |
114 | return -ENODEV; | 115 | return -ENODEV; |
115 | } | 116 | } |
@@ -122,6 +123,7 @@ delkin_cb_remove (struct pci_dev *dev) | |||
122 | if (hwif) | 123 | if (hwif) |
123 | ide_unregister(hwif->index); | 124 | ide_unregister(hwif->index); |
124 | 125 | ||
126 | pci_release_regions(dev); | ||
125 | pci_disable_device(dev); | 127 | pci_disable_device(dev); |
126 | } | 128 | } |
127 | 129 | ||
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index 7fd83a9d4dee..041720e22762 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c | |||
@@ -38,8 +38,7 @@ MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE st | |||
38 | { \ | 38 | { \ |
39 | .name = name_str, \ | 39 | .name = name_str, \ |
40 | .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | \ | 40 | .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | \ |
41 | extra_flags | \ | 41 | extra_flags, \ |
42 | IDE_HFLAG_BOOTABLE, \ | ||
43 | .swdma_mask = ATA_SWDMA2, \ | 42 | .swdma_mask = ATA_SWDMA2, \ |
44 | .mwdma_mask = ATA_MWDMA2, \ | 43 | .mwdma_mask = ATA_MWDMA2, \ |
45 | .udma_mask = ATA_UDMA6, \ | 44 | .udma_mask = ATA_UDMA6, \ |
@@ -50,9 +49,8 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = { | |||
50 | 49 | ||
51 | { /* 1 */ | 50 | { /* 1 */ |
52 | .name = "NS87410", | 51 | .name = "NS87410", |
53 | .enablebits = {{0x43,0x08,0x08}, {0x47,0x08,0x08}}, | 52 | .enablebits = { {0x43, 0x08, 0x08}, {0x47, 0x08, 0x08} }, |
54 | .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | | 53 | .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, |
55 | IDE_HFLAG_BOOTABLE, | ||
56 | .swdma_mask = ATA_SWDMA2, | 54 | .swdma_mask = ATA_SWDMA2, |
57 | .mwdma_mask = ATA_MWDMA2, | 55 | .mwdma_mask = ATA_MWDMA2, |
58 | .udma_mask = ATA_UDMA6, | 56 | .udma_mask = ATA_UDMA6, |
@@ -99,7 +97,7 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = { | |||
99 | * Called when the PCI registration layer (or the IDE initialization) | 97 | * Called when the PCI registration layer (or the IDE initialization) |
100 | * finds a device matching our IDE device tables. | 98 | * finds a device matching our IDE device tables. |
101 | */ | 99 | */ |
102 | 100 | ||
103 | static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_device_id *id) | 101 | static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_device_id *id) |
104 | { | 102 | { |
105 | const struct ide_port_info *d = &generic_chipsets[id->driver_data]; | 103 | const struct ide_port_info *d = &generic_chipsets[id->driver_data]; |
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c index 9f01da46b016..9f2fc3094000 100644 --- a/drivers/ide/pci/hpt34x.c +++ b/drivers/ide/pci/hpt34x.c | |||
@@ -133,7 +133,7 @@ static const struct ide_port_info hpt34x_chipsets[] __devinitdata = { | |||
133 | .init_chipset = init_chipset_hpt34x, | 133 | .init_chipset = init_chipset_hpt34x, |
134 | .init_hwif = init_hwif_hpt34x, | 134 | .init_hwif = init_hwif_hpt34x, |
135 | .extra = 16, | 135 | .extra = 16, |
136 | .host_flags = IDE_HFLAGS_HPT34X, | 136 | .host_flags = IDE_HFLAGS_HPT34X | IDE_HFLAG_NON_BOOTABLE, |
137 | .pio_mask = ATA_PIO5, | 137 | .pio_mask = ATA_PIO5, |
138 | }, | 138 | }, |
139 | { /* 1 */ | 139 | { /* 1 */ |
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 82d0e318a1fe..a49090672145 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c | |||
@@ -1557,7 +1557,7 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic | |||
1557 | hpt374_init(dev, dev2); | 1557 | hpt374_init(dev, dev2); |
1558 | else { | 1558 | else { |
1559 | if (hpt36x_init(dev, dev2)) | 1559 | if (hpt36x_init(dev, dev2)) |
1560 | d.host_flags |= IDE_HFLAG_BOOTABLE; | 1560 | d.host_flags &= ~IDE_HFLAG_NON_BOOTABLE; |
1561 | } | 1561 | } |
1562 | 1562 | ||
1563 | ret = ide_setup_pci_devices(dev, dev2, &d); | 1563 | ret = ide_setup_pci_devices(dev, dev2, &d); |
diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c index e3427eaab430..5b5b0cc4b76a 100644 --- a/drivers/ide/pci/it8213.c +++ b/drivers/ide/pci/it8213.c | |||
@@ -35,7 +35,7 @@ static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
35 | static DEFINE_SPINLOCK(tune_lock); | 35 | static DEFINE_SPINLOCK(tune_lock); |
36 | int control = 0; | 36 | int control = 0; |
37 | 37 | ||
38 | static const u8 timings[][2]= { | 38 | static const u8 timings[][2] = { |
39 | { 0, 0 }, | 39 | { 0, 0 }, |
40 | { 0, 0 }, | 40 | { 0, 0 }, |
41 | { 1, 0 }, | 41 | { 1, 0 }, |
@@ -105,11 +105,10 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
105 | 105 | ||
106 | if (!(reg48 & u_flag)) | 106 | if (!(reg48 & u_flag)) |
107 | pci_write_config_byte(dev, 0x48, reg48 | u_flag); | 107 | pci_write_config_byte(dev, 0x48, reg48 | u_flag); |
108 | if (speed >= XFER_UDMA_5) { | 108 | if (speed >= XFER_UDMA_5) |
109 | pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag); | 109 | pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag); |
110 | } else { | 110 | else |
111 | pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); | 111 | pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); |
112 | } | ||
113 | 112 | ||
114 | if ((reg4a & a_speed) != u_speed) | 113 | if ((reg4a & a_speed) != u_speed) |
115 | pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed); | 114 | pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed); |
@@ -170,9 +169,8 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif) | |||
170 | { \ | 169 | { \ |
171 | .name = name_str, \ | 170 | .name = name_str, \ |
172 | .init_hwif = init_hwif_it8213, \ | 171 | .init_hwif = init_hwif_it8213, \ |
173 | .enablebits = {{0x41,0x80,0x80}}, \ | 172 | .enablebits = { {0x41, 0x80, 0x80} }, \ |
174 | .host_flags = IDE_HFLAG_SINGLE | \ | 173 | .host_flags = IDE_HFLAG_SINGLE, \ |
175 | IDE_HFLAG_BOOTABLE, \ | ||
176 | .pio_mask = ATA_PIO4, \ | 174 | .pio_mask = ATA_PIO4, \ |
177 | .swdma_mask = ATA_SWDMA2_ONLY, \ | 175 | .swdma_mask = ATA_SWDMA2_ONLY, \ |
178 | .mwdma_mask = ATA_MWDMA12_ONLY, \ | 176 | .mwdma_mask = ATA_MWDMA12_ONLY, \ |
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c index d8a167451fd6..a38ec47423a0 100644 --- a/drivers/ide/pci/it821x.c +++ b/drivers/ide/pci/it821x.c | |||
@@ -523,16 +523,12 @@ static void __devinit it821x_quirkproc(ide_drive_t *drive) | |||
523 | static void __devinit init_hwif_it821x(ide_hwif_t *hwif) | 523 | static void __devinit init_hwif_it821x(ide_hwif_t *hwif) |
524 | { | 524 | { |
525 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 525 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
526 | struct it821x_dev *idev = kzalloc(sizeof(struct it821x_dev), GFP_KERNEL); | 526 | struct it821x_dev **itdevs = (struct it821x_dev **)pci_get_drvdata(dev); |
527 | struct it821x_dev *idev = itdevs[hwif->channel]; | ||
527 | u8 conf; | 528 | u8 conf; |
528 | 529 | ||
529 | hwif->quirkproc = &it821x_quirkproc; | 530 | hwif->quirkproc = &it821x_quirkproc; |
530 | 531 | ||
531 | if (idev == NULL) { | ||
532 | printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n"); | ||
533 | return; | ||
534 | } | ||
535 | |||
536 | ide_set_hwifdata(hwif, idev); | 532 | ide_set_hwifdata(hwif, idev); |
537 | 533 | ||
538 | pci_read_config_byte(dev, 0x50, &conf); | 534 | pci_read_config_byte(dev, 0x50, &conf); |
@@ -623,7 +619,6 @@ static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const cha | |||
623 | .name = name_str, \ | 619 | .name = name_str, \ |
624 | .init_chipset = init_chipset_it821x, \ | 620 | .init_chipset = init_chipset_it821x, \ |
625 | .init_hwif = init_hwif_it821x, \ | 621 | .init_hwif = init_hwif_it821x, \ |
626 | .host_flags = IDE_HFLAG_BOOTABLE, \ | ||
627 | .pio_mask = ATA_PIO4, \ | 622 | .pio_mask = ATA_PIO4, \ |
628 | } | 623 | } |
629 | 624 | ||
@@ -642,6 +637,22 @@ static const struct ide_port_info it821x_chipsets[] __devinitdata = { | |||
642 | 637 | ||
643 | static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | 638 | static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_device_id *id) |
644 | { | 639 | { |
640 | struct it821x_dev *itdevs[2] = { NULL, NULL} , *itdev; | ||
641 | unsigned int i; | ||
642 | |||
643 | for (i = 0; i < 2; i++) { | ||
644 | itdev = kzalloc(sizeof(*itdev), GFP_KERNEL); | ||
645 | if (itdev == NULL) { | ||
646 | kfree(itdevs[0]); | ||
647 | printk(KERN_ERR "it821x: out of memory\n"); | ||
648 | return -ENOMEM; | ||
649 | } | ||
650 | |||
651 | itdevs[i] = itdev; | ||
652 | } | ||
653 | |||
654 | pci_set_drvdata(dev, itdevs); | ||
655 | |||
645 | return ide_setup_pci_device(dev, &it821x_chipsets[id->driver_data]); | 656 | return ide_setup_pci_device(dev, &it821x_chipsets[id->driver_data]); |
646 | } | 657 | } |
647 | 658 | ||
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c index a56bcb4f22f4..673f7dc8ba65 100644 --- a/drivers/ide/pci/jmicron.c +++ b/drivers/ide/pci/jmicron.c | |||
@@ -63,8 +63,7 @@ static u8 __devinit ata66_jmicron(ide_hwif_t *hwif) | |||
63 | * actually do our cable checking etc. Thankfully we don't need | 63 | * actually do our cable checking etc. Thankfully we don't need |
64 | * to do the plumbing for other cases. | 64 | * to do the plumbing for other cases. |
65 | */ | 65 | */ |
66 | switch (port_map[port]) | 66 | switch (port_map[port]) { |
67 | { | ||
68 | case PORT_PATA0: | 67 | case PORT_PATA0: |
69 | if (control & (1 << 3)) /* 40/80 pin primary */ | 68 | if (control & (1 << 3)) /* 40/80 pin primary */ |
70 | return ATA_CBL_PATA40; | 69 | return ATA_CBL_PATA40; |
@@ -114,7 +113,6 @@ static void __devinit init_hwif_jmicron(ide_hwif_t *hwif) | |||
114 | static const struct ide_port_info jmicron_chipset __devinitdata = { | 113 | static const struct ide_port_info jmicron_chipset __devinitdata = { |
115 | .name = "JMB", | 114 | .name = "JMB", |
116 | .init_hwif = init_hwif_jmicron, | 115 | .init_hwif = init_hwif_jmicron, |
117 | .host_flags = IDE_HFLAG_BOOTABLE, | ||
118 | .enablebits = { { 0x40, 0x01, 0x01 }, { 0x40, 0x10, 0x10 } }, | 116 | .enablebits = { { 0x40, 0x01, 0x01 }, { 0x40, 0x10, 0x10 } }, |
119 | .pio_mask = ATA_PIO5, | 117 | .pio_mask = ATA_PIO5, |
120 | .mwdma_mask = ATA_MWDMA2, | 118 | .mwdma_mask = ATA_MWDMA2, |
diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c index 75513320aad9..3015d6916d4c 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/pci/ns87415.c | |||
@@ -265,8 +265,7 @@ static const struct ide_port_info ns87415_chipset __devinitdata = { | |||
265 | #endif | 265 | #endif |
266 | .init_hwif = init_hwif_ns87415, | 266 | .init_hwif = init_hwif_ns87415, |
267 | .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | | 267 | .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | |
268 | IDE_HFLAG_NO_ATAPI_DMA | | 268 | IDE_HFLAG_NO_ATAPI_DMA, |
269 | IDE_HFLAG_BOOTABLE, | ||
270 | }; | 269 | }; |
271 | 270 | ||
272 | static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id) | 271 | static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id) |
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c index 46e8748f507e..88a4dd94eeea 100644 --- a/drivers/ide/pci/opti621.c +++ b/drivers/ide/pci/opti621.c | |||
@@ -57,9 +57,9 @@ | |||
57 | * (use idebus=xx to select PCI bus speed). | 57 | * (use idebus=xx to select PCI bus speed). |
58 | * | 58 | * |
59 | * Version 0.1, Nov 8, 1996 | 59 | * Version 0.1, Nov 8, 1996 |
60 | * by Jaromir Koutek, for 2.1.8. | 60 | * by Jaromir Koutek, for 2.1.8. |
61 | * Initial version of driver. | 61 | * Initial version of driver. |
62 | * | 62 | * |
63 | * Version 0.2 | 63 | * Version 0.2 |
64 | * Number 0.2 skipped. | 64 | * Number 0.2 skipped. |
65 | * | 65 | * |
@@ -75,7 +75,7 @@ | |||
75 | * by Jaromir Koutek | 75 | * by Jaromir Koutek |
76 | * Updates for use with (again) new IDE block driver. | 76 | * Updates for use with (again) new IDE block driver. |
77 | * Update of documentation. | 77 | * Update of documentation. |
78 | * | 78 | * |
79 | * Version 0.6, Jan 2, 1999 | 79 | * Version 0.6, Jan 2, 1999 |
80 | * by Jaromir Koutek | 80 | * by Jaromir Koutek |
81 | * Reversed to version 0.3 of the driver, because | 81 | * Reversed to version 0.3 of the driver, because |
@@ -208,29 +208,34 @@ typedef struct pio_clocks_s { | |||
208 | 208 | ||
209 | static void compute_clocks(int pio, pio_clocks_t *clks) | 209 | static void compute_clocks(int pio, pio_clocks_t *clks) |
210 | { | 210 | { |
211 | if (pio != PIO_NOT_EXIST) { | 211 | if (pio != PIO_NOT_EXIST) { |
212 | int adr_setup, data_pls; | 212 | int adr_setup, data_pls; |
213 | int bus_speed = system_bus_clock(); | 213 | int bus_speed = system_bus_clock(); |
214 | 214 | ||
215 | adr_setup = ide_pio_timings[pio].setup_time; | 215 | adr_setup = ide_pio_timings[pio].setup_time; |
216 | data_pls = ide_pio_timings[pio].active_time; | 216 | data_pls = ide_pio_timings[pio].active_time; |
217 | clks->address_time = cmpt_clk(adr_setup, bus_speed); | 217 | clks->address_time = cmpt_clk(adr_setup, bus_speed); |
218 | clks->data_time = cmpt_clk(data_pls, bus_speed); | 218 | clks->data_time = cmpt_clk(data_pls, bus_speed); |
219 | clks->recovery_time = cmpt_clk(ide_pio_timings[pio].cycle_time | 219 | clks->recovery_time = cmpt_clk(ide_pio_timings[pio].cycle_time |
220 | - adr_setup-data_pls, bus_speed); | 220 | - adr_setup-data_pls, bus_speed); |
221 | if (clks->address_time<1) clks->address_time = 1; | 221 | if (clks->address_time < 1) |
222 | if (clks->address_time>4) clks->address_time = 4; | 222 | clks->address_time = 1; |
223 | if (clks->data_time<1) clks->data_time = 1; | 223 | if (clks->address_time > 4) |
224 | if (clks->data_time>16) clks->data_time = 16; | 224 | clks->address_time = 4; |
225 | if (clks->recovery_time<2) clks->recovery_time = 2; | 225 | if (clks->data_time < 1) |
226 | if (clks->recovery_time>17) clks->recovery_time = 17; | 226 | clks->data_time = 1; |
227 | if (clks->data_time > 16) | ||
228 | clks->data_time = 16; | ||
229 | if (clks->recovery_time < 2) | ||
230 | clks->recovery_time = 2; | ||
231 | if (clks->recovery_time > 17) | ||
232 | clks->recovery_time = 17; | ||
227 | } else { | 233 | } else { |
228 | clks->address_time = 1; | 234 | clks->address_time = 1; |
229 | clks->data_time = 1; | 235 | clks->data_time = 1; |
230 | clks->recovery_time = 2; | 236 | clks->recovery_time = 2; |
231 | /* minimal values */ | 237 | /* minimal values */ |
232 | } | 238 | } |
233 | |||
234 | } | 239 | } |
235 | 240 | ||
236 | static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) | 241 | static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) |
@@ -247,8 +252,8 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
247 | 252 | ||
248 | /* sets drive->drive_data for both drives */ | 253 | /* sets drive->drive_data for both drives */ |
249 | compute_pios(drive, pio); | 254 | compute_pios(drive, pio); |
250 | pio1 = hwif->drives[0].drive_data; | 255 | pio1 = hwif->drives[0].drive_data; |
251 | pio2 = hwif->drives[1].drive_data; | 256 | pio2 = hwif->drives[1].drive_data; |
252 | 257 | ||
253 | compute_clocks(pio1, &first); | 258 | compute_clocks(pio1, &first); |
254 | compute_clocks(pio2, &second); | 259 | compute_clocks(pio2, &second); |
@@ -275,7 +280,7 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
275 | 280 | ||
276 | spin_lock_irqsave(&opti621_lock, flags); | 281 | spin_lock_irqsave(&opti621_lock, flags); |
277 | 282 | ||
278 | reg_base = hwif->io_ports[IDE_DATA_OFFSET]; | 283 | reg_base = hwif->io_ports[IDE_DATA_OFFSET]; |
279 | 284 | ||
280 | /* allow Register-B */ | 285 | /* allow Register-B */ |
281 | outb(0xc0, reg_base + CNTRL_REG); | 286 | outb(0xc0, reg_base + CNTRL_REG); |
@@ -324,7 +329,7 @@ static void __devinit opti621_port_init_devs(ide_hwif_t *hwif) | |||
324 | /* | 329 | /* |
325 | * init_hwif_opti621() is called once for each hwif found at boot. | 330 | * init_hwif_opti621() is called once for each hwif found at boot. |
326 | */ | 331 | */ |
327 | static void __devinit init_hwif_opti621 (ide_hwif_t *hwif) | 332 | static void __devinit init_hwif_opti621(ide_hwif_t *hwif) |
328 | { | 333 | { |
329 | hwif->port_init_devs = opti621_port_init_devs; | 334 | hwif->port_init_devs = opti621_port_init_devs; |
330 | hwif->set_pio_mode = &opti621_set_pio_mode; | 335 | hwif->set_pio_mode = &opti621_set_pio_mode; |
@@ -334,18 +339,16 @@ static const struct ide_port_info opti621_chipsets[] __devinitdata = { | |||
334 | { /* 0 */ | 339 | { /* 0 */ |
335 | .name = "OPTI621", | 340 | .name = "OPTI621", |
336 | .init_hwif = init_hwif_opti621, | 341 | .init_hwif = init_hwif_opti621, |
337 | .enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, | 342 | .enablebits = { {0x45, 0x80, 0x00}, {0x40, 0x08, 0x00} }, |
338 | .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | | 343 | .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, |
339 | IDE_HFLAG_BOOTABLE, | ||
340 | .pio_mask = ATA_PIO3, | 344 | .pio_mask = ATA_PIO3, |
341 | .swdma_mask = ATA_SWDMA2, | 345 | .swdma_mask = ATA_SWDMA2, |
342 | .mwdma_mask = ATA_MWDMA2, | 346 | .mwdma_mask = ATA_MWDMA2, |
343 | },{ /* 1 */ | 347 | }, { /* 1 */ |
344 | .name = "OPTI621X", | 348 | .name = "OPTI621X", |
345 | .init_hwif = init_hwif_opti621, | 349 | .init_hwif = init_hwif_opti621, |
346 | .enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, | 350 | .enablebits = { {0x45, 0x80, 0x00}, {0x40, 0x08, 0x00} }, |
347 | .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | | 351 | .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, |
348 | IDE_HFLAG_BOOTABLE, | ||
349 | .pio_mask = ATA_PIO3, | 352 | .pio_mask = ATA_PIO3, |
350 | .swdma_mask = ATA_SWDMA2, | 353 | .swdma_mask = ATA_SWDMA2, |
351 | .mwdma_mask = ATA_MWDMA2, | 354 | .mwdma_mask = ATA_MWDMA2, |
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index decef0f47674..89d74ffdb207 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c | |||
@@ -307,9 +307,9 @@ static void __devinit init_hwif_ich(ide_hwif_t *hwif) | |||
307 | } | 307 | } |
308 | 308 | ||
309 | #ifndef CONFIG_IA64 | 309 | #ifndef CONFIG_IA64 |
310 | #define IDE_HFLAGS_PIIX (IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE) | 310 | #define IDE_HFLAGS_PIIX IDE_HFLAG_LEGACY_IRQS |
311 | #else | 311 | #else |
312 | #define IDE_HFLAGS_PIIX IDE_HFLAG_BOOTABLE | 312 | #define IDE_HFLAGS_PIIX 0 |
313 | #endif | 313 | #endif |
314 | 314 | ||
315 | #define DECLARE_PIIX_DEV(name_str, udma) \ | 315 | #define DECLARE_PIIX_DEV(name_str, udma) \ |
diff --git a/drivers/ide/pci/rz1000.c b/drivers/ide/pci/rz1000.c index 51676612f78f..532154adba29 100644 --- a/drivers/ide/pci/rz1000.c +++ b/drivers/ide/pci/rz1000.c | |||
@@ -43,7 +43,7 @@ static const struct ide_port_info rz1000_chipset __devinitdata = { | |||
43 | .name = "RZ100x", | 43 | .name = "RZ100x", |
44 | .init_hwif = init_hwif_rz1000, | 44 | .init_hwif = init_hwif_rz1000, |
45 | .chipset = ide_rz1000, | 45 | .chipset = ide_rz1000, |
46 | .host_flags = IDE_HFLAG_NO_DMA | IDE_HFLAG_BOOTABLE, | 46 | .host_flags = IDE_HFLAG_NO_DMA, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_device_id *id) | 49 | static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_device_id *id) |
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index 561aa47c7720..44985c8f36e7 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c | |||
@@ -307,8 +307,7 @@ static const struct ide_port_info sc1200_chipset __devinitdata = { | |||
307 | .init_hwif = init_hwif_sc1200, | 307 | .init_hwif = init_hwif_sc1200, |
308 | .host_flags = IDE_HFLAG_SERIALIZE | | 308 | .host_flags = IDE_HFLAG_SERIALIZE | |
309 | IDE_HFLAG_POST_SET_MODE | | 309 | IDE_HFLAG_POST_SET_MODE | |
310 | IDE_HFLAG_ABUSE_DMA_MODES | | 310 | IDE_HFLAG_ABUSE_DMA_MODES, |
311 | IDE_HFLAG_BOOTABLE, | ||
312 | .pio_mask = ATA_PIO4, | 311 | .pio_mask = ATA_PIO4, |
313 | .mwdma_mask = ATA_MWDMA2, | 312 | .mwdma_mask = ATA_MWDMA2, |
314 | .udma_mask = ATA_UDMA2, | 313 | .udma_mask = ATA_UDMA2, |
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index ef07c7a8b97a..52145796f12f 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c | |||
@@ -65,7 +65,7 @@ | |||
65 | 65 | ||
66 | static struct scc_ports { | 66 | static struct scc_ports { |
67 | unsigned long ctl, dma; | 67 | unsigned long ctl, dma; |
68 | unsigned char hwif_id; /* for removing hwif from system */ | 68 | ide_hwif_t *hwif; /* for removing port from system */ |
69 | } scc_ports[MAX_HWIFS]; | 69 | } scc_ports[MAX_HWIFS]; |
70 | 70 | ||
71 | /* PIO transfer mode table */ | 71 | /* PIO transfer mode table */ |
@@ -534,12 +534,8 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev, | |||
534 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | 534 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
535 | int i; | 535 | int i; |
536 | 536 | ||
537 | for (i = 0; i < MAX_HWIFS; i++) { | 537 | hwif = ide_find_port(); |
538 | hwif = &ide_hwifs[i]; | 538 | if (hwif == NULL) { |
539 | if (hwif->chipset == ide_unknown) | ||
540 | break; /* pick an unused entry */ | ||
541 | } | ||
542 | if (i == MAX_HWIFS) { | ||
543 | printk(KERN_ERR "%s: too many IDE interfaces, " | 539 | printk(KERN_ERR "%s: too many IDE interfaces, " |
544 | "no room in table\n", SCC_PATA_NAME); | 540 | "no room in table\n", SCC_PATA_NAME); |
545 | return -ENOMEM; | 541 | return -ENOMEM; |
@@ -696,7 +692,7 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif) | |||
696 | { | 692 | { |
697 | struct scc_ports *ports = ide_get_hwifdata(hwif); | 693 | struct scc_ports *ports = ide_get_hwifdata(hwif); |
698 | 694 | ||
699 | ports->hwif_id = hwif->index; | 695 | ports->hwif = hwif; |
700 | 696 | ||
701 | hwif->dma_command = hwif->dma_base; | 697 | hwif->dma_command = hwif->dma_base; |
702 | hwif->dma_status = hwif->dma_base + 0x04; | 698 | hwif->dma_status = hwif->dma_base + 0x04; |
@@ -725,8 +721,7 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif) | |||
725 | .name = name_str, \ | 721 | .name = name_str, \ |
726 | .init_iops = init_iops_scc, \ | 722 | .init_iops = init_iops_scc, \ |
727 | .init_hwif = init_hwif_scc, \ | 723 | .init_hwif = init_hwif_scc, \ |
728 | .host_flags = IDE_HFLAG_SINGLE | \ | 724 | .host_flags = IDE_HFLAG_SINGLE, \ |
729 | IDE_HFLAG_BOOTABLE, \ | ||
730 | .pio_mask = ATA_PIO4, \ | 725 | .pio_mask = ATA_PIO4, \ |
731 | } | 726 | } |
732 | 727 | ||
@@ -758,7 +753,7 @@ static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_i | |||
758 | static void __devexit scc_remove(struct pci_dev *dev) | 753 | static void __devexit scc_remove(struct pci_dev *dev) |
759 | { | 754 | { |
760 | struct scc_ports *ports = pci_get_drvdata(dev); | 755 | struct scc_ports *ports = pci_get_drvdata(dev); |
761 | ide_hwif_t *hwif = &ide_hwifs[ports->hwif_id]; | 756 | ide_hwif_t *hwif = ports->hwif; |
762 | unsigned long ctl_base = pci_resource_start(dev, 0); | 757 | unsigned long ctl_base = pci_resource_start(dev, 0); |
763 | unsigned long dma_base = pci_resource_start(dev, 1); | 758 | unsigned long dma_base = pci_resource_start(dev, 1); |
764 | unsigned long ctl_size = pci_resource_len(dev, 0); | 759 | unsigned long ctl_size = pci_resource_len(dev, 0); |
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index c11880b0709f..cfe927469793 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c | |||
@@ -350,8 +350,7 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif) | |||
350 | 350 | ||
351 | #define IDE_HFLAGS_SVWKS \ | 351 | #define IDE_HFLAGS_SVWKS \ |
352 | (IDE_HFLAG_LEGACY_IRQS | \ | 352 | (IDE_HFLAG_LEGACY_IRQS | \ |
353 | IDE_HFLAG_ABUSE_SET_DMA_MODE | \ | 353 | IDE_HFLAG_ABUSE_SET_DMA_MODE) |
354 | IDE_HFLAG_BOOTABLE) | ||
355 | 354 | ||
356 | static const struct ide_port_info serverworks_chipsets[] __devinitdata = { | 355 | static const struct ide_port_info serverworks_chipsets[] __devinitdata = { |
357 | { /* 0 */ | 356 | { /* 0 */ |
@@ -418,7 +417,7 @@ static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device | |||
418 | else if (idx == 2 || idx == 3) { | 417 | else if (idx == 2 || idx == 3) { |
419 | if ((PCI_FUNC(dev->devfn) & 1) == 0) { | 418 | if ((PCI_FUNC(dev->devfn) & 1) == 0) { |
420 | if (pci_resource_start(dev, 0) != 0x01f1) | 419 | if (pci_resource_start(dev, 0) != 0x01f1) |
421 | d.host_flags &= ~IDE_HFLAG_BOOTABLE; | 420 | d.host_flags |= IDE_HFLAG_NON_BOOTABLE; |
422 | d.host_flags |= IDE_HFLAG_SINGLE; | 421 | d.host_flags |= IDE_HFLAG_SINGLE; |
423 | } else | 422 | } else |
424 | d.host_flags &= ~IDE_HFLAG_SINGLE; | 423 | d.host_flags &= ~IDE_HFLAG_SINGLE; |
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 9d1a3038af9b..6bd9523cf642 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c | |||
@@ -590,20 +590,12 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) | |||
590 | unsigned long bar0, cmd_phys_base, ctl; | 590 | unsigned long bar0, cmd_phys_base, ctl; |
591 | void __iomem *virt_base; | 591 | void __iomem *virt_base; |
592 | ide_hwif_t *hwif; | 592 | ide_hwif_t *hwif; |
593 | int h; | ||
594 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | 593 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
595 | hw_regs_t hw; | 594 | hw_regs_t hw; |
596 | struct ide_port_info d = sgiioc4_port_info; | 595 | struct ide_port_info d = sgiioc4_port_info; |
597 | 596 | ||
598 | /* | 597 | hwif = ide_find_port(); |
599 | * Find an empty HWIF; if none available, return -ENOMEM. | 598 | if (hwif == NULL) { |
600 | */ | ||
601 | for (h = 0; h < MAX_HWIFS; ++h) { | ||
602 | hwif = &ide_hwifs[h]; | ||
603 | if (hwif->chipset == ide_unknown) | ||
604 | break; | ||
605 | } | ||
606 | if (h == MAX_HWIFS) { | ||
607 | printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", | 599 | printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", |
608 | DRV_NAME); | 600 | DRV_NAME); |
609 | return -ENOMEM; | 601 | return -ENOMEM; |
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index b6be1b45f329..c9ecab8aeb61 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c | |||
@@ -808,7 +808,6 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) | |||
808 | .init_chipset = init_chipset_siimage, \ | 808 | .init_chipset = init_chipset_siimage, \ |
809 | .init_iops = init_iops_siimage, \ | 809 | .init_iops = init_iops_siimage, \ |
810 | .init_hwif = init_hwif_siimage, \ | 810 | .init_hwif = init_hwif_siimage, \ |
811 | .host_flags = IDE_HFLAG_BOOTABLE, \ | ||
812 | .pio_mask = ATA_PIO4, \ | 811 | .pio_mask = ATA_PIO4, \ |
813 | .mwdma_mask = ATA_MWDMA2, \ | 812 | .mwdma_mask = ATA_MWDMA2, \ |
814 | .udma_mask = ATA_UDMA6, \ | 813 | .udma_mask = ATA_UDMA6, \ |
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index 512bb4c1fd5c..181b647e5ca9 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c | |||
@@ -59,10 +59,10 @@ | |||
59 | #define ATA_16 0x01 | 59 | #define ATA_16 0x01 |
60 | #define ATA_33 0x02 | 60 | #define ATA_33 0x02 |
61 | #define ATA_66 0x03 | 61 | #define ATA_66 0x03 |
62 | #define ATA_100a 0x04 // SiS730/SiS550 is ATA100 with ATA66 layout | 62 | #define ATA_100a 0x04 /* SiS730/SiS550 is ATA100 with ATA66 layout */ |
63 | #define ATA_100 0x05 | 63 | #define ATA_100 0x05 |
64 | #define ATA_133a 0x06 // SiS961b with 133 support | 64 | #define ATA_133a 0x06 /* SiS961b with 133 support */ |
65 | #define ATA_133 0x07 // SiS962/963 | 65 | #define ATA_133 0x07 /* SiS962/963 */ |
66 | 66 | ||
67 | static u8 chipset_family; | 67 | static u8 chipset_family; |
68 | 68 | ||
@@ -111,69 +111,70 @@ static const struct { | |||
111 | Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */ | 111 | Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */ |
112 | 112 | ||
113 | /* {0, ATA_16, ATA_33, ATA_66, ATA_100a, ATA_100, ATA_133} */ | 113 | /* {0, ATA_16, ATA_33, ATA_66, ATA_100a, ATA_100, ATA_133} */ |
114 | static u8 cycle_time_offset[] = {0,0,5,4,4,0,0}; | 114 | static u8 cycle_time_offset[] = { 0, 0, 5, 4, 4, 0, 0 }; |
115 | static u8 cycle_time_range[] = {0,0,2,3,3,4,4}; | 115 | static u8 cycle_time_range[] = { 0, 0, 2, 3, 3, 4, 4 }; |
116 | static u8 cycle_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = { | 116 | static u8 cycle_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = { |
117 | {0,0,0,0,0,0,0}, /* no udma */ | 117 | { 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */ |
118 | {0,0,0,0,0,0,0}, /* no udma */ | 118 | { 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */ |
119 | {3,2,1,0,0,0,0}, /* ATA_33 */ | 119 | { 3, 2, 1, 0, 0, 0, 0 }, /* ATA_33 */ |
120 | {7,5,3,2,1,0,0}, /* ATA_66 */ | 120 | { 7, 5, 3, 2, 1, 0, 0 }, /* ATA_66 */ |
121 | {7,5,3,2,1,0,0}, /* ATA_100a (730 specific), differences are on cycle_time range and offset */ | 121 | { 7, 5, 3, 2, 1, 0, 0 }, /* ATA_100a (730 specific), |
122 | {11,7,5,4,2,1,0}, /* ATA_100 */ | 122 | different cycle_time range and offset */ |
123 | {15,10,7,5,3,2,1}, /* ATA_133a (earliest 691 southbridges) */ | 123 | { 11, 7, 5, 4, 2, 1, 0 }, /* ATA_100 */ |
124 | {15,10,7,5,3,2,1}, /* ATA_133 */ | 124 | { 15, 10, 7, 5, 3, 2, 1 }, /* ATA_133a (earliest 691 southbridges) */ |
125 | { 15, 10, 7, 5, 3, 2, 1 }, /* ATA_133 */ | ||
125 | }; | 126 | }; |
126 | /* CRC Valid Setup Time vary across IDE clock setting 33/66/100/133 | 127 | /* CRC Valid Setup Time vary across IDE clock setting 33/66/100/133 |
127 | See SiS962 data sheet for more detail */ | 128 | See SiS962 data sheet for more detail */ |
128 | static u8 cvs_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = { | 129 | static u8 cvs_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = { |
129 | {0,0,0,0,0,0,0}, /* no udma */ | 130 | { 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */ |
130 | {0,0,0,0,0,0,0}, /* no udma */ | 131 | { 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */ |
131 | {2,1,1,0,0,0,0}, | 132 | { 2, 1, 1, 0, 0, 0, 0 }, |
132 | {4,3,2,1,0,0,0}, | 133 | { 4, 3, 2, 1, 0, 0, 0 }, |
133 | {4,3,2,1,0,0,0}, | 134 | { 4, 3, 2, 1, 0, 0, 0 }, |
134 | {6,4,3,1,1,1,0}, | 135 | { 6, 4, 3, 1, 1, 1, 0 }, |
135 | {9,6,4,2,2,2,2}, | 136 | { 9, 6, 4, 2, 2, 2, 2 }, |
136 | {9,6,4,2,2,2,2}, | 137 | { 9, 6, 4, 2, 2, 2, 2 }, |
137 | }; | 138 | }; |
138 | /* Initialize time, Active time, Recovery time vary across | 139 | /* Initialize time, Active time, Recovery time vary across |
139 | IDE clock settings. These 3 arrays hold the register value | 140 | IDE clock settings. These 3 arrays hold the register value |
140 | for PIO0/1/2/3/4 and DMA0/1/2 mode in order */ | 141 | for PIO0/1/2/3/4 and DMA0/1/2 mode in order */ |
141 | static u8 ini_time_value[][8] = { | 142 | static u8 ini_time_value[][8] = { |
142 | {0,0,0,0,0,0,0,0}, | 143 | { 0, 0, 0, 0, 0, 0, 0, 0 }, |
143 | {0,0,0,0,0,0,0,0}, | 144 | { 0, 0, 0, 0, 0, 0, 0, 0 }, |
144 | {2,1,0,0,0,1,0,0}, | 145 | { 2, 1, 0, 0, 0, 1, 0, 0 }, |
145 | {4,3,1,1,1,3,1,1}, | 146 | { 4, 3, 1, 1, 1, 3, 1, 1 }, |
146 | {4,3,1,1,1,3,1,1}, | 147 | { 4, 3, 1, 1, 1, 3, 1, 1 }, |
147 | {6,4,2,2,2,4,2,2}, | 148 | { 6, 4, 2, 2, 2, 4, 2, 2 }, |
148 | {9,6,3,3,3,6,3,3}, | 149 | { 9, 6, 3, 3, 3, 6, 3, 3 }, |
149 | {9,6,3,3,3,6,3,3}, | 150 | { 9, 6, 3, 3, 3, 6, 3, 3 }, |
150 | }; | 151 | }; |
151 | static u8 act_time_value[][8] = { | 152 | static u8 act_time_value[][8] = { |
152 | {0,0,0,0,0,0,0,0}, | 153 | { 0, 0, 0, 0, 0, 0, 0, 0 }, |
153 | {0,0,0,0,0,0,0,0}, | 154 | { 0, 0, 0, 0, 0, 0, 0, 0 }, |
154 | {9,9,9,2,2,7,2,2}, | 155 | { 9, 9, 9, 2, 2, 7, 2, 2 }, |
155 | {19,19,19,5,4,14,5,4}, | 156 | { 19, 19, 19, 5, 4, 14, 5, 4 }, |
156 | {19,19,19,5,4,14,5,4}, | 157 | { 19, 19, 19, 5, 4, 14, 5, 4 }, |
157 | {28,28,28,7,6,21,7,6}, | 158 | { 28, 28, 28, 7, 6, 21, 7, 6 }, |
158 | {38,38,38,10,9,28,10,9}, | 159 | { 38, 38, 38, 10, 9, 28, 10, 9 }, |
159 | {38,38,38,10,9,28,10,9}, | 160 | { 38, 38, 38, 10, 9, 28, 10, 9 }, |
160 | }; | 161 | }; |
161 | static u8 rco_time_value[][8] = { | 162 | static u8 rco_time_value[][8] = { |
162 | {0,0,0,0,0,0,0,0}, | 163 | { 0, 0, 0, 0, 0, 0, 0, 0 }, |
163 | {0,0,0,0,0,0,0,0}, | 164 | { 0, 0, 0, 0, 0, 0, 0, 0 }, |
164 | {9,2,0,2,0,7,1,1}, | 165 | { 9, 2, 0, 2, 0, 7, 1, 1 }, |
165 | {19,5,1,5,2,16,3,2}, | 166 | { 19, 5, 1, 5, 2, 16, 3, 2 }, |
166 | {19,5,1,5,2,16,3,2}, | 167 | { 19, 5, 1, 5, 2, 16, 3, 2 }, |
167 | {30,9,3,9,4,25,6,4}, | 168 | { 30, 9, 3, 9, 4, 25, 6, 4 }, |
168 | {40,12,4,12,5,34,12,5}, | 169 | { 40, 12, 4, 12, 5, 34, 12, 5 }, |
169 | {40,12,4,12,5,34,12,5}, | 170 | { 40, 12, 4, 12, 5, 34, 12, 5 }, |
170 | }; | 171 | }; |
171 | 172 | ||
172 | /* | 173 | /* |
173 | * Printing configuration | 174 | * Printing configuration |
174 | */ | 175 | */ |
175 | /* Used for chipset type printing at boot time */ | 176 | /* Used for chipset type printing at boot time */ |
176 | static char* chipset_capability[] = { | 177 | static char *chipset_capability[] = { |
177 | "ATA", "ATA 16", | 178 | "ATA", "ATA 16", |
178 | "ATA 33", "ATA 66", | 179 | "ATA 33", "ATA 66", |
179 | "ATA 100 (1st gen)", "ATA 100 (2nd gen)", | 180 | "ATA 100 (1st gen)", "ATA 100 (2nd gen)", |
@@ -272,7 +273,7 @@ static void sis_program_timings(ide_drive_t *drive, const u8 mode) | |||
272 | sis_ata133_program_timings(drive, mode); | 273 | sis_ata133_program_timings(drive, mode); |
273 | } | 274 | } |
274 | 275 | ||
275 | static void config_drive_art_rwp (ide_drive_t *drive) | 276 | static void config_drive_art_rwp(ide_drive_t *drive) |
276 | { | 277 | { |
277 | ide_hwif_t *hwif = HWIF(drive); | 278 | ide_hwif_t *hwif = HWIF(drive); |
278 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 279 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
@@ -358,8 +359,7 @@ static u8 sis5513_ata133_udma_filter(ide_drive_t *drive) | |||
358 | return (regdw & 0x08) ? ATA_UDMA6 : ATA_UDMA5; | 359 | return (regdw & 0x08) ? ATA_UDMA6 : ATA_UDMA5; |
359 | } | 360 | } |
360 | 361 | ||
361 | /* Chip detection and general config */ | 362 | static int __devinit sis_find_family(struct pci_dev *dev) |
362 | static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const char *name) | ||
363 | { | 363 | { |
364 | struct pci_dev *host; | 364 | struct pci_dev *host; |
365 | int i = 0; | 365 | int i = 0; |
@@ -381,7 +381,7 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c | |||
381 | chipset_family = ATA_100a; | 381 | chipset_family = ATA_100a; |
382 | } | 382 | } |
383 | pci_dev_put(host); | 383 | pci_dev_put(host); |
384 | 384 | ||
385 | printk(KERN_INFO "SIS5513: %s %s controller\n", | 385 | printk(KERN_INFO "SIS5513: %s %s controller\n", |
386 | SiSHostChipInfo[i].name, chipset_capability[chipset_family]); | 386 | SiSHostChipInfo[i].name, chipset_capability[chipset_family]); |
387 | } | 387 | } |
@@ -440,63 +440,60 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c | |||
440 | } | 440 | } |
441 | } | 441 | } |
442 | 442 | ||
443 | if (!chipset_family) | 443 | return chipset_family; |
444 | return -1; | 444 | } |
445 | 445 | ||
446 | static unsigned int __devinit init_chipset_sis5513(struct pci_dev *dev, | ||
447 | const char *name) | ||
448 | { | ||
446 | /* Make general config ops here | 449 | /* Make general config ops here |
447 | 1/ tell IDE channels to operate in Compatibility mode only | 450 | 1/ tell IDE channels to operate in Compatibility mode only |
448 | 2/ tell old chips to allow per drive IDE timings */ | 451 | 2/ tell old chips to allow per drive IDE timings */ |
449 | 452 | ||
450 | { | 453 | u8 reg; |
451 | u8 reg; | 454 | u16 regw; |
452 | u16 regw; | 455 | |
453 | 456 | switch (chipset_family) { | |
454 | switch(chipset_family) { | 457 | case ATA_133: |
455 | case ATA_133: | 458 | /* SiS962 operation mode */ |
456 | /* SiS962 operation mode */ | 459 | pci_read_config_word(dev, 0x50, ®w); |
457 | pci_read_config_word(dev, 0x50, ®w); | 460 | if (regw & 0x08) |
458 | if (regw & 0x08) | 461 | pci_write_config_word(dev, 0x50, regw&0xfff7); |
459 | pci_write_config_word(dev, 0x50, regw&0xfff7); | 462 | pci_read_config_word(dev, 0x52, ®w); |
460 | pci_read_config_word(dev, 0x52, ®w); | 463 | if (regw & 0x08) |
461 | if (regw & 0x08) | 464 | pci_write_config_word(dev, 0x52, regw&0xfff7); |
462 | pci_write_config_word(dev, 0x52, regw&0xfff7); | 465 | break; |
463 | break; | 466 | case ATA_133a: |
464 | case ATA_133a: | 467 | case ATA_100: |
465 | case ATA_100: | 468 | /* Fixup latency */ |
466 | /* Fixup latency */ | 469 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80); |
467 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80); | 470 | /* Set compatibility bit */ |
468 | /* Set compatibility bit */ | 471 | pci_read_config_byte(dev, 0x49, ®); |
469 | pci_read_config_byte(dev, 0x49, ®); | 472 | if (!(reg & 0x01)) |
470 | if (!(reg & 0x01)) { | 473 | pci_write_config_byte(dev, 0x49, reg|0x01); |
471 | pci_write_config_byte(dev, 0x49, reg|0x01); | 474 | break; |
472 | } | 475 | case ATA_100a: |
473 | break; | 476 | case ATA_66: |
474 | case ATA_100a: | 477 | /* Fixup latency */ |
475 | case ATA_66: | 478 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10); |
476 | /* Fixup latency */ | 479 | |
477 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10); | 480 | /* On ATA_66 chips the bit was elsewhere */ |
478 | 481 | pci_read_config_byte(dev, 0x52, ®); | |
479 | /* On ATA_66 chips the bit was elsewhere */ | 482 | if (!(reg & 0x04)) |
480 | pci_read_config_byte(dev, 0x52, ®); | 483 | pci_write_config_byte(dev, 0x52, reg|0x04); |
481 | if (!(reg & 0x04)) { | 484 | break; |
482 | pci_write_config_byte(dev, 0x52, reg|0x04); | 485 | case ATA_33: |
483 | } | 486 | /* On ATA_33 we didn't have a single bit to set */ |
484 | break; | 487 | pci_read_config_byte(dev, 0x09, ®); |
485 | case ATA_33: | 488 | if ((reg & 0x0f) != 0x00) |
486 | /* On ATA_33 we didn't have a single bit to set */ | 489 | pci_write_config_byte(dev, 0x09, reg&0xf0); |
487 | pci_read_config_byte(dev, 0x09, ®); | 490 | case ATA_16: |
488 | if ((reg & 0x0f) != 0x00) { | 491 | /* force per drive recovery and active timings |
489 | pci_write_config_byte(dev, 0x09, reg&0xf0); | 492 | needed on ATA_33 and below chips */ |
490 | } | 493 | pci_read_config_byte(dev, 0x52, ®); |
491 | case ATA_16: | 494 | if (!(reg & 0x08)) |
492 | /* force per drive recovery and active timings | 495 | pci_write_config_byte(dev, 0x52, reg|0x08); |
493 | needed on ATA_33 and below chips */ | 496 | break; |
494 | pci_read_config_byte(dev, 0x52, ®); | ||
495 | if (!(reg & 0x08)) { | ||
496 | pci_write_config_byte(dev, 0x52, reg|0x08); | ||
497 | } | ||
498 | break; | ||
499 | } | ||
500 | } | 497 | } |
501 | 498 | ||
502 | return 0; | 499 | return 0; |
@@ -546,10 +543,8 @@ static u8 __devinit ata66_sis5513(ide_hwif_t *hwif) | |||
546 | return ata66 ? ATA_CBL_PATA80 : ATA_CBL_PATA40; | 543 | return ata66 ? ATA_CBL_PATA80 : ATA_CBL_PATA40; |
547 | } | 544 | } |
548 | 545 | ||
549 | static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif) | 546 | static void __devinit init_hwif_sis5513(ide_hwif_t *hwif) |
550 | { | 547 | { |
551 | u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f }; | ||
552 | |||
553 | hwif->set_pio_mode = &sis_set_pio_mode; | 548 | hwif->set_pio_mode = &sis_set_pio_mode; |
554 | hwif->set_dma_mode = &sis_set_dma_mode; | 549 | hwif->set_dma_mode = &sis_set_dma_mode; |
555 | 550 | ||
@@ -557,27 +552,29 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif) | |||
557 | hwif->udma_filter = sis5513_ata133_udma_filter; | 552 | hwif->udma_filter = sis5513_ata133_udma_filter; |
558 | 553 | ||
559 | hwif->cable_detect = ata66_sis5513; | 554 | hwif->cable_detect = ata66_sis5513; |
560 | |||
561 | if (hwif->dma_base == 0) | ||
562 | return; | ||
563 | |||
564 | hwif->ultra_mask = udma_rates[chipset_family]; | ||
565 | } | 555 | } |
566 | 556 | ||
567 | static const struct ide_port_info sis5513_chipset __devinitdata = { | 557 | static const struct ide_port_info sis5513_chipset __devinitdata = { |
568 | .name = "SIS5513", | 558 | .name = "SIS5513", |
569 | .init_chipset = init_chipset_sis5513, | 559 | .init_chipset = init_chipset_sis5513, |
570 | .init_hwif = init_hwif_sis5513, | 560 | .init_hwif = init_hwif_sis5513, |
571 | .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, | 561 | .enablebits = { {0x4a, 0x02, 0x02}, {0x4a, 0x04, 0x04} }, |
572 | .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_NO_AUTODMA | | 562 | .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_NO_AUTODMA, |
573 | IDE_HFLAG_BOOTABLE, | ||
574 | .pio_mask = ATA_PIO4, | 563 | .pio_mask = ATA_PIO4, |
575 | .mwdma_mask = ATA_MWDMA2, | 564 | .mwdma_mask = ATA_MWDMA2, |
576 | }; | 565 | }; |
577 | 566 | ||
578 | static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id) | 567 | static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id) |
579 | { | 568 | { |
580 | return ide_setup_pci_device(dev, &sis5513_chipset); | 569 | struct ide_port_info d = sis5513_chipset; |
570 | u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f }; | ||
571 | |||
572 | if (sis_find_family(dev) == 0) | ||
573 | return -ENOTSUPP; | ||
574 | |||
575 | d.udma_mask = udma_rates[chipset_family]; | ||
576 | |||
577 | return ide_setup_pci_device(dev, &d); | ||
581 | } | 578 | } |
582 | 579 | ||
583 | static const struct pci_device_id sis5513_pci_tbl[] = { | 580 | static const struct pci_device_id sis5513_pci_tbl[] = { |
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 1f00251a4a87..40b3eeb2d847 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c | |||
@@ -332,8 +332,7 @@ static const struct ide_port_info sl82c105_chipset __devinitdata = { | |||
332 | #if defined(CONFIG_LOPEC) || defined(CONFIG_SANDPOINT) | 332 | #if defined(CONFIG_LOPEC) || defined(CONFIG_SANDPOINT) |
333 | IDE_HFLAG_FORCE_LEGACY_IRQS | | 333 | IDE_HFLAG_FORCE_LEGACY_IRQS | |
334 | #endif | 334 | #endif |
335 | IDE_HFLAG_NO_AUTODMA | | 335 | IDE_HFLAG_NO_AUTODMA, |
336 | IDE_HFLAG_BOOTABLE, | ||
337 | .pio_mask = ATA_PIO5, | 336 | .pio_mask = ATA_PIO5, |
338 | }; | 337 | }; |
339 | 338 | ||
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c index 65f4c2ffaa59..eab557c45d1b 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/pci/slc90e66.c | |||
@@ -27,9 +27,9 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
27 | unsigned long flags; | 27 | unsigned long flags; |
28 | u16 master_data; | 28 | u16 master_data; |
29 | u8 slave_data; | 29 | u8 slave_data; |
30 | int control = 0; | 30 | int control = 0; |
31 | /* ISP RTC */ | 31 | /* ISP RTC */ |
32 | static const u8 timings[][2]= { | 32 | static const u8 timings[][2] = { |
33 | { 0, 0 }, | 33 | { 0, 0 }, |
34 | { 0, 0 }, | 34 | { 0, 0 }, |
35 | { 1, 0 }, | 35 | { 1, 0 }, |
@@ -136,8 +136,8 @@ static void __devinit init_hwif_slc90e66(ide_hwif_t *hwif) | |||
136 | static const struct ide_port_info slc90e66_chipset __devinitdata = { | 136 | static const struct ide_port_info slc90e66_chipset __devinitdata = { |
137 | .name = "SLC90E66", | 137 | .name = "SLC90E66", |
138 | .init_hwif = init_hwif_slc90e66, | 138 | .init_hwif = init_hwif_slc90e66, |
139 | .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, | 139 | .enablebits = { {0x41, 0x80, 0x80}, {0x43, 0x80, 0x80} }, |
140 | .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE, | 140 | .host_flags = IDE_HFLAG_LEGACY_IRQS, |
141 | .pio_mask = ATA_PIO4, | 141 | .pio_mask = ATA_PIO4, |
142 | .swdma_mask = ATA_SWDMA2_ONLY, | 142 | .swdma_mask = ATA_SWDMA2_ONLY, |
143 | .mwdma_mask = ATA_MWDMA12_ONLY, | 143 | .mwdma_mask = ATA_MWDMA12_ONLY, |
diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c index 1e4a6262bcef..c15435182e3c 100644 --- a/drivers/ide/pci/tc86c001.c +++ b/drivers/ide/pci/tc86c001.c | |||
@@ -18,20 +18,20 @@ static void tc86c001_set_mode(ide_drive_t *drive, const u8 speed) | |||
18 | u16 mode, scr = inw(scr_port); | 18 | u16 mode, scr = inw(scr_port); |
19 | 19 | ||
20 | switch (speed) { | 20 | switch (speed) { |
21 | case XFER_UDMA_4: mode = 0x00c0; break; | 21 | case XFER_UDMA_4: mode = 0x00c0; break; |
22 | case XFER_UDMA_3: mode = 0x00b0; break; | 22 | case XFER_UDMA_3: mode = 0x00b0; break; |
23 | case XFER_UDMA_2: mode = 0x00a0; break; | 23 | case XFER_UDMA_2: mode = 0x00a0; break; |
24 | case XFER_UDMA_1: mode = 0x0090; break; | 24 | case XFER_UDMA_1: mode = 0x0090; break; |
25 | case XFER_UDMA_0: mode = 0x0080; break; | 25 | case XFER_UDMA_0: mode = 0x0080; break; |
26 | case XFER_MW_DMA_2: mode = 0x0070; break; | 26 | case XFER_MW_DMA_2: mode = 0x0070; break; |
27 | case XFER_MW_DMA_1: mode = 0x0060; break; | 27 | case XFER_MW_DMA_1: mode = 0x0060; break; |
28 | case XFER_MW_DMA_0: mode = 0x0050; break; | 28 | case XFER_MW_DMA_0: mode = 0x0050; break; |
29 | case XFER_PIO_4: mode = 0x0400; break; | 29 | case XFER_PIO_4: mode = 0x0400; break; |
30 | case XFER_PIO_3: mode = 0x0300; break; | 30 | case XFER_PIO_3: mode = 0x0300; break; |
31 | case XFER_PIO_2: mode = 0x0200; break; | 31 | case XFER_PIO_2: mode = 0x0200; break; |
32 | case XFER_PIO_1: mode = 0x0100; break; | 32 | case XFER_PIO_1: mode = 0x0100; break; |
33 | case XFER_PIO_0: | 33 | case XFER_PIO_0: |
34 | default: mode = 0x0000; break; | 34 | default: mode = 0x0000; break; |
35 | } | 35 | } |
36 | 36 | ||
37 | scr &= (speed < XFER_MW_DMA_0) ? 0xf8ff : 0xff0f; | 37 | scr &= (speed < XFER_MW_DMA_0) ? 0xf8ff : 0xff0f; |
diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c index a67d02a3f96e..3316b197c779 100644 --- a/drivers/ide/pci/triflex.c +++ b/drivers/ide/pci/triflex.c | |||
@@ -97,7 +97,6 @@ static const struct ide_port_info triflex_device __devinitdata = { | |||
97 | .name = "TRIFLEX", | 97 | .name = "TRIFLEX", |
98 | .init_hwif = init_hwif_triflex, | 98 | .init_hwif = init_hwif_triflex, |
99 | .enablebits = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}}, | 99 | .enablebits = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}}, |
100 | .host_flags = IDE_HFLAG_BOOTABLE, | ||
101 | .pio_mask = ATA_PIO4, | 100 | .pio_mask = ATA_PIO4, |
102 | .swdma_mask = ATA_SWDMA2, | 101 | .swdma_mask = ATA_SWDMA2, |
103 | .mwdma_mask = ATA_MWDMA2, | 102 | .mwdma_mask = ATA_MWDMA2, |
diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c index de750f7a43e9..2b8f3a2837d7 100644 --- a/drivers/ide/pci/trm290.c +++ b/drivers/ide/pci/trm290.c | |||
@@ -337,7 +337,6 @@ static const struct ide_port_info trm290_chipset __devinitdata = { | |||
337 | IDE_HFLAG_TRUST_BIOS_FOR_DMA | | 337 | IDE_HFLAG_TRUST_BIOS_FOR_DMA | |
338 | #endif | 338 | #endif |
339 | IDE_HFLAG_NO_AUTODMA | | 339 | IDE_HFLAG_NO_AUTODMA | |
340 | IDE_HFLAG_BOOTABLE | | ||
341 | IDE_HFLAG_NO_LBA48, | 340 | IDE_HFLAG_NO_LBA48, |
342 | }; | 341 | }; |
343 | 342 | ||
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 9004e7521889..cff3cafedc47 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c | |||
@@ -429,11 +429,9 @@ static const struct ide_port_info via82cxxx_chipset __devinitdata = { | |||
429 | .init_hwif = init_hwif_via82cxxx, | 429 | .init_hwif = init_hwif_via82cxxx, |
430 | .enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } }, | 430 | .enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } }, |
431 | .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST | | 431 | .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST | |
432 | IDE_HFLAG_PIO_NO_DOWNGRADE | | ||
433 | IDE_HFLAG_ABUSE_SET_DMA_MODE | | 432 | IDE_HFLAG_ABUSE_SET_DMA_MODE | |
434 | IDE_HFLAG_POST_SET_MODE | | 433 | IDE_HFLAG_POST_SET_MODE | |
435 | IDE_HFLAG_IO_32BIT | | 434 | IDE_HFLAG_IO_32BIT, |
436 | IDE_HFLAG_BOOTABLE, | ||
437 | .pio_mask = ATA_PIO5, | 435 | .pio_mask = ATA_PIO5, |
438 | .swdma_mask = ATA_SWDMA2, | 436 | .swdma_mask = ATA_SWDMA2, |
439 | .mwdma_mask = ATA_MWDMA2, | 437 | .mwdma_mask = ATA_MWDMA2, |
diff --git a/drivers/ide/ppc/mpc8xx.c b/drivers/ide/ppc/mpc8xx.c index a784a97ca7ec..467656f06ccc 100644 --- a/drivers/ide/ppc/mpc8xx.c +++ b/drivers/ide/ppc/mpc8xx.c | |||
@@ -36,6 +36,8 @@ | |||
36 | #include <asm/machdep.h> | 36 | #include <asm/machdep.h> |
37 | #include <asm/irq.h> | 37 | #include <asm/irq.h> |
38 | 38 | ||
39 | #define DRV_NAME "ide-mpc8xx" | ||
40 | |||
39 | static int identify (volatile u8 *p); | 41 | static int identify (volatile u8 *p); |
40 | static void print_fixed (volatile u8 *p); | 42 | static void print_fixed (volatile u8 *p); |
41 | static void print_funcid (int func); | 43 | static void print_funcid (int func); |
@@ -127,7 +129,7 @@ static int pcmcia_schlvl = PCMCIA_SCHLVL; | |||
127 | * MPC8xx's internal PCMCIA interface | 129 | * MPC8xx's internal PCMCIA interface |
128 | */ | 130 | */ |
129 | #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT) | 131 | #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT) |
130 | static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) | 132 | static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) |
131 | { | 133 | { |
132 | unsigned long *p = hw->io_ports; | 134 | unsigned long *p = hw->io_ports; |
133 | int i; | 135 | int i; |
@@ -182,6 +184,13 @@ static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) | |||
182 | pcmcia_phy_base, pcmcia_phy_end, | 184 | pcmcia_phy_base, pcmcia_phy_end, |
183 | pcmcia_phy_end - pcmcia_phy_base); | 185 | pcmcia_phy_end - pcmcia_phy_base); |
184 | 186 | ||
187 | if (!request_mem_region(pcmcia_phy_base, | ||
188 | pcmcia_phy_end - pcmcia_phy_base, | ||
189 | DRV_NAME)) { | ||
190 | printk(KERN_ERR "%s: resources busy\n", DRV_NAME); | ||
191 | return -EBUSY; | ||
192 | } | ||
193 | |||
185 | pcmcia_base=(unsigned long)ioremap(pcmcia_phy_base, | 194 | pcmcia_base=(unsigned long)ioremap(pcmcia_phy_base, |
186 | pcmcia_phy_end-pcmcia_phy_base); | 195 | pcmcia_phy_end-pcmcia_phy_base); |
187 | 196 | ||
@@ -236,7 +245,7 @@ static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) | |||
236 | if (pcmp->pcmc_pipr & (M8XX_PCMCIA_CD1(_slot_)|M8XX_PCMCIA_CD2(_slot_))) { | 245 | if (pcmp->pcmc_pipr & (M8XX_PCMCIA_CD1(_slot_)|M8XX_PCMCIA_CD2(_slot_))) { |
237 | printk ("No card in slot %c: PIPR=%08x\n", | 246 | printk ("No card in slot %c: PIPR=%08x\n", |
238 | 'A' + _slot_, (u32) pcmp->pcmc_pipr); | 247 | 'A' + _slot_, (u32) pcmp->pcmc_pipr); |
239 | return; /* No card in slot */ | 248 | return -ENODEV; /* No card in slot */ |
240 | } | 249 | } |
241 | 250 | ||
242 | check_ide_device (pcmcia_base); | 251 | check_ide_device (pcmcia_base); |
@@ -279,9 +288,6 @@ static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) | |||
279 | } | 288 | } |
280 | #endif /* CONFIG_IDE_8xx_PCCARD */ | 289 | #endif /* CONFIG_IDE_8xx_PCCARD */ |
281 | 290 | ||
282 | ide_hwifs[data_port].pio_mask = ATA_PIO4; | ||
283 | ide_hwifs[data_port].set_pio_mode = m8xx_ide_set_pio_mode; | ||
284 | |||
285 | /* Enable Harddisk Interrupt, | 291 | /* Enable Harddisk Interrupt, |
286 | * and make it edge sensitive | 292 | * and make it edge sensitive |
287 | */ | 293 | */ |
@@ -296,6 +302,8 @@ static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) | |||
296 | /* Enable falling edge irq */ | 302 | /* Enable falling edge irq */ |
297 | pcmp->pcmc_per = 0x100000 >> (16 * _slot_); | 303 | pcmp->pcmc_per = 0x100000 >> (16 * _slot_); |
298 | #endif /* CONFIG_IDE_8xx_PCCARD */ | 304 | #endif /* CONFIG_IDE_8xx_PCCARD */ |
305 | |||
306 | return 0; | ||
299 | } | 307 | } |
300 | #endif /* CONFIG_IDE_8xx_PCCARD || CONFIG_IDE_8xx_DIRECT */ | 308 | #endif /* CONFIG_IDE_8xx_PCCARD || CONFIG_IDE_8xx_DIRECT */ |
301 | 309 | ||
@@ -304,7 +312,7 @@ static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) | |||
304 | * MPC8xx's internal PCMCIA interface | 312 | * MPC8xx's internal PCMCIA interface |
305 | */ | 313 | */ |
306 | #if defined(CONFIG_IDE_EXT_DIRECT) | 314 | #if defined(CONFIG_IDE_EXT_DIRECT) |
307 | static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) | 315 | static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) |
308 | { | 316 | { |
309 | unsigned long *p = hw->io_ports; | 317 | unsigned long *p = hw->io_ports; |
310 | int i; | 318 | int i; |
@@ -327,7 +335,12 @@ static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) | |||
327 | printk ("IDE phys mem : %08x...%08x (size %08x)\n", | 335 | printk ("IDE phys mem : %08x...%08x (size %08x)\n", |
328 | ide_phy_base, ide_phy_end, | 336 | ide_phy_base, ide_phy_end, |
329 | ide_phy_end - ide_phy_base); | 337 | ide_phy_end - ide_phy_base); |
330 | 338 | ||
339 | if (!request_mem_region(ide_phy_base, 0x200, DRV_NAME)) { | ||
340 | printk(KERN_ERR "%s: resources busy\n", DRV_NAME); | ||
341 | return -EBUSY; | ||
342 | } | ||
343 | |||
331 | ide_base=(unsigned long)ioremap(ide_phy_base, | 344 | ide_base=(unsigned long)ioremap(ide_phy_base, |
332 | ide_phy_end-ide_phy_base); | 345 | ide_phy_end-ide_phy_base); |
333 | 346 | ||
@@ -357,15 +370,14 @@ static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) | |||
357 | hw->irq = ioport_dsc[data_port].irq; | 370 | hw->irq = ioport_dsc[data_port].irq; |
358 | hw->ack_intr = (ide_ack_intr_t *)ide_interrupt_ack; | 371 | hw->ack_intr = (ide_ack_intr_t *)ide_interrupt_ack; |
359 | 372 | ||
360 | ide_hwifs[data_port].pio_mask = ATA_PIO4; | ||
361 | ide_hwifs[data_port].set_pio_mode = m8xx_ide_set_pio_mode; | ||
362 | |||
363 | /* Enable Harddisk Interrupt, | 373 | /* Enable Harddisk Interrupt, |
364 | * and make it edge sensitive | 374 | * and make it edge sensitive |
365 | */ | 375 | */ |
366 | /* (11-18) Set edge detect for irq, no wakeup from low power mode */ | 376 | /* (11-18) Set edge detect for irq, no wakeup from low power mode */ |
367 | ((immap_t *) IMAP_ADDR)->im_siu_conf.sc_siel |= | 377 | ((immap_t *) IMAP_ADDR)->im_siu_conf.sc_siel |= |
368 | (0x80000000 >> ioport_dsc[data_port].irq); | 378 | (0x80000000 >> ioport_dsc[data_port].irq); |
379 | |||
380 | return 0; | ||
369 | } | 381 | } |
370 | #endif /* CONFIG_IDE_8xx_DIRECT */ | 382 | #endif /* CONFIG_IDE_8xx_DIRECT */ |
371 | 383 | ||
@@ -794,14 +806,28 @@ static int __init mpc8xx_ide_probe(void) | |||
794 | 806 | ||
795 | #ifdef IDE0_BASE_OFFSET | 807 | #ifdef IDE0_BASE_OFFSET |
796 | memset(&hw, 0, sizeof(hw)); | 808 | memset(&hw, 0, sizeof(hw)); |
797 | m8xx_ide_init_ports(&hw, 0); | 809 | if (!m8xx_ide_init_ports(&hw, 0)) { |
798 | ide_init_port_hw(&ide_hwifs[0], &hw); | 810 | ide_hwif_t *hwif = &ide_hwifs[0]; |
799 | idx[0] = 0; | 811 | |
812 | ide_init_port_hw(hwif, &hw); | ||
813 | hwif->mmio = 1; | ||
814 | hwif->pio_mask = ATA_PIO4; | ||
815 | hwif->set_pio_mode = m8xx_ide_set_pio_mode; | ||
816 | |||
817 | idx[0] = 0; | ||
818 | } | ||
800 | #ifdef IDE1_BASE_OFFSET | 819 | #ifdef IDE1_BASE_OFFSET |
801 | memset(&hw, 0, sizeof(hw)); | 820 | memset(&hw, 0, sizeof(hw)); |
802 | m8xx_ide_init_ports(&hw, 1); | 821 | if (!m8xx_ide_init_ports(&hw, 1)) { |
803 | ide_init_port_hw(&ide_hwifs[1], &hw); | 822 | ide_hwif_t *mate = &ide_hwifs[1]; |
804 | idx[1] = 1; | 823 | |
824 | ide_init_port_hw(mate, &hw); | ||
825 | mate->mmio = 1; | ||
826 | mate->pio_mask = ATA_PIO4; | ||
827 | mate->set_pio_mode = m8xx_ide_set_pio_mode; | ||
828 | |||
829 | idx[1] = 1; | ||
830 | } | ||
805 | #endif | 831 | #endif |
806 | #endif | 832 | #endif |
807 | 833 | ||
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 88619b50d9ef..177961edc430 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c | |||
@@ -79,8 +79,6 @@ typedef struct pmac_ide_hwif { | |||
79 | 79 | ||
80 | } pmac_ide_hwif_t; | 80 | } pmac_ide_hwif_t; |
81 | 81 | ||
82 | static pmac_ide_hwif_t pmac_ide[MAX_HWIFS]; | ||
83 | |||
84 | enum { | 82 | enum { |
85 | controller_ohare, /* OHare based */ | 83 | controller_ohare, /* OHare based */ |
86 | controller_heathrow, /* Heathrow/Paddington */ | 84 | controller_heathrow, /* Heathrow/Paddington */ |
@@ -923,7 +921,6 @@ pmac_ide_do_resume(ide_hwif_t *hwif) | |||
923 | static const struct ide_port_info pmac_port_info = { | 921 | static const struct ide_port_info pmac_port_info = { |
924 | .chipset = ide_pmac, | 922 | .chipset = ide_pmac, |
925 | .host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA | | 923 | .host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA | |
926 | IDE_HFLAG_PIO_NO_DOWNGRADE | | ||
927 | IDE_HFLAG_POST_SET_MODE | | 924 | IDE_HFLAG_POST_SET_MODE | |
928 | IDE_HFLAG_NO_DMA | /* no SFF-style DMA */ | 925 | IDE_HFLAG_NO_DMA | /* no SFF-style DMA */ |
929 | IDE_HFLAG_UNMASK_IRQS, | 926 | IDE_HFLAG_UNMASK_IRQS, |
@@ -1088,35 +1085,36 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) | |||
1088 | { | 1085 | { |
1089 | void __iomem *base; | 1086 | void __iomem *base; |
1090 | unsigned long regbase; | 1087 | unsigned long regbase; |
1091 | int irq; | ||
1092 | ide_hwif_t *hwif; | 1088 | ide_hwif_t *hwif; |
1093 | pmac_ide_hwif_t *pmif; | 1089 | pmac_ide_hwif_t *pmif; |
1094 | int i, rc; | 1090 | int irq, rc; |
1095 | hw_regs_t hw; | 1091 | hw_regs_t hw; |
1096 | 1092 | ||
1097 | i = 0; | 1093 | pmif = kzalloc(sizeof(*pmif), GFP_KERNEL); |
1098 | while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0 | 1094 | if (pmif == NULL) |
1099 | || pmac_ide[i].node != NULL)) | 1095 | return -ENOMEM; |
1100 | ++i; | 1096 | |
1101 | if (i >= MAX_HWIFS) { | 1097 | hwif = ide_find_port(); |
1098 | if (hwif == NULL) { | ||
1102 | printk(KERN_ERR "ide-pmac: MacIO interface attach with no slot\n"); | 1099 | printk(KERN_ERR "ide-pmac: MacIO interface attach with no slot\n"); |
1103 | printk(KERN_ERR " %s\n", mdev->ofdev.node->full_name); | 1100 | printk(KERN_ERR " %s\n", mdev->ofdev.node->full_name); |
1104 | return -ENODEV; | 1101 | rc = -ENODEV; |
1102 | goto out_free_pmif; | ||
1105 | } | 1103 | } |
1106 | 1104 | ||
1107 | pmif = &pmac_ide[i]; | ||
1108 | hwif = &ide_hwifs[i]; | ||
1109 | |||
1110 | if (macio_resource_count(mdev) == 0) { | 1105 | if (macio_resource_count(mdev) == 0) { |
1111 | printk(KERN_WARNING "ide%d: no address for %s\n", | 1106 | printk(KERN_WARNING "ide-pmac: no address for %s\n", |
1112 | i, mdev->ofdev.node->full_name); | 1107 | mdev->ofdev.node->full_name); |
1113 | return -ENXIO; | 1108 | rc = -ENXIO; |
1109 | goto out_free_pmif; | ||
1114 | } | 1110 | } |
1115 | 1111 | ||
1116 | /* Request memory resource for IO ports */ | 1112 | /* Request memory resource for IO ports */ |
1117 | if (macio_request_resource(mdev, 0, "ide-pmac (ports)")) { | 1113 | if (macio_request_resource(mdev, 0, "ide-pmac (ports)")) { |
1118 | printk(KERN_ERR "ide%d: can't request mmio resource !\n", i); | 1114 | printk(KERN_ERR "ide-pmac: can't request MMIO resource for " |
1119 | return -EBUSY; | 1115 | "%s!\n", mdev->ofdev.node->full_name); |
1116 | rc = -EBUSY; | ||
1117 | goto out_free_pmif; | ||
1120 | } | 1118 | } |
1121 | 1119 | ||
1122 | /* XXX This is bogus. Should be fixed in the registry by checking | 1120 | /* XXX This is bogus. Should be fixed in the registry by checking |
@@ -1125,8 +1123,8 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) | |||
1125 | * where that happens though... | 1123 | * where that happens though... |
1126 | */ | 1124 | */ |
1127 | if (macio_irq_count(mdev) == 0) { | 1125 | if (macio_irq_count(mdev) == 0) { |
1128 | printk(KERN_WARNING "ide%d: no intrs for device %s, using 13\n", | 1126 | printk(KERN_WARNING "ide-pmac: no intrs for device %s, using " |
1129 | i, mdev->ofdev.node->full_name); | 1127 | "13\n", mdev->ofdev.node->full_name); |
1130 | irq = irq_create_mapping(NULL, 13); | 1128 | irq = irq_create_mapping(NULL, 13); |
1131 | } else | 1129 | } else |
1132 | irq = macio_irq(mdev, 0); | 1130 | irq = macio_irq(mdev, 0); |
@@ -1144,7 +1142,9 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) | |||
1144 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC | 1142 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC |
1145 | if (macio_resource_count(mdev) >= 2) { | 1143 | if (macio_resource_count(mdev) >= 2) { |
1146 | if (macio_request_resource(mdev, 1, "ide-pmac (dma)")) | 1144 | if (macio_request_resource(mdev, 1, "ide-pmac (dma)")) |
1147 | printk(KERN_WARNING "ide%d: can't request DMA resource !\n", i); | 1145 | printk(KERN_WARNING "ide-pmac: can't request DMA " |
1146 | "resource for %s!\n", | ||
1147 | mdev->ofdev.node->full_name); | ||
1148 | else | 1148 | else |
1149 | pmif->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x1000); | 1149 | pmif->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x1000); |
1150 | } else | 1150 | } else |
@@ -1166,11 +1166,15 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) | |||
1166 | iounmap(pmif->dma_regs); | 1166 | iounmap(pmif->dma_regs); |
1167 | macio_release_resource(mdev, 1); | 1167 | macio_release_resource(mdev, 1); |
1168 | } | 1168 | } |
1169 | memset(pmif, 0, sizeof(*pmif)); | ||
1170 | macio_release_resource(mdev, 0); | 1169 | macio_release_resource(mdev, 0); |
1170 | kfree(pmif); | ||
1171 | } | 1171 | } |
1172 | 1172 | ||
1173 | return rc; | 1173 | return rc; |
1174 | |||
1175 | out_free_pmif: | ||
1176 | kfree(pmif); | ||
1177 | return rc; | ||
1174 | } | 1178 | } |
1175 | 1179 | ||
1176 | static int | 1180 | static int |
@@ -1215,7 +1219,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1215 | pmac_ide_hwif_t *pmif; | 1219 | pmac_ide_hwif_t *pmif; |
1216 | void __iomem *base; | 1220 | void __iomem *base; |
1217 | unsigned long rbase, rlen; | 1221 | unsigned long rbase, rlen; |
1218 | int i, rc; | 1222 | int rc; |
1219 | hw_regs_t hw; | 1223 | hw_regs_t hw; |
1220 | 1224 | ||
1221 | np = pci_device_to_OF_node(pdev); | 1225 | np = pci_device_to_OF_node(pdev); |
@@ -1223,30 +1227,32 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1223 | printk(KERN_ERR "ide-pmac: cannot find MacIO node for Kauai ATA interface\n"); | 1227 | printk(KERN_ERR "ide-pmac: cannot find MacIO node for Kauai ATA interface\n"); |
1224 | return -ENODEV; | 1228 | return -ENODEV; |
1225 | } | 1229 | } |
1226 | i = 0; | 1230 | |
1227 | while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0 | 1231 | pmif = kzalloc(sizeof(*pmif), GFP_KERNEL); |
1228 | || pmac_ide[i].node != NULL)) | 1232 | if (pmif == NULL) |
1229 | ++i; | 1233 | return -ENOMEM; |
1230 | if (i >= MAX_HWIFS) { | 1234 | |
1235 | hwif = ide_find_port(); | ||
1236 | if (hwif == NULL) { | ||
1231 | printk(KERN_ERR "ide-pmac: PCI interface attach with no slot\n"); | 1237 | printk(KERN_ERR "ide-pmac: PCI interface attach with no slot\n"); |
1232 | printk(KERN_ERR " %s\n", np->full_name); | 1238 | printk(KERN_ERR " %s\n", np->full_name); |
1233 | return -ENODEV; | 1239 | rc = -ENODEV; |
1240 | goto out_free_pmif; | ||
1234 | } | 1241 | } |
1235 | 1242 | ||
1236 | pmif = &pmac_ide[i]; | ||
1237 | hwif = &ide_hwifs[i]; | ||
1238 | |||
1239 | if (pci_enable_device(pdev)) { | 1243 | if (pci_enable_device(pdev)) { |
1240 | printk(KERN_WARNING "ide%i: Can't enable PCI device for %s\n", | 1244 | printk(KERN_WARNING "ide-pmac: Can't enable PCI device for " |
1241 | i, np->full_name); | 1245 | "%s\n", np->full_name); |
1242 | return -ENXIO; | 1246 | rc = -ENXIO; |
1247 | goto out_free_pmif; | ||
1243 | } | 1248 | } |
1244 | pci_set_master(pdev); | 1249 | pci_set_master(pdev); |
1245 | 1250 | ||
1246 | if (pci_request_regions(pdev, "Kauai ATA")) { | 1251 | if (pci_request_regions(pdev, "Kauai ATA")) { |
1247 | printk(KERN_ERR "ide%d: Cannot obtain PCI resources for %s\n", | 1252 | printk(KERN_ERR "ide-pmac: Cannot obtain PCI resources for " |
1248 | i, np->full_name); | 1253 | "%s\n", np->full_name); |
1249 | return -ENXIO; | 1254 | rc = -ENXIO; |
1255 | goto out_free_pmif; | ||
1250 | } | 1256 | } |
1251 | 1257 | ||
1252 | hwif->dev = &pdev->dev; | 1258 | hwif->dev = &pdev->dev; |
@@ -1276,11 +1282,15 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1276 | /* The inteface is released to the common IDE layer */ | 1282 | /* The inteface is released to the common IDE layer */ |
1277 | pci_set_drvdata(pdev, NULL); | 1283 | pci_set_drvdata(pdev, NULL); |
1278 | iounmap(base); | 1284 | iounmap(base); |
1279 | memset(pmif, 0, sizeof(*pmif)); | ||
1280 | pci_release_regions(pdev); | 1285 | pci_release_regions(pdev); |
1286 | kfree(pmif); | ||
1281 | } | 1287 | } |
1282 | 1288 | ||
1283 | return rc; | 1289 | return rc; |
1290 | |||
1291 | out_free_pmif: | ||
1292 | kfree(pmif); | ||
1293 | return rc; | ||
1284 | } | 1294 | } |
1285 | 1295 | ||
1286 | static int | 1296 | static int |
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index f7ede0e42881..6302010fd8e2 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c | |||
@@ -20,73 +20,6 @@ | |||
20 | #include <asm/io.h> | 20 | #include <asm/io.h> |
21 | #include <asm/irq.h> | 21 | #include <asm/irq.h> |
22 | 22 | ||
23 | |||
24 | /** | ||
25 | * ide_match_hwif - match a PCI IDE against an ide_hwif | ||
26 | * @io_base: I/O base of device | ||
27 | * @bootable: set if its bootable | ||
28 | * @name: name of device | ||
29 | * | ||
30 | * Match a PCI IDE port against an entry in ide_hwifs[], | ||
31 | * based on io_base port if possible. Return the matching hwif, | ||
32 | * or a new hwif. If we find an error (clashing, out of devices, etc) | ||
33 | * return NULL | ||
34 | * | ||
35 | * FIXME: we need to handle mmio matches here too | ||
36 | */ | ||
37 | |||
38 | static ide_hwif_t *ide_match_hwif(unsigned long io_base, u8 bootable, const char *name) | ||
39 | { | ||
40 | int h; | ||
41 | ide_hwif_t *hwif; | ||
42 | |||
43 | /* | ||
44 | * Look for a hwif with matching io_base default value. | ||
45 | * If chipset is "ide_unknown", then claim that hwif slot. | ||
46 | * Otherwise, some other chipset has already claimed it.. :( | ||
47 | */ | ||
48 | for (h = 0; h < MAX_HWIFS; ++h) { | ||
49 | hwif = &ide_hwifs[h]; | ||
50 | if (hwif->io_ports[IDE_DATA_OFFSET] == io_base) { | ||
51 | if (hwif->chipset == ide_unknown) | ||
52 | return hwif; /* match */ | ||
53 | printk(KERN_ERR "%s: port 0x%04lx already claimed by %s\n", | ||
54 | name, io_base, hwif->name); | ||
55 | return NULL; /* already claimed */ | ||
56 | } | ||
57 | } | ||
58 | /* | ||
59 | * Okay, there is no hwif matching our io_base, | ||
60 | * so we'll just claim an unassigned slot. | ||
61 | * Give preference to claiming other slots before claiming ide0/ide1, | ||
62 | * just in case there's another interface yet-to-be-scanned | ||
63 | * which uses ports 1f0/170 (the ide0/ide1 defaults). | ||
64 | * | ||
65 | * Unless there is a bootable card that does not use the standard | ||
66 | * ports 1f0/170 (the ide0/ide1 defaults). The (bootable) flag. | ||
67 | */ | ||
68 | if (bootable) { | ||
69 | for (h = 0; h < MAX_HWIFS; ++h) { | ||
70 | hwif = &ide_hwifs[h]; | ||
71 | if (hwif->chipset == ide_unknown) | ||
72 | return hwif; /* pick an unused entry */ | ||
73 | } | ||
74 | } else { | ||
75 | for (h = 2; h < MAX_HWIFS; ++h) { | ||
76 | hwif = ide_hwifs + h; | ||
77 | if (hwif->chipset == ide_unknown) | ||
78 | return hwif; /* pick an unused entry */ | ||
79 | } | ||
80 | } | ||
81 | for (h = 0; h < 2 && h < MAX_HWIFS; ++h) { | ||
82 | hwif = ide_hwifs + h; | ||
83 | if (hwif->chipset == ide_unknown) | ||
84 | return hwif; /* pick an unused entry */ | ||
85 | } | ||
86 | printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", name); | ||
87 | return NULL; | ||
88 | } | ||
89 | |||
90 | /** | 23 | /** |
91 | * ide_setup_pci_baseregs - place a PCI IDE controller native | 24 | * ide_setup_pci_baseregs - place a PCI IDE controller native |
92 | * @dev: PCI device of interface to switch native | 25 | * @dev: PCI device of interface to switch native |
@@ -94,13 +27,13 @@ static ide_hwif_t *ide_match_hwif(unsigned long io_base, u8 bootable, const char | |||
94 | * | 27 | * |
95 | * We attempt to place the PCI interface into PCI native mode. If | 28 | * We attempt to place the PCI interface into PCI native mode. If |
96 | * we succeed the BARs are ok and the controller is in PCI mode. | 29 | * we succeed the BARs are ok and the controller is in PCI mode. |
97 | * Returns 0 on success or an errno code. | 30 | * Returns 0 on success or an errno code. |
98 | * | 31 | * |
99 | * FIXME: if we program the interface and then fail to set the BARS | 32 | * FIXME: if we program the interface and then fail to set the BARS |
100 | * we don't switch it back to legacy mode. Do we actually care ?? | 33 | * we don't switch it back to legacy mode. Do we actually care ?? |
101 | */ | 34 | */ |
102 | 35 | ||
103 | static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name) | 36 | static int ide_setup_pci_baseregs(struct pci_dev *dev, const char *name) |
104 | { | 37 | { |
105 | u8 progif = 0; | 38 | u8 progif = 0; |
106 | 39 | ||
@@ -207,7 +140,6 @@ void ide_setup_pci_noise(struct pci_dev *dev, const struct ide_port_info *d) | |||
207 | " PCI slot %s\n", d->name, dev->vendor, dev->device, | 140 | " PCI slot %s\n", d->name, dev->vendor, dev->device, |
208 | dev->revision, pci_name(dev)); | 141 | dev->revision, pci_name(dev)); |
209 | } | 142 | } |
210 | |||
211 | EXPORT_SYMBOL_GPL(ide_setup_pci_noise); | 143 | EXPORT_SYMBOL_GPL(ide_setup_pci_noise); |
212 | 144 | ||
213 | 145 | ||
@@ -220,7 +152,7 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise); | |||
220 | * but if that fails then we only need IO space. The PCI code should | 152 | * but if that fails then we only need IO space. The PCI code should |
221 | * have setup the proper resources for us already for controllers in | 153 | * have setup the proper resources for us already for controllers in |
222 | * legacy mode. | 154 | * legacy mode. |
223 | * | 155 | * |
224 | * Returns zero on success or an error code | 156 | * Returns zero on success or an error code |
225 | */ | 157 | */ |
226 | 158 | ||
@@ -279,8 +211,8 @@ static int ide_pci_configure(struct pci_dev *dev, const struct ide_port_info *d) | |||
279 | * Maybe the user deliberately *disabled* the device, | 211 | * Maybe the user deliberately *disabled* the device, |
280 | * but we'll eventually ignore it again if no drives respond. | 212 | * but we'll eventually ignore it again if no drives respond. |
281 | */ | 213 | */ |
282 | if (ide_setup_pci_baseregs(dev, d->name) || pci_write_config_word(dev, PCI_COMMAND, pcicmd|PCI_COMMAND_IO)) | 214 | if (ide_setup_pci_baseregs(dev, d->name) || |
283 | { | 215 | pci_write_config_word(dev, PCI_COMMAND, pcicmd | PCI_COMMAND_IO)) { |
284 | printk(KERN_INFO "%s: device disabled (BIOS)\n", d->name); | 216 | printk(KERN_INFO "%s: device disabled (BIOS)\n", d->name); |
285 | return -ENODEV; | 217 | return -ENODEV; |
286 | } | 218 | } |
@@ -301,26 +233,24 @@ static int ide_pci_configure(struct pci_dev *dev, const struct ide_port_info *d) | |||
301 | * @d: IDE port info | 233 | * @d: IDE port info |
302 | * @bar: BAR number | 234 | * @bar: BAR number |
303 | * | 235 | * |
304 | * Checks if a BAR is configured and points to MMIO space. If so | 236 | * Checks if a BAR is configured and points to MMIO space. If so, |
305 | * print an error and return an error code. Otherwise return 0 | 237 | * return an error code. Otherwise return 0 |
306 | */ | 238 | */ |
307 | 239 | ||
308 | static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *d, int bar) | 240 | static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *d, |
241 | int bar) | ||
309 | { | 242 | { |
310 | ulong flags = pci_resource_flags(dev, bar); | 243 | ulong flags = pci_resource_flags(dev, bar); |
311 | 244 | ||
312 | /* Unconfigured ? */ | 245 | /* Unconfigured ? */ |
313 | if (!flags || pci_resource_len(dev, bar) == 0) | 246 | if (!flags || pci_resource_len(dev, bar) == 0) |
314 | return 0; | 247 | return 0; |
315 | 248 | ||
316 | /* I/O space */ | 249 | /* I/O space */ |
317 | if(flags & PCI_BASE_ADDRESS_IO_MASK) | 250 | if (flags & IORESOURCE_IO) |
318 | return 0; | 251 | return 0; |
319 | 252 | ||
320 | /* Bad */ | 253 | /* Bad */ |
321 | printk(KERN_ERR "%s: IO baseregs (BIOS) are reported " | ||
322 | "as MEM, report to " | ||
323 | "<andre@linux-ide.org>.\n", d->name); | ||
324 | return -EINVAL; | 254 | return -EINVAL; |
325 | } | 255 | } |
326 | 256 | ||
@@ -344,14 +274,16 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, | |||
344 | { | 274 | { |
345 | unsigned long ctl = 0, base = 0; | 275 | unsigned long ctl = 0, base = 0; |
346 | ide_hwif_t *hwif; | 276 | ide_hwif_t *hwif; |
347 | u8 bootable = (d->host_flags & IDE_HFLAG_BOOTABLE) ? 1 : 0; | ||
348 | struct hw_regs_s hw; | 277 | struct hw_regs_s hw; |
349 | 278 | ||
350 | if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) { | 279 | if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) { |
351 | /* Possibly we should fail if these checks report true */ | 280 | if (ide_pci_check_iomem(dev, d, 2 * port) || |
352 | ide_pci_check_iomem(dev, d, 2*port); | 281 | ide_pci_check_iomem(dev, d, 2 * port + 1)) { |
353 | ide_pci_check_iomem(dev, d, 2*port+1); | 282 | printk(KERN_ERR "%s: I/O baseregs (BIOS) are reported " |
354 | 283 | "as MEM for port %d!\n", d->name, port); | |
284 | return NULL; | ||
285 | } | ||
286 | |||
355 | ctl = pci_resource_start(dev, 2*port+1); | 287 | ctl = pci_resource_start(dev, 2*port+1); |
356 | base = pci_resource_start(dev, 2*port); | 288 | base = pci_resource_start(dev, 2*port); |
357 | if ((ctl && !base) || (base && !ctl)) { | 289 | if ((ctl && !base) || (base && !ctl)) { |
@@ -360,14 +292,18 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, | |||
360 | return NULL; | 292 | return NULL; |
361 | } | 293 | } |
362 | } | 294 | } |
363 | if (!ctl) | 295 | if (!ctl) { |
364 | { | ||
365 | /* Use default values */ | 296 | /* Use default values */ |
366 | ctl = port ? 0x374 : 0x3f4; | 297 | ctl = port ? 0x374 : 0x3f4; |
367 | base = port ? 0x170 : 0x1f0; | 298 | base = port ? 0x170 : 0x1f0; |
368 | } | 299 | } |
369 | if ((hwif = ide_match_hwif(base, bootable, d->name)) == NULL) | 300 | |
370 | return NULL; /* no room in ide_hwifs[] */ | 301 | hwif = ide_find_port_slot(d); |
302 | if (hwif == NULL) { | ||
303 | printk(KERN_ERR "%s: too many IDE interfaces, no room in " | ||
304 | "table\n", d->name); | ||
305 | return NULL; | ||
306 | } | ||
371 | 307 | ||
372 | memset(&hw, 0, sizeof(hw)); | 308 | memset(&hw, 0, sizeof(hw)); |
373 | hw.irq = irq; | 309 | hw.irq = irq; |
@@ -407,9 +343,9 @@ void ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d) | |||
407 | unsigned long dma_base = ide_get_or_set_dma_base(d, hwif); | 343 | unsigned long dma_base = ide_get_or_set_dma_base(d, hwif); |
408 | if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) { | 344 | if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) { |
409 | /* | 345 | /* |
410 | * Set up BM-DMA capability | 346 | * Set up BM-DMA capability |
411 | * (PnP BIOS should have done this) | 347 | * (PnP BIOS should have done this) |
412 | */ | 348 | */ |
413 | pci_set_master(dev); | 349 | pci_set_master(dev); |
414 | if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd) || !(pcicmd & PCI_COMMAND_MASTER)) { | 350 | if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd) || !(pcicmd & PCI_COMMAND_MASTER)) { |
415 | printk(KERN_ERR "%s: %s error updating PCICMD\n", | 351 | printk(KERN_ERR "%s: %s error updating PCICMD\n", |
@@ -514,7 +450,6 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int | |||
514 | *(idx + port) = hwif->index; | 450 | *(idx + port) = hwif->index; |
515 | } | 451 | } |
516 | } | 452 | } |
517 | |||
518 | EXPORT_SYMBOL_GPL(ide_pci_setup_ports); | 453 | EXPORT_SYMBOL_GPL(ide_pci_setup_ports); |
519 | 454 | ||
520 | /* | 455 | /* |
@@ -597,7 +532,6 @@ int ide_setup_pci_device(struct pci_dev *dev, const struct ide_port_info *d) | |||
597 | 532 | ||
598 | return ret; | 533 | return ret; |
599 | } | 534 | } |
600 | |||
601 | EXPORT_SYMBOL_GPL(ide_setup_pci_device); | 535 | EXPORT_SYMBOL_GPL(ide_setup_pci_device); |
602 | 536 | ||
603 | int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2, | 537 | int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2, |
@@ -621,5 +555,4 @@ int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2, | |||
621 | out: | 555 | out: |
622 | return ret; | 556 | return ret; |
623 | } | 557 | } |
624 | |||
625 | EXPORT_SYMBOL_GPL(ide_setup_pci_devices); | 558 | EXPORT_SYMBOL_GPL(ide_setup_pci_devices); |
diff --git a/include/asm-x86/bios_ebda.h b/include/asm-x86/bios_ebda.h index 9cbd9a668af8..b4a46b7be794 100644 --- a/include/asm-x86/bios_ebda.h +++ b/include/asm-x86/bios_ebda.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef _MACH_BIOS_EBDA_H | 1 | #ifndef _MACH_BIOS_EBDA_H |
2 | #define _MACH_BIOS_EBDA_H | 2 | #define _MACH_BIOS_EBDA_H |
3 | 3 | ||
4 | #include <asm/io.h> | ||
5 | |||
4 | /* | 6 | /* |
5 | * there is a real-mode segmented pointer pointing to the | 7 | * there is a real-mode segmented pointer pointing to the |
6 | * 4K EBDA area at 0x40E. | 8 | * 4K EBDA area at 0x40E. |
diff --git a/include/asm-x86/io_apic.h b/include/asm-x86/io_apic.h index 0c9e17c73e05..d593e14f0341 100644 --- a/include/asm-x86/io_apic.h +++ b/include/asm-x86/io_apic.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef __ASM_IO_APIC_H | 1 | #ifndef __ASM_IO_APIC_H |
2 | #define __ASM_IO_APIC_H | 2 | #define __ASM_IO_APIC_H |
3 | 3 | ||
4 | #include <asm/types.h> | 4 | #include <linux/types.h> |
5 | #include <asm/mpspec.h> | 5 | #include <asm/mpspec.h> |
6 | #include <asm/apicdef.h> | 6 | #include <asm/apicdef.h> |
7 | 7 | ||
@@ -110,11 +110,13 @@ extern int nr_ioapic_registers[MAX_IO_APICS]; | |||
110 | * MP-BIOS irq configuration table structures: | 110 | * MP-BIOS irq configuration table structures: |
111 | */ | 111 | */ |
112 | 112 | ||
113 | #define MP_MAX_IOAPIC_PIN 127 | ||
114 | |||
113 | struct mp_ioapic_routing { | 115 | struct mp_ioapic_routing { |
114 | int apic_id; | 116 | int apic_id; |
115 | int gsi_base; | 117 | int gsi_base; |
116 | int gsi_end; | 118 | int gsi_end; |
117 | u32 pin_programmed[4]; | 119 | DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1); |
118 | }; | 120 | }; |
119 | 121 | ||
120 | /* I/O APIC entries */ | 122 | /* I/O APIC entries */ |
diff --git a/include/asm-x86/mach-default/smpboot_hooks.h b/include/asm-x86/mach-default/smpboot_hooks.h index 3ff2c5bff93a..56d0e1fa0258 100644 --- a/include/asm-x86/mach-default/smpboot_hooks.h +++ b/include/asm-x86/mach-default/smpboot_hooks.h | |||
@@ -33,7 +33,7 @@ static inline void smpboot_restore_warm_reset_vector(void) | |||
33 | *((volatile long *) phys_to_virt(0x467)) = 0; | 33 | *((volatile long *) phys_to_virt(0x467)) = 0; |
34 | } | 34 | } |
35 | 35 | ||
36 | static inline void smpboot_setup_io_apic(void) | 36 | static inline void __init smpboot_setup_io_apic(void) |
37 | { | 37 | { |
38 | /* | 38 | /* |
39 | * Here we can be sure that there is an IO-APIC in the system. Let's | 39 | * Here we can be sure that there is an IO-APIC in the system. Let's |
diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index 168b6447cf18..577ab79c4c27 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h | |||
@@ -198,16 +198,16 @@ do { \ | |||
198 | */ | 198 | */ |
199 | #define update_mmu_cache(vma, address, pte) do { } while (0) | 199 | #define update_mmu_cache(vma, address, pte) do { } while (0) |
200 | 200 | ||
201 | void native_pagetable_setup_start(pgd_t *base); | 201 | extern void native_pagetable_setup_start(pgd_t *base); |
202 | void native_pagetable_setup_done(pgd_t *base); | 202 | extern void native_pagetable_setup_done(pgd_t *base); |
203 | 203 | ||
204 | #ifndef CONFIG_PARAVIRT | 204 | #ifndef CONFIG_PARAVIRT |
205 | static inline void paravirt_pagetable_setup_start(pgd_t *base) | 205 | static inline void __init paravirt_pagetable_setup_start(pgd_t *base) |
206 | { | 206 | { |
207 | native_pagetable_setup_start(base); | 207 | native_pagetable_setup_start(base); |
208 | } | 208 | } |
209 | 209 | ||
210 | static inline void paravirt_pagetable_setup_done(pgd_t *base) | 210 | static inline void __init paravirt_pagetable_setup_done(pgd_t *base) |
211 | { | 211 | { |
212 | native_pagetable_setup_done(base); | 212 | native_pagetable_setup_done(base); |
213 | } | 213 | } |
diff --git a/include/asm-x86/posix_types.h b/include/asm-x86/posix_types.h index fe312a5ba204..bb7133dc155d 100644 --- a/include/asm-x86/posix_types.h +++ b/include/asm-x86/posix_types.h | |||
@@ -1,5 +1,11 @@ | |||
1 | #ifdef __KERNEL__ | 1 | #ifdef __KERNEL__ |
2 | # if defined(CONFIG_X86_32) || defined(__i386__) | 2 | # ifdef CONFIG_X86_32 |
3 | # include "posix_types_32.h" | ||
4 | # else | ||
5 | # include "posix_types_64.h" | ||
6 | # endif | ||
7 | #else | ||
8 | # ifdef __i386__ | ||
3 | # include "posix_types_32.h" | 9 | # include "posix_types_32.h" |
4 | # else | 10 | # else |
5 | # include "posix_types_64.h" | 11 | # include "posix_types_64.h" |
diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index e6bf92ddeb21..117343b0c271 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h | |||
@@ -118,7 +118,6 @@ struct cpuinfo_x86 { | |||
118 | #define X86_VENDOR_CYRIX 1 | 118 | #define X86_VENDOR_CYRIX 1 |
119 | #define X86_VENDOR_AMD 2 | 119 | #define X86_VENDOR_AMD 2 |
120 | #define X86_VENDOR_UMC 3 | 120 | #define X86_VENDOR_UMC 3 |
121 | #define X86_VENDOR_NEXGEN 4 | ||
122 | #define X86_VENDOR_CENTAUR 5 | 121 | #define X86_VENDOR_CENTAUR 5 |
123 | #define X86_VENDOR_TRANSMETA 7 | 122 | #define X86_VENDOR_TRANSMETA 7 |
124 | #define X86_VENDOR_NSC 8 | 123 | #define X86_VENDOR_NSC 8 |
diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index 24ec061566c5..9f922b0b95d6 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h | |||
@@ -231,6 +231,8 @@ extern int do_get_thread_area(struct task_struct *p, int idx, | |||
231 | extern int do_set_thread_area(struct task_struct *p, int idx, | 231 | extern int do_set_thread_area(struct task_struct *p, int idx, |
232 | struct user_desc __user *info, int can_allocate); | 232 | struct user_desc __user *info, int can_allocate); |
233 | 233 | ||
234 | #define __ARCH_WANT_COMPAT_SYS_PTRACE | ||
235 | |||
234 | #endif /* __KERNEL__ */ | 236 | #endif /* __KERNEL__ */ |
235 | 237 | ||
236 | #endif /* !__ASSEMBLY__ */ | 238 | #endif /* !__ASSEMBLY__ */ |
diff --git a/include/asm-x86/rio.h b/include/asm-x86/rio.h index 3451c576e6af..c9448bd8968f 100644 --- a/include/asm-x86/rio.h +++ b/include/asm-x86/rio.h | |||
@@ -60,15 +60,4 @@ enum { | |||
60 | ALT_CALGARY = 5, /* Second Planar Calgary */ | 60 | ALT_CALGARY = 5, /* Second Planar Calgary */ |
61 | }; | 61 | }; |
62 | 62 | ||
63 | /* | ||
64 | * there is a real-mode segmented pointer pointing to the | ||
65 | * 4K EBDA area at 0x40E. | ||
66 | */ | ||
67 | static inline unsigned long get_bios_ebda(void) | ||
68 | { | ||
69 | unsigned long address = *(unsigned short *)phys_to_virt(0x40EUL); | ||
70 | address <<= 4; | ||
71 | return address; | ||
72 | } | ||
73 | |||
74 | #endif /* __ASM_RIO_H */ | 63 | #endif /* __ASM_RIO_H */ |
diff --git a/include/asm-x86/unistd.h b/include/asm-x86/unistd.h index effc7ad8e12f..2a58ed3e51d8 100644 --- a/include/asm-x86/unistd.h +++ b/include/asm-x86/unistd.h | |||
@@ -1,5 +1,11 @@ | |||
1 | #ifdef __KERNEL__ | 1 | #ifdef __KERNEL__ |
2 | # if defined(CONFIG_X86_32) || defined(__i386__) | 2 | # ifdef CONFIG_X86_32 |
3 | # include "unistd_32.h" | ||
4 | # else | ||
5 | # include "unistd_64.h" | ||
6 | # endif | ||
7 | #else | ||
8 | # ifdef __i386__ | ||
3 | # include "unistd_32.h" | 9 | # include "unistd_32.h" |
4 | # else | 10 | # else |
5 | # include "unistd_64.h" | 11 | # include "unistd_64.h" |
diff --git a/include/linux/Kbuild b/include/linux/Kbuild index cbb5ccb27de3..bda6f04791d4 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild | |||
@@ -210,7 +210,6 @@ unifdef-y += hayesesp.h | |||
210 | unifdef-y += hdlcdrv.h | 210 | unifdef-y += hdlcdrv.h |
211 | unifdef-y += hdlc.h | 211 | unifdef-y += hdlc.h |
212 | unifdef-y += hdreg.h | 212 | unifdef-y += hdreg.h |
213 | unifdef-y += hdsmart.h | ||
214 | unifdef-y += hid.h | 213 | unifdef-y += hid.h |
215 | unifdef-y += hiddev.h | 214 | unifdef-y += hiddev.h |
216 | unifdef-y += hidraw.h | 215 | unifdef-y += hidraw.h |
diff --git a/include/linux/hdsmart.h b/include/linux/hdsmart.h deleted file mode 100644 index 4f4faf9d4238..000000000000 --- a/include/linux/hdsmart.h +++ /dev/null | |||
@@ -1,126 +0,0 @@ | |||
1 | /* | ||
2 | * linux/include/linux/hdsmart.h | ||
3 | * | ||
4 | * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org> | ||
5 | * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2, or (at your option) | ||
10 | * any later version. | ||
11 | * | ||
12 | * You should have received a copy of the GNU General Public License | ||
13 | * (for example /usr/src/linux/COPYING); if not, write to the Free | ||
14 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
15 | */ | ||
16 | |||
17 | #ifndef _LINUX_HDSMART_H | ||
18 | #define _LINUX_HDSMART_H | ||
19 | |||
20 | #ifndef __KERNEL__ | ||
21 | #define OFFLINE_FULL_SCAN 0 | ||
22 | #define SHORT_SELF_TEST 1 | ||
23 | #define EXTEND_SELF_TEST 2 | ||
24 | #define SHORT_CAPTIVE_SELF_TEST 129 | ||
25 | #define EXTEND_CAPTIVE_SELF_TEST 130 | ||
26 | |||
27 | /* smart_attribute is the vendor specific in SFF-8035 spec */ | ||
28 | typedef struct ata_smart_attribute_s { | ||
29 | unsigned char id; | ||
30 | unsigned short status_flag; | ||
31 | unsigned char normalized; | ||
32 | unsigned char worse_normal; | ||
33 | unsigned char raw[6]; | ||
34 | unsigned char reserv; | ||
35 | } __attribute__ ((packed)) ata_smart_attribute_t; | ||
36 | |||
37 | /* smart_values is format of the read drive Atrribute command */ | ||
38 | typedef struct ata_smart_values_s { | ||
39 | unsigned short revnumber; | ||
40 | ata_smart_attribute_t vendor_attributes [30]; | ||
41 | unsigned char offline_data_collection_status; | ||
42 | unsigned char self_test_exec_status; | ||
43 | unsigned short total_time_to_complete_off_line; | ||
44 | unsigned char vendor_specific_366; | ||
45 | unsigned char offline_data_collection_capability; | ||
46 | unsigned short smart_capability; | ||
47 | unsigned char errorlog_capability; | ||
48 | unsigned char vendor_specific_371; | ||
49 | unsigned char short_test_completion_time; | ||
50 | unsigned char extend_test_completion_time; | ||
51 | unsigned char reserved_374_385 [12]; | ||
52 | unsigned char vendor_specific_386_509 [125]; | ||
53 | unsigned char chksum; | ||
54 | } __attribute__ ((packed)) ata_smart_values_t; | ||
55 | |||
56 | /* Smart Threshold data structures */ | ||
57 | /* Vendor attribute of SMART Threshold */ | ||
58 | typedef struct ata_smart_threshold_entry_s { | ||
59 | unsigned char id; | ||
60 | unsigned char normalized_threshold; | ||
61 | unsigned char reserved[10]; | ||
62 | } __attribute__ ((packed)) ata_smart_threshold_entry_t; | ||
63 | |||
64 | /* Format of Read SMART THreshold Command */ | ||
65 | typedef struct ata_smart_thresholds_s { | ||
66 | unsigned short revnumber; | ||
67 | ata_smart_threshold_entry_t thres_entries[30]; | ||
68 | unsigned char reserved[149]; | ||
69 | unsigned char chksum; | ||
70 | } __attribute__ ((packed)) ata_smart_thresholds_t; | ||
71 | |||
72 | typedef struct ata_smart_errorlog_command_struct_s { | ||
73 | unsigned char devicecontrolreg; | ||
74 | unsigned char featuresreg; | ||
75 | unsigned char sector_count; | ||
76 | unsigned char sector_number; | ||
77 | unsigned char cylinder_low; | ||
78 | unsigned char cylinder_high; | ||
79 | unsigned char drive_head; | ||
80 | unsigned char commandreg; | ||
81 | unsigned int timestamp; | ||
82 | } __attribute__ ((packed)) ata_smart_errorlog_command_struct_t; | ||
83 | |||
84 | typedef struct ata_smart_errorlog_error_struct_s { | ||
85 | unsigned char error_condition; | ||
86 | unsigned char extended_error[14]; | ||
87 | unsigned char state; | ||
88 | unsigned short timestamp; | ||
89 | } __attribute__ ((packed)) ata_smart_errorlog_error_struct_t; | ||
90 | |||
91 | typedef struct ata_smart_errorlog_struct_s { | ||
92 | ata_smart_errorlog_command_struct_t commands[6]; | ||
93 | ata_smart_errorlog_error_struct_t error_struct; | ||
94 | } __attribute__ ((packed)) ata_smart_errorlog_struct_t; | ||
95 | |||
96 | typedef struct ata_smart_errorlog_s { | ||
97 | unsigned char revnumber; | ||
98 | unsigned char error_log_pointer; | ||
99 | ata_smart_errorlog_struct_t errorlog_struct[5]; | ||
100 | unsigned short ata_error_count; | ||
101 | unsigned short non_fatal_count; | ||
102 | unsigned short drive_timeout_count; | ||
103 | unsigned char reserved[53]; | ||
104 | unsigned char chksum; | ||
105 | } __attribute__ ((packed)) ata_smart_errorlog_t; | ||
106 | |||
107 | typedef struct ata_smart_selftestlog_struct_s { | ||
108 | unsigned char selftestnumber; | ||
109 | unsigned char selfteststatus; | ||
110 | unsigned short timestamp; | ||
111 | unsigned char selftestfailurecheckpoint; | ||
112 | unsigned int lbafirstfailure; | ||
113 | unsigned char vendorspecific[15]; | ||
114 | } __attribute__ ((packed)) ata_smart_selftestlog_struct_t; | ||
115 | |||
116 | typedef struct ata_smart_selftestlog_s { | ||
117 | unsigned short revnumber; | ||
118 | ata_smart_selftestlog_struct_t selftest_struct[21]; | ||
119 | unsigned char vendorspecific[2]; | ||
120 | unsigned char mostrecenttest; | ||
121 | unsigned char resevered[2]; | ||
122 | unsigned char chksum; | ||
123 | } __attribute__ ((packed)) ata_smart_selftestlog_t; | ||
124 | #endif /* __KERNEL__ */ | ||
125 | |||
126 | #endif /* _LINUX_HDSMART_H */ | ||
diff --git a/include/linux/ide.h b/include/linux/ide.h index 5f3e82ae901a..f20410dd4482 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -170,7 +170,6 @@ typedef struct hw_regs_s { | |||
170 | struct device *dev; | 170 | struct device *dev; |
171 | } hw_regs_t; | 171 | } hw_regs_t; |
172 | 172 | ||
173 | struct hwif_s * ide_find_port(unsigned long); | ||
174 | void ide_init_port_data(struct hwif_s *, unsigned int); | 173 | void ide_init_port_data(struct hwif_s *, unsigned int); |
175 | void ide_init_port_hw(struct hwif_s *, hw_regs_t *); | 174 | void ide_init_port_hw(struct hwif_s *, hw_regs_t *); |
176 | 175 | ||
@@ -522,7 +521,6 @@ typedef struct hwif_s { | |||
522 | unsigned reset : 1; /* reset after probe */ | 521 | unsigned reset : 1; /* reset after probe */ |
523 | unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */ | 522 | unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */ |
524 | unsigned mmio : 1; /* host uses MMIO */ | 523 | unsigned mmio : 1; /* host uses MMIO */ |
525 | unsigned straight8 : 1; /* Alan's straight 8 check */ | ||
526 | 524 | ||
527 | struct device gendev; | 525 | struct device gendev; |
528 | struct device *portdev; | 526 | struct device *portdev; |
@@ -809,6 +807,13 @@ extern ide_hwif_t ide_hwifs[]; /* master data repository */ | |||
809 | #endif | 807 | #endif |
810 | extern int noautodma; | 808 | extern int noautodma; |
811 | 809 | ||
810 | ide_hwif_t *ide_find_port_slot(const struct ide_port_info *); | ||
811 | |||
812 | static inline ide_hwif_t *ide_find_port(void) | ||
813 | { | ||
814 | return ide_find_port_slot(NULL); | ||
815 | } | ||
816 | |||
812 | extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs); | 817 | extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs); |
813 | int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq, | 818 | int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq, |
814 | int uptodate, int nr_sectors); | 819 | int uptodate, int nr_sectors); |
@@ -1027,8 +1032,8 @@ enum { | |||
1027 | IDE_HFLAG_SINGLE = (1 << 1), | 1032 | IDE_HFLAG_SINGLE = (1 << 1), |
1028 | /* don't use legacy PIO blacklist */ | 1033 | /* don't use legacy PIO blacklist */ |
1029 | IDE_HFLAG_PIO_NO_BLACKLIST = (1 << 2), | 1034 | IDE_HFLAG_PIO_NO_BLACKLIST = (1 << 2), |
1030 | /* don't use conservative PIO "downgrade" */ | 1035 | /* set for the second port of QD65xx */ |
1031 | IDE_HFLAG_PIO_NO_DOWNGRADE = (1 << 3), | 1036 | IDE_HFLAG_QD_2ND_PORT = (1 << 3), |
1032 | /* use PIO8/9 for prefetch off/on */ | 1037 | /* use PIO8/9 for prefetch off/on */ |
1033 | IDE_HFLAG_ABUSE_PREFETCH = (1 << 4), | 1038 | IDE_HFLAG_ABUSE_PREFETCH = (1 << 4), |
1034 | /* use PIO6/7 for fast-devsel off/on */ | 1039 | /* use PIO6/7 for fast-devsel off/on */ |
@@ -1050,8 +1055,8 @@ enum { | |||
1050 | IDE_HFLAG_VDMA = (1 << 11), | 1055 | IDE_HFLAG_VDMA = (1 << 11), |
1051 | /* ATAPI DMA is unsupported */ | 1056 | /* ATAPI DMA is unsupported */ |
1052 | IDE_HFLAG_NO_ATAPI_DMA = (1 << 12), | 1057 | IDE_HFLAG_NO_ATAPI_DMA = (1 << 12), |
1053 | /* set if host is a "bootable" controller */ | 1058 | /* set if host is a "non-bootable" controller */ |
1054 | IDE_HFLAG_BOOTABLE = (1 << 13), | 1059 | IDE_HFLAG_NON_BOOTABLE = (1 << 13), |
1055 | /* host doesn't support DMA */ | 1060 | /* host doesn't support DMA */ |
1056 | IDE_HFLAG_NO_DMA = (1 << 14), | 1061 | IDE_HFLAG_NO_DMA = (1 << 14), |
1057 | /* check if host is PCI IDE device before allowing DMA */ | 1062 | /* check if host is PCI IDE device before allowing DMA */ |
@@ -1079,8 +1084,6 @@ enum { | |||
1079 | /* unmask IRQs */ | 1084 | /* unmask IRQs */ |
1080 | IDE_HFLAG_UNMASK_IRQS = (1 << 25), | 1085 | IDE_HFLAG_UNMASK_IRQS = (1 << 25), |
1081 | IDE_HFLAG_ABUSE_SET_DMA_MODE = (1 << 26), | 1086 | IDE_HFLAG_ABUSE_SET_DMA_MODE = (1 << 26), |
1082 | /* host is CY82C693 */ | ||
1083 | IDE_HFLAG_CY82C693 = (1 << 27), | ||
1084 | /* force host out of "simplex" mode */ | 1087 | /* force host out of "simplex" mode */ |
1085 | IDE_HFLAG_CLEAR_SIMPLEX = (1 << 28), | 1088 | IDE_HFLAG_CLEAR_SIMPLEX = (1 << 28), |
1086 | /* DSC overlap is unsupported */ | 1089 | /* DSC overlap is unsupported */ |
@@ -1092,9 +1095,9 @@ enum { | |||
1092 | }; | 1095 | }; |
1093 | 1096 | ||
1094 | #ifdef CONFIG_BLK_DEV_OFFBOARD | 1097 | #ifdef CONFIG_BLK_DEV_OFFBOARD |
1095 | # define IDE_HFLAG_OFF_BOARD IDE_HFLAG_BOOTABLE | ||
1096 | #else | ||
1097 | # define IDE_HFLAG_OFF_BOARD 0 | 1098 | # define IDE_HFLAG_OFF_BOARD 0 |
1099 | #else | ||
1100 | # define IDE_HFLAG_OFF_BOARD IDE_HFLAG_NON_BOOTABLE | ||
1098 | #endif | 1101 | #endif |
1099 | 1102 | ||
1100 | struct ide_port_info { | 1103 | struct ide_port_info { |
diff --git a/kernel/fork.c b/kernel/fork.c index efb618fc8ffe..cb46befdd3a0 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1787,7 +1787,7 @@ bad_unshare_out: | |||
1787 | int unshare_files(struct files_struct **displaced) | 1787 | int unshare_files(struct files_struct **displaced) |
1788 | { | 1788 | { |
1789 | struct task_struct *task = current; | 1789 | struct task_struct *task = current; |
1790 | struct files_struct *copy; | 1790 | struct files_struct *copy = NULL; |
1791 | int error; | 1791 | int error; |
1792 | 1792 | ||
1793 | error = unshare_fd(CLONE_FILES, ©); | 1793 | error = unshare_fd(CLONE_FILES, ©); |