diff options
author | Steve French <sfrench@us.ibm.com> | 2008-03-11 15:15:41 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2008-03-11 15:15:41 -0400 |
commit | 5b4d4771e2a56671c7f1c94edda427a1e3d6f111 (patch) | |
tree | 58718288a28cca121a94b681a7865473a10dfd64 | |
parent | 55f78e1771f0886162edd441dd4f39c287779de2 (diff) | |
parent | baadac8b10c5ac15ce3d26b68fa266c8889b163f (diff) |
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
108 files changed, 3284 insertions, 976 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index 0f23d67f958f..bec5a32e4095 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c | |||
@@ -486,9 +486,12 @@ static void concat(char *dst, char *args[]) | |||
486 | unsigned int i, len = 0; | 486 | unsigned int i, len = 0; |
487 | 487 | ||
488 | for (i = 0; args[i]; i++) { | 488 | for (i = 0; args[i]; i++) { |
489 | if (i) { | ||
490 | strcat(dst+len, " "); | ||
491 | len++; | ||
492 | } | ||
489 | strcpy(dst+len, args[i]); | 493 | strcpy(dst+len, args[i]); |
490 | strcat(dst+len, " "); | 494 | len += strlen(args[i]); |
491 | len += strlen(args[i]) + 1; | ||
492 | } | 495 | } |
493 | /* In case it's empty. */ | 496 | /* In case it's empty. */ |
494 | dst[len] = '\0'; | 497 | dst[len] = '\0'; |
diff --git a/Documentation/pci.txt b/Documentation/pci.txt index bb7bd27d4682..d2c2e6e2b224 100644 --- a/Documentation/pci.txt +++ b/Documentation/pci.txt | |||
@@ -123,7 +123,7 @@ initialization with a pointer to a structure describing the driver | |||
123 | 123 | ||
124 | 124 | ||
125 | The ID table is an array of struct pci_device_id entries ending with an | 125 | The ID table is an array of struct pci_device_id entries ending with an |
126 | all-zero entry; use of the macro DECLARE_PCI_DEVICE_TABLE is the preferred | 126 | all-zero entry; use of the macro DEFINE_PCI_DEVICE_TABLE is the preferred |
127 | method of declaring the table. Each entry consists of: | 127 | method of declaring the table. Each entry consists of: |
128 | 128 | ||
129 | vendor,device Vendor and device ID to match (or PCI_ANY_ID) | 129 | vendor,device Vendor and device ID to match (or PCI_ANY_ID) |
@@ -193,7 +193,7 @@ Tips on when/where to use the above attributes: | |||
193 | o Do not mark the struct pci_driver. | 193 | o Do not mark the struct pci_driver. |
194 | 194 | ||
195 | o The ID table array should be marked __devinitconst; this is done | 195 | o The ID table array should be marked __devinitconst; this is done |
196 | automatically if the table is declared with DECLARE_PCI_DEVICE_TABLE(). | 196 | automatically if the table is declared with DEFINE_PCI_DEVICE_TABLE(). |
197 | 197 | ||
198 | o The probe() and remove() functions should be marked __devinit | 198 | o The probe() and remove() functions should be marked __devinit |
199 | and __devexit respectively. All initialization functions | 199 | and __devexit respectively. All initialization functions |
diff --git a/Documentation/scheduler/sched-stats.txt b/Documentation/scheduler/sched-stats.txt index 442e14d35dea..01e69404ee5e 100644 --- a/Documentation/scheduler/sched-stats.txt +++ b/Documentation/scheduler/sched-stats.txt | |||
@@ -142,7 +142,7 @@ of idleness (idle, busy, and newly idle): | |||
142 | 142 | ||
143 | /proc/<pid>/schedstat | 143 | /proc/<pid>/schedstat |
144 | ---------------- | 144 | ---------------- |
145 | schedstats also adds a new /proc/<pid/schedstat file to include some of | 145 | schedstats also adds a new /proc/<pid>/schedstat file to include some of |
146 | the same information on a per-process level. There are three fields in | 146 | the same information on a per-process level. There are three fields in |
147 | this file correlating for that process to: | 147 | this file correlating for that process to: |
148 | 1) time spent on the cpu | 148 | 1) time spent on the cpu |
diff --git a/Documentation/usb/usb-help.txt b/Documentation/usb/usb-help.txt index a7408593829f..4273ca2b86ba 100644 --- a/Documentation/usb/usb-help.txt +++ b/Documentation/usb/usb-help.txt | |||
@@ -1,5 +1,5 @@ | |||
1 | usb-help.txt | 1 | usb-help.txt |
2 | 2000-July-12 | 2 | 2008-Mar-7 |
3 | 3 | ||
4 | For USB help other than the readme files that are located in | 4 | For USB help other than the readme files that are located in |
5 | Documentation/usb/*, see the following: | 5 | Documentation/usb/*, see the following: |
@@ -10,9 +10,7 @@ Linux-USB project: http://www.linux-usb.org | |||
10 | Linux USB Guide: http://linux-usb.sourceforge.net | 10 | Linux USB Guide: http://linux-usb.sourceforge.net |
11 | Linux-USB device overview (working devices and drivers): | 11 | Linux-USB device overview (working devices and drivers): |
12 | http://www.qbik.ch/usb/devices/ | 12 | http://www.qbik.ch/usb/devices/ |
13 | 13 | ||
14 | The Linux-USB mailing lists are: | 14 | The Linux-USB mailing list is at linux-usb@vger.kernel.org |
15 | linux-usb-users@lists.sourceforge.net for general user help | ||
16 | linux-usb-devel@lists.sourceforge.net for developer discussions | ||
17 | 15 | ||
18 | ### | 16 | ### |
diff --git a/MAINTAINERS b/MAINTAINERS index 558636e3a954..25f450fe1059 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2156,7 +2156,7 @@ L: netdev@vger.kernel.org | |||
2156 | S: Maintained | 2156 | S: Maintained |
2157 | 2157 | ||
2158 | IPATH DRIVER: | 2158 | IPATH DRIVER: |
2159 | P: Arthur Jones | 2159 | P: Ralph Campbell |
2160 | M: infinipath@qlogic.com | 2160 | M: infinipath@qlogic.com |
2161 | L: general@lists.openfabrics.org | 2161 | L: general@lists.openfabrics.org |
2162 | T: git git://git.qlogic.com/ipath-linux-2.6 | 2162 | T: git git://git.qlogic.com/ipath-linux-2.6 |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 2 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 25 | 3 | SUBLEVEL = 25 |
4 | EXTRAVERSION = -rc4 | 4 | EXTRAVERSION = -rc5 |
5 | NAME = Funky Weasel is Jiggy wit it | 5 | NAME = Funky Weasel is Jiggy wit it |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index be6fa105cd34..e07a23fc5b74 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c | |||
@@ -144,15 +144,14 @@ iommu_arena_find_pages(struct device *dev, struct pci_iommu_arena *arena, | |||
144 | unsigned long base; | 144 | unsigned long base; |
145 | unsigned long boundary_size; | 145 | unsigned long boundary_size; |
146 | 146 | ||
147 | BUG_ON(arena->dma_base & ~PAGE_MASK); | ||
148 | base = arena->dma_base >> PAGE_SHIFT; | 147 | base = arena->dma_base >> PAGE_SHIFT; |
149 | if (dev) | 148 | if (dev) { |
150 | boundary_size = ALIGN(dma_get_max_seg_size(dev) + 1, PAGE_SIZE) | 149 | boundary_size = dma_get_seg_boundary(dev) + 1; |
151 | >> PAGE_SHIFT; | 150 | BUG_ON(!is_power_of_2(boundary_size)); |
152 | else | 151 | boundary_size >>= PAGE_SHIFT; |
153 | boundary_size = ALIGN(1UL << 32, PAGE_SIZE) >> PAGE_SHIFT; | 152 | } else { |
154 | 153 | boundary_size = 1UL << (32 - PAGE_SHIFT); | |
155 | BUG_ON(!is_power_of_2(boundary_size)); | 154 | } |
156 | 155 | ||
157 | /* Search forward for the first mask-aligned sequence of N free ptes */ | 156 | /* Search forward for the first mask-aligned sequence of N free ptes */ |
158 | ptes = arena->ptes; | 157 | ptes = arena->ptes; |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index f41c9538ca30..237fc128143d 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -66,9 +66,6 @@ config MMU | |||
66 | config ZONE_DMA | 66 | config ZONE_DMA |
67 | def_bool y | 67 | def_bool y |
68 | 68 | ||
69 | config QUICKLIST | ||
70 | def_bool X86_32 | ||
71 | |||
72 | config SBUS | 69 | config SBUS |
73 | bool | 70 | bool |
74 | 71 | ||
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 8f64abe699fd..d5904eef1d31 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
@@ -1055,10 +1055,17 @@ static int putreg32(struct task_struct *child, unsigned regno, u32 value) | |||
1055 | R32(esi, si); | 1055 | R32(esi, si); |
1056 | R32(ebp, bp); | 1056 | R32(ebp, bp); |
1057 | R32(eax, ax); | 1057 | R32(eax, ax); |
1058 | R32(orig_eax, orig_ax); | ||
1059 | R32(eip, ip); | 1058 | R32(eip, ip); |
1060 | R32(esp, sp); | 1059 | R32(esp, sp); |
1061 | 1060 | ||
1061 | case offsetof(struct user32, regs.orig_eax): | ||
1062 | /* | ||
1063 | * Sign-extend the value so that orig_eax = -1 | ||
1064 | * causes (long)orig_ax < 0 tests to fire correctly. | ||
1065 | */ | ||
1066 | regs->orig_ax = (long) (s32) value; | ||
1067 | break; | ||
1068 | |||
1062 | case offsetof(struct user32, regs.eflags): | 1069 | case offsetof(struct user32, regs.eflags): |
1063 | return set_flags(child, value); | 1070 | return set_flags(child, value); |
1064 | 1071 | ||
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c index 56b72fb67f9b..1c83e5124c65 100644 --- a/arch/x86/kernel/signal_64.c +++ b/arch/x86/kernel/signal_64.c | |||
@@ -311,6 +311,35 @@ give_sigsegv: | |||
311 | } | 311 | } |
312 | 312 | ||
313 | /* | 313 | /* |
314 | * Return -1L or the syscall number that @regs is executing. | ||
315 | */ | ||
316 | static long current_syscall(struct pt_regs *regs) | ||
317 | { | ||
318 | /* | ||
319 | * We always sign-extend a -1 value being set here, | ||
320 | * so this is always either -1L or a syscall number. | ||
321 | */ | ||
322 | return regs->orig_ax; | ||
323 | } | ||
324 | |||
325 | /* | ||
326 | * Return a value that is -EFOO if the system call in @regs->orig_ax | ||
327 | * returned an error. This only works for @regs from @current. | ||
328 | */ | ||
329 | static long current_syscall_ret(struct pt_regs *regs) | ||
330 | { | ||
331 | #ifdef CONFIG_IA32_EMULATION | ||
332 | if (test_thread_flag(TIF_IA32)) | ||
333 | /* | ||
334 | * Sign-extend the value so (int)-EFOO becomes (long)-EFOO | ||
335 | * and will match correctly in comparisons. | ||
336 | */ | ||
337 | return (int) regs->ax; | ||
338 | #endif | ||
339 | return regs->ax; | ||
340 | } | ||
341 | |||
342 | /* | ||
314 | * OK, we're invoking a handler | 343 | * OK, we're invoking a handler |
315 | */ | 344 | */ |
316 | 345 | ||
@@ -327,9 +356,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
327 | #endif | 356 | #endif |
328 | 357 | ||
329 | /* Are we from a system call? */ | 358 | /* Are we from a system call? */ |
330 | if ((long)regs->orig_ax >= 0) { | 359 | if (current_syscall(regs) >= 0) { |
331 | /* If so, check system call restarting.. */ | 360 | /* If so, check system call restarting.. */ |
332 | switch (regs->ax) { | 361 | switch (current_syscall_ret(regs)) { |
333 | case -ERESTART_RESTARTBLOCK: | 362 | case -ERESTART_RESTARTBLOCK: |
334 | case -ERESTARTNOHAND: | 363 | case -ERESTARTNOHAND: |
335 | regs->ax = -EINTR; | 364 | regs->ax = -EINTR; |
@@ -426,10 +455,9 @@ static void do_signal(struct pt_regs *regs) | |||
426 | } | 455 | } |
427 | 456 | ||
428 | /* Did we come from a system call? */ | 457 | /* Did we come from a system call? */ |
429 | if ((long)regs->orig_ax >= 0) { | 458 | if (current_syscall(regs) >= 0) { |
430 | /* Restart the system call - no handlers present */ | 459 | /* Restart the system call - no handlers present */ |
431 | long res = regs->ax; | 460 | switch (current_syscall_ret(regs)) { |
432 | switch (res) { | ||
433 | case -ERESTARTNOHAND: | 461 | case -ERESTARTNOHAND: |
434 | case -ERESTARTSYS: | 462 | case -ERESTARTSYS: |
435 | case -ERESTARTNOINTR: | 463 | case -ERESTARTNOINTR: |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index cccb38a59653..a104c532ff70 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -84,7 +84,6 @@ struct lguest_data lguest_data = { | |||
84 | .blocked_interrupts = { 1 }, /* Block timer interrupts */ | 84 | .blocked_interrupts = { 1 }, /* Block timer interrupts */ |
85 | .syscall_vec = SYSCALL_VECTOR, | 85 | .syscall_vec = SYSCALL_VECTOR, |
86 | }; | 86 | }; |
87 | static cycle_t clock_base; | ||
88 | 87 | ||
89 | /*G:037 async_hcall() is pretty simple: I'm quite proud of it really. We have a | 88 | /*G:037 async_hcall() is pretty simple: I'm quite proud of it really. We have a |
90 | * ring buffer of stored hypercalls which the Host will run though next time we | 89 | * ring buffer of stored hypercalls which the Host will run though next time we |
@@ -327,8 +326,8 @@ static void lguest_cpuid(unsigned int *ax, unsigned int *bx, | |||
327 | case 1: /* Basic feature request. */ | 326 | case 1: /* Basic feature request. */ |
328 | /* We only allow kernel to see SSE3, CMPXCHG16B and SSSE3 */ | 327 | /* We only allow kernel to see SSE3, CMPXCHG16B and SSSE3 */ |
329 | *cx &= 0x00002201; | 328 | *cx &= 0x00002201; |
330 | /* SSE, SSE2, FXSR, MMX, CMOV, CMPXCHG8B, FPU. */ | 329 | /* SSE, SSE2, FXSR, MMX, CMOV, CMPXCHG8B, TSC, FPU. */ |
331 | *dx &= 0x07808101; | 330 | *dx &= 0x07808111; |
332 | /* The Host can do a nice optimization if it knows that the | 331 | /* The Host can do a nice optimization if it knows that the |
333 | * kernel mappings (addresses above 0xC0000000 or whatever | 332 | * kernel mappings (addresses above 0xC0000000 or whatever |
334 | * PAGE_OFFSET is set to) haven't changed. But Linux calls | 333 | * PAGE_OFFSET is set to) haven't changed. But Linux calls |
@@ -481,7 +480,7 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval) | |||
481 | { | 480 | { |
482 | *pmdp = pmdval; | 481 | *pmdp = pmdval; |
483 | lazy_hcall(LHCALL_SET_PMD, __pa(pmdp)&PAGE_MASK, | 482 | lazy_hcall(LHCALL_SET_PMD, __pa(pmdp)&PAGE_MASK, |
484 | (__pa(pmdp)&(PAGE_SIZE-1)), 0); | 483 | (__pa(pmdp)&(PAGE_SIZE-1))/4, 0); |
485 | } | 484 | } |
486 | 485 | ||
487 | /* There are a couple of legacy places where the kernel sets a PTE, but we | 486 | /* There are a couple of legacy places where the kernel sets a PTE, but we |
@@ -595,19 +594,25 @@ static unsigned long lguest_get_wallclock(void) | |||
595 | return lguest_data.time.tv_sec; | 594 | return lguest_data.time.tv_sec; |
596 | } | 595 | } |
597 | 596 | ||
597 | /* The TSC is a Time Stamp Counter. The Host tells us what speed it runs at, | ||
598 | * or 0 if it's unusable as a reliable clock source. This matches what we want | ||
599 | * here: if we return 0 from this function, the x86 TSC clock will not register | ||
600 | * itself. */ | ||
601 | static unsigned long lguest_cpu_khz(void) | ||
602 | { | ||
603 | return lguest_data.tsc_khz; | ||
604 | } | ||
605 | |||
606 | /* If we can't use the TSC, the kernel falls back to our "lguest_clock", where | ||
607 | * we read the time value given to us by the Host. */ | ||
598 | static cycle_t lguest_clock_read(void) | 608 | static cycle_t lguest_clock_read(void) |
599 | { | 609 | { |
600 | unsigned long sec, nsec; | 610 | unsigned long sec, nsec; |
601 | 611 | ||
602 | /* If the Host tells the TSC speed, we can trust that. */ | 612 | /* Since the time is in two parts (seconds and nanoseconds), we risk |
603 | if (lguest_data.tsc_khz) | 613 | * reading it just as it's changing from 99 & 0.999999999 to 100 and 0, |
604 | return native_read_tsc(); | 614 | * and getting 99 and 0. As Linux tends to come apart under the stress |
605 | 615 | * of time travel, we must be careful: */ | |
606 | /* If we can't use the TSC, we read the time value written by the Host. | ||
607 | * Since it's in two parts (seconds and nanoseconds), we risk reading | ||
608 | * it just as it's changing from 99 & 0.999999999 to 100 and 0, and | ||
609 | * getting 99 and 0. As Linux tends to come apart under the stress of | ||
610 | * time travel, we must be careful: */ | ||
611 | do { | 616 | do { |
612 | /* First we read the seconds part. */ | 617 | /* First we read the seconds part. */ |
613 | sec = lguest_data.time.tv_sec; | 618 | sec = lguest_data.time.tv_sec; |
@@ -622,14 +627,14 @@ static cycle_t lguest_clock_read(void) | |||
622 | /* Now if the seconds part has changed, try again. */ | 627 | /* Now if the seconds part has changed, try again. */ |
623 | } while (unlikely(lguest_data.time.tv_sec != sec)); | 628 | } while (unlikely(lguest_data.time.tv_sec != sec)); |
624 | 629 | ||
625 | /* Our non-TSC clock is in real nanoseconds. */ | 630 | /* Our lguest clock is in real nanoseconds. */ |
626 | return sec*1000000000ULL + nsec; | 631 | return sec*1000000000ULL + nsec; |
627 | } | 632 | } |
628 | 633 | ||
629 | /* This is what we tell the kernel is our clocksource. */ | 634 | /* This is the fallback clocksource: lower priority than the TSC clocksource. */ |
630 | static struct clocksource lguest_clock = { | 635 | static struct clocksource lguest_clock = { |
631 | .name = "lguest", | 636 | .name = "lguest", |
632 | .rating = 400, | 637 | .rating = 200, |
633 | .read = lguest_clock_read, | 638 | .read = lguest_clock_read, |
634 | .mask = CLOCKSOURCE_MASK(64), | 639 | .mask = CLOCKSOURCE_MASK(64), |
635 | .mult = 1 << 22, | 640 | .mult = 1 << 22, |
@@ -637,12 +642,6 @@ static struct clocksource lguest_clock = { | |||
637 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 642 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
638 | }; | 643 | }; |
639 | 644 | ||
640 | /* The "scheduler clock" is just our real clock, adjusted to start at zero */ | ||
641 | static unsigned long long lguest_sched_clock(void) | ||
642 | { | ||
643 | return cyc2ns(&lguest_clock, lguest_clock_read() - clock_base); | ||
644 | } | ||
645 | |||
646 | /* We also need a "struct clock_event_device": Linux asks us to set it to go | 645 | /* We also need a "struct clock_event_device": Linux asks us to set it to go |
647 | * off some time in the future. Actually, James Morris figured all this out, I | 646 | * off some time in the future. Actually, James Morris figured all this out, I |
648 | * just applied the patch. */ | 647 | * just applied the patch. */ |
@@ -712,19 +711,8 @@ static void lguest_time_init(void) | |||
712 | /* Set up the timer interrupt (0) to go to our simple timer routine */ | 711 | /* Set up the timer interrupt (0) to go to our simple timer routine */ |
713 | set_irq_handler(0, lguest_time_irq); | 712 | set_irq_handler(0, lguest_time_irq); |
714 | 713 | ||
715 | /* Our clock structure looks like arch/x86/kernel/tsc_32.c if we can | ||
716 | * use the TSC, otherwise it's a dumb nanosecond-resolution clock. | ||
717 | * Either way, the "rating" is set so high that it's always chosen over | ||
718 | * any other clocksource. */ | ||
719 | if (lguest_data.tsc_khz) | ||
720 | lguest_clock.mult = clocksource_khz2mult(lguest_data.tsc_khz, | ||
721 | lguest_clock.shift); | ||
722 | clock_base = lguest_clock_read(); | ||
723 | clocksource_register(&lguest_clock); | 714 | clocksource_register(&lguest_clock); |
724 | 715 | ||
725 | /* Now we've set up our clock, we can use it as the scheduler clock */ | ||
726 | pv_time_ops.sched_clock = lguest_sched_clock; | ||
727 | |||
728 | /* We can't set cpumask in the initializer: damn C limitations! Set it | 716 | /* We can't set cpumask in the initializer: damn C limitations! Set it |
729 | * here and register our timer device. */ | 717 | * here and register our timer device. */ |
730 | lguest_clockevent.cpumask = cpumask_of_cpu(0); | 718 | lguest_clockevent.cpumask = cpumask_of_cpu(0); |
@@ -995,6 +983,7 @@ __init void lguest_init(void) | |||
995 | /* time operations */ | 983 | /* time operations */ |
996 | pv_time_ops.get_wallclock = lguest_get_wallclock; | 984 | pv_time_ops.get_wallclock = lguest_get_wallclock; |
997 | pv_time_ops.time_init = lguest_time_init; | 985 | pv_time_ops.time_init = lguest_time_init; |
986 | pv_time_ops.get_cpu_khz = lguest_cpu_khz; | ||
998 | 987 | ||
999 | /* Now is a good time to look at the implementations of these functions | 988 | /* Now is a good time to look at the implementations of these functions |
1000 | * before returning to the rest of lguest_init(). */ | 989 | * before returning to the rest of lguest_init(). */ |
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index ac3c959e271d..8fe576baa148 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c | |||
@@ -134,8 +134,6 @@ static void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, | |||
134 | return NULL; | 134 | return NULL; |
135 | } | 135 | } |
136 | 136 | ||
137 | WARN_ON_ONCE(page_is_ram(pfn)); | ||
138 | |||
139 | switch (mode) { | 137 | switch (mode) { |
140 | case IOR_MODE_UNCACHED: | 138 | case IOR_MODE_UNCACHED: |
141 | default: | 139 | default: |
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c index 73aba7125203..2f9e9afcb9f4 100644 --- a/arch/x86/mm/pgtable_32.c +++ b/arch/x86/mm/pgtable_32.c | |||
@@ -342,12 +342,16 @@ static void pgd_mop_up_pmds(struct mm_struct *mm, pgd_t *pgdp) | |||
342 | 342 | ||
343 | pgd_t *pgd_alloc(struct mm_struct *mm) | 343 | pgd_t *pgd_alloc(struct mm_struct *mm) |
344 | { | 344 | { |
345 | pgd_t *pgd = quicklist_alloc(0, GFP_KERNEL, pgd_ctor); | 345 | pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO); |
346 | 346 | ||
347 | mm->pgd = pgd; /* so that alloc_pd can use it */ | 347 | /* so that alloc_pd can use it */ |
348 | mm->pgd = pgd; | ||
349 | if (pgd) | ||
350 | pgd_ctor(pgd); | ||
348 | 351 | ||
349 | if (pgd && !pgd_prepopulate_pmd(mm, pgd)) { | 352 | if (pgd && !pgd_prepopulate_pmd(mm, pgd)) { |
350 | quicklist_free(0, pgd_dtor, pgd); | 353 | pgd_dtor(pgd); |
354 | free_page((unsigned long)pgd); | ||
351 | pgd = NULL; | 355 | pgd = NULL; |
352 | } | 356 | } |
353 | 357 | ||
@@ -357,12 +361,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm) | |||
357 | void pgd_free(struct mm_struct *mm, pgd_t *pgd) | 361 | void pgd_free(struct mm_struct *mm, pgd_t *pgd) |
358 | { | 362 | { |
359 | pgd_mop_up_pmds(mm, pgd); | 363 | pgd_mop_up_pmds(mm, pgd); |
360 | quicklist_free(0, pgd_dtor, pgd); | 364 | pgd_dtor(pgd); |
361 | } | 365 | free_page((unsigned long)pgd); |
362 | |||
363 | void check_pgt_cache(void) | ||
364 | { | ||
365 | quicklist_trim(0, pgd_dtor, 25, 16); | ||
366 | } | 366 | } |
367 | 367 | ||
368 | void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte) | 368 | void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte) |
diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c index 10ac8c316c46..2f7109ac4c15 100644 --- a/arch/x86/pci/pcbios.c +++ b/arch/x86/pci/pcbios.c | |||
@@ -198,6 +198,11 @@ static int pci_bios_read(unsigned int seg, unsigned int bus, | |||
198 | "b" (bx), | 198 | "b" (bx), |
199 | "D" ((long)reg), | 199 | "D" ((long)reg), |
200 | "S" (&pci_indirect)); | 200 | "S" (&pci_indirect)); |
201 | /* | ||
202 | * Zero-extend the result beyond 8 bits, do not trust the | ||
203 | * BIOS having done it: | ||
204 | */ | ||
205 | *value &= 0xff; | ||
201 | break; | 206 | break; |
202 | case 2: | 207 | case 2: |
203 | __asm__("lcall *(%%esi); cld\n\t" | 208 | __asm__("lcall *(%%esi); cld\n\t" |
@@ -210,6 +215,11 @@ static int pci_bios_read(unsigned int seg, unsigned int bus, | |||
210 | "b" (bx), | 215 | "b" (bx), |
211 | "D" ((long)reg), | 216 | "D" ((long)reg), |
212 | "S" (&pci_indirect)); | 217 | "S" (&pci_indirect)); |
218 | /* | ||
219 | * Zero-extend the result beyond 16 bits, do not trust the | ||
220 | * BIOS having done it: | ||
221 | */ | ||
222 | *value &= 0xffff; | ||
213 | break; | 223 | break; |
214 | case 4: | 224 | case 4: |
215 | __asm__("lcall *(%%esi); cld\n\t" | 225 | __asm__("lcall *(%%esi); cld\n\t" |
diff --git a/crypto/chainiv.c b/crypto/chainiv.c index 0a7cac6e9089..6da3f577e4db 100644 --- a/crypto/chainiv.c +++ b/crypto/chainiv.c | |||
@@ -318,10 +318,8 @@ int __init chainiv_module_init(void) | |||
318 | { | 318 | { |
319 | return crypto_register_template(&chainiv_tmpl); | 319 | return crypto_register_template(&chainiv_tmpl); |
320 | } | 320 | } |
321 | EXPORT_SYMBOL_GPL(chainiv_module_init); | ||
322 | 321 | ||
323 | void __exit chainiv_module_exit(void) | 322 | void chainiv_module_exit(void) |
324 | { | 323 | { |
325 | crypto_unregister_template(&chainiv_tmpl); | 324 | crypto_unregister_template(&chainiv_tmpl); |
326 | } | 325 | } |
327 | EXPORT_SYMBOL_GPL(chainiv_module_exit); | ||
diff --git a/crypto/eseqiv.c b/crypto/eseqiv.c index 6f2cd063b6fe..b14f14e314b6 100644 --- a/crypto/eseqiv.c +++ b/crypto/eseqiv.c | |||
@@ -251,10 +251,8 @@ int __init eseqiv_module_init(void) | |||
251 | { | 251 | { |
252 | return crypto_register_template(&eseqiv_tmpl); | 252 | return crypto_register_template(&eseqiv_tmpl); |
253 | } | 253 | } |
254 | EXPORT_SYMBOL_GPL(eseqiv_module_init); | ||
255 | 254 | ||
256 | void __exit eseqiv_module_exit(void) | 255 | void __exit eseqiv_module_exit(void) |
257 | { | 256 | { |
258 | crypto_unregister_template(&eseqiv_tmpl); | 257 | crypto_unregister_template(&eseqiv_tmpl); |
259 | } | 258 | } |
260 | EXPORT_SYMBOL_GPL(eseqiv_module_exit); | ||
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index ba8f7f4dfa11..e469647330de 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -538,6 +538,15 @@ config PATA_RADISYS | |||
538 | 538 | ||
539 | If unsure, say N. | 539 | If unsure, say N. |
540 | 540 | ||
541 | config PATA_RB500 | ||
542 | tristate "RouterBoard 500 PATA CompactFlash support" | ||
543 | depends on MIKROTIK_RB500 | ||
544 | help | ||
545 | This option enables support for the RouterBoard 500 | ||
546 | PATA CompactFlash controller. | ||
547 | |||
548 | If unsure, say N. | ||
549 | |||
541 | config PATA_RZ1000 | 550 | config PATA_RZ1000 |
542 | tristate "PC Tech RZ1000 PATA support" | 551 | tristate "PC Tech RZ1000 PATA support" |
543 | depends on PCI | 552 | depends on PCI |
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 701651e37c89..0511e6f0bb58 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile | |||
@@ -55,6 +55,7 @@ obj-$(CONFIG_PATA_PDC2027X) += pata_pdc2027x.o | |||
55 | obj-$(CONFIG_PATA_PDC_OLD) += pata_pdc202xx_old.o | 55 | obj-$(CONFIG_PATA_PDC_OLD) += pata_pdc202xx_old.o |
56 | obj-$(CONFIG_PATA_QDI) += pata_qdi.o | 56 | obj-$(CONFIG_PATA_QDI) += pata_qdi.o |
57 | obj-$(CONFIG_PATA_RADISYS) += pata_radisys.o | 57 | obj-$(CONFIG_PATA_RADISYS) += pata_radisys.o |
58 | obj-$(CONFIG_PATA_RB500) += pata_rb500_cf.o | ||
58 | obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o | 59 | obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o |
59 | obj-$(CONFIG_PATA_SC1200) += pata_sc1200.o | 60 | obj-$(CONFIG_PATA_SC1200) += pata_sc1200.o |
60 | obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o | 61 | obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 8a49835bd0f8..6978469eb16d 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -567,6 +567,18 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
567 | { PCI_VDEVICE(NVIDIA, 0x0abd), board_ahci }, /* MCP79 */ | 567 | { PCI_VDEVICE(NVIDIA, 0x0abd), board_ahci }, /* MCP79 */ |
568 | { PCI_VDEVICE(NVIDIA, 0x0abe), board_ahci }, /* MCP79 */ | 568 | { PCI_VDEVICE(NVIDIA, 0x0abe), board_ahci }, /* MCP79 */ |
569 | { PCI_VDEVICE(NVIDIA, 0x0abf), board_ahci }, /* MCP79 */ | 569 | { PCI_VDEVICE(NVIDIA, 0x0abf), board_ahci }, /* MCP79 */ |
570 | { PCI_VDEVICE(NVIDIA, 0x0bc8), board_ahci }, /* MCP7B */ | ||
571 | { PCI_VDEVICE(NVIDIA, 0x0bc9), board_ahci }, /* MCP7B */ | ||
572 | { PCI_VDEVICE(NVIDIA, 0x0bca), board_ahci }, /* MCP7B */ | ||
573 | { PCI_VDEVICE(NVIDIA, 0x0bcb), board_ahci }, /* MCP7B */ | ||
574 | { PCI_VDEVICE(NVIDIA, 0x0bcc), board_ahci }, /* MCP7B */ | ||
575 | { PCI_VDEVICE(NVIDIA, 0x0bcd), board_ahci }, /* MCP7B */ | ||
576 | { PCI_VDEVICE(NVIDIA, 0x0bce), board_ahci }, /* MCP7B */ | ||
577 | { PCI_VDEVICE(NVIDIA, 0x0bcf), board_ahci }, /* MCP7B */ | ||
578 | { PCI_VDEVICE(NVIDIA, 0x0bd0), board_ahci }, /* MCP7B */ | ||
579 | { PCI_VDEVICE(NVIDIA, 0x0bd1), board_ahci }, /* MCP7B */ | ||
580 | { PCI_VDEVICE(NVIDIA, 0x0bd2), board_ahci }, /* MCP7B */ | ||
581 | { PCI_VDEVICE(NVIDIA, 0x0bd3), board_ahci }, /* MCP7B */ | ||
570 | 582 | ||
571 | /* SiS */ | 583 | /* SiS */ |
572 | { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */ | 584 | { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */ |
@@ -672,7 +684,7 @@ static void ahci_save_initial_config(struct pci_dev *pdev, | |||
672 | cap &= ~HOST_CAP_NCQ; | 684 | cap &= ~HOST_CAP_NCQ; |
673 | } | 685 | } |
674 | 686 | ||
675 | if ((cap && HOST_CAP_PMP) && (hpriv->flags & AHCI_HFLAG_NO_PMP)) { | 687 | if ((cap & HOST_CAP_PMP) && (hpriv->flags & AHCI_HFLAG_NO_PMP)) { |
676 | dev_printk(KERN_INFO, &pdev->dev, | 688 | dev_printk(KERN_INFO, &pdev->dev, |
677 | "controller can't do PMP, turning off CAP_PMP\n"); | 689 | "controller can't do PMP, turning off CAP_PMP\n"); |
678 | cap &= ~HOST_CAP_PMP; | 690 | cap &= ~HOST_CAP_PMP; |
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 9e8ec19260af..0770cb7391a4 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
@@ -382,7 +382,7 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf) | |||
382 | 382 | ||
383 | if (ata_msg_probe(ap)) | 383 | if (ata_msg_probe(ap)) |
384 | ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n", | 384 | ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n", |
385 | __FUNCTION__, ap->port_no); | 385 | __func__, ap->port_no); |
386 | 386 | ||
387 | /* _GTF has no input parameters */ | 387 | /* _GTF has no input parameters */ |
388 | status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output); | 388 | status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output); |
@@ -402,7 +402,7 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf) | |||
402 | if (ata_msg_probe(ap)) | 402 | if (ata_msg_probe(ap)) |
403 | ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF: " | 403 | ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF: " |
404 | "length or ptr is NULL (0x%llx, 0x%p)\n", | 404 | "length or ptr is NULL (0x%llx, 0x%p)\n", |
405 | __FUNCTION__, | 405 | __func__, |
406 | (unsigned long long)output.length, | 406 | (unsigned long long)output.length, |
407 | output.pointer); | 407 | output.pointer); |
408 | rc = -EINVAL; | 408 | rc = -EINVAL; |
@@ -432,7 +432,7 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf) | |||
432 | if (ata_msg_probe(ap)) | 432 | if (ata_msg_probe(ap)) |
433 | ata_dev_printk(dev, KERN_DEBUG, | 433 | ata_dev_printk(dev, KERN_DEBUG, |
434 | "%s: returning gtf=%p, gtf_count=%d\n", | 434 | "%s: returning gtf=%p, gtf_count=%d\n", |
435 | __FUNCTION__, *gtf, rc); | 435 | __func__, *gtf, rc); |
436 | } | 436 | } |
437 | return rc; | 437 | return rc; |
438 | 438 | ||
@@ -725,7 +725,7 @@ static int ata_acpi_push_id(struct ata_device *dev) | |||
725 | 725 | ||
726 | if (ata_msg_probe(ap)) | 726 | if (ata_msg_probe(ap)) |
727 | ata_dev_printk(dev, KERN_DEBUG, "%s: ix = %d, port#: %d\n", | 727 | ata_dev_printk(dev, KERN_DEBUG, "%s: ix = %d, port#: %d\n", |
728 | __FUNCTION__, dev->devno, ap->port_no); | 728 | __func__, dev->devno, ap->port_no); |
729 | 729 | ||
730 | /* Give the drive Identify data to the drive via the _SDD method */ | 730 | /* Give the drive Identify data to the drive via the _SDD method */ |
731 | /* _SDD: set up input parameters */ | 731 | /* _SDD: set up input parameters */ |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 4fbcce758b04..4bbe31f98ef8 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -106,7 +106,8 @@ static struct ata_force_ent *ata_force_tbl; | |||
106 | static int ata_force_tbl_size; | 106 | static int ata_force_tbl_size; |
107 | 107 | ||
108 | static char ata_force_param_buf[PAGE_SIZE] __initdata; | 108 | static char ata_force_param_buf[PAGE_SIZE] __initdata; |
109 | module_param_string(force, ata_force_param_buf, sizeof(ata_force_param_buf), 0444); | 109 | /* param_buf is thrown away after initialization, disallow read */ |
110 | module_param_string(force, ata_force_param_buf, sizeof(ata_force_param_buf), 0); | ||
110 | MODULE_PARM_DESC(force, "Force ATA configurations including cable type, link speed and transfer mode (see Documentation/kernel-parameters.txt for details)"); | 111 | MODULE_PARM_DESC(force, "Force ATA configurations including cable type, link speed and transfer mode (see Documentation/kernel-parameters.txt for details)"); |
111 | 112 | ||
112 | int atapi_enabled = 1; | 113 | int atapi_enabled = 1; |
@@ -1719,7 +1720,7 @@ void ata_port_flush_task(struct ata_port *ap) | |||
1719 | cancel_rearming_delayed_work(&ap->port_task); | 1720 | cancel_rearming_delayed_work(&ap->port_task); |
1720 | 1721 | ||
1721 | if (ata_msg_ctl(ap)) | 1722 | if (ata_msg_ctl(ap)) |
1722 | ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __FUNCTION__); | 1723 | ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __func__); |
1723 | } | 1724 | } |
1724 | 1725 | ||
1725 | static void ata_qc_complete_internal(struct ata_queued_cmd *qc) | 1726 | static void ata_qc_complete_internal(struct ata_queued_cmd *qc) |
@@ -2056,7 +2057,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, | |||
2056 | int rc; | 2057 | int rc; |
2057 | 2058 | ||
2058 | if (ata_msg_ctl(ap)) | 2059 | if (ata_msg_ctl(ap)) |
2059 | ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__); | 2060 | ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __func__); |
2060 | 2061 | ||
2061 | ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ | 2062 | ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ |
2062 | retry: | 2063 | retry: |
@@ -2253,12 +2254,12 @@ int ata_dev_configure(struct ata_device *dev) | |||
2253 | 2254 | ||
2254 | if (!ata_dev_enabled(dev) && ata_msg_info(ap)) { | 2255 | if (!ata_dev_enabled(dev) && ata_msg_info(ap)) { |
2255 | ata_dev_printk(dev, KERN_INFO, "%s: ENTER/EXIT -- nodev\n", | 2256 | ata_dev_printk(dev, KERN_INFO, "%s: ENTER/EXIT -- nodev\n", |
2256 | __FUNCTION__); | 2257 | __func__); |
2257 | return 0; | 2258 | return 0; |
2258 | } | 2259 | } |
2259 | 2260 | ||
2260 | if (ata_msg_probe(ap)) | 2261 | if (ata_msg_probe(ap)) |
2261 | ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__); | 2262 | ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __func__); |
2262 | 2263 | ||
2263 | /* set horkage */ | 2264 | /* set horkage */ |
2264 | dev->horkage |= ata_dev_blacklisted(dev); | 2265 | dev->horkage |= ata_dev_blacklisted(dev); |
@@ -2279,7 +2280,7 @@ int ata_dev_configure(struct ata_device *dev) | |||
2279 | ata_dev_printk(dev, KERN_DEBUG, | 2280 | ata_dev_printk(dev, KERN_DEBUG, |
2280 | "%s: cfg 49:%04x 82:%04x 83:%04x 84:%04x " | 2281 | "%s: cfg 49:%04x 82:%04x 83:%04x 84:%04x " |
2281 | "85:%04x 86:%04x 87:%04x 88:%04x\n", | 2282 | "85:%04x 86:%04x 87:%04x 88:%04x\n", |
2282 | __FUNCTION__, | 2283 | __func__, |
2283 | id[49], id[82], id[83], id[84], | 2284 | id[49], id[82], id[83], id[84], |
2284 | id[85], id[86], id[87], id[88]); | 2285 | id[85], id[86], id[87], id[88]); |
2285 | 2286 | ||
@@ -2511,13 +2512,13 @@ int ata_dev_configure(struct ata_device *dev) | |||
2511 | 2512 | ||
2512 | if (ata_msg_probe(ap)) | 2513 | if (ata_msg_probe(ap)) |
2513 | ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n", | 2514 | ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n", |
2514 | __FUNCTION__, ata_chk_status(ap)); | 2515 | __func__, ata_chk_status(ap)); |
2515 | return 0; | 2516 | return 0; |
2516 | 2517 | ||
2517 | err_out_nosup: | 2518 | err_out_nosup: |
2518 | if (ata_msg_probe(ap)) | 2519 | if (ata_msg_probe(ap)) |
2519 | ata_dev_printk(dev, KERN_DEBUG, | 2520 | ata_dev_printk(dev, KERN_DEBUG, |
2520 | "%s: EXIT, err\n", __FUNCTION__); | 2521 | "%s: EXIT, err\n", __func__); |
2521 | return rc; | 2522 | return rc; |
2522 | } | 2523 | } |
2523 | 2524 | ||
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 698ce2cea52c..681252fd8143 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -2150,6 +2150,15 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2150 | ap->ops->set_piomode(ap, dev); | 2150 | ap->ops->set_piomode(ap, dev); |
2151 | } | 2151 | } |
2152 | 2152 | ||
2153 | if (!softreset && !hardreset) { | ||
2154 | if (verbose) | ||
2155 | ata_link_printk(link, KERN_INFO, "no reset method " | ||
2156 | "available, skipping reset\n"); | ||
2157 | if (!(lflags & ATA_LFLAG_ASSUME_CLASS)) | ||
2158 | lflags |= ATA_LFLAG_ASSUME_ATA; | ||
2159 | goto done; | ||
2160 | } | ||
2161 | |||
2153 | /* Determine which reset to use and record in ehc->i.action. | 2162 | /* Determine which reset to use and record in ehc->i.action. |
2154 | * prereset() may examine and modify it. | 2163 | * prereset() may examine and modify it. |
2155 | */ | 2164 | */ |
@@ -2254,6 +2263,7 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2254 | lflags |= ATA_LFLAG_ASSUME_ATA; | 2263 | lflags |= ATA_LFLAG_ASSUME_ATA; |
2255 | } | 2264 | } |
2256 | 2265 | ||
2266 | done: | ||
2257 | ata_link_for_each_dev(dev, link) { | 2267 | ata_link_for_each_dev(dev, link) { |
2258 | /* After the reset, the device state is PIO 0 and the | 2268 | /* After the reset, the device state is PIO 0 and the |
2259 | * controller state is undefined. Reset also wakes up | 2269 | * controller state is undefined. Reset also wakes up |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 60cd4b179766..20dc572fb45a 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -56,7 +56,8 @@ u8 ata_irq_on(struct ata_port *ap) | |||
56 | ap->ctl &= ~ATA_NIEN; | 56 | ap->ctl &= ~ATA_NIEN; |
57 | ap->last_ctl = ap->ctl; | 57 | ap->last_ctl = ap->ctl; |
58 | 58 | ||
59 | iowrite8(ap->ctl, ioaddr->ctl_addr); | 59 | if (ioaddr->ctl_addr) |
60 | iowrite8(ap->ctl, ioaddr->ctl_addr); | ||
60 | tmp = ata_wait_idle(ap); | 61 | tmp = ata_wait_idle(ap); |
61 | 62 | ||
62 | ap->ops->irq_clear(ap); | 63 | ap->ops->irq_clear(ap); |
@@ -81,12 +82,14 @@ void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) | |||
81 | unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; | 82 | unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; |
82 | 83 | ||
83 | if (tf->ctl != ap->last_ctl) { | 84 | if (tf->ctl != ap->last_ctl) { |
84 | iowrite8(tf->ctl, ioaddr->ctl_addr); | 85 | if (ioaddr->ctl_addr) |
86 | iowrite8(tf->ctl, ioaddr->ctl_addr); | ||
85 | ap->last_ctl = tf->ctl; | 87 | ap->last_ctl = tf->ctl; |
86 | ata_wait_idle(ap); | 88 | ata_wait_idle(ap); |
87 | } | 89 | } |
88 | 90 | ||
89 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { | 91 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { |
92 | WARN_ON(!ioaddr->ctl_addr); | ||
90 | iowrite8(tf->hob_feature, ioaddr->feature_addr); | 93 | iowrite8(tf->hob_feature, ioaddr->feature_addr); |
91 | iowrite8(tf->hob_nsect, ioaddr->nsect_addr); | 94 | iowrite8(tf->hob_nsect, ioaddr->nsect_addr); |
92 | iowrite8(tf->hob_lbal, ioaddr->lbal_addr); | 95 | iowrite8(tf->hob_lbal, ioaddr->lbal_addr); |
@@ -167,14 +170,17 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | |||
167 | tf->device = ioread8(ioaddr->device_addr); | 170 | tf->device = ioread8(ioaddr->device_addr); |
168 | 171 | ||
169 | if (tf->flags & ATA_TFLAG_LBA48) { | 172 | if (tf->flags & ATA_TFLAG_LBA48) { |
170 | iowrite8(tf->ctl | ATA_HOB, ioaddr->ctl_addr); | 173 | if (likely(ioaddr->ctl_addr)) { |
171 | tf->hob_feature = ioread8(ioaddr->error_addr); | 174 | iowrite8(tf->ctl | ATA_HOB, ioaddr->ctl_addr); |
172 | tf->hob_nsect = ioread8(ioaddr->nsect_addr); | 175 | tf->hob_feature = ioread8(ioaddr->error_addr); |
173 | tf->hob_lbal = ioread8(ioaddr->lbal_addr); | 176 | tf->hob_nsect = ioread8(ioaddr->nsect_addr); |
174 | tf->hob_lbam = ioread8(ioaddr->lbam_addr); | 177 | tf->hob_lbal = ioread8(ioaddr->lbal_addr); |
175 | tf->hob_lbah = ioread8(ioaddr->lbah_addr); | 178 | tf->hob_lbam = ioread8(ioaddr->lbam_addr); |
176 | iowrite8(tf->ctl, ioaddr->ctl_addr); | 179 | tf->hob_lbah = ioread8(ioaddr->lbah_addr); |
177 | ap->last_ctl = tf->ctl; | 180 | iowrite8(tf->ctl, ioaddr->ctl_addr); |
181 | ap->last_ctl = tf->ctl; | ||
182 | } else | ||
183 | WARN_ON(1); | ||
178 | } | 184 | } |
179 | } | 185 | } |
180 | 186 | ||
@@ -352,7 +358,8 @@ void ata_bmdma_freeze(struct ata_port *ap) | |||
352 | ap->ctl |= ATA_NIEN; | 358 | ap->ctl |= ATA_NIEN; |
353 | ap->last_ctl = ap->ctl; | 359 | ap->last_ctl = ap->ctl; |
354 | 360 | ||
355 | iowrite8(ap->ctl, ioaddr->ctl_addr); | 361 | if (ioaddr->ctl_addr) |
362 | iowrite8(ap->ctl, ioaddr->ctl_addr); | ||
356 | 363 | ||
357 | /* Under certain circumstances, some controllers raise IRQ on | 364 | /* Under certain circumstances, some controllers raise IRQ on |
358 | * ATA_NIEN manipulation. Also, many controllers fail to mask | 365 | * ATA_NIEN manipulation. Also, many controllers fail to mask |
@@ -459,13 +466,14 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
459 | */ | 466 | */ |
460 | void ata_bmdma_error_handler(struct ata_port *ap) | 467 | void ata_bmdma_error_handler(struct ata_port *ap) |
461 | { | 468 | { |
462 | ata_reset_fn_t hardreset; | 469 | ata_reset_fn_t softreset = NULL, hardreset = NULL; |
463 | 470 | ||
464 | hardreset = NULL; | 471 | if (ap->ioaddr.ctl_addr) |
472 | softreset = ata_std_softreset; | ||
465 | if (sata_scr_valid(&ap->link)) | 473 | if (sata_scr_valid(&ap->link)) |
466 | hardreset = sata_std_hardreset; | 474 | hardreset = sata_std_hardreset; |
467 | 475 | ||
468 | ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, hardreset, | 476 | ata_bmdma_drive_eh(ap, ata_std_prereset, softreset, hardreset, |
469 | ata_std_postreset); | 477 | ata_std_postreset); |
470 | } | 478 | } |
471 | 479 | ||
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index 028af5dbeed6..511c89b9bae8 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #undef PDC_DEBUG | 39 | #undef PDC_DEBUG |
40 | 40 | ||
41 | #ifdef PDC_DEBUG | 41 | #ifdef PDC_DEBUG |
42 | #define PDPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) | 42 | #define PDPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) |
43 | #else | 43 | #else |
44 | #define PDPRINTK(fmt, args...) | 44 | #define PDPRINTK(fmt, args...) |
45 | #endif | 45 | #endif |
diff --git a/drivers/ata/pata_rb500_cf.c b/drivers/ata/pata_rb500_cf.c new file mode 100644 index 000000000000..4ce9b03fe6c8 --- /dev/null +++ b/drivers/ata/pata_rb500_cf.c | |||
@@ -0,0 +1,314 @@ | |||
1 | /* | ||
2 | * A low-level PATA driver to handle a Compact Flash connected on the | ||
3 | * Mikrotik's RouterBoard 532 board. | ||
4 | * | ||
5 | * Copyright (C) 2007 Gabor Juhos <juhosg at openwrt.org> | ||
6 | * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org> | ||
7 | * | ||
8 | * This file was based on: drivers/ata/pata_ixp4xx_cf.c | ||
9 | * Copyright (C) 2006-07 Tower Technologies | ||
10 | * Author: Alessandro Zummo <a.zummo@towertech.it> | ||
11 | * | ||
12 | * Also was based on the driver for Linux 2.4.xx published by Mikrotik for | ||
13 | * their RouterBoard 1xx and 5xx series devices. The original Mikrotik code | ||
14 | * seems not to have a license. | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or modify | ||
17 | * it under the terms of the GNU General Public License version 2 as | ||
18 | * published by the Free Software Foundation. | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | |||
26 | #include <linux/io.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/irq.h> | ||
29 | |||
30 | #include <linux/libata.h> | ||
31 | #include <scsi/scsi_host.h> | ||
32 | |||
33 | #include <asm/gpio.h> | ||
34 | |||
35 | #define DRV_NAME "pata-rb500-cf" | ||
36 | #define DRV_VERSION "0.1.0" | ||
37 | #define DRV_DESC "PATA driver for RouterBOARD 532 Compact Flash" | ||
38 | |||
39 | #define RB500_CF_MAXPORTS 1 | ||
40 | #define RB500_CF_IO_DELAY 400 | ||
41 | |||
42 | #define RB500_CF_REG_CMD 0x0800 | ||
43 | #define RB500_CF_REG_CTRL 0x080E | ||
44 | #define RB500_CF_REG_DATA 0x0C00 | ||
45 | |||
46 | struct rb500_cf_info { | ||
47 | void __iomem *iobase; | ||
48 | unsigned int gpio_line; | ||
49 | int frozen; | ||
50 | unsigned int irq; | ||
51 | }; | ||
52 | |||
53 | /* ------------------------------------------------------------------------ */ | ||
54 | |||
55 | static inline void rb500_pata_finish_io(struct ata_port *ap) | ||
56 | { | ||
57 | struct ata_host *ah = ap->host; | ||
58 | struct rb500_cf_info *info = ah->private_data; | ||
59 | |||
60 | ata_altstatus(ap); | ||
61 | ndelay(RB500_CF_IO_DELAY); | ||
62 | |||
63 | set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH); | ||
64 | } | ||
65 | |||
66 | static void rb500_pata_exec_command(struct ata_port *ap, | ||
67 | const struct ata_taskfile *tf) | ||
68 | { | ||
69 | writeb(tf->command, ap->ioaddr.command_addr); | ||
70 | rb500_pata_finish_io(ap); | ||
71 | } | ||
72 | |||
73 | static void rb500_pata_data_xfer(struct ata_device *adev, unsigned char *buf, | ||
74 | unsigned int buflen, int write_data) | ||
75 | { | ||
76 | struct ata_port *ap = adev->link->ap; | ||
77 | void __iomem *ioaddr = ap->ioaddr.data_addr; | ||
78 | |||
79 | if (write_data) { | ||
80 | for (; buflen > 0; buflen--, buf++) | ||
81 | writeb(*buf, ioaddr); | ||
82 | } else { | ||
83 | for (; buflen > 0; buflen--, buf++) | ||
84 | *buf = readb(ioaddr); | ||
85 | } | ||
86 | |||
87 | rb500_pata_finish_io(adev->link->ap); | ||
88 | } | ||
89 | |||
90 | static void rb500_pata_freeze(struct ata_port *ap) | ||
91 | { | ||
92 | struct rb500_cf_info *info = ap->host->private_data; | ||
93 | |||
94 | info->frozen = 1; | ||
95 | } | ||
96 | |||
97 | static void rb500_pata_thaw(struct ata_port *ap) | ||
98 | { | ||
99 | struct rb500_cf_info *info = ap->host->private_data; | ||
100 | |||
101 | info->frozen = 0; | ||
102 | } | ||
103 | |||
104 | static irqreturn_t rb500_pata_irq_handler(int irq, void *dev_instance) | ||
105 | { | ||
106 | struct ata_host *ah = dev_instance; | ||
107 | struct rb500_cf_info *info = ah->private_data; | ||
108 | |||
109 | if (gpio_get_value(info->gpio_line)) { | ||
110 | set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW); | ||
111 | if (!info->frozen) | ||
112 | ata_interrupt(info->irq, dev_instance); | ||
113 | } else { | ||
114 | set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH); | ||
115 | } | ||
116 | |||
117 | return IRQ_HANDLED; | ||
118 | } | ||
119 | |||
120 | static void rb500_pata_irq_clear(struct ata_port *ap) | ||
121 | { | ||
122 | } | ||
123 | |||
124 | static int rb500_pata_port_start(struct ata_port *ap) | ||
125 | { | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static struct ata_port_operations rb500_pata_port_ops = { | ||
130 | .tf_load = ata_tf_load, | ||
131 | .tf_read = ata_tf_read, | ||
132 | |||
133 | .exec_command = rb500_pata_exec_command, | ||
134 | .check_status = ata_check_status, | ||
135 | .dev_select = ata_std_dev_select, | ||
136 | |||
137 | .data_xfer = rb500_pata_data_xfer, | ||
138 | |||
139 | .qc_prep = ata_qc_prep, | ||
140 | .qc_issue = ata_qc_issue_prot, | ||
141 | |||
142 | .freeze = rb500_pata_freeze, | ||
143 | .thaw = rb500_pata_thaw, | ||
144 | .error_handler = ata_bmdma_error_handler, | ||
145 | |||
146 | .irq_handler = rb500_pata_irq_handler, | ||
147 | .irq_clear = rb500_pata_irq_clear, | ||
148 | .irq_on = ata_irq_on, | ||
149 | |||
150 | .port_start = rb500_pata_port_start, | ||
151 | }; | ||
152 | |||
153 | /* ------------------------------------------------------------------------ */ | ||
154 | |||
155 | static struct scsi_host_template rb500_pata_sht = { | ||
156 | .module = THIS_MODULE, | ||
157 | .name = DRV_NAME, | ||
158 | .ioctl = ata_scsi_ioctl, | ||
159 | .queuecommand = ata_scsi_queuecmd, | ||
160 | .slave_configure = ata_scsi_slave_config, | ||
161 | .slave_destroy = ata_scsi_slave_destroy, | ||
162 | .bios_param = ata_std_bios_param, | ||
163 | .proc_name = DRV_NAME, | ||
164 | |||
165 | .can_queue = ATA_DEF_QUEUE, | ||
166 | .this_id = ATA_SHT_THIS_ID, | ||
167 | .sg_tablesize = LIBATA_MAX_PRD, | ||
168 | .dma_boundary = ATA_DMA_BOUNDARY, | ||
169 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | ||
170 | .emulated = ATA_SHT_EMULATED, | ||
171 | .use_clustering = ATA_SHT_USE_CLUSTERING, | ||
172 | }; | ||
173 | |||
174 | /* ------------------------------------------------------------------------ */ | ||
175 | |||
176 | static void rb500_pata_setup_ports(struct ata_host *ah) | ||
177 | { | ||
178 | struct rb500_cf_info *info = ah->private_data; | ||
179 | struct ata_port *ap; | ||
180 | |||
181 | ap = ah->ports[0]; | ||
182 | |||
183 | ap->ops = &rb500_pata_port_ops; | ||
184 | ap->pio_mask = 0x1f; /* PIO4 */ | ||
185 | ap->flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO; | ||
186 | |||
187 | ap->ioaddr.cmd_addr = info->iobase + RB500_CF_REG_CMD; | ||
188 | ap->ioaddr.ctl_addr = info->iobase + RB500_CF_REG_CTRL; | ||
189 | ap->ioaddr.altstatus_addr = info->iobase + RB500_CF_REG_CTRL; | ||
190 | |||
191 | ata_std_ports(&ap->ioaddr); | ||
192 | |||
193 | ap->ioaddr.data_addr = info->iobase + RB500_CF_REG_DATA; | ||
194 | } | ||
195 | |||
196 | static __devinit int rb500_pata_driver_probe(struct platform_device *pdev) | ||
197 | { | ||
198 | unsigned int irq; | ||
199 | int gpio; | ||
200 | struct resource *res; | ||
201 | struct ata_host *ah; | ||
202 | struct rb500_cf_info *info; | ||
203 | int ret; | ||
204 | |||
205 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
206 | if (!res) { | ||
207 | dev_err(&pdev->dev, "no IOMEM resource found\n"); | ||
208 | return -EINVAL; | ||
209 | } | ||
210 | |||
211 | irq = platform_get_irq(pdev, 0); | ||
212 | if (irq <= 0) { | ||
213 | dev_err(&pdev->dev, "no IRQ resource found\n"); | ||
214 | return -ENOENT; | ||
215 | } | ||
216 | |||
217 | gpio = irq_to_gpio(irq); | ||
218 | if (gpio < 0) { | ||
219 | dev_err(&pdev->dev, "no GPIO found for irq%d\n", irq); | ||
220 | return -ENOENT; | ||
221 | } | ||
222 | |||
223 | ret = gpio_request(gpio, DRV_NAME); | ||
224 | if (ret) { | ||
225 | dev_err(&pdev->dev, "GPIO request failed\n"); | ||
226 | return ret; | ||
227 | } | ||
228 | |||
229 | /* allocate host */ | ||
230 | ah = ata_host_alloc(&pdev->dev, RB500_CF_MAXPORTS); | ||
231 | if (!ah) | ||
232 | return -ENOMEM; | ||
233 | |||
234 | platform_set_drvdata(pdev, ah); | ||
235 | |||
236 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | ||
237 | if (!info) | ||
238 | return -ENOMEM; | ||
239 | |||
240 | ah->private_data = info; | ||
241 | info->gpio_line = gpio; | ||
242 | info->irq = irq; | ||
243 | |||
244 | info->iobase = devm_ioremap_nocache(&pdev->dev, res->start, | ||
245 | res->end - res->start + 1); | ||
246 | if (!info->iobase) | ||
247 | return -ENOMEM; | ||
248 | |||
249 | ret = gpio_direction_input(gpio); | ||
250 | if (ret) { | ||
251 | dev_err(&pdev->dev, "unable to set GPIO direction, err=%d\n", | ||
252 | ret); | ||
253 | goto err_free_gpio; | ||
254 | } | ||
255 | |||
256 | rb500_pata_setup_ports(ah); | ||
257 | |||
258 | ret = ata_host_activate(ah, irq, rb500_pata_irq_handler, | ||
259 | IRQF_TRIGGER_LOW, &rb500_pata_sht); | ||
260 | if (ret) | ||
261 | goto err_free_gpio; | ||
262 | |||
263 | return 0; | ||
264 | |||
265 | err_free_gpio: | ||
266 | gpio_free(gpio); | ||
267 | |||
268 | return ret; | ||
269 | } | ||
270 | |||
271 | static __devexit int rb500_pata_driver_remove(struct platform_device *pdev) | ||
272 | { | ||
273 | struct ata_host *ah = platform_get_drvdata(pdev); | ||
274 | struct rb500_cf_info *info = ah->private_data; | ||
275 | |||
276 | ata_host_detach(ah); | ||
277 | gpio_free(info->gpio_line); | ||
278 | |||
279 | return 0; | ||
280 | } | ||
281 | |||
282 | static struct platform_driver rb500_pata_platform_driver = { | ||
283 | .probe = rb500_pata_driver_probe, | ||
284 | .remove = __devexit_p(rb500_pata_driver_remove), | ||
285 | .driver = { | ||
286 | .name = DRV_NAME, | ||
287 | .owner = THIS_MODULE, | ||
288 | }, | ||
289 | }; | ||
290 | |||
291 | /* ------------------------------------------------------------------------ */ | ||
292 | |||
293 | #define DRV_INFO DRV_DESC " version " DRV_VERSION | ||
294 | |||
295 | static int __init rb500_pata_module_init(void) | ||
296 | { | ||
297 | printk(KERN_INFO DRV_INFO "\n"); | ||
298 | |||
299 | return platform_driver_register(&rb500_pata_platform_driver); | ||
300 | } | ||
301 | |||
302 | static void __exit rb500_pata_module_exit(void) | ||
303 | { | ||
304 | platform_driver_unregister(&rb500_pata_platform_driver); | ||
305 | } | ||
306 | |||
307 | MODULE_AUTHOR("Gabor Juhos <juhosg at openwrt.org>"); | ||
308 | MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); | ||
309 | MODULE_DESCRIPTION(DRV_DESC); | ||
310 | MODULE_VERSION(DRV_VERSION); | ||
311 | MODULE_LICENSE("GPL"); | ||
312 | |||
313 | module_init(rb500_pata_module_init); | ||
314 | module_exit(rb500_pata_module_exit); | ||
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index efaf282c438c..911ec600fe71 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -648,7 +648,7 @@ u64 dma_get_required_mask(struct device *dev) | |||
648 | high_totalram += high_totalram - 1; | 648 | high_totalram += high_totalram - 1; |
649 | mask = (((u64)high_totalram) << 32) + 0xffffffff; | 649 | mask = (((u64)high_totalram) << 32) + 0xffffffff; |
650 | } | 650 | } |
651 | return mask & *dev->dma_mask; | 651 | return mask; |
652 | } | 652 | } |
653 | EXPORT_SYMBOL_GPL(dma_get_required_mask); | 653 | EXPORT_SYMBOL_GPL(dma_get_required_mask); |
654 | #endif | 654 | #endif |
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 2f79c55acdcc..8e13fd942163 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
@@ -133,6 +133,7 @@ int sysdev_class_register(struct sysdev_class * cls) | |||
133 | pr_debug("Registering sysdev class '%s'\n", | 133 | pr_debug("Registering sysdev class '%s'\n", |
134 | kobject_name(&cls->kset.kobj)); | 134 | kobject_name(&cls->kset.kobj)); |
135 | INIT_LIST_HEAD(&cls->drivers); | 135 | INIT_LIST_HEAD(&cls->drivers); |
136 | memset(&cls->kset.kobj, 0x00, sizeof(struct kobject)); | ||
136 | cls->kset.kobj.parent = &system_kset->kobj; | 137 | cls->kset.kobj.parent = &system_kset->kobj; |
137 | cls->kset.kobj.ktype = &ktype_sysdev_class; | 138 | cls->kset.kobj.ktype = &ktype_sysdev_class; |
138 | cls->kset.kobj.kset = system_kset; | 139 | cls->kset.kobj.kset = system_kset; |
@@ -227,6 +228,9 @@ int sysdev_register(struct sys_device * sysdev) | |||
227 | 228 | ||
228 | pr_debug("Registering sys device '%s'\n", kobject_name(&sysdev->kobj)); | 229 | pr_debug("Registering sys device '%s'\n", kobject_name(&sysdev->kobj)); |
229 | 230 | ||
231 | /* initialize the kobject to 0, in case it had previously been used */ | ||
232 | memset(&sysdev->kobj, 0x00, sizeof(struct kobject)); | ||
233 | |||
230 | /* Make sure the kset is set */ | 234 | /* Make sure the kset is set */ |
231 | sysdev->kobj.kset = &cls->kset; | 235 | sysdev->kobj.kset = &cls->kset; |
232 | 236 | ||
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index dfaab2322de3..6d0dc5f9b6bb 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c | |||
@@ -190,6 +190,14 @@ enum card_type { | |||
190 | F32_8 = 8192, /* 3072 bytes downl. + 1024 bytes uplink * 2 -> 8192 */ | 190 | F32_8 = 8192, /* 3072 bytes downl. + 1024 bytes uplink * 2 -> 8192 */ |
191 | }; | 191 | }; |
192 | 192 | ||
193 | /* Initialization states a card can be in */ | ||
194 | enum card_state { | ||
195 | NOZOMI_STATE_UKNOWN = 0, | ||
196 | NOZOMI_STATE_ENABLED = 1, /* pci device enabled */ | ||
197 | NOZOMI_STATE_ALLOCATED = 2, /* config setup done */ | ||
198 | NOZOMI_STATE_READY = 3, /* flowcontrols received */ | ||
199 | }; | ||
200 | |||
193 | /* Two different toggle channels exist */ | 201 | /* Two different toggle channels exist */ |
194 | enum channel_type { | 202 | enum channel_type { |
195 | CH_A = 0, | 203 | CH_A = 0, |
@@ -385,6 +393,7 @@ struct nozomi { | |||
385 | spinlock_t spin_mutex; /* secures access to registers and tty */ | 393 | spinlock_t spin_mutex; /* secures access to registers and tty */ |
386 | 394 | ||
387 | unsigned int index_start; | 395 | unsigned int index_start; |
396 | enum card_state state; | ||
388 | u32 open_ttys; | 397 | u32 open_ttys; |
389 | }; | 398 | }; |
390 | 399 | ||
@@ -686,6 +695,7 @@ static int nozomi_read_config_table(struct nozomi *dc) | |||
686 | dc->last_ier = dc->last_ier | CTRL_DL; | 695 | dc->last_ier = dc->last_ier | CTRL_DL; |
687 | writew(dc->last_ier, dc->reg_ier); | 696 | writew(dc->last_ier, dc->reg_ier); |
688 | 697 | ||
698 | dc->state = NOZOMI_STATE_ALLOCATED; | ||
689 | dev_info(&dc->pdev->dev, "Initialization OK!\n"); | 699 | dev_info(&dc->pdev->dev, "Initialization OK!\n"); |
690 | return 1; | 700 | return 1; |
691 | } | 701 | } |
@@ -944,6 +954,14 @@ static int receive_flow_control(struct nozomi *dc) | |||
944 | case CTRL_APP2: | 954 | case CTRL_APP2: |
945 | port = PORT_APP2; | 955 | port = PORT_APP2; |
946 | enable_ier = APP2_DL; | 956 | enable_ier = APP2_DL; |
957 | if (dc->state == NOZOMI_STATE_ALLOCATED) { | ||
958 | /* | ||
959 | * After card initialization the flow control | ||
960 | * received for APP2 is always the last | ||
961 | */ | ||
962 | dc->state = NOZOMI_STATE_READY; | ||
963 | dev_info(&dc->pdev->dev, "Device READY!\n"); | ||
964 | } | ||
947 | break; | 965 | break; |
948 | default: | 966 | default: |
949 | dev_err(&dc->pdev->dev, | 967 | dev_err(&dc->pdev->dev, |
@@ -1366,22 +1384,12 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1366 | 1384 | ||
1367 | dc->pdev = pdev; | 1385 | dc->pdev = pdev; |
1368 | 1386 | ||
1369 | /* Find out what card type it is */ | ||
1370 | nozomi_get_card_type(dc); | ||
1371 | |||
1372 | ret = pci_enable_device(dc->pdev); | 1387 | ret = pci_enable_device(dc->pdev); |
1373 | if (ret) { | 1388 | if (ret) { |
1374 | dev_err(&pdev->dev, "Failed to enable PCI Device\n"); | 1389 | dev_err(&pdev->dev, "Failed to enable PCI Device\n"); |
1375 | goto err_free; | 1390 | goto err_free; |
1376 | } | 1391 | } |
1377 | 1392 | ||
1378 | start = pci_resource_start(dc->pdev, 0); | ||
1379 | if (start == 0) { | ||
1380 | dev_err(&pdev->dev, "No I/O address for card detected\n"); | ||
1381 | ret = -ENODEV; | ||
1382 | goto err_disable_device; | ||
1383 | } | ||
1384 | |||
1385 | ret = pci_request_regions(dc->pdev, NOZOMI_NAME); | 1393 | ret = pci_request_regions(dc->pdev, NOZOMI_NAME); |
1386 | if (ret) { | 1394 | if (ret) { |
1387 | dev_err(&pdev->dev, "I/O address 0x%04x already in use\n", | 1395 | dev_err(&pdev->dev, "I/O address 0x%04x already in use\n", |
@@ -1389,6 +1397,16 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1389 | goto err_disable_device; | 1397 | goto err_disable_device; |
1390 | } | 1398 | } |
1391 | 1399 | ||
1400 | start = pci_resource_start(dc->pdev, 0); | ||
1401 | if (start == 0) { | ||
1402 | dev_err(&pdev->dev, "No I/O address for card detected\n"); | ||
1403 | ret = -ENODEV; | ||
1404 | goto err_rel_regs; | ||
1405 | } | ||
1406 | |||
1407 | /* Find out what card type it is */ | ||
1408 | nozomi_get_card_type(dc); | ||
1409 | |||
1392 | dc->base_addr = ioremap(start, dc->card_type); | 1410 | dc->base_addr = ioremap(start, dc->card_type); |
1393 | if (!dc->base_addr) { | 1411 | if (!dc->base_addr) { |
1394 | dev_err(&pdev->dev, "Unable to map card MMIO\n"); | 1412 | dev_err(&pdev->dev, "Unable to map card MMIO\n"); |
@@ -1425,6 +1443,14 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1425 | dc->index_start = ndev_idx * MAX_PORT; | 1443 | dc->index_start = ndev_idx * MAX_PORT; |
1426 | ndevs[ndev_idx] = dc; | 1444 | ndevs[ndev_idx] = dc; |
1427 | 1445 | ||
1446 | pci_set_drvdata(pdev, dc); | ||
1447 | |||
1448 | /* Enable RESET interrupt */ | ||
1449 | dc->last_ier = RESET; | ||
1450 | iowrite16(dc->last_ier, dc->reg_ier); | ||
1451 | |||
1452 | dc->state = NOZOMI_STATE_ENABLED; | ||
1453 | |||
1428 | for (i = 0; i < MAX_PORT; i++) { | 1454 | for (i = 0; i < MAX_PORT; i++) { |
1429 | mutex_init(&dc->port[i].tty_sem); | 1455 | mutex_init(&dc->port[i].tty_sem); |
1430 | dc->port[i].tty_open_count = 0; | 1456 | dc->port[i].tty_open_count = 0; |
@@ -1433,12 +1459,6 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1433 | &pdev->dev); | 1459 | &pdev->dev); |
1434 | } | 1460 | } |
1435 | 1461 | ||
1436 | /* Enable RESET interrupt. */ | ||
1437 | dc->last_ier = RESET; | ||
1438 | writew(dc->last_ier, dc->reg_ier); | ||
1439 | |||
1440 | pci_set_drvdata(pdev, dc); | ||
1441 | |||
1442 | return 0; | 1462 | return 0; |
1443 | 1463 | ||
1444 | err_free_sbuf: | 1464 | err_free_sbuf: |
@@ -1553,7 +1573,7 @@ static int ntty_open(struct tty_struct *tty, struct file *file) | |||
1553 | struct nozomi *dc = get_dc_by_tty(tty); | 1573 | struct nozomi *dc = get_dc_by_tty(tty); |
1554 | unsigned long flags; | 1574 | unsigned long flags; |
1555 | 1575 | ||
1556 | if (!port || !dc) | 1576 | if (!port || !dc || dc->state != NOZOMI_STATE_READY) |
1557 | return -ENODEV; | 1577 | return -ENODEV; |
1558 | 1578 | ||
1559 | if (mutex_lock_interruptible(&port->tty_sem)) | 1579 | if (mutex_lock_interruptible(&port->tty_sem)) |
@@ -1716,6 +1736,10 @@ static int ntty_tiocmget(struct tty_struct *tty, struct file *file) | |||
1716 | static int ntty_tiocmset(struct tty_struct *tty, struct file *file, | 1736 | static int ntty_tiocmset(struct tty_struct *tty, struct file *file, |
1717 | unsigned int set, unsigned int clear) | 1737 | unsigned int set, unsigned int clear) |
1718 | { | 1738 | { |
1739 | struct nozomi *dc = get_dc_by_tty(tty); | ||
1740 | unsigned long flags; | ||
1741 | |||
1742 | spin_lock_irqsave(&dc->spin_mutex, flags); | ||
1719 | if (set & TIOCM_RTS) | 1743 | if (set & TIOCM_RTS) |
1720 | set_rts(tty, 1); | 1744 | set_rts(tty, 1); |
1721 | else if (clear & TIOCM_RTS) | 1745 | else if (clear & TIOCM_RTS) |
@@ -1725,6 +1749,7 @@ static int ntty_tiocmset(struct tty_struct *tty, struct file *file, | |||
1725 | set_dtr(tty, 1); | 1749 | set_dtr(tty, 1); |
1726 | else if (clear & TIOCM_DTR) | 1750 | else if (clear & TIOCM_DTR) |
1727 | set_dtr(tty, 0); | 1751 | set_dtr(tty, 0); |
1752 | spin_unlock_irqrestore(&dc->spin_mutex, flags); | ||
1728 | 1753 | ||
1729 | return 0; | 1754 | return 0; |
1730 | } | 1755 | } |
@@ -1762,7 +1787,7 @@ static int ntty_ioctl_tiocgicount(struct port *port, void __user *argp) | |||
1762 | icount.brk = cnow.brk; | 1787 | icount.brk = cnow.brk; |
1763 | icount.buf_overrun = cnow.buf_overrun; | 1788 | icount.buf_overrun = cnow.buf_overrun; |
1764 | 1789 | ||
1765 | return copy_to_user(argp, &icount, sizeof(icount)); | 1790 | return copy_to_user(argp, &icount, sizeof(icount)) ? -EFAULT : 0; |
1766 | } | 1791 | } |
1767 | 1792 | ||
1768 | static int ntty_ioctl(struct tty_struct *tty, struct file *file, | 1793 | static int ntty_ioctl(struct tty_struct *tty, struct file *file, |
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 8fc4fe4e38f1..589ac6f65b9a 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -1620,14 +1620,8 @@ static int __init rc_init_drivers(void) | |||
1620 | 1620 | ||
1621 | static void rc_release_drivers(void) | 1621 | static void rc_release_drivers(void) |
1622 | { | 1622 | { |
1623 | unsigned long flags; | ||
1624 | |||
1625 | spin_lock_irqsave(&riscom_lock, flags); | ||
1626 | |||
1627 | tty_unregister_driver(riscom_driver); | 1623 | tty_unregister_driver(riscom_driver); |
1628 | put_tty_driver(riscom_driver); | 1624 | put_tty_driver(riscom_driver); |
1629 | |||
1630 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1631 | } | 1625 | } |
1632 | 1626 | ||
1633 | #ifndef MODULE | 1627 | #ifndef MODULE |
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 92583cd4bffd..6e72fd31184d 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c | |||
@@ -184,6 +184,7 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) | |||
184 | gc->direction_output = pca953x_gpio_direction_output; | 184 | gc->direction_output = pca953x_gpio_direction_output; |
185 | gc->get = pca953x_gpio_get_value; | 185 | gc->get = pca953x_gpio_get_value; |
186 | gc->set = pca953x_gpio_set_value; | 186 | gc->set = pca953x_gpio_set_value; |
187 | gc->can_sleep = 1; | ||
187 | 188 | ||
188 | gc->base = chip->gpio_start; | 189 | gc->base = chip->gpio_start; |
189 | gc->ngpio = gpios; | 190 | gc->ngpio = gpios; |
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index b10ade92efed..4df405157086 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
@@ -3759,6 +3759,7 @@ static void cm_remove_one(struct ib_device *device) | |||
3759 | port = cm_dev->port[i-1]; | 3759 | port = cm_dev->port[i-1]; |
3760 | ib_modify_port(device, port->port_num, 0, &port_modify); | 3760 | ib_modify_port(device, port->port_num, 0, &port_modify); |
3761 | ib_unregister_mad_agent(port->mad_agent); | 3761 | ib_unregister_mad_agent(port->mad_agent); |
3762 | flush_workqueue(cm.wq); | ||
3762 | cm_remove_port_fs(port); | 3763 | cm_remove_port_fs(port); |
3763 | } | 3764 | } |
3764 | kobject_put(&cm_dev->dev_obj); | 3765 | kobject_put(&cm_dev->dev_obj); |
@@ -3813,6 +3814,7 @@ static void __exit ib_cm_cleanup(void) | |||
3813 | cancel_delayed_work(&timewait_info->work.work); | 3814 | cancel_delayed_work(&timewait_info->work.work); |
3814 | spin_unlock_irq(&cm.lock); | 3815 | spin_unlock_irq(&cm.lock); |
3815 | 3816 | ||
3817 | ib_unregister_client(&cm_client); | ||
3816 | destroy_workqueue(cm.wq); | 3818 | destroy_workqueue(cm.wq); |
3817 | 3819 | ||
3818 | list_for_each_entry_safe(timewait_info, tmp, &cm.timewait_list, list) { | 3820 | list_for_each_entry_safe(timewait_info, tmp, &cm.timewait_list, list) { |
@@ -3820,7 +3822,6 @@ static void __exit ib_cm_cleanup(void) | |||
3820 | kfree(timewait_info); | 3822 | kfree(timewait_info); |
3821 | } | 3823 | } |
3822 | 3824 | ||
3823 | ib_unregister_client(&cm_client); | ||
3824 | class_unregister(&cm_class); | 3825 | class_unregister(&cm_class); |
3825 | idr_destroy(&cm.local_id_table); | 3826 | idr_destroy(&cm.local_id_table); |
3826 | } | 3827 | } |
diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c index 7f00347364f7..06d502c06a4d 100644 --- a/drivers/infiniband/core/fmr_pool.c +++ b/drivers/infiniband/core/fmr_pool.c | |||
@@ -139,7 +139,7 @@ static inline struct ib_pool_fmr *ib_fmr_cache_lookup(struct ib_fmr_pool *pool, | |||
139 | static void ib_fmr_batch_release(struct ib_fmr_pool *pool) | 139 | static void ib_fmr_batch_release(struct ib_fmr_pool *pool) |
140 | { | 140 | { |
141 | int ret; | 141 | int ret; |
142 | struct ib_pool_fmr *fmr, *next; | 142 | struct ib_pool_fmr *fmr; |
143 | LIST_HEAD(unmap_list); | 143 | LIST_HEAD(unmap_list); |
144 | LIST_HEAD(fmr_list); | 144 | LIST_HEAD(fmr_list); |
145 | 145 | ||
@@ -158,20 +158,6 @@ static void ib_fmr_batch_release(struct ib_fmr_pool *pool) | |||
158 | #endif | 158 | #endif |
159 | } | 159 | } |
160 | 160 | ||
161 | /* | ||
162 | * The free_list may hold FMRs that have been put there | ||
163 | * because they haven't reached the max_remap count. | ||
164 | * Invalidate their mapping as well. | ||
165 | */ | ||
166 | list_for_each_entry_safe(fmr, next, &pool->free_list, list) { | ||
167 | if (fmr->remap_count == 0) | ||
168 | continue; | ||
169 | hlist_del_init(&fmr->cache_node); | ||
170 | fmr->remap_count = 0; | ||
171 | list_add_tail(&fmr->fmr->list, &fmr_list); | ||
172 | list_move(&fmr->list, &unmap_list); | ||
173 | } | ||
174 | |||
175 | list_splice(&pool->dirty_list, &unmap_list); | 161 | list_splice(&pool->dirty_list, &unmap_list); |
176 | INIT_LIST_HEAD(&pool->dirty_list); | 162 | INIT_LIST_HEAD(&pool->dirty_list); |
177 | pool->dirty_len = 0; | 163 | pool->dirty_len = 0; |
@@ -384,6 +370,11 @@ void ib_destroy_fmr_pool(struct ib_fmr_pool *pool) | |||
384 | 370 | ||
385 | i = 0; | 371 | i = 0; |
386 | list_for_each_entry_safe(fmr, tmp, &pool->free_list, list) { | 372 | list_for_each_entry_safe(fmr, tmp, &pool->free_list, list) { |
373 | if (fmr->remap_count) { | ||
374 | INIT_LIST_HEAD(&fmr_list); | ||
375 | list_add_tail(&fmr->fmr->list, &fmr_list); | ||
376 | ib_unmap_fmr(&fmr_list); | ||
377 | } | ||
387 | ib_dealloc_fmr(fmr->fmr); | 378 | ib_dealloc_fmr(fmr->fmr); |
388 | list_del(&fmr->list); | 379 | list_del(&fmr->list); |
389 | kfree(fmr); | 380 | kfree(fmr); |
@@ -407,8 +398,23 @@ EXPORT_SYMBOL(ib_destroy_fmr_pool); | |||
407 | */ | 398 | */ |
408 | int ib_flush_fmr_pool(struct ib_fmr_pool *pool) | 399 | int ib_flush_fmr_pool(struct ib_fmr_pool *pool) |
409 | { | 400 | { |
410 | int serial = atomic_inc_return(&pool->req_ser); | 401 | int serial; |
402 | struct ib_pool_fmr *fmr, *next; | ||
403 | |||
404 | /* | ||
405 | * The free_list holds FMRs that may have been used | ||
406 | * but have not been remapped enough times to be dirty. | ||
407 | * Put them on the dirty list now so that the cleanup | ||
408 | * thread will reap them too. | ||
409 | */ | ||
410 | spin_lock_irq(&pool->pool_lock); | ||
411 | list_for_each_entry_safe(fmr, next, &pool->free_list, list) { | ||
412 | if (fmr->remap_count > 0) | ||
413 | list_move(&fmr->list, &pool->dirty_list); | ||
414 | } | ||
415 | spin_unlock_irq(&pool->pool_lock); | ||
411 | 416 | ||
417 | serial = atomic_inc_return(&pool->req_ser); | ||
412 | wake_up_process(pool->thread); | 418 | wake_up_process(pool->thread); |
413 | 419 | ||
414 | if (wait_event_interruptible(pool->force_wait, | 420 | if (wait_event_interruptible(pool->force_wait, |
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c index 223b1aa7d92b..81c9195b512a 100644 --- a/drivers/infiniband/core/iwcm.c +++ b/drivers/infiniband/core/iwcm.c | |||
@@ -839,6 +839,7 @@ static void cm_work_handler(struct work_struct *_work) | |||
839 | unsigned long flags; | 839 | unsigned long flags; |
840 | int empty; | 840 | int empty; |
841 | int ret = 0; | 841 | int ret = 0; |
842 | int destroy_id; | ||
842 | 843 | ||
843 | spin_lock_irqsave(&cm_id_priv->lock, flags); | 844 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
844 | empty = list_empty(&cm_id_priv->work_list); | 845 | empty = list_empty(&cm_id_priv->work_list); |
@@ -857,9 +858,9 @@ static void cm_work_handler(struct work_struct *_work) | |||
857 | destroy_cm_id(&cm_id_priv->id); | 858 | destroy_cm_id(&cm_id_priv->id); |
858 | } | 859 | } |
859 | BUG_ON(atomic_read(&cm_id_priv->refcount)==0); | 860 | BUG_ON(atomic_read(&cm_id_priv->refcount)==0); |
861 | destroy_id = test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags); | ||
860 | if (iwcm_deref_id(cm_id_priv)) { | 862 | if (iwcm_deref_id(cm_id_priv)) { |
861 | if (test_bit(IWCM_F_CALLBACK_DESTROY, | 863 | if (destroy_id) { |
862 | &cm_id_priv->flags)) { | ||
863 | BUG_ON(!list_empty(&cm_id_priv->work_list)); | 864 | BUG_ON(!list_empty(&cm_id_priv->work_list)); |
864 | free_cm_id(cm_id_priv); | 865 | free_cm_id(cm_id_priv); |
865 | } | 866 | } |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index df1838f8f94d..b2ea9210467f 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c | |||
@@ -189,7 +189,7 @@ static struct ib_cq *iwch_create_cq(struct ib_device *ibdev, int entries, int ve | |||
189 | return ERR_PTR(-ENOMEM); | 189 | return ERR_PTR(-ENOMEM); |
190 | } | 190 | } |
191 | chp->rhp = rhp; | 191 | chp->rhp = rhp; |
192 | chp->ibcq.cqe = (1 << chp->cq.size_log2) - 1; | 192 | chp->ibcq.cqe = 1 << chp->cq.size_log2; |
193 | spin_lock_init(&chp->lock); | 193 | spin_lock_init(&chp->lock); |
194 | atomic_set(&chp->refcnt, 1); | 194 | atomic_set(&chp->refcnt, 1); |
195 | init_waitqueue_head(&chp->wait); | 195 | init_waitqueue_head(&chp->wait); |
@@ -819,8 +819,11 @@ static struct ib_qp *iwch_create_qp(struct ib_pd *pd, | |||
819 | kfree(qhp); | 819 | kfree(qhp); |
820 | return ERR_PTR(-ENOMEM); | 820 | return ERR_PTR(-ENOMEM); |
821 | } | 821 | } |
822 | |||
822 | attrs->cap.max_recv_wr = rqsize - 1; | 823 | attrs->cap.max_recv_wr = rqsize - 1; |
823 | attrs->cap.max_send_wr = sqsize; | 824 | attrs->cap.max_send_wr = sqsize; |
825 | attrs->cap.max_inline_data = T3_MAX_INLINE; | ||
826 | |||
824 | qhp->rhp = rhp; | 827 | qhp->rhp = rhp; |
825 | qhp->attr.pd = php->pdid; | 828 | qhp->attr.pd = php->pdid; |
826 | qhp->attr.scq = ((struct iwch_cq *) attrs->send_cq)->cq.cqid; | 829 | qhp->attr.scq = ((struct iwch_cq *) attrs->send_cq)->cq.cqid; |
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 714b8db02b29..993f0a8ff28f 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c | |||
@@ -237,36 +237,32 @@ static int iser_free_ib_conn_res(struct iser_conn *ib_conn) | |||
237 | static | 237 | static |
238 | struct iser_device *iser_device_find_by_ib_device(struct rdma_cm_id *cma_id) | 238 | struct iser_device *iser_device_find_by_ib_device(struct rdma_cm_id *cma_id) |
239 | { | 239 | { |
240 | struct list_head *p_list; | 240 | struct iser_device *device; |
241 | struct iser_device *device = NULL; | ||
242 | 241 | ||
243 | mutex_lock(&ig.device_list_mutex); | 242 | mutex_lock(&ig.device_list_mutex); |
244 | 243 | ||
245 | p_list = ig.device_list.next; | 244 | list_for_each_entry(device, &ig.device_list, ig_list) |
246 | while (p_list != &ig.device_list) { | ||
247 | device = list_entry(p_list, struct iser_device, ig_list); | ||
248 | /* find if there's a match using the node GUID */ | 245 | /* find if there's a match using the node GUID */ |
249 | if (device->ib_device->node_guid == cma_id->device->node_guid) | 246 | if (device->ib_device->node_guid == cma_id->device->node_guid) |
250 | break; | 247 | goto inc_refcnt; |
251 | } | ||
252 | 248 | ||
253 | if (device == NULL) { | 249 | device = kzalloc(sizeof *device, GFP_KERNEL); |
254 | device = kzalloc(sizeof *device, GFP_KERNEL); | 250 | if (device == NULL) |
255 | if (device == NULL) | 251 | goto out; |
256 | goto out; | 252 | |
257 | /* assign this device to the device */ | 253 | /* assign this device to the device */ |
258 | device->ib_device = cma_id->device; | 254 | device->ib_device = cma_id->device; |
259 | /* init the device and link it into ig device list */ | 255 | /* init the device and link it into ig device list */ |
260 | if (iser_create_device_ib_res(device)) { | 256 | if (iser_create_device_ib_res(device)) { |
261 | kfree(device); | 257 | kfree(device); |
262 | device = NULL; | 258 | device = NULL; |
263 | goto out; | 259 | goto out; |
264 | } | ||
265 | list_add(&device->ig_list, &ig.device_list); | ||
266 | } | 260 | } |
267 | out: | 261 | list_add(&device->ig_list, &ig.device_list); |
268 | BUG_ON(device == NULL); | 262 | |
263 | inc_refcnt: | ||
269 | device->refcount++; | 264 | device->refcount++; |
265 | out: | ||
270 | mutex_unlock(&ig.device_list_mutex); | 266 | mutex_unlock(&ig.device_list_mutex); |
271 | return device; | 267 | return device; |
272 | } | 268 | } |
@@ -372,6 +368,12 @@ static void iser_addr_handler(struct rdma_cm_id *cma_id) | |||
372 | int ret; | 368 | int ret; |
373 | 369 | ||
374 | device = iser_device_find_by_ib_device(cma_id); | 370 | device = iser_device_find_by_ib_device(cma_id); |
371 | if (!device) { | ||
372 | iser_err("device lookup/creation failed\n"); | ||
373 | iser_connect_error(cma_id); | ||
374 | return; | ||
375 | } | ||
376 | |||
375 | ib_conn = (struct iser_conn *)cma_id->context; | 377 | ib_conn = (struct iser_conn *)cma_id->context; |
376 | ib_conn->device = device; | 378 | ib_conn->device = device; |
377 | 379 | ||
@@ -380,7 +382,6 @@ static void iser_addr_handler(struct rdma_cm_id *cma_id) | |||
380 | iser_err("resolve route failed: %d\n", ret); | 382 | iser_err("resolve route failed: %d\n", ret); |
381 | iser_connect_error(cma_id); | 383 | iser_connect_error(cma_id); |
382 | } | 384 | } |
383 | return; | ||
384 | } | 385 | } |
385 | 386 | ||
386 | static void iser_route_handler(struct rdma_cm_id *cma_id) | 387 | static void iser_route_handler(struct rdma_cm_id *cma_id) |
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h index dd22d91f8b39..c972e5d03a3f 100644 --- a/drivers/input/serio/i8042.h +++ b/drivers/input/serio/i8042.h | |||
@@ -16,7 +16,7 @@ | |||
16 | 16 | ||
17 | #if defined(CONFIG_MACH_JAZZ) | 17 | #if defined(CONFIG_MACH_JAZZ) |
18 | #include "i8042-jazzio.h" | 18 | #include "i8042-jazzio.h" |
19 | #elif defined(CONFIG_SGI_IP22) | 19 | #elif defined(CONFIG_SGI_HAS_I8042) |
20 | #include "i8042-ip22io.h" | 20 | #include "i8042-ip22io.h" |
21 | #elif defined(CONFIG_PPC) | 21 | #elif defined(CONFIG_PPC) |
22 | #include "i8042-ppcio.h" | 22 | #include "i8042-ppcio.h" |
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c index 7743d73768df..c632c08cbbdc 100644 --- a/drivers/lguest/core.c +++ b/drivers/lguest/core.c | |||
@@ -69,11 +69,22 @@ static __init int map_switcher(void) | |||
69 | switcher_page[i] = virt_to_page(addr); | 69 | switcher_page[i] = virt_to_page(addr); |
70 | } | 70 | } |
71 | 71 | ||
72 | /* First we check that the Switcher won't overlap the fixmap area at | ||
73 | * the top of memory. It's currently nowhere near, but it could have | ||
74 | * very strange effects if it ever happened. */ | ||
75 | if (SWITCHER_ADDR + (TOTAL_SWITCHER_PAGES+1)*PAGE_SIZE > FIXADDR_START){ | ||
76 | err = -ENOMEM; | ||
77 | printk("lguest: mapping switcher would thwack fixmap\n"); | ||
78 | goto free_pages; | ||
79 | } | ||
80 | |||
72 | /* Now we reserve the "virtual memory area" we want: 0xFFC00000 | 81 | /* Now we reserve the "virtual memory area" we want: 0xFFC00000 |
73 | * (SWITCHER_ADDR). We might not get it in theory, but in practice | 82 | * (SWITCHER_ADDR). We might not get it in theory, but in practice |
74 | * it's worked so far. */ | 83 | * it's worked so far. The end address needs +1 because __get_vm_area |
84 | * allocates an extra guard page, so we need space for that. */ | ||
75 | switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE, | 85 | switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE, |
76 | VM_ALLOC, SWITCHER_ADDR, VMALLOC_END); | 86 | VM_ALLOC, SWITCHER_ADDR, SWITCHER_ADDR |
87 | + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE); | ||
77 | if (!switcher_vma) { | 88 | if (!switcher_vma) { |
78 | err = -ENOMEM; | 89 | err = -ENOMEM; |
79 | printk("lguest: could not map switcher pages high\n"); | 90 | printk("lguest: could not map switcher pages high\n"); |
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c index 85d42d3d01a9..2221485b0773 100644 --- a/drivers/lguest/lguest_user.c +++ b/drivers/lguest/lguest_user.c | |||
@@ -241,15 +241,16 @@ static ssize_t write(struct file *file, const char __user *in, | |||
241 | cpu = &lg->cpus[cpu_id]; | 241 | cpu = &lg->cpus[cpu_id]; |
242 | if (!cpu) | 242 | if (!cpu) |
243 | return -EINVAL; | 243 | return -EINVAL; |
244 | } | ||
245 | 244 | ||
246 | /* Once the Guest is dead, all you can do is read() why it died. */ | 245 | /* Once the Guest is dead, you can only read() why it died. */ |
247 | if (lg && lg->dead) | 246 | if (lg->dead) |
248 | return -ENOENT; | 247 | return -ENOENT; |
249 | 248 | ||
250 | /* If you're not the task which owns the Guest, you can only break */ | 249 | /* If you're not the task which owns the Guest, all you can do |
251 | if (lg && current != cpu->tsk && req != LHREQ_BREAK) | 250 | * is break the Launcher out of running the Guest. */ |
252 | return -EPERM; | 251 | if (current != cpu->tsk && req != LHREQ_BREAK) |
252 | return -EPERM; | ||
253 | } | ||
253 | 254 | ||
254 | switch (req) { | 255 | switch (req) { |
255 | case LHREQ_INITIALIZE: | 256 | case LHREQ_INITIALIZE: |
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c index 275f23c2deb4..a7f64a9d67e0 100644 --- a/drivers/lguest/page_tables.c +++ b/drivers/lguest/page_tables.c | |||
@@ -391,7 +391,7 @@ static unsigned int find_pgdir(struct lguest *lg, unsigned long pgtable) | |||
391 | { | 391 | { |
392 | unsigned int i; | 392 | unsigned int i; |
393 | for (i = 0; i < ARRAY_SIZE(lg->pgdirs); i++) | 393 | for (i = 0; i < ARRAY_SIZE(lg->pgdirs); i++) |
394 | if (lg->pgdirs[i].gpgdir == pgtable) | 394 | if (lg->pgdirs[i].pgdir && lg->pgdirs[i].gpgdir == pgtable) |
395 | break; | 395 | break; |
396 | return i; | 396 | return i; |
397 | } | 397 | } |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 831aed9c56ff..c14dacdacfac 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -1045,7 +1045,8 @@ void bitmap_daemon_work(struct bitmap *bitmap) | |||
1045 | if (bitmap == NULL) | 1045 | if (bitmap == NULL) |
1046 | return; | 1046 | return; |
1047 | if (time_before(jiffies, bitmap->daemon_lastrun + bitmap->daemon_sleep*HZ)) | 1047 | if (time_before(jiffies, bitmap->daemon_lastrun + bitmap->daemon_sleep*HZ)) |
1048 | return; | 1048 | goto done; |
1049 | |||
1049 | bitmap->daemon_lastrun = jiffies; | 1050 | bitmap->daemon_lastrun = jiffies; |
1050 | if (bitmap->allclean) { | 1051 | if (bitmap->allclean) { |
1051 | bitmap->mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT; | 1052 | bitmap->mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT; |
@@ -1142,6 +1143,7 @@ void bitmap_daemon_work(struct bitmap *bitmap) | |||
1142 | } | 1143 | } |
1143 | } | 1144 | } |
1144 | 1145 | ||
1146 | done: | ||
1145 | if (bitmap->allclean == 0) | 1147 | if (bitmap->allclean == 0) |
1146 | bitmap->mddev->thread->timeout = bitmap->daemon_sleep * HZ; | 1148 | bitmap->mddev->thread->timeout = bitmap->daemon_sleep * HZ; |
1147 | } | 1149 | } |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 827824a9f3e9..ccbbf63727cc 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -5149,7 +5149,7 @@ static int md_seq_show(struct seq_file *seq, void *v) | |||
5149 | if (mddev->ro==1) | 5149 | if (mddev->ro==1) |
5150 | seq_printf(seq, " (read-only)"); | 5150 | seq_printf(seq, " (read-only)"); |
5151 | if (mddev->ro==2) | 5151 | if (mddev->ro==2) |
5152 | seq_printf(seq, "(auto-read-only)"); | 5152 | seq_printf(seq, " (auto-read-only)"); |
5153 | seq_printf(seq, " %s", mddev->pers->name); | 5153 | seq_printf(seq, " %s", mddev->pers->name); |
5154 | } | 5154 | } |
5155 | 5155 | ||
diff --git a/drivers/memstick/Kconfig b/drivers/memstick/Kconfig index 1093fdb07297..f0ca41c20323 100644 --- a/drivers/memstick/Kconfig +++ b/drivers/memstick/Kconfig | |||
@@ -8,7 +8,7 @@ menuconfig MEMSTICK | |||
8 | Sony MemoryStick is a proprietary storage/extension card protocol. | 8 | Sony MemoryStick is a proprietary storage/extension card protocol. |
9 | 9 | ||
10 | If you want MemoryStick support, you should say Y here and also | 10 | If you want MemoryStick support, you should say Y here and also |
11 | to the specific driver for your MMC interface. | 11 | to the specific driver for your MemoryStick interface. |
12 | 12 | ||
13 | if MEMSTICK | 13 | if MEMSTICK |
14 | 14 | ||
diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index bba467fe4bce..de80dba12f9b 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | 19 | ||
20 | #define DRIVER_NAME "memstick" | 20 | #define DRIVER_NAME "memstick" |
21 | #define DRIVER_VERSION "0.2" | ||
22 | 21 | ||
23 | static unsigned int cmd_retries = 3; | 22 | static unsigned int cmd_retries = 3; |
24 | module_param(cmd_retries, uint, 0644); | 23 | module_param(cmd_retries, uint, 0644); |
@@ -236,7 +235,7 @@ int memstick_next_req(struct memstick_host *host, struct memstick_request **mrq) | |||
236 | rc = host->card->next_request(host->card, mrq); | 235 | rc = host->card->next_request(host->card, mrq); |
237 | 236 | ||
238 | if (!rc) | 237 | if (!rc) |
239 | host->retries = cmd_retries; | 238 | host->retries = cmd_retries > 1 ? cmd_retries - 1 : 1; |
240 | else | 239 | else |
241 | *mrq = NULL; | 240 | *mrq = NULL; |
242 | 241 | ||
@@ -271,7 +270,7 @@ void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc, | |||
271 | mrq->data_dir = READ; | 270 | mrq->data_dir = READ; |
272 | 271 | ||
273 | mrq->sg = *sg; | 272 | mrq->sg = *sg; |
274 | mrq->io_type = MEMSTICK_IO_SG; | 273 | mrq->long_data = 1; |
275 | 274 | ||
276 | if (tpc == MS_TPC_SET_CMD || tpc == MS_TPC_EX_SET_CMD) | 275 | if (tpc == MS_TPC_SET_CMD || tpc == MS_TPC_EX_SET_CMD) |
277 | mrq->need_card_int = 1; | 276 | mrq->need_card_int = 1; |
@@ -306,7 +305,7 @@ void memstick_init_req(struct memstick_request *mrq, unsigned char tpc, | |||
306 | if (mrq->data_dir == WRITE) | 305 | if (mrq->data_dir == WRITE) |
307 | memcpy(mrq->data, buf, mrq->data_len); | 306 | memcpy(mrq->data, buf, mrq->data_len); |
308 | 307 | ||
309 | mrq->io_type = MEMSTICK_IO_VAL; | 308 | mrq->long_data = 0; |
310 | 309 | ||
311 | if (tpc == MS_TPC_SET_CMD || tpc == MS_TPC_EX_SET_CMD) | 310 | if (tpc == MS_TPC_SET_CMD || tpc == MS_TPC_EX_SET_CMD) |
312 | mrq->need_card_int = 1; | 311 | mrq->need_card_int = 1; |
@@ -561,6 +560,31 @@ void memstick_free_host(struct memstick_host *host) | |||
561 | } | 560 | } |
562 | EXPORT_SYMBOL(memstick_free_host); | 561 | EXPORT_SYMBOL(memstick_free_host); |
563 | 562 | ||
563 | /** | ||
564 | * memstick_suspend_host - notify bus driver of host suspension | ||
565 | * @host - host to use | ||
566 | */ | ||
567 | void memstick_suspend_host(struct memstick_host *host) | ||
568 | { | ||
569 | mutex_lock(&host->lock); | ||
570 | host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_OFF); | ||
571 | mutex_unlock(&host->lock); | ||
572 | } | ||
573 | EXPORT_SYMBOL(memstick_suspend_host); | ||
574 | |||
575 | /** | ||
576 | * memstick_resume_host - notify bus driver of host resumption | ||
577 | * @host - host to use | ||
578 | */ | ||
579 | void memstick_resume_host(struct memstick_host *host) | ||
580 | { | ||
581 | mutex_lock(&host->lock); | ||
582 | host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_ON); | ||
583 | mutex_unlock(&host->lock); | ||
584 | memstick_detect_change(host); | ||
585 | } | ||
586 | EXPORT_SYMBOL(memstick_resume_host); | ||
587 | |||
564 | int memstick_register_driver(struct memstick_driver *drv) | 588 | int memstick_register_driver(struct memstick_driver *drv) |
565 | { | 589 | { |
566 | drv->driver.bus = &memstick_bus_type; | 590 | drv->driver.bus = &memstick_bus_type; |
@@ -611,4 +635,3 @@ module_exit(memstick_exit); | |||
611 | MODULE_AUTHOR("Alex Dubov"); | 635 | MODULE_AUTHOR("Alex Dubov"); |
612 | MODULE_LICENSE("GPL"); | 636 | MODULE_LICENSE("GPL"); |
613 | MODULE_DESCRIPTION("Sony MemoryStick core driver"); | 637 | MODULE_DESCRIPTION("Sony MemoryStick core driver"); |
614 | MODULE_VERSION(DRIVER_VERSION); | ||
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index 423ad8cf4bb9..1d637e4561d3 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c | |||
@@ -16,10 +16,10 @@ | |||
16 | #include <linux/idr.h> | 16 | #include <linux/idr.h> |
17 | #include <linux/hdreg.h> | 17 | #include <linux/hdreg.h> |
18 | #include <linux/kthread.h> | 18 | #include <linux/kthread.h> |
19 | #include <linux/delay.h> | ||
19 | #include <linux/memstick.h> | 20 | #include <linux/memstick.h> |
20 | 21 | ||
21 | #define DRIVER_NAME "mspro_block" | 22 | #define DRIVER_NAME "mspro_block" |
22 | #define DRIVER_VERSION "0.2" | ||
23 | 23 | ||
24 | static int major; | 24 | static int major; |
25 | module_param(major, int, 0644); | 25 | module_param(major, int, 0644); |
@@ -110,6 +110,17 @@ struct mspro_mbr { | |||
110 | unsigned int sectors_per_partition; | 110 | unsigned int sectors_per_partition; |
111 | } __attribute__((packed)); | 111 | } __attribute__((packed)); |
112 | 112 | ||
113 | struct mspro_specfile { | ||
114 | char name[8]; | ||
115 | char ext[3]; | ||
116 | unsigned char attr; | ||
117 | unsigned char reserved[10]; | ||
118 | unsigned short time; | ||
119 | unsigned short date; | ||
120 | unsigned short cluster; | ||
121 | unsigned int size; | ||
122 | } __attribute__((packed)); | ||
123 | |||
113 | struct mspro_devinfo { | 124 | struct mspro_devinfo { |
114 | unsigned short cylinders; | 125 | unsigned short cylinders; |
115 | unsigned short heads; | 126 | unsigned short heads; |
@@ -293,6 +304,20 @@ static ssize_t mspro_block_attr_show_sysinfo(struct device *dev, | |||
293 | dev_attr); | 304 | dev_attr); |
294 | struct mspro_sys_info *x_sys = x_attr->data; | 305 | struct mspro_sys_info *x_sys = x_attr->data; |
295 | ssize_t rc = 0; | 306 | ssize_t rc = 0; |
307 | int date_tz = 0, date_tz_f = 0; | ||
308 | |||
309 | if (x_sys->assembly_date[0] > 0x80U) { | ||
310 | date_tz = (~x_sys->assembly_date[0]) + 1; | ||
311 | date_tz_f = date_tz & 3; | ||
312 | date_tz >>= 2; | ||
313 | date_tz = -date_tz; | ||
314 | date_tz_f *= 15; | ||
315 | } else if (x_sys->assembly_date[0] < 0x80U) { | ||
316 | date_tz = x_sys->assembly_date[0]; | ||
317 | date_tz_f = date_tz & 3; | ||
318 | date_tz >>= 2; | ||
319 | date_tz_f *= 15; | ||
320 | } | ||
296 | 321 | ||
297 | rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "class: %x\n", | 322 | rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "class: %x\n", |
298 | x_sys->class); | 323 | x_sys->class); |
@@ -305,8 +330,8 @@ static ssize_t mspro_block_attr_show_sysinfo(struct device *dev, | |||
305 | rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "page size: %x\n", | 330 | rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "page size: %x\n", |
306 | be16_to_cpu(x_sys->page_size)); | 331 | be16_to_cpu(x_sys->page_size)); |
307 | rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "assembly date: " | 332 | rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "assembly date: " |
308 | "%d %04u-%02u-%02u %02u:%02u:%02u\n", | 333 | "GMT%+d:%d %04u-%02u-%02u %02u:%02u:%02u\n", |
309 | x_sys->assembly_date[0], | 334 | date_tz, date_tz_f, |
310 | be16_to_cpu(*(unsigned short *) | 335 | be16_to_cpu(*(unsigned short *) |
311 | &x_sys->assembly_date[1]), | 336 | &x_sys->assembly_date[1]), |
312 | x_sys->assembly_date[3], x_sys->assembly_date[4], | 337 | x_sys->assembly_date[3], x_sys->assembly_date[4], |
@@ -398,6 +423,41 @@ static ssize_t mspro_block_attr_show_mbr(struct device *dev, | |||
398 | return rc; | 423 | return rc; |
399 | } | 424 | } |
400 | 425 | ||
426 | static ssize_t mspro_block_attr_show_specfile(struct device *dev, | ||
427 | struct device_attribute *attr, | ||
428 | char *buffer) | ||
429 | { | ||
430 | struct mspro_sys_attr *x_attr = container_of(attr, | ||
431 | struct mspro_sys_attr, | ||
432 | dev_attr); | ||
433 | struct mspro_specfile *x_spfile = x_attr->data; | ||
434 | char name[9], ext[4]; | ||
435 | ssize_t rc = 0; | ||
436 | |||
437 | memcpy(name, x_spfile->name, 8); | ||
438 | name[8] = 0; | ||
439 | memcpy(ext, x_spfile->ext, 3); | ||
440 | ext[3] = 0; | ||
441 | |||
442 | rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "name: %s\n", name); | ||
443 | rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "ext: %s\n", ext); | ||
444 | rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "attribute: %x\n", | ||
445 | x_spfile->attr); | ||
446 | rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "time: %d:%d:%d\n", | ||
447 | x_spfile->time >> 11, | ||
448 | (x_spfile->time >> 5) & 0x3f, | ||
449 | (x_spfile->time & 0x1f) * 2); | ||
450 | rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "date: %d-%d-%d\n", | ||
451 | (x_spfile->date >> 9) + 1980, | ||
452 | (x_spfile->date >> 5) & 0xf, | ||
453 | x_spfile->date & 0x1f); | ||
454 | rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "start cluster: %x\n", | ||
455 | x_spfile->cluster); | ||
456 | rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "size: %x\n", | ||
457 | x_spfile->size); | ||
458 | return rc; | ||
459 | } | ||
460 | |||
401 | static ssize_t mspro_block_attr_show_devinfo(struct device *dev, | 461 | static ssize_t mspro_block_attr_show_devinfo(struct device *dev, |
402 | struct device_attribute *attr, | 462 | struct device_attribute *attr, |
403 | char *buffer) | 463 | char *buffer) |
@@ -430,6 +490,9 @@ static sysfs_show_t mspro_block_attr_show(unsigned char tag) | |||
430 | return mspro_block_attr_show_modelname; | 490 | return mspro_block_attr_show_modelname; |
431 | case MSPRO_BLOCK_ID_MBR: | 491 | case MSPRO_BLOCK_ID_MBR: |
432 | return mspro_block_attr_show_mbr; | 492 | return mspro_block_attr_show_mbr; |
493 | case MSPRO_BLOCK_ID_SPECFILEVALUES1: | ||
494 | case MSPRO_BLOCK_ID_SPECFILEVALUES2: | ||
495 | return mspro_block_attr_show_specfile; | ||
433 | case MSPRO_BLOCK_ID_DEVINFO: | 496 | case MSPRO_BLOCK_ID_DEVINFO: |
434 | return mspro_block_attr_show_devinfo; | 497 | return mspro_block_attr_show_devinfo; |
435 | default: | 498 | default: |
@@ -629,7 +692,7 @@ static void mspro_block_process_request(struct memstick_dev *card, | |||
629 | param.system = msb->system; | 692 | param.system = msb->system; |
630 | param.data_count = cpu_to_be16(page_count); | 693 | param.data_count = cpu_to_be16(page_count); |
631 | param.data_address = cpu_to_be32((uint32_t)t_sec); | 694 | param.data_address = cpu_to_be32((uint32_t)t_sec); |
632 | param.cmd_param = 0; | 695 | param.tpc_param = 0; |
633 | 696 | ||
634 | msb->data_dir = rq_data_dir(req); | 697 | msb->data_dir = rq_data_dir(req); |
635 | msb->transfer_cmd = msb->data_dir == READ | 698 | msb->transfer_cmd = msb->data_dir == READ |
@@ -758,10 +821,10 @@ static int mspro_block_switch_to_parallel(struct memstick_dev *card) | |||
758 | struct memstick_host *host = card->host; | 821 | struct memstick_host *host = card->host; |
759 | struct mspro_block_data *msb = memstick_get_drvdata(card); | 822 | struct mspro_block_data *msb = memstick_get_drvdata(card); |
760 | struct mspro_param_register param = { | 823 | struct mspro_param_register param = { |
761 | .system = 0, | 824 | .system = MEMSTICK_SYS_PAR4, |
762 | .data_count = 0, | 825 | .data_count = 0, |
763 | .data_address = 0, | 826 | .data_address = 0, |
764 | .cmd_param = 0 | 827 | .tpc_param = 0 |
765 | }; | 828 | }; |
766 | 829 | ||
767 | card->next_request = h_mspro_block_req_init; | 830 | card->next_request = h_mspro_block_req_init; |
@@ -773,8 +836,8 @@ static int mspro_block_switch_to_parallel(struct memstick_dev *card) | |||
773 | if (card->current_mrq.error) | 836 | if (card->current_mrq.error) |
774 | return card->current_mrq.error; | 837 | return card->current_mrq.error; |
775 | 838 | ||
776 | msb->system = 0; | 839 | msb->system = MEMSTICK_SYS_PAR4; |
777 | host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_PARALLEL); | 840 | host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_PAR4); |
778 | 841 | ||
779 | card->next_request = h_mspro_block_req_init; | 842 | card->next_request = h_mspro_block_req_init; |
780 | msb->mrq_handler = h_mspro_block_default; | 843 | msb->mrq_handler = h_mspro_block_default; |
@@ -783,8 +846,24 @@ static int mspro_block_switch_to_parallel(struct memstick_dev *card) | |||
783 | wait_for_completion(&card->mrq_complete); | 846 | wait_for_completion(&card->mrq_complete); |
784 | 847 | ||
785 | if (card->current_mrq.error) { | 848 | if (card->current_mrq.error) { |
786 | msb->system = 0x80; | 849 | msb->system = MEMSTICK_SYS_SERIAL; |
850 | host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_OFF); | ||
851 | msleep(1000); | ||
852 | host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_ON); | ||
787 | host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_SERIAL); | 853 | host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_SERIAL); |
854 | |||
855 | if (memstick_set_rw_addr(card)) | ||
856 | return card->current_mrq.error; | ||
857 | |||
858 | param.system = msb->system; | ||
859 | |||
860 | card->next_request = h_mspro_block_req_init; | ||
861 | msb->mrq_handler = h_mspro_block_default; | ||
862 | memstick_init_req(&card->current_mrq, MS_TPC_WRITE_REG, ¶m, | ||
863 | sizeof(param)); | ||
864 | memstick_new_req(host); | ||
865 | wait_for_completion(&card->mrq_complete); | ||
866 | |||
788 | return -EFAULT; | 867 | return -EFAULT; |
789 | } | 868 | } |
790 | 869 | ||
@@ -802,7 +881,7 @@ static int mspro_block_read_attributes(struct memstick_dev *card) | |||
802 | .system = msb->system, | 881 | .system = msb->system, |
803 | .data_count = cpu_to_be16(1), | 882 | .data_count = cpu_to_be16(1), |
804 | .data_address = 0, | 883 | .data_address = 0, |
805 | .cmd_param = 0 | 884 | .tpc_param = 0 |
806 | }; | 885 | }; |
807 | struct mspro_attribute *attr = NULL; | 886 | struct mspro_attribute *attr = NULL; |
808 | struct mspro_sys_attr *s_attr = NULL; | 887 | struct mspro_sys_attr *s_attr = NULL; |
@@ -922,7 +1001,7 @@ static int mspro_block_read_attributes(struct memstick_dev *card) | |||
922 | param.system = msb->system; | 1001 | param.system = msb->system; |
923 | param.data_count = cpu_to_be16((rc / msb->page_size) + 1); | 1002 | param.data_count = cpu_to_be16((rc / msb->page_size) + 1); |
924 | param.data_address = cpu_to_be32(addr / msb->page_size); | 1003 | param.data_address = cpu_to_be32(addr / msb->page_size); |
925 | param.cmd_param = 0; | 1004 | param.tpc_param = 0; |
926 | 1005 | ||
927 | sg_init_one(&msb->req_sg[0], buffer, | 1006 | sg_init_one(&msb->req_sg[0], buffer, |
928 | be16_to_cpu(param.data_count) * msb->page_size); | 1007 | be16_to_cpu(param.data_count) * msb->page_size); |
@@ -964,7 +1043,7 @@ static int mspro_block_init_card(struct memstick_dev *card) | |||
964 | struct memstick_host *host = card->host; | 1043 | struct memstick_host *host = card->host; |
965 | int rc = 0; | 1044 | int rc = 0; |
966 | 1045 | ||
967 | msb->system = 0x80; | 1046 | msb->system = MEMSTICK_SYS_SERIAL; |
968 | card->reg_addr.r_offset = offsetof(struct mspro_register, status); | 1047 | card->reg_addr.r_offset = offsetof(struct mspro_register, status); |
969 | card->reg_addr.r_length = sizeof(struct ms_status_register); | 1048 | card->reg_addr.r_length = sizeof(struct ms_status_register); |
970 | card->reg_addr.w_offset = offsetof(struct mspro_register, param); | 1049 | card->reg_addr.w_offset = offsetof(struct mspro_register, param); |
@@ -973,7 +1052,7 @@ static int mspro_block_init_card(struct memstick_dev *card) | |||
973 | if (memstick_set_rw_addr(card)) | 1052 | if (memstick_set_rw_addr(card)) |
974 | return -EIO; | 1053 | return -EIO; |
975 | 1054 | ||
976 | if (host->caps & MEMSTICK_CAP_PARALLEL) { | 1055 | if (host->caps & MEMSTICK_CAP_PAR4) { |
977 | if (mspro_block_switch_to_parallel(card)) | 1056 | if (mspro_block_switch_to_parallel(card)) |
978 | printk(KERN_WARNING "%s: could not switch to " | 1057 | printk(KERN_WARNING "%s: could not switch to " |
979 | "parallel interface\n", card->dev.bus_id); | 1058 | "parallel interface\n", card->dev.bus_id); |
@@ -1348,4 +1427,3 @@ MODULE_LICENSE("GPL"); | |||
1348 | MODULE_AUTHOR("Alex Dubov"); | 1427 | MODULE_AUTHOR("Alex Dubov"); |
1349 | MODULE_DESCRIPTION("Sony MemoryStickPro block device driver"); | 1428 | MODULE_DESCRIPTION("Sony MemoryStickPro block device driver"); |
1350 | MODULE_DEVICE_TABLE(memstick, mspro_block_id_tbl); | 1429 | MODULE_DEVICE_TABLE(memstick, mspro_block_id_tbl); |
1351 | MODULE_VERSION(DRIVER_VERSION); | ||
diff --git a/drivers/memstick/host/Kconfig b/drivers/memstick/host/Kconfig index c002fcc3c879..4ce5c8dffb68 100644 --- a/drivers/memstick/host/Kconfig +++ b/drivers/memstick/host/Kconfig | |||
@@ -20,3 +20,13 @@ config MEMSTICK_TIFM_MS | |||
20 | To compile this driver as a module, choose M here: the | 20 | To compile this driver as a module, choose M here: the |
21 | module will be called tifm_ms. | 21 | module will be called tifm_ms. |
22 | 22 | ||
23 | config MEMSTICK_JMICRON_38X | ||
24 | tristate "JMicron JMB38X MemoryStick interface support (EXPERIMENTAL)" | ||
25 | depends on EXPERIMENTAL && PCI | ||
26 | |||
27 | help | ||
28 | Say Y here if you want to be able to access MemoryStick cards with | ||
29 | the JMicron(R) JMB38X MemoryStick card reader. | ||
30 | |||
31 | To compile this driver as a module, choose M here: the | ||
32 | module will be called jmb38x_ms. | ||
diff --git a/drivers/memstick/host/Makefile b/drivers/memstick/host/Makefile index ee666380efa1..12530e4311d3 100644 --- a/drivers/memstick/host/Makefile +++ b/drivers/memstick/host/Makefile | |||
@@ -3,8 +3,8 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | ifeq ($(CONFIG_MEMSTICK_DEBUG),y) | 5 | ifeq ($(CONFIG_MEMSTICK_DEBUG),y) |
6 | EXTRA_CFLAGS += -DDEBUG | 6 | EXTRA_CFLAGS += -DDEBUG |
7 | endif | 7 | endif |
8 | 8 | ||
9 | obj-$(CONFIG_MEMSTICK_TIFM_MS) += tifm_ms.o | 9 | obj-$(CONFIG_MEMSTICK_TIFM_MS) += tifm_ms.o |
10 | 10 | obj-$(CONFIG_MEMSTICK_JMICRON_38X) += jmb38x_ms.o | |
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c new file mode 100644 index 000000000000..03fe8783b1ee --- /dev/null +++ b/drivers/memstick/host/jmb38x_ms.c | |||
@@ -0,0 +1,945 @@ | |||
1 | /* | ||
2 | * jmb38x_ms.c - JMicron jmb38x MemoryStick card reader | ||
3 | * | ||
4 | * Copyright (C) 2008 Alex Dubov <oakad@yahoo.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/spinlock.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/pci.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/highmem.h> | ||
17 | #include <linux/memstick.h> | ||
18 | |||
19 | #define DRIVER_NAME "jmb38x_ms" | ||
20 | |||
21 | static int no_dma; | ||
22 | module_param(no_dma, bool, 0644); | ||
23 | |||
24 | enum { | ||
25 | DMA_ADDRESS = 0x00, | ||
26 | BLOCK = 0x04, | ||
27 | DMA_CONTROL = 0x08, | ||
28 | TPC_P0 = 0x0c, | ||
29 | TPC_P1 = 0x10, | ||
30 | TPC = 0x14, | ||
31 | HOST_CONTROL = 0x18, | ||
32 | DATA = 0x1c, | ||
33 | STATUS = 0x20, | ||
34 | INT_STATUS = 0x24, | ||
35 | INT_STATUS_ENABLE = 0x28, | ||
36 | INT_SIGNAL_ENABLE = 0x2c, | ||
37 | TIMER = 0x30, | ||
38 | TIMER_CONTROL = 0x34, | ||
39 | PAD_OUTPUT_ENABLE = 0x38, | ||
40 | PAD_PU_PD = 0x3c, | ||
41 | CLOCK_DELAY = 0x40, | ||
42 | ADMA_ADDRESS = 0x44, | ||
43 | CLOCK_CONTROL = 0x48, | ||
44 | LED_CONTROL = 0x4c, | ||
45 | VERSION = 0x50 | ||
46 | }; | ||
47 | |||
48 | struct jmb38x_ms_host { | ||
49 | struct jmb38x_ms *chip; | ||
50 | void __iomem *addr; | ||
51 | spinlock_t lock; | ||
52 | int id; | ||
53 | char host_id[DEVICE_ID_SIZE]; | ||
54 | int irq; | ||
55 | unsigned int block_pos; | ||
56 | unsigned long timeout_jiffies; | ||
57 | struct timer_list timer; | ||
58 | struct memstick_request *req; | ||
59 | unsigned char eject:1, | ||
60 | use_dma:1; | ||
61 | unsigned char cmd_flags; | ||
62 | unsigned char io_pos; | ||
63 | unsigned int io_word[2]; | ||
64 | }; | ||
65 | |||
66 | struct jmb38x_ms { | ||
67 | struct pci_dev *pdev; | ||
68 | int host_cnt; | ||
69 | struct memstick_host *hosts[]; | ||
70 | }; | ||
71 | |||
72 | #define BLOCK_COUNT_MASK 0xffff0000 | ||
73 | #define BLOCK_SIZE_MASK 0x00000fff | ||
74 | |||
75 | #define DMA_CONTROL_ENABLE 0x00000001 | ||
76 | |||
77 | #define TPC_DATA_SEL 0x00008000 | ||
78 | #define TPC_DIR 0x00004000 | ||
79 | #define TPC_WAIT_INT 0x00002000 | ||
80 | #define TPC_GET_INT 0x00000800 | ||
81 | #define TPC_CODE_SZ_MASK 0x00000700 | ||
82 | #define TPC_DATA_SZ_MASK 0x00000007 | ||
83 | |||
84 | #define HOST_CONTROL_RESET_REQ 0x00008000 | ||
85 | #define HOST_CONTROL_REI 0x00004000 | ||
86 | #define HOST_CONTROL_LED 0x00000400 | ||
87 | #define HOST_CONTROL_FAST_CLK 0x00000200 | ||
88 | #define HOST_CONTROL_RESET 0x00000100 | ||
89 | #define HOST_CONTROL_POWER_EN 0x00000080 | ||
90 | #define HOST_CONTROL_CLOCK_EN 0x00000040 | ||
91 | #define HOST_CONTROL_IF_SHIFT 4 | ||
92 | |||
93 | #define HOST_CONTROL_IF_SERIAL 0x0 | ||
94 | #define HOST_CONTROL_IF_PAR4 0x1 | ||
95 | #define HOST_CONTROL_IF_PAR8 0x3 | ||
96 | |||
97 | #define STATUS_HAS_MEDIA 0x00000400 | ||
98 | #define STATUS_FIFO_EMPTY 0x00000200 | ||
99 | #define STATUS_FIFO_FULL 0x00000100 | ||
100 | |||
101 | #define INT_STATUS_TPC_ERR 0x00080000 | ||
102 | #define INT_STATUS_CRC_ERR 0x00040000 | ||
103 | #define INT_STATUS_TIMER_TO 0x00020000 | ||
104 | #define INT_STATUS_HSK_TO 0x00010000 | ||
105 | #define INT_STATUS_ANY_ERR 0x00008000 | ||
106 | #define INT_STATUS_FIFO_WRDY 0x00000080 | ||
107 | #define INT_STATUS_FIFO_RRDY 0x00000040 | ||
108 | #define INT_STATUS_MEDIA_OUT 0x00000010 | ||
109 | #define INT_STATUS_MEDIA_IN 0x00000008 | ||
110 | #define INT_STATUS_DMA_BOUNDARY 0x00000004 | ||
111 | #define INT_STATUS_EOTRAN 0x00000002 | ||
112 | #define INT_STATUS_EOTPC 0x00000001 | ||
113 | |||
114 | #define INT_STATUS_ALL 0x000f801f | ||
115 | |||
116 | #define PAD_OUTPUT_ENABLE_MS 0x0F3F | ||
117 | |||
118 | #define PAD_PU_PD_OFF 0x7FFF0000 | ||
119 | #define PAD_PU_PD_ON_MS_SOCK0 0x5f8f0000 | ||
120 | #define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000 | ||
121 | |||
122 | enum { | ||
123 | CMD_READY = 0x01, | ||
124 | FIFO_READY = 0x02, | ||
125 | REG_DATA = 0x04, | ||
126 | AUTO_GET_INT = 0x08 | ||
127 | }; | ||
128 | |||
129 | static unsigned int jmb38x_ms_read_data(struct jmb38x_ms_host *host, | ||
130 | unsigned char *buf, unsigned int length) | ||
131 | { | ||
132 | unsigned int off = 0; | ||
133 | |||
134 | while (host->io_pos && length) { | ||
135 | buf[off++] = host->io_word[0] & 0xff; | ||
136 | host->io_word[0] >>= 8; | ||
137 | length--; | ||
138 | host->io_pos--; | ||
139 | } | ||
140 | |||
141 | if (!length) | ||
142 | return off; | ||
143 | |||
144 | while (!(STATUS_FIFO_EMPTY & readl(host->addr + STATUS))) { | ||
145 | if (length < 4) | ||
146 | break; | ||
147 | *(unsigned int *)(buf + off) = __raw_readl(host->addr + DATA); | ||
148 | length -= 4; | ||
149 | off += 4; | ||
150 | } | ||
151 | |||
152 | if (length | ||
153 | && !(STATUS_FIFO_EMPTY & readl(host->addr + STATUS))) { | ||
154 | host->io_word[0] = readl(host->addr + DATA); | ||
155 | for (host->io_pos = 4; host->io_pos; --host->io_pos) { | ||
156 | buf[off++] = host->io_word[0] & 0xff; | ||
157 | host->io_word[0] >>= 8; | ||
158 | length--; | ||
159 | if (!length) | ||
160 | break; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | return off; | ||
165 | } | ||
166 | |||
167 | static unsigned int jmb38x_ms_read_reg_data(struct jmb38x_ms_host *host, | ||
168 | unsigned char *buf, | ||
169 | unsigned int length) | ||
170 | { | ||
171 | unsigned int off = 0; | ||
172 | |||
173 | while (host->io_pos > 4 && length) { | ||
174 | buf[off++] = host->io_word[0] & 0xff; | ||
175 | host->io_word[0] >>= 8; | ||
176 | length--; | ||
177 | host->io_pos--; | ||
178 | } | ||
179 | |||
180 | if (!length) | ||
181 | return off; | ||
182 | |||
183 | while (host->io_pos && length) { | ||
184 | buf[off++] = host->io_word[1] & 0xff; | ||
185 | host->io_word[1] >>= 8; | ||
186 | length--; | ||
187 | host->io_pos--; | ||
188 | } | ||
189 | |||
190 | return off; | ||
191 | } | ||
192 | |||
193 | static unsigned int jmb38x_ms_write_data(struct jmb38x_ms_host *host, | ||
194 | unsigned char *buf, | ||
195 | unsigned int length) | ||
196 | { | ||
197 | unsigned int off = 0; | ||
198 | |||
199 | if (host->io_pos) { | ||
200 | while (host->io_pos < 4 && length) { | ||
201 | host->io_word[0] |= buf[off++] << (host->io_pos * 8); | ||
202 | host->io_pos++; | ||
203 | length--; | ||
204 | } | ||
205 | } | ||
206 | |||
207 | if (host->io_pos == 4 | ||
208 | && !(STATUS_FIFO_FULL & readl(host->addr + STATUS))) { | ||
209 | writel(host->io_word[0], host->addr + DATA); | ||
210 | host->io_pos = 0; | ||
211 | host->io_word[0] = 0; | ||
212 | } else if (host->io_pos) { | ||
213 | return off; | ||
214 | } | ||
215 | |||
216 | if (!length) | ||
217 | return off; | ||
218 | |||
219 | while (!(STATUS_FIFO_FULL & readl(host->addr + STATUS))) { | ||
220 | if (length < 4) | ||
221 | break; | ||
222 | |||
223 | __raw_writel(*(unsigned int *)(buf + off), | ||
224 | host->addr + DATA); | ||
225 | length -= 4; | ||
226 | off += 4; | ||
227 | } | ||
228 | |||
229 | switch (length) { | ||
230 | case 3: | ||
231 | host->io_word[0] |= buf[off + 2] << 16; | ||
232 | host->io_pos++; | ||
233 | case 2: | ||
234 | host->io_word[0] |= buf[off + 1] << 8; | ||
235 | host->io_pos++; | ||
236 | case 1: | ||
237 | host->io_word[0] |= buf[off]; | ||
238 | host->io_pos++; | ||
239 | } | ||
240 | |||
241 | off += host->io_pos; | ||
242 | |||
243 | return off; | ||
244 | } | ||
245 | |||
246 | static unsigned int jmb38x_ms_write_reg_data(struct jmb38x_ms_host *host, | ||
247 | unsigned char *buf, | ||
248 | unsigned int length) | ||
249 | { | ||
250 | unsigned int off = 0; | ||
251 | |||
252 | while (host->io_pos < 4 && length) { | ||
253 | host->io_word[0] &= ~(0xff << (host->io_pos * 8)); | ||
254 | host->io_word[0] |= buf[off++] << (host->io_pos * 8); | ||
255 | host->io_pos++; | ||
256 | length--; | ||
257 | } | ||
258 | |||
259 | if (!length) | ||
260 | return off; | ||
261 | |||
262 | while (host->io_pos < 8 && length) { | ||
263 | host->io_word[1] &= ~(0xff << (host->io_pos * 8)); | ||
264 | host->io_word[1] |= buf[off++] << (host->io_pos * 8); | ||
265 | host->io_pos++; | ||
266 | length--; | ||
267 | } | ||
268 | |||
269 | return off; | ||
270 | } | ||
271 | |||
272 | static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host) | ||
273 | { | ||
274 | unsigned int length; | ||
275 | unsigned int off; | ||
276 | unsigned int t_size, p_off, p_cnt; | ||
277 | unsigned char *buf; | ||
278 | struct page *pg; | ||
279 | unsigned long flags = 0; | ||
280 | |||
281 | if (host->req->long_data) { | ||
282 | length = host->req->sg.length - host->block_pos; | ||
283 | off = host->req->sg.offset + host->block_pos; | ||
284 | } else { | ||
285 | length = host->req->data_len - host->block_pos; | ||
286 | off = 0; | ||
287 | } | ||
288 | |||
289 | while (length) { | ||
290 | if (host->req->long_data) { | ||
291 | pg = nth_page(sg_page(&host->req->sg), | ||
292 | off >> PAGE_SHIFT); | ||
293 | p_off = offset_in_page(off); | ||
294 | p_cnt = PAGE_SIZE - p_off; | ||
295 | p_cnt = min(p_cnt, length); | ||
296 | |||
297 | local_irq_save(flags); | ||
298 | buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + p_off; | ||
299 | } else { | ||
300 | buf = host->req->data + host->block_pos; | ||
301 | p_cnt = host->req->data_len - host->block_pos; | ||
302 | } | ||
303 | |||
304 | if (host->req->data_dir == WRITE) | ||
305 | t_size = !(host->cmd_flags & REG_DATA) | ||
306 | ? jmb38x_ms_write_data(host, buf, p_cnt) | ||
307 | : jmb38x_ms_write_reg_data(host, buf, p_cnt); | ||
308 | else | ||
309 | t_size = !(host->cmd_flags & REG_DATA) | ||
310 | ? jmb38x_ms_read_data(host, buf, p_cnt) | ||
311 | : jmb38x_ms_read_reg_data(host, buf, p_cnt); | ||
312 | |||
313 | if (host->req->long_data) { | ||
314 | kunmap_atomic(buf - p_off, KM_BIO_SRC_IRQ); | ||
315 | local_irq_restore(flags); | ||
316 | } | ||
317 | |||
318 | if (!t_size) | ||
319 | break; | ||
320 | host->block_pos += t_size; | ||
321 | length -= t_size; | ||
322 | off += t_size; | ||
323 | } | ||
324 | |||
325 | if (!length && host->req->data_dir == WRITE) { | ||
326 | if (host->cmd_flags & REG_DATA) { | ||
327 | writel(host->io_word[0], host->addr + TPC_P0); | ||
328 | writel(host->io_word[1], host->addr + TPC_P1); | ||
329 | } else if (host->io_pos) { | ||
330 | writel(host->io_word[0], host->addr + DATA); | ||
331 | } | ||
332 | } | ||
333 | |||
334 | return length; | ||
335 | } | ||
336 | |||
337 | static int jmb38x_ms_issue_cmd(struct memstick_host *msh) | ||
338 | { | ||
339 | struct jmb38x_ms_host *host = memstick_priv(msh); | ||
340 | unsigned char *data; | ||
341 | unsigned int data_len, cmd, t_val; | ||
342 | |||
343 | if (!(STATUS_HAS_MEDIA & readl(host->addr + STATUS))) { | ||
344 | dev_dbg(msh->cdev.dev, "no media status\n"); | ||
345 | host->req->error = -ETIME; | ||
346 | return host->req->error; | ||
347 | } | ||
348 | |||
349 | dev_dbg(msh->cdev.dev, "control %08x\n", | ||
350 | readl(host->addr + HOST_CONTROL)); | ||
351 | dev_dbg(msh->cdev.dev, "status %08x\n", readl(host->addr + INT_STATUS)); | ||
352 | dev_dbg(msh->cdev.dev, "hstatus %08x\n", readl(host->addr + STATUS)); | ||
353 | |||
354 | host->cmd_flags = 0; | ||
355 | host->block_pos = 0; | ||
356 | host->io_pos = 0; | ||
357 | host->io_word[0] = 0; | ||
358 | host->io_word[1] = 0; | ||
359 | |||
360 | cmd = host->req->tpc << 16; | ||
361 | cmd |= TPC_DATA_SEL; | ||
362 | |||
363 | if (host->req->data_dir == READ) | ||
364 | cmd |= TPC_DIR; | ||
365 | if (host->req->need_card_int) | ||
366 | cmd |= TPC_WAIT_INT; | ||
367 | if (host->req->get_int_reg) | ||
368 | cmd |= TPC_GET_INT; | ||
369 | |||
370 | data = host->req->data; | ||
371 | |||
372 | host->use_dma = !no_dma; | ||
373 | |||
374 | if (host->req->long_data) { | ||
375 | data_len = host->req->sg.length; | ||
376 | } else { | ||
377 | data_len = host->req->data_len; | ||
378 | host->use_dma = 0; | ||
379 | } | ||
380 | |||
381 | if (data_len <= 8) { | ||
382 | cmd &= ~(TPC_DATA_SEL | 0xf); | ||
383 | host->cmd_flags |= REG_DATA; | ||
384 | cmd |= data_len & 0xf; | ||
385 | host->use_dma = 0; | ||
386 | } | ||
387 | |||
388 | if (host->use_dma) { | ||
389 | if (1 != pci_map_sg(host->chip->pdev, &host->req->sg, 1, | ||
390 | host->req->data_dir == READ | ||
391 | ? PCI_DMA_FROMDEVICE | ||
392 | : PCI_DMA_TODEVICE)) { | ||
393 | host->req->error = -ENOMEM; | ||
394 | return host->req->error; | ||
395 | } | ||
396 | data_len = sg_dma_len(&host->req->sg); | ||
397 | writel(sg_dma_address(&host->req->sg), | ||
398 | host->addr + DMA_ADDRESS); | ||
399 | writel(((1 << 16) & BLOCK_COUNT_MASK) | ||
400 | | (data_len & BLOCK_SIZE_MASK), | ||
401 | host->addr + BLOCK); | ||
402 | writel(DMA_CONTROL_ENABLE, host->addr + DMA_CONTROL); | ||
403 | } else if (!(host->cmd_flags & REG_DATA)) { | ||
404 | writel(((1 << 16) & BLOCK_COUNT_MASK) | ||
405 | | (data_len & BLOCK_SIZE_MASK), | ||
406 | host->addr + BLOCK); | ||
407 | t_val = readl(host->addr + INT_STATUS_ENABLE); | ||
408 | t_val |= host->req->data_dir == READ | ||
409 | ? INT_STATUS_FIFO_RRDY | ||
410 | : INT_STATUS_FIFO_WRDY; | ||
411 | |||
412 | writel(t_val, host->addr + INT_STATUS_ENABLE); | ||
413 | writel(t_val, host->addr + INT_SIGNAL_ENABLE); | ||
414 | } else { | ||
415 | cmd &= ~(TPC_DATA_SEL | 0xf); | ||
416 | host->cmd_flags |= REG_DATA; | ||
417 | cmd |= data_len & 0xf; | ||
418 | |||
419 | if (host->req->data_dir == WRITE) { | ||
420 | jmb38x_ms_transfer_data(host); | ||
421 | writel(host->io_word[0], host->addr + TPC_P0); | ||
422 | writel(host->io_word[1], host->addr + TPC_P1); | ||
423 | } | ||
424 | } | ||
425 | |||
426 | mod_timer(&host->timer, jiffies + host->timeout_jiffies); | ||
427 | writel(HOST_CONTROL_LED | readl(host->addr + HOST_CONTROL), | ||
428 | host->addr + HOST_CONTROL); | ||
429 | host->req->error = 0; | ||
430 | |||
431 | writel(cmd, host->addr + TPC); | ||
432 | dev_dbg(msh->cdev.dev, "executing TPC %08x, len %x\n", cmd, data_len); | ||
433 | |||
434 | return 0; | ||
435 | } | ||
436 | |||
437 | static void jmb38x_ms_complete_cmd(struct memstick_host *msh, int last) | ||
438 | { | ||
439 | struct jmb38x_ms_host *host = memstick_priv(msh); | ||
440 | unsigned int t_val = 0; | ||
441 | int rc; | ||
442 | |||
443 | del_timer(&host->timer); | ||
444 | |||
445 | dev_dbg(msh->cdev.dev, "c control %08x\n", | ||
446 | readl(host->addr + HOST_CONTROL)); | ||
447 | dev_dbg(msh->cdev.dev, "c status %08x\n", | ||
448 | readl(host->addr + INT_STATUS)); | ||
449 | dev_dbg(msh->cdev.dev, "c hstatus %08x\n", readl(host->addr + STATUS)); | ||
450 | |||
451 | if (host->req->get_int_reg) { | ||
452 | t_val = readl(host->addr + TPC_P0); | ||
453 | host->req->int_reg = (t_val & 0xff); | ||
454 | } | ||
455 | |||
456 | if (host->use_dma) { | ||
457 | writel(0, host->addr + DMA_CONTROL); | ||
458 | pci_unmap_sg(host->chip->pdev, &host->req->sg, 1, | ||
459 | host->req->data_dir == READ | ||
460 | ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); | ||
461 | } else { | ||
462 | t_val = readl(host->addr + INT_STATUS_ENABLE); | ||
463 | if (host->req->data_dir == READ) | ||
464 | t_val &= ~INT_STATUS_FIFO_RRDY; | ||
465 | else | ||
466 | t_val &= ~INT_STATUS_FIFO_WRDY; | ||
467 | |||
468 | writel(t_val, host->addr + INT_STATUS_ENABLE); | ||
469 | writel(t_val, host->addr + INT_SIGNAL_ENABLE); | ||
470 | } | ||
471 | |||
472 | writel((~HOST_CONTROL_LED) & readl(host->addr + HOST_CONTROL), | ||
473 | host->addr + HOST_CONTROL); | ||
474 | |||
475 | if (!last) { | ||
476 | do { | ||
477 | rc = memstick_next_req(msh, &host->req); | ||
478 | } while (!rc && jmb38x_ms_issue_cmd(msh)); | ||
479 | } else { | ||
480 | do { | ||
481 | rc = memstick_next_req(msh, &host->req); | ||
482 | if (!rc) | ||
483 | host->req->error = -ETIME; | ||
484 | } while (!rc); | ||
485 | } | ||
486 | } | ||
487 | |||
488 | static irqreturn_t jmb38x_ms_isr(int irq, void *dev_id) | ||
489 | { | ||
490 | struct memstick_host *msh = dev_id; | ||
491 | struct jmb38x_ms_host *host = memstick_priv(msh); | ||
492 | unsigned int irq_status; | ||
493 | |||
494 | spin_lock(&host->lock); | ||
495 | irq_status = readl(host->addr + INT_STATUS); | ||
496 | dev_dbg(&host->chip->pdev->dev, "irq_status = %08x\n", irq_status); | ||
497 | if (irq_status == 0 || irq_status == (~0)) { | ||
498 | spin_unlock(&host->lock); | ||
499 | return IRQ_NONE; | ||
500 | } | ||
501 | |||
502 | if (host->req) { | ||
503 | if (irq_status & INT_STATUS_ANY_ERR) { | ||
504 | if (irq_status & INT_STATUS_CRC_ERR) | ||
505 | host->req->error = -EILSEQ; | ||
506 | else | ||
507 | host->req->error = -ETIME; | ||
508 | } else { | ||
509 | if (host->use_dma) { | ||
510 | if (irq_status & INT_STATUS_EOTRAN) | ||
511 | host->cmd_flags |= FIFO_READY; | ||
512 | } else { | ||
513 | if (irq_status & (INT_STATUS_FIFO_RRDY | ||
514 | | INT_STATUS_FIFO_WRDY)) | ||
515 | jmb38x_ms_transfer_data(host); | ||
516 | |||
517 | if (irq_status & INT_STATUS_EOTRAN) { | ||
518 | jmb38x_ms_transfer_data(host); | ||
519 | host->cmd_flags |= FIFO_READY; | ||
520 | } | ||
521 | } | ||
522 | |||
523 | if (irq_status & INT_STATUS_EOTPC) { | ||
524 | host->cmd_flags |= CMD_READY; | ||
525 | if (host->cmd_flags & REG_DATA) { | ||
526 | if (host->req->data_dir == READ) { | ||
527 | host->io_word[0] | ||
528 | = readl(host->addr | ||
529 | + TPC_P0); | ||
530 | host->io_word[1] | ||
531 | = readl(host->addr | ||
532 | + TPC_P1); | ||
533 | host->io_pos = 8; | ||
534 | |||
535 | jmb38x_ms_transfer_data(host); | ||
536 | } | ||
537 | host->cmd_flags |= FIFO_READY; | ||
538 | } | ||
539 | } | ||
540 | } | ||
541 | } | ||
542 | |||
543 | if (irq_status & (INT_STATUS_MEDIA_IN | INT_STATUS_MEDIA_OUT)) { | ||
544 | dev_dbg(&host->chip->pdev->dev, "media changed\n"); | ||
545 | memstick_detect_change(msh); | ||
546 | } | ||
547 | |||
548 | writel(irq_status, host->addr + INT_STATUS); | ||
549 | |||
550 | if (host->req | ||
551 | && (((host->cmd_flags & CMD_READY) | ||
552 | && (host->cmd_flags & FIFO_READY)) | ||
553 | || host->req->error)) | ||
554 | jmb38x_ms_complete_cmd(msh, 0); | ||
555 | |||
556 | spin_unlock(&host->lock); | ||
557 | return IRQ_HANDLED; | ||
558 | } | ||
559 | |||
560 | static void jmb38x_ms_abort(unsigned long data) | ||
561 | { | ||
562 | struct memstick_host *msh = (struct memstick_host *)data; | ||
563 | struct jmb38x_ms_host *host = memstick_priv(msh); | ||
564 | unsigned long flags; | ||
565 | |||
566 | dev_dbg(&host->chip->pdev->dev, "abort\n"); | ||
567 | spin_lock_irqsave(&host->lock, flags); | ||
568 | if (host->req) { | ||
569 | host->req->error = -ETIME; | ||
570 | jmb38x_ms_complete_cmd(msh, 0); | ||
571 | } | ||
572 | spin_unlock_irqrestore(&host->lock, flags); | ||
573 | } | ||
574 | |||
575 | static void jmb38x_ms_request(struct memstick_host *msh) | ||
576 | { | ||
577 | struct jmb38x_ms_host *host = memstick_priv(msh); | ||
578 | unsigned long flags; | ||
579 | int rc; | ||
580 | |||
581 | spin_lock_irqsave(&host->lock, flags); | ||
582 | if (host->req) { | ||
583 | spin_unlock_irqrestore(&host->lock, flags); | ||
584 | BUG(); | ||
585 | return; | ||
586 | } | ||
587 | |||
588 | do { | ||
589 | rc = memstick_next_req(msh, &host->req); | ||
590 | } while (!rc && jmb38x_ms_issue_cmd(msh)); | ||
591 | spin_unlock_irqrestore(&host->lock, flags); | ||
592 | } | ||
593 | |||
594 | static void jmb38x_ms_reset(struct jmb38x_ms_host *host) | ||
595 | { | ||
596 | unsigned int host_ctl = readl(host->addr + HOST_CONTROL); | ||
597 | |||
598 | writel(host_ctl | HOST_CONTROL_RESET_REQ | HOST_CONTROL_RESET, | ||
599 | host->addr + HOST_CONTROL); | ||
600 | |||
601 | while (HOST_CONTROL_RESET_REQ | ||
602 | & (host_ctl = readl(host->addr + HOST_CONTROL))) { | ||
603 | ndelay(100); | ||
604 | dev_dbg(&host->chip->pdev->dev, "reset\n"); | ||
605 | } | ||
606 | |||
607 | writel(INT_STATUS_ALL, host->addr + INT_STATUS_ENABLE); | ||
608 | writel(INT_STATUS_ALL, host->addr + INT_SIGNAL_ENABLE); | ||
609 | |||
610 | dev_dbg(&host->chip->pdev->dev, "reset\n"); | ||
611 | } | ||
612 | |||
613 | static void jmb38x_ms_set_param(struct memstick_host *msh, | ||
614 | enum memstick_param param, | ||
615 | int value) | ||
616 | { | ||
617 | struct jmb38x_ms_host *host = memstick_priv(msh); | ||
618 | unsigned int host_ctl; | ||
619 | unsigned long flags; | ||
620 | |||
621 | spin_lock_irqsave(&host->lock, flags); | ||
622 | |||
623 | switch (param) { | ||
624 | case MEMSTICK_POWER: | ||
625 | if (value == MEMSTICK_POWER_ON) { | ||
626 | jmb38x_ms_reset(host); | ||
627 | |||
628 | writel(host->id ? PAD_PU_PD_ON_MS_SOCK1 | ||
629 | : PAD_PU_PD_ON_MS_SOCK0, | ||
630 | host->addr + PAD_PU_PD); | ||
631 | |||
632 | writel(PAD_OUTPUT_ENABLE_MS, | ||
633 | host->addr + PAD_OUTPUT_ENABLE); | ||
634 | |||
635 | host_ctl = readl(host->addr + HOST_CONTROL); | ||
636 | host_ctl |= 7; | ||
637 | writel(host_ctl | (HOST_CONTROL_POWER_EN | ||
638 | | HOST_CONTROL_CLOCK_EN), | ||
639 | host->addr + HOST_CONTROL); | ||
640 | |||
641 | dev_dbg(&host->chip->pdev->dev, "power on\n"); | ||
642 | } else if (value == MEMSTICK_POWER_OFF) { | ||
643 | writel(readl(host->addr + HOST_CONTROL) | ||
644 | & ~(HOST_CONTROL_POWER_EN | ||
645 | | HOST_CONTROL_CLOCK_EN), | ||
646 | host->addr + HOST_CONTROL); | ||
647 | writel(0, host->addr + PAD_OUTPUT_ENABLE); | ||
648 | writel(PAD_PU_PD_OFF, host->addr + PAD_PU_PD); | ||
649 | dev_dbg(&host->chip->pdev->dev, "power off\n"); | ||
650 | } | ||
651 | break; | ||
652 | case MEMSTICK_INTERFACE: | ||
653 | /* jmb38x_ms_reset(host); */ | ||
654 | |||
655 | host_ctl = readl(host->addr + HOST_CONTROL); | ||
656 | host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT); | ||
657 | /* host_ctl |= 7; */ | ||
658 | |||
659 | if (value == MEMSTICK_SERIAL) { | ||
660 | host_ctl &= ~HOST_CONTROL_FAST_CLK; | ||
661 | host_ctl |= HOST_CONTROL_IF_SERIAL | ||
662 | << HOST_CONTROL_IF_SHIFT; | ||
663 | host_ctl |= HOST_CONTROL_REI; | ||
664 | writel(0, host->addr + CLOCK_DELAY); | ||
665 | } else if (value == MEMSTICK_PAR4) { | ||
666 | host_ctl |= HOST_CONTROL_FAST_CLK; | ||
667 | host_ctl |= HOST_CONTROL_IF_PAR4 | ||
668 | << HOST_CONTROL_IF_SHIFT; | ||
669 | host_ctl &= ~HOST_CONTROL_REI; | ||
670 | writel(4, host->addr + CLOCK_DELAY); | ||
671 | } else if (value == MEMSTICK_PAR8) { | ||
672 | host_ctl |= HOST_CONTROL_FAST_CLK; | ||
673 | host_ctl |= HOST_CONTROL_IF_PAR8 | ||
674 | << HOST_CONTROL_IF_SHIFT; | ||
675 | host_ctl &= ~HOST_CONTROL_REI; | ||
676 | writel(4, host->addr + CLOCK_DELAY); | ||
677 | } | ||
678 | writel(host_ctl, host->addr + HOST_CONTROL); | ||
679 | break; | ||
680 | }; | ||
681 | |||
682 | spin_unlock_irqrestore(&host->lock, flags); | ||
683 | } | ||
684 | |||
685 | #ifdef CONFIG_PM | ||
686 | |||
687 | static int jmb38x_ms_suspend(struct pci_dev *dev, pm_message_t state) | ||
688 | { | ||
689 | struct jmb38x_ms *jm = pci_get_drvdata(dev); | ||
690 | int cnt; | ||
691 | |||
692 | for (cnt = 0; cnt < jm->host_cnt; ++cnt) { | ||
693 | if (!jm->hosts[cnt]) | ||
694 | break; | ||
695 | memstick_suspend_host(jm->hosts[cnt]); | ||
696 | } | ||
697 | |||
698 | pci_save_state(dev); | ||
699 | pci_enable_wake(dev, pci_choose_state(dev, state), 0); | ||
700 | pci_disable_device(dev); | ||
701 | pci_set_power_state(dev, pci_choose_state(dev, state)); | ||
702 | return 0; | ||
703 | } | ||
704 | |||
705 | static int jmb38x_ms_resume(struct pci_dev *dev) | ||
706 | { | ||
707 | struct jmb38x_ms *jm = pci_get_drvdata(dev); | ||
708 | int rc; | ||
709 | |||
710 | pci_set_power_state(dev, PCI_D0); | ||
711 | pci_restore_state(dev); | ||
712 | rc = pci_enable_device(dev); | ||
713 | if (rc) | ||
714 | return rc; | ||
715 | pci_set_master(dev); | ||
716 | |||
717 | pci_read_config_dword(dev, 0xac, &rc); | ||
718 | pci_write_config_dword(dev, 0xac, rc | 0x00470000); | ||
719 | |||
720 | for (rc = 0; rc < jm->host_cnt; ++rc) { | ||
721 | if (!jm->hosts[rc]) | ||
722 | break; | ||
723 | memstick_resume_host(jm->hosts[rc]); | ||
724 | memstick_detect_change(jm->hosts[rc]); | ||
725 | } | ||
726 | |||
727 | return 0; | ||
728 | } | ||
729 | |||
730 | #else | ||
731 | |||
732 | #define jmb38x_ms_suspend NULL | ||
733 | #define jmb38x_ms_resume NULL | ||
734 | |||
735 | #endif /* CONFIG_PM */ | ||
736 | |||
737 | static int jmb38x_ms_count_slots(struct pci_dev *pdev) | ||
738 | { | ||
739 | int cnt, rc = 0; | ||
740 | |||
741 | for (cnt = 0; cnt < PCI_ROM_RESOURCE; ++cnt) { | ||
742 | if (!(IORESOURCE_MEM & pci_resource_flags(pdev, cnt))) | ||
743 | break; | ||
744 | |||
745 | if (256 != pci_resource_len(pdev, cnt)) | ||
746 | break; | ||
747 | |||
748 | ++rc; | ||
749 | } | ||
750 | return rc; | ||
751 | } | ||
752 | |||
753 | static struct memstick_host *jmb38x_ms_alloc_host(struct jmb38x_ms *jm, int cnt) | ||
754 | { | ||
755 | struct memstick_host *msh; | ||
756 | struct jmb38x_ms_host *host; | ||
757 | |||
758 | msh = memstick_alloc_host(sizeof(struct jmb38x_ms_host), | ||
759 | &jm->pdev->dev); | ||
760 | if (!msh) | ||
761 | return NULL; | ||
762 | |||
763 | host = memstick_priv(msh); | ||
764 | host->chip = jm; | ||
765 | host->addr = ioremap(pci_resource_start(jm->pdev, cnt), | ||
766 | pci_resource_len(jm->pdev, cnt)); | ||
767 | if (!host->addr) | ||
768 | goto err_out_free; | ||
769 | |||
770 | spin_lock_init(&host->lock); | ||
771 | host->id = cnt; | ||
772 | snprintf(host->host_id, DEVICE_ID_SIZE, DRIVER_NAME ":slot%d", | ||
773 | host->id); | ||
774 | host->irq = jm->pdev->irq; | ||
775 | host->timeout_jiffies = msecs_to_jiffies(4000); | ||
776 | msh->request = jmb38x_ms_request; | ||
777 | msh->set_param = jmb38x_ms_set_param; | ||
778 | /* | ||
779 | msh->caps = MEMSTICK_CAP_AUTO_GET_INT | MEMSTICK_CAP_PAR4 | ||
780 | | MEMSTICK_CAP_PAR8; | ||
781 | */ | ||
782 | msh->caps = MEMSTICK_CAP_PAR4 | MEMSTICK_CAP_PAR8; | ||
783 | |||
784 | setup_timer(&host->timer, jmb38x_ms_abort, (unsigned long)msh); | ||
785 | |||
786 | if (!request_irq(host->irq, jmb38x_ms_isr, IRQF_SHARED, host->host_id, | ||
787 | msh)) | ||
788 | return msh; | ||
789 | |||
790 | iounmap(host->addr); | ||
791 | err_out_free: | ||
792 | kfree(msh); | ||
793 | return NULL; | ||
794 | } | ||
795 | |||
796 | static void jmb38x_ms_free_host(struct memstick_host *msh) | ||
797 | { | ||
798 | struct jmb38x_ms_host *host = memstick_priv(msh); | ||
799 | |||
800 | free_irq(host->irq, msh); | ||
801 | iounmap(host->addr); | ||
802 | memstick_free_host(msh); | ||
803 | } | ||
804 | |||
805 | static int jmb38x_ms_probe(struct pci_dev *pdev, | ||
806 | const struct pci_device_id *dev_id) | ||
807 | { | ||
808 | struct jmb38x_ms *jm; | ||
809 | int pci_dev_busy = 0; | ||
810 | int rc, cnt; | ||
811 | |||
812 | rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
813 | if (rc) | ||
814 | return rc; | ||
815 | |||
816 | rc = pci_enable_device(pdev); | ||
817 | if (rc) | ||
818 | return rc; | ||
819 | |||
820 | pci_set_master(pdev); | ||
821 | |||
822 | rc = pci_request_regions(pdev, DRIVER_NAME); | ||
823 | if (rc) { | ||
824 | pci_dev_busy = 1; | ||
825 | goto err_out; | ||
826 | } | ||
827 | |||
828 | pci_read_config_dword(pdev, 0xac, &rc); | ||
829 | pci_write_config_dword(pdev, 0xac, rc | 0x00470000); | ||
830 | |||
831 | cnt = jmb38x_ms_count_slots(pdev); | ||
832 | if (!cnt) { | ||
833 | rc = -ENODEV; | ||
834 | pci_dev_busy = 1; | ||
835 | goto err_out; | ||
836 | } | ||
837 | |||
838 | jm = kzalloc(sizeof(struct jmb38x_ms) | ||
839 | + cnt * sizeof(struct memstick_host *), GFP_KERNEL); | ||
840 | if (!jm) { | ||
841 | rc = -ENOMEM; | ||
842 | goto err_out_int; | ||
843 | } | ||
844 | |||
845 | jm->pdev = pdev; | ||
846 | jm->host_cnt = cnt; | ||
847 | pci_set_drvdata(pdev, jm); | ||
848 | |||
849 | for (cnt = 0; cnt < jm->host_cnt; ++cnt) { | ||
850 | jm->hosts[cnt] = jmb38x_ms_alloc_host(jm, cnt); | ||
851 | if (!jm->hosts[cnt]) | ||
852 | break; | ||
853 | |||
854 | rc = memstick_add_host(jm->hosts[cnt]); | ||
855 | |||
856 | if (rc) { | ||
857 | jmb38x_ms_free_host(jm->hosts[cnt]); | ||
858 | jm->hosts[cnt] = NULL; | ||
859 | break; | ||
860 | } | ||
861 | } | ||
862 | |||
863 | if (cnt) | ||
864 | return 0; | ||
865 | |||
866 | rc = -ENODEV; | ||
867 | |||
868 | pci_set_drvdata(pdev, NULL); | ||
869 | kfree(jm); | ||
870 | err_out_int: | ||
871 | pci_release_regions(pdev); | ||
872 | err_out: | ||
873 | if (!pci_dev_busy) | ||
874 | pci_disable_device(pdev); | ||
875 | return rc; | ||
876 | } | ||
877 | |||
878 | static void jmb38x_ms_remove(struct pci_dev *dev) | ||
879 | { | ||
880 | struct jmb38x_ms *jm = pci_get_drvdata(dev); | ||
881 | struct jmb38x_ms_host *host; | ||
882 | int cnt; | ||
883 | unsigned long flags; | ||
884 | |||
885 | for (cnt = 0; cnt < jm->host_cnt; ++cnt) { | ||
886 | if (!jm->hosts[cnt]) | ||
887 | break; | ||
888 | |||
889 | host = memstick_priv(jm->hosts[cnt]); | ||
890 | |||
891 | writel(0, host->addr + INT_SIGNAL_ENABLE); | ||
892 | writel(0, host->addr + INT_STATUS_ENABLE); | ||
893 | mmiowb(); | ||
894 | dev_dbg(&jm->pdev->dev, "interrupts off\n"); | ||
895 | spin_lock_irqsave(&host->lock, flags); | ||
896 | if (host->req) { | ||
897 | host->req->error = -ETIME; | ||
898 | jmb38x_ms_complete_cmd(jm->hosts[cnt], 1); | ||
899 | } | ||
900 | spin_unlock_irqrestore(&host->lock, flags); | ||
901 | |||
902 | memstick_remove_host(jm->hosts[cnt]); | ||
903 | dev_dbg(&jm->pdev->dev, "host removed\n"); | ||
904 | |||
905 | jmb38x_ms_free_host(jm->hosts[cnt]); | ||
906 | } | ||
907 | |||
908 | pci_set_drvdata(dev, NULL); | ||
909 | pci_release_regions(dev); | ||
910 | pci_disable_device(dev); | ||
911 | kfree(jm); | ||
912 | } | ||
913 | |||
914 | static struct pci_device_id jmb38x_ms_id_tbl [] = { | ||
915 | { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_MS, PCI_ANY_ID, | ||
916 | PCI_ANY_ID, 0, 0, 0 }, | ||
917 | { } | ||
918 | }; | ||
919 | |||
920 | static struct pci_driver jmb38x_ms_driver = { | ||
921 | .name = DRIVER_NAME, | ||
922 | .id_table = jmb38x_ms_id_tbl, | ||
923 | .probe = jmb38x_ms_probe, | ||
924 | .remove = jmb38x_ms_remove, | ||
925 | .suspend = jmb38x_ms_suspend, | ||
926 | .resume = jmb38x_ms_resume | ||
927 | }; | ||
928 | |||
929 | static int __init jmb38x_ms_init(void) | ||
930 | { | ||
931 | return pci_register_driver(&jmb38x_ms_driver); | ||
932 | } | ||
933 | |||
934 | static void __exit jmb38x_ms_exit(void) | ||
935 | { | ||
936 | pci_unregister_driver(&jmb38x_ms_driver); | ||
937 | } | ||
938 | |||
939 | MODULE_AUTHOR("Alex Dubov"); | ||
940 | MODULE_DESCRIPTION("JMicron jmb38x MemoryStick driver"); | ||
941 | MODULE_LICENSE("GPL"); | ||
942 | MODULE_DEVICE_TABLE(pci, jmb38x_ms_id_tbl); | ||
943 | |||
944 | module_init(jmb38x_ms_init); | ||
945 | module_exit(jmb38x_ms_exit); | ||
diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c index 4fb24215bd95..2b5bf52a8302 100644 --- a/drivers/memstick/host/tifm_ms.c +++ b/drivers/memstick/host/tifm_ms.c | |||
@@ -20,293 +20,315 @@ | |||
20 | #include <asm/io.h> | 20 | #include <asm/io.h> |
21 | 21 | ||
22 | #define DRIVER_NAME "tifm_ms" | 22 | #define DRIVER_NAME "tifm_ms" |
23 | #define DRIVER_VERSION "0.1" | ||
24 | 23 | ||
25 | static int no_dma; | 24 | static int no_dma; |
26 | module_param(no_dma, bool, 0644); | 25 | module_param(no_dma, bool, 0644); |
27 | 26 | ||
28 | #define TIFM_MS_TIMEOUT 0x00100 | 27 | /* |
29 | #define TIFM_MS_BADCRC 0x00200 | 28 | * Some control bits of TIFM appear to conform to Sony's reference design, |
30 | #define TIFM_MS_EOTPC 0x01000 | 29 | * so I'm just assuming they all are. |
31 | #define TIFM_MS_INT 0x02000 | 30 | */ |
32 | |||
33 | /* The meaning of the bit majority in this constant is unknown. */ | ||
34 | #define TIFM_MS_SERIAL 0x04010 | ||
35 | 31 | ||
36 | #define TIFM_MS_SYS_LATCH 0x00100 | 32 | #define TIFM_MS_STAT_DRQ 0x04000 |
37 | #define TIFM_MS_SYS_NOT_RDY 0x00800 | 33 | #define TIFM_MS_STAT_MSINT 0x02000 |
38 | #define TIFM_MS_SYS_DATA 0x10000 | 34 | #define TIFM_MS_STAT_RDY 0x01000 |
35 | #define TIFM_MS_STAT_CRC 0x00200 | ||
36 | #define TIFM_MS_STAT_TOE 0x00100 | ||
37 | #define TIFM_MS_STAT_EMP 0x00020 | ||
38 | #define TIFM_MS_STAT_FUL 0x00010 | ||
39 | #define TIFM_MS_STAT_CED 0x00008 | ||
40 | #define TIFM_MS_STAT_ERR 0x00004 | ||
41 | #define TIFM_MS_STAT_BRQ 0x00002 | ||
42 | #define TIFM_MS_STAT_CNK 0x00001 | ||
43 | |||
44 | #define TIFM_MS_SYS_DMA 0x10000 | ||
45 | #define TIFM_MS_SYS_RESET 0x08000 | ||
46 | #define TIFM_MS_SYS_SRAC 0x04000 | ||
47 | #define TIFM_MS_SYS_INTEN 0x02000 | ||
48 | #define TIFM_MS_SYS_NOCRC 0x01000 | ||
49 | #define TIFM_MS_SYS_INTCLR 0x00800 | ||
50 | #define TIFM_MS_SYS_MSIEN 0x00400 | ||
51 | #define TIFM_MS_SYS_FCLR 0x00200 | ||
52 | #define TIFM_MS_SYS_FDIR 0x00100 | ||
53 | #define TIFM_MS_SYS_DAM 0x00080 | ||
54 | #define TIFM_MS_SYS_DRM 0x00040 | ||
55 | #define TIFM_MS_SYS_DRQSL 0x00020 | ||
56 | #define TIFM_MS_SYS_REI 0x00010 | ||
57 | #define TIFM_MS_SYS_REO 0x00008 | ||
58 | #define TIFM_MS_SYS_BSY_MASK 0x00007 | ||
59 | |||
60 | #define TIFM_MS_SYS_FIFO (TIFM_MS_SYS_INTEN | TIFM_MS_SYS_MSIEN \ | ||
61 | | TIFM_MS_SYS_FCLR | TIFM_MS_SYS_BSY_MASK) | ||
39 | 62 | ||
40 | /* Hardware flags */ | 63 | /* Hardware flags */ |
41 | enum { | 64 | enum { |
42 | CMD_READY = 0x0001, | 65 | CMD_READY = 0x01, |
43 | FIFO_READY = 0x0002, | 66 | FIFO_READY = 0x02, |
44 | CARD_READY = 0x0004, | 67 | CARD_INT = 0x04 |
45 | DATA_CARRY = 0x0008 | ||
46 | }; | 68 | }; |
47 | 69 | ||
48 | struct tifm_ms { | 70 | struct tifm_ms { |
49 | struct tifm_dev *dev; | 71 | struct tifm_dev *dev; |
50 | unsigned short eject:1, | 72 | struct timer_list timer; |
51 | no_dma:1; | 73 | struct memstick_request *req; |
52 | unsigned short cmd_flags; | ||
53 | unsigned int mode_mask; | 74 | unsigned int mode_mask; |
54 | unsigned int block_pos; | 75 | unsigned int block_pos; |
55 | unsigned long timeout_jiffies; | 76 | unsigned long timeout_jiffies; |
56 | 77 | unsigned char eject:1, | |
57 | struct timer_list timer; | 78 | use_dma:1; |
58 | struct memstick_request *req; | 79 | unsigned char cmd_flags; |
80 | unsigned char io_pos; | ||
59 | unsigned int io_word; | 81 | unsigned int io_word; |
60 | }; | 82 | }; |
61 | 83 | ||
62 | static void tifm_ms_read_fifo(struct tifm_ms *host, unsigned int fifo_offset, | 84 | static unsigned int tifm_ms_read_data(struct tifm_ms *host, |
63 | struct page *pg, unsigned int page_off, | 85 | unsigned char *buf, unsigned int length) |
64 | unsigned int length) | ||
65 | { | 86 | { |
66 | struct tifm_dev *sock = host->dev; | 87 | struct tifm_dev *sock = host->dev; |
67 | unsigned int cnt = 0, off = 0; | 88 | unsigned int off = 0; |
68 | unsigned char *buf = kmap_atomic(pg, KM_BIO_DST_IRQ) + page_off; | 89 | |
90 | while (host->io_pos && length) { | ||
91 | buf[off++] = host->io_word & 0xff; | ||
92 | host->io_word >>= 8; | ||
93 | length--; | ||
94 | host->io_pos--; | ||
95 | } | ||
69 | 96 | ||
70 | if (host->cmd_flags & DATA_CARRY) { | 97 | if (!length) |
71 | while ((fifo_offset & 3) && length) { | 98 | return off; |
99 | |||
100 | while (!(TIFM_MS_STAT_EMP & readl(sock->addr + SOCK_MS_STATUS))) { | ||
101 | if (length < 4) | ||
102 | break; | ||
103 | *(unsigned int *)(buf + off) = __raw_readl(sock->addr | ||
104 | + SOCK_MS_DATA); | ||
105 | length -= 4; | ||
106 | off += 4; | ||
107 | } | ||
108 | |||
109 | if (length | ||
110 | && !(TIFM_MS_STAT_EMP & readl(sock->addr + SOCK_MS_STATUS))) { | ||
111 | host->io_word = readl(sock->addr + SOCK_MS_DATA); | ||
112 | for (host->io_pos = 4; host->io_pos; --host->io_pos) { | ||
72 | buf[off++] = host->io_word & 0xff; | 113 | buf[off++] = host->io_word & 0xff; |
73 | host->io_word >>= 8; | 114 | host->io_word >>= 8; |
74 | length--; | 115 | length--; |
75 | fifo_offset++; | 116 | if (!length) |
117 | break; | ||
76 | } | 118 | } |
77 | if (!(fifo_offset & 3)) | ||
78 | host->cmd_flags &= ~DATA_CARRY; | ||
79 | if (!length) | ||
80 | return; | ||
81 | } | 119 | } |
82 | 120 | ||
83 | do { | 121 | return off; |
84 | host->io_word = readl(sock->addr + SOCK_FIFO_ACCESS | ||
85 | + fifo_offset); | ||
86 | cnt = 4; | ||
87 | while (length && cnt) { | ||
88 | buf[off++] = (host->io_word >> 8) & 0xff; | ||
89 | cnt--; | ||
90 | length--; | ||
91 | } | ||
92 | fifo_offset += 4 - cnt; | ||
93 | } while (length); | ||
94 | |||
95 | if (cnt) | ||
96 | host->cmd_flags |= DATA_CARRY; | ||
97 | |||
98 | kunmap_atomic(buf - page_off, KM_BIO_DST_IRQ); | ||
99 | } | 122 | } |
100 | 123 | ||
101 | static void tifm_ms_write_fifo(struct tifm_ms *host, unsigned int fifo_offset, | 124 | static unsigned int tifm_ms_write_data(struct tifm_ms *host, |
102 | struct page *pg, unsigned int page_off, | 125 | unsigned char *buf, unsigned int length) |
103 | unsigned int length) | ||
104 | { | 126 | { |
105 | struct tifm_dev *sock = host->dev; | 127 | struct tifm_dev *sock = host->dev; |
106 | unsigned int cnt = 0, off = 0; | 128 | unsigned int off = 0; |
107 | unsigned char *buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + page_off; | ||
108 | 129 | ||
109 | if (host->cmd_flags & DATA_CARRY) { | 130 | if (host->io_pos) { |
110 | while (fifo_offset & 3) { | 131 | while (host->io_pos < 4 && length) { |
111 | host->io_word |= buf[off++] << (8 * (fifo_offset & 3)); | 132 | host->io_word |= buf[off++] << (host->io_pos * 8); |
133 | host->io_pos++; | ||
112 | length--; | 134 | length--; |
113 | fifo_offset++; | ||
114 | } | 135 | } |
115 | if (!(fifo_offset & 3)) { | ||
116 | writel(host->io_word, sock->addr + SOCK_FIFO_ACCESS | ||
117 | + fifo_offset - 4); | ||
118 | |||
119 | host->cmd_flags &= ~DATA_CARRY; | ||
120 | } | ||
121 | if (!length) | ||
122 | return; | ||
123 | } | 136 | } |
124 | 137 | ||
125 | do { | 138 | if (host->io_pos == 4 |
126 | cnt = 4; | 139 | && !(TIFM_MS_STAT_FUL & readl(sock->addr + SOCK_MS_STATUS))) { |
140 | writel(TIFM_MS_SYS_FDIR | readl(sock->addr + SOCK_MS_SYSTEM), | ||
141 | sock->addr + SOCK_MS_SYSTEM); | ||
142 | writel(host->io_word, sock->addr + SOCK_MS_DATA); | ||
143 | host->io_pos = 0; | ||
127 | host->io_word = 0; | 144 | host->io_word = 0; |
128 | while (length && cnt) { | 145 | } else if (host->io_pos) { |
129 | host->io_word |= buf[off++] << (4 - cnt); | 146 | return off; |
130 | cnt--; | 147 | } |
131 | length--; | ||
132 | } | ||
133 | fifo_offset += 4 - cnt; | ||
134 | if (!cnt) | ||
135 | writel(host->io_word, sock->addr + SOCK_FIFO_ACCESS | ||
136 | + fifo_offset - 4); | ||
137 | |||
138 | } while (length); | ||
139 | |||
140 | if (cnt) | ||
141 | host->cmd_flags |= DATA_CARRY; | ||
142 | 148 | ||
143 | kunmap_atomic(buf - page_off, KM_BIO_SRC_IRQ); | 149 | if (!length) |
144 | } | 150 | return off; |
145 | 151 | ||
146 | static void tifm_ms_move_block(struct tifm_ms *host, unsigned int length) | 152 | while (!(TIFM_MS_STAT_FUL & readl(sock->addr + SOCK_MS_STATUS))) { |
147 | { | 153 | if (length < 4) |
148 | unsigned int t_size; | 154 | break; |
149 | unsigned int off = host->req->sg.offset + host->block_pos; | 155 | writel(TIFM_MS_SYS_FDIR | readl(sock->addr + SOCK_MS_SYSTEM), |
150 | unsigned int p_off, p_cnt; | 156 | sock->addr + SOCK_MS_SYSTEM); |
151 | struct page *pg; | 157 | __raw_writel(*(unsigned int *)(buf + off), |
152 | unsigned long flags; | 158 | sock->addr + SOCK_MS_DATA); |
159 | length -= 4; | ||
160 | off += 4; | ||
161 | } | ||
153 | 162 | ||
154 | dev_dbg(&host->dev->dev, "moving block\n"); | 163 | switch (length) { |
155 | local_irq_save(flags); | 164 | case 3: |
156 | t_size = length; | 165 | host->io_word |= buf[off + 2] << 16; |
157 | while (t_size) { | 166 | host->io_pos++; |
158 | pg = nth_page(sg_page(&host->req->sg), off >> PAGE_SHIFT); | 167 | case 2: |
159 | p_off = offset_in_page(off); | 168 | host->io_word |= buf[off + 1] << 8; |
160 | p_cnt = PAGE_SIZE - p_off; | 169 | host->io_pos++; |
161 | p_cnt = min(p_cnt, t_size); | 170 | case 1: |
171 | host->io_word |= buf[off]; | ||
172 | host->io_pos++; | ||
173 | } | ||
162 | 174 | ||
163 | if (host->req->data_dir == WRITE) | 175 | off += host->io_pos; |
164 | tifm_ms_write_fifo(host, length - t_size, | ||
165 | pg, p_off, p_cnt); | ||
166 | else | ||
167 | tifm_ms_read_fifo(host, length - t_size, | ||
168 | pg, p_off, p_cnt); | ||
169 | 176 | ||
170 | t_size -= p_cnt; | 177 | return off; |
171 | } | ||
172 | local_irq_restore(flags); | ||
173 | } | 178 | } |
174 | 179 | ||
175 | static int tifm_ms_transfer_data(struct tifm_ms *host, int skip) | 180 | static unsigned int tifm_ms_transfer_data(struct tifm_ms *host) |
176 | { | 181 | { |
177 | struct tifm_dev *sock = host->dev; | 182 | struct tifm_dev *sock = host->dev; |
178 | unsigned int length = host->req->sg.length - host->block_pos; | 183 | unsigned int length; |
184 | unsigned int off; | ||
185 | unsigned int t_size, p_off, p_cnt; | ||
186 | unsigned char *buf; | ||
187 | struct page *pg; | ||
188 | unsigned long flags = 0; | ||
189 | |||
190 | if (host->req->long_data) { | ||
191 | length = host->req->sg.length - host->block_pos; | ||
192 | off = host->req->sg.offset + host->block_pos; | ||
193 | } else { | ||
194 | length = host->req->data_len - host->block_pos; | ||
195 | off = 0; | ||
196 | } | ||
197 | dev_dbg(&sock->dev, "fifo data transfer, %d, %d\n", length, | ||
198 | host->block_pos); | ||
199 | |||
200 | while (length) { | ||
201 | if (host->req->long_data) { | ||
202 | pg = nth_page(sg_page(&host->req->sg), | ||
203 | off >> PAGE_SHIFT); | ||
204 | p_off = offset_in_page(off); | ||
205 | p_cnt = PAGE_SIZE - p_off; | ||
206 | p_cnt = min(p_cnt, length); | ||
207 | |||
208 | local_irq_save(flags); | ||
209 | buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + p_off; | ||
210 | } else { | ||
211 | buf = host->req->data + host->block_pos; | ||
212 | p_cnt = host->req->data_len - host->block_pos; | ||
213 | } | ||
179 | 214 | ||
180 | if (!length) | 215 | t_size = host->req->data_dir == WRITE |
181 | return 1; | 216 | ? tifm_ms_write_data(host, buf, p_cnt) |
217 | : tifm_ms_read_data(host, buf, p_cnt); | ||
182 | 218 | ||
183 | if (length > TIFM_FIFO_SIZE) | 219 | if (host->req->long_data) { |
184 | length = TIFM_FIFO_SIZE; | 220 | kunmap_atomic(buf - p_off, KM_BIO_SRC_IRQ); |
221 | local_irq_restore(flags); | ||
222 | } | ||
185 | 223 | ||
186 | if (!skip) { | 224 | if (!t_size) |
187 | tifm_ms_move_block(host, length); | 225 | break; |
188 | host->block_pos += length; | 226 | host->block_pos += t_size; |
227 | length -= t_size; | ||
228 | off += t_size; | ||
189 | } | 229 | } |
190 | 230 | ||
191 | if ((host->req->data_dir == READ) | 231 | dev_dbg(&sock->dev, "fifo data transfer, %d remaining\n", length); |
192 | && (host->block_pos == host->req->sg.length)) | 232 | if (!length && (host->req->data_dir == WRITE)) { |
193 | return 1; | 233 | if (host->io_pos) { |
194 | 234 | writel(TIFM_MS_SYS_FDIR | |
195 | writel(ilog2(length) - 2, sock->addr + SOCK_FIFO_PAGE_SIZE); | 235 | | readl(sock->addr + SOCK_MS_SYSTEM), |
196 | if (host->req->data_dir == WRITE) | 236 | sock->addr + SOCK_MS_SYSTEM); |
197 | writel((1 << 8) | TIFM_DMA_TX, sock->addr + SOCK_DMA_CONTROL); | 237 | writel(host->io_word, sock->addr + SOCK_MS_DATA); |
198 | else | 238 | } |
199 | writel((1 << 8), sock->addr + SOCK_DMA_CONTROL); | 239 | writel(TIFM_MS_SYS_FDIR |
240 | | readl(sock->addr + SOCK_MS_SYSTEM), | ||
241 | sock->addr + SOCK_MS_SYSTEM); | ||
242 | writel(0, sock->addr + SOCK_MS_DATA); | ||
243 | } else { | ||
244 | readl(sock->addr + SOCK_MS_DATA); | ||
245 | } | ||
200 | 246 | ||
201 | return 0; | 247 | return length; |
202 | } | 248 | } |
203 | 249 | ||
204 | static int tifm_ms_issue_cmd(struct tifm_ms *host) | 250 | static int tifm_ms_issue_cmd(struct tifm_ms *host) |
205 | { | 251 | { |
206 | struct tifm_dev *sock = host->dev; | 252 | struct tifm_dev *sock = host->dev; |
207 | unsigned char *data; | 253 | unsigned char *data; |
208 | unsigned int data_len = 0, cmd = 0, cmd_mask = 0, cnt, tval = 0; | 254 | unsigned int data_len, cmd, sys_param; |
209 | 255 | ||
210 | host->cmd_flags = 0; | 256 | host->cmd_flags = 0; |
257 | host->block_pos = 0; | ||
258 | host->io_pos = 0; | ||
259 | host->io_word = 0; | ||
260 | host->cmd_flags = 0; | ||
211 | 261 | ||
212 | if (host->req->io_type == MEMSTICK_IO_SG) { | 262 | data = host->req->data; |
213 | if (!host->no_dma) { | ||
214 | if (1 != tifm_map_sg(sock, &host->req->sg, 1, | ||
215 | host->req->data_dir == READ | ||
216 | ? PCI_DMA_FROMDEVICE | ||
217 | : PCI_DMA_TODEVICE)) { | ||
218 | host->req->error = -ENOMEM; | ||
219 | return host->req->error; | ||
220 | } | ||
221 | data_len = sg_dma_len(&host->req->sg); | ||
222 | } else | ||
223 | data_len = host->req->sg.length; | ||
224 | |||
225 | writel(TIFM_FIFO_INT_SETALL, | ||
226 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | ||
227 | writel(TIFM_FIFO_ENABLE, | ||
228 | sock->addr + SOCK_FIFO_CONTROL); | ||
229 | writel(TIFM_FIFO_INTMASK, | ||
230 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); | ||
231 | 263 | ||
232 | if (!host->no_dma) { | 264 | host->use_dma = !no_dma; |
233 | writel(ilog2(data_len) - 2, | ||
234 | sock->addr + SOCK_FIFO_PAGE_SIZE); | ||
235 | writel(sg_dma_address(&host->req->sg), | ||
236 | sock->addr + SOCK_DMA_ADDRESS); | ||
237 | if (host->req->data_dir == WRITE) | ||
238 | writel((1 << 8) | TIFM_DMA_TX | TIFM_DMA_EN, | ||
239 | sock->addr + SOCK_DMA_CONTROL); | ||
240 | else | ||
241 | writel((1 << 8) | TIFM_DMA_EN, | ||
242 | sock->addr + SOCK_DMA_CONTROL); | ||
243 | } else { | ||
244 | tifm_ms_transfer_data(host, | ||
245 | host->req->data_dir == READ); | ||
246 | } | ||
247 | 265 | ||
248 | cmd_mask = readl(sock->addr + SOCK_MS_SYSTEM); | 266 | if (host->req->long_data) { |
249 | cmd_mask |= TIFM_MS_SYS_DATA | TIFM_MS_SYS_NOT_RDY; | 267 | data_len = host->req->sg.length; |
250 | writel(cmd_mask, sock->addr + SOCK_MS_SYSTEM); | 268 | if (!is_power_of_2(data_len)) |
251 | } else if (host->req->io_type == MEMSTICK_IO_VAL) { | 269 | host->use_dma = 0; |
252 | data = host->req->data; | 270 | } else { |
253 | data_len = host->req->data_len; | 271 | data_len = host->req->data_len; |
272 | host->use_dma = 0; | ||
273 | } | ||
254 | 274 | ||
255 | cmd_mask = host->mode_mask | 0x2607; /* unknown constant */ | 275 | writel(TIFM_FIFO_INT_SETALL, |
256 | 276 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | |
257 | if (host->req->data_dir == WRITE) { | 277 | writel(TIFM_FIFO_ENABLE, |
258 | cmd_mask |= TIFM_MS_SYS_LATCH; | 278 | sock->addr + SOCK_FIFO_CONTROL); |
259 | writel(cmd_mask, sock->addr + SOCK_MS_SYSTEM); | 279 | |
260 | for (cnt = 0; (data_len - cnt) >= 4; cnt += 4) { | 280 | if (host->use_dma) { |
261 | writel(TIFM_MS_SYS_LATCH | 281 | if (1 != tifm_map_sg(sock, &host->req->sg, 1, |
262 | | readl(sock->addr + SOCK_MS_SYSTEM), | 282 | host->req->data_dir == READ |
263 | sock->addr + SOCK_MS_SYSTEM); | 283 | ? PCI_DMA_FROMDEVICE |
264 | __raw_writel(*(unsigned int *)(data + cnt), | 284 | : PCI_DMA_TODEVICE)) { |
265 | sock->addr + SOCK_MS_DATA); | 285 | host->req->error = -ENOMEM; |
266 | dev_dbg(&sock->dev, "writing %x\n", | 286 | return host->req->error; |
267 | *(int *)(data + cnt)); | 287 | } |
268 | } | 288 | data_len = sg_dma_len(&host->req->sg); |
269 | switch (data_len - cnt) { | ||
270 | case 3: | ||
271 | tval |= data[cnt + 2] << 16; | ||
272 | case 2: | ||
273 | tval |= data[cnt + 1] << 8; | ||
274 | case 1: | ||
275 | tval |= data[cnt]; | ||
276 | writel(TIFM_MS_SYS_LATCH | ||
277 | | readl(sock->addr + SOCK_MS_SYSTEM), | ||
278 | sock->addr + SOCK_MS_SYSTEM); | ||
279 | writel(tval, sock->addr + SOCK_MS_DATA); | ||
280 | dev_dbg(&sock->dev, "writing %x\n", tval); | ||
281 | } | ||
282 | 289 | ||
283 | writel(TIFM_MS_SYS_LATCH | 290 | writel(ilog2(data_len) - 2, |
284 | | readl(sock->addr + SOCK_MS_SYSTEM), | 291 | sock->addr + SOCK_FIFO_PAGE_SIZE); |
285 | sock->addr + SOCK_MS_SYSTEM); | 292 | writel(TIFM_FIFO_INTMASK, |
286 | writel(0, sock->addr + SOCK_MS_DATA); | 293 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); |
287 | dev_dbg(&sock->dev, "writing %x\n", 0); | 294 | sys_param = TIFM_DMA_EN | (1 << 8); |
295 | if (host->req->data_dir == WRITE) | ||
296 | sys_param |= TIFM_DMA_TX; | ||
297 | |||
298 | writel(TIFM_FIFO_INTMASK, | ||
299 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); | ||
288 | 300 | ||
289 | } else | 301 | writel(sg_dma_address(&host->req->sg), |
290 | writel(cmd_mask, sock->addr + SOCK_MS_SYSTEM); | 302 | sock->addr + SOCK_DMA_ADDRESS); |
303 | writel(sys_param, sock->addr + SOCK_DMA_CONTROL); | ||
304 | } else { | ||
305 | writel(host->mode_mask | TIFM_MS_SYS_FIFO, | ||
306 | sock->addr + SOCK_MS_SYSTEM); | ||
291 | 307 | ||
292 | cmd_mask = readl(sock->addr + SOCK_MS_SYSTEM); | 308 | writel(TIFM_FIFO_MORE, |
293 | cmd_mask &= ~TIFM_MS_SYS_DATA; | 309 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); |
294 | cmd_mask |= TIFM_MS_SYS_NOT_RDY; | 310 | } |
295 | dev_dbg(&sock->dev, "mask %x\n", cmd_mask); | ||
296 | writel(cmd_mask, sock->addr + SOCK_MS_SYSTEM); | ||
297 | } else | ||
298 | BUG(); | ||
299 | 311 | ||
300 | mod_timer(&host->timer, jiffies + host->timeout_jiffies); | 312 | mod_timer(&host->timer, jiffies + host->timeout_jiffies); |
301 | writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), | 313 | writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), |
302 | sock->addr + SOCK_CONTROL); | 314 | sock->addr + SOCK_CONTROL); |
303 | host->req->error = 0; | 315 | host->req->error = 0; |
304 | 316 | ||
317 | sys_param = readl(sock->addr + SOCK_MS_SYSTEM); | ||
318 | sys_param |= TIFM_MS_SYS_INTCLR; | ||
319 | |||
320 | if (host->use_dma) | ||
321 | sys_param |= TIFM_MS_SYS_DMA; | ||
322 | else | ||
323 | sys_param &= ~TIFM_MS_SYS_DMA; | ||
324 | |||
325 | writel(sys_param, sock->addr + SOCK_MS_SYSTEM); | ||
326 | |||
305 | cmd = (host->req->tpc & 0xf) << 12; | 327 | cmd = (host->req->tpc & 0xf) << 12; |
306 | cmd |= data_len; | 328 | cmd |= data_len; |
307 | writel(cmd, sock->addr + SOCK_MS_COMMAND); | 329 | writel(cmd, sock->addr + SOCK_MS_COMMAND); |
308 | 330 | ||
309 | dev_dbg(&sock->dev, "executing TPC %x, %x\n", cmd, cmd_mask); | 331 | dev_dbg(&sock->dev, "executing TPC %x, %x\n", cmd, sys_param); |
310 | return 0; | 332 | return 0; |
311 | } | 333 | } |
312 | 334 | ||
@@ -314,47 +336,20 @@ static void tifm_ms_complete_cmd(struct tifm_ms *host) | |||
314 | { | 336 | { |
315 | struct tifm_dev *sock = host->dev; | 337 | struct tifm_dev *sock = host->dev; |
316 | struct memstick_host *msh = tifm_get_drvdata(sock); | 338 | struct memstick_host *msh = tifm_get_drvdata(sock); |
317 | unsigned int tval = 0, data_len; | ||
318 | unsigned char *data; | ||
319 | int rc; | 339 | int rc; |
320 | 340 | ||
321 | del_timer(&host->timer); | 341 | del_timer(&host->timer); |
322 | if (host->req->io_type == MEMSTICK_IO_SG) { | ||
323 | if (!host->no_dma) | ||
324 | tifm_unmap_sg(sock, &host->req->sg, 1, | ||
325 | host->req->data_dir == READ | ||
326 | ? PCI_DMA_FROMDEVICE | ||
327 | : PCI_DMA_TODEVICE); | ||
328 | } else if (host->req->io_type == MEMSTICK_IO_VAL) { | ||
329 | writel(~TIFM_MS_SYS_DATA & readl(sock->addr + SOCK_MS_SYSTEM), | ||
330 | sock->addr + SOCK_MS_SYSTEM); | ||
331 | |||
332 | data = host->req->data; | ||
333 | data_len = host->req->data_len; | ||
334 | 342 | ||
335 | if (host->req->data_dir == READ) { | 343 | if (host->use_dma) |
336 | for (rc = 0; (data_len - rc) >= 4; rc += 4) | 344 | tifm_unmap_sg(sock, &host->req->sg, 1, |
337 | *(int *)(data + rc) | 345 | host->req->data_dir == READ |
338 | = __raw_readl(sock->addr | 346 | ? PCI_DMA_FROMDEVICE |
339 | + SOCK_MS_DATA); | 347 | : PCI_DMA_TODEVICE); |
340 | |||
341 | if (data_len - rc) | ||
342 | tval = readl(sock->addr + SOCK_MS_DATA); | ||
343 | switch (data_len - rc) { | ||
344 | case 3: | ||
345 | data[rc + 2] = (tval >> 16) & 0xff; | ||
346 | case 2: | ||
347 | data[rc + 1] = (tval >> 8) & 0xff; | ||
348 | case 1: | ||
349 | data[rc] = tval & 0xff; | ||
350 | } | ||
351 | readl(sock->addr + SOCK_MS_DATA); | ||
352 | } | ||
353 | } | ||
354 | 348 | ||
355 | writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), | 349 | writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), |
356 | sock->addr + SOCK_CONTROL); | 350 | sock->addr + SOCK_CONTROL); |
357 | 351 | ||
352 | dev_dbg(&sock->dev, "TPC complete\n"); | ||
358 | do { | 353 | do { |
359 | rc = memstick_next_req(msh, &host->req); | 354 | rc = memstick_next_req(msh, &host->req); |
360 | } while (!rc && tifm_ms_issue_cmd(host)); | 355 | } while (!rc && tifm_ms_issue_cmd(host)); |
@@ -365,11 +360,10 @@ static int tifm_ms_check_status(struct tifm_ms *host) | |||
365 | if (!host->req->error) { | 360 | if (!host->req->error) { |
366 | if (!(host->cmd_flags & CMD_READY)) | 361 | if (!(host->cmd_flags & CMD_READY)) |
367 | return 1; | 362 | return 1; |
368 | if ((host->req->io_type == MEMSTICK_IO_SG) | 363 | if (!(host->cmd_flags & FIFO_READY)) |
369 | && !(host->cmd_flags & FIFO_READY)) | ||
370 | return 1; | 364 | return 1; |
371 | if (host->req->need_card_int | 365 | if (host->req->need_card_int |
372 | && !(host->cmd_flags & CARD_READY)) | 366 | && !(host->cmd_flags & CARD_INT)) |
373 | return 1; | 367 | return 1; |
374 | } | 368 | } |
375 | return 0; | 369 | return 0; |
@@ -379,18 +373,24 @@ static int tifm_ms_check_status(struct tifm_ms *host) | |||
379 | static void tifm_ms_data_event(struct tifm_dev *sock) | 373 | static void tifm_ms_data_event(struct tifm_dev *sock) |
380 | { | 374 | { |
381 | struct tifm_ms *host; | 375 | struct tifm_ms *host; |
382 | unsigned int fifo_status = 0; | 376 | unsigned int fifo_status = 0, host_status = 0; |
383 | int rc = 1; | 377 | int rc = 1; |
384 | 378 | ||
385 | spin_lock(&sock->lock); | 379 | spin_lock(&sock->lock); |
386 | host = memstick_priv((struct memstick_host *)tifm_get_drvdata(sock)); | 380 | host = memstick_priv((struct memstick_host *)tifm_get_drvdata(sock)); |
387 | fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS); | 381 | fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS); |
388 | dev_dbg(&sock->dev, "data event: fifo_status %x, flags %x\n", | 382 | host_status = readl(sock->addr + SOCK_MS_STATUS); |
389 | fifo_status, host->cmd_flags); | 383 | dev_dbg(&sock->dev, |
384 | "data event: fifo_status %x, host_status %x, flags %x\n", | ||
385 | fifo_status, host_status, host->cmd_flags); | ||
390 | 386 | ||
391 | if (host->req) { | 387 | if (host->req) { |
392 | if (fifo_status & TIFM_FIFO_READY) { | 388 | if (host->use_dma && (fifo_status & 1)) { |
393 | if (!host->no_dma || tifm_ms_transfer_data(host, 0)) { | 389 | host->cmd_flags |= FIFO_READY; |
390 | rc = tifm_ms_check_status(host); | ||
391 | } | ||
392 | if (!host->use_dma && (fifo_status & TIFM_FIFO_MORE)) { | ||
393 | if (!tifm_ms_transfer_data(host)) { | ||
394 | host->cmd_flags |= FIFO_READY; | 394 | host->cmd_flags |= FIFO_READY; |
395 | rc = tifm_ms_check_status(host); | 395 | rc = tifm_ms_check_status(host); |
396 | } | 396 | } |
@@ -419,9 +419,9 @@ static void tifm_ms_card_event(struct tifm_dev *sock) | |||
419 | host_status, host->cmd_flags); | 419 | host_status, host->cmd_flags); |
420 | 420 | ||
421 | if (host->req) { | 421 | if (host->req) { |
422 | if (host_status & TIFM_MS_TIMEOUT) | 422 | if (host_status & TIFM_MS_STAT_TOE) |
423 | host->req->error = -ETIME; | 423 | host->req->error = -ETIME; |
424 | else if (host_status & TIFM_MS_BADCRC) | 424 | else if (host_status & TIFM_MS_STAT_CRC) |
425 | host->req->error = -EILSEQ; | 425 | host->req->error = -EILSEQ; |
426 | 426 | ||
427 | if (host->req->error) { | 427 | if (host->req->error) { |
@@ -430,18 +430,17 @@ static void tifm_ms_card_event(struct tifm_dev *sock) | |||
430 | writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL); | 430 | writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL); |
431 | } | 431 | } |
432 | 432 | ||
433 | if (host_status & TIFM_MS_EOTPC) | 433 | if (host_status & TIFM_MS_STAT_RDY) |
434 | host->cmd_flags |= CMD_READY; | 434 | host->cmd_flags |= CMD_READY; |
435 | if (host_status & TIFM_MS_INT) | 435 | |
436 | host->cmd_flags |= CARD_READY; | 436 | if (host_status & TIFM_MS_STAT_MSINT) |
437 | host->cmd_flags |= CARD_INT; | ||
437 | 438 | ||
438 | rc = tifm_ms_check_status(host); | 439 | rc = tifm_ms_check_status(host); |
439 | 440 | ||
440 | } | 441 | } |
441 | 442 | ||
442 | writel(TIFM_MS_SYS_NOT_RDY | readl(sock->addr + SOCK_MS_SYSTEM), | 443 | writel(TIFM_MS_SYS_INTCLR | readl(sock->addr + SOCK_MS_SYSTEM), |
443 | sock->addr + SOCK_MS_SYSTEM); | ||
444 | writel((~TIFM_MS_SYS_DATA) & readl(sock->addr + SOCK_MS_SYSTEM), | ||
445 | sock->addr + SOCK_MS_SYSTEM); | 444 | sock->addr + SOCK_MS_SYSTEM); |
446 | 445 | ||
447 | if (!rc) | 446 | if (!rc) |
@@ -497,15 +496,26 @@ static void tifm_ms_set_param(struct memstick_host *msh, | |||
497 | 496 | ||
498 | switch (param) { | 497 | switch (param) { |
499 | case MEMSTICK_POWER: | 498 | case MEMSTICK_POWER: |
500 | /* this is set by card detection mechanism */ | 499 | /* also affected by media detection mechanism */ |
500 | if (value == MEMSTICK_POWER_ON) { | ||
501 | host->mode_mask = TIFM_MS_SYS_SRAC | TIFM_MS_SYS_REI; | ||
502 | writel(TIFM_MS_SYS_RESET, sock->addr + SOCK_MS_SYSTEM); | ||
503 | writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR, | ||
504 | sock->addr + SOCK_MS_SYSTEM); | ||
505 | writel(0xffffffff, sock->addr + SOCK_MS_STATUS); | ||
506 | } else if (value == MEMSTICK_POWER_OFF) { | ||
507 | writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR, | ||
508 | sock->addr + SOCK_MS_SYSTEM); | ||
509 | writel(0xffffffff, sock->addr + SOCK_MS_STATUS); | ||
510 | } | ||
501 | break; | 511 | break; |
502 | case MEMSTICK_INTERFACE: | 512 | case MEMSTICK_INTERFACE: |
503 | if (value == MEMSTICK_SERIAL) { | 513 | if (value == MEMSTICK_SERIAL) { |
504 | host->mode_mask = TIFM_MS_SERIAL; | 514 | host->mode_mask = TIFM_MS_SYS_SRAC | TIFM_MS_SYS_REI; |
505 | writel((~TIFM_CTRL_FAST_CLK) | 515 | writel((~TIFM_CTRL_FAST_CLK) |
506 | & readl(sock->addr + SOCK_CONTROL), | 516 | & readl(sock->addr + SOCK_CONTROL), |
507 | sock->addr + SOCK_CONTROL); | 517 | sock->addr + SOCK_CONTROL); |
508 | } else if (value == MEMSTICK_PARALLEL) { | 518 | } else if (value == MEMSTICK_PAR4) { |
509 | host->mode_mask = 0; | 519 | host->mode_mask = 0; |
510 | writel(TIFM_CTRL_FAST_CLK | 520 | writel(TIFM_CTRL_FAST_CLK |
511 | | readl(sock->addr + SOCK_CONTROL), | 521 | | readl(sock->addr + SOCK_CONTROL), |
@@ -532,21 +542,6 @@ static void tifm_ms_abort(unsigned long data) | |||
532 | tifm_eject(host->dev); | 542 | tifm_eject(host->dev); |
533 | } | 543 | } |
534 | 544 | ||
535 | static int tifm_ms_initialize_host(struct tifm_ms *host) | ||
536 | { | ||
537 | struct tifm_dev *sock = host->dev; | ||
538 | struct memstick_host *msh = tifm_get_drvdata(sock); | ||
539 | |||
540 | host->mode_mask = TIFM_MS_SERIAL; | ||
541 | writel(0x8000, sock->addr + SOCK_MS_SYSTEM); | ||
542 | writel(0x0200 | TIFM_MS_SYS_NOT_RDY, sock->addr + SOCK_MS_SYSTEM); | ||
543 | writel(0xffffffff, sock->addr + SOCK_MS_STATUS); | ||
544 | if (tifm_has_ms_pif(sock)) | ||
545 | msh->caps |= MEMSTICK_CAP_PARALLEL; | ||
546 | |||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | static int tifm_ms_probe(struct tifm_dev *sock) | 545 | static int tifm_ms_probe(struct tifm_dev *sock) |
551 | { | 546 | { |
552 | struct memstick_host *msh; | 547 | struct memstick_host *msh; |
@@ -568,7 +563,6 @@ static int tifm_ms_probe(struct tifm_dev *sock) | |||
568 | tifm_set_drvdata(sock, msh); | 563 | tifm_set_drvdata(sock, msh); |
569 | host->dev = sock; | 564 | host->dev = sock; |
570 | host->timeout_jiffies = msecs_to_jiffies(1000); | 565 | host->timeout_jiffies = msecs_to_jiffies(1000); |
571 | host->no_dma = no_dma; | ||
572 | 566 | ||
573 | setup_timer(&host->timer, tifm_ms_abort, (unsigned long)host); | 567 | setup_timer(&host->timer, tifm_ms_abort, (unsigned long)host); |
574 | 568 | ||
@@ -576,10 +570,10 @@ static int tifm_ms_probe(struct tifm_dev *sock) | |||
576 | msh->set_param = tifm_ms_set_param; | 570 | msh->set_param = tifm_ms_set_param; |
577 | sock->card_event = tifm_ms_card_event; | 571 | sock->card_event = tifm_ms_card_event; |
578 | sock->data_event = tifm_ms_data_event; | 572 | sock->data_event = tifm_ms_data_event; |
579 | rc = tifm_ms_initialize_host(host); | 573 | if (tifm_has_ms_pif(sock)) |
574 | msh->caps |= MEMSTICK_CAP_PAR4; | ||
580 | 575 | ||
581 | if (!rc) | 576 | rc = memstick_add_host(msh); |
582 | rc = memstick_add_host(msh); | ||
583 | if (!rc) | 577 | if (!rc) |
584 | return 0; | 578 | return 0; |
585 | 579 | ||
@@ -601,7 +595,7 @@ static void tifm_ms_remove(struct tifm_dev *sock) | |||
601 | writel(TIFM_FIFO_INT_SETALL, | 595 | writel(TIFM_FIFO_INT_SETALL, |
602 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | 596 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); |
603 | writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL); | 597 | writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL); |
604 | if ((host->req->io_type == MEMSTICK_IO_SG) && !host->no_dma) | 598 | if (host->use_dma) |
605 | tifm_unmap_sg(sock, &host->req->sg, 1, | 599 | tifm_unmap_sg(sock, &host->req->sg, 1, |
606 | host->req->data_dir == READ | 600 | host->req->data_dir == READ |
607 | ? PCI_DMA_TODEVICE | 601 | ? PCI_DMA_TODEVICE |
@@ -617,10 +611,6 @@ static void tifm_ms_remove(struct tifm_dev *sock) | |||
617 | spin_unlock_irqrestore(&sock->lock, flags); | 611 | spin_unlock_irqrestore(&sock->lock, flags); |
618 | 612 | ||
619 | memstick_remove_host(msh); | 613 | memstick_remove_host(msh); |
620 | |||
621 | writel(0x0200 | TIFM_MS_SYS_NOT_RDY, sock->addr + SOCK_MS_SYSTEM); | ||
622 | writel(0xffffffff, sock->addr + SOCK_MS_STATUS); | ||
623 | |||
624 | memstick_free_host(msh); | 614 | memstick_free_host(msh); |
625 | } | 615 | } |
626 | 616 | ||
@@ -628,17 +618,17 @@ static void tifm_ms_remove(struct tifm_dev *sock) | |||
628 | 618 | ||
629 | static int tifm_ms_suspend(struct tifm_dev *sock, pm_message_t state) | 619 | static int tifm_ms_suspend(struct tifm_dev *sock, pm_message_t state) |
630 | { | 620 | { |
621 | struct memstick_host *msh = tifm_get_drvdata(sock); | ||
622 | |||
623 | memstick_suspend_host(msh); | ||
631 | return 0; | 624 | return 0; |
632 | } | 625 | } |
633 | 626 | ||
634 | static int tifm_ms_resume(struct tifm_dev *sock) | 627 | static int tifm_ms_resume(struct tifm_dev *sock) |
635 | { | 628 | { |
636 | struct memstick_host *msh = tifm_get_drvdata(sock); | 629 | struct memstick_host *msh = tifm_get_drvdata(sock); |
637 | struct tifm_ms *host = memstick_priv(msh); | ||
638 | |||
639 | tifm_ms_initialize_host(host); | ||
640 | memstick_detect_change(msh); | ||
641 | 630 | ||
631 | memstick_resume_host(msh); | ||
642 | return 0; | 632 | return 0; |
643 | } | 633 | } |
644 | 634 | ||
@@ -679,7 +669,6 @@ MODULE_AUTHOR("Alex Dubov"); | |||
679 | MODULE_DESCRIPTION("TI FlashMedia MemoryStick driver"); | 669 | MODULE_DESCRIPTION("TI FlashMedia MemoryStick driver"); |
680 | MODULE_LICENSE("GPL"); | 670 | MODULE_LICENSE("GPL"); |
681 | MODULE_DEVICE_TABLE(tifm, tifm_ms_id_tbl); | 671 | MODULE_DEVICE_TABLE(tifm, tifm_ms_id_tbl); |
682 | MODULE_VERSION(DRIVER_VERSION); | ||
683 | 672 | ||
684 | module_init(tifm_ms_init); | 673 | module_init(tifm_ms_init); |
685 | module_exit(tifm_ms_exit); | 674 | module_exit(tifm_ms_exit); |
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c index 63a089b29545..67503ea71d21 100644 --- a/drivers/misc/tifm_7xx1.c +++ b/drivers/misc/tifm_7xx1.c | |||
@@ -368,6 +368,8 @@ static int tifm_7xx1_probe(struct pci_dev *dev, | |||
368 | goto err_out_irq; | 368 | goto err_out_irq; |
369 | 369 | ||
370 | writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1), | 370 | writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1), |
371 | fm->addr + FM_CLEAR_INTERRUPT_ENABLE); | ||
372 | writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1), | ||
371 | fm->addr + FM_SET_INTERRUPT_ENABLE); | 373 | fm->addr + FM_SET_INTERRUPT_ENABLE); |
372 | return 0; | 374 | return 0; |
373 | 375 | ||
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index 600ed7b67ae7..bbccde9f228f 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c | |||
@@ -963,6 +963,7 @@ static int __init ebda_rsrc_controller (void) | |||
963 | 963 | ||
964 | bus_info_ptr1 = ibmphp_find_same_bus_num (hpc_ptr->slots[index].slot_bus_num); | 964 | bus_info_ptr1 = ibmphp_find_same_bus_num (hpc_ptr->slots[index].slot_bus_num); |
965 | if (!bus_info_ptr1) { | 965 | if (!bus_info_ptr1) { |
966 | kfree(tmp_slot); | ||
966 | rc = -ENODEV; | 967 | rc = -ENODEV; |
967 | goto error; | 968 | goto error; |
968 | } | 969 | } |
diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index a64d85821996..c0e50a461055 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c | |||
@@ -138,7 +138,7 @@ static struct of_device_id __devinitdata of_platform_serial_table[] = { | |||
138 | { /* end of list */ }, | 138 | { /* end of list */ }, |
139 | }; | 139 | }; |
140 | 140 | ||
141 | static struct of_platform_driver __devinitdata of_platform_serial_driver = { | 141 | static struct of_platform_driver of_platform_serial_driver = { |
142 | .owner = THIS_MODULE, | 142 | .owner = THIS_MODULE, |
143 | .name = "of_serial", | 143 | .name = "of_serial", |
144 | .probe = of_platform_serial_probe, | 144 | .probe = of_platform_serial_probe, |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index c13955164686..6f45dd669b33 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -131,7 +131,7 @@ config USB_ATMEL_USBA | |||
131 | 131 | ||
132 | config USB_GADGET_FSL_USB2 | 132 | config USB_GADGET_FSL_USB2 |
133 | boolean "Freescale Highspeed USB DR Peripheral Controller" | 133 | boolean "Freescale Highspeed USB DR Peripheral Controller" |
134 | depends on MPC834x || PPC_MPC831x | 134 | depends on FSL_SOC |
135 | select USB_GADGET_DUALSPEED | 135 | select USB_GADGET_DUALSPEED |
136 | help | 136 | help |
137 | Some of Freescale PowerPC processors have a High Speed | 137 | Some of Freescale PowerPC processors have a High Speed |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index b8ad55aff842..46ee7f4c0912 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -281,23 +281,44 @@ static void ehci_iaa_watchdog(unsigned long param) | |||
281 | { | 281 | { |
282 | struct ehci_hcd *ehci = (struct ehci_hcd *) param; | 282 | struct ehci_hcd *ehci = (struct ehci_hcd *) param; |
283 | unsigned long flags; | 283 | unsigned long flags; |
284 | u32 status, cmd; | ||
285 | 284 | ||
286 | spin_lock_irqsave (&ehci->lock, flags); | 285 | spin_lock_irqsave (&ehci->lock, flags); |
287 | WARN_ON(!ehci->reclaim); | ||
288 | 286 | ||
289 | status = ehci_readl(ehci, &ehci->regs->status); | 287 | /* Lost IAA irqs wedge things badly; seen first with a vt8235. |
290 | cmd = ehci_readl(ehci, &ehci->regs->command); | 288 | * So we need this watchdog, but must protect it against both |
291 | ehci_dbg(ehci, "IAA watchdog: status %x cmd %x\n", status, cmd); | 289 | * (a) SMP races against real IAA firing and retriggering, and |
292 | 290 | * (b) clean HC shutdown, when IAA watchdog was pending. | |
293 | /* lost IAA irqs wedge things badly; seen first with a vt8235 */ | 291 | */ |
294 | if (ehci->reclaim) { | 292 | if (ehci->reclaim |
295 | if (status & STS_IAA) { | 293 | && !timer_pending(&ehci->iaa_watchdog) |
296 | ehci_vdbg (ehci, "lost IAA\n"); | 294 | && HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { |
295 | u32 cmd, status; | ||
296 | |||
297 | /* If we get here, IAA is *REALLY* late. It's barely | ||
298 | * conceivable that the system is so busy that CMD_IAAD | ||
299 | * is still legitimately set, so let's be sure it's | ||
300 | * clear before we read STS_IAA. (The HC should clear | ||
301 | * CMD_IAAD when it sets STS_IAA.) | ||
302 | */ | ||
303 | cmd = ehci_readl(ehci, &ehci->regs->command); | ||
304 | if (cmd & CMD_IAAD) | ||
305 | ehci_writel(ehci, cmd & ~CMD_IAAD, | ||
306 | &ehci->regs->command); | ||
307 | |||
308 | /* If IAA is set here it either legitimately triggered | ||
309 | * before we cleared IAAD above (but _way_ late, so we'll | ||
310 | * still count it as lost) ... or a silicon erratum: | ||
311 | * - VIA seems to set IAA without triggering the IRQ; | ||
312 | * - IAAD potentially cleared without setting IAA. | ||
313 | */ | ||
314 | status = ehci_readl(ehci, &ehci->regs->status); | ||
315 | if ((status & STS_IAA) || !(cmd & CMD_IAAD)) { | ||
297 | COUNT (ehci->stats.lost_iaa); | 316 | COUNT (ehci->stats.lost_iaa); |
298 | ehci_writel(ehci, STS_IAA, &ehci->regs->status); | 317 | ehci_writel(ehci, STS_IAA, &ehci->regs->status); |
299 | } | 318 | } |
300 | ehci_writel(ehci, cmd & ~CMD_IAAD, &ehci->regs->command); | 319 | |
320 | ehci_vdbg(ehci, "IAA watchdog: status %x cmd %x\n", | ||
321 | status, cmd); | ||
301 | end_unlink_async(ehci); | 322 | end_unlink_async(ehci); |
302 | } | 323 | } |
303 | 324 | ||
@@ -631,7 +652,7 @@ static int ehci_run (struct usb_hcd *hcd) | |||
631 | static irqreturn_t ehci_irq (struct usb_hcd *hcd) | 652 | static irqreturn_t ehci_irq (struct usb_hcd *hcd) |
632 | { | 653 | { |
633 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 654 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
634 | u32 status, pcd_status = 0; | 655 | u32 status, pcd_status = 0, cmd; |
635 | int bh; | 656 | int bh; |
636 | 657 | ||
637 | spin_lock (&ehci->lock); | 658 | spin_lock (&ehci->lock); |
@@ -652,7 +673,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
652 | 673 | ||
653 | /* clear (just) interrupts */ | 674 | /* clear (just) interrupts */ |
654 | ehci_writel(ehci, status, &ehci->regs->status); | 675 | ehci_writel(ehci, status, &ehci->regs->status); |
655 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted write */ | 676 | cmd = ehci_readl(ehci, &ehci->regs->command); |
656 | bh = 0; | 677 | bh = 0; |
657 | 678 | ||
658 | #ifdef EHCI_VERBOSE_DEBUG | 679 | #ifdef EHCI_VERBOSE_DEBUG |
@@ -673,8 +694,17 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
673 | 694 | ||
674 | /* complete the unlinking of some qh [4.15.2.3] */ | 695 | /* complete the unlinking of some qh [4.15.2.3] */ |
675 | if (status & STS_IAA) { | 696 | if (status & STS_IAA) { |
676 | COUNT (ehci->stats.reclaim); | 697 | /* guard against (alleged) silicon errata */ |
677 | end_unlink_async(ehci); | 698 | if (cmd & CMD_IAAD) { |
699 | ehci_writel(ehci, cmd & ~CMD_IAAD, | ||
700 | &ehci->regs->command); | ||
701 | ehci_dbg(ehci, "IAA with IAAD still set?\n"); | ||
702 | } | ||
703 | if (ehci->reclaim) { | ||
704 | COUNT(ehci->stats.reclaim); | ||
705 | end_unlink_async(ehci); | ||
706 | } else | ||
707 | ehci_dbg(ehci, "IAA with nothing to reclaim?\n"); | ||
678 | } | 708 | } |
679 | 709 | ||
680 | /* remote wakeup [4.3.1] */ | 710 | /* remote wakeup [4.3.1] */ |
@@ -781,7 +811,7 @@ static int ehci_urb_enqueue ( | |||
781 | static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | 811 | static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) |
782 | { | 812 | { |
783 | /* failfast */ | 813 | /* failfast */ |
784 | if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) | 814 | if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state) && ehci->reclaim) |
785 | end_unlink_async(ehci); | 815 | end_unlink_async(ehci); |
786 | 816 | ||
787 | /* if it's not linked then there's nothing to do */ | 817 | /* if it's not linked then there's nothing to do */ |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 08c65c1a3771..779d07851a4d 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -94,6 +94,7 @@ static struct usb_device_id id_table_earthmate [] = { | |||
94 | 94 | ||
95 | static struct usb_device_id id_table_cyphidcomrs232 [] = { | 95 | static struct usb_device_id id_table_cyphidcomrs232 [] = { |
96 | { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, | 96 | { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, |
97 | { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, | ||
97 | { } /* Terminating entry */ | 98 | { } /* Terminating entry */ |
98 | }; | 99 | }; |
99 | 100 | ||
@@ -106,6 +107,7 @@ static struct usb_device_id id_table_combined [] = { | |||
106 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, | 107 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, |
107 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, | 108 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, |
108 | { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, | 109 | { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, |
110 | { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, | ||
109 | { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, | 111 | { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, |
110 | { } /* Terminating entry */ | 112 | { } /* Terminating entry */ |
111 | }; | 113 | }; |
diff --git a/drivers/usb/serial/cypress_m8.h b/drivers/usb/serial/cypress_m8.h index e1c7c27e18b7..0388065bb794 100644 --- a/drivers/usb/serial/cypress_m8.h +++ b/drivers/usb/serial/cypress_m8.h | |||
@@ -19,6 +19,10 @@ | |||
19 | #define VENDOR_ID_CYPRESS 0x04b4 | 19 | #define VENDOR_ID_CYPRESS 0x04b4 |
20 | #define PRODUCT_ID_CYPHIDCOM 0x5500 | 20 | #define PRODUCT_ID_CYPHIDCOM 0x5500 |
21 | 21 | ||
22 | /* Powercom UPS, chip CY7C63723 */ | ||
23 | #define VENDOR_ID_POWERCOM 0x0d9f | ||
24 | #define PRODUCT_ID_UPS 0x0002 | ||
25 | |||
22 | /* Nokia CA-42 USB to serial cable */ | 26 | /* Nokia CA-42 USB to serial cable */ |
23 | #define VENDOR_ID_DAZZLE 0x07d0 | 27 | #define VENDOR_ID_DAZZLE 0x07d0 |
24 | #define PRODUCT_ID_CA42 0x4101 | 28 | #define PRODUCT_ID_CA42 0x4101 |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 91dc433dbcf1..3abb3c863647 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -359,6 +359,7 @@ static struct usb_device_id id_table_combined [] = { | |||
359 | { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, | 359 | { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, |
360 | { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, | 360 | { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, |
361 | { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) }, | 361 | { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) }, |
362 | { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) }, | ||
362 | { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID), | 363 | { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID), |
363 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 364 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
364 | { USB_DEVICE(FIC_VID, FIC_NEO1973_DEBUG_PID), | 365 | { USB_DEVICE(FIC_VID, FIC_NEO1973_DEBUG_PID), |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index e1eb742abcd5..6da539ede0ee 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -557,6 +557,9 @@ | |||
557 | #define TML_VID 0x1B91 /* Vendor ID */ | 557 | #define TML_VID 0x1B91 /* Vendor ID */ |
558 | #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ | 558 | #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ |
559 | 559 | ||
560 | /* Propox devices */ | ||
561 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 | ||
562 | |||
560 | /* Commands */ | 563 | /* Commands */ |
561 | #define FTDI_SIO_RESET 0 /* Reset the port */ | 564 | #define FTDI_SIO_RESET 0 /* Reset the port */ |
562 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ | 565 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 97fa3c428435..7cfce9dabb90 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -323,7 +323,7 @@ static void flush_and_resubmit_read_urb (struct usb_serial_port *port) | |||
323 | room = tty_buffer_request_room(tty, urb->actual_length); | 323 | room = tty_buffer_request_room(tty, urb->actual_length); |
324 | if (room) { | 324 | if (room) { |
325 | tty_insert_flip_string(tty, urb->transfer_buffer, room); | 325 | tty_insert_flip_string(tty, urb->transfer_buffer, room); |
326 | tty_flip_buffer_push(tty); /* is this allowed from an URB callback ? */ | 326 | tty_flip_buffer_push(tty); |
327 | } | 327 | } |
328 | } | 328 | } |
329 | 329 | ||
@@ -349,10 +349,12 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb) | |||
349 | 349 | ||
350 | /* Throttle the device if requested by tty */ | 350 | /* Throttle the device if requested by tty */ |
351 | spin_lock_irqsave(&port->lock, flags); | 351 | spin_lock_irqsave(&port->lock, flags); |
352 | if (!(port->throttled = port->throttle_req)) | 352 | if (!(port->throttled = port->throttle_req)) { |
353 | /* Handle data and continue reading from device */ | 353 | spin_unlock_irqrestore(&port->lock, flags); |
354 | flush_and_resubmit_read_urb(port); | 354 | flush_and_resubmit_read_urb(port); |
355 | spin_unlock_irqrestore(&port->lock, flags); | 355 | } else { |
356 | spin_unlock_irqrestore(&port->lock, flags); | ||
357 | } | ||
356 | } | 358 | } |
357 | EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); | 359 | EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); |
358 | 360 | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 828a4377ec6a..a396fbbdc9c2 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -111,6 +111,42 @@ static int option_send_setup(struct usb_serial_port *port); | |||
111 | #define HUAWEI_PRODUCT_E220BIS 0x1004 | 111 | #define HUAWEI_PRODUCT_E220BIS 0x1004 |
112 | 112 | ||
113 | #define NOVATELWIRELESS_VENDOR_ID 0x1410 | 113 | #define NOVATELWIRELESS_VENDOR_ID 0x1410 |
114 | |||
115 | /* MERLIN EVDO PRODUCTS */ | ||
116 | #define NOVATELWIRELESS_PRODUCT_V640 0x1100 | ||
117 | #define NOVATELWIRELESS_PRODUCT_V620 0x1110 | ||
118 | #define NOVATELWIRELESS_PRODUCT_V740 0x1120 | ||
119 | #define NOVATELWIRELESS_PRODUCT_V720 0x1130 | ||
120 | |||
121 | /* MERLIN HSDPA/HSPA PRODUCTS */ | ||
122 | #define NOVATELWIRELESS_PRODUCT_U730 0x1400 | ||
123 | #define NOVATELWIRELESS_PRODUCT_U740 0x1410 | ||
124 | #define NOVATELWIRELESS_PRODUCT_U870 0x1420 | ||
125 | #define NOVATELWIRELESS_PRODUCT_XU870 0x1430 | ||
126 | #define NOVATELWIRELESS_PRODUCT_X950D 0x1450 | ||
127 | |||
128 | /* EXPEDITE PRODUCTS */ | ||
129 | #define NOVATELWIRELESS_PRODUCT_EV620 0x2100 | ||
130 | #define NOVATELWIRELESS_PRODUCT_ES720 0x2110 | ||
131 | #define NOVATELWIRELESS_PRODUCT_E725 0x2120 | ||
132 | #define NOVATELWIRELESS_PRODUCT_EU730 0x2400 | ||
133 | #define NOVATELWIRELESS_PRODUCT_EU740 0x2410 | ||
134 | #define NOVATELWIRELESS_PRODUCT_EU870D 0x2420 | ||
135 | |||
136 | /* OVATION PRODUCTS */ | ||
137 | #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 | ||
138 | #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 | ||
139 | |||
140 | /* FUTURE NOVATEL PRODUCTS */ | ||
141 | #define NOVATELWIRELESS_PRODUCT_EVDO_1 0x6000 | ||
142 | #define NOVATELWIRELESS_PRODUCT_HSPA_1 0x7000 | ||
143 | #define NOVATELWIRELESS_PRODUCT_EMBEDDED_1 0x8000 | ||
144 | #define NOVATELWIRELESS_PRODUCT_GLOBAL_1 0x9000 | ||
145 | #define NOVATELWIRELESS_PRODUCT_EVDO_2 0x6001 | ||
146 | #define NOVATELWIRELESS_PRODUCT_HSPA_2 0x7001 | ||
147 | #define NOVATELWIRELESS_PRODUCT_EMBEDDED_2 0x8001 | ||
148 | #define NOVATELWIRELESS_PRODUCT_GLOBAL_2 0x9001 | ||
149 | |||
114 | #define DELL_VENDOR_ID 0x413C | 150 | #define DELL_VENDOR_ID 0x413C |
115 | 151 | ||
116 | #define KYOCERA_VENDOR_ID 0x0c88 | 152 | #define KYOCERA_VENDOR_ID 0x0c88 |
@@ -168,21 +204,34 @@ static struct usb_device_id option_ids[] = { | |||
168 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, | 204 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, |
169 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, | 205 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, |
170 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, | 206 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, |
171 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1100) }, /* Novatel Merlin XS620/S640 */ | 207 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */ |
172 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1110) }, /* Novatel Merlin S620 */ | 208 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */ |
173 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1120) }, /* Novatel Merlin EX720 */ | 209 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, /* Novatel Merlin EX720/V740/X720 */ |
174 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1130) }, /* Novatel Merlin S720 */ | 210 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V720) }, /* Novatel Merlin V720/S720/PC720 */ |
175 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1400) }, /* Novatel U730 */ | 211 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U730) }, /* Novatel U730/U740 (VF version) */ |
176 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1410) }, /* Novatel U740 */ | 212 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U740) }, /* Novatel U740 */ |
177 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1420) }, /* Novatel EU870 */ | 213 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U870) }, /* Novatel U870 */ |
178 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */ | 214 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_XU870) }, /* Novatel Merlin XU870 HSDPA/3G */ |
179 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2100) }, /* Novatel EV620 CDMA/EV-DO */ | 215 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_X950D) }, /* Novatel X950D */ |
180 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */ | 216 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EV620) }, /* Novatel EV620/ES620 CDMA/EV-DO */ |
217 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES720) }, /* Novatel ES620/ES720/U720/USB720 */ | ||
218 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E725) }, /* Novatel E725/E726 */ | ||
181 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ | 219 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ |
182 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ | 220 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU730) }, /* Novatel EU730 and Vodafone EU740 */ |
183 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4100) }, /* Novatel U727 */ | 221 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU740) }, /* Novatel non-Vodafone EU740 */ |
184 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4400) }, /* Novatel MC950 */ | 222 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */ |
223 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ | ||
224 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ | ||
185 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x5010) }, /* Novatel U727 */ | 225 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x5010) }, /* Novatel U727 */ |
226 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_1) }, /* Novatel EVDO product */ | ||
227 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_1) }, /* Novatel HSPA product */ | ||
228 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_1) }, /* Novatel Embedded product */ | ||
229 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_1) }, /* Novatel Global product */ | ||
230 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_2) }, /* Novatel EVDO product */ | ||
231 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_2) }, /* Novatel HSPA product */ | ||
232 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_2) }, /* Novatel Embedded product */ | ||
233 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_2) }, /* Novatel Global product */ | ||
234 | |||
186 | { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ | 235 | { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ |
187 | { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ | 236 | { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ |
188 | { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ | 237 | { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ |
diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index d43a3415e12f..6d14327c921d 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c | |||
@@ -522,8 +522,8 @@ int sddr55_reset(struct us_data *us) { | |||
522 | 522 | ||
523 | static unsigned long sddr55_get_capacity(struct us_data *us) { | 523 | static unsigned long sddr55_get_capacity(struct us_data *us) { |
524 | 524 | ||
525 | unsigned char manufacturerID; | 525 | unsigned char uninitialized_var(manufacturerID); |
526 | unsigned char deviceID; | 526 | unsigned char uninitialized_var(deviceID); |
527 | int result; | 527 | int result; |
528 | struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra; | 528 | struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra; |
529 | 529 | ||
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 758435f8a6f8..e0b0580705e4 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -553,6 +553,19 @@ config FB_BF54X_LQ043 | |||
553 | help | 553 | help |
554 | This is the framebuffer device driver for a SHARP LQ043T1DG01 TFT LCD | 554 | This is the framebuffer device driver for a SHARP LQ043T1DG01 TFT LCD |
555 | 555 | ||
556 | config FB_BFIN_T350MCQB | ||
557 | tristate "Varitronix COG-T350MCQB TFT LCD display (BF527 EZKIT)" | ||
558 | depends on FB && BLACKFIN | ||
559 | select BFIN_GPTIMERS | ||
560 | select FB_CFB_FILLRECT | ||
561 | select FB_CFB_COPYAREA | ||
562 | select FB_CFB_IMAGEBLIT | ||
563 | help | ||
564 | This is the framebuffer device driver for a Varitronix VL-PS-COG-T350MCQB-01 display TFT LCD | ||
565 | This display is a QVGA 320x240 24-bit RGB display interfaced by an 8-bit wide PPI | ||
566 | It uses PPI[0..7] PPI_FS1, PPI_FS2 and PPI_CLK. | ||
567 | |||
568 | |||
556 | config FB_STI | 569 | config FB_STI |
557 | tristate "HP STI frame buffer device support" | 570 | tristate "HP STI frame buffer device support" |
558 | depends on FB && PARISC | 571 | depends on FB && PARISC |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 83e02b3429b6..03371c789039 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -122,6 +122,7 @@ obj-$(CONFIG_FB_EFI) += efifb.o | |||
122 | obj-$(CONFIG_FB_VGA16) += vga16fb.o | 122 | obj-$(CONFIG_FB_VGA16) += vga16fb.o |
123 | obj-$(CONFIG_FB_OF) += offb.o | 123 | obj-$(CONFIG_FB_OF) += offb.o |
124 | obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o | 124 | obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o |
125 | obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o | ||
125 | 126 | ||
126 | # the test framebuffer is last | 127 | # the test framebuffer is last |
127 | obj-$(CONFIG_FB_VIRTUAL) += vfb.o | 128 | obj-$(CONFIG_FB_VIRTUAL) += vfb.o |
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c index 0ce791e6f79c..986a550c0439 100644 --- a/drivers/video/bf54x-lq043fb.c +++ b/drivers/video/bf54x-lq043fb.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * | 8 | * |
9 | * | 9 | * |
10 | * Modified: | 10 | * Modified: |
11 | * Copyright 2004-2007 Analog Devices Inc. | 11 | * Copyright 2007-2008 Analog Devices Inc. |
12 | * | 12 | * |
13 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 13 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
14 | * | 14 | * |
@@ -241,7 +241,7 @@ static int request_ports(struct bfin_bf54xfb_info *fbi) | |||
241 | u16 eppi_req_18[] = EPPI0_18; | 241 | u16 eppi_req_18[] = EPPI0_18; |
242 | u16 disp = fbi->mach_info->disp; | 242 | u16 disp = fbi->mach_info->disp; |
243 | 243 | ||
244 | if (gpio_request(disp, NULL)) { | 244 | if (gpio_request(disp, DRIVER_NAME)) { |
245 | printk(KERN_ERR "Requesting GPIO %d faild\n", disp); | 245 | printk(KERN_ERR "Requesting GPIO %d faild\n", disp); |
246 | return -EFAULT; | 246 | return -EFAULT; |
247 | } | 247 | } |
@@ -672,7 +672,7 @@ static int __init bfin_bf54x_probe(struct platform_device *pdev) | |||
672 | &bfin_lq043fb_bl_ops); | 672 | &bfin_lq043fb_bl_ops); |
673 | bl_dev->props.max_brightness = 255; | 673 | bl_dev->props.max_brightness = 255; |
674 | 674 | ||
675 | lcd_dev = lcd_device_register(DRIVER_NAME, NULL, &bfin_lcd_ops); | 675 | lcd_dev = lcd_device_register(DRIVER_NAME, &pdev->dev, NULL, &bfin_lcd_ops); |
676 | lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n"); | 676 | lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n"); |
677 | #endif | 677 | #endif |
678 | 678 | ||
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c new file mode 100644 index 000000000000..a2bb2de9e020 --- /dev/null +++ b/drivers/video/bfin-t350mcqb-fb.c | |||
@@ -0,0 +1,685 @@ | |||
1 | /* | ||
2 | * File: drivers/video/bfin-t350mcqb-fb.c | ||
3 | * Based on: | ||
4 | * Author: Michael Hennerich <hennerich@blackfin.uclinux.org> | ||
5 | * | ||
6 | * Created: | ||
7 | * Description: Blackfin LCD Framebufer driver | ||
8 | * | ||
9 | * | ||
10 | * Modified: | ||
11 | * Copyright 2004-2007 Analog Devices Inc. | ||
12 | * | ||
13 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or modify | ||
16 | * it under the terms of the GNU General Public License as published by | ||
17 | * the Free Software Foundation; either version 2 of the License, or | ||
18 | * (at your option) any later version. | ||
19 | * | ||
20 | * This program is distributed in the hope that it will be useful, | ||
21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
23 | * GNU General Public License for more details. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License | ||
26 | * along with this program; if not, see the file COPYING, or write | ||
27 | * to the Free Software Foundation, Inc., | ||
28 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
29 | */ | ||
30 | |||
31 | #include <linux/module.h> | ||
32 | #include <linux/kernel.h> | ||
33 | #include <linux/errno.h> | ||
34 | #include <linux/string.h> | ||
35 | #include <linux/fb.h> | ||
36 | #include <linux/init.h> | ||
37 | #include <linux/types.h> | ||
38 | #include <linux/interrupt.h> | ||
39 | #include <linux/device.h> | ||
40 | #include <linux/backlight.h> | ||
41 | #include <linux/lcd.h> | ||
42 | #include <linux/dma-mapping.h> | ||
43 | #include <linux/platform_device.h> | ||
44 | |||
45 | #include <asm/blackfin.h> | ||
46 | #include <asm/irq.h> | ||
47 | #include <asm/dma-mapping.h> | ||
48 | #include <asm/dma.h> | ||
49 | #include <asm/portmux.h> | ||
50 | #include <asm/gptimers.h> | ||
51 | |||
52 | #define NO_BL_SUPPORT | ||
53 | |||
54 | #define LCD_X_RES 320 /* Horizontal Resolution */ | ||
55 | #define LCD_Y_RES 240 /* Vertical Resolution */ | ||
56 | #define LCD_BPP 24 /* Bit Per Pixel */ | ||
57 | |||
58 | #define DMA_BUS_SIZE 16 | ||
59 | #define LCD_CLK (12*1000*1000) /* 12MHz */ | ||
60 | |||
61 | #define CLOCKS_PER_PIX 3 | ||
62 | |||
63 | /* | ||
64 | * HS and VS timing parameters (all in number of PPI clk ticks) | ||
65 | */ | ||
66 | |||
67 | #define U_LINE 1 /* Blanking Lines */ | ||
68 | |||
69 | #define H_ACTPIX (LCD_X_RES * CLOCKS_PER_PIX) /* active horizontal pixel */ | ||
70 | #define H_PERIOD (408 * CLOCKS_PER_PIX) /* HS period */ | ||
71 | #define H_PULSE 90 /* HS pulse width */ | ||
72 | #define H_START 204 /* first valid pixel */ | ||
73 | |||
74 | #define V_LINES (LCD_Y_RES + U_LINE) /* total vertical lines */ | ||
75 | #define V_PULSE (3 * H_PERIOD) /* VS pulse width (1-5 H_PERIODs) */ | ||
76 | #define V_PERIOD (H_PERIOD * V_LINES) /* VS period */ | ||
77 | |||
78 | #define ACTIVE_VIDEO_MEM_OFFSET (U_LINE * H_ACTPIX) | ||
79 | |||
80 | #define BFIN_LCD_NBR_PALETTE_ENTRIES 256 | ||
81 | |||
82 | #define DRIVER_NAME "bfin-t350mcqb" | ||
83 | static char driver_name[] = DRIVER_NAME; | ||
84 | |||
85 | struct bfin_t350mcqbfb_info { | ||
86 | struct fb_info *fb; | ||
87 | struct device *dev; | ||
88 | unsigned char *fb_buffer; /* RGB Buffer */ | ||
89 | dma_addr_t dma_handle; | ||
90 | int lq043_mmap; | ||
91 | int lq043_open_cnt; | ||
92 | int irq; | ||
93 | spinlock_t lock; /* lock */ | ||
94 | }; | ||
95 | |||
96 | static int nocursor; | ||
97 | module_param(nocursor, int, 0644); | ||
98 | MODULE_PARM_DESC(nocursor, "cursor enable/disable"); | ||
99 | |||
100 | #define PPI_TX_MODE 0x2 | ||
101 | #define PPI_XFER_TYPE_11 0xC | ||
102 | #define PPI_PORT_CFG_01 0x10 | ||
103 | #define PPI_PACK_EN 0x80 | ||
104 | #define PPI_POLS_1 0x8000 | ||
105 | |||
106 | static void bfin_t350mcqb_config_ppi(struct bfin_t350mcqbfb_info *fbi) | ||
107 | { | ||
108 | bfin_write_PPI_DELAY(H_START); | ||
109 | bfin_write_PPI_COUNT(H_ACTPIX-1); | ||
110 | bfin_write_PPI_FRAME(V_LINES); | ||
111 | |||
112 | bfin_write_PPI_CONTROL(PPI_TX_MODE | /* output mode , PORT_DIR */ | ||
113 | PPI_XFER_TYPE_11 | /* sync mode XFR_TYPE */ | ||
114 | PPI_PORT_CFG_01 | /* two frame sync PORT_CFG */ | ||
115 | PPI_PACK_EN | /* packing enabled PACK_EN */ | ||
116 | PPI_POLS_1); /* faling edge syncs POLS */ | ||
117 | } | ||
118 | |||
119 | static inline void bfin_t350mcqb_disable_ppi(void) | ||
120 | { | ||
121 | bfin_write_PPI_CONTROL(bfin_read_PPI_CONTROL() & ~PORT_EN); | ||
122 | } | ||
123 | |||
124 | static inline void bfin_t350mcqb_enable_ppi(void) | ||
125 | { | ||
126 | bfin_write_PPI_CONTROL(bfin_read_PPI_CONTROL() | PORT_EN); | ||
127 | } | ||
128 | |||
129 | static void bfin_t350mcqb_start_timers(void) | ||
130 | { | ||
131 | unsigned long flags; | ||
132 | |||
133 | local_irq_save(flags); | ||
134 | enable_gptimers(TIMER1bit); | ||
135 | enable_gptimers(TIMER0bit); | ||
136 | local_irq_restore(flags); | ||
137 | } | ||
138 | |||
139 | static void bfin_t350mcqb_stop_timers(void) | ||
140 | { | ||
141 | disable_gptimers(TIMER0bit | TIMER1bit); | ||
142 | |||
143 | set_gptimer_status(0, TIMER_STATUS_TRUN0 | TIMER_STATUS_TRUN1 | | ||
144 | TIMER_STATUS_TIMIL0 | TIMER_STATUS_TIMIL1 | | ||
145 | TIMER_STATUS_TOVF0 | TIMER_STATUS_TOVF1); | ||
146 | |||
147 | } | ||
148 | |||
149 | static void bfin_t350mcqb_init_timers(void) | ||
150 | { | ||
151 | |||
152 | bfin_t350mcqb_stop_timers(); | ||
153 | |||
154 | set_gptimer_period(TIMER0_id, H_PERIOD); | ||
155 | set_gptimer_pwidth(TIMER0_id, H_PULSE); | ||
156 | set_gptimer_config(TIMER0_id, TIMER_MODE_PWM | TIMER_PERIOD_CNT | | ||
157 | TIMER_TIN_SEL | TIMER_CLK_SEL| | ||
158 | TIMER_EMU_RUN); | ||
159 | |||
160 | set_gptimer_period(TIMER1_id, V_PERIOD); | ||
161 | set_gptimer_pwidth(TIMER1_id, V_PULSE); | ||
162 | set_gptimer_config(TIMER1_id, TIMER_MODE_PWM | TIMER_PERIOD_CNT | | ||
163 | TIMER_TIN_SEL | TIMER_CLK_SEL | | ||
164 | TIMER_EMU_RUN); | ||
165 | |||
166 | } | ||
167 | |||
168 | static void bfin_t350mcqb_config_dma(struct bfin_t350mcqbfb_info *fbi) | ||
169 | { | ||
170 | |||
171 | set_dma_config(CH_PPI, | ||
172 | set_bfin_dma_config(DIR_READ, DMA_FLOW_AUTO, | ||
173 | INTR_DISABLE, DIMENSION_2D, | ||
174 | DATA_SIZE_16, | ||
175 | DMA_NOSYNC_KEEP_DMA_BUF)); | ||
176 | set_dma_x_count(CH_PPI, (LCD_X_RES * LCD_BPP) / DMA_BUS_SIZE); | ||
177 | set_dma_x_modify(CH_PPI, DMA_BUS_SIZE / 8); | ||
178 | set_dma_y_count(CH_PPI, V_LINES); | ||
179 | |||
180 | set_dma_y_modify(CH_PPI, DMA_BUS_SIZE / 8); | ||
181 | set_dma_start_addr(CH_PPI, (unsigned long)fbi->fb_buffer); | ||
182 | |||
183 | } | ||
184 | |||
185 | static int bfin_t350mcqb_request_ports(int action) | ||
186 | { | ||
187 | u16 ppi0_req_8[] = {P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, | ||
188 | P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, | ||
189 | P_PPI0_D3, P_PPI0_D4, P_PPI0_D5, | ||
190 | P_PPI0_D6, P_PPI0_D7, 0}; | ||
191 | |||
192 | if (action) { | ||
193 | if (peripheral_request_list(ppi0_req_8, DRIVER_NAME)) { | ||
194 | printk(KERN_ERR "Requesting Peripherals faild\n"); | ||
195 | return -EFAULT; | ||
196 | } | ||
197 | } else | ||
198 | peripheral_free_list(ppi0_req_8); | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static int bfin_t350mcqb_fb_open(struct fb_info *info, int user) | ||
204 | { | ||
205 | struct bfin_t350mcqbfb_info *fbi = info->par; | ||
206 | |||
207 | spin_lock(&fbi->lock); | ||
208 | fbi->lq043_open_cnt++; | ||
209 | |||
210 | if (fbi->lq043_open_cnt <= 1) { | ||
211 | |||
212 | bfin_t350mcqb_disable_ppi(); | ||
213 | SSYNC(); | ||
214 | |||
215 | bfin_t350mcqb_config_dma(fbi); | ||
216 | bfin_t350mcqb_config_ppi(fbi); | ||
217 | bfin_t350mcqb_init_timers(); | ||
218 | |||
219 | /* start dma */ | ||
220 | enable_dma(CH_PPI); | ||
221 | bfin_t350mcqb_enable_ppi(); | ||
222 | bfin_t350mcqb_start_timers(); | ||
223 | } | ||
224 | |||
225 | spin_unlock(&fbi->lock); | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static int bfin_t350mcqb_fb_release(struct fb_info *info, int user) | ||
231 | { | ||
232 | struct bfin_t350mcqbfb_info *fbi = info->par; | ||
233 | |||
234 | spin_lock(&fbi->lock); | ||
235 | |||
236 | fbi->lq043_open_cnt--; | ||
237 | fbi->lq043_mmap = 0; | ||
238 | |||
239 | if (fbi->lq043_open_cnt <= 0) { | ||
240 | bfin_t350mcqb_disable_ppi(); | ||
241 | SSYNC(); | ||
242 | disable_dma(CH_PPI); | ||
243 | bfin_t350mcqb_stop_timers(); | ||
244 | memset(fbi->fb_buffer, 0, info->fix.smem_len); | ||
245 | } | ||
246 | |||
247 | spin_unlock(&fbi->lock); | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | static int bfin_t350mcqb_fb_check_var(struct fb_var_screeninfo *var, | ||
253 | struct fb_info *info) | ||
254 | { | ||
255 | |||
256 | if (var->bits_per_pixel != LCD_BPP) { | ||
257 | pr_debug("%s: depth not supported: %u BPP\n", __FUNCTION__, | ||
258 | var->bits_per_pixel); | ||
259 | return -EINVAL; | ||
260 | } | ||
261 | |||
262 | if (info->var.xres != var->xres || info->var.yres != var->yres || | ||
263 | info->var.xres_virtual != var->xres_virtual || | ||
264 | info->var.yres_virtual != var->yres_virtual) { | ||
265 | pr_debug("%s: Resolution not supported: X%u x Y%u \n", | ||
266 | __FUNCTION__, var->xres, var->yres); | ||
267 | return -EINVAL; | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * Memory limit | ||
272 | */ | ||
273 | |||
274 | if ((info->fix.line_length * var->yres_virtual) > info->fix.smem_len) { | ||
275 | pr_debug("%s: Memory Limit requested yres_virtual = %u\n", | ||
276 | __FUNCTION__, var->yres_virtual); | ||
277 | return -ENOMEM; | ||
278 | } | ||
279 | |||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static int bfin_t350mcqb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) | ||
284 | { | ||
285 | struct bfin_t350mcqbfb_info *fbi = info->par; | ||
286 | |||
287 | if (fbi->lq043_mmap) | ||
288 | return -1; | ||
289 | |||
290 | spin_lock(&fbi->lock); | ||
291 | fbi->lq043_mmap = 1; | ||
292 | spin_unlock(&fbi->lock); | ||
293 | |||
294 | vma->vm_start = (unsigned long)(fbi->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET); | ||
295 | |||
296 | vma->vm_end = vma->vm_start + info->fix.smem_len; | ||
297 | /* For those who don't understand how mmap works, go read | ||
298 | * Documentation/nommu-mmap.txt. | ||
299 | * For those that do, you will know that the VM_MAYSHARE flag | ||
300 | * must be set in the vma->vm_flags structure on noMMU | ||
301 | * Other flags can be set, and are documented in | ||
302 | * include/linux/mm.h | ||
303 | */ | ||
304 | vma->vm_flags |= VM_MAYSHARE; | ||
305 | |||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | int bfin_t350mcqb_fb_cursor(struct fb_info *info, struct fb_cursor *cursor) | ||
310 | { | ||
311 | if (nocursor) | ||
312 | return 0; | ||
313 | else | ||
314 | return -EINVAL; /* just to force soft_cursor() call */ | ||
315 | } | ||
316 | |||
317 | static int bfin_t350mcqb_fb_setcolreg(u_int regno, u_int red, u_int green, | ||
318 | u_int blue, u_int transp, | ||
319 | struct fb_info *info) | ||
320 | { | ||
321 | if (regno >= BFIN_LCD_NBR_PALETTE_ENTRIES) | ||
322 | return -EINVAL; | ||
323 | |||
324 | if (info->var.grayscale) { | ||
325 | /* grayscale = 0.30*R + 0.59*G + 0.11*B */ | ||
326 | red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; | ||
327 | } | ||
328 | |||
329 | if (info->fix.visual == FB_VISUAL_TRUECOLOR) { | ||
330 | |||
331 | u32 value; | ||
332 | /* Place color in the pseudopalette */ | ||
333 | if (regno > 16) | ||
334 | return -EINVAL; | ||
335 | |||
336 | red >>= (16 - info->var.red.length); | ||
337 | green >>= (16 - info->var.green.length); | ||
338 | blue >>= (16 - info->var.blue.length); | ||
339 | |||
340 | value = (red << info->var.red.offset) | | ||
341 | (green << info->var.green.offset) | | ||
342 | (blue << info->var.blue.offset); | ||
343 | value &= 0xFFFFFF; | ||
344 | |||
345 | ((u32 *) (info->pseudo_palette))[regno] = value; | ||
346 | |||
347 | } | ||
348 | |||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | static struct fb_ops bfin_t350mcqb_fb_ops = { | ||
353 | .owner = THIS_MODULE, | ||
354 | .fb_open = bfin_t350mcqb_fb_open, | ||
355 | .fb_release = bfin_t350mcqb_fb_release, | ||
356 | .fb_check_var = bfin_t350mcqb_fb_check_var, | ||
357 | .fb_fillrect = cfb_fillrect, | ||
358 | .fb_copyarea = cfb_copyarea, | ||
359 | .fb_imageblit = cfb_imageblit, | ||
360 | .fb_mmap = bfin_t350mcqb_fb_mmap, | ||
361 | .fb_cursor = bfin_t350mcqb_fb_cursor, | ||
362 | .fb_setcolreg = bfin_t350mcqb_fb_setcolreg, | ||
363 | }; | ||
364 | |||
365 | #ifndef NO_BL_SUPPORT | ||
366 | static int bl_get_brightness(struct backlight_device *bd) | ||
367 | { | ||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static struct backlight_ops bfin_lq043fb_bl_ops = { | ||
372 | .get_brightness = bl_get_brightness, | ||
373 | }; | ||
374 | |||
375 | static struct backlight_device *bl_dev; | ||
376 | |||
377 | static int bfin_lcd_get_power(struct lcd_device *dev) | ||
378 | { | ||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | static int bfin_lcd_set_power(struct lcd_device *dev, int power) | ||
383 | { | ||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | static int bfin_lcd_get_contrast(struct lcd_device *dev) | ||
388 | { | ||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static int bfin_lcd_set_contrast(struct lcd_device *dev, int contrast) | ||
393 | { | ||
394 | |||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static int bfin_lcd_check_fb(struct fb_info *fi) | ||
399 | { | ||
400 | if (!fi || (fi == &bfin_t350mcqb_fb)) | ||
401 | return 1; | ||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static struct lcd_ops bfin_lcd_ops = { | ||
406 | .get_power = bfin_lcd_get_power, | ||
407 | .set_power = bfin_lcd_set_power, | ||
408 | .get_contrast = bfin_lcd_get_contrast, | ||
409 | .set_contrast = bfin_lcd_set_contrast, | ||
410 | .check_fb = bfin_lcd_check_fb, | ||
411 | }; | ||
412 | |||
413 | static struct lcd_device *lcd_dev; | ||
414 | #endif | ||
415 | |||
416 | static irqreturn_t bfin_t350mcqb_irq_error(int irq, void *dev_id) | ||
417 | { | ||
418 | /*struct bfin_t350mcqbfb_info *info = (struct bfin_t350mcqbfb_info *)dev_id;*/ | ||
419 | |||
420 | u16 status = bfin_read_PPI_STATUS(); | ||
421 | bfin_write_PPI_STATUS(0xFFFF); | ||
422 | |||
423 | if (status) { | ||
424 | bfin_t350mcqb_disable_ppi(); | ||
425 | disable_dma(CH_PPI); | ||
426 | |||
427 | /* start dma */ | ||
428 | enable_dma(CH_PPI); | ||
429 | bfin_t350mcqb_enable_ppi(); | ||
430 | bfin_write_PPI_STATUS(0xFFFF); | ||
431 | } | ||
432 | |||
433 | return IRQ_HANDLED; | ||
434 | } | ||
435 | |||
436 | static int __init bfin_t350mcqb_probe(struct platform_device *pdev) | ||
437 | { | ||
438 | struct bfin_t350mcqbfb_info *info; | ||
439 | struct fb_info *fbinfo; | ||
440 | int ret; | ||
441 | |||
442 | printk(KERN_INFO DRIVER_NAME ": %dx%d %d-bit RGB FrameBuffer initializing...\n", | ||
443 | LCD_X_RES, LCD_Y_RES, LCD_BPP); | ||
444 | |||
445 | if (request_dma(CH_PPI, "CH_PPI") < 0) { | ||
446 | printk(KERN_ERR DRIVER_NAME | ||
447 | ": couldn't request CH_PPI DMA\n"); | ||
448 | ret = -EFAULT; | ||
449 | goto out1; | ||
450 | } | ||
451 | |||
452 | fbinfo = | ||
453 | framebuffer_alloc(sizeof(struct bfin_t350mcqbfb_info), &pdev->dev); | ||
454 | if (!fbinfo) { | ||
455 | ret = -ENOMEM; | ||
456 | goto out2; | ||
457 | } | ||
458 | |||
459 | info = fbinfo->par; | ||
460 | info->fb = fbinfo; | ||
461 | info->dev = &pdev->dev; | ||
462 | |||
463 | platform_set_drvdata(pdev, fbinfo); | ||
464 | |||
465 | strcpy(fbinfo->fix.id, driver_name); | ||
466 | |||
467 | fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; | ||
468 | fbinfo->fix.type_aux = 0; | ||
469 | fbinfo->fix.xpanstep = 0; | ||
470 | fbinfo->fix.ypanstep = 0; | ||
471 | fbinfo->fix.ywrapstep = 0; | ||
472 | fbinfo->fix.accel = FB_ACCEL_NONE; | ||
473 | fbinfo->fix.visual = FB_VISUAL_TRUECOLOR; | ||
474 | |||
475 | fbinfo->var.nonstd = 0; | ||
476 | fbinfo->var.activate = FB_ACTIVATE_NOW; | ||
477 | fbinfo->var.height = -1; | ||
478 | fbinfo->var.width = -1; | ||
479 | fbinfo->var.accel_flags = 0; | ||
480 | fbinfo->var.vmode = FB_VMODE_NONINTERLACED; | ||
481 | |||
482 | fbinfo->var.xres = LCD_X_RES; | ||
483 | fbinfo->var.xres_virtual = LCD_X_RES; | ||
484 | fbinfo->var.yres = LCD_Y_RES; | ||
485 | fbinfo->var.yres_virtual = LCD_Y_RES; | ||
486 | fbinfo->var.bits_per_pixel = LCD_BPP; | ||
487 | |||
488 | fbinfo->var.red.offset = 0; | ||
489 | fbinfo->var.green.offset = 8; | ||
490 | fbinfo->var.blue.offset = 16; | ||
491 | fbinfo->var.transp.offset = 0; | ||
492 | fbinfo->var.red.length = 8; | ||
493 | fbinfo->var.green.length = 8; | ||
494 | fbinfo->var.blue.length = 8; | ||
495 | fbinfo->var.transp.length = 0; | ||
496 | fbinfo->fix.smem_len = LCD_X_RES * LCD_Y_RES * LCD_BPP / 8; | ||
497 | |||
498 | fbinfo->fix.line_length = fbinfo->var.xres_virtual * | ||
499 | fbinfo->var.bits_per_pixel / 8; | ||
500 | |||
501 | |||
502 | fbinfo->fbops = &bfin_t350mcqb_fb_ops; | ||
503 | fbinfo->flags = FBINFO_FLAG_DEFAULT; | ||
504 | |||
505 | info->fb_buffer = | ||
506 | dma_alloc_coherent(NULL, fbinfo->fix.smem_len, &info->dma_handle, | ||
507 | GFP_KERNEL); | ||
508 | |||
509 | if (NULL == info->fb_buffer) { | ||
510 | printk(KERN_ERR DRIVER_NAME | ||
511 | ": couldn't allocate dma buffer.\n"); | ||
512 | ret = -ENOMEM; | ||
513 | goto out3; | ||
514 | } | ||
515 | |||
516 | memset(info->fb_buffer, 0, fbinfo->fix.smem_len); | ||
517 | |||
518 | fbinfo->screen_base = (void *)info->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET; | ||
519 | fbinfo->fix.smem_start = (int)info->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET; | ||
520 | |||
521 | fbinfo->fbops = &bfin_t350mcqb_fb_ops; | ||
522 | |||
523 | fbinfo->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); | ||
524 | if (!fbinfo->pseudo_palette) { | ||
525 | printk(KERN_ERR DRIVER_NAME | ||
526 | "Fail to allocate pseudo_palette\n"); | ||
527 | |||
528 | ret = -ENOMEM; | ||
529 | goto out4; | ||
530 | } | ||
531 | |||
532 | memset(fbinfo->pseudo_palette, 0, sizeof(u32) * 16); | ||
533 | |||
534 | if (fb_alloc_cmap(&fbinfo->cmap, BFIN_LCD_NBR_PALETTE_ENTRIES, 0) | ||
535 | < 0) { | ||
536 | printk(KERN_ERR DRIVER_NAME | ||
537 | "Fail to allocate colormap (%d entries)\n", | ||
538 | BFIN_LCD_NBR_PALETTE_ENTRIES); | ||
539 | ret = -EFAULT; | ||
540 | goto out5; | ||
541 | } | ||
542 | |||
543 | if (bfin_t350mcqb_request_ports(1)) { | ||
544 | printk(KERN_ERR DRIVER_NAME ": couldn't request gpio port.\n"); | ||
545 | ret = -EFAULT; | ||
546 | goto out6; | ||
547 | } | ||
548 | |||
549 | info->irq = platform_get_irq(pdev, 0); | ||
550 | if (info->irq < 0) { | ||
551 | ret = -EINVAL; | ||
552 | goto out7; | ||
553 | } | ||
554 | |||
555 | if (request_irq(info->irq, (void *)bfin_t350mcqb_irq_error, IRQF_DISABLED, | ||
556 | "PPI ERROR", info) < 0) { | ||
557 | printk(KERN_ERR DRIVER_NAME | ||
558 | ": unable to request PPI ERROR IRQ\n"); | ||
559 | ret = -EFAULT; | ||
560 | goto out7; | ||
561 | } | ||
562 | |||
563 | if (register_framebuffer(fbinfo) < 0) { | ||
564 | printk(KERN_ERR DRIVER_NAME | ||
565 | ": unable to register framebuffer.\n"); | ||
566 | ret = -EINVAL; | ||
567 | goto out8; | ||
568 | } | ||
569 | #ifndef NO_BL_SUPPORT | ||
570 | bl_dev = | ||
571 | backlight_device_register("bf52x-bl", NULL, NULL, | ||
572 | &bfin_lq043fb_bl_ops); | ||
573 | bl_dev->props.max_brightness = 255; | ||
574 | |||
575 | lcd_dev = lcd_device_register(DRIVER_NAME, NULL, &bfin_lcd_ops); | ||
576 | lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n"); | ||
577 | #endif | ||
578 | |||
579 | return 0; | ||
580 | |||
581 | out8: | ||
582 | free_irq(info->irq, info); | ||
583 | out7: | ||
584 | bfin_t350mcqb_request_ports(0); | ||
585 | out6: | ||
586 | fb_dealloc_cmap(&fbinfo->cmap); | ||
587 | out5: | ||
588 | kfree(fbinfo->pseudo_palette); | ||
589 | out4: | ||
590 | dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer, | ||
591 | info->dma_handle); | ||
592 | out3: | ||
593 | framebuffer_release(fbinfo); | ||
594 | out2: | ||
595 | free_dma(CH_PPI); | ||
596 | out1: | ||
597 | platform_set_drvdata(pdev, NULL); | ||
598 | |||
599 | return ret; | ||
600 | } | ||
601 | |||
602 | static int bfin_t350mcqb_remove(struct platform_device *pdev) | ||
603 | { | ||
604 | |||
605 | struct fb_info *fbinfo = platform_get_drvdata(pdev); | ||
606 | struct bfin_t350mcqbfb_info *info = fbinfo->par; | ||
607 | |||
608 | free_dma(CH_PPI); | ||
609 | free_irq(info->irq, info); | ||
610 | |||
611 | if (info->fb_buffer != NULL) | ||
612 | dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer, | ||
613 | info->dma_handle); | ||
614 | |||
615 | kfree(fbinfo->pseudo_palette); | ||
616 | fb_dealloc_cmap(&fbinfo->cmap); | ||
617 | |||
618 | #ifndef NO_BL_SUPPORT | ||
619 | lcd_device_unregister(lcd_dev); | ||
620 | backlight_device_unregister(bl_dev); | ||
621 | #endif | ||
622 | |||
623 | unregister_framebuffer(fbinfo); | ||
624 | |||
625 | bfin_t350mcqb_request_ports(0); | ||
626 | |||
627 | printk(KERN_INFO DRIVER_NAME ": Unregister LCD driver.\n"); | ||
628 | |||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | #ifdef CONFIG_PM | ||
633 | static int bfin_t350mcqb_suspend(struct platform_device *pdev, pm_message_t state) | ||
634 | { | ||
635 | struct fb_info *fbinfo = platform_get_drvdata(pdev); | ||
636 | struct bfin_t350mcqbfb_info *info = fbinfo->par; | ||
637 | |||
638 | bfin_t350mcqb_disable_ppi(); | ||
639 | disable_dma(CH_PPI); | ||
640 | bfin_write_PPI_STATUS(0xFFFF); | ||
641 | |||
642 | return 0; | ||
643 | } | ||
644 | |||
645 | static int bfin_t350mcqb_resume(struct platform_device *pdev) | ||
646 | { | ||
647 | struct fb_info *fbinfo = platform_get_drvdata(pdev); | ||
648 | struct bfin_t350mcqbfb_info *info = fbinfo->par; | ||
649 | |||
650 | enable_dma(CH_PPI); | ||
651 | bfin_t350mcqb_enable_ppi(); | ||
652 | |||
653 | return 0; | ||
654 | } | ||
655 | #else | ||
656 | #define bfin_t350mcqb_suspend NULL | ||
657 | #define bfin_t350mcqb_resume NULL | ||
658 | #endif | ||
659 | |||
660 | static struct platform_driver bfin_t350mcqb_driver = { | ||
661 | .probe = bfin_t350mcqb_probe, | ||
662 | .remove = bfin_t350mcqb_remove, | ||
663 | .suspend = bfin_t350mcqb_suspend, | ||
664 | .resume = bfin_t350mcqb_resume, | ||
665 | .driver = { | ||
666 | .name = DRIVER_NAME, | ||
667 | .owner = THIS_MODULE, | ||
668 | }, | ||
669 | }; | ||
670 | |||
671 | static int __devinit bfin_t350mcqb_driver_init(void) | ||
672 | { | ||
673 | return platform_driver_register(&bfin_t350mcqb_driver); | ||
674 | } | ||
675 | |||
676 | static void __exit bfin_t350mcqb_driver_cleanup(void) | ||
677 | { | ||
678 | platform_driver_unregister(&bfin_t350mcqb_driver); | ||
679 | } | ||
680 | |||
681 | MODULE_DESCRIPTION("Blackfin TFT LCD Driver"); | ||
682 | MODULE_LICENSE("GPL"); | ||
683 | |||
684 | module_init(bfin_t350mcqb_driver_init); | ||
685 | module_exit(bfin_t350mcqb_driver_cleanup); | ||
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c index 80cd117ca65c..01f77bcc68f9 100644 --- a/drivers/video/mbx/mbxfb.c +++ b/drivers/video/mbx/mbxfb.c | |||
@@ -889,7 +889,7 @@ static int __devinit mbxfb_probe(struct platform_device *dev) | |||
889 | struct mbxfb_info *mfbi; | 889 | struct mbxfb_info *mfbi; |
890 | struct mbxfb_platform_data *pdata; | 890 | struct mbxfb_platform_data *pdata; |
891 | 891 | ||
892 | dev_dbg(dev, "mbxfb_probe\n"); | 892 | dev_dbg(&dev->dev, "mbxfb_probe\n"); |
893 | 893 | ||
894 | pdata = dev->dev.platform_data; | 894 | pdata = dev->dev.platform_data; |
895 | if (!pdata) { | 895 | if (!pdata) { |
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index e7c8db2eb49b..f98be301140c 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c | |||
@@ -505,16 +505,24 @@ ngleSetupAttrPlanes(struct stifb_info *fb, int BufferNumber) | |||
505 | static void | 505 | static void |
506 | rattlerSetupPlanes(struct stifb_info *fb) | 506 | rattlerSetupPlanes(struct stifb_info *fb) |
507 | { | 507 | { |
508 | int saved_id, y; | ||
509 | |||
510 | /* Write RAMDAC pixel read mask register so all overlay | ||
511 | * planes are display-enabled. (CRX24 uses Bt462 pixel | ||
512 | * read mask register for overlay planes, not image planes). | ||
513 | */ | ||
508 | CRX24_SETUP_RAMDAC(fb); | 514 | CRX24_SETUP_RAMDAC(fb); |
509 | 515 | ||
510 | /* replacement for: SETUP_FB(fb, CRX24_OVERLAY_PLANES); */ | 516 | /* change fb->id temporarily to fool SETUP_FB() */ |
511 | WRITE_WORD(0x83000300, fb, REG_14); | 517 | saved_id = fb->id; |
512 | SETUP_HW(fb); | 518 | fb->id = CRX24_OVERLAY_PLANES; |
513 | WRITE_BYTE(1, fb, REG_16b1); | 519 | SETUP_FB(fb); |
520 | fb->id = saved_id; | ||
521 | |||
522 | for (y = 0; y < fb->info.var.yres; ++y) | ||
523 | memset(fb->info.screen_base + y * fb->info.fix.line_length, | ||
524 | 0xff, fb->info.var.xres * fb->info.var.bits_per_pixel/8); | ||
514 | 525 | ||
515 | fb_memset((void*)fb->info.fix.smem_start, 0xff, | ||
516 | fb->info.var.yres*fb->info.fix.line_length); | ||
517 | |||
518 | CRX24_SET_OVLY_MASK(fb); | 526 | CRX24_SET_OVLY_MASK(fb); |
519 | SETUP_FB(fb); | 527 | SETUP_FB(fb); |
520 | } | 528 | } |
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c index 919ce75db9e2..0a4e07d43d2d 100644 --- a/drivers/video/tridentfb.c +++ b/drivers/video/tridentfb.c | |||
@@ -566,44 +566,32 @@ static inline void write3CE(int reg, unsigned char val) | |||
566 | 566 | ||
567 | static void enable_mmio(void) | 567 | static void enable_mmio(void) |
568 | { | 568 | { |
569 | unsigned char tmp; | ||
570 | |||
571 | /* Goto New Mode */ | 569 | /* Goto New Mode */ |
572 | outb(0x0B, 0x3C4); | 570 | outb(0x0B, 0x3C4); |
573 | inb(0x3C5); | 571 | inb(0x3C5); |
574 | 572 | ||
575 | /* Unprotect registers */ | 573 | /* Unprotect registers */ |
576 | outb(NewMode1, 0x3C4); | 574 | outb(NewMode1, 0x3C4); |
577 | tmp = inb(0x3C5); | ||
578 | outb(0x80, 0x3C5); | 575 | outb(0x80, 0x3C5); |
579 | 576 | ||
580 | /* Enable MMIO */ | 577 | /* Enable MMIO */ |
581 | outb(PCIReg, 0x3D4); | 578 | outb(PCIReg, 0x3D4); |
582 | outb(inb(0x3D5) | 0x01, 0x3D5); | 579 | outb(inb(0x3D5) | 0x01, 0x3D5); |
583 | |||
584 | t_outb(NewMode1, 0x3C4); | ||
585 | t_outb(tmp, 0x3C5); | ||
586 | } | 580 | } |
587 | 581 | ||
588 | static void disable_mmio(void) | 582 | static void disable_mmio(void) |
589 | { | 583 | { |
590 | unsigned char tmp; | ||
591 | |||
592 | /* Goto New Mode */ | 584 | /* Goto New Mode */ |
593 | t_outb(0x0B, 0x3C4); | 585 | t_outb(0x0B, 0x3C4); |
594 | t_inb(0x3C5); | 586 | t_inb(0x3C5); |
595 | 587 | ||
596 | /* Unprotect registers */ | 588 | /* Unprotect registers */ |
597 | t_outb(NewMode1, 0x3C4); | 589 | t_outb(NewMode1, 0x3C4); |
598 | tmp = t_inb(0x3C5); | ||
599 | t_outb(0x80, 0x3C5); | 590 | t_outb(0x80, 0x3C5); |
600 | 591 | ||
601 | /* Disable MMIO */ | 592 | /* Disable MMIO */ |
602 | t_outb(PCIReg, 0x3D4); | 593 | t_outb(PCIReg, 0x3D4); |
603 | t_outb(t_inb(0x3D5) & ~0x01, 0x3D5); | 594 | t_outb(t_inb(0x3D5) & ~0x01, 0x3D5); |
604 | |||
605 | outb(NewMode1, 0x3C4); | ||
606 | outb(tmp, 0x3C5); | ||
607 | } | 595 | } |
608 | 596 | ||
609 | #define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F) | 597 | #define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F) |
@@ -757,7 +745,7 @@ static unsigned int __devinit get_memsize(void) | |||
757 | switch (tmp) { | 745 | switch (tmp) { |
758 | 746 | ||
759 | case 0x01: | 747 | case 0x01: |
760 | k = 512; | 748 | k = 512 * Kb; |
761 | break; | 749 | break; |
762 | case 0x02: | 750 | case 0x02: |
763 | k = 6 * Mb; /* XP */ | 751 | k = 6 * Mb; /* XP */ |
diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c index 5941ca601a3a..df72f90123df 100644 --- a/drivers/watchdog/cpu5wdt.c +++ b/drivers/watchdog/cpu5wdt.c | |||
@@ -59,9 +59,9 @@ static int ticks = 10000; | |||
59 | 59 | ||
60 | static struct { | 60 | static struct { |
61 | struct completion stop; | 61 | struct completion stop; |
62 | volatile int running; | 62 | int running; |
63 | struct timer_list timer; | 63 | struct timer_list timer; |
64 | volatile int queue; | 64 | int queue; |
65 | int default_ticks; | 65 | int default_ticks; |
66 | unsigned long inuse; | 66 | unsigned long inuse; |
67 | } cpu5wdt_device; | 67 | } cpu5wdt_device; |
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index a2e174b09fe7..6483d1066b95 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c | |||
@@ -58,41 +58,6 @@ struct bios32_service_dir { | |||
58 | u8 reserved[5]; | 58 | u8 reserved[5]; |
59 | }; | 59 | }; |
60 | 60 | ||
61 | /* | ||
62 | * smbios_entry_point - defines SMBIOS entry point structure | ||
63 | * | ||
64 | * anchor[4] - anchor string (_SM_) | ||
65 | * checksum - checksum of the entry point structure | ||
66 | * length - length of the entry point structure | ||
67 | * major_ver - major version (02h for revision 2.1) | ||
68 | * minor_ver - minor version (01h for revision 2.1) | ||
69 | * max_struct_size - size of the largest SMBIOS structure | ||
70 | * revision - entry point structure revision implemented | ||
71 | * formatted_area[5] - reserved | ||
72 | * intermediate_anchor[5] - intermediate anchor string (_DMI_) | ||
73 | * intermediate_checksum - intermediate checksum | ||
74 | * table_length - structure table length | ||
75 | * table_address - structure table address | ||
76 | * table_num_structs - number of SMBIOS structures present | ||
77 | * bcd_revision - BCD revision | ||
78 | */ | ||
79 | struct smbios_entry_point { | ||
80 | u8 anchor[4]; | ||
81 | u8 checksum; | ||
82 | u8 length; | ||
83 | u8 major_ver; | ||
84 | u8 minor_ver; | ||
85 | u16 max_struct_size; | ||
86 | u8 revision; | ||
87 | u8 formatted_area[5]; | ||
88 | u8 intermediate_anchor[5]; | ||
89 | u8 intermediate_checksum; | ||
90 | u16 table_length; | ||
91 | u64 table_address; | ||
92 | u16 table_num_structs; | ||
93 | u8 bcd_revision; | ||
94 | }; | ||
95 | |||
96 | /* type 212 */ | 61 | /* type 212 */ |
97 | struct smbios_cru64_info { | 62 | struct smbios_cru64_info { |
98 | u8 type; | 63 | u8 type; |
@@ -175,31 +140,13 @@ static struct pci_device_id hpwdt_devices[] = { | |||
175 | }; | 140 | }; |
176 | MODULE_DEVICE_TABLE(pci, hpwdt_devices); | 141 | MODULE_DEVICE_TABLE(pci, hpwdt_devices); |
177 | 142 | ||
178 | /* | ||
179 | * bios_checksum | ||
180 | */ | ||
181 | static int __devinit bios_checksum(const char __iomem *ptr, int len) | ||
182 | { | ||
183 | char sum = 0; | ||
184 | int i; | ||
185 | |||
186 | /* | ||
187 | * calculate checksum of size bytes. This should add up | ||
188 | * to zero if we have a valid header. | ||
189 | */ | ||
190 | for (i = 0; i < len; i++) | ||
191 | sum += ptr[i]; | ||
192 | |||
193 | return ((sum == 0) && (len > 0)); | ||
194 | } | ||
195 | |||
196 | #ifndef CONFIG_X86_64 | 143 | #ifndef CONFIG_X86_64 |
197 | /* --32 Bit Bios------------------------------------------------------------ */ | 144 | /* --32 Bit Bios------------------------------------------------------------ */ |
198 | 145 | ||
199 | #define HPWDT_ARCH 32 | 146 | #define HPWDT_ARCH 32 |
200 | 147 | ||
201 | asmlinkage void asminline_call(struct cmn_registers *pi86Regs, | 148 | static void asminline_call(struct cmn_registers *pi86Regs, |
202 | unsigned long *pRomEntry) | 149 | unsigned long *pRomEntry) |
203 | { | 150 | { |
204 | asm("pushl %ebp \n\t" | 151 | asm("pushl %ebp \n\t" |
205 | "movl %esp, %ebp \n\t" | 152 | "movl %esp, %ebp \n\t" |
@@ -303,6 +250,24 @@ static int __devinit cru_detect(unsigned long map_entry, | |||
303 | } | 250 | } |
304 | 251 | ||
305 | /* | 252 | /* |
253 | * bios_checksum | ||
254 | */ | ||
255 | static int __devinit bios_checksum(const char __iomem *ptr, int len) | ||
256 | { | ||
257 | char sum = 0; | ||
258 | int i; | ||
259 | |||
260 | /* | ||
261 | * calculate checksum of size bytes. This should add up | ||
262 | * to zero if we have a valid header. | ||
263 | */ | ||
264 | for (i = 0; i < len; i++) | ||
265 | sum += ptr[i]; | ||
266 | |||
267 | return ((sum == 0) && (len > 0)); | ||
268 | } | ||
269 | |||
270 | /* | ||
306 | * bios32_present | 271 | * bios32_present |
307 | * | 272 | * |
308 | * Routine Description: | 273 | * Routine Description: |
@@ -368,8 +333,8 @@ static int __devinit detect_cru_service(void) | |||
368 | 333 | ||
369 | #define HPWDT_ARCH 64 | 334 | #define HPWDT_ARCH 64 |
370 | 335 | ||
371 | asmlinkage void asminline_call(struct cmn_registers *pi86Regs, | 336 | static void asminline_call(struct cmn_registers *pi86Regs, |
372 | unsigned long *pRomEntry) | 337 | unsigned long *pRomEntry) |
373 | { | 338 | { |
374 | asm("pushq %rbp \n\t" | 339 | asm("pushq %rbp \n\t" |
375 | "movq %rsp, %rbp \n\t" | 340 | "movq %rsp, %rbp \n\t" |
@@ -410,12 +375,8 @@ asmlinkage void asminline_call(struct cmn_registers *pi86Regs, | |||
410 | * dmi_find_cru | 375 | * dmi_find_cru |
411 | * | 376 | * |
412 | * Routine Description: | 377 | * Routine Description: |
413 | * This function checks wether or not a SMBIOS/DMI record is | 378 | * This function checks whether or not a SMBIOS/DMI record is |
414 | * the 64bit CRU info or not | 379 | * the 64bit CRU info or not |
415 | * | ||
416 | * Return Value: | ||
417 | * 0 : SUCCESS - if record found | ||
418 | * <0 : FAILURE - if record not found | ||
419 | */ | 380 | */ |
420 | static void __devinit dmi_find_cru(const struct dmi_header *dm) | 381 | static void __devinit dmi_find_cru(const struct dmi_header *dm) |
421 | { | 382 | { |
@@ -434,138 +395,11 @@ static void __devinit dmi_find_cru(const struct dmi_header *dm) | |||
434 | } | 395 | } |
435 | } | 396 | } |
436 | 397 | ||
437 | /* | ||
438 | * dmi_table | ||
439 | * | ||
440 | * Routine Description: | ||
441 | * Decode the SMBIOS/DMI table and check if we have a 64bit CRU record | ||
442 | * or not. | ||
443 | * | ||
444 | * We have to be cautious here. We have seen BIOSes with DMI pointers | ||
445 | * pointing to completely the wrong place for example | ||
446 | */ | ||
447 | static void __devinit dmi_table(u8 *buf, int len, int num, | ||
448 | void (*decode)(const struct dmi_header *)) | ||
449 | { | ||
450 | u8 *data = buf; | ||
451 | int i = 0; | ||
452 | |||
453 | /* | ||
454 | * Stop when we see all the items the table claimed to have | ||
455 | * OR we run off the end of the table (also happens) | ||
456 | */ | ||
457 | while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { | ||
458 | const struct dmi_header *dm = (const struct dmi_header *)data; | ||
459 | |||
460 | /* | ||
461 | * We want to know the total length (formated area and strings) | ||
462 | * before decoding to make sure we won't run off the table in | ||
463 | * dmi_decode or dmi_string | ||
464 | */ | ||
465 | data += dm->length; | ||
466 | while ((data - buf < len - 1) && (data[0] || data[1])) | ||
467 | data++; | ||
468 | if (data - buf < len - 1) | ||
469 | decode(dm); | ||
470 | data += 2; | ||
471 | i++; | ||
472 | } | ||
473 | } | ||
474 | |||
475 | /* | ||
476 | * smbios_present | ||
477 | * | ||
478 | * Routine Description: | ||
479 | * This function parses the SMBIOS entry point table to retrieve | ||
480 | * the 64 bit CRU Service. | ||
481 | * | ||
482 | * Return Value: | ||
483 | * 0 : SUCCESS | ||
484 | * <0 : FAILURE | ||
485 | */ | ||
486 | static int __devinit smbios_present(const char __iomem *p) | ||
487 | { | ||
488 | struct smbios_entry_point *eps = | ||
489 | (struct smbios_entry_point *) p; | ||
490 | int length; | ||
491 | u8 *buf; | ||
492 | |||
493 | /* check if we have indeed the SMBIOS table entry point */ | ||
494 | if ((strncmp((char *)eps->anchor, "_SM_", | ||
495 | sizeof(eps->anchor))) == 0) { | ||
496 | length = eps->length; | ||
497 | |||
498 | /* SMBIOS v2.1 implementation might use 0x1e */ | ||
499 | if ((length == 0x1e) && | ||
500 | (eps->major_ver == 2) && | ||
501 | (eps->minor_ver == 1)) | ||
502 | length = 0x1f; | ||
503 | |||
504 | /* | ||
505 | * Now we will check: | ||
506 | * - SMBIOS checksum must be 0 | ||
507 | * - intermediate anchor should be _DMI_ | ||
508 | * - intermediate checksum should be 0 | ||
509 | */ | ||
510 | if ((bios_checksum(p, length)) && | ||
511 | (strncmp((char *)eps->intermediate_anchor, "_DMI_", | ||
512 | sizeof(eps->intermediate_anchor)) == 0) && | ||
513 | (bios_checksum(p+0x10, 15))) { | ||
514 | buf = ioremap(eps->table_address, eps->table_length); | ||
515 | if (buf == NULL) | ||
516 | return -ENODEV; | ||
517 | |||
518 | |||
519 | /* Scan the DMI table for the 64 bit CRU service */ | ||
520 | dmi_table(buf, eps->table_length, | ||
521 | eps->table_num_structs, dmi_find_cru); | ||
522 | |||
523 | iounmap(buf); | ||
524 | return 0; | ||
525 | } | ||
526 | } | ||
527 | |||
528 | return -ENODEV; | ||
529 | } | ||
530 | |||
531 | static int __devinit smbios_scan_machine(void) | ||
532 | { | ||
533 | char __iomem *p, *q; | ||
534 | int rc; | ||
535 | |||
536 | if (efi_enabled) { | ||
537 | if (efi.smbios == EFI_INVALID_TABLE_ADDR) | ||
538 | return -ENODEV; | ||
539 | |||
540 | p = ioremap(efi.smbios, 32); | ||
541 | if (p == NULL) | ||
542 | return -ENOMEM; | ||
543 | |||
544 | rc = smbios_present(p); | ||
545 | iounmap(p); | ||
546 | } else { | ||
547 | /* | ||
548 | * Search from 0x0f0000 through 0x0fffff, inclusive. | ||
549 | */ | ||
550 | p = ioremap(PCI_ROM_BASE1, ROM_SIZE); | ||
551 | if (p == NULL) | ||
552 | return -ENOMEM; | ||
553 | |||
554 | for (q = p; q < p + ROM_SIZE; q += 16) { | ||
555 | rc = smbios_present(q); | ||
556 | if (!rc) { | ||
557 | break; | ||
558 | } | ||
559 | } | ||
560 | iounmap(p); | ||
561 | } | ||
562 | } | ||
563 | |||
564 | static int __devinit detect_cru_service(void) | 398 | static int __devinit detect_cru_service(void) |
565 | { | 399 | { |
566 | cru_rom_addr = NULL; | 400 | cru_rom_addr = NULL; |
567 | 401 | ||
568 | smbios_scan_machine(); /* will become dmi_walk(dmi_find_cru); */ | 402 | dmi_walk(dmi_find_cru); |
569 | 403 | ||
570 | /* if cru_rom_addr has been set then we found a CRU service */ | 404 | /* if cru_rom_addr has been set then we found a CRU service */ |
571 | return ((cru_rom_addr != NULL)? 0: -ENODEV); | 405 | return ((cru_rom_addr != NULL)? 0: -ENODEV); |
diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c index 1b6d7d1b715d..1efcad3b6fca 100644 --- a/drivers/watchdog/it8712f_wdt.c +++ b/drivers/watchdog/it8712f_wdt.c | |||
@@ -7,7 +7,8 @@ | |||
7 | * | 7 | * |
8 | * drivers/char/watchdog/scx200_wdt.c | 8 | * drivers/char/watchdog/scx200_wdt.c |
9 | * drivers/hwmon/it87.c | 9 | * drivers/hwmon/it87.c |
10 | * IT8712F EC-LPC I/O Preliminary Specification 0.9.2.pdf | 10 | * IT8712F EC-LPC I/O Preliminary Specification 0.8.2 |
11 | * IT8712F EC-LPC I/O Preliminary Specification 0.9.3 | ||
11 | * | 12 | * |
12 | * This program is free software; you can redistribute it and/or | 13 | * This program is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU General Public License as | 14 | * modify it under the terms of the GNU General Public License as |
@@ -40,6 +41,7 @@ MODULE_DESCRIPTION("IT8712F Watchdog Driver"); | |||
40 | MODULE_LICENSE("GPL"); | 41 | MODULE_LICENSE("GPL"); |
41 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 42 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
42 | 43 | ||
44 | static int max_units = 255; | ||
43 | static int margin = 60; /* in seconds */ | 45 | static int margin = 60; /* in seconds */ |
44 | module_param(margin, int, 0); | 46 | module_param(margin, int, 0); |
45 | MODULE_PARM_DESC(margin, "Watchdog margin in seconds"); | 47 | MODULE_PARM_DESC(margin, "Watchdog margin in seconds"); |
@@ -51,6 +53,7 @@ MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); | |||
51 | static struct semaphore it8712f_wdt_sem; | 53 | static struct semaphore it8712f_wdt_sem; |
52 | static unsigned expect_close; | 54 | static unsigned expect_close; |
53 | static spinlock_t io_lock; | 55 | static spinlock_t io_lock; |
56 | static unsigned char revision; | ||
54 | 57 | ||
55 | /* Dog Food address - We use the game port address */ | 58 | /* Dog Food address - We use the game port address */ |
56 | static unsigned short address; | 59 | static unsigned short address; |
@@ -108,6 +111,15 @@ superio_inw(int reg) | |||
108 | return val; | 111 | return val; |
109 | } | 112 | } |
110 | 113 | ||
114 | static void | ||
115 | superio_outw(int val, int reg) | ||
116 | { | ||
117 | outb(reg++, REG); | ||
118 | outb((val >> 8) & 0xff, VAL); | ||
119 | outb(reg, REG); | ||
120 | outb(val & 0xff, VAL); | ||
121 | } | ||
122 | |||
111 | static inline void | 123 | static inline void |
112 | superio_select(int ldn) | 124 | superio_select(int ldn) |
113 | { | 125 | { |
@@ -143,15 +155,33 @@ static void | |||
143 | it8712f_wdt_update_margin(void) | 155 | it8712f_wdt_update_margin(void) |
144 | { | 156 | { |
145 | int config = WDT_OUT_KRST | WDT_OUT_PWROK; | 157 | int config = WDT_OUT_KRST | WDT_OUT_PWROK; |
146 | 158 | int units = margin; | |
147 | printk(KERN_INFO NAME ": timer margin %d seconds\n", margin); | 159 | |
148 | 160 | /* Switch to minutes precision if the configured margin | |
149 | /* The timeout register only has 8bits wide */ | 161 | * value does not fit within the register width. |
150 | if (margin < 256) | 162 | */ |
151 | config |= WDT_UNIT_SEC; /* else UNIT are MINUTES */ | 163 | if (units <= max_units) { |
164 | config |= WDT_UNIT_SEC; /* else UNIT is MINUTES */ | ||
165 | printk(KERN_INFO NAME ": timer margin %d seconds\n", units); | ||
166 | } else { | ||
167 | units /= 60; | ||
168 | printk(KERN_INFO NAME ": timer margin %d minutes\n", units); | ||
169 | } | ||
152 | superio_outb(config, WDT_CONFIG); | 170 | superio_outb(config, WDT_CONFIG); |
153 | 171 | ||
154 | superio_outb((margin > 255) ? (margin / 60) : margin, WDT_TIMEOUT); | 172 | if (revision >= 0x08) |
173 | superio_outw(units, WDT_TIMEOUT); | ||
174 | else | ||
175 | superio_outb(units, WDT_TIMEOUT); | ||
176 | } | ||
177 | |||
178 | static int | ||
179 | it8712f_wdt_get_status(void) | ||
180 | { | ||
181 | if (superio_inb(WDT_CONTROL) & 0x01) | ||
182 | return WDIOF_CARDRESET; | ||
183 | else | ||
184 | return 0; | ||
155 | } | 185 | } |
156 | 186 | ||
157 | static void | 187 | static void |
@@ -234,7 +264,7 @@ it8712f_wdt_ioctl(struct inode *inode, struct file *file, | |||
234 | .firmware_version = 1, | 264 | .firmware_version = 1, |
235 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 265 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
236 | }; | 266 | }; |
237 | int new_margin; | 267 | int value; |
238 | 268 | ||
239 | switch (cmd) { | 269 | switch (cmd) { |
240 | default: | 270 | default: |
@@ -244,17 +274,27 @@ it8712f_wdt_ioctl(struct inode *inode, struct file *file, | |||
244 | return -EFAULT; | 274 | return -EFAULT; |
245 | return 0; | 275 | return 0; |
246 | case WDIOC_GETSTATUS: | 276 | case WDIOC_GETSTATUS: |
277 | superio_enter(); | ||
278 | superio_select(LDN_GPIO); | ||
279 | |||
280 | value = it8712f_wdt_get_status(); | ||
281 | |||
282 | superio_exit(); | ||
283 | |||
284 | return put_user(value, p); | ||
247 | case WDIOC_GETBOOTSTATUS: | 285 | case WDIOC_GETBOOTSTATUS: |
248 | return put_user(0, p); | 286 | return put_user(0, p); |
249 | case WDIOC_KEEPALIVE: | 287 | case WDIOC_KEEPALIVE: |
250 | it8712f_wdt_ping(); | 288 | it8712f_wdt_ping(); |
251 | return 0; | 289 | return 0; |
252 | case WDIOC_SETTIMEOUT: | 290 | case WDIOC_SETTIMEOUT: |
253 | if (get_user(new_margin, p)) | 291 | if (get_user(value, p)) |
254 | return -EFAULT; | 292 | return -EFAULT; |
255 | if (new_margin < 1) | 293 | if (value < 1) |
294 | return -EINVAL; | ||
295 | if (value > (max_units * 60)) | ||
256 | return -EINVAL; | 296 | return -EINVAL; |
257 | margin = new_margin; | 297 | margin = value; |
258 | superio_enter(); | 298 | superio_enter(); |
259 | superio_select(LDN_GPIO); | 299 | superio_select(LDN_GPIO); |
260 | 300 | ||
@@ -262,6 +302,7 @@ it8712f_wdt_ioctl(struct inode *inode, struct file *file, | |||
262 | 302 | ||
263 | superio_exit(); | 303 | superio_exit(); |
264 | it8712f_wdt_ping(); | 304 | it8712f_wdt_ping(); |
305 | /* Fall through */ | ||
265 | case WDIOC_GETTIMEOUT: | 306 | case WDIOC_GETTIMEOUT: |
266 | if (put_user(margin, p)) | 307 | if (put_user(margin, p)) |
267 | return -EFAULT; | 308 | return -EFAULT; |
@@ -336,9 +377,18 @@ it8712f_wdt_find(unsigned short *address) | |||
336 | } | 377 | } |
337 | 378 | ||
338 | err = 0; | 379 | err = 0; |
339 | printk(KERN_DEBUG NAME ": Found IT%04xF chip revision %d - " | 380 | revision = superio_inb(DEVREV) & 0x0f; |
381 | |||
382 | /* Later revisions have 16-bit values per datasheet 0.9.1 */ | ||
383 | if (revision >= 0x08) | ||
384 | max_units = 65535; | ||
385 | |||
386 | if (margin > (max_units * 60)) | ||
387 | margin = (max_units * 60); | ||
388 | |||
389 | printk(KERN_INFO NAME ": Found IT%04xF chip revision %d - " | ||
340 | "using DogFood address 0x%x\n", | 390 | "using DogFood address 0x%x\n", |
341 | chip_type, superio_inb(DEVREV) & 0x0f, *address); | 391 | chip_type, revision, *address); |
342 | 392 | ||
343 | exit: | 393 | exit: |
344 | superio_exit(); | 394 | superio_exit(); |
diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c index e6e07b4575eb..6905135a776c 100644 --- a/drivers/watchdog/machzwd.c +++ b/drivers/watchdog/machzwd.c | |||
@@ -141,7 +141,7 @@ static unsigned long next_heartbeat = 0; | |||
141 | #ifndef ZF_DEBUG | 141 | #ifndef ZF_DEBUG |
142 | # define dprintk(format, args...) | 142 | # define dprintk(format, args...) |
143 | #else | 143 | #else |
144 | # define dprintk(format, args...) printk(KERN_DEBUG PFX ":%s:%d: " format, __FUNCTION__, __LINE__ , ## args) | 144 | # define dprintk(format, args...) printk(KERN_DEBUG PFX ":%s:%d: " format, __func__, __LINE__ , ## args) |
145 | #endif | 145 | #endif |
146 | 146 | ||
147 | 147 | ||
diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index 789831b3fa00..10b89f2703bd 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c | |||
@@ -59,9 +59,9 @@ static int ticks = 100 * HZ; | |||
59 | 59 | ||
60 | static struct { | 60 | static struct { |
61 | struct completion stop; | 61 | struct completion stop; |
62 | volatile int running; | 62 | int running; |
63 | struct timer_list timer; | 63 | struct timer_list timer; |
64 | volatile int queue; | 64 | int queue; |
65 | int default_ticks; | 65 | int default_ticks; |
66 | unsigned long inuse; | 66 | unsigned long inuse; |
67 | unsigned gpio; | 67 | unsigned gpio; |
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c index 0f3fd6c9c354..bf443d077a1e 100644 --- a/drivers/watchdog/pcwd_usb.c +++ b/drivers/watchdog/pcwd_usb.c | |||
@@ -179,11 +179,11 @@ static void usb_pcwd_intr_done(struct urb *urb) | |||
179 | case -ENOENT: | 179 | case -ENOENT: |
180 | case -ESHUTDOWN: | 180 | case -ESHUTDOWN: |
181 | /* this urb is terminated, clean up */ | 181 | /* this urb is terminated, clean up */ |
182 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); | 182 | dbg("%s - urb shutting down with status: %d", __func__, urb->status); |
183 | return; | 183 | return; |
184 | /* -EPIPE: should clear the halt */ | 184 | /* -EPIPE: should clear the halt */ |
185 | default: /* error */ | 185 | default: /* error */ |
186 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); | 186 | dbg("%s - nonzero urb status received: %d", __func__, urb->status); |
187 | goto resubmit; | 187 | goto resubmit; |
188 | } | 188 | } |
189 | 189 | ||
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 5d1c15f83d23..7645e8812156 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c | |||
@@ -144,7 +144,7 @@ static int s3c2410wdt_start(void) | |||
144 | } | 144 | } |
145 | 145 | ||
146 | DBG("%s: wdt_count=0x%08x, wtcon=%08lx\n", | 146 | DBG("%s: wdt_count=0x%08x, wtcon=%08lx\n", |
147 | __FUNCTION__, wdt_count, wtcon); | 147 | __func__, wdt_count, wtcon); |
148 | 148 | ||
149 | writel(wdt_count, wdt_base + S3C2410_WTDAT); | 149 | writel(wdt_count, wdt_base + S3C2410_WTDAT); |
150 | writel(wdt_count, wdt_base + S3C2410_WTCNT); | 150 | writel(wdt_count, wdt_base + S3C2410_WTCNT); |
@@ -167,7 +167,7 @@ static int s3c2410wdt_set_heartbeat(int timeout) | |||
167 | count = timeout * freq; | 167 | count = timeout * freq; |
168 | 168 | ||
169 | DBG("%s: count=%d, timeout=%d, freq=%d\n", | 169 | DBG("%s: count=%d, timeout=%d, freq=%d\n", |
170 | __FUNCTION__, count, timeout, freq); | 170 | __func__, count, timeout, freq); |
171 | 171 | ||
172 | /* if the count is bigger than the watchdog register, | 172 | /* if the count is bigger than the watchdog register, |
173 | then work out what we need to do (and if) we can | 173 | then work out what we need to do (and if) we can |
@@ -189,7 +189,7 @@ static int s3c2410wdt_set_heartbeat(int timeout) | |||
189 | tmr_margin = timeout; | 189 | tmr_margin = timeout; |
190 | 190 | ||
191 | DBG("%s: timeout=%d, divisor=%d, count=%d (%08x)\n", | 191 | DBG("%s: timeout=%d, divisor=%d, count=%d (%08x)\n", |
192 | __FUNCTION__, timeout, divisor, count, count/divisor); | 192 | __func__, timeout, divisor, count, count/divisor); |
193 | 193 | ||
194 | count /= divisor; | 194 | count /= divisor; |
195 | wdt_count = count; | 195 | wdt_count = count; |
@@ -355,7 +355,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev) | |||
355 | int ret; | 355 | int ret; |
356 | int size; | 356 | int size; |
357 | 357 | ||
358 | DBG("%s: probe=%p\n", __FUNCTION__, pdev); | 358 | DBG("%s: probe=%p\n", __func__, pdev); |
359 | 359 | ||
360 | dev = &pdev->dev; | 360 | dev = &pdev->dev; |
361 | wdt_dev = &pdev->dev; | 361 | wdt_dev = &pdev->dev; |
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index 61dde863bd40..1277f7e9cc54 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c | |||
@@ -298,7 +298,7 @@ static int sh_wdt_mmap(struct file *file, struct vm_area_struct *vma) | |||
298 | if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, | 298 | if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, |
299 | PAGE_SIZE, vma->vm_page_prot)) { | 299 | PAGE_SIZE, vma->vm_page_prot)) { |
300 | printk(KERN_ERR PFX "%s: io_remap_pfn_range failed\n", | 300 | printk(KERN_ERR PFX "%s: io_remap_pfn_range failed\n", |
301 | __FUNCTION__); | 301 | __func__); |
302 | return -EAGAIN; | 302 | return -EAGAIN; |
303 | } | 303 | } |
304 | 304 | ||
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index ee50c9610e7f..b8057c51b205 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
@@ -451,9 +451,9 @@ static void o2net_set_nn_state(struct o2net_node *nn, | |||
451 | /* delay if we're withing a RECONNECT_DELAY of the | 451 | /* delay if we're withing a RECONNECT_DELAY of the |
452 | * last attempt */ | 452 | * last attempt */ |
453 | delay = (nn->nn_last_connect_attempt + | 453 | delay = (nn->nn_last_connect_attempt + |
454 | msecs_to_jiffies(o2net_reconnect_delay(sc->sc_node))) | 454 | msecs_to_jiffies(o2net_reconnect_delay(NULL))) |
455 | - jiffies; | 455 | - jiffies; |
456 | if (delay > msecs_to_jiffies(o2net_reconnect_delay(sc->sc_node))) | 456 | if (delay > msecs_to_jiffies(o2net_reconnect_delay(NULL))) |
457 | delay = 0; | 457 | delay = 0; |
458 | mlog(ML_CONN, "queueing conn attempt in %lu jiffies\n", delay); | 458 | mlog(ML_CONN, "queueing conn attempt in %lu jiffies\n", delay); |
459 | queue_delayed_work(o2net_wq, &nn->nn_connect_work, delay); | 459 | queue_delayed_work(o2net_wq, &nn->nn_connect_work, delay); |
@@ -1552,12 +1552,11 @@ static void o2net_connect_expired(struct work_struct *work) | |||
1552 | 1552 | ||
1553 | spin_lock(&nn->nn_lock); | 1553 | spin_lock(&nn->nn_lock); |
1554 | if (!nn->nn_sc_valid) { | 1554 | if (!nn->nn_sc_valid) { |
1555 | struct o2nm_node *node = nn->nn_sc->sc_node; | ||
1556 | mlog(ML_ERROR, "no connection established with node %u after " | 1555 | mlog(ML_ERROR, "no connection established with node %u after " |
1557 | "%u.%u seconds, giving up and returning errors.\n", | 1556 | "%u.%u seconds, giving up and returning errors.\n", |
1558 | o2net_num_from_nn(nn), | 1557 | o2net_num_from_nn(nn), |
1559 | o2net_idle_timeout(node) / 1000, | 1558 | o2net_idle_timeout(NULL) / 1000, |
1560 | o2net_idle_timeout(node) % 1000); | 1559 | o2net_idle_timeout(NULL) % 1000); |
1561 | 1560 | ||
1562 | o2net_set_nn_state(nn, NULL, 0, -ENOTCONN); | 1561 | o2net_set_nn_state(nn, NULL, 0, -ENOTCONN); |
1563 | } | 1562 | } |
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index 9843ee17ea27..dc8ea666efdb 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h | |||
@@ -176,6 +176,7 @@ struct dlm_mig_lockres_priv | |||
176 | { | 176 | { |
177 | struct dlm_lock_resource *lockres; | 177 | struct dlm_lock_resource *lockres; |
178 | u8 real_master; | 178 | u8 real_master; |
179 | u8 extra_ref; | ||
179 | }; | 180 | }; |
180 | 181 | ||
181 | struct dlm_assert_master_priv | 182 | struct dlm_assert_master_priv |
@@ -602,17 +603,19 @@ enum dlm_query_join_response_code { | |||
602 | JOIN_PROTOCOL_MISMATCH, | 603 | JOIN_PROTOCOL_MISMATCH, |
603 | }; | 604 | }; |
604 | 605 | ||
606 | struct dlm_query_join_packet { | ||
607 | u8 code; /* Response code. dlm_minor and fs_minor | ||
608 | are only valid if this is JOIN_OK */ | ||
609 | u8 dlm_minor; /* The minor version of the protocol the | ||
610 | dlm is speaking. */ | ||
611 | u8 fs_minor; /* The minor version of the protocol the | ||
612 | filesystem is speaking. */ | ||
613 | u8 reserved; | ||
614 | }; | ||
615 | |||
605 | union dlm_query_join_response { | 616 | union dlm_query_join_response { |
606 | u32 intval; | 617 | u32 intval; |
607 | struct { | 618 | struct dlm_query_join_packet packet; |
608 | u8 code; /* Response code. dlm_minor and fs_minor | ||
609 | are only valid if this is JOIN_OK */ | ||
610 | u8 dlm_minor; /* The minor version of the protocol the | ||
611 | dlm is speaking. */ | ||
612 | u8 fs_minor; /* The minor version of the protocol the | ||
613 | filesystem is speaking. */ | ||
614 | u8 reserved; | ||
615 | } packet; | ||
616 | }; | 619 | }; |
617 | 620 | ||
618 | struct dlm_lock_request | 621 | struct dlm_lock_request |
diff --git a/fs/ocfs2/dlm/dlmconvert.c b/fs/ocfs2/dlm/dlmconvert.c index ecb4d997221e..75997b4deaf3 100644 --- a/fs/ocfs2/dlm/dlmconvert.c +++ b/fs/ocfs2/dlm/dlmconvert.c | |||
@@ -487,7 +487,7 @@ int dlm_convert_lock_handler(struct o2net_msg *msg, u32 len, void *data, | |||
487 | "cookie=%u:%llu\n", | 487 | "cookie=%u:%llu\n", |
488 | dlm_get_lock_cookie_node(be64_to_cpu(cnv->cookie)), | 488 | dlm_get_lock_cookie_node(be64_to_cpu(cnv->cookie)), |
489 | dlm_get_lock_cookie_seq(be64_to_cpu(cnv->cookie))); | 489 | dlm_get_lock_cookie_seq(be64_to_cpu(cnv->cookie))); |
490 | __dlm_print_one_lock_resource(res); | 490 | dlm_print_one_lock_resource(res); |
491 | goto leave; | 491 | goto leave; |
492 | } | 492 | } |
493 | 493 | ||
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 638d2ebb892b..0879d86113e3 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
@@ -713,14 +713,46 @@ static int dlm_query_join_proto_check(char *proto_type, int node, | |||
713 | return rc; | 713 | return rc; |
714 | } | 714 | } |
715 | 715 | ||
716 | /* | ||
717 | * struct dlm_query_join_packet is made up of four one-byte fields. They | ||
718 | * are effectively in big-endian order already. However, little-endian | ||
719 | * machines swap them before putting the packet on the wire (because | ||
720 | * query_join's response is a status, and that status is treated as a u32 | ||
721 | * on the wire). Thus, a big-endian and little-endian machines will treat | ||
722 | * this structure differently. | ||
723 | * | ||
724 | * The solution is to have little-endian machines swap the structure when | ||
725 | * converting from the structure to the u32 representation. This will | ||
726 | * result in the structure having the correct format on the wire no matter | ||
727 | * the host endian format. | ||
728 | */ | ||
729 | static void dlm_query_join_packet_to_wire(struct dlm_query_join_packet *packet, | ||
730 | u32 *wire) | ||
731 | { | ||
732 | union dlm_query_join_response response; | ||
733 | |||
734 | response.packet = *packet; | ||
735 | *wire = cpu_to_be32(response.intval); | ||
736 | } | ||
737 | |||
738 | static void dlm_query_join_wire_to_packet(u32 wire, | ||
739 | struct dlm_query_join_packet *packet) | ||
740 | { | ||
741 | union dlm_query_join_response response; | ||
742 | |||
743 | response.intval = cpu_to_be32(wire); | ||
744 | *packet = response.packet; | ||
745 | } | ||
746 | |||
716 | static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, | 747 | static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, |
717 | void **ret_data) | 748 | void **ret_data) |
718 | { | 749 | { |
719 | struct dlm_query_join_request *query; | 750 | struct dlm_query_join_request *query; |
720 | union dlm_query_join_response response = { | 751 | struct dlm_query_join_packet packet = { |
721 | .packet.code = JOIN_DISALLOW, | 752 | .code = JOIN_DISALLOW, |
722 | }; | 753 | }; |
723 | struct dlm_ctxt *dlm = NULL; | 754 | struct dlm_ctxt *dlm = NULL; |
755 | u32 response; | ||
724 | u8 nodenum; | 756 | u8 nodenum; |
725 | 757 | ||
726 | query = (struct dlm_query_join_request *) msg->buf; | 758 | query = (struct dlm_query_join_request *) msg->buf; |
@@ -737,11 +769,11 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, | |||
737 | mlog(0, "node %u is not in our live map yet\n", | 769 | mlog(0, "node %u is not in our live map yet\n", |
738 | query->node_idx); | 770 | query->node_idx); |
739 | 771 | ||
740 | response.packet.code = JOIN_DISALLOW; | 772 | packet.code = JOIN_DISALLOW; |
741 | goto respond; | 773 | goto respond; |
742 | } | 774 | } |
743 | 775 | ||
744 | response.packet.code = JOIN_OK_NO_MAP; | 776 | packet.code = JOIN_OK_NO_MAP; |
745 | 777 | ||
746 | spin_lock(&dlm_domain_lock); | 778 | spin_lock(&dlm_domain_lock); |
747 | dlm = __dlm_lookup_domain_full(query->domain, query->name_len); | 779 | dlm = __dlm_lookup_domain_full(query->domain, query->name_len); |
@@ -760,7 +792,7 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, | |||
760 | mlog(0, "disallow join as node %u does not " | 792 | mlog(0, "disallow join as node %u does not " |
761 | "have node %u in its nodemap\n", | 793 | "have node %u in its nodemap\n", |
762 | query->node_idx, nodenum); | 794 | query->node_idx, nodenum); |
763 | response.packet.code = JOIN_DISALLOW; | 795 | packet.code = JOIN_DISALLOW; |
764 | goto unlock_respond; | 796 | goto unlock_respond; |
765 | } | 797 | } |
766 | } | 798 | } |
@@ -780,23 +812,23 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, | |||
780 | /*If this is a brand new context and we | 812 | /*If this is a brand new context and we |
781 | * haven't started our join process yet, then | 813 | * haven't started our join process yet, then |
782 | * the other node won the race. */ | 814 | * the other node won the race. */ |
783 | response.packet.code = JOIN_OK_NO_MAP; | 815 | packet.code = JOIN_OK_NO_MAP; |
784 | } else if (dlm->joining_node != DLM_LOCK_RES_OWNER_UNKNOWN) { | 816 | } else if (dlm->joining_node != DLM_LOCK_RES_OWNER_UNKNOWN) { |
785 | /* Disallow parallel joins. */ | 817 | /* Disallow parallel joins. */ |
786 | response.packet.code = JOIN_DISALLOW; | 818 | packet.code = JOIN_DISALLOW; |
787 | } else if (dlm->reco.state & DLM_RECO_STATE_ACTIVE) { | 819 | } else if (dlm->reco.state & DLM_RECO_STATE_ACTIVE) { |
788 | mlog(0, "node %u trying to join, but recovery " | 820 | mlog(0, "node %u trying to join, but recovery " |
789 | "is ongoing.\n", bit); | 821 | "is ongoing.\n", bit); |
790 | response.packet.code = JOIN_DISALLOW; | 822 | packet.code = JOIN_DISALLOW; |
791 | } else if (test_bit(bit, dlm->recovery_map)) { | 823 | } else if (test_bit(bit, dlm->recovery_map)) { |
792 | mlog(0, "node %u trying to join, but it " | 824 | mlog(0, "node %u trying to join, but it " |
793 | "still needs recovery.\n", bit); | 825 | "still needs recovery.\n", bit); |
794 | response.packet.code = JOIN_DISALLOW; | 826 | packet.code = JOIN_DISALLOW; |
795 | } else if (test_bit(bit, dlm->domain_map)) { | 827 | } else if (test_bit(bit, dlm->domain_map)) { |
796 | mlog(0, "node %u trying to join, but it " | 828 | mlog(0, "node %u trying to join, but it " |
797 | "is still in the domain! needs recovery?\n", | 829 | "is still in the domain! needs recovery?\n", |
798 | bit); | 830 | bit); |
799 | response.packet.code = JOIN_DISALLOW; | 831 | packet.code = JOIN_DISALLOW; |
800 | } else { | 832 | } else { |
801 | /* Alright we're fully a part of this domain | 833 | /* Alright we're fully a part of this domain |
802 | * so we keep some state as to who's joining | 834 | * so we keep some state as to who's joining |
@@ -807,19 +839,15 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, | |||
807 | if (dlm_query_join_proto_check("DLM", bit, | 839 | if (dlm_query_join_proto_check("DLM", bit, |
808 | &dlm->dlm_locking_proto, | 840 | &dlm->dlm_locking_proto, |
809 | &query->dlm_proto)) { | 841 | &query->dlm_proto)) { |
810 | response.packet.code = | 842 | packet.code = JOIN_PROTOCOL_MISMATCH; |
811 | JOIN_PROTOCOL_MISMATCH; | ||
812 | } else if (dlm_query_join_proto_check("fs", bit, | 843 | } else if (dlm_query_join_proto_check("fs", bit, |
813 | &dlm->fs_locking_proto, | 844 | &dlm->fs_locking_proto, |
814 | &query->fs_proto)) { | 845 | &query->fs_proto)) { |
815 | response.packet.code = | 846 | packet.code = JOIN_PROTOCOL_MISMATCH; |
816 | JOIN_PROTOCOL_MISMATCH; | ||
817 | } else { | 847 | } else { |
818 | response.packet.dlm_minor = | 848 | packet.dlm_minor = query->dlm_proto.pv_minor; |
819 | query->dlm_proto.pv_minor; | 849 | packet.fs_minor = query->fs_proto.pv_minor; |
820 | response.packet.fs_minor = | 850 | packet.code = JOIN_OK; |
821 | query->fs_proto.pv_minor; | ||
822 | response.packet.code = JOIN_OK; | ||
823 | __dlm_set_joining_node(dlm, query->node_idx); | 851 | __dlm_set_joining_node(dlm, query->node_idx); |
824 | } | 852 | } |
825 | } | 853 | } |
@@ -830,9 +858,10 @@ unlock_respond: | |||
830 | spin_unlock(&dlm_domain_lock); | 858 | spin_unlock(&dlm_domain_lock); |
831 | 859 | ||
832 | respond: | 860 | respond: |
833 | mlog(0, "We respond with %u\n", response.packet.code); | 861 | mlog(0, "We respond with %u\n", packet.code); |
834 | 862 | ||
835 | return response.intval; | 863 | dlm_query_join_packet_to_wire(&packet, &response); |
864 | return response; | ||
836 | } | 865 | } |
837 | 866 | ||
838 | static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data, | 867 | static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data, |
@@ -937,7 +966,7 @@ static int dlm_send_join_cancels(struct dlm_ctxt *dlm, | |||
937 | sizeof(unsigned long))) { | 966 | sizeof(unsigned long))) { |
938 | mlog(ML_ERROR, | 967 | mlog(ML_ERROR, |
939 | "map_size %u != BITS_TO_LONGS(O2NM_MAX_NODES) %u\n", | 968 | "map_size %u != BITS_TO_LONGS(O2NM_MAX_NODES) %u\n", |
940 | map_size, BITS_TO_LONGS(O2NM_MAX_NODES)); | 969 | map_size, (unsigned)BITS_TO_LONGS(O2NM_MAX_NODES)); |
941 | return -EINVAL; | 970 | return -EINVAL; |
942 | } | 971 | } |
943 | 972 | ||
@@ -968,7 +997,8 @@ static int dlm_request_join(struct dlm_ctxt *dlm, | |||
968 | { | 997 | { |
969 | int status; | 998 | int status; |
970 | struct dlm_query_join_request join_msg; | 999 | struct dlm_query_join_request join_msg; |
971 | union dlm_query_join_response join_resp; | 1000 | struct dlm_query_join_packet packet; |
1001 | u32 join_resp; | ||
972 | 1002 | ||
973 | mlog(0, "querying node %d\n", node); | 1003 | mlog(0, "querying node %d\n", node); |
974 | 1004 | ||
@@ -984,11 +1014,12 @@ static int dlm_request_join(struct dlm_ctxt *dlm, | |||
984 | 1014 | ||
985 | status = o2net_send_message(DLM_QUERY_JOIN_MSG, DLM_MOD_KEY, &join_msg, | 1015 | status = o2net_send_message(DLM_QUERY_JOIN_MSG, DLM_MOD_KEY, &join_msg, |
986 | sizeof(join_msg), node, | 1016 | sizeof(join_msg), node, |
987 | &join_resp.intval); | 1017 | &join_resp); |
988 | if (status < 0 && status != -ENOPROTOOPT) { | 1018 | if (status < 0 && status != -ENOPROTOOPT) { |
989 | mlog_errno(status); | 1019 | mlog_errno(status); |
990 | goto bail; | 1020 | goto bail; |
991 | } | 1021 | } |
1022 | dlm_query_join_wire_to_packet(join_resp, &packet); | ||
992 | 1023 | ||
993 | /* -ENOPROTOOPT from the net code means the other side isn't | 1024 | /* -ENOPROTOOPT from the net code means the other side isn't |
994 | listening for our message type -- that's fine, it means | 1025 | listening for our message type -- that's fine, it means |
@@ -997,10 +1028,10 @@ static int dlm_request_join(struct dlm_ctxt *dlm, | |||
997 | if (status == -ENOPROTOOPT) { | 1028 | if (status == -ENOPROTOOPT) { |
998 | status = 0; | 1029 | status = 0; |
999 | *response = JOIN_OK_NO_MAP; | 1030 | *response = JOIN_OK_NO_MAP; |
1000 | } else if (join_resp.packet.code == JOIN_DISALLOW || | 1031 | } else if (packet.code == JOIN_DISALLOW || |
1001 | join_resp.packet.code == JOIN_OK_NO_MAP) { | 1032 | packet.code == JOIN_OK_NO_MAP) { |
1002 | *response = join_resp.packet.code; | 1033 | *response = packet.code; |
1003 | } else if (join_resp.packet.code == JOIN_PROTOCOL_MISMATCH) { | 1034 | } else if (packet.code == JOIN_PROTOCOL_MISMATCH) { |
1004 | mlog(ML_NOTICE, | 1035 | mlog(ML_NOTICE, |
1005 | "This node requested DLM locking protocol %u.%u and " | 1036 | "This node requested DLM locking protocol %u.%u and " |
1006 | "filesystem locking protocol %u.%u. At least one of " | 1037 | "filesystem locking protocol %u.%u. At least one of " |
@@ -1012,14 +1043,12 @@ static int dlm_request_join(struct dlm_ctxt *dlm, | |||
1012 | dlm->fs_locking_proto.pv_minor, | 1043 | dlm->fs_locking_proto.pv_minor, |
1013 | node); | 1044 | node); |
1014 | status = -EPROTO; | 1045 | status = -EPROTO; |
1015 | *response = join_resp.packet.code; | 1046 | *response = packet.code; |
1016 | } else if (join_resp.packet.code == JOIN_OK) { | 1047 | } else if (packet.code == JOIN_OK) { |
1017 | *response = join_resp.packet.code; | 1048 | *response = packet.code; |
1018 | /* Use the same locking protocol as the remote node */ | 1049 | /* Use the same locking protocol as the remote node */ |
1019 | dlm->dlm_locking_proto.pv_minor = | 1050 | dlm->dlm_locking_proto.pv_minor = packet.dlm_minor; |
1020 | join_resp.packet.dlm_minor; | 1051 | dlm->fs_locking_proto.pv_minor = packet.fs_minor; |
1021 | dlm->fs_locking_proto.pv_minor = | ||
1022 | join_resp.packet.fs_minor; | ||
1023 | mlog(0, | 1052 | mlog(0, |
1024 | "Node %d responds JOIN_OK with DLM locking protocol " | 1053 | "Node %d responds JOIN_OK with DLM locking protocol " |
1025 | "%u.%u and fs locking protocol %u.%u\n", | 1054 | "%u.%u and fs locking protocol %u.%u\n", |
@@ -1031,11 +1060,11 @@ static int dlm_request_join(struct dlm_ctxt *dlm, | |||
1031 | } else { | 1060 | } else { |
1032 | status = -EINVAL; | 1061 | status = -EINVAL; |
1033 | mlog(ML_ERROR, "invalid response %d from node %u\n", | 1062 | mlog(ML_ERROR, "invalid response %d from node %u\n", |
1034 | join_resp.packet.code, node); | 1063 | packet.code, node); |
1035 | } | 1064 | } |
1036 | 1065 | ||
1037 | mlog(0, "status %d, node %d response is %d\n", status, node, | 1066 | mlog(0, "status %d, node %d response is %d\n", status, node, |
1038 | *response); | 1067 | *response); |
1039 | 1068 | ||
1040 | bail: | 1069 | bail: |
1041 | return status; | 1070 | return status; |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index c92d1b19fc0b..ea6b89577860 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
@@ -1663,7 +1663,12 @@ way_up_top: | |||
1663 | dlm_put_mle(tmpmle); | 1663 | dlm_put_mle(tmpmle); |
1664 | } | 1664 | } |
1665 | send_response: | 1665 | send_response: |
1666 | 1666 | /* | |
1667 | * __dlm_lookup_lockres() grabbed a reference to this lockres. | ||
1668 | * The reference is released by dlm_assert_master_worker() under | ||
1669 | * the call to dlm_dispatch_assert_master(). If | ||
1670 | * dlm_assert_master_worker() isn't called, we drop it here. | ||
1671 | */ | ||
1667 | if (dispatch_assert) { | 1672 | if (dispatch_assert) { |
1668 | if (response != DLM_MASTER_RESP_YES) | 1673 | if (response != DLM_MASTER_RESP_YES) |
1669 | mlog(ML_ERROR, "invalid response %d\n", response); | 1674 | mlog(ML_ERROR, "invalid response %d\n", response); |
@@ -1678,7 +1683,11 @@ send_response: | |||
1678 | if (ret < 0) { | 1683 | if (ret < 0) { |
1679 | mlog(ML_ERROR, "failed to dispatch assert master work\n"); | 1684 | mlog(ML_ERROR, "failed to dispatch assert master work\n"); |
1680 | response = DLM_MASTER_RESP_ERROR; | 1685 | response = DLM_MASTER_RESP_ERROR; |
1686 | dlm_lockres_put(res); | ||
1681 | } | 1687 | } |
1688 | } else { | ||
1689 | if (res) | ||
1690 | dlm_lockres_put(res); | ||
1682 | } | 1691 | } |
1683 | 1692 | ||
1684 | dlm_put(dlm); | 1693 | dlm_put(dlm); |
@@ -2348,7 +2357,7 @@ int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data, | |||
2348 | mlog(ML_ERROR, "%s:%.*s: node %u trying to drop ref " | 2357 | mlog(ML_ERROR, "%s:%.*s: node %u trying to drop ref " |
2349 | "but it is already dropped!\n", dlm->name, | 2358 | "but it is already dropped!\n", dlm->name, |
2350 | res->lockname.len, res->lockname.name, node); | 2359 | res->lockname.len, res->lockname.name, node); |
2351 | __dlm_print_one_lock_resource(res); | 2360 | dlm_print_one_lock_resource(res); |
2352 | } | 2361 | } |
2353 | ret = 0; | 2362 | ret = 0; |
2354 | goto done; | 2363 | goto done; |
@@ -2408,7 +2417,7 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data) | |||
2408 | mlog(ML_ERROR, "%s:%.*s: node %u trying to drop ref " | 2417 | mlog(ML_ERROR, "%s:%.*s: node %u trying to drop ref " |
2409 | "but it is already dropped!\n", dlm->name, | 2418 | "but it is already dropped!\n", dlm->name, |
2410 | res->lockname.len, res->lockname.name, node); | 2419 | res->lockname.len, res->lockname.name, node); |
2411 | __dlm_print_one_lock_resource(res); | 2420 | dlm_print_one_lock_resource(res); |
2412 | } | 2421 | } |
2413 | 2422 | ||
2414 | dlm_lockres_put(res); | 2423 | dlm_lockres_put(res); |
@@ -2933,6 +2942,9 @@ static void dlm_remove_nonlocal_locks(struct dlm_ctxt *dlm, | |||
2933 | dlm_lockres_clear_refmap_bit(lock->ml.node, res); | 2942 | dlm_lockres_clear_refmap_bit(lock->ml.node, res); |
2934 | list_del_init(&lock->list); | 2943 | list_del_init(&lock->list); |
2935 | dlm_lock_put(lock); | 2944 | dlm_lock_put(lock); |
2945 | /* In a normal unlock, we would have added a | ||
2946 | * DLM_UNLOCK_FREE_LOCK action. Force it. */ | ||
2947 | dlm_lock_put(lock); | ||
2936 | } | 2948 | } |
2937 | } | 2949 | } |
2938 | queue++; | 2950 | queue++; |
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 91f747b8a538..bcb9260c3735 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c | |||
@@ -519,9 +519,9 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm) | |||
519 | return 0; | 519 | return 0; |
520 | 520 | ||
521 | master_here: | 521 | master_here: |
522 | mlog(0, "(%d) mastering recovery of %s:%u here(this=%u)!\n", | 522 | mlog(ML_NOTICE, "(%d) Node %u is the Recovery Master for the Dead Node " |
523 | task_pid_nr(dlm->dlm_reco_thread_task), | 523 | "%u for Domain %s\n", task_pid_nr(dlm->dlm_reco_thread_task), |
524 | dlm->name, dlm->reco.dead_node, dlm->node_num); | 524 | dlm->node_num, dlm->reco.dead_node, dlm->name); |
525 | 525 | ||
526 | status = dlm_remaster_locks(dlm, dlm->reco.dead_node); | 526 | status = dlm_remaster_locks(dlm, dlm->reco.dead_node); |
527 | if (status < 0) { | 527 | if (status < 0) { |
@@ -1191,7 +1191,7 @@ static int dlm_add_lock_to_array(struct dlm_lock *lock, | |||
1191 | (ml->type == LKM_EXMODE || | 1191 | (ml->type == LKM_EXMODE || |
1192 | memcmp(mres->lvb, lock->lksb->lvb, DLM_LVB_LEN))) { | 1192 | memcmp(mres->lvb, lock->lksb->lvb, DLM_LVB_LEN))) { |
1193 | mlog(ML_ERROR, "mismatched lvbs!\n"); | 1193 | mlog(ML_ERROR, "mismatched lvbs!\n"); |
1194 | __dlm_print_one_lock_resource(lock->lockres); | 1194 | dlm_print_one_lock_resource(lock->lockres); |
1195 | BUG(); | 1195 | BUG(); |
1196 | } | 1196 | } |
1197 | memcpy(mres->lvb, lock->lksb->lvb, DLM_LVB_LEN); | 1197 | memcpy(mres->lvb, lock->lksb->lvb, DLM_LVB_LEN); |
@@ -1327,6 +1327,7 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, | |||
1327 | (struct dlm_migratable_lockres *)msg->buf; | 1327 | (struct dlm_migratable_lockres *)msg->buf; |
1328 | int ret = 0; | 1328 | int ret = 0; |
1329 | u8 real_master; | 1329 | u8 real_master; |
1330 | u8 extra_refs = 0; | ||
1330 | char *buf = NULL; | 1331 | char *buf = NULL; |
1331 | struct dlm_work_item *item = NULL; | 1332 | struct dlm_work_item *item = NULL; |
1332 | struct dlm_lock_resource *res = NULL; | 1333 | struct dlm_lock_resource *res = NULL; |
@@ -1404,16 +1405,28 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, | |||
1404 | __dlm_insert_lockres(dlm, res); | 1405 | __dlm_insert_lockres(dlm, res); |
1405 | spin_unlock(&dlm->spinlock); | 1406 | spin_unlock(&dlm->spinlock); |
1406 | 1407 | ||
1408 | /* Add an extra ref for this lock-less lockres lest the | ||
1409 | * dlm_thread purges it before we get the chance to add | ||
1410 | * locks to it */ | ||
1411 | dlm_lockres_get(res); | ||
1412 | |||
1413 | /* There are three refs that need to be put. | ||
1414 | * 1. Taken above. | ||
1415 | * 2. kref_init in dlm_new_lockres()->dlm_init_lockres(). | ||
1416 | * 3. dlm_lookup_lockres() | ||
1417 | * The first one is handled at the end of this function. The | ||
1418 | * other two are handled in the worker thread after locks have | ||
1419 | * been attached. Yes, we don't wait for purge time to match | ||
1420 | * kref_init. The lockres will still have atleast one ref | ||
1421 | * added because it is in the hash __dlm_insert_lockres() */ | ||
1422 | extra_refs++; | ||
1423 | |||
1407 | /* now that the new lockres is inserted, | 1424 | /* now that the new lockres is inserted, |
1408 | * make it usable by other processes */ | 1425 | * make it usable by other processes */ |
1409 | spin_lock(&res->spinlock); | 1426 | spin_lock(&res->spinlock); |
1410 | res->state &= ~DLM_LOCK_RES_IN_PROGRESS; | 1427 | res->state &= ~DLM_LOCK_RES_IN_PROGRESS; |
1411 | spin_unlock(&res->spinlock); | 1428 | spin_unlock(&res->spinlock); |
1412 | wake_up(&res->wq); | 1429 | wake_up(&res->wq); |
1413 | |||
1414 | /* add an extra ref for just-allocated lockres | ||
1415 | * otherwise the lockres will be purged immediately */ | ||
1416 | dlm_lockres_get(res); | ||
1417 | } | 1430 | } |
1418 | 1431 | ||
1419 | /* at this point we have allocated everything we need, | 1432 | /* at this point we have allocated everything we need, |
@@ -1443,12 +1456,17 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, | |||
1443 | dlm_init_work_item(dlm, item, dlm_mig_lockres_worker, buf); | 1456 | dlm_init_work_item(dlm, item, dlm_mig_lockres_worker, buf); |
1444 | item->u.ml.lockres = res; /* already have a ref */ | 1457 | item->u.ml.lockres = res; /* already have a ref */ |
1445 | item->u.ml.real_master = real_master; | 1458 | item->u.ml.real_master = real_master; |
1459 | item->u.ml.extra_ref = extra_refs; | ||
1446 | spin_lock(&dlm->work_lock); | 1460 | spin_lock(&dlm->work_lock); |
1447 | list_add_tail(&item->list, &dlm->work_list); | 1461 | list_add_tail(&item->list, &dlm->work_list); |
1448 | spin_unlock(&dlm->work_lock); | 1462 | spin_unlock(&dlm->work_lock); |
1449 | queue_work(dlm->dlm_worker, &dlm->dispatched_work); | 1463 | queue_work(dlm->dlm_worker, &dlm->dispatched_work); |
1450 | 1464 | ||
1451 | leave: | 1465 | leave: |
1466 | /* One extra ref taken needs to be put here */ | ||
1467 | if (extra_refs) | ||
1468 | dlm_lockres_put(res); | ||
1469 | |||
1452 | dlm_put(dlm); | 1470 | dlm_put(dlm); |
1453 | if (ret < 0) { | 1471 | if (ret < 0) { |
1454 | if (buf) | 1472 | if (buf) |
@@ -1464,17 +1482,19 @@ leave: | |||
1464 | 1482 | ||
1465 | static void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data) | 1483 | static void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data) |
1466 | { | 1484 | { |
1467 | struct dlm_ctxt *dlm = data; | 1485 | struct dlm_ctxt *dlm; |
1468 | struct dlm_migratable_lockres *mres; | 1486 | struct dlm_migratable_lockres *mres; |
1469 | int ret = 0; | 1487 | int ret = 0; |
1470 | struct dlm_lock_resource *res; | 1488 | struct dlm_lock_resource *res; |
1471 | u8 real_master; | 1489 | u8 real_master; |
1490 | u8 extra_ref; | ||
1472 | 1491 | ||
1473 | dlm = item->dlm; | 1492 | dlm = item->dlm; |
1474 | mres = (struct dlm_migratable_lockres *)data; | 1493 | mres = (struct dlm_migratable_lockres *)data; |
1475 | 1494 | ||
1476 | res = item->u.ml.lockres; | 1495 | res = item->u.ml.lockres; |
1477 | real_master = item->u.ml.real_master; | 1496 | real_master = item->u.ml.real_master; |
1497 | extra_ref = item->u.ml.extra_ref; | ||
1478 | 1498 | ||
1479 | if (real_master == DLM_LOCK_RES_OWNER_UNKNOWN) { | 1499 | if (real_master == DLM_LOCK_RES_OWNER_UNKNOWN) { |
1480 | /* this case is super-rare. only occurs if | 1500 | /* this case is super-rare. only occurs if |
@@ -1517,6 +1537,12 @@ again: | |||
1517 | } | 1537 | } |
1518 | 1538 | ||
1519 | leave: | 1539 | leave: |
1540 | /* See comment in dlm_mig_lockres_handler() */ | ||
1541 | if (res) { | ||
1542 | if (extra_ref) | ||
1543 | dlm_lockres_put(res); | ||
1544 | dlm_lockres_put(res); | ||
1545 | } | ||
1520 | kfree(data); | 1546 | kfree(data); |
1521 | mlog_exit(ret); | 1547 | mlog_exit(ret); |
1522 | } | 1548 | } |
@@ -1644,7 +1670,8 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data, | |||
1644 | /* retry!? */ | 1670 | /* retry!? */ |
1645 | BUG(); | 1671 | BUG(); |
1646 | } | 1672 | } |
1647 | } | 1673 | } else /* put.. incase we are not the master */ |
1674 | dlm_lockres_put(res); | ||
1648 | spin_unlock(&res->spinlock); | 1675 | spin_unlock(&res->spinlock); |
1649 | } | 1676 | } |
1650 | spin_unlock(&dlm->spinlock); | 1677 | spin_unlock(&dlm->spinlock); |
@@ -1921,6 +1948,7 @@ void dlm_move_lockres_to_recovery_list(struct dlm_ctxt *dlm, | |||
1921 | "Recovering res %s:%.*s, is already on recovery list!\n", | 1948 | "Recovering res %s:%.*s, is already on recovery list!\n", |
1922 | dlm->name, res->lockname.len, res->lockname.name); | 1949 | dlm->name, res->lockname.len, res->lockname.name); |
1923 | list_del_init(&res->recovering); | 1950 | list_del_init(&res->recovering); |
1951 | dlm_lockres_put(res); | ||
1924 | } | 1952 | } |
1925 | /* We need to hold a reference while on the recovery list */ | 1953 | /* We need to hold a reference while on the recovery list */ |
1926 | dlm_lockres_get(res); | 1954 | dlm_lockres_get(res); |
@@ -2130,11 +2158,16 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm, | |||
2130 | assert_spin_locked(&dlm->spinlock); | 2158 | assert_spin_locked(&dlm->spinlock); |
2131 | assert_spin_locked(&res->spinlock); | 2159 | assert_spin_locked(&res->spinlock); |
2132 | 2160 | ||
2161 | /* We do two dlm_lock_put(). One for removing from list and the other is | ||
2162 | * to force the DLM_UNLOCK_FREE_LOCK action so as to free the locks */ | ||
2163 | |||
2133 | /* TODO: check pending_asts, pending_basts here */ | 2164 | /* TODO: check pending_asts, pending_basts here */ |
2134 | list_for_each_entry_safe(lock, next, &res->granted, list) { | 2165 | list_for_each_entry_safe(lock, next, &res->granted, list) { |
2135 | if (lock->ml.node == dead_node) { | 2166 | if (lock->ml.node == dead_node) { |
2136 | list_del_init(&lock->list); | 2167 | list_del_init(&lock->list); |
2137 | dlm_lock_put(lock); | 2168 | dlm_lock_put(lock); |
2169 | /* Can't schedule DLM_UNLOCK_FREE_LOCK - do manually */ | ||
2170 | dlm_lock_put(lock); | ||
2138 | freed++; | 2171 | freed++; |
2139 | } | 2172 | } |
2140 | } | 2173 | } |
@@ -2142,6 +2175,8 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm, | |||
2142 | if (lock->ml.node == dead_node) { | 2175 | if (lock->ml.node == dead_node) { |
2143 | list_del_init(&lock->list); | 2176 | list_del_init(&lock->list); |
2144 | dlm_lock_put(lock); | 2177 | dlm_lock_put(lock); |
2178 | /* Can't schedule DLM_UNLOCK_FREE_LOCK - do manually */ | ||
2179 | dlm_lock_put(lock); | ||
2145 | freed++; | 2180 | freed++; |
2146 | } | 2181 | } |
2147 | } | 2182 | } |
@@ -2149,6 +2184,8 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm, | |||
2149 | if (lock->ml.node == dead_node) { | 2184 | if (lock->ml.node == dead_node) { |
2150 | list_del_init(&lock->list); | 2185 | list_del_init(&lock->list); |
2151 | dlm_lock_put(lock); | 2186 | dlm_lock_put(lock); |
2187 | /* Can't schedule DLM_UNLOCK_FREE_LOCK - do manually */ | ||
2188 | dlm_lock_put(lock); | ||
2152 | freed++; | 2189 | freed++; |
2153 | } | 2190 | } |
2154 | } | 2191 | } |
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index cebd089f8955..4060bb328bc8 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c | |||
@@ -176,12 +176,14 @@ static int dlm_purge_lockres(struct dlm_ctxt *dlm, | |||
176 | res->lockname.name, master); | 176 | res->lockname.name, master); |
177 | 177 | ||
178 | if (!master) { | 178 | if (!master) { |
179 | /* drop spinlock... retake below */ | ||
180 | spin_unlock(&dlm->spinlock); | ||
181 | |||
179 | spin_lock(&res->spinlock); | 182 | spin_lock(&res->spinlock); |
180 | /* This ensures that clear refmap is sent after the set */ | 183 | /* This ensures that clear refmap is sent after the set */ |
181 | __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG); | 184 | __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG); |
182 | spin_unlock(&res->spinlock); | 185 | spin_unlock(&res->spinlock); |
183 | /* drop spinlock to do messaging, retake below */ | 186 | |
184 | spin_unlock(&dlm->spinlock); | ||
185 | /* clear our bit from the master's refmap, ignore errors */ | 187 | /* clear our bit from the master's refmap, ignore errors */ |
186 | ret = dlm_drop_lockres_ref(dlm, res); | 188 | ret = dlm_drop_lockres_ref(dlm, res); |
187 | if (ret < 0) { | 189 | if (ret < 0) { |
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index f7794306b2bd..1f1873bf41fb 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
@@ -2409,7 +2409,7 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) | |||
2409 | return 0; | 2409 | return 0; |
2410 | } | 2410 | } |
2411 | 2411 | ||
2412 | static struct seq_operations ocfs2_dlm_seq_ops = { | 2412 | static const struct seq_operations ocfs2_dlm_seq_ops = { |
2413 | .start = ocfs2_dlm_seq_start, | 2413 | .start = ocfs2_dlm_seq_start, |
2414 | .stop = ocfs2_dlm_seq_stop, | 2414 | .stop = ocfs2_dlm_seq_stop, |
2415 | .next = ocfs2_dlm_seq_next, | 2415 | .next = ocfs2_dlm_seq_next, |
diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c index 37835ffcb039..8166968e9015 100644 --- a/fs/ocfs2/resize.c +++ b/fs/ocfs2/resize.c | |||
@@ -597,7 +597,7 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input) | |||
597 | memset(cr, 0, sizeof(struct ocfs2_chain_rec)); | 597 | memset(cr, 0, sizeof(struct ocfs2_chain_rec)); |
598 | } | 598 | } |
599 | 599 | ||
600 | cr->c_blkno = le64_to_cpu(input->group); | 600 | cr->c_blkno = cpu_to_le64(input->group); |
601 | le32_add_cpu(&cr->c_total, input->clusters * cl_bpc); | 601 | le32_add_cpu(&cr->c_total, input->clusters * cl_bpc); |
602 | le32_add_cpu(&cr->c_free, input->frees * cl_bpc); | 602 | le32_add_cpu(&cr->c_free, input->frees * cl_bpc); |
603 | 603 | ||
diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index a842c7222b1e..4e6a0fca0b47 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h | |||
@@ -26,10 +26,9 @@ struct mm_struct; | |||
26 | struct vm_area_struct; | 26 | struct vm_area_struct; |
27 | 27 | ||
28 | extern pgd_t swapper_pg_dir[1024]; | 28 | extern pgd_t swapper_pg_dir[1024]; |
29 | extern struct kmem_cache *pmd_cache; | ||
30 | void check_pgt_cache(void); | ||
31 | 29 | ||
32 | static inline void pgtable_cache_init(void) {} | 30 | static inline void pgtable_cache_init(void) { } |
31 | static inline void check_pgt_cache(void) { } | ||
33 | void paging_init(void); | 32 | void paging_init(void); |
34 | 33 | ||
35 | 34 | ||
diff --git a/include/crypto/internal/skcipher.h b/include/crypto/internal/skcipher.h index a8f12644a13c..ccc32bad9a89 100644 --- a/include/crypto/internal/skcipher.h +++ b/include/crypto/internal/skcipher.h | |||
@@ -68,7 +68,7 @@ void skcipher_geniv_exit(struct crypto_tfm *tfm); | |||
68 | int __init eseqiv_module_init(void); | 68 | int __init eseqiv_module_init(void); |
69 | void __exit eseqiv_module_exit(void); | 69 | void __exit eseqiv_module_exit(void); |
70 | int __init chainiv_module_init(void); | 70 | int __init chainiv_module_init(void); |
71 | void __exit chainiv_module_exit(void); | 71 | void chainiv_module_exit(void); |
72 | 72 | ||
73 | static inline struct crypto_ablkcipher *skcipher_geniv_cipher( | 73 | static inline struct crypto_ablkcipher *skcipher_geniv_cipher( |
74 | struct crypto_ablkcipher *geniv) | 74 | struct crypto_ablkcipher *geniv) |
diff --git a/include/linux/firmware.h b/include/linux/firmware.h index 33d8f2087b6e..4d10c7328d2d 100644 --- a/include/linux/firmware.h +++ b/include/linux/firmware.h | |||
@@ -10,7 +10,10 @@ struct firmware { | |||
10 | size_t size; | 10 | size_t size; |
11 | u8 *data; | 11 | u8 *data; |
12 | }; | 12 | }; |
13 | |||
13 | struct device; | 14 | struct device; |
15 | |||
16 | #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) | ||
14 | int request_firmware(const struct firmware **fw, const char *name, | 17 | int request_firmware(const struct firmware **fw, const char *name, |
15 | struct device *device); | 18 | struct device *device); |
16 | int request_firmware_nowait( | 19 | int request_firmware_nowait( |
@@ -19,4 +22,24 @@ int request_firmware_nowait( | |||
19 | void (*cont)(const struct firmware *fw, void *context)); | 22 | void (*cont)(const struct firmware *fw, void *context)); |
20 | 23 | ||
21 | void release_firmware(const struct firmware *fw); | 24 | void release_firmware(const struct firmware *fw); |
25 | #else | ||
26 | static inline int request_firmware(const struct firmware **fw, | ||
27 | const char *name, | ||
28 | struct device *device) | ||
29 | { | ||
30 | return -EINVAL; | ||
31 | } | ||
32 | static inline int request_firmware_nowait( | ||
33 | struct module *module, int uevent, | ||
34 | const char *name, struct device *device, void *context, | ||
35 | void (*cont)(const struct firmware *fw, void *context)) | ||
36 | { | ||
37 | return -EINVAL; | ||
38 | } | ||
39 | |||
40 | static inline void release_firmware(const struct firmware *fw) | ||
41 | { | ||
42 | } | ||
43 | #endif | ||
44 | |||
22 | #endif | 45 | #endif |
diff --git a/include/linux/memstick.h b/include/linux/memstick.h index 334d059d6794..b7ee25888836 100644 --- a/include/linux/memstick.h +++ b/include/linux/memstick.h | |||
@@ -22,6 +22,8 @@ struct ms_status_register { | |||
22 | unsigned char reserved; | 22 | unsigned char reserved; |
23 | unsigned char interrupt; | 23 | unsigned char interrupt; |
24 | #define MEMSTICK_INT_CMDNAK 0x0001 | 24 | #define MEMSTICK_INT_CMDNAK 0x0001 |
25 | #define MEMSTICK_INT_IOREQ 0x0008 | ||
26 | #define MEMSTICK_INT_IOBREQ 0x0010 | ||
25 | #define MEMSTICK_INT_BREQ 0x0020 | 27 | #define MEMSTICK_INT_BREQ 0x0020 |
26 | #define MEMSTICK_INT_ERR 0x0040 | 28 | #define MEMSTICK_INT_ERR 0x0040 |
27 | #define MEMSTICK_INT_CED 0x0080 | 29 | #define MEMSTICK_INT_CED 0x0080 |
@@ -47,13 +49,17 @@ struct ms_status_register { | |||
47 | 49 | ||
48 | struct ms_id_register { | 50 | struct ms_id_register { |
49 | unsigned char type; | 51 | unsigned char type; |
50 | unsigned char reserved; | 52 | unsigned char if_mode; |
51 | unsigned char category; | 53 | unsigned char category; |
52 | unsigned char class; | 54 | unsigned char class; |
53 | } __attribute__((packed)); | 55 | } __attribute__((packed)); |
54 | 56 | ||
55 | struct ms_param_register { | 57 | struct ms_param_register { |
56 | unsigned char system; | 58 | unsigned char system; |
59 | #define MEMSTICK_SYS_ATEN 0xc0 | ||
60 | #define MEMSTICK_SYS_BAMD 0x80 | ||
61 | #define MEMSTICK_SYS_PAM 0x08 | ||
62 | |||
57 | unsigned char block_address_msb; | 63 | unsigned char block_address_msb; |
58 | unsigned short block_address; | 64 | unsigned short block_address; |
59 | unsigned char cp; | 65 | unsigned char cp; |
@@ -90,16 +96,48 @@ struct ms_register { | |||
90 | 96 | ||
91 | struct mspro_param_register { | 97 | struct mspro_param_register { |
92 | unsigned char system; | 98 | unsigned char system; |
99 | #define MEMSTICK_SYS_SERIAL 0x80 | ||
100 | #define MEMSTICK_SYS_PAR4 0x00 | ||
101 | #define MEMSTICK_SYS_PAR8 0x40 | ||
102 | |||
103 | unsigned short data_count; | ||
104 | unsigned int data_address; | ||
105 | unsigned char tpc_param; | ||
106 | } __attribute__((packed)); | ||
107 | |||
108 | struct mspro_io_info_register { | ||
109 | unsigned char version; | ||
110 | unsigned char io_category; | ||
111 | unsigned char current_req; | ||
112 | unsigned char card_opt_info; | ||
113 | unsigned char rdy_wait_time; | ||
114 | } __attribute__((packed)); | ||
115 | |||
116 | struct mspro_io_func_register { | ||
117 | unsigned char func_enable; | ||
118 | unsigned char func_select; | ||
119 | unsigned char func_intmask; | ||
120 | unsigned char transfer_mode; | ||
121 | } __attribute__((packed)); | ||
122 | |||
123 | struct mspro_io_cmd_register { | ||
124 | unsigned short tpc_param; | ||
93 | unsigned short data_count; | 125 | unsigned short data_count; |
94 | unsigned int data_address; | 126 | unsigned int data_address; |
95 | unsigned char cmd_param; | ||
96 | } __attribute__((packed)); | 127 | } __attribute__((packed)); |
97 | 128 | ||
98 | struct mspro_register { | 129 | struct mspro_register { |
99 | struct ms_status_register status; | 130 | struct ms_status_register status; |
100 | struct ms_id_register id; | 131 | struct ms_id_register id; |
101 | unsigned char reserved[8]; | 132 | unsigned char reserved0[8]; |
102 | struct mspro_param_register param; | 133 | struct mspro_param_register param; |
134 | unsigned char reserved1[8]; | ||
135 | struct mspro_io_info_register io_info; | ||
136 | struct mspro_io_func_register io_func; | ||
137 | unsigned char reserved2[7]; | ||
138 | struct mspro_io_cmd_register io_cmd; | ||
139 | unsigned char io_int; | ||
140 | unsigned char io_int_func; | ||
103 | } __attribute__((packed)); | 141 | } __attribute__((packed)); |
104 | 142 | ||
105 | struct ms_register_addr { | 143 | struct ms_register_addr { |
@@ -110,49 +148,55 @@ struct ms_register_addr { | |||
110 | } __attribute__((packed)); | 148 | } __attribute__((packed)); |
111 | 149 | ||
112 | enum { | 150 | enum { |
151 | MS_TPC_READ_MG_STATUS = 0x01, | ||
113 | MS_TPC_READ_LONG_DATA = 0x02, | 152 | MS_TPC_READ_LONG_DATA = 0x02, |
114 | MS_TPC_READ_SHORT_DATA = 0x03, | 153 | MS_TPC_READ_SHORT_DATA = 0x03, |
154 | MS_TPC_READ_MG_DATA = 0x03, | ||
115 | MS_TPC_READ_REG = 0x04, | 155 | MS_TPC_READ_REG = 0x04, |
116 | MS_TPC_READ_IO_DATA = 0x05, /* unverified */ | 156 | MS_TPC_READ_QUAD_DATA = 0x05, |
157 | MS_TPC_READ_IO_DATA = 0x05, | ||
117 | MS_TPC_GET_INT = 0x07, | 158 | MS_TPC_GET_INT = 0x07, |
118 | MS_TPC_SET_RW_REG_ADRS = 0x08, | 159 | MS_TPC_SET_RW_REG_ADRS = 0x08, |
119 | MS_TPC_EX_SET_CMD = 0x09, | 160 | MS_TPC_EX_SET_CMD = 0x09, |
120 | MS_TPC_WRITE_IO_DATA = 0x0a, /* unverified */ | 161 | MS_TPC_WRITE_QUAD_DATA = 0x0a, |
162 | MS_TPC_WRITE_IO_DATA = 0x0a, | ||
121 | MS_TPC_WRITE_REG = 0x0b, | 163 | MS_TPC_WRITE_REG = 0x0b, |
122 | MS_TPC_WRITE_SHORT_DATA = 0x0c, | 164 | MS_TPC_WRITE_SHORT_DATA = 0x0c, |
165 | MS_TPC_WRITE_MG_DATA = 0x0c, | ||
123 | MS_TPC_WRITE_LONG_DATA = 0x0d, | 166 | MS_TPC_WRITE_LONG_DATA = 0x0d, |
124 | MS_TPC_SET_CMD = 0x0e | 167 | MS_TPC_SET_CMD = 0x0e |
125 | }; | 168 | }; |
126 | 169 | ||
127 | enum { | 170 | enum { |
128 | MS_CMD_BLOCK_END = 0x33, | 171 | MS_CMD_BLOCK_END = 0x33, |
129 | MS_CMD_RESET = 0x3c, | 172 | MS_CMD_RESET = 0x3c, |
130 | MS_CMD_BLOCK_WRITE = 0x55, | 173 | MS_CMD_BLOCK_WRITE = 0x55, |
131 | MS_CMD_SLEEP = 0x5a, | 174 | MS_CMD_SLEEP = 0x5a, |
132 | MS_CMD_BLOCK_ERASE = 0x99, | 175 | MS_CMD_BLOCK_ERASE = 0x99, |
133 | MS_CMD_BLOCK_READ = 0xaa, | 176 | MS_CMD_BLOCK_READ = 0xaa, |
134 | MS_CMD_CLEAR_BUF = 0xc3, | 177 | MS_CMD_CLEAR_BUF = 0xc3, |
135 | MS_CMD_FLASH_STOP = 0xcc, | 178 | MS_CMD_FLASH_STOP = 0xcc, |
136 | MSPRO_CMD_FORMAT = 0x10, | 179 | MS_CMD_LOAD_ID = 0x60, |
137 | MSPRO_CMD_SLEEP = 0x11, | 180 | MS_CMD_CMP_ICV = 0x7f, |
138 | MSPRO_CMD_READ_DATA = 0x20, | 181 | MSPRO_CMD_FORMAT = 0x10, |
139 | MSPRO_CMD_WRITE_DATA = 0x21, | 182 | MSPRO_CMD_SLEEP = 0x11, |
140 | MSPRO_CMD_READ_ATRB = 0x24, | 183 | MSPRO_CMD_WAKEUP = 0x12, |
141 | MSPRO_CMD_STOP = 0x25, | 184 | MSPRO_CMD_READ_DATA = 0x20, |
142 | MSPRO_CMD_ERASE = 0x26, | 185 | MSPRO_CMD_WRITE_DATA = 0x21, |
143 | MSPRO_CMD_SET_IBA = 0x46, | 186 | MSPRO_CMD_READ_ATRB = 0x24, |
144 | MSPRO_CMD_SET_IBD = 0x47 | 187 | MSPRO_CMD_STOP = 0x25, |
145 | /* | 188 | MSPRO_CMD_ERASE = 0x26, |
146 | MSPRO_CMD_RESET | 189 | MSPRO_CMD_READ_QUAD = 0x27, |
147 | MSPRO_CMD_WAKEUP | 190 | MSPRO_CMD_WRITE_QUAD = 0x28, |
148 | MSPRO_CMD_IN_IO_DATA | 191 | MSPRO_CMD_SET_IBD = 0x46, |
149 | MSPRO_CMD_OUT_IO_DATA | 192 | MSPRO_CMD_GET_IBD = 0x47, |
150 | MSPRO_CMD_READ_IO_ATRB | 193 | MSPRO_CMD_IN_IO_DATA = 0xb0, |
151 | MSPRO_CMD_IN_IO_FIFO | 194 | MSPRO_CMD_OUT_IO_DATA = 0xb1, |
152 | MSPRO_CMD_OUT_IO_FIFO | 195 | MSPRO_CMD_READ_IO_ATRB = 0xb2, |
153 | MSPRO_CMD_IN_IOM | 196 | MSPRO_CMD_IN_IO_FIFO = 0xb3, |
154 | MSPRO_CMD_OUT_IOM | 197 | MSPRO_CMD_OUT_IO_FIFO = 0xb4, |
155 | */ | 198 | MSPRO_CMD_IN_IOM = 0xb5, |
199 | MSPRO_CMD_OUT_IOM = 0xb6, | ||
156 | }; | 200 | }; |
157 | 201 | ||
158 | /*** Driver structures and functions ***/ | 202 | /*** Driver structures and functions ***/ |
@@ -165,7 +209,8 @@ enum memstick_param { MEMSTICK_POWER = 1, MEMSTICK_INTERFACE }; | |||
165 | #define MEMSTICK_POWER_ON 1 | 209 | #define MEMSTICK_POWER_ON 1 |
166 | 210 | ||
167 | #define MEMSTICK_SERIAL 0 | 211 | #define MEMSTICK_SERIAL 0 |
168 | #define MEMSTICK_PARALLEL 1 | 212 | #define MEMSTICK_PAR4 1 |
213 | #define MEMSTICK_PAR8 2 | ||
169 | 214 | ||
170 | struct memstick_host; | 215 | struct memstick_host; |
171 | struct memstick_driver; | 216 | struct memstick_driver; |
@@ -195,11 +240,7 @@ struct memstick_request { | |||
195 | unsigned char data_dir:1, | 240 | unsigned char data_dir:1, |
196 | need_card_int:1, | 241 | need_card_int:1, |
197 | get_int_reg:1, | 242 | get_int_reg:1, |
198 | io_type:2; | 243 | long_data:1; |
199 | #define MEMSTICK_IO_NONE 0 | ||
200 | #define MEMSTICK_IO_VAL 1 | ||
201 | #define MEMSTICK_IO_SG 2 | ||
202 | |||
203 | unsigned char int_reg; | 244 | unsigned char int_reg; |
204 | int error; | 245 | int error; |
205 | union { | 246 | union { |
@@ -231,8 +272,9 @@ struct memstick_host { | |||
231 | struct mutex lock; | 272 | struct mutex lock; |
232 | unsigned int id; | 273 | unsigned int id; |
233 | unsigned int caps; | 274 | unsigned int caps; |
234 | #define MEMSTICK_CAP_PARALLEL 1 | 275 | #define MEMSTICK_CAP_AUTO_GET_INT 1 |
235 | #define MEMSTICK_CAP_AUTO_GET_INT 2 | 276 | #define MEMSTICK_CAP_PAR4 2 |
277 | #define MEMSTICK_CAP_PAR8 4 | ||
236 | 278 | ||
237 | struct work_struct media_checker; | 279 | struct work_struct media_checker; |
238 | struct class_device cdev; | 280 | struct class_device cdev; |
@@ -270,6 +312,8 @@ int memstick_add_host(struct memstick_host *host); | |||
270 | void memstick_remove_host(struct memstick_host *host); | 312 | void memstick_remove_host(struct memstick_host *host); |
271 | void memstick_free_host(struct memstick_host *host); | 313 | void memstick_free_host(struct memstick_host *host); |
272 | void memstick_detect_change(struct memstick_host *host); | 314 | void memstick_detect_change(struct memstick_host *host); |
315 | void memstick_suspend_host(struct memstick_host *host); | ||
316 | void memstick_resume_host(struct memstick_host *host); | ||
273 | 317 | ||
274 | void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc, | 318 | void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc, |
275 | struct scatterlist *sg); | 319 | struct scatterlist *sg); |
diff --git a/include/linux/pci.h b/include/linux/pci.h index f3165e7ac431..38eff1947750 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -389,13 +389,13 @@ struct pci_driver { | |||
389 | #define to_pci_driver(drv) container_of(drv, struct pci_driver, driver) | 389 | #define to_pci_driver(drv) container_of(drv, struct pci_driver, driver) |
390 | 390 | ||
391 | /** | 391 | /** |
392 | * DECLARE_PCI_DEVICE_TABLE - macro used to describe a pci device table | 392 | * DEFINE_PCI_DEVICE_TABLE - macro used to describe a pci device table |
393 | * @_table: device table name | 393 | * @_table: device table name |
394 | * | 394 | * |
395 | * This macro is used to create a struct pci_device_id array (a device table) | 395 | * This macro is used to create a struct pci_device_id array (a device table) |
396 | * in a generic manner. | 396 | * in a generic manner. |
397 | */ | 397 | */ |
398 | #define DECLARE_PCI_DEVICE_TABLE(_table) \ | 398 | #define DEFINE_PCI_DEVICE_TABLE(_table) \ |
399 | const struct pci_device_id _table[] __devinitconst | 399 | const struct pci_device_id _table[] __devinitconst |
400 | 400 | ||
401 | /** | 401 | /** |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index effdb558a588..70eb3c803d47 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -2184,6 +2184,7 @@ | |||
2184 | #define PCI_DEVICE_ID_JMICRON_JMB366 0x2366 | 2184 | #define PCI_DEVICE_ID_JMICRON_JMB366 0x2366 |
2185 | #define PCI_DEVICE_ID_JMICRON_JMB368 0x2368 | 2185 | #define PCI_DEVICE_ID_JMICRON_JMB368 0x2368 |
2186 | #define PCI_DEVICE_ID_JMICRON_JMB38X_SD 0x2381 | 2186 | #define PCI_DEVICE_ID_JMICRON_JMB38X_SD 0x2381 |
2187 | #define PCI_DEVICE_ID_JMICRON_JMB38X_MS 0x2383 | ||
2187 | 2188 | ||
2188 | #define PCI_VENDOR_ID_KORENIX 0x1982 | 2189 | #define PCI_VENDOR_ID_KORENIX 0x1982 |
2189 | #define PCI_DEVICE_ID_KORENIX_JETCARDF0 0x1600 | 2190 | #define PCI_DEVICE_ID_KORENIX_JETCARDF0 0x1600 |
diff --git a/include/linux/tifm.h b/include/linux/tifm.h index da76ed85f595..848c0f392541 100644 --- a/include/linux/tifm.h +++ b/include/linux/tifm.h | |||
@@ -70,9 +70,9 @@ enum { | |||
70 | 70 | ||
71 | #define TIFM_FIFO_ENABLE 0x00000001 | 71 | #define TIFM_FIFO_ENABLE 0x00000001 |
72 | #define TIFM_FIFO_READY 0x00000001 | 72 | #define TIFM_FIFO_READY 0x00000001 |
73 | #define TIFM_FIFO_MORE 0x00000008 | ||
73 | #define TIFM_FIFO_INT_SETALL 0x0000ffff | 74 | #define TIFM_FIFO_INT_SETALL 0x0000ffff |
74 | #define TIFM_FIFO_INTMASK 0x00000005 | 75 | #define TIFM_FIFO_INTMASK 0x00000005 |
75 | #define TIFM_FIFO_SIZE 0x00000200 | ||
76 | 76 | ||
77 | #define TIFM_DMA_RESET 0x00000002 | 77 | #define TIFM_DMA_RESET 0x00000002 |
78 | #define TIFM_DMA_TX 0x00008000 | 78 | #define TIFM_DMA_TX 0x00008000 |
diff --git a/include/linux/time.h b/include/linux/time.h index 2091a19f1655..d32ef0ad4c0a 100644 --- a/include/linux/time.h +++ b/include/linux/time.h | |||
@@ -174,6 +174,10 @@ static inline void timespec_add_ns(struct timespec *a, u64 ns) | |||
174 | { | 174 | { |
175 | ns += a->tv_nsec; | 175 | ns += a->tv_nsec; |
176 | while(unlikely(ns >= NSEC_PER_SEC)) { | 176 | while(unlikely(ns >= NSEC_PER_SEC)) { |
177 | /* The following asm() prevents the compiler from | ||
178 | * optimising this loop into a modulo operation. */ | ||
179 | asm("" : "+r"(ns)); | ||
180 | |||
177 | ns -= NSEC_PER_SEC; | 181 | ns -= NSEC_PER_SEC; |
178 | a->tv_sec++; | 182 | a->tv_sec++; |
179 | } | 183 | } |
diff --git a/include/linux/timex.h b/include/linux/timex.h index c3f374786a43..8ea3e71ba7fa 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h | |||
@@ -232,14 +232,7 @@ static inline int ntp_synced(void) | |||
232 | #else | 232 | #else |
233 | #define NTP_INTERVAL_FREQ (HZ) | 233 | #define NTP_INTERVAL_FREQ (HZ) |
234 | #endif | 234 | #endif |
235 | 235 | #define NTP_INTERVAL_LENGTH (NSEC_PER_SEC/NTP_INTERVAL_FREQ) | |
236 | #define CLOCK_TICK_OVERFLOW (LATCH * HZ - CLOCK_TICK_RATE) | ||
237 | #define CLOCK_TICK_ADJUST (((s64)CLOCK_TICK_OVERFLOW * NSEC_PER_SEC) / \ | ||
238 | (s64)CLOCK_TICK_RATE) | ||
239 | |||
240 | /* Because using NSEC_PER_SEC would be too easy */ | ||
241 | #define NTP_INTERVAL_LENGTH ((((s64)TICK_USEC * NSEC_PER_USEC * USER_HZ) + \ | ||
242 | CLOCK_TICK_ADJUST) / NTP_INTERVAL_FREQ) | ||
243 | 236 | ||
244 | /* Returns how long ticks are at present, in ns / 2^(SHIFT_SCALE-10). */ | 237 | /* Returns how long ticks are at present, in ns / 2^(SHIFT_SCALE-10). */ |
245 | extern u64 current_tick_length(void); | 238 | extern u64 current_tick_length(void); |
diff --git a/include/linux/usb/Kbuild b/include/linux/usb/Kbuild index b8cba1dcb2c6..42e84fc315e3 100644 --- a/include/linux/usb/Kbuild +++ b/include/linux/usb/Kbuild | |||
@@ -3,5 +3,5 @@ header-y += cdc.h | |||
3 | header-y += ch9.h | 3 | header-y += ch9.h |
4 | header-y += gadgetfs.h | 4 | header-y += gadgetfs.h |
5 | header-y += midi.h | 5 | header-y += midi.h |
6 | unifdef-y += g_printer.h | 6 | header-y += g_printer.h |
7 | 7 | ||
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index aa3047ff00d1..f3295296b435 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h | |||
@@ -15,8 +15,6 @@ | |||
15 | #ifndef __LINUX_USB_GADGET_H | 15 | #ifndef __LINUX_USB_GADGET_H |
16 | #define __LINUX_USB_GADGET_H | 16 | #define __LINUX_USB_GADGET_H |
17 | 17 | ||
18 | #ifdef __KERNEL__ | ||
19 | |||
20 | struct usb_ep; | 18 | struct usb_ep; |
21 | 19 | ||
22 | /** | 20 | /** |
@@ -848,6 +846,4 @@ extern struct usb_ep *usb_ep_autoconfig(struct usb_gadget *, | |||
848 | 846 | ||
849 | extern void usb_ep_autoconfig_reset(struct usb_gadget *) __devinit; | 847 | extern void usb_ep_autoconfig_reset(struct usb_gadget *) __devinit; |
850 | 848 | ||
851 | #endif /* __KERNEL__ */ | ||
852 | |||
853 | #endif /* __LINUX_USB_GADGET_H */ | 849 | #endif /* __LINUX_USB_GADGET_H */ |
diff --git a/init/Kconfig b/init/Kconfig index 074ac97f55e3..a97924bc5b8d 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -865,38 +865,10 @@ source "block/Kconfig" | |||
865 | config PREEMPT_NOTIFIERS | 865 | config PREEMPT_NOTIFIERS |
866 | bool | 866 | bool |
867 | 867 | ||
868 | choice | ||
869 | prompt "RCU implementation type:" | ||
870 | default CLASSIC_RCU | ||
871 | help | ||
872 | This allows you to choose either the classic RCU implementation | ||
873 | that is designed for best read-side performance on non-realtime | ||
874 | systems, or the preemptible RCU implementation for best latency | ||
875 | on realtime systems. Note that some kernel preemption modes | ||
876 | will restrict your choice. | ||
877 | |||
878 | Select the default if you are unsure. | ||
879 | |||
880 | config CLASSIC_RCU | 868 | config CLASSIC_RCU |
881 | bool "Classic RCU" | 869 | def_bool !PREEMPT_RCU |
882 | help | 870 | help |
883 | This option selects the classic RCU implementation that is | 871 | This option selects the classic RCU implementation that is |
884 | designed for best read-side performance on non-realtime | 872 | designed for best read-side performance on non-realtime |
885 | systems. | 873 | systems. Classic RCU is the default. Note that the |
886 | 874 | PREEMPT_RCU symbol is used to select/deselect this option. | |
887 | Say Y if you are unsure. | ||
888 | |||
889 | config PREEMPT_RCU | ||
890 | bool "Preemptible RCU" | ||
891 | depends on PREEMPT | ||
892 | help | ||
893 | This option reduces the latency of the kernel by making certain | ||
894 | RCU sections preemptible. Normally RCU code is non-preemptible, if | ||
895 | this option is selected then read-only RCU sections become | ||
896 | preemptible. This helps latency, but may expose bugs due to | ||
897 | now-naive assumptions about each RCU read-side critical section | ||
898 | remaining on a given CPU through its execution. | ||
899 | |||
900 | Say N if you are unsure. | ||
901 | |||
902 | endchoice | ||
@@ -271,9 +271,10 @@ static struct mempolicy *shm_get_policy(struct vm_area_struct *vma, | |||
271 | 271 | ||
272 | if (sfd->vm_ops->get_policy) | 272 | if (sfd->vm_ops->get_policy) |
273 | pol = sfd->vm_ops->get_policy(vma, addr); | 273 | pol = sfd->vm_ops->get_policy(vma, addr); |
274 | else if (vma->vm_policy) | 274 | else if (vma->vm_policy) { |
275 | pol = vma->vm_policy; | 275 | pol = vma->vm_policy; |
276 | else | 276 | mpol_get(pol); /* get_vma_policy() expects this */ |
277 | } else | ||
277 | pol = current->mempolicy; | 278 | pol = current->mempolicy; |
278 | return pol; | 279 | return pol; |
279 | } | 280 | } |
diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt index 0669b70fa6a3..9fdba03dc1fc 100644 --- a/kernel/Kconfig.preempt +++ b/kernel/Kconfig.preempt | |||
@@ -52,8 +52,23 @@ config PREEMPT | |||
52 | 52 | ||
53 | endchoice | 53 | endchoice |
54 | 54 | ||
55 | config PREEMPT_RCU | ||
56 | bool "Preemptible RCU" | ||
57 | depends on PREEMPT | ||
58 | default n | ||
59 | help | ||
60 | This option reduces the latency of the kernel by making certain | ||
61 | RCU sections preemptible. Normally RCU code is non-preemptible, if | ||
62 | this option is selected then read-only RCU sections become | ||
63 | preemptible. This helps latency, but may expose bugs due to | ||
64 | now-naive assumptions about each RCU read-side critical section | ||
65 | remaining on a given CPU through its execution. | ||
66 | |||
67 | Say N if you are unsure. | ||
68 | |||
55 | config RCU_TRACE | 69 | config RCU_TRACE |
56 | bool "Enable tracing for RCU - currently stats in debugfs" | 70 | bool "Enable tracing for RCU - currently stats in debugfs" |
71 | depends on PREEMPT_RCU | ||
57 | select DEBUG_FS | 72 | select DEBUG_FS |
58 | default y | 73 | default y |
59 | help | 74 | help |
diff --git a/kernel/exit.c b/kernel/exit.c index cd20bf07e9e3..53872bf993fa 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -1378,7 +1378,7 @@ unlock_sig: | |||
1378 | if (!retval && infop) | 1378 | if (!retval && infop) |
1379 | retval = put_user(0, &infop->si_errno); | 1379 | retval = put_user(0, &infop->si_errno); |
1380 | if (!retval && infop) | 1380 | if (!retval && infop) |
1381 | retval = put_user(why, &infop->si_code); | 1381 | retval = put_user((short)why, &infop->si_code); |
1382 | if (!retval && infop) | 1382 | if (!retval && infop) |
1383 | retval = put_user(exit_code, &infop->si_status); | 1383 | retval = put_user(exit_code, &infop->si_status); |
1384 | if (!retval && infop) | 1384 | if (!retval && infop) |
diff --git a/kernel/module.c b/kernel/module.c index be4807fb90e4..5d437bffd8dc 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -2178,10 +2178,20 @@ sys_init_module(void __user *umod, | |||
2178 | wake_up(&module_wq); | 2178 | wake_up(&module_wq); |
2179 | return ret; | 2179 | return ret; |
2180 | } | 2180 | } |
2181 | if (ret > 0) { | ||
2182 | printk(KERN_WARNING "%s: '%s'->init suspiciously returned %d, " | ||
2183 | "it should follow 0/-E convention\n" | ||
2184 | KERN_WARNING "%s: loading module anyway...\n", | ||
2185 | __func__, mod->name, ret, | ||
2186 | __func__); | ||
2187 | dump_stack(); | ||
2188 | } | ||
2181 | 2189 | ||
2182 | /* Now it's a first class citizen! */ | 2190 | /* Now it's a first class citizen! Wake up anyone waiting for it. */ |
2183 | mutex_lock(&module_mutex); | ||
2184 | mod->state = MODULE_STATE_LIVE; | 2191 | mod->state = MODULE_STATE_LIVE; |
2192 | wake_up(&module_wq); | ||
2193 | |||
2194 | mutex_lock(&module_mutex); | ||
2185 | /* Drop initial reference. */ | 2195 | /* Drop initial reference. */ |
2186 | module_put(mod); | 2196 | module_put(mod); |
2187 | unwind_remove_table(mod->unwind_info, 1); | 2197 | unwind_remove_table(mod->unwind_info, 1); |
@@ -2190,7 +2200,6 @@ sys_init_module(void __user *umod, | |||
2190 | mod->init_size = 0; | 2200 | mod->init_size = 0; |
2191 | mod->init_text_size = 0; | 2201 | mod->init_text_size = 0; |
2192 | mutex_unlock(&module_mutex); | 2202 | mutex_unlock(&module_mutex); |
2193 | wake_up(&module_wq); | ||
2194 | 2203 | ||
2195 | return 0; | 2204 | return 0; |
2196 | } | 2205 | } |
diff --git a/kernel/sched.c b/kernel/sched.c index 52b98675acb2..1cb53fb1fe3d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -5881,7 +5881,8 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
5881 | spin_unlock_irq(&rq->lock); | 5881 | spin_unlock_irq(&rq->lock); |
5882 | break; | 5882 | break; |
5883 | 5883 | ||
5884 | case CPU_DOWN_PREPARE: | 5884 | case CPU_DYING: |
5885 | case CPU_DYING_FROZEN: | ||
5885 | /* Update our root-domain */ | 5886 | /* Update our root-domain */ |
5886 | rq = cpu_rq(cpu); | 5887 | rq = cpu_rq(cpu); |
5887 | spin_lock_irqsave(&rq->lock, flags); | 5888 | spin_lock_irqsave(&rq->lock, flags); |
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index c88b5910e7ab..5fd9b9469770 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
@@ -42,12 +42,13 @@ long time_esterror = NTP_PHASE_LIMIT; /* estimated error (us) */ | |||
42 | long time_freq; /* frequency offset (scaled ppm)*/ | 42 | long time_freq; /* frequency offset (scaled ppm)*/ |
43 | static long time_reftime; /* time at last adjustment (s) */ | 43 | static long time_reftime; /* time at last adjustment (s) */ |
44 | long time_adjust; | 44 | long time_adjust; |
45 | static long ntp_tick_adj; | ||
45 | 46 | ||
46 | static void ntp_update_frequency(void) | 47 | static void ntp_update_frequency(void) |
47 | { | 48 | { |
48 | u64 second_length = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) | 49 | u64 second_length = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) |
49 | << TICK_LENGTH_SHIFT; | 50 | << TICK_LENGTH_SHIFT; |
50 | second_length += (s64)CLOCK_TICK_ADJUST << TICK_LENGTH_SHIFT; | 51 | second_length += (s64)ntp_tick_adj << TICK_LENGTH_SHIFT; |
51 | second_length += (s64)time_freq << (TICK_LENGTH_SHIFT - SHIFT_NSEC); | 52 | second_length += (s64)time_freq << (TICK_LENGTH_SHIFT - SHIFT_NSEC); |
52 | 53 | ||
53 | tick_length_base = second_length; | 54 | tick_length_base = second_length; |
@@ -342,14 +343,16 @@ int do_adjtimex(struct timex *txc) | |||
342 | freq_adj = shift_right(freq_adj, time_constant * 2 + | 343 | freq_adj = shift_right(freq_adj, time_constant * 2 + |
343 | (SHIFT_PLL + 2) * 2 - SHIFT_NSEC); | 344 | (SHIFT_PLL + 2) * 2 - SHIFT_NSEC); |
344 | if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) { | 345 | if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) { |
346 | u64 utemp64; | ||
345 | temp64 = time_offset << (SHIFT_NSEC - SHIFT_FLL); | 347 | temp64 = time_offset << (SHIFT_NSEC - SHIFT_FLL); |
346 | if (time_offset < 0) { | 348 | if (time_offset < 0) { |
347 | temp64 = -temp64; | 349 | utemp64 = -temp64; |
348 | do_div(temp64, mtemp); | 350 | do_div(utemp64, mtemp); |
349 | freq_adj -= temp64; | 351 | freq_adj -= utemp64; |
350 | } else { | 352 | } else { |
351 | do_div(temp64, mtemp); | 353 | utemp64 = temp64; |
352 | freq_adj += temp64; | 354 | do_div(utemp64, mtemp); |
355 | freq_adj += utemp64; | ||
353 | } | 356 | } |
354 | } | 357 | } |
355 | freq_adj += time_freq; | 358 | freq_adj += time_freq; |
@@ -400,3 +403,11 @@ leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0) | |||
400 | notify_cmos_timer(); | 403 | notify_cmos_timer(); |
401 | return(result); | 404 | return(result); |
402 | } | 405 | } |
406 | |||
407 | static int __init ntp_tick_adj_setup(char *str) | ||
408 | { | ||
409 | ntp_tick_adj = simple_strtol(str, NULL, 0); | ||
410 | return 1; | ||
411 | } | ||
412 | |||
413 | __setup("ntp_tick_adj=", ntp_tick_adj_setup); | ||
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 2968298f8f36..686da821d376 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -640,7 +640,7 @@ void tick_cancel_sched_timer(int cpu) | |||
640 | 640 | ||
641 | if (ts->sched_timer.base) | 641 | if (ts->sched_timer.base) |
642 | hrtimer_cancel(&ts->sched_timer); | 642 | hrtimer_cancel(&ts->sched_timer); |
643 | ts->tick_stopped = 0; | 643 | |
644 | ts->nohz_mode = NOHZ_MODE_INACTIVE; | 644 | ts->nohz_mode = NOHZ_MODE_INACTIVE; |
645 | } | 645 | } |
646 | #endif /* HIGH_RES_TIMERS */ | 646 | #endif /* HIGH_RES_TIMERS */ |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 1af9fb050fe2..671af612b768 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -187,8 +187,7 @@ static void change_clocksource(void) | |||
187 | 187 | ||
188 | clock->error = 0; | 188 | clock->error = 0; |
189 | clock->xtime_nsec = 0; | 189 | clock->xtime_nsec = 0; |
190 | clocksource_calculate_interval(clock, | 190 | clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH); |
191 | (unsigned long)(current_tick_length()>>TICK_LENGTH_SHIFT)); | ||
192 | 191 | ||
193 | tick_clock_notify(); | 192 | tick_clock_notify(); |
194 | 193 | ||
@@ -245,8 +244,7 @@ void __init timekeeping_init(void) | |||
245 | ntp_clear(); | 244 | ntp_clear(); |
246 | 245 | ||
247 | clock = clocksource_get_next(); | 246 | clock = clocksource_get_next(); |
248 | clocksource_calculate_interval(clock, | 247 | clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH); |
249 | (unsigned long)(current_tick_length()>>TICK_LENGTH_SHIFT)); | ||
250 | clock->cycle_last = clocksource_read(clock); | 248 | clock->cycle_last = clocksource_read(clock); |
251 | 249 | ||
252 | xtime.tv_sec = sec; | 250 | xtime.tv_sec = sec; |
diff --git a/mm/filemap.c b/mm/filemap.c index 5c74b68935ac..df343d1e6345 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/backing-dev.h> | 28 | #include <linux/backing-dev.h> |
29 | #include <linux/pagevec.h> | 29 | #include <linux/pagevec.h> |
30 | #include <linux/blkdev.h> | 30 | #include <linux/blkdev.h> |
31 | #include <linux/backing-dev.h> | ||
32 | #include <linux/security.h> | 31 | #include <linux/security.h> |
33 | #include <linux/syscalls.h> | 32 | #include <linux/syscalls.h> |
34 | #include <linux/cpuset.h> | 33 | #include <linux/cpuset.h> |
@@ -1743,21 +1742,27 @@ size_t iov_iter_copy_from_user(struct page *page, | |||
1743 | } | 1742 | } |
1744 | EXPORT_SYMBOL(iov_iter_copy_from_user); | 1743 | EXPORT_SYMBOL(iov_iter_copy_from_user); |
1745 | 1744 | ||
1746 | static void __iov_iter_advance_iov(struct iov_iter *i, size_t bytes) | 1745 | void iov_iter_advance(struct iov_iter *i, size_t bytes) |
1747 | { | 1746 | { |
1747 | BUG_ON(i->count < bytes); | ||
1748 | |||
1748 | if (likely(i->nr_segs == 1)) { | 1749 | if (likely(i->nr_segs == 1)) { |
1749 | i->iov_offset += bytes; | 1750 | i->iov_offset += bytes; |
1751 | i->count -= bytes; | ||
1750 | } else { | 1752 | } else { |
1751 | const struct iovec *iov = i->iov; | 1753 | const struct iovec *iov = i->iov; |
1752 | size_t base = i->iov_offset; | 1754 | size_t base = i->iov_offset; |
1753 | 1755 | ||
1754 | /* | 1756 | /* |
1755 | * The !iov->iov_len check ensures we skip over unlikely | 1757 | * The !iov->iov_len check ensures we skip over unlikely |
1756 | * zero-length segments. | 1758 | * zero-length segments (without overruning the iovec). |
1757 | */ | 1759 | */ |
1758 | while (bytes || !iov->iov_len) { | 1760 | while (bytes || unlikely(!iov->iov_len && i->count)) { |
1759 | int copy = min(bytes, iov->iov_len - base); | 1761 | int copy; |
1760 | 1762 | ||
1763 | copy = min(bytes, iov->iov_len - base); | ||
1764 | BUG_ON(!i->count || i->count < copy); | ||
1765 | i->count -= copy; | ||
1761 | bytes -= copy; | 1766 | bytes -= copy; |
1762 | base += copy; | 1767 | base += copy; |
1763 | if (iov->iov_len == base) { | 1768 | if (iov->iov_len == base) { |
@@ -1769,14 +1774,6 @@ static void __iov_iter_advance_iov(struct iov_iter *i, size_t bytes) | |||
1769 | i->iov_offset = base; | 1774 | i->iov_offset = base; |
1770 | } | 1775 | } |
1771 | } | 1776 | } |
1772 | |||
1773 | void iov_iter_advance(struct iov_iter *i, size_t bytes) | ||
1774 | { | ||
1775 | BUG_ON(i->count < bytes); | ||
1776 | |||
1777 | __iov_iter_advance_iov(i, bytes); | ||
1778 | i->count -= bytes; | ||
1779 | } | ||
1780 | EXPORT_SYMBOL(iov_iter_advance); | 1777 | EXPORT_SYMBOL(iov_iter_advance); |
1781 | 1778 | ||
1782 | /* | 1779 | /* |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index dcacc811e70e..74c1b6b0b37b 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -286,6 +286,12 @@ static struct page *alloc_buddy_huge_page(struct vm_area_struct *vma, | |||
286 | 286 | ||
287 | spin_lock(&hugetlb_lock); | 287 | spin_lock(&hugetlb_lock); |
288 | if (page) { | 288 | if (page) { |
289 | /* | ||
290 | * This page is now managed by the hugetlb allocator and has | ||
291 | * no users -- drop the buddy allocator's reference. | ||
292 | */ | ||
293 | put_page_testzero(page); | ||
294 | VM_BUG_ON(page_count(page)); | ||
289 | nid = page_to_nid(page); | 295 | nid = page_to_nid(page); |
290 | set_compound_page_dtor(page, free_huge_page); | 296 | set_compound_page_dtor(page, free_huge_page); |
291 | /* | 297 | /* |
@@ -369,13 +375,14 @@ free: | |||
369 | enqueue_huge_page(page); | 375 | enqueue_huge_page(page); |
370 | else { | 376 | else { |
371 | /* | 377 | /* |
372 | * Decrement the refcount and free the page using its | 378 | * The page has a reference count of zero already, so |
373 | * destructor. This must be done with hugetlb_lock | 379 | * call free_huge_page directly instead of using |
380 | * put_page. This must be done with hugetlb_lock | ||
374 | * unlocked which is safe because free_huge_page takes | 381 | * unlocked which is safe because free_huge_page takes |
375 | * hugetlb_lock before deciding how to free the page. | 382 | * hugetlb_lock before deciding how to free the page. |
376 | */ | 383 | */ |
377 | spin_unlock(&hugetlb_lock); | 384 | spin_unlock(&hugetlb_lock); |
378 | put_page(page); | 385 | free_huge_page(page); |
379 | spin_lock(&hugetlb_lock); | 386 | spin_lock(&hugetlb_lock); |
380 | } | 387 | } |
381 | } | 388 | } |
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 6c7ba1a63d23..3c3601121509 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -1296,7 +1296,9 @@ struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr, | |||
1296 | unsigned nid; | 1296 | unsigned nid; |
1297 | 1297 | ||
1298 | nid = interleave_nid(pol, vma, addr, HPAGE_SHIFT); | 1298 | nid = interleave_nid(pol, vma, addr, HPAGE_SHIFT); |
1299 | __mpol_free(pol); /* finished with pol */ | 1299 | if (unlikely(pol != &default_policy && |
1300 | pol != current->mempolicy)) | ||
1301 | __mpol_free(pol); /* finished with pol */ | ||
1300 | return NODE_DATA(nid)->node_zonelists + gfp_zone(gfp_flags); | 1302 | return NODE_DATA(nid)->node_zonelists + gfp_zone(gfp_flags); |
1301 | } | 1303 | } |
1302 | 1304 | ||
@@ -1360,6 +1362,9 @@ alloc_page_vma(gfp_t gfp, struct vm_area_struct *vma, unsigned long addr) | |||
1360 | unsigned nid; | 1362 | unsigned nid; |
1361 | 1363 | ||
1362 | nid = interleave_nid(pol, vma, addr, PAGE_SHIFT); | 1364 | nid = interleave_nid(pol, vma, addr, PAGE_SHIFT); |
1365 | if (unlikely(pol != &default_policy && | ||
1366 | pol != current->mempolicy)) | ||
1367 | __mpol_free(pol); /* finished with pol */ | ||
1363 | return alloc_page_interleave(gfp, 0, nid); | 1368 | return alloc_page_interleave(gfp, 0, nid); |
1364 | } | 1369 | } |
1365 | zl = zonelist_policy(gfp, pol); | 1370 | zl = zonelist_policy(gfp, pol); |
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 675672f313be..f48838a078cb 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -1762,6 +1762,8 @@ static int check_hw_params_convention(struct snd_usb_substream *subs) | |||
1762 | 1762 | ||
1763 | channels = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL); | 1763 | channels = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL); |
1764 | rates = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL); | 1764 | rates = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL); |
1765 | if (!channels || !rates) | ||
1766 | goto __out; | ||
1765 | 1767 | ||
1766 | list_for_each(p, &subs->fmt_list) { | 1768 | list_for_each(p, &subs->fmt_list) { |
1767 | struct audioformat *f; | 1769 | struct audioformat *f; |