diff --git a/[refs] b/[refs] index f6d85606b1a5..f35106332fcb 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5a90fa71f6d45054c78b2bd6dbc4feba1638e1d2 +refs/heads/master: 505d7b193181be029f4f9aea59e6bdbfdd1e9e76 diff --git a/trunk/Documentation/pcmcia/driver-changes.txt b/trunk/Documentation/pcmcia/driver-changes.txt index 403e7b4dcdd4..59ccc63838c1 100644 --- a/trunk/Documentation/pcmcia/driver-changes.txt +++ b/trunk/Documentation/pcmcia/driver-changes.txt @@ -56,12 +56,3 @@ This file details changes in 2.6 which affect PCMCIA card driver authors: memory regions in-use. The name argument should be a pointer to your driver name. Eg, for pcnet_cs, name should point to the string "pcnet_cs". - -* CardServices is gone - CardServices() in 2.4 is just a big switch statement to call various - services. In 2.6, all of those entry points are exported and called - directly (except for pcmcia_report_error(), just use cs_error() instead). - -* struct pcmcia_driver - You need to use struct pcmcia_driver and pcmcia_{un,}register_driver - instead of {un,}register_pccard_driver diff --git a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt index a18ecb92b356..104a994b8289 100644 --- a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt @@ -636,16 +636,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 3stack-digout 3-jack in back, a HP out and a SPDIF out 5stack 5-jack in back, 2-jack in front 5stack-digout 5-jack in back, 2-jack in front, a SPDIF out - 6stack 6-jack in back, 2-jack in front - 6stack-digout 6-jack with a SPDIF out w810 3-jack z71v 3-jack (HP shared SPDIF) asus 3-jack uniwill 3-jack F1734 2-jack - test for testing/debugging purpose, almost all controls can be - adjusted. Appearing only when compiled with - $CONFIG_SND_DEBUG=y CMI9880 minimal 3-jack in back @@ -1059,13 +1054,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. The power-management is supported. - Module snd-pxa2xx-ac97 (on arm only) - ------------------------------------ - - Module for AC97 driver for the Intel PXA2xx chip - - For ARM architecture only. - Module snd-rme32 ---------------- @@ -1185,13 +1173,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module supports up to 8 cards. - Module snd-sun-dbri (on sparc only) - ----------------------------------- - - Module for DBRI sound chips found on Sparcs. - - Module supports up to 8 cards. - Module snd-wavefront -------------------- @@ -1390,7 +1371,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module snd-vxpocket ------------------- - Module for Digigram VX-Pocket VX2 and 440 PCMCIA cards. + Module for Digigram VX-Pocket VX2 PCMCIA card. ibl - Capture IBL size. (default = 0, minimum size) @@ -1410,6 +1391,29 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Note: the driver is build only when CONFIG_ISA is set. + Module snd-vxp440 + ----------------- + + Module for Digigram VX-Pocket 440 PCMCIA card. + + ibl - Capture IBL size. (default = 0, minimum size) + + Module supports up to 8 cards. The module is compiled only when + PCMCIA is supported on kernel. + + To activate the driver via the card manager, you'll need to set + up /etc/pcmcia/vxp440.conf. See the sound/pcmcia/vx/vxp440.c. + + When the driver is compiled as a module and the hotplug firmware + is supported, the firmware data is loaded via hotplug automatically. + Install the necessary firmware files in alsa-firmware package. + When no hotplug fw loader is available, you need to load the + firmware via vxloader utility in alsa-tools package. + + About capture IBL, see the description of snd-vx222 module. + + Note: the driver is build only when CONFIG_ISA is set. + Module snd-ymfpci ----------------- diff --git a/trunk/Documentation/x86_64/boot-options.txt b/trunk/Documentation/x86_64/boot-options.txt index 476c0c22fbb7..b9e6be00cadf 100644 --- a/trunk/Documentation/x86_64/boot-options.txt +++ b/trunk/Documentation/x86_64/boot-options.txt @@ -47,7 +47,7 @@ Timing notsc Don't use the CPU time stamp counter to read the wall time. This can be used to work around timing problems on multiprocessor systems - with not properly synchronized CPUs. + with not properly synchronized CPUs. Only useful with a SMP kernel report_lost_ticks Report when timer interrupts are lost because some code turned off @@ -74,9 +74,6 @@ Idle loop event. This will make the CPUs eat a lot more power, but may be useful to get slightly better performance in multiprocessor benchmarks. It also makes some profiling using performance counters more accurate. - Please note that on systems with MONITOR/MWAIT support (like Intel EM64T - CPUs) this option has no performance advantage over the normal idle loop. - It may also interact badly with hyperthreading. Rebooting @@ -181,5 +178,6 @@ Debugging Misc noreplacement Don't replace instructions with more appropiate ones - for the CPU. This may be useful on asymmetric MP systems - where some CPU have less capabilities than the others. + for the CPU. This may be useful on asymmetric MP systems + where some CPU have less capabilities than the others. + diff --git a/trunk/Makefile b/trunk/Makefile index 717b9b9192d5..cf34a6b5c6eb 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 13 -EXTRAVERSION =-rc4 +EXTRAVERSION =-rc3 NAME=Woozy Numbat # *DOCUMENTATION* diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index 295e0a8379cf..b2085735a2ba 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -176,6 +176,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void) cpu_set(cpu, mm->cpu_vm_mask); cpu_switch_mm(mm->pgd, mm); enter_lazy_tlb(mm, current); + local_flush_tlb_all(); cpu_init(); diff --git a/trunk/arch/i386/kernel/cpu/intel_cacheinfo.c b/trunk/arch/i386/kernel/cpu/intel_cacheinfo.c index 6c55b50cf048..1d768b263269 100644 --- a/trunk/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/trunk/arch/i386/kernel/cpu/intel_cacheinfo.c @@ -128,7 +128,7 @@ static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_le cpuid_count(4, index, &eax, &ebx, &ecx, &edx); cache_eax.full = eax; if (cache_eax.split.type == CACHE_TYPE_NULL) - return -EIO; /* better error ? */ + return -1; this_leaf->eax.full = eax; this_leaf->ebx.full = ebx; @@ -334,7 +334,6 @@ static int __devinit detect_cache_attributes(unsigned int cpu) struct _cpuid4_info *this_leaf; unsigned long j; int retval; - cpumask_t oldmask; if (num_cache_leaves == 0) return -ENOENT; @@ -346,26 +345,19 @@ static int __devinit detect_cache_attributes(unsigned int cpu) memset(cpuid4_info[cpu], 0, sizeof(struct _cpuid4_info) * num_cache_leaves); - oldmask = current->cpus_allowed; - retval = set_cpus_allowed(current, cpumask_of_cpu(cpu)); - if (retval) - goto out; - /* Do cpuid and store the results */ - retval = 0; for (j = 0; j < num_cache_leaves; j++) { this_leaf = CPUID4_INFO_IDX(cpu, j); retval = cpuid4_cache_lookup(j, this_leaf); if (unlikely(retval < 0)) - break; + goto err_out; cache_shared_cpu_map_setup(cpu, j); } - set_cpus_allowed(current, oldmask); + return 0; -out: - if (retval) - free_cache_attributes(cpu); - return retval; +err_out: + free_cache_attributes(cpu); + return -ENOMEM; } #ifdef CONFIG_SYSFS diff --git a/trunk/arch/i386/kernel/numaq.c b/trunk/arch/i386/kernel/numaq.c index 5f5b075f860a..e51edf0a6564 100644 --- a/trunk/arch/i386/kernel/numaq.c +++ b/trunk/arch/i386/kernel/numaq.c @@ -31,7 +31,6 @@ #include #include #include -#include #define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT)) @@ -78,11 +77,3 @@ int __init get_memcfg_numaq(void) smp_dump_qct(); return 1; } - -static int __init numaq_dsc_disable(void) -{ - printk(KERN_DEBUG "NUMAQ: disabling TSC\n"); - tsc_disable = 1; - return 0; -} -core_initcall(numaq_dsc_disable); diff --git a/trunk/arch/i386/pci/irq.c b/trunk/arch/i386/pci/irq.c index d291fb7f1357..766b104ac1a1 100644 --- a/trunk/arch/i386/pci/irq.c +++ b/trunk/arch/i386/pci/irq.c @@ -550,13 +550,6 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route static __init int via_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) { /* FIXME: We should move some of the quirk fixup stuff here */ - - if (router->device == PCI_DEVICE_ID_VIA_82C686 && - device == PCI_DEVICE_ID_VIA_82C586_0) { - /* Asus k7m bios wrongly reports 82C686A as 586-compatible */ - device = PCI_DEVICE_ID_VIA_82C686; - } - switch(device) { case PCI_DEVICE_ID_VIA_82C586_0: diff --git a/trunk/arch/um/drivers/Makefile b/trunk/arch/um/drivers/Makefile index de17d4c6e02d..d6c31a95b887 100644 --- a/trunk/arch/um/drivers/Makefile +++ b/trunk/arch/um/drivers/Makefile @@ -19,8 +19,6 @@ harddog-objs := harddog_kern.o harddog_user.o LDFLAGS_pcap.o := -r $(shell $(CC) $(CFLAGS) -print-file-name=libpcap.a) -targets := pcap_kern.o pcap_user.o - $(obj)/pcap.o: $(obj)/pcap_kern.o $(obj)/pcap_user.o $(LD) -r -dp -o $@ $^ $(LDFLAGS) $(LDFLAGS_pcap.o) #XXX: The call below does not work because the flags are added before the @@ -28,7 +26,7 @@ $(obj)/pcap.o: $(obj)/pcap_kern.o $(obj)/pcap_user.o #$(call if_changed,ld) # When the above is fixed, don't forget to add this too! -#targets += $(obj)/pcap.o +#targets := $(obj)/pcap.o obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o obj-$(CONFIG_SSL) += ssl.o diff --git a/trunk/arch/um/drivers/mconsole_kern.c b/trunk/arch/um/drivers/mconsole_kern.c index c190c2414197..404de41a4f67 100644 --- a/trunk/arch/um/drivers/mconsole_kern.c +++ b/trunk/arch/um/drivers/mconsole_kern.c @@ -557,7 +557,7 @@ static int create_proc_mconsole(void) ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL); if(ent == NULL){ - printk(KERN_INFO "create_proc_mconsole : create_proc_entry failed\n"); + printk("create_proc_mconsole : create_proc_entry failed\n"); return(0); } diff --git a/trunk/arch/um/kernel/exitcode.c b/trunk/arch/um/kernel/exitcode.c index d21ebad666b4..0ea87f24b36f 100644 --- a/trunk/arch/um/kernel/exitcode.c +++ b/trunk/arch/um/kernel/exitcode.c @@ -48,7 +48,7 @@ static int make_proc_exitcode(void) ent = create_proc_entry("exitcode", 0600, &proc_root); if(ent == NULL){ - printk(KERN_WARNING "make_proc_exitcode : Failed to register " + printk("make_proc_exitcode : Failed to register " "/proc/exitcode\n"); return(0); } diff --git a/trunk/arch/um/kernel/process.c b/trunk/arch/um/kernel/process.c index 67acd92c5322..8b01a5584e80 100644 --- a/trunk/arch/um/kernel/process.c +++ b/trunk/arch/um/kernel/process.c @@ -131,7 +131,7 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack, return(arg.pid); } -static int ptrace_child(void *arg) +static int ptrace_child(void) { int ret; int pid = os_getpid(), ppid = getppid(); @@ -160,20 +160,16 @@ static int ptrace_child(void *arg) _exit(ret); } -static int start_ptraced_child(void **stack_out) +static int start_ptraced_child(void) { - void *stack; - unsigned long sp; int pid, n, status; - stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if(stack == MAP_FAILED) - panic("check_ptrace : mmap failed, errno = %d", errno); - sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); - pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); + pid = fork(); + if(pid == 0) + ptrace_child(); + if(pid < 0) - panic("check_ptrace : clone failed, errno = %d", errno); + panic("check_ptrace : fork failed, errno = %d", errno); CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); if(n < 0) panic("check_ptrace : wait failed, errno = %d", errno); @@ -181,7 +177,6 @@ static int start_ptraced_child(void **stack_out) panic("check_ptrace : expected SIGSTOP, got status = %d", status); - *stack_out = stack; return(pid); } @@ -189,12 +184,12 @@ static int start_ptraced_child(void **stack_out) * just avoid using sysemu, not panic, but only if SYSEMU features are broken. * So only for SYSEMU features we test mustpanic, while normal host features * must work anyway!*/ -static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) +static int stop_ptraced_child(int pid, int exitcode, int mustexit) { int status, n, ret = 0; if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) - panic("check_ptrace : ptrace failed, errno = %d", errno); + panic("stop_ptraced_child : ptrace failed, errno = %d", errno); CATCH_EINTR(n = waitpid(pid, &status, 0)); if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { int exit_with = WEXITSTATUS(status); @@ -205,15 +200,13 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) printk("check_ptrace : child exited with exitcode %d, while " "expecting %d; status 0x%x", exit_with, exitcode, status); - if (mustpanic) + if (mustexit) panic("\n"); else printk("\n"); ret = -1; } - if(munmap(stack, PAGE_SIZE) < 0) - panic("check_ptrace : munmap failed, errno = %d", errno); return ret; } @@ -249,12 +242,11 @@ __uml_setup("nosysemu", nosysemu_cmd_param, static void __init check_sysemu(void) { - void *stack; int pid, syscall, n, status, count=0; printk("Checking syscall emulation patch for ptrace..."); sysemu_supported = 0; - pid = start_ptraced_child(&stack); + pid = start_ptraced_child(); if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) goto fail; @@ -272,7 +264,7 @@ static void __init check_sysemu(void) panic("check_sysemu : failed to modify system " "call return, errno = %d", errno); - if (stop_ptraced_child(pid, stack, 0, 0) < 0) + if (stop_ptraced_child(pid, 0, 0) < 0) goto fail_stopped; sysemu_supported = 1; @@ -280,7 +272,7 @@ static void __init check_sysemu(void) set_using_sysemu(!force_sysemu_disabled); printk("Checking advanced syscall emulation patch for ptrace..."); - pid = start_ptraced_child(&stack); + pid = start_ptraced_child(); while(1){ count++; if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) @@ -305,7 +297,7 @@ static void __init check_sysemu(void) break; } } - if (stop_ptraced_child(pid, stack, 0, 0) < 0) + if (stop_ptraced_child(pid, 0, 0) < 0) goto fail_stopped; sysemu_supported = 2; @@ -316,18 +308,17 @@ static void __init check_sysemu(void) return; fail: - stop_ptraced_child(pid, stack, 1, 0); + stop_ptraced_child(pid, 1, 0); fail_stopped: printk("missing\n"); } void __init check_ptrace(void) { - void *stack; int pid, syscall, n, status; printk("Checking that ptrace can change system call numbers..."); - pid = start_ptraced_child(&stack); + pid = start_ptraced_child(); if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); @@ -354,7 +345,7 @@ void __init check_ptrace(void) break; } } - stop_ptraced_child(pid, stack, 0, 1); + stop_ptraced_child(pid, 0, 1); printk("OK\n"); check_sysemu(); } @@ -389,11 +380,10 @@ extern void *__syscall_stub_start, __syscall_stub_end; static inline void check_skas3_ptrace_support(void) { struct ptrace_faultinfo fi; - void *stack; int pid, n; printf("Checking for the skas3 patch in the host..."); - pid = start_ptraced_child(&stack); + pid = start_ptraced_child(); n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); if (n < 0) { @@ -412,7 +402,7 @@ static inline void check_skas3_ptrace_support(void) } init_registers(pid); - stop_ptraced_child(pid, stack, 1, 1); + stop_ptraced_child(pid, 1, 1); } int can_do_skas(void) diff --git a/trunk/arch/um/kernel/process_kern.c b/trunk/arch/um/kernel/process_kern.c index c23d8a08d0ff..d4036ed680bc 100644 --- a/trunk/arch/um/kernel/process_kern.c +++ b/trunk/arch/um/kernel/process_kern.c @@ -412,7 +412,7 @@ int __init make_proc_sysemu(void) if (ent == NULL) { - printk(KERN_WARNING "Failed to register /proc/sysemu\n"); + printk("Failed to register /proc/sysemu\n"); return(0); } diff --git a/trunk/arch/um/kernel/skas/process.c b/trunk/arch/um/kernel/skas/process.c index 6dd9e5bf18ed..ba671dab8878 100644 --- a/trunk/arch/um/kernel/skas/process.c +++ b/trunk/arch/um/kernel/skas/process.c @@ -64,7 +64,7 @@ void wait_stub_done(int pid, int sig, char * fname) (WSTOPSIG(status) == SIGVTALRM)); if((n < 0) || !WIFSTOPPED(status) || - (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){ + (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status != SIGTRAP))){ panic("%s : failed to wait for SIGUSR1/SIGTRAP, " "pid = %d, n = %d, errno = %d, status = 0x%x\n", fname, pid, n, errno, status); diff --git a/trunk/arch/um/kernel/skas/trap_user.c b/trunk/arch/um/kernel/skas/trap_user.c index 9950a6716fe5..0dee1d95c806 100644 --- a/trunk/arch/um/kernel/skas/trap_user.c +++ b/trunk/arch/um/kernel/skas/trap_user.c @@ -58,6 +58,7 @@ void user_signal(int sig, union uml_pt_regs *regs, int pid) int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) || (sig == SIGILL) || (sig == SIGTRAP)); + regs->skas.is_user = 1; if (segv) get_skas_faultinfo(pid, ®s->skas.faultinfo); info = &sig_info[sig]; diff --git a/trunk/arch/um/kernel/time_kern.c b/trunk/arch/um/kernel/time_kern.c index 4e08f7545d63..a8b4ef601f59 100644 --- a/trunk/arch/um/kernel/time_kern.c +++ b/trunk/arch/um/kernel/time_kern.c @@ -137,10 +137,7 @@ long um_stime(int __user *tptr) void timer_handler(int sig, union uml_pt_regs *regs) { local_irq_disable(); - irq_enter(); - update_process_times(CHOOSE_MODE(user_context(UPT_SP(regs)), - (regs)->skas.is_user)); - irq_exit(); + update_process_times(CHOOSE_MODE(user_context(UPT_SP(regs)), (regs)->skas.is_user)); local_irq_enable(); if(current_thread->cpu == 0) timer_irq(regs); diff --git a/trunk/arch/um/os-Linux/user_syms.c b/trunk/arch/um/os-Linux/user_syms.c index 56d3f870926b..75d7af9ae1d2 100644 --- a/trunk/arch/um/os-Linux/user_syms.c +++ b/trunk/arch/um/os-Linux/user_syms.c @@ -83,9 +83,6 @@ EXPORT_SYMBOL_PROTO(statfs64); EXPORT_SYMBOL_PROTO(getuid); -EXPORT_SYMBOL_PROTO(fsync); -EXPORT_SYMBOL_PROTO(fdatasync); - /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically diff --git a/trunk/arch/um/sys-i386/stub_segv.c b/trunk/arch/um/sys-i386/stub_segv.c index 68aeabe3a654..b251442ad0b1 100644 --- a/trunk/arch/um/sys-i386/stub_segv.c +++ b/trunk/arch/um/sys-i386/stub_segv.c @@ -21,10 +21,10 @@ stub_segv_handler(int sig) __asm__("movl %0, %%eax ; int $0x80": : "g" (__NR_getpid)); __asm__("movl %%eax, %%ebx ; movl %0, %%eax ; movl %1, %%ecx ;" "int $0x80": : "g" (__NR_kill), "g" (SIGUSR1)); - /* Load pointer to sigcontext into esp, since we need to leave + /* Pop the frame pointer and return address since we need to leave * the stack in its original form when we do the sigreturn here, by * hand. */ - __asm__("mov %0,%%esp ; movl %1, %%eax ; " - "int $0x80" : : "a" (sc), "g" (__NR_sigreturn)); + __asm__("popl %%eax ; popl %%eax ; popl %%eax ; movl %0, %%eax ; " + "int $0x80" : : "g" (__NR_sigreturn)); } diff --git a/trunk/arch/x86_64/Kconfig b/trunk/arch/x86_64/Kconfig index 660a03a89e66..4b8326177c52 100644 --- a/trunk/arch/x86_64/Kconfig +++ b/trunk/arch/x86_64/Kconfig @@ -329,15 +329,12 @@ config HPET_EMULATE_RTC config GART_IOMMU bool "IOMMU support" - default y depends on PCI help - Support the IOMMU. Needed to run systems with more than 3GB of memory + Support the K8 IOMMU. Needed to run systems with more than 4GB of memory properly with 32-bit PCI devices that do not support DAC (Double Address Cycle). The IOMMU can be turned off at runtime with the iommu=off parameter. Normally the kernel will take the right choice by itself. - This option includes a driver for the AMD Opteron/Athlon64 IOMMU - and a software emulation used on some other systems. If unsure, say Y. # need this always enabled with GART_IOMMU for the VIA workaround diff --git a/trunk/arch/x86_64/Makefile b/trunk/arch/x86_64/Makefile index 4c6ed96d5f7c..428915697675 100644 --- a/trunk/arch/x86_64/Makefile +++ b/trunk/arch/x86_64/Makefile @@ -21,6 +21,18 @@ # # $Id: Makefile,v 1.31 2002/03/22 15:56:07 ak Exp $ +# +# early bootup linking needs 32bit. You can either use real 32bit tools +# here or 64bit tools in 32bit mode. +# +IA32_CC := $(CC) $(CPPFLAGS) -m32 -O2 -fomit-frame-pointer +IA32_LD := $(LD) -m elf_i386 +IA32_AS := $(CC) $(AFLAGS) -m32 -Wa,--32 -traditional -c +IA32_OBJCOPY := $(CROSS_COMPILE)objcopy +IA32_CPP := $(CROSS_COMPILE)gcc -m32 -E +export IA32_CC IA32_LD IA32_AS IA32_OBJCOPY IA32_CPP + + LDFLAGS := -m elf_x86_64 OBJCOPYFLAGS := -O binary -R .note -R .comment -S LDFLAGS_vmlinux := diff --git a/trunk/arch/x86_64/defconfig b/trunk/arch/x86_64/defconfig index 776f3c866b70..569595b74c7c 100644 --- a/trunk/arch/x86_64/defconfig +++ b/trunk/arch/x86_64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.13-rc3 -# Fri Jul 22 16:47:31 2005 +# Linux kernel version: 2.6.12-rc4 +# Fri May 13 06:39:11 2005 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -84,27 +84,14 @@ CONFIG_X86_IO_APIC=y CONFIG_X86_LOCAL_APIC=y CONFIG_MTRR=y CONFIG_SMP=y -CONFIG_SCHED_SMT=y -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_PREEMPT_BKL=y +CONFIG_SCHED_SMT=y CONFIG_K8_NUMA=y # CONFIG_NUMA_EMU is not set -CONFIG_ARCH_DISCONTIGMEM_ENABLE=y -CONFIG_NUMA=y -CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_SELECT_MEMORY_MODEL=y -# CONFIG_FLATMEM_MANUAL is not set -CONFIG_DISCONTIGMEM_MANUAL=y -# CONFIG_SPARSEMEM_MANUAL is not set CONFIG_DISCONTIGMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_NEED_MULTIPLE_NODES=y -CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y +CONFIG_NUMA=y CONFIG_HAVE_DEC_LOCK=y -CONFIG_NR_CPUS=32 +CONFIG_NR_CPUS=8 CONFIG_HPET_TIMER=y CONFIG_X86_PM_TIMER=y CONFIG_HPET_EMULATE_RTC=y @@ -112,13 +99,7 @@ CONFIG_GART_IOMMU=y CONFIG_SWIOTLB=y CONFIG_X86_MCE=y CONFIG_X86_MCE_INTEL=y -CONFIG_PHYSICAL_START=0x100000 -# CONFIG_KEXEC is not set CONFIG_SECCOMP=y -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_ISA_DMA_API=y @@ -137,11 +118,12 @@ CONFIG_PM_STD_PARTITION="" CONFIG_ACPI=y CONFIG_ACPI_BOOT=y CONFIG_ACPI_INTERPRETER=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_SLEEP_PROC_FS=y CONFIG_ACPI_AC=y CONFIG_ACPI_BATTERY=y CONFIG_ACPI_BUTTON=y # CONFIG_ACPI_VIDEO is not set -CONFIG_ACPI_HOTKEY=m CONFIG_ACPI_FAN=y CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_THERMAL=y @@ -172,7 +154,6 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set # # CPUFreq processor drivers @@ -222,76 +203,6 @@ CONFIG_COMPAT=y CONFIG_SYSVIPC_COMPAT=y CONFIG_UID16=y -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_IP_TCPDIAG=y -CONFIG_IP_TCPDIAG_IPV6=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -CONFIG_IPV6=y -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_IPV6_TUNNEL is not set -# CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -CONFIG_NETPOLL=y -# CONFIG_NETPOLL_RX is not set -# CONFIG_NETPOLL_TRAP is not set -CONFIG_NET_POLL_CONTROLLER=y -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set - # # Device Drivers # @@ -397,7 +308,6 @@ CONFIG_BLK_DEV_AMD74XX=y # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set CONFIG_BLK_DEV_PIIX=y -# CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set CONFIG_BLK_DEV_PDC202XX_NEW=y @@ -428,7 +338,6 @@ CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_OSST is not set # CONFIG_BLK_DEV_SR is not set # CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -463,6 +372,7 @@ CONFIG_AIC79XX_DEBUG_MASK=0 # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set CONFIG_SCSI_SATA=y +# CONFIG_SCSI_SATA_AHCI is not set # CONFIG_SCSI_SATA_SVW is not set CONFIG_SCSI_ATA_PIIX=y # CONFIG_SCSI_SATA_NV is not set @@ -500,21 +410,14 @@ CONFIG_SCSI_QLA2XXX=y # # Multi-device support (RAID and LVM) # -CONFIG_MD=y -# CONFIG_BLK_DEV_MD is not set -CONFIG_BLK_DEV_DM=y -# CONFIG_DM_CRYPT is not set -# CONFIG_DM_SNAPSHOT is not set -# CONFIG_DM_MIRROR is not set -# CONFIG_DM_ZERO is not set -# CONFIG_DM_MULTIPATH is not set +# CONFIG_MD is not set # # Fusion MPT device support # -# CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set +CONFIG_FUSION=y +CONFIG_FUSION_MAX_SGE=40 +# CONFIG_FUSION_CTL is not set # # IEEE 1394 (FireWire) support @@ -527,8 +430,75 @@ CONFIG_BLK_DEV_DM=y # CONFIG_I2O is not set # -# Network device support +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +CONFIG_IP_TCPDIAG_IPV6=y +CONFIG_IPV6=y +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) # +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set @@ -547,9 +517,7 @@ CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set -CONFIG_NET_VENDOR_3COM=y -CONFIG_VORTEX=y -# CONFIG_TYPHOON is not set +# CONFIG_NET_VENDOR_3COM is not set # # Tulip family network device support @@ -564,7 +532,7 @@ CONFIG_NET_PCI=y CONFIG_FORCEDETH=y # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set -CONFIG_E100=y +# CONFIG_E100 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set @@ -585,15 +553,14 @@ CONFIG_8139TOO=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set CONFIG_E1000=y +# CONFIG_E1000_NAPI is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set -# CONFIG_SKGE is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y -# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) @@ -680,6 +647,7 @@ CONFIG_SERIO_I8042=y CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y # # Character devices @@ -748,19 +716,12 @@ CONFIG_MAX_RAW_DEVS=256 # I2C support # # CONFIG_I2C is not set -# CONFIG_I2C_SENSOR is not set # # Dallas's 1-wire bus # # CONFIG_W1 is not set -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_DEBUG_CHIP is not set - # # Misc devices # @@ -847,7 +808,6 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN is not set CONFIG_USB_OHCI_LITTLE_ENDIAN=y @@ -886,15 +846,12 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_HIDDEV is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # CONFIG_USB_MTOUCH is not set -# CONFIG_USB_ITMTOUCH is not set # CONFIG_USB_EGALAX is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set # # USB Imaging devices @@ -945,11 +902,10 @@ CONFIG_USB_MON=y # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set # CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set # CONFIG_USB_TEST is not set # -# USB DSL modem support +# USB ATM/DSL drivers # # @@ -967,10 +923,6 @@ CONFIG_USB_MON=y # # CONFIG_INFINIBAND is not set -# -# SN Devices -# - # # Firmware Drivers # @@ -983,7 +935,6 @@ CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y # CONFIG_EXT2_FS_SECURITY is not set -# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y @@ -1006,7 +957,6 @@ CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y CONFIG_AUTOFS_FS=y @@ -1036,6 +986,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y # CONFIG_TMPFS_XATTR is not set @@ -1065,18 +1016,15 @@ CONFIG_RAMFS=y # CONFIG_NFS_FS=y CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set CONFIG_NFSD_TCP=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y -CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set diff --git a/trunk/arch/x86_64/ia32/Makefile b/trunk/arch/x86_64/ia32/Makefile index f76217d8f579..a12b19da4b59 100644 --- a/trunk/arch/x86_64/ia32/Makefile +++ b/trunk/arch/x86_64/ia32/Makefile @@ -4,14 +4,14 @@ obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o \ ia32_signal.o tls32.o \ - ia32_binfmt.o fpu32.o ptrace32.o syscall32.o syscall32_syscall.o + ia32_binfmt.o fpu32.o ptrace32.o syscall32.o sysv-$(CONFIG_SYSVIPC) := ipc32.o obj-$(CONFIG_IA32_EMULATION) += $(sysv-y) obj-$(CONFIG_IA32_AOUT) += ia32_aout.o -$(obj)/syscall32_syscall.o: \ +$(obj)/syscall32.o: $(src)/syscall32.c \ $(foreach F,sysenter syscall,$(obj)/vsyscall-$F.so) # Teach kbuild about targets diff --git a/trunk/arch/x86_64/ia32/syscall32.c b/trunk/arch/x86_64/ia32/syscall32.c index adbc5f8089e9..816a3b89f13d 100644 --- a/trunk/arch/x86_64/ia32/syscall32.c +++ b/trunk/arch/x86_64/ia32/syscall32.c @@ -14,6 +14,16 @@ #include #include +/* 32bit VDSOs mapped into user space. */ +asm(".section \".init.data\",\"aw\"\n" + "syscall32_syscall:\n" + ".incbin \"arch/x86_64/ia32/vsyscall-syscall.so\"\n" + "syscall32_syscall_end:\n" + "syscall32_sysenter:\n" + ".incbin \"arch/x86_64/ia32/vsyscall-sysenter.so\"\n" + "syscall32_sysenter_end:\n" + ".previous"); + extern unsigned char syscall32_syscall[], syscall32_syscall_end[]; extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[]; extern int sysctl_vsyscall32; diff --git a/trunk/arch/x86_64/ia32/syscall32_syscall.S b/trunk/arch/x86_64/ia32/syscall32_syscall.S deleted file mode 100644 index 8f8271bdf135..000000000000 --- a/trunk/arch/x86_64/ia32/syscall32_syscall.S +++ /dev/null @@ -1,17 +0,0 @@ -/* 32bit VDSOs mapped into user space. */ - - .section ".init.data","aw" - - .globl syscall32_syscall - .globl syscall32_syscall_end - -syscall32_syscall: - .incbin "arch/x86_64/ia32/vsyscall-syscall.so" -syscall32_syscall_end: - - .globl syscall32_sysenter - .globl syscall32_sysenter_end - -syscall32_sysenter: - .incbin "arch/x86_64/ia32/vsyscall-sysenter.so" -syscall32_sysenter_end: diff --git a/trunk/arch/x86_64/kernel/entry.S b/trunk/arch/x86_64/kernel/entry.S index 096d470e280f..28817490fdc6 100644 --- a/trunk/arch/x86_64/kernel/entry.S +++ b/trunk/arch/x86_64/kernel/entry.S @@ -76,7 +76,7 @@ .macro FAKE_STACK_FRAME child_rip /* push in order ss, rsp, eflags, cs, rip */ - xorl %eax, %eax + xorq %rax, %rax pushq %rax /* ss */ CFI_ADJUST_CFA_OFFSET 8 pushq %rax /* rsp */ @@ -423,7 +423,7 @@ ENTRY(stub_rt_sigreturn) testl $3,CS(%rdi) je 1f swapgs -1: incl %gs:pda_irqcount # RED-PEN should check preempt count +1: addl $1,%gs:pda_irqcount # RED-PEN should check preempt count movq %gs:pda_irqstackptr,%rax cmoveq %rax,%rsp pushq %rdi # save old stack @@ -436,7 +436,7 @@ ENTRY(common_interrupt) ret_from_intr: popq %rdi cli - decl %gs:pda_irqcount + subl $1,%gs:pda_irqcount #ifdef CONFIG_DEBUG_INFO movq RBP(%rdi),%rbp #endif @@ -494,7 +494,7 @@ retint_signal: sti SAVE_REST movq $-1,ORIG_RAX(%rsp) - xorl %esi,%esi # oldset + xorq %rsi,%rsi # oldset movq %rsp,%rdi # &pt_regs call do_notify_resume RESTORE_REST @@ -752,7 +752,7 @@ child_rip: movq %rsi, %rdi call *%rax # exit - xorl %edi, %edi + xorq %rdi, %rdi call do_exit /* @@ -918,15 +918,3 @@ ENTRY(machine_check) ENTRY(call_debug) zeroentry do_call_debug -ENTRY(call_softirq) - movq %gs:pda_irqstackptr,%rax - pushq %r15 - movq %rsp,%r15 - incl %gs:pda_irqcount - cmove %rax,%rsp - call __do_softirq - movq %r15,%rsp - decl %gs:pda_irqcount - popq %r15 - ret - diff --git a/trunk/arch/x86_64/kernel/genapic.c b/trunk/arch/x86_64/kernel/genapic.c index 30c843a5efdd..69b9c25a8fc4 100644 --- a/trunk/arch/x86_64/kernel/genapic.c +++ b/trunk/arch/x86_64/kernel/genapic.c @@ -31,7 +31,6 @@ u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; extern struct genapic apic_cluster; extern struct genapic apic_flat; -extern struct genapic apic_physflat; struct genapic *genapic = &apic_flat; @@ -45,7 +44,12 @@ void __init clustered_apic_check(void) u8 clusters, max_cluster; u8 id; u8 cluster_cnt[NUM_APIC_CLUSTERS]; - int num_cpus = 0; + + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { + /* AMD always uses flat mode right now */ + genapic = &apic_flat; + goto print; + } #if defined(CONFIG_ACPI_BUS) /* @@ -60,34 +64,15 @@ void __init clustered_apic_check(void) #endif memset(cluster_cnt, 0, sizeof(cluster_cnt)); + for (i = 0; i < NR_CPUS; i++) { id = bios_cpu_apicid[i]; - if (id == BAD_APICID) - continue; - num_cpus++; - cluster_cnt[APIC_CLUSTERID(id)]++; + if (id != BAD_APICID) + cluster_cnt[APIC_CLUSTERID(id)]++; } - /* Don't use clustered mode on AMD platforms. */ - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { - genapic = &apic_physflat; -#ifndef CONFIG_CPU_HOTPLUG - /* In the CPU hotplug case we cannot use broadcast mode - because that opens a race when a CPU is removed. - Stay at physflat mode in this case. - It is bad to do this unconditionally though. Once - we have ACPI platform support for CPU hotplug - we should detect hotplug capablity from ACPI tables and - only do this when really needed. -AK */ - if (num_cpus <= 8) - genapic = &apic_flat; -#endif - goto print; - } - clusters = 0; max_cluster = 0; - for (i = 0; i < NUM_APIC_CLUSTERS; i++) { if (cluster_cnt[i] > 0) { ++clusters; diff --git a/trunk/arch/x86_64/kernel/genapic_flat.c b/trunk/arch/x86_64/kernel/genapic_flat.c index adc96282a9e2..282846965080 100644 --- a/trunk/arch/x86_64/kernel/genapic_flat.c +++ b/trunk/arch/x86_64/kernel/genapic_flat.c @@ -2,11 +2,13 @@ * Copyright 2004 James Cleverdon, IBM. * Subject to the GNU Public License, v.2 * - * Flat APIC subarch code. + * Flat APIC subarch code. Maximum 8 CPUs, logical delivery. * * Hacked for x86-64 by James Cleverdon from i386 architecture code by * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and * James Cleverdon. + * Ashok Raj + * Removed IPI broadcast shortcut to support CPU hotplug */ #include #include @@ -18,6 +20,47 @@ #include #include +/* + * The following permit choosing broadcast IPI shortcut v.s sending IPI only + * to online cpus via the send_IPI_mask varient. + * The mask version is my preferred option, since it eliminates a lot of + * other extra code that would need to be written to cleanup intrs sent + * to a CPU while offline. + * + * Sending broadcast introduces lots of trouble in CPU hotplug situations. + * These IPI's are delivered to cpu's irrespective of their offline status + * and could pickup stale intr data when these CPUS are turned online. + * + * Not using broadcast is a cleaner approach IMO, but Andi Kleen disagrees with + * the idea of not using broadcast IPI's anymore. Hence the run time check + * is introduced, on his request so we can choose an alternate mechanism. + * + * Initial wacky performance tests that collect cycle counts show + * no increase in using mask v.s broadcast version. In fact they seem + * identical in terms of cycle counts. + * + * if we need to use broadcast, we need to do the following. + * + * cli; + * hold call_lock; + * clear any pending IPI, just ack and clear all pending intr + * set cpu_online_map; + * release call_lock; + * sti; + * + * The complicated dummy irq processing shown above is not required if + * we didnt sent IPI's to wrong CPU's in the first place. + * + * - Ashok Raj + */ +#ifdef CONFIG_HOTPLUG_CPU +#define DEFAULT_SEND_IPI (1) +#else +#define DEFAULT_SEND_IPI (0) +#endif + +static int no_broadcast=DEFAULT_SEND_IPI; + static cpumask_t flat_target_cpus(void) { return cpu_online_map; @@ -76,15 +119,37 @@ static void flat_send_IPI_mask(cpumask_t cpumask, int vector) local_irq_restore(flags); } +static inline void __local_flat_send_IPI_allbutself(int vector) +{ + if (no_broadcast) { + cpumask_t mask = cpu_online_map; + int this_cpu = get_cpu(); + + cpu_clear(this_cpu, mask); + flat_send_IPI_mask(mask, vector); + put_cpu(); + } + else + __send_IPI_shortcut(APIC_DEST_ALLBUT, vector, APIC_DEST_LOGICAL); +} + +static inline void __local_flat_send_IPI_all(int vector) +{ + if (no_broadcast) + flat_send_IPI_mask(cpu_online_map, vector); + else + __send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL); +} + static void flat_send_IPI_allbutself(int vector) { if (((num_online_cpus()) - 1) >= 1) - __send_IPI_shortcut(APIC_DEST_ALLBUT, vector,APIC_DEST_LOGICAL); + __local_flat_send_IPI_allbutself(vector); } static void flat_send_IPI_all(int vector) { - __send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL); + __local_flat_send_IPI_all(vector); } static int flat_apic_id_registered(void) @@ -105,6 +170,16 @@ static unsigned int phys_pkg_id(int index_msb) return ((ebx >> 24) & 0xFF) >> index_msb; } +static __init int no_ipi_broadcast(char *str) +{ + get_option(&str, &no_broadcast); + printk ("Using %s mode\n", no_broadcast ? "No IPI Broadcast" : + "IPI Broadcast"); + return 1; +} + +__setup("no_ipi_broadcast", no_ipi_broadcast); + struct genapic apic_flat = { .name = "flat", .int_delivery_mode = dest_LowestPrio, @@ -120,62 +195,11 @@ struct genapic apic_flat = { .phys_pkg_id = phys_pkg_id, }; -/* - * Physflat mode is used when there are more than 8 CPUs on a AMD system. - * We cannot use logical delivery in this case because the mask - * overflows, so use physical mode. - */ - -static cpumask_t physflat_target_cpus(void) -{ - return cpumask_of_cpu(0); -} - -static void physflat_send_IPI_mask(cpumask_t cpumask, int vector) -{ - send_IPI_mask_sequence(cpumask, vector); -} - -static void physflat_send_IPI_allbutself(int vector) -{ - cpumask_t allbutme = cpu_online_map; - int me = get_cpu(); - cpu_clear(me, allbutme); - physflat_send_IPI_mask(allbutme, vector); - put_cpu(); -} - -static void physflat_send_IPI_all(int vector) +static int __init print_ipi_mode(void) { - physflat_send_IPI_mask(cpu_online_map, vector); + printk ("Using IPI %s mode\n", no_broadcast ? "No-Shortcut" : + "Shortcut"); + return 0; } -static unsigned int physflat_cpu_mask_to_apicid(cpumask_t cpumask) -{ - int cpu; - - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - cpu = first_cpu(cpumask); - if ((unsigned)cpu < NR_CPUS) - return x86_cpu_to_apicid[cpu]; - else - return BAD_APICID; -} - -struct genapic apic_physflat = { - .name = "physical flat", - .int_delivery_mode = dest_LowestPrio, - .int_dest_mode = (APIC_DEST_PHYSICAL != 0), - .int_delivery_dest = APIC_DEST_PHYSICAL | APIC_DM_LOWEST, - .target_cpus = physflat_target_cpus, - .apic_id_registered = flat_apic_id_registered, - .init_apic_ldr = flat_init_apic_ldr,/*not needed, but shouldn't hurt*/ - .send_IPI_all = physflat_send_IPI_all, - .send_IPI_allbutself = physflat_send_IPI_allbutself, - .send_IPI_mask = physflat_send_IPI_mask, - .cpu_mask_to_apicid = physflat_cpu_mask_to_apicid, - .phys_pkg_id = phys_pkg_id, -}; +late_initcall(print_ipi_mode); diff --git a/trunk/arch/x86_64/kernel/head.S b/trunk/arch/x86_64/kernel/head.S index 98ff5eb32b9a..8d765aa77a26 100644 --- a/trunk/arch/x86_64/kernel/head.S +++ b/trunk/arch/x86_64/kernel/head.S @@ -137,14 +137,14 @@ startup_64: wrmsr /* Setup cr0 */ -#define CR0_PM 1 /* protected mode */ -#define CR0_MP (1<<1) -#define CR0_ET (1<<4) -#define CR0_NE (1<<5) -#define CR0_WP (1<<16) -#define CR0_AM (1<<18) -#define CR0_PAGING (1<<31) - movl $CR0_PM|CR0_MP|CR0_ET|CR0_NE|CR0_WP|CR0_AM|CR0_PAGING,%eax + xorq %rax, %rax + btsq $31, %rax /* Enable paging */ + btsq $0, %rax /* Enable protected mode */ + btsq $1, %rax /* Enable MP */ + btsq $4, %rax /* Enable ET */ + btsq $5, %rax /* Enable NE */ + btsq $16, %rax /* Enable WP */ + btsq $18, %rax /* Enable AM */ /* Make changes effective */ movq %rax, %cr0 diff --git a/trunk/arch/x86_64/kernel/irq.c b/trunk/arch/x86_64/kernel/irq.c index 849a20aec7ca..cc3fb85f5145 100644 --- a/trunk/arch/x86_64/kernel/irq.c +++ b/trunk/arch/x86_64/kernel/irq.c @@ -135,22 +135,3 @@ void fixup_irqs(cpumask_t map) local_irq_disable(); } #endif - -extern void call_softirq(void); - -asmlinkage void do_softirq(void) -{ - __u32 pending; - unsigned long flags; - - if (in_interrupt()) - return; - - local_irq_save(flags); - pending = local_softirq_pending(); - /* Switch to interrupt stack */ - if (pending) - call_softirq(); - local_irq_restore(flags); -} -EXPORT_SYMBOL(do_softirq); diff --git a/trunk/arch/x86_64/kernel/mce.c b/trunk/arch/x86_64/kernel/mce.c index 3b267c91bb0c..21e70625a495 100644 --- a/trunk/arch/x86_64/kernel/mce.c +++ b/trunk/arch/x86_64/kernel/mce.c @@ -15,8 +15,6 @@ #include #include #include -#include -#include #include #include #include @@ -516,7 +514,10 @@ static struct sysdev_class mce_sysclass = { set_kset_name("machinecheck"), }; -static DEFINE_PER_CPU(struct sys_device, device_mce); +static struct sys_device device_mce = { + .id = 0, + .cls = &mce_sysclass, +}; /* Why are there no generic functions for this? */ #define ACCESSOR(name, var, start) \ @@ -541,83 +542,27 @@ ACCESSOR(bank4ctl,bank[4],mce_restart()) ACCESSOR(tolerant,tolerant,) ACCESSOR(check_interval,check_interval,mce_restart()) -/* Per cpu sysdev init. All of the cpus still share the same ctl bank */ -static __cpuinit int mce_create_device(unsigned int cpu) +static __cpuinit int mce_init_device(void) { int err; - if (!mce_available(&cpu_data[cpu])) - return -EIO; - - per_cpu(device_mce,cpu).id = cpu; - per_cpu(device_mce,cpu).cls = &mce_sysclass; - - err = sysdev_register(&per_cpu(device_mce,cpu)); - - if (!err) { - sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank0ctl); - sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank1ctl); - sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank2ctl); - sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank3ctl); - sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank4ctl); - sysdev_create_file(&per_cpu(device_mce,cpu), &attr_tolerant); - sysdev_create_file(&per_cpu(device_mce,cpu), &attr_check_interval); - } - return err; -} - -#ifdef CONFIG_HOTPLUG_CPU -static __cpuinit void mce_remove_device(unsigned int cpu) -{ - sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank0ctl); - sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank1ctl); - sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank2ctl); - sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank3ctl); - sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank4ctl); - sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_tolerant); - sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_check_interval); - sysdev_unregister(&per_cpu(device_mce,cpu)); -} -#endif - -/* Get notified when a cpu comes on/off. Be hotplug friendly. */ -static __cpuinit int -mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) -{ - unsigned int cpu = (unsigned long)hcpu; - - switch (action) { - case CPU_ONLINE: - mce_create_device(cpu); - break; -#ifdef CONFIG_HOTPLUG_CPU - case CPU_DEAD: - mce_remove_device(cpu); - break; -#endif - } - return NOTIFY_OK; -} - -static struct notifier_block mce_cpu_notifier = { - .notifier_call = mce_cpu_callback, -}; - -static __init int mce_init_device(void) -{ - int err; - int i = 0; - if (!mce_available(&boot_cpu_data)) return -EIO; err = sysdev_class_register(&mce_sysclass); - - for_each_online_cpu(i) { - mce_create_device(i); - } - - register_cpu_notifier(&mce_cpu_notifier); + if (!err) + err = sysdev_register(&device_mce); + if (!err) { + /* could create per CPU objects, but it is not worth it. */ + sysdev_create_file(&device_mce, &attr_bank0ctl); + sysdev_create_file(&device_mce, &attr_bank1ctl); + sysdev_create_file(&device_mce, &attr_bank2ctl); + sysdev_create_file(&device_mce, &attr_bank3ctl); + sysdev_create_file(&device_mce, &attr_bank4ctl); + sysdev_create_file(&device_mce, &attr_tolerant); + sysdev_create_file(&device_mce, &attr_check_interval); + } + misc_register(&mce_log_device); return err; -} +} device_initcall(mce_init_device); diff --git a/trunk/arch/x86_64/kernel/mpparse.c b/trunk/arch/x86_64/kernel/mpparse.c index 08abf9f5b159..9c5aa2a790c7 100644 --- a/trunk/arch/x86_64/kernel/mpparse.c +++ b/trunk/arch/x86_64/kernel/mpparse.c @@ -109,7 +109,7 @@ static int __init mpf_checksum(unsigned char *mp, int len) static void __init MP_processor_info (struct mpc_config_processor *m) { - int ver, cpu; + int ver; static int found_bsp=0; if (!(m->mpc_cpuflag & CPU_ENABLED)) @@ -131,7 +131,7 @@ static void __init MP_processor_info (struct mpc_config_processor *m) return; } - cpu = num_processors++; + num_processors++; if (m->mpc_apicid > MAX_APICS) { printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n", @@ -155,18 +155,13 @@ static void __init MP_processor_info (struct mpc_config_processor *m) * in same order as logical cpu numbers. Hence the first * entry is BSP, and so on. */ - cpu = 0; - bios_cpu_apicid[0] = m->mpc_apicid; x86_cpu_to_apicid[0] = m->mpc_apicid; found_bsp = 1; - } else - cpu = num_processors - found_bsp; - bios_cpu_apicid[cpu] = m->mpc_apicid; - x86_cpu_to_apicid[cpu] = m->mpc_apicid; - - cpu_set(cpu, cpu_possible_map); - cpu_set(cpu, cpu_present_map); + } else { + bios_cpu_apicid[num_processors - found_bsp] = m->mpc_apicid; + x86_cpu_to_apicid[num_processors - found_bsp] = m->mpc_apicid; + } } static void __init MP_bus_info (struct mpc_config_bus *m) diff --git a/trunk/arch/x86_64/kernel/setup.c b/trunk/arch/x86_64/kernel/setup.c index 0aa526298e92..5fd03225058a 100644 --- a/trunk/arch/x86_64/kernel/setup.c +++ b/trunk/arch/x86_64/kernel/setup.c @@ -765,6 +765,8 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c) int cpu = smp_processor_id(); int node = 0; unsigned bits; + if (c->x86_num_cores == 1) + return; bits = 0; while ((1 << bits) < c->x86_num_cores) @@ -1079,7 +1081,8 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c) else mtrr_ap_init(); #ifdef CONFIG_NUMA - numa_add_cpu(smp_processor_id()); + if (c != &boot_cpu_data) + numa_add_cpu(c - cpu_data); #endif } diff --git a/trunk/arch/x86_64/kernel/setup64.c b/trunk/arch/x86_64/kernel/setup64.c index 34082c1cc41e..f2b9c6bc999a 100644 --- a/trunk/arch/x86_64/kernel/setup64.c +++ b/trunk/arch/x86_64/kernel/setup64.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -23,8 +22,10 @@ #include #include #include +#include #include -#include +#include +#include char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,}; @@ -32,6 +33,11 @@ cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; struct x8664_pda cpu_pda[NR_CPUS] __cacheline_aligned; +extern struct task_struct init_task; + +extern unsigned char __per_cpu_start[], __per_cpu_end[]; + +extern struct desc_ptr cpu_gdt_descr[]; struct desc_ptr idt_descr = { 256 * 16, (unsigned long) idt_table }; char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned"))); @@ -95,7 +101,7 @@ void __init setup_per_cpu_areas(void) #endif for (i = 0; i < NR_CPUS; i++) { - char *ptr; + unsigned char *ptr; if (!NODE_DATA(cpu_to_node(i))) { printk("cpu with no node %d, num_online_nodes %d\n", @@ -184,7 +190,11 @@ void __cpuinit check_efer(void) */ void __cpuinit cpu_init (void) { +#ifdef CONFIG_SMP int cpu = stack_smp_processor_id(); +#else + int cpu = smp_processor_id(); +#endif struct tss_struct *t = &per_cpu(init_tss, cpu); unsigned long v; char *estacks = NULL; @@ -204,7 +214,7 @@ void __cpuinit cpu_init (void) printk("Initializing CPU#%d\n", cpu); - clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); + clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); /* * Initialize the per-CPU GDT with the boot GDT, diff --git a/trunk/arch/x86_64/kernel/smp.c b/trunk/arch/x86_64/kernel/smp.c index 6ee74db52303..ccae392886af 100644 --- a/trunk/arch/x86_64/kernel/smp.c +++ b/trunk/arch/x86_64/kernel/smp.c @@ -129,9 +129,10 @@ asmlinkage void smp_invalidate_interrupt (void) } else leave_mm(cpu); } -out: ack_APIC_irq(); cpu_clear(cpu, flush_cpumask); + +out: put_cpu_no_resched(); } diff --git a/trunk/arch/x86_64/kernel/smpboot.c b/trunk/arch/x86_64/kernel/smpboot.c index 6d23354443c0..e773a794ec45 100644 --- a/trunk/arch/x86_64/kernel/smpboot.c +++ b/trunk/arch/x86_64/kernel/smpboot.c @@ -112,6 +112,24 @@ struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; #define get_idle_for_cpu(x) (idle_thread_array[(x)]) #define set_idle_for_cpu(x,p) (idle_thread_array[(x)] = (p)) +/* + * cpu_possible_map should be static, it cannot change as cpu's + * are onlined, or offlined. The reason is per-cpu data-structures + * are allocated by some modules at init time, and dont expect to + * do this dynamically on cpu arrival/departure. + * cpu_present_map on the other hand can change dynamically. + * In case when cpu_hotplug is not compiled, then we resort to current + * behaviour, which is cpu_possible == cpu_present. + * If cpu-hotplug is supported, then we need to preallocate for all + * those NR_CPUS, hence cpu_possible_map represents entire NR_CPUS range. + * - Ashok Raj + */ +#ifdef CONFIG_HOTPLUG_CPU +#define fixup_cpu_possible_map(x) cpu_set((x), cpu_possible_map) +#else +#define fixup_cpu_possible_map(x) +#endif + /* * Currently trivial. Write the real->protected mode * bootstrap into the page concerned. The caller @@ -755,9 +773,8 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) initial_code = start_secondary; clear_ti_thread_flag(c_idle.idle->thread_info, TIF_FORK); - printk(KERN_INFO "Booting processor %d/%d APIC 0x%x\n", cpu, - cpus_weight(cpu_present_map), - apicid); + printk(KERN_INFO "Booting processor %d/%d rip %lx rsp %lx\n", cpu, apicid, + start_rip, init_rsp); /* * This grunge runs the startup process for @@ -907,27 +924,6 @@ static __init void enforce_max_cpus(unsigned max_cpus) } } -#ifdef CONFIG_HOTPLUG_CPU -/* - * cpu_possible_map should be static, it cannot change as cpu's - * are onlined, or offlined. The reason is per-cpu data-structures - * are allocated by some modules at init time, and dont expect to - * do this dynamically on cpu arrival/departure. - * cpu_present_map on the other hand can change dynamically. - * In case when cpu_hotplug is not compiled, then we resort to current - * behaviour, which is cpu_possible == cpu_present. - * If cpu-hotplug is supported, then we need to preallocate for all - * those NR_CPUS, hence cpu_possible_map represents entire NR_CPUS range. - * - Ashok Raj - */ -static void prefill_possible_map(void) -{ - int i; - for (i = 0; i < NR_CPUS; i++) - cpu_set(i, cpu_possible_map); -} -#endif - /* * Various sanity checks. */ @@ -991,15 +987,25 @@ static int __init smp_sanity_check(unsigned max_cpus) */ void __init smp_prepare_cpus(unsigned int max_cpus) { + int i; + nmi_watchdog_default(); current_cpu_data = boot_cpu_data; current_thread_info()->cpu = 0; /* needed? */ enforce_max_cpus(max_cpus); -#ifdef CONFIG_HOTPLUG_CPU - prefill_possible_map(); -#endif + /* + * Fill in cpu_present_mask + */ + for (i = 0; i < NR_CPUS; i++) { + int apicid = cpu_present_to_apicid(i); + if (physid_isset(apicid, phys_cpu_present_map)) { + cpu_set(i, cpu_present_map); + cpu_set(i, cpu_possible_map); + } + fixup_cpu_possible_map(i); + } if (smp_sanity_check(max_cpus) < 0) { printk(KERN_INFO "SMP disabled\n"); @@ -1183,7 +1189,8 @@ void __cpu_die(unsigned int cpu) printk ("CPU %d is now offline\n", cpu); return; } - msleep(100); + current->state = TASK_UNINTERRUPTIBLE; + schedule_timeout(HZ/10); } printk(KERN_ERR "CPU %u didn't die...\n", cpu); } diff --git a/trunk/arch/x86_64/kernel/traps.c b/trunk/arch/x86_64/kernel/traps.c index 6ead433a3885..102736630002 100644 --- a/trunk/arch/x86_64/kernel/traps.c +++ b/trunk/arch/x86_64/kernel/traps.c @@ -594,6 +594,9 @@ asmlinkage void default_do_nmi(struct pt_regs *regs) if (!cpu) reason = get_nmi_reason(); + if (!cpu_online(cpu)) + return; + if (!(reason & 0xc0)) { if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) == NOTIFY_STOP) diff --git a/trunk/arch/x86_64/lib/delay.c b/trunk/arch/x86_64/lib/delay.c index 841bd738a189..33a873a3c223 100644 --- a/trunk/arch/x86_64/lib/delay.c +++ b/trunk/arch/x86_64/lib/delay.c @@ -18,6 +18,8 @@ #include #endif +int x86_udelay_tsc = 0; /* Delay via TSC */ + int read_current_timer(unsigned long *timer_value) { rdtscll(*timer_value); diff --git a/trunk/arch/x86_64/mm/fault.c b/trunk/arch/x86_64/mm/fault.c index 13792721037e..2f187986f940 100644 --- a/trunk/arch/x86_64/mm/fault.c +++ b/trunk/arch/x86_64/mm/fault.c @@ -23,6 +23,7 @@ #include /* For unblank_screen() */ #include #include +#include #include #include diff --git a/trunk/arch/x86_64/mm/numa.c b/trunk/arch/x86_64/mm/numa.c index 70cb2904a90f..ac61c186eb02 100644 --- a/trunk/arch/x86_64/mm/numa.c +++ b/trunk/arch/x86_64/mm/numa.c @@ -36,36 +36,34 @@ int numa_off __initdata; int __init compute_hash_shift(struct node *nodes, int numnodes) { int i; - int shift = 20; - unsigned long addr,maxend=0; + int shift = 24; + u64 addr; - for (i = 0; i < numnodes; i++) - if ((nodes[i].start != nodes[i].end) && (nodes[i].end > maxend)) - maxend = nodes[i].end; - - while ((1UL << shift) < (maxend / NODEMAPSIZE)) - shift++; - - printk (KERN_DEBUG"Using %d for the hash shift. Max adder is %lx \n", - shift,maxend); - memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE); - for (i = 0; i < numnodes; i++) { - if (nodes[i].start == nodes[i].end) - continue; - for (addr = nodes[i].start; - addr < nodes[i].end; - addr += (1UL << shift)) { - if (memnodemap[addr >> shift] != 0xff) { - printk(KERN_INFO - "Your memory is not aligned you need to rebuild your kernel " - "with a bigger NODEMAPSIZE shift=%d adder=%lu\n", - shift,addr); - return -1; + /* When in doubt use brute force. */ + while (shift < 48) { + memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE); + for (i = 0; i < numnodes; i++) { + if (nodes[i].start == nodes[i].end) + continue; + for (addr = nodes[i].start; + addr < nodes[i].end; + addr += (1UL << shift)) { + if (memnodemap[addr >> shift] != 0xff && + memnodemap[addr >> shift] != i) { + printk(KERN_INFO + "node %d shift %d addr %Lx conflict %d\n", + i, shift, addr, memnodemap[addr>>shift]); + goto next; + } + memnodemap[addr >> shift] = i; } - memnodemap[addr >> shift] = i; } + return shift; + next: + shift++; } - return shift; + memset(memnodemap,0,sizeof(*memnodemap) * NODEMAPSIZE); + return -1; } #ifdef CONFIG_SPARSEMEM diff --git a/trunk/arch/x86_64/mm/srat.c b/trunk/arch/x86_64/mm/srat.c index 8e3d097a9ddd..5d01b31472e1 100644 --- a/trunk/arch/x86_64/mm/srat.c +++ b/trunk/arch/x86_64/mm/srat.c @@ -20,9 +20,6 @@ static struct acpi_table_slit *acpi_slit; -/* Internal processor count */ -static unsigned int __initdata num_processors = 0; - static nodemask_t nodes_parsed __initdata; static nodemask_t nodes_found __initdata; static struct node nodes[MAX_NUMNODES] __initdata; @@ -104,18 +101,16 @@ acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) bad_srat(); return; } - if (num_processors >= NR_CPUS) { - printk(KERN_ERR "SRAT: Processor #%d (lapic %u) INVALID. (Max ID: %d).\n", - num_processors, pa->apic_id, NR_CPUS); + if (pa->apic_id >= NR_CPUS) { + printk(KERN_ERR "SRAT: lapic %u too large.\n", + pa->apic_id); bad_srat(); return; } - cpu_to_node[num_processors] = node; + cpu_to_node[pa->apic_id] = node; acpi_numa = 1; - printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> CPU %u -> Node %u\n", - pxm, pa->apic_id, num_processors, node); - - num_processors++; + printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n", + pxm, pa->apic_id, node); } /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ @@ -129,6 +124,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) if (srat_disabled() || ma->flags.enabled == 0) return; + /* hotplug bit is ignored for now */ pxm = ma->proximity_domain; node = setup_node(pxm); if (node < 0) { @@ -138,10 +134,6 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) } start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); - /* It is fine to add this area to the nodes data it will be used later*/ - if (ma->flags.hot_pluggable == 1) - printk(KERN_INFO "SRAT: hot plug zone found %lx - %lx \n", - start, end); i = conflicting_nodes(start, end); if (i >= 0) { printk(KERN_ERR diff --git a/trunk/arch/x86_64/pci/k8-bus.c b/trunk/arch/x86_64/pci/k8-bus.c index c2c38b579939..7e7d0c2a0025 100644 --- a/trunk/arch/x86_64/pci/k8-bus.c +++ b/trunk/arch/x86_64/pci/k8-bus.c @@ -29,7 +29,7 @@ __init static int fill_mp_bus_to_cpumask(void) { struct pci_dev *nb_dev = NULL; - int i, j; + int i, j, printed; u32 ldtbus, nid; static int lbnr[3] = { LDT_BUS_NUMBER_REGISTER_0, diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index 418b1469d75d..3e9fb6e4a52a 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -1135,7 +1135,7 @@ static int revalidate_allvol(ctlr_info_t *host) /* this is for the online array utilities */ if (!drv->heads && i) continue; - blk_queue_hardsect_size(drv->queue, drv->block_size); + blk_queue_hardsect_size(host->queue, drv->block_size); set_capacity(disk, drv->nr_blocks); add_disk(disk); } @@ -1691,7 +1691,7 @@ static int cciss_revalidate(struct gendisk *disk) cciss_read_capacity(h->ctlr, logvol, size_buff, 1, &total_size, &block_size); cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size, inq_buff, drv); - blk_queue_hardsect_size(drv->queue, drv->block_size); + blk_queue_hardsect_size(h->queue, drv->block_size); set_capacity(disk, drv->nr_blocks); kfree(size_buff); @@ -2248,12 +2248,12 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) * them up. We will also keep track of the next queue to run so * that every queue gets a chance to be started first. */ - for (j=0; j < h->highest_lun + 1; j++){ - int curr_queue = (start_queue + j) % (h->highest_lun + 1); + for (j=0; j < NWD; j++){ + int curr_queue = (start_queue + j) % NWD; /* make sure the disk has been added and the drive is real * because this can be called from the middle of init_one. */ - if(!(h->drv[curr_queue].queue) || + if(!(h->gendisk[curr_queue]->queue) || !(h->drv[curr_queue].heads)) continue; blk_start_queue(h->gendisk[curr_queue]->queue); @@ -2264,14 +2264,14 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) { if (curr_queue == start_queue){ - h->next_to_run = (start_queue + 1) % (h->highest_lun + 1); + h->next_to_run = (start_queue + 1) % NWD; goto cleanup; } else { h->next_to_run = curr_queue; goto cleanup; } } else { - curr_queue = (curr_queue + 1) % (h->highest_lun + 1); + curr_queue = (curr_queue + 1) % NWD; } } @@ -2279,6 +2279,7 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); return IRQ_HANDLED; } + /* * We cannot read the structure directly, for portablity we must use * the io functions. @@ -2788,6 +2789,13 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, } spin_lock_init(&hba[i]->lock); + q = blk_init_queue(do_cciss_request, &hba[i]->lock); + if (!q) + goto clean4; + + q->backing_dev_info.ra_pages = READ_AHEAD; + hba[i]->queue = q; + q->queuedata = hba[i]; /* Initialize the pdev driver private data. have it point to hba[i]. */ @@ -2809,20 +2817,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, cciss_procinit(i); - for(j=0; j < NWD; j++) { /* mfm */ - drive_info_struct *drv = &(hba[i]->drv[j]); - struct gendisk *disk = hba[i]->gendisk[j]; - - q = blk_init_queue(do_cciss_request, &hba[i]->lock); - if (!q) { - printk(KERN_ERR - "cciss: unable to allocate queue for disk %d\n", - j); - break; - } - drv->queue = q; - - q->backing_dev_info.ra_pages = READ_AHEAD; blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); /* This is a hardware imposed limit. */ @@ -2833,23 +2827,26 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, blk_queue_max_sectors(q, 512); - q->queuedata = hba[i]; + + for(j=0; jdrv[j]); + struct gendisk *disk = hba[i]->gendisk[j]; + sprintf(disk->disk_name, "cciss/c%dd%d", i, j); sprintf(disk->devfs_name, "cciss/host%d/target%d", i, j); disk->major = hba[i]->major; disk->first_minor = j << NWD_SHIFT; disk->fops = &cciss_fops; - disk->queue = q; + disk->queue = hba[i]->queue; disk->private_data = drv; /* we must register the controller even if no disks exist */ /* this is for the online array utilities */ if(!drv->heads && j) continue; - blk_queue_hardsect_size(q, drv->block_size); + blk_queue_hardsect_size(hba[i]->queue, drv->block_size); set_capacity(disk, drv->nr_blocks); add_disk(disk); } - return(1); clean4: @@ -2915,10 +2912,10 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev) for (j = 0; j < NWD; j++) { struct gendisk *disk = hba[i]->gendisk[j]; if (disk->flags & GENHD_FL_UP) - blk_cleanup_queue(disk->queue); del_gendisk(disk); } + blk_cleanup_queue(hba[i]->queue); pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct), diff --git a/trunk/drivers/block/cciss.h b/trunk/drivers/block/cciss.h index 566587d0a500..8fb19206eddb 100644 --- a/trunk/drivers/block/cciss.h +++ b/trunk/drivers/block/cciss.h @@ -29,7 +29,6 @@ typedef struct _drive_info_struct { __u32 LunID; int usage_count; - struct request_queue *queue; sector_t nr_blocks; int block_size; int heads; @@ -73,6 +72,7 @@ struct ctlr_info unsigned int maxQsinceinit; unsigned int maxSG; spinlock_t lock; + struct request_queue *queue; //* pointers to command and error info pool */ CommandList_struct *cmd_pool; @@ -260,7 +260,7 @@ struct board_type { struct access_method *access; }; -#define CCISS_LOCK(i) (&hba[i]->lock) +#define CCISS_LOCK(i) (hba[i]->queue->queue_lock) #endif /* CCISS_H */ diff --git a/trunk/drivers/firmware/pcdp.c b/trunk/drivers/firmware/pcdp.c index ae1fb45dbb40..53c95c0bbf46 100644 --- a/trunk/drivers/firmware/pcdp.c +++ b/trunk/drivers/firmware/pcdp.c @@ -25,22 +25,14 @@ setup_serial_console(struct pcdp_uart *uart) #ifdef CONFIG_SERIAL_8250_CONSOLE int mmio; static char options[64], *p = options; - char parity; mmio = (uart->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY); p += sprintf(p, "console=uart,%s,0x%lx", mmio ? "mmio" : "io", uart->addr.address); - if (uart->baud) { + if (uart->baud) p += sprintf(p, ",%lu", uart->baud); - if (uart->bits) { - switch (uart->parity) { - case 0x2: parity = 'e'; break; - case 0x3: parity = 'o'; break; - default: parity = 'n'; - } - p += sprintf(p, "%c%d", parity, uart->bits); - } - } + if (uart->bits) + p += sprintf(p, "n%d", uart->bits); return early_serial_console_init(options); #else diff --git a/trunk/drivers/ide/legacy/ide-cs.c b/trunk/drivers/ide/legacy/ide-cs.c index 03747439ac9c..aac59751e1b4 100644 --- a/trunk/drivers/ide/legacy/ide-cs.c +++ b/trunk/drivers/ide/legacy/ide-cs.c @@ -465,7 +465,7 @@ static struct pcmcia_device_id ide_ids[] = { PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591), PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4), PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde), - PCMCIA_DEVICE_PROD_ID12("EXP", "CD+GAME", 0x6f58c983, 0x63c13aaf), + PCMCIA_DEVICE_PROD_ID12("EXP", "CD", 0x6f58c983, 0xaae5994f), PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591), PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728), PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e), @@ -481,7 +481,6 @@ static struct pcmcia_device_id ide_ids[] = { PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), - PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), PCMCIA_DEVICE_NULL, }; MODULE_DEVICE_TABLE(pcmcia, ide_ids); diff --git a/trunk/drivers/infiniband/core/ucm.c b/trunk/drivers/infiniband/core/ucm.c index 61d07c732f49..546ec61c407f 100644 --- a/trunk/drivers/infiniband/core/ucm.c +++ b/trunk/drivers/infiniband/core/ucm.c @@ -49,11 +49,6 @@ MODULE_AUTHOR("Libor Michalek"); MODULE_DESCRIPTION("InfiniBand userspace Connection Manager access"); MODULE_LICENSE("Dual BSD/GPL"); -static int ucm_debug_level; - -module_param_named(debug_level, ucm_debug_level, int, 0644); -MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0"); - enum { IB_UCM_MAJOR = 231, IB_UCM_MINOR = 255 @@ -61,14 +56,6 @@ enum { #define IB_UCM_DEV MKDEV(IB_UCM_MAJOR, IB_UCM_MINOR) -#define PFX "UCM: " - -#define ucm_dbg(format, arg...) \ - do { \ - if (ucm_debug_level > 0) \ - printk(KERN_DEBUG PFX format, ## arg); \ - } while (0) - static struct semaphore ctx_id_mutex; static struct idr ctx_id_table; static int ctx_id_rover = 0; @@ -120,7 +107,7 @@ static void ib_ucm_ctx_put(struct ib_ucm_context *ctx) up(&ctx->file->mutex); - ucm_dbg("Destroyed CM ID <%d>\n", ctx->id); + printk(KERN_ERR "UCM: Destroyed CM ID <%d>\n", ctx->id); ib_destroy_cm_id(ctx->cm_id); kfree(ctx); @@ -158,7 +145,7 @@ static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file) if (result) goto error; - ucm_dbg("Allocated CM ID <%d>\n", ctx->id); + printk(KERN_ERR "UCM: Allocated CM ID <%d>\n", ctx->id); return ctx; error: @@ -391,8 +378,10 @@ static int ib_ucm_event_process(struct ib_cm_event *evt, return 0; error: - kfree(uvt->info); - kfree(uvt->data); + if (uvt->info) + kfree(uvt->info); + if (uvt->data) + kfree(uvt->data); return result; } @@ -418,7 +407,8 @@ static int ib_ucm_event_handler(struct ib_cm_id *cm_id, break; } - ucm_dbg("Event. CM ID <%d> event <%d>\n", id, event->event); + printk(KERN_ERR "UCM: Event. CM ID <%d> event <%d>\n", + id, event->event); ctx = ib_ucm_ctx_get(id); if (!ctx) @@ -561,8 +551,10 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file, list_del(&uevent->file_list); list_del(&uevent->ctx_list); - kfree(uevent->data); - kfree(uevent->info); + if (uevent->data) + kfree(uevent->data); + if (uevent->info) + kfree(uevent->info); kfree(uevent); done: up(&file->mutex); @@ -854,9 +846,12 @@ static ssize_t ib_ucm_send_req(struct ib_ucm_file *file, up(&ctx->file->mutex); ib_ucm_ctx_put(ctx); /* func reference */ done: - kfree(param.private_data); - kfree(param.primary_path); - kfree(param.alternate_path); + if (param.private_data) + kfree(param.private_data); + if (param.primary_path) + kfree(param.primary_path); + if (param.alternate_path) + kfree(param.alternate_path); return result; } @@ -905,7 +900,8 @@ static ssize_t ib_ucm_send_rep(struct ib_ucm_file *file, up(&ctx->file->mutex); ib_ucm_ctx_put(ctx); /* func reference */ done: - kfree(param.private_data); + if (param.private_data) + kfree(param.private_data); return result; } @@ -943,7 +939,8 @@ static ssize_t ib_ucm_send_private_data(struct ib_ucm_file *file, up(&ctx->file->mutex); ib_ucm_ctx_put(ctx); /* func reference */ done: - kfree(private_data); + if (private_data) + kfree(private_data); return result; } @@ -1012,8 +1009,10 @@ static ssize_t ib_ucm_send_info(struct ib_ucm_file *file, up(&ctx->file->mutex); ib_ucm_ctx_put(ctx); /* func reference */ done: - kfree(data); - kfree(info); + if (data) + kfree(data); + if (info) + kfree(info); return result; } @@ -1064,7 +1063,8 @@ static ssize_t ib_ucm_send_mra(struct ib_ucm_file *file, up(&ctx->file->mutex); ib_ucm_ctx_put(ctx); /* func reference */ done: - kfree(data); + if (data) + kfree(data); return result; } @@ -1105,8 +1105,10 @@ static ssize_t ib_ucm_send_lap(struct ib_ucm_file *file, up(&ctx->file->mutex); ib_ucm_ctx_put(ctx); /* func reference */ done: - kfree(data); - kfree(path); + if (data) + kfree(data); + if (path) + kfree(path); return result; } @@ -1155,8 +1157,10 @@ static ssize_t ib_ucm_send_sidr_req(struct ib_ucm_file *file, up(&ctx->file->mutex); ib_ucm_ctx_put(ctx); /* func reference */ done: - kfree(param.private_data); - kfree(param.path); + if (param.private_data) + kfree(param.private_data); + if (param.path) + kfree(param.path); return result; } @@ -1205,8 +1209,10 @@ static ssize_t ib_ucm_send_sidr_rep(struct ib_ucm_file *file, up(&ctx->file->mutex); ib_ucm_ctx_put(ctx); /* func reference */ done: - kfree(param.private_data); - kfree(param.info); + if (param.private_data) + kfree(param.private_data); + if (param.info) + kfree(param.info); return result; } @@ -1246,8 +1252,8 @@ static ssize_t ib_ucm_write(struct file *filp, const char __user *buf, if (copy_from_user(&hdr, buf, sizeof(hdr))) return -EFAULT; - ucm_dbg("Write. cmd <%d> in <%d> out <%d> len <%Zu>\n", - hdr.cmd, hdr.in, hdr.out, len); + printk(KERN_ERR "UCM: Write. cmd <%d> in <%d> out <%d> len <%Zu>\n", + hdr.cmd, hdr.in, hdr.out, len); if (hdr.cmd < 0 || hdr.cmd >= ARRAY_SIZE(ucm_cmd_table)) return -EINVAL; @@ -1294,7 +1300,7 @@ static int ib_ucm_open(struct inode *inode, struct file *filp) filp->private_data = file; file->filp = filp; - ucm_dbg("Created struct\n"); + printk(KERN_ERR "UCM: Created struct\n"); return 0; } @@ -1320,7 +1326,7 @@ static int ib_ucm_close(struct inode *inode, struct file *filp) kfree(file); - ucm_dbg("Deleted struct\n"); + printk(KERN_ERR "UCM: Deleted struct\n"); return 0; } @@ -1342,7 +1348,7 @@ static int __init ib_ucm_init(void) result = register_chrdev_region(IB_UCM_DEV, 1, "infiniband_cm"); if (result) { - ucm_dbg("Error <%d> registering dev\n", result); + printk(KERN_ERR "UCM: Error <%d> registering dev\n", result); goto err_chr; } @@ -1350,14 +1356,14 @@ static int __init ib_ucm_init(void) result = cdev_add(&ib_ucm_cdev, IB_UCM_DEV, 1); if (result) { - ucm_dbg("Error <%d> adding cdev\n", result); + printk(KERN_ERR "UCM: Error <%d> adding cdev\n", result); goto err_cdev; } ib_ucm_class = class_create(THIS_MODULE, "infiniband_cm"); if (IS_ERR(ib_ucm_class)) { result = PTR_ERR(ib_ucm_class); - ucm_dbg("Error <%d> creating class\n", result); + printk(KERN_ERR "UCM: Error <%d> creating class\n", result); goto err_class; } diff --git a/trunk/drivers/infiniband/core/uverbs.h b/trunk/drivers/infiniband/core/uverbs.h index 7696022f9a4e..57347f1e82c1 100644 --- a/trunk/drivers/infiniband/core/uverbs.h +++ b/trunk/drivers/infiniband/core/uverbs.h @@ -61,7 +61,6 @@ struct ib_uverbs_event_file { int fd; int is_async; wait_queue_head_t poll_wait; - struct fasync_struct *async_queue; struct list_head event_list; }; diff --git a/trunk/drivers/infiniband/core/uverbs_main.c b/trunk/drivers/infiniband/core/uverbs_main.c index eb99e693dec2..fbbe03d8c901 100644 --- a/trunk/drivers/infiniband/core/uverbs_main.c +++ b/trunk/drivers/infiniband/core/uverbs_main.c @@ -257,19 +257,11 @@ static void ib_uverbs_event_release(struct ib_uverbs_event_file *file) spin_unlock_irq(&file->lock); } -static int ib_uverbs_event_fasync(int fd, struct file *filp, int on) -{ - struct ib_uverbs_event_file *file = filp->private_data; - - return fasync_helper(fd, filp, on, &file->async_queue); -} - static int ib_uverbs_event_close(struct inode *inode, struct file *filp) { struct ib_uverbs_event_file *file = filp->private_data; ib_uverbs_event_release(file); - ib_uverbs_event_fasync(-1, filp, 0); kref_put(&file->uverbs_file->ref, ib_uverbs_release_file); return 0; @@ -284,8 +276,7 @@ static struct file_operations uverbs_event_fops = { */ .read = ib_uverbs_event_read, .poll = ib_uverbs_event_poll, - .release = ib_uverbs_event_close, - .fasync = ib_uverbs_event_fasync + .release = ib_uverbs_event_close }; void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) @@ -305,7 +296,6 @@ void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) spin_unlock_irqrestore(&file->comp_file[0].lock, flags); wake_up_interruptible(&file->comp_file[0].poll_wait); - kill_fasync(&file->comp_file[0].async_queue, SIGIO, POLL_IN); } static void ib_uverbs_async_handler(struct ib_uverbs_file *file, @@ -326,7 +316,6 @@ static void ib_uverbs_async_handler(struct ib_uverbs_file *file, spin_unlock_irqrestore(&file->async_file.lock, flags); wake_up_interruptible(&file->async_file.poll_wait); - kill_fasync(&file->async_file.async_queue, SIGIO, POLL_IN); } void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr) @@ -361,7 +350,6 @@ static int ib_uverbs_event_init(struct ib_uverbs_event_file *file, INIT_LIST_HEAD(&file->event_list); init_waitqueue_head(&file->poll_wait); file->uverbs_file = uverbs_file; - file->async_queue = NULL; file->fd = get_unused_fd(); if (file->fd < 0) diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c index 5687c3014522..b5aea7b869f6 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c @@ -373,12 +373,8 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq, * If we're at the end of the WQE chain, or we've used up our * doorbell count, free the CQE. Otherwise just update it for * the next poll operation. - * - * This does not apply to mem-free HCAs: they don't use the - * doorbell count field, and so we should always free the CQE. */ - if (mthca_is_memfree(dev) || - !(new_wqe & cpu_to_be32(0x3f)) || (!cqe->db_cnt && dbd)) + if (!(new_wqe & cpu_to_be32(0x3f)) || (!cqe->db_cnt && dbd)) return 0; cqe->db_cnt = cpu_to_be16(be16_to_cpu(cqe->db_cnt) - dbd); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_provider.c b/trunk/drivers/infiniband/hw/mthca/mthca_provider.c index 81919a7b4935..7a58ce90e179 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_provider.c @@ -349,9 +349,9 @@ static int mthca_mmap_uar(struct ib_ucontext *context, vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - if (io_remap_pfn_range(vma, vma->vm_start, - to_mucontext(context)->uar.pfn, - PAGE_SIZE, vma->vm_page_prot)) + if (remap_pfn_range(vma, vma->vm_start, + to_mucontext(context)->uar.pfn, + PAGE_SIZE, vma->vm_page_prot)) return -EAGAIN; return 0; diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c index eee82363167d..8238766746b2 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -81,7 +81,7 @@ void ipoib_free_ah(struct kref *kref) unsigned long flags; - if ((int) priv->tx_tail - (int) ah->last_send >= 0) { + if (ah->last_send <= priv->tx_tail) { ipoib_dbg(priv, "Freeing ah %p\n", ah->ah); ib_destroy_ah(ah->ah); kfree(ah); @@ -355,7 +355,7 @@ static void __ipoib_reap_ah(struct net_device *dev) spin_lock_irq(&priv->lock); list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list) - if ((int) priv->tx_tail - (int) ah->last_send >= 0) { + if (ah->last_send <= priv->tx_tail) { list_del(&ah->list); list_add_tail(&ah->list, &remove_list); } @@ -486,7 +486,7 @@ int ipoib_ib_dev_stop(struct net_device *dev) * assume the HW is wedged and just free up * all our pending work requests. */ - while ((int) priv->tx_tail - (int) priv->tx_head < 0) { + while (priv->tx_tail < priv->tx_head) { tx_req = &priv->tx_ring[priv->tx_tail & (IPOIB_TX_RING_SIZE - 1)]; dma_unmap_single(priv->ca->dma_device, diff --git a/trunk/drivers/md/dm-table.c b/trunk/drivers/md/dm-table.c index a6d3baa46f61..a5a4c0ed8a14 100644 --- a/trunk/drivers/md/dm-table.c +++ b/trunk/drivers/md/dm-table.c @@ -869,17 +869,11 @@ static void suspend_targets(struct dm_table *t, unsigned postsuspend) void dm_table_presuspend_targets(struct dm_table *t) { - if (!t) - return; - return suspend_targets(t, 0); } void dm_table_postsuspend_targets(struct dm_table *t) { - if (!t) - return; - return suspend_targets(t, 1); } diff --git a/trunk/drivers/md/dm.c b/trunk/drivers/md/dm.c index d487d9deb98e..54fabbf06678 100644 --- a/trunk/drivers/md/dm.c +++ b/trunk/drivers/md/dm.c @@ -55,10 +55,10 @@ union map_info *dm_get_mapinfo(struct bio *bio) */ #define DMF_BLOCK_IO 0 #define DMF_SUSPENDED 1 +#define DMF_FS_LOCKED 2 struct mapped_device { - struct rw_semaphore io_lock; - struct semaphore suspend_lock; + struct rw_semaphore lock; rwlock_t map_lock; atomic_t holders; @@ -248,16 +248,16 @@ static inline void free_tio(struct mapped_device *md, struct target_io *tio) */ static int queue_io(struct mapped_device *md, struct bio *bio) { - down_write(&md->io_lock); + down_write(&md->lock); if (!test_bit(DMF_BLOCK_IO, &md->flags)) { - up_write(&md->io_lock); + up_write(&md->lock); return 1; } bio_list_add(&md->deferred, bio); - up_write(&md->io_lock); + up_write(&md->lock); return 0; /* deferred successfully */ } @@ -568,14 +568,14 @@ static int dm_request(request_queue_t *q, struct bio *bio) int r; struct mapped_device *md = q->queuedata; - down_read(&md->io_lock); + down_read(&md->lock); /* * If we're suspended we have to queue * this io for later. */ while (test_bit(DMF_BLOCK_IO, &md->flags)) { - up_read(&md->io_lock); + up_read(&md->lock); if (bio_rw(bio) == READA) { bio_io_error(bio, bio->bi_size); @@ -594,11 +594,11 @@ static int dm_request(request_queue_t *q, struct bio *bio) * We're in a while loop, because someone could suspend * before we get to the following read lock. */ - down_read(&md->io_lock); + down_read(&md->lock); } __split_bio(md, bio); - up_read(&md->io_lock); + up_read(&md->lock); return 0; } @@ -610,7 +610,7 @@ static int dm_flush_all(request_queue_t *q, struct gendisk *disk, int ret = -ENXIO; if (map) { - ret = dm_table_flush_all(map); + ret = dm_table_flush_all(md->map); dm_table_put(map); } @@ -747,8 +747,7 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent) goto bad1; memset(md, 0, sizeof(*md)); - init_rwsem(&md->io_lock); - init_MUTEX(&md->suspend_lock); + init_rwsem(&md->lock); rwlock_init(&md->map_lock); atomic_set(&md->holders, 1); atomic_set(&md->event_nr, 0); @@ -826,13 +825,18 @@ static void event_callback(void *context) wake_up(&md->eventq); } -static void __set_size(struct mapped_device *md, sector_t size) +static void __set_size(struct gendisk *disk, sector_t size) { - set_capacity(md->disk, size); - - down(&md->frozen_bdev->bd_inode->i_sem); - i_size_write(md->frozen_bdev->bd_inode, (loff_t)size << SECTOR_SHIFT); - up(&md->frozen_bdev->bd_inode->i_sem); + struct block_device *bdev; + + set_capacity(disk, size); + bdev = bdget_disk(disk, 0); + if (bdev) { + down(&bdev->bd_inode->i_sem); + i_size_write(bdev->bd_inode, (loff_t)size << SECTOR_SHIFT); + up(&bdev->bd_inode->i_sem); + bdput(bdev); + } } static int __bind(struct mapped_device *md, struct dm_table *t) @@ -841,18 +845,17 @@ static int __bind(struct mapped_device *md, struct dm_table *t) sector_t size; size = dm_table_get_size(t); - __set_size(md, size); + __set_size(md->disk, size); if (size == 0) return 0; - dm_table_get(t); - dm_table_event_callback(t, event_callback, md); - write_lock(&md->map_lock); md->map = t; - dm_table_set_restrictions(t, q); write_unlock(&md->map_lock); + dm_table_get(t); + dm_table_event_callback(md->map, event_callback, md); + dm_table_set_restrictions(t, q); return 0; } @@ -932,7 +935,7 @@ void dm_put(struct mapped_device *md) struct dm_table *map = dm_get_table(md); if (atomic_dec_and_test(&md->holders)) { - if (!dm_suspended(md)) { + if (!test_bit(DMF_SUSPENDED, &md->flags) && map) { dm_table_presuspend_targets(map); dm_table_postsuspend_targets(map); } @@ -965,17 +968,17 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table) { int r = -EINVAL; - down(&md->suspend_lock); + down_write(&md->lock); /* device must be suspended */ - if (!dm_suspended(md)) + if (!test_bit(DMF_SUSPENDED, &md->flags)) goto out; __unbind(md); r = __bind(md, table); out: - up(&md->suspend_lock); + up_write(&md->lock); return r; } @@ -983,13 +986,16 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table) * Functions to lock and unlock any filesystem running on the * device. */ -static int lock_fs(struct mapped_device *md) +static int __lock_fs(struct mapped_device *md) { - int r = -ENOMEM; + int error = -ENOMEM; + + if (test_and_set_bit(DMF_FS_LOCKED, &md->flags)) + return 0; md->frozen_bdev = bdget_disk(md->disk, 0); if (!md->frozen_bdev) { - DMWARN("bdget failed in lock_fs"); + DMWARN("bdget failed in __lock_fs"); goto out; } @@ -997,13 +1003,13 @@ static int lock_fs(struct mapped_device *md) md->frozen_sb = freeze_bdev(md->frozen_bdev); if (IS_ERR(md->frozen_sb)) { - r = PTR_ERR(md->frozen_sb); + error = PTR_ERR(md->frozen_sb); goto out_bdput; } /* don't bdput right now, we don't want the bdev * to go away while it is locked. We'll bdput - * in unlock_fs + * in __unlock_fs */ return 0; @@ -1012,11 +1018,15 @@ static int lock_fs(struct mapped_device *md) md->frozen_sb = NULL; md->frozen_bdev = NULL; out: - return r; + clear_bit(DMF_FS_LOCKED, &md->flags); + return error; } -static void unlock_fs(struct mapped_device *md) +static void __unlock_fs(struct mapped_device *md) { + if (!test_and_clear_bit(DMF_FS_LOCKED, &md->flags)) + return; + thaw_bdev(md->frozen_bdev, md->frozen_sb); bdput(md->frozen_bdev); @@ -1033,37 +1043,50 @@ static void unlock_fs(struct mapped_device *md) */ int dm_suspend(struct mapped_device *md) { - struct dm_table *map = NULL; + struct dm_table *map; DECLARE_WAITQUEUE(wait, current); - int r = -EINVAL; - - down(&md->suspend_lock); + int error = -EINVAL; - if (dm_suspended(md)) - goto out; + /* Flush I/O to the device. */ + down_read(&md->lock); + if (test_bit(DMF_BLOCK_IO, &md->flags)) + goto out_read_unlock; map = dm_get_table(md); + if (map) + /* This does not get reverted if there's an error later. */ + dm_table_presuspend_targets(map); - /* This does not get reverted if there's an error later. */ - dm_table_presuspend_targets(map); + error = __lock_fs(md); + if (error) { + dm_table_put(map); + goto out_read_unlock; + } - /* Flush I/O to the device. */ - r = lock_fs(md); - if (r) - goto out; + up_read(&md->lock); /* * First we set the BLOCK_IO flag so no more ios will be mapped. + * + * If the flag is already set we know another thread is trying to + * suspend as well, so we leave the fs locked for this thread. */ - down_write(&md->io_lock); - set_bit(DMF_BLOCK_IO, &md->flags); + error = -EINVAL; + down_write(&md->lock); + if (test_and_set_bit(DMF_BLOCK_IO, &md->flags)) { + if (map) + dm_table_put(map); + goto out_write_unlock; + } add_wait_queue(&md->wait, &wait); - up_write(&md->io_lock); + up_write(&md->lock); /* unplug */ - if (map) + if (map) { dm_table_unplug_all(map); + dm_table_put(map); + } /* * Then we wait for the already mapped ios to @@ -1079,67 +1102,62 @@ int dm_suspend(struct mapped_device *md) } set_current_state(TASK_RUNNING); - down_write(&md->io_lock); + down_write(&md->lock); remove_wait_queue(&md->wait, &wait); /* were we interrupted ? */ - r = -EINTR; - if (atomic_read(&md->pending)) { - up_write(&md->io_lock); - unlock_fs(md); - clear_bit(DMF_BLOCK_IO, &md->flags); - goto out; - } - up_write(&md->io_lock); - - dm_table_postsuspend_targets(map); + error = -EINTR; + if (atomic_read(&md->pending)) + goto out_unfreeze; set_bit(DMF_SUSPENDED, &md->flags); - r = 0; - -out: + map = dm_get_table(md); + if (map) + dm_table_postsuspend_targets(map); dm_table_put(map); - up(&md->suspend_lock); - return r; + up_write(&md->lock); + + return 0; + +out_unfreeze: + __unlock_fs(md); + clear_bit(DMF_BLOCK_IO, &md->flags); +out_write_unlock: + up_write(&md->lock); + return error; + +out_read_unlock: + up_read(&md->lock); + return error; } int dm_resume(struct mapped_device *md) { - int r = -EINVAL; struct bio *def; - struct dm_table *map = NULL; - - down(&md->suspend_lock); - if (!dm_suspended(md)) - goto out; + struct dm_table *map = dm_get_table(md); - map = dm_get_table(md); - if (!map || !dm_table_get_size(map)) - goto out; + down_write(&md->lock); + if (!map || + !test_bit(DMF_SUSPENDED, &md->flags) || + !dm_table_get_size(map)) { + up_write(&md->lock); + dm_table_put(map); + return -EINVAL; + } dm_table_resume_targets(map); - - down_write(&md->io_lock); + clear_bit(DMF_SUSPENDED, &md->flags); clear_bit(DMF_BLOCK_IO, &md->flags); def = bio_list_get(&md->deferred); __flush_deferred_io(md, def); - up_write(&md->io_lock); - - unlock_fs(md); - - clear_bit(DMF_SUSPENDED, &md->flags); - + up_write(&md->lock); + __unlock_fs(md); dm_table_unplug_all(map); - - r = 0; - -out: dm_table_put(map); - up(&md->suspend_lock); - return r; + return 0; } /*----------------------------------------------------------------- diff --git a/trunk/drivers/net/cs89x0.c b/trunk/drivers/net/cs89x0.c index 2c6dc24c3728..b96d6fb1929e 100644 --- a/trunk/drivers/net/cs89x0.c +++ b/trunk/drivers/net/cs89x0.c @@ -1450,7 +1450,6 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) /* Write the contents of the packet */ outsw(dev->base_addr + TX_FRAME_PORT,skb->data,(skb->len+1) >>1); spin_unlock_irq(&lp->lock); - lp->stats.tx_bytes += skb->len; dev->trans_start = jiffies; dev_kfree_skb (skb); diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index 5e5d2c3c7ce4..cb7f051a60ad 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -162,6 +162,7 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid); static void e1000_restore_vlan(struct e1000_adapter *adapter); +static int e1000_notify_reboot(struct notifier_block *, unsigned long event, void *ptr); static int e1000_suspend(struct pci_dev *pdev, uint32_t state); #ifdef CONFIG_PM static int e1000_resume(struct pci_dev *pdev); @@ -172,6 +173,12 @@ static int e1000_resume(struct pci_dev *pdev); static void e1000_netpoll (struct net_device *netdev); #endif +struct notifier_block e1000_notifier_reboot = { + .notifier_call = e1000_notify_reboot, + .next = NULL, + .priority = 0 +}; + /* Exported from other modules */ extern void e1000_check_options(struct e1000_adapter *adapter); @@ -214,7 +221,9 @@ e1000_init_module(void) printk(KERN_INFO "%s\n", e1000_copyright); ret = pci_module_init(&e1000_driver); - + if(ret >= 0) { + register_reboot_notifier(&e1000_notifier_reboot); + } return ret; } @@ -230,6 +239,7 @@ module_init(e1000_init_module); static void __exit e1000_exit_module(void) { + unregister_reboot_notifier(&e1000_notifier_reboot); pci_unregister_driver(&e1000_driver); } @@ -3641,6 +3651,23 @@ e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx) return 0; } +static int +e1000_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) +{ + struct pci_dev *pdev = NULL; + + switch(event) { + case SYS_DOWN: + case SYS_HALT: + case SYS_POWER_OFF: + while((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) { + if(pci_dev_driver(pdev) == &e1000_driver) + e1000_suspend(pdev, 3); + } + } + return NOTIFY_DONE; +} + static int e1000_suspend(struct pci_dev *pdev, uint32_t state) { diff --git a/trunk/drivers/net/pcmcia/nmclan_cs.c b/trunk/drivers/net/pcmcia/nmclan_cs.c index 980d7e5d66cb..dbb941004ae9 100644 --- a/trunk/drivers/net/pcmcia/nmclan_cs.c +++ b/trunk/drivers/net/pcmcia/nmclan_cs.c @@ -1671,7 +1671,7 @@ static void set_multicast_list(struct net_device *dev) static struct pcmcia_device_id nmclan_ids[] = { PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "Ethernet", 0x085a850b, 0x00b2e941), - PCMCIA_DEVICE_PROD_ID12("Portable Add-ons", "Ethernet+", 0xebf1d60, 0xad673aaf), + PCMCIA_DEVICE_PROD_ID12("Portable Add-ons", "Ethernet", 0x0ebf1d60, 0x00b2e941), PCMCIA_DEVICE_NULL, }; MODULE_DEVICE_TABLE(pcmcia, nmclan_ids); diff --git a/trunk/drivers/net/pcmcia/pcnet_cs.c b/trunk/drivers/net/pcmcia/pcnet_cs.c index 9f22d138e3ad..e1664aef3dfd 100644 --- a/trunk/drivers/net/pcmcia/pcnet_cs.c +++ b/trunk/drivers/net/pcmcia/pcnet_cs.c @@ -1639,7 +1639,7 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0143, 0xc0ab), PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x021b, 0x0101), PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x08a1, 0xc0ab), - PCMCIA_PFC_DEVICE_PROD_ID12(0, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4), + PCMCIA_PFC_DEVICE_PROD_ID12(0, "AnyCom", "Fast Ethernet ", 0x578ba6e7, 0x02d92d1e), PCMCIA_PFC_DEVICE_PROD_ID12(0, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), @@ -1683,6 +1683,7 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_PROD_ID12("ACCTON", "EN2212", 0xdfc6b5b2, 0xcb112a11), PCMCIA_DEVICE_PROD_ID12("ACCTON", "EN2216-PCMCIA-ETHERNET", 0xdfc6b5b2, 0x5542bfff), PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA100-PCM-T V2 100/10M LAN PC Card", 0xbb7fbdd7, 0xcd91cc68), + PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA-PCM", 0xbb7fbdd7, 0x5ba10d49), PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA100-PCM V2", 0x36634a66, 0xc6d05997), PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA-PCM_V2", 0xbb7fBdd7, 0x28e299f8), PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA-PCM V3", 0x36634a66, 0x62241d96), @@ -1718,7 +1719,6 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_PROD_ID12("DIGITAL", "DEPCM-XX", 0x69616cb3, 0xe600e76e), PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-650", 0x1a424a1c, 0xf28c8398), PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-660", 0x1a424a1c, 0xd9a1d05b), - PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-660+", 0x1a424a1c, 0x50dcd0ec), PCMCIA_DEVICE_PROD_ID12("D-Link", "DFE-650", 0x1a424a1c, 0x0f0073f9), PCMCIA_DEVICE_PROD_ID12("Dual Speed", "10/100 PC Card", 0x725b842d, 0xf1efee84), PCMCIA_DEVICE_PROD_ID12("Dual Speed", "10/100 Port Attached PC Card", 0x725b842d, 0x2db1f8e9), @@ -1737,7 +1737,6 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_PROD_ID12("GVC", "NIC-2000p", 0x76e171bd, 0x6eb1c947), PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "Ethernet", 0xe3736c88, 0x00b2e941), PCMCIA_DEVICE_PROD_ID12("IC-CARD", "IC-CARD", 0x60cb09a6, 0x60cb09a6), - PCMCIA_DEVICE_PROD_ID12("IC-CARD+", "IC-CARD+", 0x93693494, 0x93693494), PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCETTX", 0x547e66dc, 0x6fc5459b), PCMCIA_DEVICE_PROD_ID12("iPort", "10/100 Ethernet Card", 0x56c538d2, 0x11b0ffc0), PCMCIA_DEVICE_PROD_ID12("KANSAI ELECTRIC CO.,LTD", "KLA-PCM/T", 0xb18dc3b4, 0xcc51a956), @@ -1754,7 +1753,7 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 Integrated PC Card (PCM100)", 0x0733cc81, 0x453c3f9d), PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100)", 0x0733cc81, 0x66c5a389), PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V2)", 0x0733cc81, 0x3a3b28e9), - PCMCIA_DEVICE_PROD_ID12("Linksys", "HomeLink Phoneline + 10/100 Network PC Card (PCM100H1)", 0x733cc81, 0x7a3e5c3a), + PCMCIA_DEVICE_PROD_ID12("Linksys", "HomeLink Phoneline ", 0x0733cc81, 0x5e07cfa0), PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN100TX", 0x88fcdeda, 0x6d772737), PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN20T", 0x88fcdeda, 0x81090922), PCMCIA_DEVICE_PROD_ID12("LONGSHINE", "PCMCIA Ethernet Card", 0xf866b0b0, 0x6f6652e0), diff --git a/trunk/drivers/net/pcmcia/smc91c92_cs.c b/trunk/drivers/net/pcmcia/smc91c92_cs.c index d652e1eddb45..0d8bb4cccbb7 100644 --- a/trunk/drivers/net/pcmcia/smc91c92_cs.c +++ b/trunk/drivers/net/pcmcia/smc91c92_cs.c @@ -2332,8 +2332,8 @@ static struct pcmcia_device_id smc91c92_ids[] = { PCMCIA_PFC_DEVICE_PROD_ID123(0, "MEGAHERTZ", "XJEM1144/CCEM1144", "PCMCIA MODEM", 0xf510db04, 0x52d21e1e, 0xbd6c43ef), PCMCIA_PFC_DEVICE_PROD_ID12(0, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c), PCMCIA_PFC_DEVICE_PROD_ID12(0, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e), - PCMCIA_PFC_DEVICE_PROD_ID12(0, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9), - PCMCIA_PFC_DEVICE_PROD_ID12(0, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed), + PCMCIA_PFC_DEVICE_PROD_ID12(0, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), + PCMCIA_PFC_DEVICE_PROD_ID12(0, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x016c, 0x0020), PCMCIA_DEVICE_MANF_CARD(0x016c, 0x0023), PCMCIA_DEVICE_PROD_ID123("BASICS by New Media Corporation", "Ethernet", "SMC91C94", 0x23c78a9d, 0x00b2e941, 0xcef397fb), @@ -2343,8 +2343,8 @@ static struct pcmcia_device_id smc91c92_ids[] = { PCMCIA_DEVICE_PROD_ID12("Farallon", "Farallon Enet", 0x58d93fc4, 0x244734e9), PCMCIA_DEVICE_PROD_ID12("Megahertz", "CC10BT/2", 0x33234748, 0x3c95b953), PCMCIA_DEVICE_PROD_ID12("MELCO/SMC", "LPC-TX", 0xa2cd8e6d, 0x42da662a), - PCMCIA_DEVICE_PROD_ID12("Ositech", "Trumpcard:Four of Diamonds Ethernet", 0xc2f80cd, 0xb3466314), - PCMCIA_DEVICE_PROD_ID12("Ositech", "Trumpcard:Seven of Diamonds Ethernet", 0xc2f80cd, 0x194b650a), + PCMCIA_DEVICE_PROD_ID12("Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), + PCMCIA_DEVICE_PROD_ID12("Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Fast Ethernet PCCard", 0x281f1c5d, 0xdcea68bc), PCMCIA_DEVICE_PROD_ID12("Psion", "10Mb Ethernet", 0x4ef00b21, 0x844be9e9), PCMCIA_DEVICE_PROD_ID12("SMC", "EtherEZ Ethernet 8020", 0xc4f8b18b, 0x4a0eeb2d), diff --git a/trunk/drivers/net/pcmcia/xirc2ps_cs.c b/trunk/drivers/net/pcmcia/xirc2ps_cs.c index ce143f08638a..9f33bad174e9 100644 --- a/trunk/drivers/net/pcmcia/xirc2ps_cs.c +++ b/trunk/drivers/net/pcmcia/xirc2ps_cs.c @@ -1985,7 +1985,7 @@ static struct pcmcia_device_id xirc2ps_ids[] = { PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a), PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29), PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719), - PCMCIA_PFC_DEVICE_PROD_ID12(0, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf), + PCMCIA_PFC_DEVICE_PROD_ID12(0, "Xircom", "CreditCard Ethernet", 0x2e3ee845, 0xc0e778c2), PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x010a), PCMCIA_DEVICE_PROD_ID13("Toshiba Information Systems", "TPCENET", 0x1b3b94fe, 0xf381c1a2), PCMCIA_DEVICE_PROD_ID13("Xircom", "CE3-10/100", 0x2e3ee845, 0x0ec0ac37), diff --git a/trunk/drivers/net/wireless/orinoco_cs.c b/trunk/drivers/net/wireless/orinoco_cs.c index 1cc1492083c9..368d2f962f67 100644 --- a/trunk/drivers/net/wireless/orinoco_cs.c +++ b/trunk/drivers/net/wireless/orinoco_cs.c @@ -621,6 +621,8 @@ static struct pcmcia_device_id orinoco_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), + PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), + PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3), PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0), diff --git a/trunk/drivers/pcmcia/au1000_generic.c b/trunk/drivers/pcmcia/au1000_generic.c index 470ef756252e..0a5c95807cf2 100644 --- a/trunk/drivers/pcmcia/au1000_generic.c +++ b/trunk/drivers/pcmcia/au1000_generic.c @@ -388,7 +388,6 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i); memset(skt, 0, sizeof(*skt)); - skt->socket.resource_ops = &pccard_static_ops; skt->socket.ops = &au1x00_pcmcia_operations; skt->socket.owner = ops->owner; skt->socket.dev.dev = dev; diff --git a/trunk/drivers/pcmcia/cistpl.c b/trunk/drivers/pcmcia/cistpl.c index 3afb682255a0..dd7651ff5b43 100644 --- a/trunk/drivers/pcmcia/cistpl.c +++ b/trunk/drivers/pcmcia/cistpl.c @@ -88,38 +88,31 @@ EXPORT_SYMBOL(release_cis_mem); static void __iomem * set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags) { - pccard_mem_map *mem = &s->cis_mem; - int ret; - - if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) { - mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s); - if (mem->res == NULL) { - printk(KERN_NOTICE "cs: unable to map card memory!\n"); - return NULL; - } - s->cis_virt = NULL; - } - - if (!(s->features & SS_CAP_STATIC_MAP) && (!s->cis_virt)) - s->cis_virt = ioremap(mem->res->start, s->map_size); - - mem->card_start = card_offset; - mem->flags = flags; - - ret = s->ops->set_mem_map(s, mem); - if (ret) { - iounmap(s->cis_virt); - s->cis_virt = NULL; - return NULL; - } + pccard_mem_map *mem = &s->cis_mem; + int ret; - if (s->features & SS_CAP_STATIC_MAP) { - if (s->cis_virt) - iounmap(s->cis_virt); - s->cis_virt = ioremap(mem->static_start, s->map_size); + if (!(s->features & SS_CAP_STATIC_MAP) && mem->res == NULL) { + mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s); + if (mem->res == NULL) { + printk(KERN_NOTICE "cs: unable to map card memory!\n"); + return NULL; } + s->cis_virt = ioremap(mem->res->start, s->map_size); + } + mem->card_start = card_offset; + mem->flags = flags; + ret = s->ops->set_mem_map(s, mem); + if (ret) { + iounmap(s->cis_virt); + return NULL; + } - return s->cis_virt; + if (s->features & SS_CAP_STATIC_MAP) { + if (s->cis_virt) + iounmap(s->cis_virt); + s->cis_virt = ioremap(mem->static_start, s->map_size); + } + return s->cis_virt; } /*====================================================================== diff --git a/trunk/drivers/pcmcia/ds.c b/trunk/drivers/pcmcia/ds.c index d63f22a5bf7e..3e3c6f12bbe6 100644 --- a/trunk/drivers/pcmcia/ds.c +++ b/trunk/drivers/pcmcia/ds.c @@ -206,8 +206,8 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv) u32 hash; if (!p_drv->attach || !p_drv->event || !p_drv->detach) - printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback " - "function\n", p_drv->drv.name); + printk(KERN_DEBUG "pcmcia: %s does misses a callback function", + p_drv->drv.name); while (did && did->match_flags) { for (i=0; i<4; i++) { diff --git a/trunk/drivers/pcmcia/o2micro.h b/trunk/drivers/pcmcia/o2micro.h index a234ce1967a3..b1f6e3d9ee06 100644 --- a/trunk/drivers/pcmcia/o2micro.h +++ b/trunk/drivers/pcmcia/o2micro.h @@ -120,16 +120,11 @@ #define O2_MODE_E_LED_OUT 0x08 #define O2_MODE_E_SKTA_ACTV 0x10 -#define O2_RESERVED1 0x94 -#define O2_RESERVED2 0xD4 -#define O2_RES_READ_PREFETCH 0x02 -#define O2_RES_WRITE_BURST 0x08 - static int o2micro_override(struct yenta_socket *socket) { /* - * 'reserved' register at 0x94/D4. allows setting read prefetch and write - * bursting. read prefetching for example makes the RME Hammerfall DSP + * 'reserved' register at 0x94/D4. chaning it to 0xCA (8 bit) enables + * read prefetching which for example makes the RME Hammerfall DSP * working. for some bridges it is at 0x94, for others at 0xD4. it's * ok to write to both registers on all O2 bridges. * from Eric Still, 02Micro. @@ -137,35 +132,20 @@ static int o2micro_override(struct yenta_socket *socket) u8 a, b; if (PCI_FUNC(socket->dev->devfn) == 0) { - a = config_readb(socket, O2_RESERVED1); - b = config_readb(socket, O2_RESERVED2); + a = config_readb(socket, 0x94); + b = config_readb(socket, 0xD4); printk(KERN_INFO "Yenta O2: res at 0x94/0xD4: %02x/%02x\n", a, b); switch (socket->dev->device) { - /* - * older bridges have problems with both read prefetch and write - * bursting depending on the combination of the chipset, bridge - * and the cardbus card. so disable them to be on the safe side. - */ - case PCI_DEVICE_ID_O2_6729: - case PCI_DEVICE_ID_O2_6730: - case PCI_DEVICE_ID_O2_6812: case PCI_DEVICE_ID_O2_6832: - case PCI_DEVICE_ID_O2_6836: - printk(KERN_INFO "Yenta O2: old bridge, disabling read prefetch/write burst\n"); - config_writeb(socket, O2_RESERVED1, - a & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST)); - config_writeb(socket, O2_RESERVED2, - b & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST)); + printk(KERN_INFO "Yenta O2: old bridge, not enabling read prefetch / write burst\n"); break; default: printk(KERN_INFO "Yenta O2: enabling read prefetch/write burst\n"); - config_writeb(socket, O2_RESERVED1, - a | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST); - config_writeb(socket, O2_RESERVED2, - b | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST); + config_writeb(socket, 0x94, a | 0x0a); + config_writeb(socket, 0xD4, b | 0x0a); } } diff --git a/trunk/drivers/pcmcia/pcmcia_resource.c b/trunk/drivers/pcmcia/pcmcia_resource.c index 6f9fdb276402..184f4f88b2a0 100644 --- a/trunk/drivers/pcmcia/pcmcia_resource.c +++ b/trunk/drivers/pcmcia/pcmcia_resource.c @@ -800,7 +800,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) } else { int try; u32 mask = s->irq_mask; - void *data = &p_dev->dev.driver; /* something unique to this device */ + void *data = NULL; for (try = 0; try < 64; try++) { irq = try % 32; diff --git a/trunk/drivers/pcmcia/yenta_socket.c b/trunk/drivers/pcmcia/yenta_socket.c index 744e469a9eda..6837491f021c 100644 --- a/trunk/drivers/pcmcia/yenta_socket.c +++ b/trunk/drivers/pcmcia/yenta_socket.c @@ -1107,8 +1107,6 @@ static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state) pci_read_config_dword(dev, 17*4, &socket->saved_state[1]); pci_disable_device(dev); - free_irq(dev->irq, socket); - /* * Some laptops (IBM T22) do not like us putting the Cardbus * bridge into D3. At a guess, some other laptop will @@ -1134,13 +1132,6 @@ static int yenta_dev_resume (struct pci_dev *dev) pci_enable_device(dev); pci_set_master(dev); - if (socket->cb_irq) - if (request_irq(socket->cb_irq, yenta_interrupt, - SA_SHIRQ, "yenta", socket)) { - printk(KERN_WARNING "Yenta: request_irq() failed on resume!\n"); - socket->cb_irq = 0; - } - if (socket->type && socket->type->restore_state) socket->type->restore_state(socket); } diff --git a/trunk/drivers/scsi/ata_piix.c b/trunk/drivers/scsi/ata_piix.c index a2cfade2c1c6..3be546439252 100644 --- a/trunk/drivers/scsi/ata_piix.c +++ b/trunk/drivers/scsi/ata_piix.c @@ -38,7 +38,6 @@ enum { PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ ICH5_PMR = 0x90, /* port mapping register */ ICH5_PCS = 0x92, /* port control and status */ - PIIX_SCC = 0x0A, /* sub-class code register */ PIIX_FLAG_AHCI = (1 << 28), /* AHCI possible */ PIIX_FLAG_CHECKINTR = (1 << 29), /* make sure PCI INTx enabled */ @@ -63,8 +62,6 @@ enum { ich6_sata_rm = 4, ich7_sata = 5, esb2_sata = 6, - - PIIX_AHCI_DEVICE = 6, }; static int piix_init_one (struct pci_dev *pdev, @@ -577,11 +574,11 @@ static int piix_disable_ahci(struct pci_dev *pdev) addr = pci_resource_start(pdev, AHCI_PCI_BAR); if (!addr || !pci_resource_len(pdev, AHCI_PCI_BAR)) return 0; - + mmio = ioremap(addr, 64); if (!mmio) return -ENOMEM; - + tmp = readl(mmio + AHCI_GLOBAL_CTL); if (tmp & AHCI_ENABLE) { tmp &= ~AHCI_ENABLE; @@ -591,7 +588,7 @@ static int piix_disable_ahci(struct pci_dev *pdev) if (tmp & AHCI_ENABLE) rc = -EIO; } - + iounmap(mmio); return rc; } @@ -629,13 +626,9 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) port_info[1] = NULL; if (port_info[0]->host_flags & PIIX_FLAG_AHCI) { - u8 tmp; - pci_read_config_byte(pdev, PIIX_SCC, &tmp); - if (tmp == PIIX_AHCI_DEVICE) { - int rc = piix_disable_ahci(pdev); - if (rc) - return rc; - } + int rc = piix_disable_ahci(pdev); + if (rc) + return rc; } if (port_info[0]->host_flags & PIIX_FLAG_COMBINED) { diff --git a/trunk/drivers/scsi/qla2xxx/Kconfig b/trunk/drivers/scsi/qla2xxx/Kconfig index c1c1c687bcbd..6c73b84c6e64 100644 --- a/trunk/drivers/scsi/qla2xxx/Kconfig +++ b/trunk/drivers/scsi/qla2xxx/Kconfig @@ -7,7 +7,6 @@ config SCSI_QLA21XX tristate "QLogic ISP2100 host adapter family support" depends on SCSI_QLA2XXX select SCSI_FC_ATTRS - select FW_LOADER ---help--- This driver supports the QLogic 21xx (ISP2100) host adapter family. @@ -15,7 +14,6 @@ config SCSI_QLA22XX tristate "QLogic ISP2200 host adapter family support" depends on SCSI_QLA2XXX select SCSI_FC_ATTRS - select FW_LOADER ---help--- This driver supports the QLogic 22xx (ISP2200) host adapter family. @@ -23,7 +21,6 @@ config SCSI_QLA2300 tristate "QLogic ISP2300 host adapter family support" depends on SCSI_QLA2XXX select SCSI_FC_ATTRS - select FW_LOADER ---help--- This driver supports the QLogic 2300 (ISP2300 and ISP2312) host adapter family. @@ -32,7 +29,6 @@ config SCSI_QLA2322 tristate "QLogic ISP2322 host adapter family support" depends on SCSI_QLA2XXX select SCSI_FC_ATTRS - select FW_LOADER ---help--- This driver supports the QLogic 2322 (ISP2322) host adapter family. @@ -40,16 +36,6 @@ config SCSI_QLA6312 tristate "QLogic ISP63xx host adapter family support" depends on SCSI_QLA2XXX select SCSI_FC_ATTRS - select FW_LOADER ---help--- This driver supports the QLogic 63xx (ISP6312 and ISP6322) host adapter family. - -config SCSI_QLA24XX - tristate "QLogic ISP24xx host adapter family support" - depends on SCSI_QLA2XXX - select SCSI_FC_ATTRS - select FW_LOADER - ---help--- - This driver supports the QLogic 24xx (ISP2422 and ISP2432) host - adapter family. diff --git a/trunk/drivers/scsi/qla2xxx/Makefile b/trunk/drivers/scsi/qla2xxx/Makefile index b169687d08ff..00d2e3c21ef6 100644 --- a/trunk/drivers/scsi/qla2xxx/Makefile +++ b/trunk/drivers/scsi/qla2xxx/Makefile @@ -1,4 +1,5 @@ EXTRA_CFLAGS += -DUNIQUE_FW_NAME +EXTRA_CFLAGS += -DCONFIG_SCSI_QLA24XX -DCONFIG_SCSI_QLA24XX_MODULE qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ qla_dbg.o qla_sup.o qla_rscn.o qla_attr.o diff --git a/trunk/drivers/serial/serial_cs.c b/trunk/drivers/serial/serial_cs.c index 1ae0b381c162..de0136cc5938 100644 --- a/trunk/drivers/serial/serial_cs.c +++ b/trunk/drivers/serial/serial_cs.c @@ -790,19 +790,19 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a), PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29), PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719), - PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet ", 0x578ba6e7, 0x02d92d1e), PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c), PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58), PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e), - PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9), - PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed), - PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet", 0x2e3ee845, 0xc0e778c2), PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070), PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562), PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070), @@ -840,7 +840,7 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed), PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65), PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6), - PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400+", 0x816cc815, 0x412729fb), + PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400", 0x816cc815, 0x23539b80), PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f), PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f), PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383), diff --git a/trunk/drivers/video/fbsysfs.c b/trunk/drivers/video/fbsysfs.c index ed1d4d1ac4f7..63b505cce4ec 100644 --- a/trunk/drivers/video/fbsysfs.c +++ b/trunk/drivers/video/fbsysfs.c @@ -244,15 +244,15 @@ static ssize_t show_virtual(struct class_device *class_device, char *buf) /* Format for cmap is "%02x%c%4x%4x%4x\n" */ /* %02x entry %c transp %4x red %4x blue %4x green \n */ -/* 256 rows at 16 chars equals 4096, the normal page size */ -/* the code will automatically adjust for different page sizes */ +/* 255 rows at 16 chars equals 4096 */ +/* PAGE_SIZE can be 4096 or larger */ static ssize_t store_cmap(struct class_device *class_device, const char *buf, size_t count) { struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); int rc, i, start, length, transp = 0; - if ((count > PAGE_SIZE) || ((count % 16) != 0)) + if ((count > 4096) || ((count % 16) != 0) || (PAGE_SIZE < 4096)) return -EINVAL; if (!fb_info->fbops->fb_setcolreg && !fb_info->fbops->fb_setcmap) @@ -317,18 +317,18 @@ static ssize_t show_cmap(struct class_device *class_device, char *buf) !fb_info->cmap.green) return -EINVAL; - if (fb_info->cmap.len > PAGE_SIZE / 16) + if (PAGE_SIZE < 4096) return -EINVAL; /* don't mess with the format, the buffer is PAGE_SIZE */ - /* 256 entries at 16 chars per line equals 4096 = PAGE_SIZE */ + /* 255 entries at 16 chars per line equals 4096 = PAGE_SIZE */ for (i = 0; i < fb_info->cmap.len; i++) { - snprintf(&buf[ i * 16], PAGE_SIZE - i * 16, "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start, + sprintf(&buf[ i * 16], "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start, ((fb_info->cmap.transp && fb_info->cmap.transp[i]) ? '*' : ' '), fb_info->cmap.red[i], fb_info->cmap.blue[i], fb_info->cmap.green[i]); } - return 16 * fb_info->cmap.len; + return 4096; } static ssize_t store_blank(struct class_device *class_device, const char * buf, diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index 249dd6bb66c8..ca8f7a850fe3 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -261,7 +261,6 @@ inline void __bio_clone(struct bio *bio, struct bio *bio_src) */ bio->bi_vcnt = bio_src->bi_vcnt; bio->bi_size = bio_src->bi_size; - bio->bi_idx = bio_src->bi_idx; bio_phys_segments(q, bio); bio_hw_segments(q, bio); } diff --git a/trunk/fs/hostfs/hostfs.h b/trunk/fs/hostfs/hostfs.h index 67bca0d4a33b..c1516d013bf6 100644 --- a/trunk/fs/hostfs/hostfs.h +++ b/trunk/fs/hostfs/hostfs.h @@ -69,7 +69,6 @@ extern int read_file(int fd, unsigned long long *offset, char *buf, int len); extern int write_file(int fd, unsigned long long *offset, const char *buf, int len); extern int lseek_file(int fd, long long offset, int whence); -extern int fsync_file(int fd, int datasync); extern int file_create(char *name, int ur, int uw, int ux, int gr, int gw, int gx, int or, int ow, int ox); extern int set_attr(const char *file, struct hostfs_iattr *attrs); diff --git a/trunk/fs/hostfs/hostfs_kern.c b/trunk/fs/hostfs/hostfs_kern.c index b2d18200a003..88e68caa3784 100644 --- a/trunk/fs/hostfs/hostfs_kern.c +++ b/trunk/fs/hostfs/hostfs_kern.c @@ -382,7 +382,7 @@ int hostfs_file_open(struct inode *ino, struct file *file) int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync) { - return fsync_file(HOSTFS_I(dentry->d_inode)->fd, datasync); + return(0); } static struct file_operations hostfs_file_fops = { diff --git a/trunk/fs/hostfs/hostfs_user.c b/trunk/fs/hostfs/hostfs_user.c index b97809deba66..4796e8490f7d 100644 --- a/trunk/fs/hostfs/hostfs_user.c +++ b/trunk/fs/hostfs/hostfs_user.c @@ -153,24 +153,10 @@ int lseek_file(int fd, long long offset, int whence) int ret; ret = lseek64(fd, offset, whence); - if(ret < 0) - return(-errno); + if(ret < 0) return(-errno); return(0); } -int fsync_file(int fd, int datasync) -{ - int ret; - if (datasync) - ret = fdatasync(fd); - else - ret = fsync(fd); - - if (ret < 0) - return -errno; - return 0; -} - void close_file(void *stream) { close(*((int *) stream)); diff --git a/trunk/include/asm-generic/sections.h b/trunk/include/asm-generic/sections.h index 450eae22c39a..195ccdc069e6 100644 --- a/trunk/include/asm-generic/sections.h +++ b/trunk/include/asm-generic/sections.h @@ -11,6 +11,5 @@ extern char _sinittext[], _einittext[]; extern char _sextratext[] __attribute__((weak)); extern char _eextratext[] __attribute__((weak)); extern char _end[]; -extern char __per_cpu_start[], __per_cpu_end[]; #endif /* _ASM_GENERIC_SECTIONS_H_ */ diff --git a/trunk/include/asm-i386/bitops.h b/trunk/include/asm-i386/bitops.h index 1caee1039363..9db0b712d57a 100644 --- a/trunk/include/asm-i386/bitops.h +++ b/trunk/include/asm-i386/bitops.h @@ -310,20 +310,6 @@ static inline int find_first_zero_bit(const unsigned long *addr, unsigned size) */ int find_next_zero_bit(const unsigned long *addr, int size, int offset); -/** - * __ffs - find first bit in word. - * @word: The word to search - * - * Undefined if no bit exists, so code should check against 0 first. - */ -static inline unsigned long __ffs(unsigned long word) -{ - __asm__("bsfl %1,%0" - :"=r" (word) - :"rm" (word)); - return word; -} - /** * find_first_bit - find the first set bit in a memory region * @addr: The address to start the search at @@ -334,16 +320,22 @@ static inline unsigned long __ffs(unsigned long word) */ static inline int find_first_bit(const unsigned long *addr, unsigned size) { - int x = 0; - do { - if (*addr) - return __ffs(*addr) + x; - addr++; - if (x >= size) - break; - x += (sizeof(*addr)<<3); - } while (1); - return x; + int d0, d1; + int res; + + /* This looks at memory. Mark it volatile to tell gcc not to move it around */ + __asm__ __volatile__( + "xorl %%eax,%%eax\n\t" + "repe; scasl\n\t" + "jz 1f\n\t" + "leal -4(%%edi),%%edi\n\t" + "bsfl (%%edi),%%eax\n" + "1:\tsubl %%ebx,%%edi\n\t" + "shll $3,%%edi\n\t" + "addl %%edi,%%eax" + :"=a" (res), "=&c" (d0), "=&D" (d1) + :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory"); + return res; } /** @@ -368,6 +360,20 @@ static inline unsigned long ffz(unsigned long word) return word; } +/** + * __ffs - find first bit in word. + * @word: The word to search + * + * Undefined if no bit exists, so code should check against 0 first. + */ +static inline unsigned long __ffs(unsigned long word) +{ + __asm__("bsfl %1,%0" + :"=r" (word) + :"rm" (word)); + return word; +} + /* * fls: find last bit set. */ diff --git a/trunk/include/asm-i386/smp.h b/trunk/include/asm-i386/smp.h index a283738b80b3..edad9b4712fa 100644 --- a/trunk/include/asm-i386/smp.h +++ b/trunk/include/asm-i386/smp.h @@ -37,6 +37,9 @@ extern int smp_num_siblings; extern cpumask_t cpu_sibling_map[]; extern cpumask_t cpu_core_map[]; +extern void smp_flush_tlb(void); +extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); +extern void smp_invalidate_rcv(void); /* Process an NMI */ extern void (*mtrr_hook) (void); extern void zap_low_mappings (void); extern void lock_ipi_call_lock(void); diff --git a/trunk/include/asm-um/vm86.h b/trunk/include/asm-um/vm86.h deleted file mode 100644 index 7801f82de1f4..000000000000 --- a/trunk/include/asm-um/vm86.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_VM86_H -#define __UM_VM86_H - -#include "asm/arch/vm86.h" - -#endif diff --git a/trunk/include/asm-x86_64/bitops.h b/trunk/include/asm-x86_64/bitops.h index 05a0d374404b..a31bb99be53f 100644 --- a/trunk/include/asm-x86_64/bitops.h +++ b/trunk/include/asm-x86_64/bitops.h @@ -348,7 +348,8 @@ static inline int sched_find_first_bit(const unsigned long *b) return __ffs(b[0]); if (b[1]) return __ffs(b[1]) + 64; - return __ffs(b[2]) + 128; + if (b[2]) + return __ffs(b[2]) + 128; } /** diff --git a/trunk/include/asm-x86_64/bug.h b/trunk/include/asm-x86_64/bug.h index eed785667289..3d2a666a5dd5 100644 --- a/trunk/include/asm-x86_64/bug.h +++ b/trunk/include/asm-x86_64/bug.h @@ -8,24 +8,17 @@ * this frame. */ struct bug_frame { - unsigned char ud2[2]; - unsigned char mov; + unsigned char ud2[2]; /* should use 32bit offset instead, but the assembler doesn't like it */ char *filename; - unsigned char ret; unsigned short line; } __attribute__((packed)); #ifdef CONFIG_BUG #define HAVE_ARCH_BUG -/* We turn the bug frame into valid instructions to not confuse - the disassembler. Thanks to Jan Beulich & Suresh Siddha - for nice instruction selection. - The magic numbers generate mov $64bitimm,%eax ; ret $offset. */ -#define BUG() \ - asm volatile( \ - "ud2 ; .byte 0xa3 ; .quad %c1 ; .byte 0xc2 ; .short %c0" :: \ +#define BUG() \ + asm volatile("ud2 ; .quad %c1 ; .short %c0" :: \ "i"(__LINE__), "i" (__stringify(__FILE__))) void out_of_line_bug(void); #else diff --git a/trunk/include/asm-x86_64/desc.h b/trunk/include/asm-x86_64/desc.h index c89b58bebee2..6aefb9c0280d 100644 --- a/trunk/include/asm-x86_64/desc.h +++ b/trunk/include/asm-x86_64/desc.h @@ -75,7 +75,6 @@ struct desc_ptr { */ extern struct desc_struct default_ldt[]; extern struct gate_struct idt_table[]; -extern struct desc_ptr cpu_gdt_descr[]; static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist) { diff --git a/trunk/include/asm-x86_64/ipi.h b/trunk/include/asm-x86_64/ipi.h index 5e166b9d3bde..d1841847ed89 100644 --- a/trunk/include/asm-x86_64/ipi.h +++ b/trunk/include/asm-x86_64/ipi.h @@ -82,27 +82,30 @@ static inline void send_IPI_mask_sequence(cpumask_t mask, int vector) */ local_irq_save(flags); - for_each_cpu_mask(query_cpu, mask) { - /* - * Wait for idle. - */ - apic_wait_icr_idle(); - - /* - * prepare target chip field - */ - cfg = __prepare_ICR2(x86_cpu_to_apicid[query_cpu]); - apic_write_around(APIC_ICR2, cfg); - - /* - * program the ICR - */ - cfg = __prepare_ICR(0, vector, APIC_DEST_PHYSICAL); - - /* - * Send the IPI. The write to APIC_ICR fires this off. - */ - apic_write_around(APIC_ICR, cfg); + for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) { + if (cpu_isset(query_cpu, mask)) { + + /* + * Wait for idle. + */ + apic_wait_icr_idle(); + + /* + * prepare target chip field + */ + cfg = __prepare_ICR2(x86_cpu_to_apicid[query_cpu]); + apic_write_around(APIC_ICR2, cfg); + + /* + * program the ICR + */ + cfg = __prepare_ICR(0, vector, APIC_DEST_PHYSICAL); + + /* + * Send the IPI. The write to APIC_ICR fires this off. + */ + apic_write_around(APIC_ICR, cfg); + } } local_irq_restore(flags); } diff --git a/trunk/include/asm-x86_64/irq.h b/trunk/include/asm-x86_64/irq.h index 4482657777bb..eb3b7aa9eb9f 100644 --- a/trunk/include/asm-x86_64/irq.h +++ b/trunk/include/asm-x86_64/irq.h @@ -57,6 +57,4 @@ int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *); extern void fixup_irqs(cpumask_t map); #endif -#define __ARCH_HAS_DO_SOFTIRQ 1 - #endif /* _ASM_IRQ_H */ diff --git a/trunk/include/asm-x86_64/msr.h b/trunk/include/asm-x86_64/msr.h index ba15279a79d0..bc700232728d 100644 --- a/trunk/include/asm-x86_64/msr.h +++ b/trunk/include/asm-x86_64/msr.h @@ -218,7 +218,7 @@ extern inline unsigned int cpuid_edx(unsigned int op) #define MSR_K7_PERFCTR3 0xC0010007 #define MSR_K8_TOP_MEM1 0xC001001A #define MSR_K8_TOP_MEM2 0xC001001D -#define MSR_K8_SYSCFG 0xC0010010 +#define MSR_K8_SYSCFG 0xC0000010 /* K6 MSRs */ #define MSR_K6_EFER 0xC0000080 diff --git a/trunk/include/asm-x86_64/smp.h b/trunk/include/asm-x86_64/smp.h index 18ac762e1ab8..aeb1b73e21e1 100644 --- a/trunk/include/asm-x86_64/smp.h +++ b/trunk/include/asm-x86_64/smp.h @@ -46,7 +46,10 @@ extern int pic_mode; extern void lock_ipi_call_lock(void); extern void unlock_ipi_call_lock(void); extern int smp_num_siblings; +extern void smp_flush_tlb(void); +extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); extern void smp_send_reschedule(int cpu); +extern void smp_invalidate_rcv(void); /* Process an NMI */ extern void zap_low_mappings(void); void smp_stop_cpu(void); extern cpumask_t cpu_sibling_map[NR_CPUS]; diff --git a/trunk/include/asm-x86_64/system.h b/trunk/include/asm-x86_64/system.h index 8606e170a7dc..76165736e43a 100644 --- a/trunk/include/asm-x86_64/system.h +++ b/trunk/include/asm-x86_64/system.h @@ -116,12 +116,12 @@ struct alt_instr { /* * Alternative inline assembly with input. * - * Peculiarities: + * Pecularities: * No memory clobber here. * Argument numbers start with 1. * Best is to use constraints that are fixed size (like (%1) ... "r") * If you use variable sized constraints like "m" or "g" in the - * replacement make sure to pad to the worst case length. + * replacement maake sure to pad to the worst case length. */ #define alternative_input(oldinstr, newinstr, feature, input...) \ asm volatile ("661:\n\t" oldinstr "\n662:\n" \ @@ -335,6 +335,9 @@ void cpu_idle_wait(void); void disable_hlt(void); void enable_hlt(void); +#define HAVE_EAT_KEY +void eat_key(void); + extern unsigned long arch_align_stack(unsigned long sp); #endif diff --git a/trunk/include/asm-x86_64/tlbflush.h b/trunk/include/asm-x86_64/tlbflush.h index 505b0cf906de..061742382520 100644 --- a/trunk/include/asm-x86_64/tlbflush.h +++ b/trunk/include/asm-x86_64/tlbflush.h @@ -56,9 +56,8 @@ extern unsigned long pgkern_mask; * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables * - * x86-64 can only flush individual pages or full VMs. For a range flush - * we always do the full VM. Might be worth trying if for a small - * range a few INVLPGs in a row are a win. + * ..but the x86_64 has somewhat limited tlb flushing capabilities, + * and page-granular flushes are available only on i486 and up. */ #ifndef CONFIG_SMP @@ -116,9 +115,7 @@ static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long st static inline void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long end) { - /* x86_64 does not keep any page table caches in a software TLB. - The CPUs do in their hardware TLBs, but they are handled - by the normal TLB flushing algorithms. */ + /* x86_64 does not keep any page table caches in TLB */ } #endif /* _X8664_TLBFLUSH_H */ diff --git a/trunk/include/sound/core.h b/trunk/include/sound/core.h index 38b357fc8958..f8c4ef0aa352 100644 --- a/trunk/include/sound/core.h +++ b/trunk/include/sound/core.h @@ -126,26 +126,25 @@ struct snd_monitor_file { struct snd_monitor_file *next; }; -struct snd_shutdown_f_ops; /* define it later in init.c */ +struct snd_shutdown_f_ops; /* define it later */ /* main structure for soundcard */ struct _snd_card { - int number; /* number of soundcard (index to - snd_cards) */ + int number; /* number of soundcard (index to snd_cards) */ char id[16]; /* id string of this card */ char driver[16]; /* driver name */ char shortname[32]; /* short name of this soundcard */ char longname[80]; /* name of this soundcard */ char mixername[80]; /* mixer name */ - char components[80]; /* card components delimited with - space */ + char components[80]; /* card components delimited with space */ + struct module *module; /* top-level module */ void *private_data; /* private data for soundcard */ - void (*private_free) (snd_card_t *card); /* callback for freeing of - private data */ + void (*private_free) (snd_card_t *card); /* callback for freeing of private data */ + struct list_head devices; /* devices */ unsigned int last_numid; /* last used numeric ID */ @@ -161,8 +160,7 @@ struct _snd_card { struct proc_dir_entry *proc_root_link; /* number link to real id */ struct snd_monitor_file *files; /* all files associated to this card */ - struct snd_shutdown_f_ops *s_f_ops; /* file operations in the shutdown - state */ + struct snd_shutdown_f_ops *s_f_ops; /* file operations in the shutdown state */ spinlock_t files_lock; /* lock the files for this card */ int shutdown; /* this card is going down */ wait_queue_head_t shutdown_sleep; @@ -198,6 +196,8 @@ static inline void snd_power_unlock(snd_card_t *card) up(&card->power_lock); } +int snd_power_wait(snd_card_t *card, unsigned int power_state, struct file *file); + static inline unsigned int snd_power_get_state(snd_card_t *card) { return card->power_state; @@ -208,10 +208,6 @@ static inline void snd_power_change_state(snd_card_t *card, unsigned int state) card->power_state = state; wake_up(&card->power_sleep); } - -/* init.c */ -int snd_power_wait(snd_card_t *card, unsigned int power_state, struct file *file); - int snd_card_set_pm_callback(snd_card_t *card, int (*suspend)(snd_card_t *, pm_message_t), int (*resume)(snd_card_t *), @@ -242,14 +238,15 @@ static inline int snd_power_wait(snd_card_t *card, unsigned int state, struct fi #endif /* CONFIG_PM */ +/* device.c */ + struct _snd_minor { struct list_head list; /* list of all minors per card */ int number; /* minor number */ int device; /* device number */ const char *comment; /* for /proc/asound/devices */ struct file_operations *f_ops; /* file operations */ - char name[0]; /* device name (keep at the end of - structure) */ + char name[0]; /* device name (keep at the end of structure) */ }; typedef struct _snd_minor snd_minor_t; @@ -290,12 +287,12 @@ void snd_memory_init(void); void snd_memory_done(void); int snd_memory_info_init(void); int snd_memory_info_done(void); -void *snd_hidden_kmalloc(size_t size, unsigned int __nocast flags); -void *snd_hidden_kcalloc(size_t n, size_t size, unsigned int __nocast flags); +void *snd_hidden_kmalloc(size_t size, int flags); +void *snd_hidden_kcalloc(size_t n, size_t size, int flags); void snd_hidden_kfree(const void *obj); void *snd_hidden_vmalloc(unsigned long size); void snd_hidden_vfree(void *obj); -char *snd_hidden_kstrdup(const char *s, unsigned int __nocast flags); +char *snd_hidden_kstrdup(const char *s, int flags); #define kmalloc(size, flags) snd_hidden_kmalloc(size, flags) #define kcalloc(n, size, flags) snd_hidden_kcalloc(n, size, flags) #define kfree(obj) snd_hidden_kfree(obj) @@ -414,7 +411,7 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...) printk(fmt ,##args) #endif /** - * snd_assert - run-time assertion macro + * snd_assert - run-time assersion macro * @expr: expression * @args...: the action * @@ -430,7 +427,7 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...) }\ } while (0) /** - * snd_runtime_check - run-time assertion macro + * snd_runtime_check - run-time assersion macro * @expr: expression * @args...: the action * diff --git a/trunk/include/sound/driver.h b/trunk/include/sound/driver.h index 0d12456ec3ae..948e9a1aebef 100644 --- a/trunk/include/sound/driver.h +++ b/trunk/include/sound/driver.h @@ -51,7 +51,7 @@ #ifdef CONFIG_SND_DEBUG_MEMORY #include #include -void *snd_wrapper_kmalloc(size_t, unsigned int __nocast); +void *snd_wrapper_kmalloc(size_t, int); #undef kmalloc void snd_wrapper_kfree(const void *); #undef kfree diff --git a/trunk/include/sound/emu10k1.h b/trunk/include/sound/emu10k1.h index c2ef3f023687..c50b91958ff9 100644 --- a/trunk/include/sound/emu10k1.h +++ b/trunk/include/sound/emu10k1.h @@ -1167,7 +1167,6 @@ int snd_emu10k1_create(snd_card_t * card, unsigned short extout_mask, long max_cache_bytes, int enable_ir, - uint subsystem, emu10k1_t ** remu); int snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm); diff --git a/trunk/include/sound/version.h b/trunk/include/sound/version.h index c085136f391f..46acfa8c9988 100644 --- a/trunk/include/sound/version.h +++ b/trunk/include/sound/version.h @@ -1,3 +1,3 @@ /* include/version.h. Generated by configure. */ -#define CONFIG_SND_VERSION "1.0.9b" -#define CONFIG_SND_DATE " (Thu Jul 28 12:20:13 2005 UTC)" +#define CONFIG_SND_VERSION "1.0.9" +#define CONFIG_SND_DATE " (Sun May 29 07:31:02 2005 UTC)" diff --git a/trunk/init/main.c b/trunk/init/main.c index c9c311cf1771..b5e421e39ede 100644 --- a/trunk/init/main.c +++ b/trunk/init/main.c @@ -51,7 +51,6 @@ #include #include #include -#include /* * This is one of the first .c files built. Error out early @@ -324,6 +323,8 @@ static void __init setup_per_cpu_areas(void) { unsigned long size, i; char *ptr; + /* Created by linker magic */ + extern char __per_cpu_start[], __per_cpu_end[]; /* Copy section for each CPU (we discard the original) */ size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES); diff --git a/trunk/kernel/posix-timers.c b/trunk/kernel/posix-timers.c index 10b2ad749d14..5b7b4736d82b 100644 --- a/trunk/kernel/posix-timers.c +++ b/trunk/kernel/posix-timers.c @@ -896,10 +896,21 @@ static int adjust_abs_time(struct k_clock *clock, struct timespec *tp, jiffies_64_f = get_jiffies_64(); } /* - * Take away now to get delta and normalize + * Take away now to get delta */ - set_normalized_timespec(&oc, oc.tv_sec - now.tv_sec, - oc.tv_nsec - now.tv_nsec); + oc.tv_sec -= now.tv_sec; + oc.tv_nsec -= now.tv_nsec; + /* + * Normalize... + */ + while ((oc.tv_nsec - NSEC_PER_SEC) >= 0) { + oc.tv_nsec -= NSEC_PER_SEC; + oc.tv_sec++; + } + while ((oc.tv_nsec) < 0) { + oc.tv_nsec += NSEC_PER_SEC; + oc.tv_sec--; + } }else{ jiffies_64_f = get_jiffies_64(); } diff --git a/trunk/kernel/softirq.c b/trunk/kernel/softirq.c index 31007d6542cc..b4ab6af1dea8 100644 --- a/trunk/kernel/softirq.c +++ b/trunk/kernel/softirq.c @@ -86,7 +86,7 @@ asmlinkage void __do_softirq(void) /* Reset the pending bitmask before enabling irqs */ local_softirq_pending() = 0; - //local_irq_enable(); + local_irq_enable(); h = softirq_vec; @@ -99,7 +99,7 @@ asmlinkage void __do_softirq(void) pending >>= 1; } while (pending); - //local_irq_disable(); + local_irq_disable(); pending = local_softirq_pending(); if (pending && --max_restart) diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 52a3bf7ae177..ff9dc029233a 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -901,7 +901,8 @@ int dev_close(struct net_device *dev) smp_mb__after_clear_bit(); /* Commit netif_running(). */ while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) { /* No hurry. */ - msleep(1); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(1); } /* diff --git a/trunk/scripts/kconfig/gconf.c b/trunk/scripts/kconfig/gconf.c index 9f5aabd58fa9..ad6b12043874 100644 --- a/trunk/scripts/kconfig/gconf.c +++ b/trunk/scripts/kconfig/gconf.c @@ -178,31 +178,17 @@ const char *dbg_print_ptype(int val) } -void replace_button_icon(GladeXML * xml, GdkDrawable * window, - GtkStyle * style, gchar * btn_name, gchar ** xpm) -{ - GdkPixmap *pixmap; - GdkBitmap *mask; - GtkToolButton *button; - GtkWidget *image; - - pixmap = gdk_pixmap_create_from_xpm_d(window, &mask, - &style->bg[GTK_STATE_NORMAL], - xpm); +/* Main Window Initialization */ - button = GTK_TOOL_BUTTON(glade_xml_get_widget(xml, btn_name)); - image = gtk_image_new_from_pixmap(pixmap, mask); - gtk_widget_show(image); - gtk_tool_button_set_icon_widget(button, image); -} -/* Main Window Initialization */ void init_main_window(const gchar * glade_file) { GladeXML *xml; GtkWidget *widget; GtkTextBuffer *txtbuf; char title[256]; + GdkPixmap *pixmap; + GdkBitmap *mask; GtkStyle *style; xml = glade_xml_new(glade_file, "window1", NULL); @@ -235,22 +221,36 @@ void init_main_window(const gchar * glade_file) style = gtk_widget_get_style(main_wnd); widget = glade_xml_get_widget(xml, "toolbar1"); -#if 0 /* Use stock Gtk icons instead */ - replace_button_icon(xml, main_wnd->window, style, - "button1", (gchar **) xpm_back); - replace_button_icon(xml, main_wnd->window, style, - "button2", (gchar **) xpm_load); - replace_button_icon(xml, main_wnd->window, style, - "button3", (gchar **) xpm_save); -#endif - replace_button_icon(xml, main_wnd->window, style, - "button4", (gchar **) xpm_single_view); - replace_button_icon(xml, main_wnd->window, style, - "button5", (gchar **) xpm_split_view); - replace_button_icon(xml, main_wnd->window, style, - "button6", (gchar **) xpm_tree_view); - -#if 0 + pixmap = gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask, + &style->bg[GTK_STATE_NORMAL], + (gchar **) xpm_single_view); + gtk_image_set_from_pixmap(GTK_IMAGE + (((GtkToolbarChild + *) (g_list_nth(GTK_TOOLBAR(widget)-> + children, + 5)->data))->icon), + pixmap, mask); + pixmap = + gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask, + &style->bg[GTK_STATE_NORMAL], + (gchar **) xpm_split_view); + gtk_image_set_from_pixmap(GTK_IMAGE + (((GtkToolbarChild + *) (g_list_nth(GTK_TOOLBAR(widget)-> + children, + 6)->data))->icon), + pixmap, mask); + pixmap = + gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask, + &style->bg[GTK_STATE_NORMAL], + (gchar **) xpm_tree_view); + gtk_image_set_from_pixmap(GTK_IMAGE + (((GtkToolbarChild + *) (g_list_nth(GTK_TOOLBAR(widget)-> + children, + 7)->data))->icon), + pixmap, mask); + switch (view_mode) { case SINGLE_VIEW: widget = glade_xml_get_widget(xml, "button4"); @@ -265,7 +265,7 @@ void init_main_window(const gchar * glade_file) g_signal_emit_by_name(widget, "clicked"); break; } -#endif + txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1", "foreground", "red", @@ -322,7 +322,7 @@ void init_left_tree(void) gtk_tree_view_set_model(view, model1); gtk_tree_view_set_headers_visible(view, TRUE); gtk_tree_view_set_rules_hint(view, FALSE); - + column = gtk_tree_view_column_new(); gtk_tree_view_append_column(view, column); gtk_tree_view_column_set_title(column, _("Options")); @@ -334,11 +334,11 @@ void init_left_tree(void) renderer, "active", COL_BTNACT, "inconsistent", COL_BTNINC, - "visible", COL_BTNVIS, + "visible", COL_BTNVIS, "radio", COL_BTNRAD, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), - renderer, FALSE); + renderer, FALSE); gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), renderer, "text", COL_OPTION, @@ -386,7 +386,7 @@ void init_right_tree(void) renderer, "active", COL_BTNACT, "inconsistent", COL_BTNINC, - "visible", COL_BTNVIS, + "visible", COL_BTNVIS, "radio", COL_BTNRAD, NULL); /*g_signal_connect(G_OBJECT(renderer), "toggled", G_CALLBACK(renderer_toggled), NULL); */ @@ -806,7 +806,7 @@ void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data) } -void on_back_clicked(GtkButton * button, gpointer user_data) +void on_back_pressed(GtkButton * button, gpointer user_data) { enum prop_type ptype; @@ -821,13 +821,13 @@ void on_back_clicked(GtkButton * button, gpointer user_data) } -void on_load_clicked(GtkButton * button, gpointer user_data) +void on_load_pressed(GtkButton * button, gpointer user_data) { on_load1_activate(NULL, user_data); } -void on_save_clicked(GtkButton * button, gpointer user_data) +void on_save_pressed(GtkButton * button, gpointer user_data) { on_save1_activate(NULL, user_data); } @@ -850,12 +850,9 @@ void on_split_clicked(GtkButton * button, gpointer user_data) gtk_widget_show(tree1_w); gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h); gtk_paned_set_position(GTK_PANED(hpaned), w / 2); - if (tree2) + if (tree2) gtk_tree_store_clear(tree2); display_list(); - - /* Disable back btn, like in full mode. */ - gtk_widget_set_sensitive(back_btn, FALSE); } @@ -871,13 +868,13 @@ void on_full_clicked(GtkButton * button, gpointer user_data) } -void on_collapse_clicked(GtkButton * button, gpointer user_data) +void on_collapse_pressed(GtkButton * button, gpointer user_data) { gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w)); } -void on_expand_clicked(GtkButton * button, gpointer user_data) +void on_expand_pressed(GtkButton * button, gpointer user_data) { gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); } @@ -1245,13 +1242,13 @@ static gchar **fill_row(struct menu *menu) row[COL_VALUE] = g_strdup(menu_get_prompt(def_menu)); } - if (sym->flags & SYMBOL_CHOICEVAL) + if(sym->flags & SYMBOL_CHOICEVAL) row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); stype = sym_get_type(sym); switch (stype) { case S_BOOLEAN: - if (GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE) + if(GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE) row[COL_BTNVIS] = GINT_TO_POINTER(TRUE); if (sym_is_choice(sym)) break; @@ -1426,7 +1423,7 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) child2); gtk_tree_store_remove(tree2, &tmp); if (!valid) - return; // next parent + return; // next parent else goto reparse; // next child } else @@ -1451,7 +1448,7 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) child2); gtk_tree_store_remove(tree2, &tmp); if (!valid) - return; // next parent + return; // next parent else goto reparse; // next child } @@ -1489,12 +1486,12 @@ static void display_tree(struct menu *menu) if (sym) sym->flags &= ~SYMBOL_CHANGED; - if ((view_mode == SPLIT_VIEW) - && !(child->flags & MENU_ROOT) && (tree == tree1)) + if ((view_mode == SPLIT_VIEW) && !(child->flags & MENU_ROOT) && + (tree == tree1)) continue; - if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT) - && (tree == tree2)) + if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT) && + (tree == tree2)) continue; if (menu_is_visible(child) || show_all) @@ -1516,12 +1513,11 @@ static void display_tree(struct menu *menu) && (tree == tree2)) continue; /* - if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) - || (view_mode == FULL_VIEW) + if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) || + (view_mode == FULL_VIEW) || (view_mode == SPLIT_VIEW))*/ if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT)) - || (view_mode == FULL_VIEW) - || (view_mode == SPLIT_VIEW)) { + || (view_mode == FULL_VIEW) || (view_mode == SPLIT_VIEW)) { indent++; display_tree(child); indent--; @@ -1534,9 +1530,9 @@ static void display_tree_part(void) { if (tree2) gtk_tree_store_clear(tree2); - if (view_mode == SINGLE_VIEW) + if(view_mode == SINGLE_VIEW) display_tree(current); - else if (view_mode == SPLIT_VIEW) + else if(view_mode == SPLIT_VIEW) display_tree(browsed); gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); } @@ -1555,22 +1551,24 @@ static void display_list(void) void fixup_rootmenu(struct menu *menu) { - struct menu *child; - static int menu_cnt = 0; - - menu->flags |= MENU_ROOT; - for (child = menu->list; child; child = child->next) { - if (child->prompt && child->prompt->type == P_MENU) { - menu_cnt++; - fixup_rootmenu(child); - menu_cnt--; - } else if (!menu_cnt) - fixup_rootmenu(child); - } + struct menu *child; + static int menu_cnt = 0; + + menu->flags |= MENU_ROOT; + for (child = menu->list; child; child = child->next) { + if (child->prompt && child->prompt->type == P_MENU) { + menu_cnt++; + fixup_rootmenu(child); + menu_cnt--; + } else if (!menu_cnt) + fixup_rootmenu(child); + } } /* Main */ + + int main(int ac, char *av[]) { const char *name; diff --git a/trunk/scripts/kconfig/gconf.glade b/trunk/scripts/kconfig/gconf.glade index f8744ed64967..ace4706ab251 100644 --- a/trunk/scripts/kconfig/gconf.glade +++ b/trunk/scripts/kconfig/gconf.glade @@ -13,11 +13,6 @@ 480 True False - True - False - False - GDK_WINDOW_TYPE_HINT_NORMAL - GDK_GRAVITY_NORTH_WEST @@ -51,7 +46,7 @@ - + True gtk-open 1 @@ -74,7 +69,7 @@ - + True gtk-save 1 @@ -96,7 +91,7 @@ - + True gtk-save-as 1 @@ -110,7 +105,7 @@ - + True @@ -124,7 +119,7 @@ - + True gtk-quit 1 @@ -184,7 +179,7 @@ - + True @@ -233,7 +228,7 @@ - + True gtk-dialog-question 1 @@ -255,7 +250,7 @@ - + True gtk-properties 1 @@ -276,7 +271,7 @@ - + True gtk-justify-fill 1 @@ -313,207 +308,109 @@ GTK_ORIENTATION_HORIZONTAL GTK_TOOLBAR_BOTH True - True - + True Goes up of one level (single view) Back True - gtk-undo - True - True - False - + gtk-undo + - - False - True - - + True - True - True - False - - - - True - - - - False - False - - + True Load a config file Load True - gtk-open - True - True - False - + gtk-open + - - False - True - - + True Save a config file Save True - gtk-save - True - True - False - + gtk-save + - - False - True - - + True - True - True - False - - - - True - - - - False - False - - + True Single view Single True - gtk-missing-image - True - True - False + gtk-missing-image - - False - True - - + True Split view Split True - gtk-missing-image - True - True - False + gtk-missing-image - - False - True - - + True Full view Full True - gtk-missing-image - True - True - False + gtk-missing-image - - False - True - - + True - True - True - False - - - - True - - - - False - False - - + True Collapse the whole tree in the right frame Collapse True - gtk-remove - True - True - False - + - - False - True - - + True Expand the whole tree in the right frame Expand True - gtk-add - True - True - False - + - - False - True - @@ -608,8 +505,6 @@ True True False - False - True GTK_JUSTIFY_LEFT GTK_WRAP_WORD True diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 2253f388234f..6be273851144 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -826,8 +826,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent sid = sbsec->def_sid; rc = 0; } else { - rc = security_context_to_sid_default(context, rc, &sid, - sbsec->def_sid); + rc = security_context_to_sid(context, rc, &sid); if (rc) { printk(KERN_WARNING "%s: context_to_sid(%s) " "returned %d for dev=%s ino=%ld\n", @@ -3126,12 +3125,12 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, if (sk->sk_family == PF_INET) { addr4 = (struct sockaddr_in *)address; - if (addrlen < sizeof(struct sockaddr_in)) + if (addrlen != sizeof(struct sockaddr_in)) return -EINVAL; snum = ntohs(addr4->sin_port); } else { addr6 = (struct sockaddr_in6 *)address; - if (addrlen < SIN6_LEN_RFC2133) + if (addrlen != sizeof(struct sockaddr_in6)) return -EINVAL; snum = ntohs(addr6->sin6_port); } diff --git a/trunk/security/selinux/include/security.h b/trunk/security/selinux/include/security.h index 71c0a19c9753..fa187c9a351d 100644 --- a/trunk/security/selinux/include/security.h +++ b/trunk/security/selinux/include/security.h @@ -65,8 +65,6 @@ int security_sid_to_context(u32 sid, char **scontext, int security_context_to_sid(char *scontext, u32 scontext_len, u32 *out_sid); -int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *out_sid, u32 def_sid); - int security_get_user_sids(u32 callsid, char *username, u32 **sids, u32 *nel); diff --git a/trunk/security/selinux/ss/mls.c b/trunk/security/selinux/ss/mls.c index d4c32c39ccc9..756036bcc243 100644 --- a/trunk/security/selinux/ss/mls.c +++ b/trunk/security/selinux/ss/mls.c @@ -15,7 +15,6 @@ #include #include #include -#include "sidtab.h" #include "mls.h" #include "policydb.h" #include "services.h" @@ -208,26 +207,6 @@ int mls_context_isvalid(struct policydb *p, struct context *c) return 1; } -/* - * Copies the MLS range from `src' into `dst'. - */ -static inline int mls_copy_context(struct context *dst, - struct context *src) -{ - int l, rc = 0; - - /* Copy the MLS range from the source context */ - for (l = 0; l < 2; l++) { - dst->range.level[l].sens = src->range.level[l].sens; - rc = ebitmap_cpy(&dst->range.level[l].cat, - &src->range.level[l].cat); - if (rc) - break; - } - - return rc; -} - /* * Set the MLS fields in the security context structure * `context' based on the string representation in @@ -237,20 +216,10 @@ static inline int mls_copy_context(struct context *dst, * * This function modifies the string in place, inserting * NULL characters to terminate the MLS fields. - * - * If a def_sid is provided and no MLS field is present, - * copy the MLS field of the associated default context. - * Used for upgraded to MLS systems where objects may lack - * MLS fields. - * - * Policy read-lock must be held for sidtab lookup. - * */ int mls_context_to_sid(char oldc, char **scontext, - struct context *context, - struct sidtab *s, - u32 def_sid) + struct context *context) { char delim; @@ -262,23 +231,9 @@ int mls_context_to_sid(char oldc, if (!selinux_mls_enabled) return 0; - /* - * No MLS component to the security context, try and map to - * default if provided. - */ - if (!oldc) { - struct context *defcon; - - if (def_sid == SECSID_NULL) - goto out; - - defcon = sidtab_search(s, def_sid); - if (!defcon) - goto out; - - rc = mls_copy_context(context, defcon); + /* No MLS component to the security context. */ + if (!oldc) goto out; - } /* Extract low sensitivity. */ scontextp = p = *scontext; @@ -378,6 +333,26 @@ int mls_context_to_sid(char oldc, return rc; } +/* + * Copies the MLS range from `src' into `dst'. + */ +static inline int mls_copy_context(struct context *dst, + struct context *src) +{ + int l, rc = 0; + + /* Copy the MLS range from the source context */ + for (l = 0; l < 2; l++) { + dst->range.level[l].sens = src->range.level[l].sens; + rc = ebitmap_cpy(&dst->range.level[l].cat, + &src->range.level[l].cat); + if (rc) + break; + } + + return rc; +} + /* * Copies the effective MLS range from `src' into `dst'. */ diff --git a/trunk/security/selinux/ss/mls.h b/trunk/security/selinux/ss/mls.h index 03de697c8058..0d37beaa85e2 100644 --- a/trunk/security/selinux/ss/mls.h +++ b/trunk/security/selinux/ss/mls.h @@ -23,9 +23,7 @@ int mls_context_isvalid(struct policydb *p, struct context *c); int mls_context_to_sid(char oldc, char **scontext, - struct context *context, - struct sidtab *s, - u32 def_sid); + struct context *context); int mls_convert_context(struct policydb *oldp, struct policydb *newp, diff --git a/trunk/security/selinux/ss/services.c b/trunk/security/selinux/ss/services.c index 014120474e69..922bb45054aa 100644 --- a/trunk/security/selinux/ss/services.c +++ b/trunk/security/selinux/ss/services.c @@ -601,7 +601,18 @@ int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len) } -static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid) +/** + * security_context_to_sid - Obtain a SID for a given security context. + * @scontext: security context + * @scontext_len: length in bytes + * @sid: security identifier, SID + * + * Obtains a SID associated with the security context that + * has the string representation specified by @scontext. + * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient + * memory is available, or 0 on success. + */ +int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid) { char *scontext2; struct context context; @@ -692,7 +703,7 @@ static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *s context.type = typdatum->value; - rc = mls_context_to_sid(oldc, &p, &context, &sidtab, def_sid); + rc = mls_context_to_sid(oldc, &p, &context); if (rc) goto out_unlock; @@ -716,46 +727,6 @@ static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *s return rc; } -/** - * security_context_to_sid - Obtain a SID for a given security context. - * @scontext: security context - * @scontext_len: length in bytes - * @sid: security identifier, SID - * - * Obtains a SID associated with the security context that - * has the string representation specified by @scontext. - * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient - * memory is available, or 0 on success. - */ -int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid) -{ - return security_context_to_sid_core(scontext, scontext_len, - sid, SECSID_NULL); -} - -/** - * security_context_to_sid_default - Obtain a SID for a given security context, - * falling back to specified default if needed. - * - * @scontext: security context - * @scontext_len: length in bytes - * @sid: security identifier, SID - * @def_sid: default SID to assign on errror - * - * Obtains a SID associated with the security context that - * has the string representation specified by @scontext. - * The default SID is passed to the MLS layer to be used to allow - * kernel labeling of the MLS field if the MLS field is not present - * (for upgrading to MLS without full relabel). - * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient - * memory is available, or 0 on success. - */ -int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid) -{ - return security_context_to_sid_core(scontext, scontext_len, - sid, def_sid); -} - static int compute_sid_handle_invalid_context( struct context *scontext, struct context *tcontext, diff --git a/trunk/sound/arm/Kconfig b/trunk/sound/arm/Kconfig index 2e4a5e0d16db..34c1740aa6e9 100644 --- a/trunk/sound/arm/Kconfig +++ b/trunk/sound/arm/Kconfig @@ -20,17 +20,5 @@ config SND_ARMAACI select SND_PCM select SND_AC97_CODEC -config SND_PXA2XX_PCM - tristate - select SND_PCM - -config SND_PXA2XX_AC97 - tristate "AC97 driver for the Intel PXA2xx chip" - depends on ARCH_PXA && SND - select SND_PXA2XX_PCM - select SND_AC97_CODEC - help - Say Y or M if you want to support any AC97 codec attached to - the PXA2xx AC97 interface. - endmenu + diff --git a/trunk/sound/arm/Makefile b/trunk/sound/arm/Makefile index 103f136926d9..f74ec28e1068 100644 --- a/trunk/sound/arm/Makefile +++ b/trunk/sound/arm/Makefile @@ -3,11 +3,9 @@ # snd-sa11xx-uda1341-objs := sa11xx-uda1341.o -snd-aaci-objs := aaci.o devdma.o -snd-pxa2xx-pcm-objs := pxa2xx-pcm.o -snd-pxa2xx-ac97-objs := pxa2xx-ac97.o +# Toplevel Module Dependency obj-$(CONFIG_SND_SA11XX_UDA1341) += snd-sa11xx-uda1341.o + obj-$(CONFIG_SND_ARMAACI) += snd-aaci.o -obj-$(CONFIG_SND_PXA2XX_PCM) += snd-pxa2xx-pcm.o -obj-$(CONFIG_SND_PXA2XX_AC97) += snd-pxa2xx-ac97.o +snd-aaci-objs := aaci.o devdma.o diff --git a/trunk/sound/arm/pxa2xx-ac97.c b/trunk/sound/arm/pxa2xx-ac97.c deleted file mode 100644 index 46052304e230..000000000000 --- a/trunk/sound/arm/pxa2xx-ac97.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * linux/sound/pxa2xx-ac97.c -- AC97 support for the Intel PXA2xx chip. - * - * Author: Nicolas Pitre - * Created: Dec 02, 2004 - * Copyright: MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "pxa2xx-pcm.h" - - -static DECLARE_MUTEX(car_mutex); -static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); -static volatile long gsr_bits; - -static unsigned short pxa2xx_ac97_read(ac97_t *ac97, unsigned short reg) -{ - unsigned short val = -1; - volatile u32 *reg_addr; - - down(&car_mutex); - if (CAR & CAR_CAIP) { - printk(KERN_CRIT"%s: CAR_CAIP already set\n", __FUNCTION__); - goto out; - } - - /* set up primary or secondary codec space */ - reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE; - reg_addr += (reg >> 1); - - /* start read access across the ac97 link */ - gsr_bits = 0; - val = *reg_addr; - if (reg == AC97_GPIO_STATUS) - goto out; - wait_event_timeout(gsr_wq, gsr_bits & GSR_SDONE, 1); - if (!gsr_bits & GSR_SDONE) { - printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n", - __FUNCTION__, reg, gsr_bits); - val = -1; - goto out; - } - - /* valid data now */ - gsr_bits = 0; - val = *reg_addr; - /* but we've just started another cycle... */ - wait_event_timeout(gsr_wq, gsr_bits & GSR_SDONE, 1); - -out: up(&car_mutex); - return val; -} - -static void pxa2xx_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val) -{ - volatile u32 *reg_addr; - - down(&car_mutex); - - if (CAR & CAR_CAIP) { - printk(KERN_CRIT "%s: CAR_CAIP already set\n", __FUNCTION__); - goto out; - } - - /* set up primary or secondary codec space */ - reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE; - reg_addr += (reg >> 1); - gsr_bits = 0; - *reg_addr = val; - wait_event_timeout(gsr_wq, gsr_bits & GSR_CDONE, 1); - if (!gsr_bits & GSR_SDONE) - printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n", - __FUNCTION__, reg, gsr_bits); - -out: up(&car_mutex); -} - -static void pxa2xx_ac97_reset(ac97_t *ac97) -{ - /* First, try cold reset */ - GCR &= GCR_COLD_RST; /* clear everything but nCRST */ - GCR &= ~GCR_COLD_RST; /* then assert nCRST */ - - gsr_bits = 0; -#ifdef CONFIG_PXA27x - /* PXA27x Developers Manual section 13.5.2.2.1 */ - pxa_set_cken(1 << 31, 1); - udelay(5); - pxa_set_cken(1 << 31, 0); - GCR = GCR_COLD_RST; - udelay(50); -#else - GCR = GCR_COLD_RST; - GCR |= GCR_CDONE_IE|GCR_SDONE_IE; - wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); -#endif - - if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) { - printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n", - __FUNCTION__, gsr_bits); - - /* let's try warm reset */ - gsr_bits = 0; -#ifdef CONFIG_PXA27x - /* warm reset broken on Bulverde, - so manually keep AC97 reset high */ - pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH); - udelay(10); - GCR |= GCR_WARM_RST; - pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); - udelay(50); -#else - GCR |= GCR_WARM_RST|GCR_PRIRDY_IEN|GCR_SECRDY_IEN;; - wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); -#endif - - if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) - printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n", - __FUNCTION__, gsr_bits); - } - - GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); - GCR |= GCR_SDONE_IE|GCR_CDONE_IE; -} - -static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - long status; - - status = GSR; - if (status) { - GSR = status; - gsr_bits |= status; - wake_up(&gsr_wq); - -#ifdef CONFIG_PXA27x - /* Although we don't use those we still need to clear them - since they tend to spuriously trigger when MMC is used - (hardware bug? go figure)... */ - MISR = MISR_EOC; - PISR = PISR_EOC; - MCSR = MCSR_EOC; -#endif - - return IRQ_HANDLED; - } - - return IRQ_NONE; -} - -static ac97_bus_ops_t pxa2xx_ac97_ops = { - .read = pxa2xx_ac97_read, - .write = pxa2xx_ac97_write, - .reset = pxa2xx_ac97_reset, -}; - -static pxa2xx_pcm_dma_params_t pxa2xx_ac97_pcm_out = { - .name = "AC97 PCM out", - .dev_addr = __PREG(PCDR), - .drcmr = &DRCMRTXPCDR, - .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | - DCMD_BURST32 | DCMD_WIDTH4, -}; - -static pxa2xx_pcm_dma_params_t pxa2xx_ac97_pcm_in = { - .name = "AC97 PCM in", - .dev_addr = __PREG(PCDR), - .drcmr = &DRCMRRXPCDR, - .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | - DCMD_BURST32 | DCMD_WIDTH4, -}; - -static snd_pcm_t *pxa2xx_ac97_pcm; -static ac97_t *pxa2xx_ac97_ac97; - -static int pxa2xx_ac97_pcm_startup(snd_pcm_substream_t *substream) -{ - snd_pcm_runtime_t *runtime = substream->runtime; - pxa2xx_audio_ops_t *platform_ops; - int r; - - runtime->hw.channels_min = 2; - runtime->hw.channels_max = 2; - - r = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? - AC97_RATES_FRONT_DAC : AC97_RATES_ADC; - runtime->hw.rates = pxa2xx_ac97_ac97->rates[r]; - snd_pcm_limit_hw_rates(runtime); - - platform_ops = substream->pcm->card->dev->platform_data; - if (platform_ops && platform_ops->startup) - return platform_ops->startup(substream, platform_ops->priv); - else - return 0; -} - -static void pxa2xx_ac97_pcm_shutdown(snd_pcm_substream_t *substream) -{ - pxa2xx_audio_ops_t *platform_ops; - - platform_ops = substream->pcm->card->dev->platform_data; - if (platform_ops && platform_ops->shutdown) - platform_ops->shutdown(substream, platform_ops->priv); -} - -static int pxa2xx_ac97_pcm_prepare(snd_pcm_substream_t *substream) -{ - snd_pcm_runtime_t *runtime = substream->runtime; - int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? - AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE; - return snd_ac97_set_rate(pxa2xx_ac97_ac97, reg, runtime->rate); -} - -static pxa2xx_pcm_client_t pxa2xx_ac97_pcm_client = { - .playback_params = &pxa2xx_ac97_pcm_out, - .capture_params = &pxa2xx_ac97_pcm_in, - .startup = pxa2xx_ac97_pcm_startup, - .shutdown = pxa2xx_ac97_pcm_shutdown, - .prepare = pxa2xx_ac97_pcm_prepare, -}; - -#ifdef CONFIG_PM - -static int pxa2xx_ac97_do_suspend(snd_card_t *card, unsigned int state) -{ - if (card->power_state != SNDRV_CTL_POWER_D3cold) { - pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data; - snd_pcm_suspend_all(pxa2xx_ac97_pcm); - snd_ac97_suspend(pxa2xx_ac97_ac97); - snd_power_change_state(card, SNDRV_CTL_POWER_D3cold); - if (platform_ops && platform_ops->suspend) - platform_ops->suspend(platform_ops->priv); - GCR |= GCR_ACLINK_OFF; - pxa_set_cken(CKEN2_AC97, 0); - } - - return 0; -} - -static int pxa2xx_ac97_do_resume(snd_card_t *card, unsigned int state) -{ - if (card->power_state != SNDRV_CTL_POWER_D0) { - pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data; - pxa_set_cken(CKEN2_AC97, 1); - if (platform_ops && platform_ops->resume) - platform_ops->resume(platform_ops->priv); - snd_ac97_resume(pxa2xx_ac97_ac97); - snd_power_change_state(card, SNDRV_CTL_POWER_D0); - } - - return 0; -} - -static int pxa2xx_ac97_suspend(struct device *_dev, u32 state, u32 level) -{ - snd_card_t *card = dev_get_drvdata(_dev); - int ret = 0; - - if (card && level == SUSPEND_DISABLE) - ret = pxa2xx_ac97_do_suspend(card, SNDRV_CTL_POWER_D3cold); - - return ret; -} - -static int pxa2xx_ac97_resume(struct device *_dev, u32 level) -{ - snd_card_t *card = dev_get_drvdata(_dev); - int ret = 0; - - if (card && level == RESUME_ENABLE) - ret = pxa2xx_ac97_do_resume(card, SNDRV_CTL_POWER_D0); - - return ret; -} - -#else -#define pxa2xx_ac97_suspend NULL -#define pxa2xx_ac97_resume NULL -#endif - -static int pxa2xx_ac97_probe(struct device *dev) -{ - snd_card_t *card; - ac97_bus_t *ac97_bus; - ac97_template_t ac97_template; - int ret; - - ret = -ENOMEM; - card = snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, - THIS_MODULE, 0); - if (!card) - goto err; - - card->dev = dev; - strncpy(card->driver, dev->driver->name, sizeof(card->driver)); - - ret = pxa2xx_pcm_new(card, &pxa2xx_ac97_pcm_client, &pxa2xx_ac97_pcm); - if (ret) - goto err; - - ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL); - if (ret < 0) - goto err; - - pxa_gpio_mode(GPIO31_SYNC_AC97_MD); - pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); - pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); - pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); -#ifdef CONFIG_PXA27x - /* Use GPIO 113 as AC97 Reset on Bulverde */ - pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); -#endif - pxa_set_cken(CKEN2_AC97, 1); - - ret = snd_ac97_bus(card, 0, &pxa2xx_ac97_ops, NULL, &ac97_bus); - if (ret) - goto err; - memset(&ac97_template, 0, sizeof(ac97_template)); - ret = snd_ac97_mixer(ac97_bus, &ac97_template, &pxa2xx_ac97_ac97); - if (ret) - goto err; - - snprintf(card->shortname, sizeof(card->shortname), - "%s", snd_ac97_get_short_name(pxa2xx_ac97_ac97)); - snprintf(card->longname, sizeof(card->longname), - "%s (%s)", dev->driver->name, card->mixername); - - snd_card_set_pm_callback(card, pxa2xx_ac97_do_suspend, - pxa2xx_ac97_do_resume, NULL); - ret = snd_card_register(card); - if (ret == 0) { - dev_set_drvdata(dev, card); - return 0; - } - - err: - if (card) - snd_card_free(card); - if (CKEN & CKEN2_AC97) { - GCR |= GCR_ACLINK_OFF; - free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN2_AC97, 0); - } - return ret; -} - -static int pxa2xx_ac97_remove(struct device *dev) -{ - snd_card_t *card = dev_get_drvdata(dev); - - if (card) { - snd_card_free(card); - dev_set_drvdata(dev, NULL); - GCR |= GCR_ACLINK_OFF; - free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN2_AC97, 0); - } - - return 0; -} - -static struct device_driver pxa2xx_ac97_driver = { - .name = "pxa2xx-ac97", - .bus = &platform_bus_type, - .probe = pxa2xx_ac97_probe, - .remove = pxa2xx_ac97_remove, - .suspend = pxa2xx_ac97_suspend, - .resume = pxa2xx_ac97_resume, -}; - -static int __init pxa2xx_ac97_init(void) -{ - return driver_register(&pxa2xx_ac97_driver); -} - -static void __exit pxa2xx_ac97_exit(void) -{ - driver_unregister(&pxa2xx_ac97_driver); -} - -module_init(pxa2xx_ac97_init); -module_exit(pxa2xx_ac97_exit); - -MODULE_AUTHOR("Nicolas Pitre"); -MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/arm/pxa2xx-pcm.c b/trunk/sound/arm/pxa2xx-pcm.c deleted file mode 100644 index b1eb53b02eae..000000000000 --- a/trunk/sound/arm/pxa2xx-pcm.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * linux/sound/arm/pxa2xx-pcm.c -- ALSA PCM interface for the Intel PXA2xx chip - * - * Author: Nicolas Pitre - * Created: Nov 30, 2004 - * Copyright: (C) 2004 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "pxa2xx-pcm.h" - - -static const snd_pcm_hardware_t pxa2xx_pcm_hardware = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_PAUSE, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .period_bytes_min = 32, - .period_bytes_max = 8192 - 32, - .periods_min = 1, - .periods_max = PAGE_SIZE/sizeof(pxa_dma_desc), - .buffer_bytes_max = 128 * 1024, - .fifo_size = 32, -}; - -struct pxa2xx_runtime_data { - int dma_ch; - pxa2xx_pcm_dma_params_t *params; - pxa_dma_desc *dma_desc_array; - dma_addr_t dma_desc_array_phys; -}; - -static int pxa2xx_pcm_hw_params(snd_pcm_substream_t *substream, - snd_pcm_hw_params_t *params) -{ - snd_pcm_runtime_t *runtime = substream->runtime; - struct pxa2xx_runtime_data *rtd = runtime->private_data; - size_t totsize = params_buffer_bytes(params); - size_t period = params_period_bytes(params); - pxa_dma_desc *dma_desc; - dma_addr_t dma_buff_phys, next_desc_phys; - - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - runtime->dma_bytes = totsize; - - dma_desc = rtd->dma_desc_array; - next_desc_phys = rtd->dma_desc_array_phys; - dma_buff_phys = runtime->dma_addr; - do { - next_desc_phys += sizeof(pxa_dma_desc); - dma_desc->ddadr = next_desc_phys; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - dma_desc->dsadr = dma_buff_phys; - dma_desc->dtadr = rtd->params->dev_addr; - } else { - dma_desc->dsadr = rtd->params->dev_addr; - dma_desc->dtadr = dma_buff_phys; - } - if (period > totsize) - period = totsize; - dma_desc->dcmd = rtd->params->dcmd | period | DCMD_ENDIRQEN; - dma_desc++; - dma_buff_phys += period; - } while (totsize -= period); - dma_desc[-1].ddadr = rtd->dma_desc_array_phys; - - return 0; -} - -static int pxa2xx_pcm_hw_free(snd_pcm_substream_t *substream) -{ - struct pxa2xx_runtime_data *rtd = substream->runtime->private_data; - - *rtd->params->drcmr = 0; - snd_pcm_set_runtime_buffer(substream, NULL); - return 0; -} - -static int pxa2xx_pcm_prepare(snd_pcm_substream_t *substream) -{ - pxa2xx_pcm_client_t *client = substream->private_data; - snd_pcm_runtime_t *runtime = substream->runtime; - struct pxa2xx_runtime_data *rtd = runtime->private_data; - - DCSR(rtd->dma_ch) &= ~DCSR_RUN; - DCSR(rtd->dma_ch) = 0; - DCMD(rtd->dma_ch) = 0; - *rtd->params->drcmr = rtd->dma_ch | DRCMR_MAPVLD; - - return client->prepare(substream); -} - -static int pxa2xx_pcm_trigger(snd_pcm_substream_t *substream, int cmd) -{ - struct pxa2xx_runtime_data *rtd = substream->runtime->private_data; - int ret = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - DDADR(rtd->dma_ch) = rtd->dma_desc_array_phys; - DCSR(rtd->dma_ch) = DCSR_RUN; - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - DCSR(rtd->dma_ch) &= ~DCSR_RUN; - break; - - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - DCSR(rtd->dma_ch) |= DCSR_RUN; - break; - - default: - ret = -EINVAL; - } - - return ret; -} - -static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id, struct pt_regs *regs) -{ - snd_pcm_substream_t *substream = dev_id; - struct pxa2xx_runtime_data *rtd = substream->runtime->private_data; - int dcsr; - - dcsr = DCSR(dma_ch); - DCSR(dma_ch) = dcsr & ~DCSR_STOPIRQEN; - - if (dcsr & DCSR_ENDINTR) { - snd_pcm_period_elapsed(substream); - } else { - printk( KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n", - rtd->params->name, dma_ch, dcsr ); - snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); - } -} - -static snd_pcm_uframes_t pxa2xx_pcm_pointer(snd_pcm_substream_t *substream) -{ - snd_pcm_runtime_t *runtime = substream->runtime; - struct pxa2xx_runtime_data *rtd = runtime->private_data; - dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? - DSADR(rtd->dma_ch) : DTADR(rtd->dma_ch); - snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr); - if (x == runtime->buffer_size) - x = 0; - return x; -} - -static int -pxa2xx_pcm_hw_rule_mult32(snd_pcm_hw_params_t *params, snd_pcm_hw_rule_t *rule) -{ - snd_interval_t *i = hw_param_interval(params, rule->var); - int changed = 0; - - if (i->min & 31) { - i->min = (i->min & ~31) + 32; - i->openmin = 0; - changed = 1; - } - - if (i->max & 31) { - i->max &= ~31; - i->openmax = 0; - changed = 1; - } - - return changed; -} - -static int pxa2xx_pcm_open(snd_pcm_substream_t *substream) -{ - pxa2xx_pcm_client_t *client = substream->private_data; - snd_pcm_runtime_t *runtime = substream->runtime; - struct pxa2xx_runtime_data *rtd; - int ret; - - runtime->hw = pxa2xx_pcm_hardware; - - /* - * For mysterious reasons (and despite what the manual says) - * playback samples are lost if the DMA count is not a multiple - * of the DMA burst size. Let's add a rule to enforce that. - */ - ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, - pxa2xx_pcm_hw_rule_mult32, NULL, - SNDRV_PCM_HW_PARAM_PERIOD_BYTES, -1); - if (ret) - goto out; - ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - pxa2xx_pcm_hw_rule_mult32, NULL, - SNDRV_PCM_HW_PARAM_BUFFER_BYTES, -1); - if (ret) - goto out; - - ret = -ENOMEM; - rtd = kmalloc(sizeof(*rtd), GFP_KERNEL); - if (!rtd) - goto out; - rtd->dma_desc_array = - dma_alloc_writecombine(substream->pcm->card->dev, PAGE_SIZE, - &rtd->dma_desc_array_phys, GFP_KERNEL); - if (!rtd->dma_desc_array) - goto err1; - - rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? - client->playback_params : client->capture_params; - ret = pxa_request_dma(rtd->params->name, DMA_PRIO_LOW, - pxa2xx_pcm_dma_irq, substream); - if (ret < 0) - goto err2; - rtd->dma_ch = ret; - - runtime->private_data = rtd; - ret = client->startup(substream); - if (!ret) - goto out; - - pxa_free_dma(rtd->dma_ch); - err2: - dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE, - rtd->dma_desc_array, rtd->dma_desc_array_phys); - err1: - kfree(rtd); - out: - return ret; -} - -static int pxa2xx_pcm_close(snd_pcm_substream_t *substream) -{ - pxa2xx_pcm_client_t *client = substream->private_data; - struct pxa2xx_runtime_data *rtd = substream->runtime->private_data; - - pxa_free_dma(rtd->dma_ch); - client->shutdown(substream); - dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE, - rtd->dma_desc_array, rtd->dma_desc_array_phys); - kfree(rtd); - return 0; -} - -static int -pxa2xx_pcm_mmap(snd_pcm_substream_t *substream, struct vm_area_struct *vma) -{ - snd_pcm_runtime_t *runtime = substream->runtime; - return dma_mmap_writecombine(substream->pcm->card->dev, vma, - runtime->dma_area, - runtime->dma_addr, - runtime->dma_bytes); -} - -static snd_pcm_ops_t pxa2xx_pcm_ops = { - .open = pxa2xx_pcm_open, - .close = pxa2xx_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = pxa2xx_pcm_hw_params, - .hw_free = pxa2xx_pcm_hw_free, - .prepare = pxa2xx_pcm_prepare, - .trigger = pxa2xx_pcm_trigger, - .pointer = pxa2xx_pcm_pointer, - .mmap = pxa2xx_pcm_mmap, -}; - -static int pxa2xx_pcm_preallocate_dma_buffer(snd_pcm_t *pcm, int stream) -{ - snd_pcm_substream_t *substream = pcm->streams[stream].substream; - struct snd_dma_buffer *buf = &substream->dma_buffer; - size_t size = pxa2xx_pcm_hardware.buffer_bytes_max; - buf->dev.type = SNDRV_DMA_TYPE_DEV; - buf->dev.dev = pcm->card->dev; - buf->private_data = NULL; - buf->area = dma_alloc_writecombine(pcm->card->dev, size, - &buf->addr, GFP_KERNEL); - if (!buf->area) - return -ENOMEM; - buf->bytes = size; - return 0; -} - -static void pxa2xx_pcm_free_dma_buffers(snd_pcm_t *pcm) -{ - snd_pcm_substream_t *substream; - struct snd_dma_buffer *buf; - int stream; - - for (stream = 0; stream < 2; stream++) { - substream = pcm->streams[stream].substream; - if (!substream) - continue; - buf = &substream->dma_buffer; - if (!buf->area) - continue; - dma_free_writecombine(pcm->card->dev, buf->bytes, - buf->area, buf->addr); - buf->area = NULL; - } -} - -static u64 pxa2xx_pcm_dmamask = 0xffffffff; - -int pxa2xx_pcm_new(snd_card_t *card, pxa2xx_pcm_client_t *client, snd_pcm_t **rpcm) -{ - snd_pcm_t *pcm; - int play = client->playback_params ? 1 : 0; - int capt = client->capture_params ? 1 : 0; - int ret; - - ret = snd_pcm_new(card, "PXA2xx-PCM", 0, play, capt, &pcm); - if (ret) - goto out; - - pcm->private_data = client; - pcm->private_free = pxa2xx_pcm_free_dma_buffers; - - if (!card->dev->dma_mask) - card->dev->dma_mask = &pxa2xx_pcm_dmamask; - if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = 0xffffffff; - - if (play) { - int stream = SNDRV_PCM_STREAM_PLAYBACK; - snd_pcm_set_ops(pcm, stream, &pxa2xx_pcm_ops); - ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, stream); - if (ret) - goto out; - } - if (capt) { - int stream = SNDRV_PCM_STREAM_CAPTURE; - snd_pcm_set_ops(pcm, stream, &pxa2xx_pcm_ops); - ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, stream); - if (ret) - goto out; - } - - if (rpcm) - *rpcm = pcm; - ret = 0; - - out: - return ret; -} - -EXPORT_SYMBOL(pxa2xx_pcm_new); - -MODULE_AUTHOR("Nicolas Pitre"); -MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/arm/pxa2xx-pcm.h b/trunk/sound/arm/pxa2xx-pcm.h deleted file mode 100644 index 43517597cab9..000000000000 --- a/trunk/sound/arm/pxa2xx-pcm.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * linux/sound/arm/pxa2xx-pcm.h -- ALSA PCM interface for the Intel PXA2xx chip - * - * Author: Nicolas Pitre - * Created: Nov 30, 2004 - * Copyright: MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -typedef struct { - char *name; /* stream identifier */ - u32 dcmd; /* DMA descriptor dcmd field */ - volatile u32 *drcmr; /* the DMA request channel to use */ - u32 dev_addr; /* device physical address for DMA */ -} pxa2xx_pcm_dma_params_t; - -typedef struct { - pxa2xx_pcm_dma_params_t *playback_params; - pxa2xx_pcm_dma_params_t *capture_params; - int (*startup)(snd_pcm_substream_t *); - void (*shutdown)(snd_pcm_substream_t *); - int (*prepare)(snd_pcm_substream_t *); -} pxa2xx_pcm_client_t; - -extern int pxa2xx_pcm_new(snd_card_t *, pxa2xx_pcm_client_t *, snd_pcm_t **); - diff --git a/trunk/sound/core/device.c b/trunk/sound/core/device.c index ca00ad7740c9..18c71f913d2a 100644 --- a/trunk/sound/core/device.c +++ b/trunk/sound/core/device.c @@ -28,7 +28,7 @@ /** * snd_device_new - create an ALSA device component * @card: the card instance - * @type: the device type, SNDRV_DEV_XXX + * @type: the device type, SNDRV_DEV_TYPE_XXX * @device_data: the data pointer of this device * @ops: the operator table * @@ -46,9 +46,7 @@ int snd_device_new(snd_card_t *card, snd_device_type_t type, { snd_device_t *dev; - snd_assert(card != NULL, return -ENXIO); - snd_assert(device_data != NULL, return -ENXIO); - snd_assert(ops != NULL, return -ENXIO); + snd_assert(card != NULL && device_data != NULL && ops != NULL, return -ENXIO); dev = kcalloc(1, sizeof(*dev), GFP_KERNEL); if (dev == NULL) return -ENOMEM; @@ -104,7 +102,7 @@ int snd_device_free(snd_card_t *card, void *device_data) } /** - * snd_device_disconnect - disconnect the device + * snd_device_free - disconnect the device * @card: the card instance * @device_data: the data pointer to disconnect * @@ -120,7 +118,7 @@ int snd_device_disconnect(snd_card_t *card, void *device_data) { struct list_head *list; snd_device_t *dev; - + snd_assert(card != NULL, return -ENXIO); snd_assert(device_data != NULL, return -ENXIO); list_for_each(list, &card->devices) { @@ -156,9 +154,8 @@ int snd_device_register(snd_card_t *card, void *device_data) struct list_head *list; snd_device_t *dev; int err; - - snd_assert(card != NULL, return -ENXIO); - snd_assert(device_data != NULL, return -ENXIO); + + snd_assert(card != NULL && device_data != NULL, return -ENXIO); list_for_each(list, &card->devices) { dev = snd_device(list); if (dev->device_data != device_data) diff --git a/trunk/sound/core/info.c b/trunk/sound/core/info.c index 7f8bdf7b0058..5e122bbe7c92 100644 --- a/trunk/sound/core/info.c +++ b/trunk/sound/core/info.c @@ -702,7 +702,7 @@ int snd_info_get_line(snd_info_buffer_t * buffer, char *line, int len) } /** - * snd_info_get_str - parse a string token + * snd_info_get_line - parse a string token * @dest: the buffer to store the string token * @src: the original string * @len: the max. length of token - 1 @@ -939,8 +939,7 @@ int snd_info_unregister(snd_info_entry_t * entry) { struct proc_dir_entry *root; - snd_assert(entry != NULL, return -ENXIO); - snd_assert(entry->p != NULL, return -ENXIO); + snd_assert(entry != NULL && entry->p != NULL, return -ENXIO); root = entry->parent == NULL ? snd_proc_root : entry->parent->p; snd_assert(root, return -ENXIO); down(&info_mutex); diff --git a/trunk/sound/core/memalloc.c b/trunk/sound/core/memalloc.c index 02132561c3f8..dbc23e35fa06 100644 --- a/trunk/sound/core/memalloc.c +++ b/trunk/sound/core/memalloc.c @@ -105,8 +105,7 @@ struct snd_mem_list { */ static void *snd_dma_hack_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, - unsigned int __nocast flags) + dma_addr_t *dma_handle, int flags) { void *ret; u64 dma_mask, coherent_dma_mask; diff --git a/trunk/sound/core/memory.c b/trunk/sound/core/memory.c index f6895577bf86..c1fb28e84330 100644 --- a/trunk/sound/core/memory.c +++ b/trunk/sound/core/memory.c @@ -89,7 +89,7 @@ void snd_memory_done(void) } } -static void *__snd_kmalloc(size_t size, unsigned int __nocast flags, void *caller) +static void *__snd_kmalloc(size_t size, int flags, void *caller) { unsigned long cpu_flags; struct snd_alloc_track *t; @@ -111,12 +111,12 @@ static void *__snd_kmalloc(size_t size, unsigned int __nocast flags, void *calle } #define _snd_kmalloc(size, flags) __snd_kmalloc((size), (flags), __builtin_return_address(0)); -void *snd_hidden_kmalloc(size_t size, unsigned int __nocast flags) +void *snd_hidden_kmalloc(size_t size, int flags) { return _snd_kmalloc(size, flags); } -void *snd_hidden_kcalloc(size_t n, size_t size, unsigned int __nocast flags) +void *snd_hidden_kcalloc(size_t n, size_t size, int flags) { void *ret = NULL; if (n != 0 && size > INT_MAX / n) @@ -184,7 +184,7 @@ void snd_hidden_vfree(void *obj) snd_wrapper_vfree(obj); } -char *snd_hidden_kstrdup(const char *s, unsigned int __nocast flags) +char *snd_hidden_kstrdup(const char *s, int flags) { int len; char *buf; diff --git a/trunk/sound/core/seq/Makefile b/trunk/sound/core/seq/Makefile index 402e2b4a34c6..64cb50d7b589 100644 --- a/trunk/sound/core/seq/Makefile +++ b/trunk/sound/core/seq/Makefile @@ -38,7 +38,7 @@ obj-$(CONFIG_SND_VIRMIDI) += snd-seq-virmidi.o snd-seq-midi-event.o obj-$(call sequencer,$(CONFIG_SND_RAWMIDI)) += snd-seq-midi.o snd-seq-midi-event.o obj-$(call sequencer,$(CONFIG_SND_OPL3_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o obj-$(call sequencer,$(CONFIG_SND_OPL4_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o -obj-$(call sequencer,$(CONFIG_SND_GUS_SYNTH)) += snd-seq-midi-emul.o snd-seq-instr.o +obj-$(call sequencer,$(CONFIG_SND_GUS_SYNTH)) += snd-seq-instr.o obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-seq-midi-emul.o snd-seq-virmidi.o obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += snd-seq-midi-emul.o snd-seq-virmidi.o obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += snd-seq-midi-emul.o snd-seq-instr.o diff --git a/trunk/sound/core/seq/instr/ainstr_gf1.c b/trunk/sound/core/seq/instr/ainstr_gf1.c index 32e91c6b25fe..0779c41ca037 100644 --- a/trunk/sound/core/seq/instr/ainstr_gf1.c +++ b/trunk/sound/core/seq/instr/ainstr_gf1.c @@ -50,8 +50,7 @@ static int snd_seq_gf1_copy_wave_from_stream(snd_gf1_ops_t *ops, { gf1_wave_t *wp, *prev; gf1_xwave_t xp; - int err; - unsigned int gfp_mask; + int err, gfp_mask; unsigned int real_size; gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; diff --git a/trunk/sound/core/seq/instr/ainstr_iw.c b/trunk/sound/core/seq/instr/ainstr_iw.c index 2622b8679ca7..39ff72b2aab3 100644 --- a/trunk/sound/core/seq/instr/ainstr_iw.c +++ b/trunk/sound/core/seq/instr/ainstr_iw.c @@ -58,7 +58,7 @@ static int snd_seq_iwffff_copy_env_from_stream(__u32 req_stype, iwffff_xenv_t *ex, char __user **data, long *len, - unsigned int __nocast gfp_mask) + int gfp_mask) { __u32 stype; iwffff_env_record_t *rp, *rp_last; @@ -128,8 +128,7 @@ static int snd_seq_iwffff_copy_wave_from_stream(snd_iwffff_ops_t *ops, { iwffff_wave_t *wp, *prev; iwffff_xwave_t xp; - int err; - unsigned int gfp_mask; + int err, gfp_mask; unsigned int real_size; gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; @@ -235,8 +234,7 @@ static int snd_seq_iwffff_put(void *private_data, snd_seq_kinstr_t *instr, iwffff_xinstrument_t ix; iwffff_layer_t *lp, *prev_lp; iwffff_xlayer_t lx; - int err; - unsigned int gfp_mask; + int err, gfp_mask; if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE) return -EINVAL; diff --git a/trunk/sound/core/seq/seq_midi.c b/trunk/sound/core/seq/seq_midi.c index 4374829ea770..57be9155eb62 100644 --- a/trunk/sound/core/seq/seq_midi.c +++ b/trunk/sound/core/seq/seq_midi.c @@ -134,7 +134,7 @@ static int event_process_midi(snd_seq_event_t * ev, int direct, seq_midisynth_t *msynth = (seq_midisynth_t *) private_data; unsigned char msg[10]; /* buffer for constructing midi messages */ snd_rawmidi_substream_t *substream; - int len; + int res; snd_assert(msynth != NULL, return -EINVAL); substream = msynth->output_rfile.output; @@ -146,16 +146,20 @@ static int event_process_midi(snd_seq_event_t * ev, int direct, snd_printd("seq_midi: invalid sysex event flags = 0x%x\n", ev->flags); return 0; } - snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)dump_midi, substream); + res = snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)dump_midi, substream); snd_midi_event_reset_decode(msynth->parser); + if (res < 0) + return res; } else { if (msynth->parser == NULL) return -EIO; - len = snd_midi_event_decode(msynth->parser, msg, sizeof(msg), ev); - if (len < 0) - return 0; - if (dump_midi(substream, msg, len) < 0) + res = snd_midi_event_decode(msynth->parser, msg, sizeof(msg), ev); + if (res < 0) + return res; + if ((res = dump_midi(substream, msg, res)) < 0) { snd_midi_event_reset_decode(msynth->parser); + return res; + } } return 0; } diff --git a/trunk/sound/core/wrappers.c b/trunk/sound/core/wrappers.c index 508e6d67ee19..9f393023c327 100644 --- a/trunk/sound/core/wrappers.c +++ b/trunk/sound/core/wrappers.c @@ -27,7 +27,7 @@ #include #ifdef CONFIG_SND_DEBUG_MEMORY -void *snd_wrapper_kmalloc(size_t size, unsigned int __nocast flags) +void *snd_wrapper_kmalloc(size_t size, int flags) { return kmalloc(size, flags); } diff --git a/trunk/sound/drivers/vx/vx_uer.c b/trunk/sound/drivers/vx/vx_uer.c index 4fc38bde34f4..18114713c3b3 100644 --- a/trunk/sound/drivers/vx/vx_uer.c +++ b/trunk/sound/drivers/vx/vx_uer.c @@ -162,24 +162,34 @@ static int vx_read_uer_status(vx_core_t *chip, int *mode) static int vx_calc_clock_from_freq(vx_core_t *chip, int freq) { - int hexfreq; - - snd_assert(freq > 0, return 0); - - hexfreq = (28224000 * 10) / freq; - hexfreq = (hexfreq + 5) / 10; - - /* max freq = 55125 Hz */ - snd_assert(hexfreq > 0x00000200, return 0); - - if (hexfreq <= 0x03ff) - return hexfreq - 0x00000201; - if (hexfreq <= 0x07ff) - return (hexfreq / 2) - 1; - if (hexfreq <= 0x0fff) - return (hexfreq / 4) + 0x000001ff; - - return 0x5fe; /* min freq = 6893 Hz */ +#define XX_FECH48000 0x0000004B +#define XX_FECH32000 0x00000171 +#define XX_FECH24000 0x0000024B +#define XX_FECH16000 0x00000371 +#define XX_FECH12000 0x0000044B +#define XX_FECH8000 0x00000571 +#define XX_FECH44100 0x0000007F +#define XX_FECH29400 0x0000016F +#define XX_FECH22050 0x0000027F +#define XX_FECH14000 0x000003EF +#define XX_FECH11025 0x0000047F +#define XX_FECH7350 0x000005BF + + switch (freq) { + case 48000: return XX_FECH48000; + case 44100: return XX_FECH44100; + case 32000: return XX_FECH32000; + case 29400: return XX_FECH29400; + case 24000: return XX_FECH24000; + case 22050: return XX_FECH22050; + case 16000: return XX_FECH16000; + case 14000: return XX_FECH14000; + case 12000: return XX_FECH12000; + case 11025: return XX_FECH11025; + case 8000: return XX_FECH8000; + case 7350: return XX_FECH7350; + default: return freq; /* The value is already correct */ + } } diff --git a/trunk/sound/i2c/other/ak4114.c b/trunk/sound/i2c/other/ak4114.c index 5adde308a00f..f5e6018ea3f4 100644 --- a/trunk/sound/i2c/other/ak4114.c +++ b/trunk/sound/i2c/other/ak4114.c @@ -554,6 +554,7 @@ int snd_ak4114_check_rate_and_errors(ak4114_t *ak4114, unsigned int flags) if (snd_pcm_running(ak4114->capture_substream)) { // printk("rate changed (%i <- %i)\n", runtime->rate, res); snd_pcm_stop(ak4114->capture_substream, SNDRV_PCM_STATE_DRAINING); + wake_up(&runtime->sleep); res = 1; } snd_pcm_stream_unlock_irqrestore(ak4114->capture_substream, _flags); diff --git a/trunk/sound/isa/gus/gus_main.c b/trunk/sound/isa/gus/gus_main.c index a636d9ce3502..94bbd344be5e 100644 --- a/trunk/sound/isa/gus/gus_main.c +++ b/trunk/sound/isa/gus/gus_main.c @@ -417,13 +417,11 @@ static int snd_gus_check_version(snd_gus_card_t * gus) return 0; } -#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) static void snd_gus_seq_dev_free(snd_seq_device_t *seq_dev) { snd_gus_card_t *gus = seq_dev->private_data; gus->seq_dev = NULL; } -#endif int snd_gus_initialize(snd_gus_card_t *gus) { diff --git a/trunk/sound/isa/wavefront/wavefront_fx.c b/trunk/sound/isa/wavefront/wavefront_fx.c index 32379688eed4..0e13623f69f0 100644 --- a/trunk/sound/isa/wavefront/wavefront_fx.c +++ b/trunk/sound/isa/wavefront/wavefront_fx.c @@ -34,7 +34,7 @@ /* weird stuff, derived from port I/O tracing with dosemu */ -static unsigned char page_zero[] __initdata = { +unsigned char page_zero[] __initdata = { 0x01, 0x7c, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x11, 0x00, 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x02, 0x76, 0x00, 0x60, 0x00, 0x80, 0x02, 0x00, 0x00, @@ -61,7 +61,7 @@ static unsigned char page_zero[] __initdata = { 0x1d, 0x02, 0xdf }; -static unsigned char page_one[] __initdata = { +unsigned char page_one[] __initdata = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x19, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xd8, 0x00, 0x00, 0x02, 0x20, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, @@ -88,7 +88,7 @@ static unsigned char page_one[] __initdata = { 0x60, 0x00, 0x1b }; -static unsigned char page_two[] __initdata = { +unsigned char page_two[] __initdata = { 0xc4, 0x00, 0x44, 0x07, 0x44, 0x00, 0x40, 0x25, 0x01, 0x06, 0xc4, 0x07, 0x40, 0x25, 0x01, 0x00, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -103,7 +103,7 @@ static unsigned char page_two[] __initdata = { 0x46, 0x05, 0x46, 0x07, 0x46, 0x07, 0x44 }; -static unsigned char page_three[] __initdata = { +unsigned char page_three[] __initdata = { 0x07, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x40, 0x00, 0x40, 0x06, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -118,7 +118,7 @@ static unsigned char page_three[] __initdata = { 0x02, 0x00, 0x42, 0x00, 0xc0, 0x00, 0x40 }; -static unsigned char page_four[] __initdata = { +unsigned char page_four[] __initdata = { 0x63, 0x03, 0x26, 0x02, 0x2c, 0x00, 0x24, 0x00, 0x2e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -133,7 +133,7 @@ static unsigned char page_four[] __initdata = { 0x02, 0x62, 0x02, 0x20, 0x01, 0x21, 0x01 }; -static unsigned char page_six[] __initdata = { +unsigned char page_six[] __initdata = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x10, 0x00, 0x00, 0x12, 0x00, 0x00, 0x14, 0x00, 0x00, @@ -154,7 +154,7 @@ static unsigned char page_six[] __initdata = { 0x80, 0x00, 0x7e, 0x80, 0x80 }; -static unsigned char page_seven[] __initdata = { +unsigned char page_seven[] __initdata = { 0x0f, 0xff, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, @@ -181,7 +181,7 @@ static unsigned char page_seven[] __initdata = { 0x00, 0x02, 0x00 }; -static unsigned char page_zero_v2[] __initdata = { +unsigned char page_zero_v2[] __initdata = { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -193,7 +193,7 @@ static unsigned char page_zero_v2[] __initdata = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static unsigned char page_one_v2[] __initdata = { +unsigned char page_one_v2[] __initdata = { 0x01, 0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -205,21 +205,21 @@ static unsigned char page_one_v2[] __initdata = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static unsigned char page_two_v2[] __initdata = { +unsigned char page_two_v2[] __initdata = { 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static unsigned char page_three_v2[] __initdata = { +unsigned char page_three_v2[] __initdata = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static unsigned char page_four_v2[] __initdata = { +unsigned char page_four_v2[] __initdata = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -227,7 +227,7 @@ static unsigned char page_four_v2[] __initdata = { 0x00, 0x00, 0x00, 0x00 }; -static unsigned char page_seven_v2[] __initdata = { +unsigned char page_seven_v2[] __initdata = { 0x0f, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -239,7 +239,7 @@ static unsigned char page_seven_v2[] __initdata = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static unsigned char mod_v2[] __initdata = { +unsigned char mod_v2[] __initdata = { 0x01, 0x00, 0x02, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x03, 0x02, 0x00, 0x01, 0x04, 0x02, 0x00, 0x01, 0x05, 0x02, 0x00, 0x01, 0x06, 0x02, 0x00, 0x01, 0x07, 0x02, 0x00, 0xb0, @@ -269,7 +269,7 @@ static unsigned char mod_v2[] __initdata = { 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x05, 0x02, 0x01, 0x01, 0x06, 0x02, 0x01, 0x01, 0x07, 0x02, 0x01 }; -static unsigned char coefficients[] __initdata = { +unsigned char coefficients[] __initdata = { 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x03, 0x11, 0x00, 0x4d, 0x01, 0x32, 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x01, @@ -305,14 +305,14 @@ static unsigned char coefficients[] __initdata = { 0x06, 0x6c, 0x4c, 0x6c, 0x06, 0x50, 0x52, 0xe2, 0x06, 0x42, 0x02, 0xba }; -static unsigned char coefficients2[] __initdata = { +unsigned char coefficients2[] __initdata = { 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x45, 0x0f, 0xff, 0x07, 0x48, 0x0f, 0xff, 0x07, 0x7b, 0x04, 0xcc, 0x07, 0x7d, 0x04, 0xcc, 0x07, 0x7c, 0x00, 0x00, 0x07, 0x7e, 0x00, 0x00, 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00, 0x07, 0x4a, 0x00, 0x00, 0x07, 0x4c, 0x00, 0x00, 0x07, 0x4e, 0x00, 0x00 }; -static unsigned char coefficients3[] __initdata = { +unsigned char coefficients3[] __initdata = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x00, 0x51, 0x00, 0x51, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xf5, 0x00, 0xf5, 0x01, 0x1e, 0x01, 0x1e, 0x01, diff --git a/trunk/sound/pci/ac97/ac97_codec.c b/trunk/sound/pci/ac97/ac97_codec.c index 6983eea226da..a4b72cd2eea0 100644 --- a/trunk/sound/pci/ac97/ac97_codec.c +++ b/trunk/sound/pci/ac97/ac97_codec.c @@ -367,7 +367,6 @@ int snd_ac97_update(ac97_t *ac97, unsigned short reg, unsigned short value) ac97->regs[reg] = value; ac97->bus->ops->write(ac97, reg, value); } - set_bit(reg, ac97->reg_accessed); up(&ac97->reg_mutex); return change; } @@ -411,7 +410,6 @@ int snd_ac97_update_bits_nolock(ac97_t *ac97, unsigned short reg, ac97->regs[reg] = new; ac97->bus->ops->write(ac97, reg, new); } - set_bit(reg, ac97->reg_accessed); return change; } @@ -1078,11 +1076,6 @@ static void check_volume_resolution(ac97_t *ac97, int reg, unsigned char *lo_max for (i = 0 ; i < ARRAY_SIZE(cbit); i++) { unsigned short val; snd_ac97_write(ac97, reg, 0x8080 | cbit[i] | (cbit[i] << 8)); - /* Do the read twice due to buffers on some ac97 codecs. - * e.g. The STAC9704 returns exactly what you wrote the the register - * if you read it immediately. This causes the detect routine to fail. - */ - val = snd_ac97_read(ac97, reg); val = snd_ac97_read(ac97, reg); if (! *lo_max && (val & 0x7f) == cbit[i]) *lo_max = max[i]; @@ -2231,7 +2224,7 @@ void snd_ac97_restore_iec958(ac97_t *ac97) */ void snd_ac97_resume(ac97_t *ac97) { - unsigned long end_time; + int i; if (ac97->bus->ops->reset) { ac97->bus->ops->reset(ac97); @@ -2249,26 +2242,26 @@ void snd_ac97_resume(ac97_t *ac97) snd_ac97_write(ac97, AC97_POWERDOWN, ac97->regs[AC97_POWERDOWN]); if (ac97_is_audio(ac97)) { ac97->bus->ops->write(ac97, AC97_MASTER, 0x8101); - end_time = jiffies + msecs_to_jiffies(100); - do { + for (i = HZ/10; i >= 0; i--) { if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101) break; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1); - } while (time_after_eq(end_time, jiffies)); + } /* FIXME: extra delay */ ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000); - if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) - msleep(250); + if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/4); + } } else { - end_time = jiffies + msecs_to_jiffies(100); - do { + for (i = HZ/10; i >= 0; i--) { unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID); if (val != 0xffff && (val & 1) != 0) break; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1); - } while (time_after_eq(end_time, jiffies)); + } } __reset_ready: diff --git a/trunk/sound/pci/ac97/ac97_patch.c b/trunk/sound/pci/ac97/ac97_patch.c index 66edc857d3e6..a15eb8522b7c 100644 --- a/trunk/sound/pci/ac97/ac97_patch.c +++ b/trunk/sound/pci/ac97/ac97_patch.c @@ -1528,9 +1528,6 @@ static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = { }, AC97_SURROUND_JACK_MODE_CTL, AC97_CHANNEL_MODE_CTL, - - AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0), - AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0), }; static int patch_ad1888_specific(ac97_t *ac97) diff --git a/trunk/sound/pci/ali5451/ali5451.c b/trunk/sound/pci/ali5451/ali5451.c index f08ae71f902d..eb5c36d31a52 100644 --- a/trunk/sound/pci/ali5451/ali5451.c +++ b/trunk/sound/pci/ali5451/ali5451.c @@ -399,7 +399,7 @@ static int snd_ali_codec_ready( ali_t *codec, unsigned long end_time; unsigned int res; - end_time = jiffies + 10 * msecs_to_jiffies(250); + end_time = jiffies + 10 * (HZ >> 2); do { res = snd_ali_5451_peek(codec,port); if (! (res & 0x8000)) @@ -422,7 +422,7 @@ static int snd_ali_stimer_ready(ali_t *codec, int sched) dwChk1 = snd_ali_5451_peek(codec, ALI_STIMER); dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER); - end_time = jiffies + 10 * msecs_to_jiffies(250); + end_time = jiffies + 10 * (HZ >> 2); do { dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER); if (dwChk2 != dwChk1) diff --git a/trunk/sound/pci/atiixp_modem.c b/trunk/sound/pci/atiixp_modem.c index 8d2002951bd7..a6b4b8d589fd 100644 --- a/trunk/sound/pci/atiixp_modem.c +++ b/trunk/sound/pci/atiixp_modem.c @@ -265,7 +265,6 @@ struct snd_atiixp { */ static struct pci_device_id snd_atiixp_ids[] = { { 0x1002, 0x434d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */ - { 0x1002, 0x4378, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB400 */ { 0, } }; diff --git a/trunk/sound/pci/cmipci.c b/trunk/sound/pci/cmipci.c index f5a4ac1ceef9..4725b4a010be 100644 --- a/trunk/sound/pci/cmipci.c +++ b/trunk/sound/pci/cmipci.c @@ -306,7 +306,7 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); #define CM_REG_FM_PCI 0x50 /* - * access from SB-mixer port + * for CMI-8338 .. this is not valid for CMI-8738. */ #define CM_REG_EXTENT_IND 0xf0 #define CM_VPHONE_MASK 0xe0 /* Phone volume control (0-3) << 5 */ @@ -315,7 +315,6 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); #define CM_VSPKM 0x08 /* Speaker mute control, default high */ #define CM_RLOOPREN 0x04 /* Rec. R-channel enable */ #define CM_RLOOPLEN 0x02 /* Rec. L-channel enable */ -#define CM_VADMIC3 0x01 /* Mic record boost */ /* * CMI-8338 spec ver 0.5 (this is not valid for CMI-8738): @@ -2136,12 +2135,8 @@ static snd_kcontrol_new_t snd_cmipci_mixers[] __devinitdata = { CMIPCI_MIXER_VOL_STEREO("Aux Playback Volume", CM_REG_AUX_VOL, 4, 0, 15), CMIPCI_MIXER_SW_STEREO("Aux Playback Switch", CM_REG_MIXER2, CM_VAUXLM_SHIFT, CM_VAUXRM_SHIFT, 0), CMIPCI_MIXER_SW_STEREO("Aux Capture Switch", CM_REG_MIXER2, CM_RAUXLEN_SHIFT, CM_RAUXREN_SHIFT, 0), - CMIPCI_MIXER_SW_MONO("Mic Boost Playback Switch", CM_REG_MIXER2, CM_MICGAINZ_SHIFT, 1), + CMIPCI_MIXER_SW_MONO("Mic Boost", CM_REG_MIXER2, CM_MICGAINZ_SHIFT, 1), CMIPCI_MIXER_VOL_MONO("Mic Capture Volume", CM_REG_MIXER2, CM_VADMIC_SHIFT, 7), - CMIPCI_SB_VOL_MONO("Phone Playback Volume", CM_REG_EXTENT_IND, 5, 7), - CMIPCI_DOUBLE("Phone Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 4, 4, 1, 0, 0), - CMIPCI_DOUBLE("PC Speaker Playnack Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0), - CMIPCI_DOUBLE("Mic Boost Capture Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 0, 0, 1, 0, 0), }; /* diff --git a/trunk/sound/pci/cs46xx/cs46xx_lib.c b/trunk/sound/pci/cs46xx/cs46xx_lib.c index ff28af1f658e..fd4c50c88bc9 100644 --- a/trunk/sound/pci/cs46xx/cs46xx_lib.c +++ b/trunk/sound/pci/cs46xx/cs46xx_lib.c @@ -2400,7 +2400,8 @@ static void snd_cs46xx_codec_reset (ac97_t * ac97) if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05) return; - msleep(10); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/100); } while (time_after_eq(end_time, jiffies)); snd_printk("CS46xx secondary codec dont respond!\n"); @@ -2434,7 +2435,8 @@ static int __devinit cs46xx_detect_codec(cs46xx_t *chip, int codec) err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]); return err; } - msleep(10); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ/100); } snd_printdd("snd_cs46xx: codec %d detection timeout\n", codec); return -ENXIO; @@ -3016,7 +3018,8 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip) /* * Wait until the PLL has stabilized. */ - msleep(100); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/10); /* 100ms */ /* * Turn on clocking of the core so that we can setup the serial ports. @@ -3069,7 +3072,8 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip) */ if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY) goto ok1; - msleep(10); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((HZ+99)/100); } @@ -3118,7 +3122,8 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip) */ if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4)) goto ok2; - msleep(10); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((HZ+99)/100); } #ifndef CONFIG_SND_CS46XX_NEW_DSP diff --git a/trunk/sound/pci/emu10k1/emu10k1.c b/trunk/sound/pci/emu10k1/emu10k1.c index b17142cabead..2085a998eaeb 100644 --- a/trunk/sound/pci/emu10k1/emu10k1.c +++ b/trunk/sound/pci/emu10k1/emu10k1.c @@ -52,7 +52,6 @@ static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4}; static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64}; static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128}; static int enable_ir[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; -static uint subsystem[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* Force card subsystem model */ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard."); @@ -72,8 +71,7 @@ module_param_array(max_buffer_size, int, NULL, 0444); MODULE_PARM_DESC(max_buffer_size, "Maximum sample buffer size in MB."); module_param_array(enable_ir, bool, NULL, 0444); MODULE_PARM_DESC(enable_ir, "Enable IR."); -module_param_array(subsystem, uint, NULL, 0444); -MODULE_PARM_DESC(subsystem, "Force card subsystem model."); + /* * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400 */ @@ -124,7 +122,7 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci, max_buffer_size[dev] = 1024; if ((err = snd_emu10k1_create(card, pci, extin[dev], extout[dev], (long)max_buffer_size[dev] * 1024 * 1024, - enable_ir[dev], subsystem[dev], + enable_ir[dev], &emu)) < 0) { snd_card_free(card); return err; @@ -142,7 +140,7 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci, return err; } /* This stores the periods table. */ - if (emu->card_capabilities->ca0151_chip) { /* P16V */ + if (emu->audigy && emu->revision == 4) { /* P16V */ if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024, &emu->p16v_buffer) < 0) { snd_p16v_free(emu); return -ENOMEM; @@ -163,7 +161,7 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci, snd_card_free(card); return err; } - if (emu->card_capabilities->ca0151_chip) { /* P16V */ + if (emu->audigy && emu->revision == 4) { /* P16V */ if ((err = snd_p16v_pcm(emu, 4, NULL)) < 0) { snd_card_free(card); return err; diff --git a/trunk/sound/pci/emu10k1/emu10k1_main.c b/trunk/sound/pci/emu10k1/emu10k1_main.c index 746b51ef3966..a341e758acde 100644 --- a/trunk/sound/pci/emu10k1/emu10k1_main.c +++ b/trunk/sound/pci/emu10k1/emu10k1_main.c @@ -191,7 +191,7 @@ static int __devinit snd_emu10k1_init(emu10k1_t * emu, int enable_ir) /* Set playback routing. */ snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, 0x78e4); } - if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */ + if (emu->audigy && (emu->serial == 0x10011102) ) { /* audigy2 Value */ /* Hacks for Alice3 to work independent of haP16V driver */ u32 tmp; @@ -253,8 +253,6 @@ static int __devinit snd_emu10k1_init(emu10k1_t * emu, int enable_ir) HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); else outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); - /* FIXME: Remove all these emu->model and replace it with a card recognition parameter, - * e.g. card_capabilities->joystick */ } else if (emu->model == 0x20 || emu->model == 0xc400 || (emu->model == 0x21 && emu->revision < 6)) @@ -301,12 +299,12 @@ static int __devinit snd_emu10k1_init(emu10k1_t * emu, int enable_ir) if (emu->audigy) { outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG); - if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ + if (emu->revision == 4) { /* audigy2 */ /* Unmute Analog now. Set GPO6 to 1 for Apollo. * This has to be done after init ALice3 I2SOut beyond 48KHz. * So, sequence is important. */ outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG); - } else if (emu->card_capabilities->ca0108_chip) { /* audigy2 value */ + } else if (emu->serial == 0x10011102) { /* audigy2 value */ /* Unmute Analog now. */ outl(inl(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG); } else { @@ -616,7 +614,6 @@ static int snd_emu10k1_dev_free(snd_device_t *device) static emu_chip_details_t emu_chip_details[] = { /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/ - /* Tested by James@superbug.co.uk 3rd July 2005 */ {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102, .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]", .id = "Audigy2", @@ -630,14 +627,6 @@ static emu_chip_details_t emu_chip_details[] = { .emu10k2_chip = 1, .ca0108_chip = 1, .ac97_chip = 1} , - /* Tested by James@superbug.co.uk 8th July 2005. No sound available yet. */ - {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102, - .driver = "Audigy2", .name = "E-mu 1212m [4001]", - .id = "EMU1212m", - .emu10k2_chip = 1, - .ca0102_chip = 1, - .ecard = 1} , - /* Tested by James@superbug.co.uk 3rd July 2005 */ {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102, .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", .id = "Audigy2", @@ -698,18 +687,18 @@ static emu_chip_details_t emu_chip_details[] = { .ca0151_chip = 1, .spdif_bug = 1, .ac97_chip = 1} , - {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102, - .driver = "Audigy", .name = "Audigy 1 [SB0090]", + {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10020052, + .driver = "Audigy", .name = "Audigy 1 ES [SB0160]", .id = "Audigy", .emu10k2_chip = 1, .ca0102_chip = 1, + .spdif_bug = 1, .ac97_chip = 1} , - {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00521102, - .driver = "Audigy", .name = "Audigy 1 ES [SB0160]", + {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102, + .driver = "Audigy", .name = "Audigy 1 [SB0090]", .id = "Audigy", .emu10k2_chip = 1, .ca0102_chip = 1, - .spdif_bug = 1, .ac97_chip = 1} , {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102, .driver = "Audigy", .name = "Audigy 1 [SB0090]", @@ -723,49 +712,54 @@ static emu_chip_details_t emu_chip_details[] = { .emu10k2_chip = 1, .ca0102_chip = 1, .ac97_chip = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806B1102, - .driver = "EMU10K1", .name = "SBLive! [SB0105]", + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102, + .driver = "EMU10K1", .name = "E-mu APS [4001]", + .id = "APS", + .emu10k1_chip = 1, + .ecard = 1} , + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102, + .driver = "EMU10K1", .name = "SBLive! Player 5.1 [SB0060]", .id = "Live", .emu10k1_chip = 1, .ac97_chip = 1, .sblive51 = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806A1102, - .driver = "EMU10K1", .name = "SBLive! Value [SB0103]", + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102, + .driver = "EMU10K1", .name = "SB Live 5.1", .id = "Live", .emu10k1_chip = 1, .ac97_chip = 1, .sblive51 = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102, - .driver = "EMU10K1", .name = "SBLive! Value [SB0101]", + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102, + .driver = "EMU10K1", .name = "SBLive! Platinum [CT4760P]", .id = "Live", .emu10k1_chip = 1, - .ac97_chip = 1, - .sblive51 = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102, - .driver = "EMU10K1", .name = "SB Live 5.1", + .ac97_chip = 1} , + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102, + .driver = "EMU10K1", .name = "SBLive! [CT4620]", .id = "Live", .emu10k1_chip = 1, .ac97_chip = 1, .sblive51 = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102, - .driver = "EMU10K1", .name = "SBLive! Player 5.1 [SB0060]", + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102, + .driver = "EMU10K1", .name = "SBLive! Value [CT4670]", .id = "Live", .emu10k1_chip = 1, .ac97_chip = 1, .sblive51 = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102, - .driver = "EMU10K1", .name = "SBLive! Value [CT4850]", + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102, + .driver = "EMU10K1", .name = "SBLive! Value [CT4780]", .id = "Live", .emu10k1_chip = 1, .ac97_chip = 1, .sblive51 = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102, - .driver = "EMU10K1", .name = "SBLive! Platinum [CT4760P]", + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102, + .driver = "EMU10K1", .name = "SB PCI512 [CT4790]", .id = "Live", .emu10k1_chip = 1, - .ac97_chip = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102, - .driver = "EMU10K1", .name = "SBLive! Value [CT4871]", + .ac97_chip = 1, + .sblive51 = 1} , + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102, + .driver = "EMU10K1", .name = "SBLive! Value [CT4830]", .id = "Live", .emu10k1_chip = 1, .ac97_chip = 1, @@ -776,50 +770,50 @@ static emu_chip_details_t emu_chip_details[] = { .emu10k1_chip = 1, .ac97_chip = 1, .sblive51 = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102, - .driver = "EMU10K1", .name = "SBLive! Value [CT4870]", + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102, + .driver = "EMU10K1", .name = "SBLive! Value [CT4832]", .id = "Live", .emu10k1_chip = 1, .ac97_chip = 1, .sblive51 = 1} , - /* Tested by James@superbug.co.uk 3rd July 2005 */ - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102, - .driver = "EMU10K1", .name = "SBLive! Value [CT4832]", + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102, + .driver = "EMU10K1", .name = "SBLive! Value [CT4850]", .id = "Live", .emu10k1_chip = 1, .ac97_chip = 1, .sblive51 = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102, - .driver = "EMU10K1", .name = "SBLive! Value [CT4830]", + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102, + .driver = "EMU10K1", .name = "SBLive! Value [CT4870]", .id = "Live", .emu10k1_chip = 1, .ac97_chip = 1, .sblive51 = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102, - .driver = "EMU10K1", .name = "SB PCI512 [CT4790]", + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102, + .driver = "EMU10K1", .name = "SBLive! Value [CT4871]", .id = "Live", .emu10k1_chip = 1, .ac97_chip = 1, .sblive51 = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102, - .driver = "EMU10K1", .name = "SBLive! Value [CT4780]", + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102, + .driver = "EMU10K1", .name = "SBLive! Value [SB0060]", .id = "Live", .emu10k1_chip = 1, .ac97_chip = 1, .sblive51 = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102, - .driver = "EMU10K1", .name = "E-mu APS [4001]", - .id = "APS", + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102, + .driver = "EMU10K1", .name = "SBLive! Value [SB0101]", + .id = "Live", .emu10k1_chip = 1, - .ecard = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102, - .driver = "EMU10K1", .name = "SBLive! [CT4620]", + .ac97_chip = 1, + .sblive51 = 1} , + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806A1102, + .driver = "EMU10K1", .name = "SBLive! Value [SB0103]", .id = "Live", .emu10k1_chip = 1, .ac97_chip = 1, .sblive51 = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102, - .driver = "EMU10K1", .name = "SBLive! Value [CT4670]", + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806B1102, + .driver = "EMU10K1", .name = "SBLive! [SB0105]", .id = "Live", .emu10k1_chip = 1, .ac97_chip = 1, @@ -839,7 +833,6 @@ int __devinit snd_emu10k1_create(snd_card_t * card, unsigned short extout_mask, long max_cache_bytes, int enable_ir, - uint subsystem, emu10k1_t ** remu) { emu10k1_t *emu; @@ -885,16 +878,10 @@ int __devinit snd_emu10k1_create(snd_card_t * card, for (c = emu_chip_details; c->vendor; c++) { if (c->vendor == pci->vendor && c->device == pci->device) { - if (subsystem) { - if (c->subsystem && (c->subsystem == subsystem) ) { - break; - } else continue; - } else { - if (c->subsystem && (c->subsystem != emu->serial) ) - continue; - if (c->revision && c->revision != emu->revision) - continue; - } + if (c->subsystem && c->subsystem != emu->serial) + continue; + if (c->revision && c->revision != emu->revision) + continue; break; } } @@ -905,14 +892,10 @@ int __devinit snd_emu10k1_create(snd_card_t * card, return -ENOENT; } emu->card_capabilities = c; - if (c->subsystem && !subsystem) + if (c->subsystem != 0) snd_printdd("Sound card name=%s\n", c->name); - else if (subsystem) - snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x. Forced to subsytem=0x%x\n", - c->name, pci->vendor, pci->device, emu->serial, c->subsystem); - else - snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x.\n", - c->name, pci->vendor, pci->device, emu->serial); + else + snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x\n", c->name, pci->vendor, pci->device, emu->serial); if (!*card->id && c->id) { int i, n = 0; diff --git a/trunk/sound/pci/emu10k1/p16v.c b/trunk/sound/pci/emu10k1/p16v.c index a1691330d3b6..98f980189892 100644 --- a/trunk/sound/pci/emu10k1/p16v.c +++ b/trunk/sound/pci/emu10k1/p16v.c @@ -822,7 +822,7 @@ static int snd_p16v_volume_put_analog_unknown(snd_kcontrol_t * kcontrol, static snd_kcontrol_new_t snd_p16v_volume_control_analog_front = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "HD Analog Front Playback Volume", + .name = "HD Analog Front Volume", .info = snd_p16v_volume_info, .get = snd_p16v_volume_get_analog_front, .put = snd_p16v_volume_put_analog_front @@ -831,7 +831,7 @@ static snd_kcontrol_new_t snd_p16v_volume_control_analog_front = static snd_kcontrol_new_t snd_p16v_volume_control_analog_center_lfe = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "HD Analog Center/LFE Playback Volume", + .name = "HD Analog Center/LFE Volume", .info = snd_p16v_volume_info, .get = snd_p16v_volume_get_analog_center_lfe, .put = snd_p16v_volume_put_analog_center_lfe @@ -840,7 +840,7 @@ static snd_kcontrol_new_t snd_p16v_volume_control_analog_center_lfe = static snd_kcontrol_new_t snd_p16v_volume_control_analog_unknown = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "HD Analog Unknown Playback Volume", + .name = "HD Analog Unknown Volume", .info = snd_p16v_volume_info, .get = snd_p16v_volume_get_analog_unknown, .put = snd_p16v_volume_put_analog_unknown @@ -849,7 +849,7 @@ static snd_kcontrol_new_t snd_p16v_volume_control_analog_unknown = static snd_kcontrol_new_t snd_p16v_volume_control_analog_rear = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "HD Analog Rear Playback Volume", + .name = "HD Analog Rear Volume", .info = snd_p16v_volume_info, .get = snd_p16v_volume_get_analog_rear, .put = snd_p16v_volume_put_analog_rear @@ -858,7 +858,7 @@ static snd_kcontrol_new_t snd_p16v_volume_control_analog_rear = static snd_kcontrol_new_t snd_p16v_volume_control_spdif_front = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "HD SPDIF Front Playback Volume", + .name = "HD SPDIF Front Volume", .info = snd_p16v_volume_info, .get = snd_p16v_volume_get_spdif_front, .put = snd_p16v_volume_put_spdif_front @@ -867,7 +867,7 @@ static snd_kcontrol_new_t snd_p16v_volume_control_spdif_front = static snd_kcontrol_new_t snd_p16v_volume_control_spdif_center_lfe = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "HD SPDIF Center/LFE Playback Volume", + .name = "HD SPDIF Center/LFE Volume", .info = snd_p16v_volume_info, .get = snd_p16v_volume_get_spdif_center_lfe, .put = snd_p16v_volume_put_spdif_center_lfe @@ -876,7 +876,7 @@ static snd_kcontrol_new_t snd_p16v_volume_control_spdif_center_lfe = static snd_kcontrol_new_t snd_p16v_volume_control_spdif_unknown = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "HD SPDIF Unknown Playback Volume", + .name = "HD SPDIF Unknown Volume", .info = snd_p16v_volume_info, .get = snd_p16v_volume_get_spdif_unknown, .put = snd_p16v_volume_put_spdif_unknown @@ -885,7 +885,7 @@ static snd_kcontrol_new_t snd_p16v_volume_control_spdif_unknown = static snd_kcontrol_new_t snd_p16v_volume_control_spdif_rear = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "HD SPDIF Rear Playback Volume", + .name = "HD SPDIF Rear Volume", .info = snd_p16v_volume_info, .get = snd_p16v_volume_get_spdif_rear, .put = snd_p16v_volume_put_spdif_rear @@ -936,7 +936,7 @@ static int snd_p16v_capture_source_put(snd_kcontrol_t * kcontrol, static snd_kcontrol_new_t snd_p16v_capture_source __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "HD source Capture", + .name = "HD Capture source", .info = snd_p16v_capture_source_info, .get = snd_p16v_capture_source_get, .put = snd_p16v_capture_source_put @@ -985,7 +985,7 @@ static int snd_p16v_capture_channel_put(snd_kcontrol_t * kcontrol, static snd_kcontrol_new_t snd_p16v_capture_channel __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "HD channel Capture", + .name = "HD Capture channel", .info = snd_p16v_capture_channel_info, .get = snd_p16v_capture_channel_get, .put = snd_p16v_capture_channel_put diff --git a/trunk/sound/pci/ens1370.c b/trunk/sound/pci/ens1370.c index 78a81f3912a1..4e63498a58b2 100644 --- a/trunk/sound/pci/ens1370.c +++ b/trunk/sound/pci/ens1370.c @@ -685,15 +685,6 @@ static unsigned short snd_es1371_codec_read(ac97_t *ac97, return 0; } -static void snd_es1371_codec_wait(ac97_t *ac97) -{ - msleep(750); - snd_es1371_codec_read(ac97, AC97_RESET); - snd_es1371_codec_read(ac97, AC97_VENDOR_ID1); - snd_es1371_codec_read(ac97, AC97_VENDOR_ID2); - msleep(50); -} - static void snd_es1371_adc_rate(ensoniq_t * ensoniq, unsigned int rate) { unsigned int n, truncm, freq, result; @@ -1594,7 +1585,6 @@ static int snd_ensoniq_1371_mixer(ensoniq_t * ensoniq) static ac97_bus_ops_t ops = { .write = snd_es1371_codec_write, .read = snd_es1371_codec_read, - .wait = snd_es1371_codec_wait, }; if ((err = snd_ac97_bus(card, 0, &ops, NULL, &pbus)) < 0) @@ -2018,11 +2008,21 @@ static int __devinit snd_ensoniq_create(snd_card_t * card, if (pci->vendor == es1371_ac97_reset_hack[idx].vid && pci->device == es1371_ac97_reset_hack[idx].did && ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { + unsigned long tmo; + signed long tmo2; + ensoniq->cssr |= ES_1371_ST_AC97_RST; outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); /* need to delay around 20ms(bleech) to give some CODECs enough time to wakeup */ - msleep(20); + tmo = jiffies + (HZ / 50) + 1; + while (1) { + tmo2 = tmo - jiffies; + if (tmo2 <= 0) + break; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(tmo2); + } break; } /* AC'97 warm reset to start the bitclk */ diff --git a/trunk/sound/pci/es1968.c b/trunk/sound/pci/es1968.c index 9d7a28783930..327a341e276b 100644 --- a/trunk/sound/pci/es1968.c +++ b/trunk/sound/pci/es1968.c @@ -664,6 +664,11 @@ static inline u16 maestro_read(es1968_t *chip, u16 reg) return result; } +#define big_mdelay(msec) do {\ + set_current_state(TASK_UNINTERRUPTIBLE);\ + schedule_timeout(((msec) * HZ + 999) / 1000);\ +} while (0) + /* Wait for the codec bus to be free */ static int snd_es1968_ac97_wait(es1968_t *chip) { @@ -1804,7 +1809,8 @@ static void __devinit es1968_measure_clock(es1968_t *chip) snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR); do_gettimeofday(&start_time); spin_unlock_irq(&chip->reg_lock); - msleep(50); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 20); /* 50 msec */ spin_lock_irq(&chip->reg_lock); offset = __apu_get_register(chip, apu, 5); do_gettimeofday(&stop_time); @@ -2087,7 +2093,7 @@ static void snd_es1968_ac97_reset(es1968_t *chip) outw(0x0000, ioaddr + 0x60); /* write 0 to gpio 0 */ udelay(20); outw(0x0001, ioaddr + 0x60); /* write 1 to gpio 1 */ - msleep(20); + big_mdelay(20); outw(save_68 | 0x1, ioaddr + 0x68); /* now restore .. */ outw((inw(ioaddr + 0x38) & 0xfffc) | 0x1, ioaddr + 0x38); @@ -2103,7 +2109,7 @@ static void snd_es1968_ac97_reset(es1968_t *chip) outw(0x0001, ioaddr + 0x60); /* write 1 to gpio */ udelay(20); outw(0x0009, ioaddr + 0x60); /* write 9 to gpio */ - msleep(500); + big_mdelay(500); //outw(inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38); outw(inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a); outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c); @@ -2129,7 +2135,7 @@ static void snd_es1968_ac97_reset(es1968_t *chip) if (w > 10000) { outb(inb(ioaddr + 0x37) | 0x08, ioaddr + 0x37); /* do a software reset */ - msleep(500); /* oh my.. */ + big_mdelay(500); /* oh my.. */ outb(inb(ioaddr + 0x37) & ~0x08, ioaddr + 0x37); udelay(1); diff --git a/trunk/sound/pci/hda/hda_codec.h b/trunk/sound/pci/hda/hda_codec.h index dd0d99d2ad27..59991560d492 100644 --- a/trunk/sound/pci/hda/hda_codec.h +++ b/trunk/sound/pci/hda/hda_codec.h @@ -262,9 +262,6 @@ enum { #define AC_PINCTL_OUT_EN (1<<6) #define AC_PINCTL_HP_EN (1<<7) -/* Unsolicited response - 8bit */ -#define AC_USRSP_EN (1<<7) - /* configuration default - 32bit */ #define AC_DEFCFG_SEQUENCE (0xf<<0) #define AC_DEFCFG_DEF_ASSOC (0xf<<4) diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index 288ab0764830..5e0cca36ed57 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -178,9 +178,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; #define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */ #define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */ -/* GCTL unsolicited response enable bit */ -#define ICH6_GCTL_UREN (1<<8) - /* GCTL reset bit */ #define ICH6_GCTL_RESET (1<<0) @@ -565,9 +562,6 @@ static int azx_reset(azx_t *chip) return -EBUSY; } - /* Accept unsolicited responses */ - azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UREN); - /* detect codecs */ if (! chip->codec_mask) { chip->codec_mask = azx_readw(chip, STATESTS); diff --git a/trunk/sound/pci/hda/patch_cmedia.c b/trunk/sound/pci/hda/patch_cmedia.c index 86f195f19eef..2d6e3e3d0a38 100644 --- a/trunk/sound/pci/hda/patch_cmedia.c +++ b/trunk/sound/pci/hda/patch_cmedia.c @@ -408,7 +408,7 @@ static int cmi9880_fill_multi_dac_nids(struct hda_codec *codec, const struct aut /* search for an empty channel */ for (j = 0; j < cfg->line_outs; j++) { if (! assigned[j]) { - spec->dac_nids[i] = j + 0x03; + spec->dac_nids[i] = i + 0x03; assigned[j] = 1; break; } @@ -444,10 +444,11 @@ static int cmi9880_fill_multi_init(struct hda_codec *codec, const struct auto_pi len = snd_hda_get_connections(codec, nid, conn, 4); for (k = 0; k < len; k++) if (conn[k] == spec->dac_nids[i]) { - spec->multi_init[j].param = k; + spec->multi_init[j].param = j; break; } j++; + break; } } return 0; diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 9b8569900787..bab89843d850 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -40,7 +40,6 @@ enum { ALC880_W810, ALC880_Z71V, ALC880_AUTO, - ALC880_6ST, ALC880_6ST_DIG, ALC880_F1734, ALC880_ASUS, @@ -120,7 +119,6 @@ struct alc_spec { unsigned int num_kctl_alloc, num_kctl_used; snd_kcontrol_new_t *kctl_alloc; struct hda_input_mux private_imux; - hda_nid_t private_dac_nids[4]; }; @@ -1549,10 +1547,9 @@ static struct hda_board_config alc880_cfg_tbl[] = { { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG }, { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG }, { .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG }, - /* { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, */ /* conflict with 6stack */ + { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, { .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG }, - /* note subvendor = 0 below */ - /* { .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG }, */ + { .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG }, { .modelname = "w810", .config = ALC880_W810 }, { .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 }, @@ -1560,10 +1557,7 @@ static struct hda_board_config alc880_cfg_tbl[] = { { .modelname = "z71v", .config = ALC880_Z71V }, { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V }, - { .modelname = "6stack", .config = ALC880_6ST }, - { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_6ST }, /* Acer APFV */ - - { .modelname = "6stack-digout", .config = ALC880_6ST_DIG }, + { .modelname = "6statack-digout", .config = ALC880_6ST_DIG }, { .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG }, { .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG }, { .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG }, @@ -1650,15 +1644,6 @@ static struct alc_config_preset alc880_presets[] = { .channel_mode = alc880_fivestack_modes, .input_mux = &alc880_capture_source, }, - [ALC880_6ST] = { - .mixers = { alc880_six_stack_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, - .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), - .dac_nids = alc880_6st_dac_nids, - .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), - .channel_mode = alc880_sixstack_modes, - .input_mux = &alc880_6stack_capture_source, - }, [ALC880_6ST_DIG] = { .mixers = { alc880_six_stack_mixer }, .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, @@ -1671,8 +1656,7 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_W810] = { .mixers = { alc880_w810_base_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs, - alc880_gpio2_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), .dac_nids = alc880_w810_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, @@ -1682,7 +1666,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_Z71V] = { .mixers = { alc880_z71v_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs, + alc880_gpio2_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), .dac_nids = alc880_z71v_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, @@ -1824,7 +1809,6 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pi int i, j; memset(assigned, 0, sizeof(assigned)); - spec->multiout.dac_nids = spec->private_dac_nids; /* check the pins hardwired to audio widget */ for (i = 0; i < cfg->line_outs; i++) { diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index 9d503da7320d..013be2ea513a 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -30,37 +30,32 @@ #include #include #include -#include #include "hda_codec.h" #include "hda_local.h" #undef STAC_TEST -#define NUM_CONTROL_ALLOC 32 -#define STAC_HP_EVENT 0x37 -#define STAC_UNSOL_ENABLE (AC_USRSP_EN | STAC_HP_EVENT) - struct sigmatel_spec { - snd_kcontrol_new_t *mixers[4]; - unsigned int num_mixers; - - unsigned int surr_switch: 1; - /* playback */ struct hda_multi_out multiout; - hda_nid_t dac_nids[4]; + hda_nid_t playback_nid; /* capture */ hda_nid_t *adc_nids; unsigned int num_adcs; hda_nid_t *mux_nids; unsigned int num_muxes; + hda_nid_t capture_nid; hda_nid_t dig_in_nid; -#ifdef STAC_TEST + /* power management*/ + hda_nid_t *pstate_nids; + unsigned int num_pstates; + /* pin widgets */ hda_nid_t *pin_nids; unsigned int num_pins; +#ifdef STAC_TEST unsigned int *pin_configs; #endif @@ -69,20 +64,16 @@ struct sigmatel_spec { snd_kcontrol_new_t *mixer; /* capture source */ - struct hda_input_mux *input_mux; + struct hda_input_mux input_mux; + char input_labels[HDA_MAX_NUM_INPUTS][16]; unsigned int cur_mux[2]; /* channel mode */ unsigned int num_ch_modes; unsigned int cur_ch_mode; + const struct sigmatel_channel_mode *channel_modes; - struct hda_pcm pcm_rec[2]; /* PCM information */ - - /* dynamic controls and input_mux */ - struct auto_pin_cfg autocfg; - unsigned int num_kctl_alloc, num_kctl_used; - snd_kcontrol_new_t *kctl_alloc; - struct hda_input_mux private_imux; + struct hda_pcm pcm_rec[1]; /* PCM information */ }; static hda_nid_t stac9200_adc_nids[1] = { @@ -97,6 +88,14 @@ static hda_nid_t stac9200_dac_nids[1] = { 0x02, }; +static hda_nid_t stac9200_pstate_nids[3] = { + 0x01, 0x02, 0x03, +}; + +static hda_nid_t stac9200_pin_nids[8] = { + 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, +}; + static hda_nid_t stac922x_adc_nids[2] = { 0x06, 0x07, }; @@ -105,22 +104,24 @@ static hda_nid_t stac922x_mux_nids[2] = { 0x12, 0x13, }; -#ifdef STAC_TEST -static hda_nid_t stac9200_pin_nids[8] = { - 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, +static hda_nid_t stac922x_dac_nids[4] = { + 0x02, 0x03, 0x04, 0x05, +}; + +static hda_nid_t stac922x_pstate_nids[8] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x11, }; static hda_nid_t stac922x_pin_nids[10] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x15, 0x1b, }; -#endif static int stac92xx_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; - return snd_hda_input_mux_info(spec->input_mux, uinfo); + return snd_hda_input_mux_info(&spec->input_mux, uinfo); } static int stac92xx_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) @@ -139,64 +140,26 @@ static int stac92xx_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t struct sigmatel_spec *spec = codec->spec; unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, + return snd_hda_input_mux_put(codec, &spec->input_mux, ucontrol, spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]); } -static struct hda_verb stac9200_core_init[] = { +static struct hda_verb stac9200_ch2_init[] = { /* set dac0mux for dac converter */ - { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, + { 0x07, 0x701, 0x00}, {} }; -static struct hda_verb stac922x_core_init[] = { +static struct hda_verb stac922x_ch2_init[] = { /* set master volume and direct control */ - { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + { 0x16, 0x70f, 0xff}, {} }; -static int stac922x_channel_modes[3] = {2, 6, 8}; - -static int stac922x_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct sigmatel_spec *spec = codec->spec; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = spec->num_ch_modes; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - sprintf(uinfo->value.enumerated.name, "%dch", - stac922x_channel_modes[uinfo->value.enumerated.item]); - return 0; -} - -static int stac922x_ch_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct sigmatel_spec *spec = codec->spec; - - ucontrol->value.enumerated.item[0] = spec->cur_ch_mode; - return 0; -} - -static int stac922x_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct sigmatel_spec *spec = codec->spec; - - if (ucontrol->value.enumerated.item[0] >= spec->num_ch_modes) - ucontrol->value.enumerated.item[0] = spec->num_ch_modes; - if (ucontrol->value.enumerated.item[0] == spec->cur_ch_mode && - ! codec->in_resume) - return 0; - - spec->cur_ch_mode = ucontrol->value.enumerated.item[0]; - spec->multiout.max_channels = stac922x_channel_modes[spec->cur_ch_mode]; - - return 1; -} +struct sigmatel_channel_mode { + unsigned int channels; + const struct hda_verb *sequence; +}; static snd_kcontrol_new_t stac9200_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), @@ -211,12 +174,13 @@ static snd_kcontrol_new_t stac9200_mixer[] = { }, HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Input Mux Volume", 0x0c, 0, HDA_OUTPUT), { } /* end */ }; -/* This needs to be generated dynamically based on sequence */ static snd_kcontrol_new_t stac922x_mixer[] = { + HDA_CODEC_VOLUME("PCM Playback Volume", 0x2, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("PCM Playback Switch", 0x2, 0x0, HDA_OUTPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Input Source", @@ -231,38 +195,14 @@ static snd_kcontrol_new_t stac922x_mixer[] = { { } /* end */ }; -static snd_kcontrol_new_t stac922x_ch_mode_mixer[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Channel Mode", - .info = stac922x_ch_mode_info, - .get = stac922x_ch_mode_get, - .put = stac922x_ch_mode_put, - }, - { } /* end */ -}; - static int stac92xx_build_controls(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; int err; - int i; err = snd_hda_add_new_ctls(codec, spec->mixer); if (err < 0) return err; - - for (i = 0; i < spec->num_mixers; i++) { - err = snd_hda_add_new_ctls(codec, spec->mixers[i]); - if (err < 0) - return err; - } - - if (spec->surr_switch) { - err = snd_hda_add_new_ctls(codec, stac922x_ch_mode_mixer); - if (err < 0) - return err; - } if (spec->multiout.dig_out_nid) { err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); if (err < 0) @@ -282,9 +222,9 @@ static unsigned int stac9200_pin_configs[8] = { 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, }; -static unsigned int stac922x_pin_configs[10] = { - 0x01014010, 0x01014011, 0x01014012, 0x0221401f, - 0x01813122, 0x01014014, 0x01441030, 0x01c41030, +static unsigned int stac922x_pin_configs[14] = { + 0x40000100, 0x40000100, 0x40000100, 0x01114010, + 0x01813122, 0x40000100, 0x01447010, 0x01c47010, 0x40000100, 0x40000100, }; @@ -315,66 +255,180 @@ static void stac92xx_set_config_regs(struct hda_codec *codec) } #endif +static int stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, unsigned int value) +{ + unsigned int pin_ctl; + + pin_ctl = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_PIN_WIDGET_CONTROL, + 0x00); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + pin_ctl | value); + + return 0; +} + +static int stac92xx_set_vref(struct hda_codec *codec, hda_nid_t nid) +{ + unsigned int vref_caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP) >> AC_PINCAP_VREF_SHIFT; + unsigned int vref_ctl = AC_PINCTL_VREF_HIZ; + + if (vref_caps & AC_PINCAP_VREF_100) + vref_ctl = AC_PINCTL_VREF_100; + else if (vref_caps & AC_PINCAP_VREF_80) + vref_ctl = AC_PINCTL_VREF_80; + else if (vref_caps & AC_PINCAP_VREF_50) + vref_ctl = AC_PINCTL_VREF_50; + else if (vref_caps & AC_PINCAP_VREF_GRD) + vref_ctl = AC_PINCTL_VREF_GRD; + + stac92xx_set_pinctl(codec, nid, vref_ctl); + + return 0; +} + /* - * Analog playback callbacks + * retrieve the default device type from the default config value */ -static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - snd_pcm_substream_t *substream) +#define get_defcfg_type(cfg) ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) +#define get_defcfg_location(cfg) ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) + +static int stac92xx_config_pin(struct hda_codec *codec, hda_nid_t nid, unsigned int pin_cfg) { struct sigmatel_spec *spec = codec->spec; - return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); + u32 location = get_defcfg_location(pin_cfg); + char *label; + const char *type = NULL; + int ainput = 0; + + switch(get_defcfg_type(pin_cfg)) { + case AC_JACK_HP_OUT: + /* Enable HP amp */ + stac92xx_set_pinctl(codec, nid, AC_PINCTL_HP_EN); + /* Fall through */ + case AC_JACK_SPDIF_OUT: + case AC_JACK_LINE_OUT: + case AC_JACK_SPEAKER: + /* Enable output */ + stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); + break; + case AC_JACK_SPDIF_IN: + stac92xx_set_pinctl(codec, nid, AC_PINCTL_IN_EN); + break; + case AC_JACK_MIC_IN: + if ((location & 0x0f) == AC_JACK_LOC_FRONT) + type = "Front Mic"; + else + type = "Mic"; + ainput = 1; + /* Set vref */ + stac92xx_set_vref(codec, nid); + stac92xx_set_pinctl(codec, nid, AC_PINCTL_IN_EN); + break; + case AC_JACK_CD: + type = "CD"; + ainput = 1; + stac92xx_set_pinctl(codec, nid, AC_PINCTL_IN_EN); + break; + case AC_JACK_LINE_IN: + if ((location & 0x0f) == AC_JACK_LOC_FRONT) + type = "Front Line"; + else + type = "Line"; + ainput = 1; + stac92xx_set_pinctl(codec, nid, AC_PINCTL_IN_EN); + break; + case AC_JACK_AUX: + if ((location & 0x0f) == AC_JACK_LOC_FRONT) + type = "Front Aux"; + else + type = "Aux"; + ainput = 1; + stac92xx_set_pinctl(codec, nid, AC_PINCTL_IN_EN); + break; + } + + if (ainput) { + hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; + int i, j, num_cons, index = -1; + if (!type) + type = "Input"; + label = spec->input_labels[spec->input_mux.num_items]; + strcpy(label, type); + spec->input_mux.items[spec->input_mux.num_items].label = label; + for (i=0; inum_muxes; i++) { + num_cons = snd_hda_get_connections(codec, spec->mux_nids[i], con_lst, HDA_MAX_NUM_INPUTS); + for (j=0; j= 0) + break; + } + spec->input_mux.items[spec->input_mux.num_items].index = index; + spec->input_mux.num_items++; + } + + return 0; } -/* - * set up the i/o for analog out - * when the digital out is available, copy the front out to digital out, too. - */ -static int stac92xx_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, - unsigned int stream_tag, - unsigned int format, - snd_pcm_substream_t *substream) +static int stac92xx_config_pins(struct hda_codec *codec) { - hda_nid_t *nids = mout->dac_nids; - int chs = substream->runtime->channels; + struct sigmatel_spec *spec = codec->spec; int i; + unsigned int pin_cfg; - down(&codec->spdif_mutex); - if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { - if (chs == 2 && - snd_hda_is_supported_format(codec, mout->dig_out_nid, format) && - ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) { - mout->dig_out_used = HDA_DIG_ANALOG_DUP; - /* setup digital receiver */ - snd_hda_codec_setup_stream(codec, mout->dig_out_nid, - stream_tag, 0, format); - } else { - mout->dig_out_used = 0; - snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); - } + for (i=0; i < spec->num_pins; i++) { + /* Default to disabled */ + snd_hda_codec_write(codec, spec->pin_nids[i], 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + 0x00); + + pin_cfg = snd_hda_codec_read(codec, spec->pin_nids[i], 0, + AC_VERB_GET_CONFIG_DEFAULT, + 0x00); + if (((pin_cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) == AC_JACK_PORT_NONE) + continue; /* Move on */ + + stac92xx_config_pin(codec, spec->pin_nids[i], pin_cfg); } - up(&codec->spdif_mutex); - - /* front */ - snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format); - if (mout->hp_nid) - /* headphone out will just decode front left/right (stereo) */ - snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format); - /* surrounds */ - if (mout->max_channels > 2) - for (i = 1; i < mout->num_dacs; i++) { - if ((mout->max_channels == 6) && (i == 3)) - break; - if (chs >= (i + 1) * 2) /* independent out */ - snd_hda_codec_setup_stream(codec, nids[i], stream_tag, i * 2, - format); - else /* copy front */ - snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 0, - format); - } + + return 0; +} + +static int stac92xx_init(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + int i; + + for (i=0; i < spec->num_pstates; i++) + snd_hda_codec_write(codec, spec->pstate_nids[i], 0, + AC_VERB_SET_POWER_STATE, 0x00); + + mdelay(100); + + snd_hda_sequence_write(codec, spec->init); + +#ifdef STAC_TEST + stac92xx_set_config_regs(codec); +#endif + + stac92xx_config_pins(codec); + return 0; } +/* + * Analog playback callbacks + */ +static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + snd_pcm_substream_t *substream) +{ + struct sigmatel_spec *spec = codec->spec; + return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); +} static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo, struct hda_codec *codec, @@ -383,7 +437,7 @@ static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo, snd_pcm_substream_t *substream) { struct sigmatel_spec *spec = codec->spec; - return stac92xx_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, + return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream); } @@ -462,7 +516,7 @@ static struct hda_pcm_stream stac92xx_pcm_digital_capture = { static struct hda_pcm_stream stac92xx_pcm_analog_playback = { .substreams = 1, .channels_min = 2, - .channels_max = 8, + .channels_max = 2, .nid = 0x02, /* NID to query formats and rates */ .ops = { .open = stac92xx_playback_pcm_open, @@ -490,9 +544,11 @@ static int stac92xx_build_pcms(struct hda_codec *codec) codec->num_pcms = 1; codec->pcm_info = info; - info->name = "STAC92xx Analog"; + info->name = "STAC92xx"; info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback; + info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->playback_nid; info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture; + info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->capture_nid; if (spec->multiout.dig_out_nid || spec->dig_in_nid) { codec->num_pcms++; @@ -511,413 +567,21 @@ static int stac92xx_build_pcms(struct hda_codec *codec) return 0; } -enum { - STAC_CTL_WIDGET_VOL, - STAC_CTL_WIDGET_MUTE, -}; - -static snd_kcontrol_new_t stac92xx_control_templates[] = { - HDA_CODEC_VOLUME(NULL, 0, 0, 0), - HDA_CODEC_MUTE(NULL, 0, 0, 0), -}; - -/* add dynamic controls */ -static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val) -{ - snd_kcontrol_new_t *knew; - - if (spec->num_kctl_used >= spec->num_kctl_alloc) { - int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; - - knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */ - if (! knew) - return -ENOMEM; - if (spec->kctl_alloc) { - memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc); - kfree(spec->kctl_alloc); - } - spec->kctl_alloc = knew; - spec->num_kctl_alloc = num; - } - - knew = &spec->kctl_alloc[spec->num_kctl_used]; - *knew = stac92xx_control_templates[type]; - knew->name = kstrdup(name, GFP_KERNEL); - if (! knew->name) - return -ENOMEM; - knew->private_value = val; - spec->num_kctl_used++; - return 0; -} - -/* fill in the dac_nids table from the parsed pin configuration */ -static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct auto_pin_cfg *cfg) -{ - struct sigmatel_spec *spec = codec->spec; - hda_nid_t nid; - int i; - - /* check the pins hardwired to audio widget */ - for (i = 0; i < cfg->line_outs; i++) { - nid = cfg->line_out_pins[i]; - spec->multiout.dac_nids[i] = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_CONNECT_LIST, 0) & 0xff; - } - - spec->multiout.num_dacs = cfg->line_outs; - - return 0; -} - -/* add playback controls from the parsed DAC table */ -static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, const struct auto_pin_cfg *cfg) -{ - char name[32]; - static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; - hda_nid_t nid; - int i, err; - - for (i = 0; i < cfg->line_outs; i++) { - if (! spec->multiout.dac_nids[i]) - continue; - - nid = spec->multiout.dac_nids[i]; - - if (i == 2) { - /* Center/LFE */ - if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "Center Playback Volume", - HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) - return err; - if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "LFE Playback Volume", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) - return err; - if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "Center Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) - return err; - if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "LFE Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) - return err; - } else { - sprintf(name, "%s Playback Volume", chname[i]); - if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) - return err; - sprintf(name, "%s Playback Switch", chname[i]); - if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) - return err; - } - } - - return 0; -} - -/* add playback controls for HP output */ -static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, struct auto_pin_cfg *cfg) -{ - struct sigmatel_spec *spec = codec->spec; - hda_nid_t pin = cfg->hp_pin; - hda_nid_t nid; - int i, err; - unsigned int wid_caps; - - if (! pin) - return 0; - - wid_caps = snd_hda_param_read(codec, pin, AC_PAR_AUDIO_WIDGET_CAP); - if (wid_caps & AC_WCAP_UNSOL_CAP) - /* Enable unsolicited responses on the HP widget */ - snd_hda_codec_write(codec, pin, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - STAC_UNSOL_ENABLE); - - nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff; - for (i = 0; i < cfg->line_outs; i++) { - if (! spec->multiout.dac_nids[i]) - continue; - if (spec->multiout.dac_nids[i] == nid) - return 0; - } - - spec->multiout.hp_nid = nid; - - /* control HP volume/switch on the output mixer amp */ - if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "Headphone Playback Volume", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) - return err; - if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "Headphone Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) - return err; - - return 0; -} - -/* create playback/capture controls for input pins */ -static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) -{ - struct sigmatel_spec *spec = codec->spec; - static char *labels[AUTO_PIN_LAST] = { - "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux" - }; - struct hda_input_mux *imux = &spec->private_imux; - hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; - int i, j, k; - - for (i = 0; i < AUTO_PIN_LAST; i++) { - int index = -1; - if (cfg->input_pins[i]) { - imux->items[imux->num_items].label = labels[i]; - - for (j=0; jnum_muxes; j++) { - int num_cons = snd_hda_get_connections(codec, spec->mux_nids[j], con_lst, HDA_MAX_NUM_INPUTS); - for (k=0; kinput_pins[i]) { - index = k; - break; - } - if (index >= 0) - break; - } - imux->items[imux->num_items].index = index; - imux->num_items++; - } - } - - return 0; -} - -static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type) - -{ - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); -} - -static void stac92xx_auto_init_multi_out(struct hda_codec *codec) -{ - struct sigmatel_spec *spec = codec->spec; - int i; - - for (i = 0; i < spec->autocfg.line_outs; i++) { - hda_nid_t nid = spec->autocfg.line_out_pins[i]; - stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); - } -} - -static void stac92xx_auto_init_hp_out(struct hda_codec *codec) -{ - struct sigmatel_spec *spec = codec->spec; - hda_nid_t pin; - - pin = spec->autocfg.hp_pin; - if (pin) /* connect to front */ - stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); -} - -static int stac922x_parse_auto_config(struct hda_codec *codec) -{ - struct sigmatel_spec *spec = codec->spec; - int err; - - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg)) < 0) - return err; - if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) - return err; - if (! spec->autocfg.line_outs && ! spec->autocfg.hp_pin) - return 0; /* can't find valid pin config */ - - if ((err = stac92xx_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || - (err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg)) < 0 || - (err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0) - return err; - - spec->multiout.max_channels = spec->multiout.num_dacs * 2; - if (spec->multiout.max_channels > 2) { - spec->surr_switch = 1; - spec->cur_ch_mode = 1; - spec->num_ch_modes = 2; - if (spec->multiout.max_channels == 8) { - spec->cur_ch_mode++; - spec->num_ch_modes++; - } - } - - if (spec->autocfg.dig_out_pin) { - spec->multiout.dig_out_nid = 0x08; - stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN); - } - if (spec->autocfg.dig_in_pin) { - spec->dig_in_nid = 0x09; - stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN); - } - - if (spec->kctl_alloc) - spec->mixers[spec->num_mixers++] = spec->kctl_alloc; - - spec->input_mux = &spec->private_imux; - - return 1; -} - -static int stac9200_parse_auto_config(struct hda_codec *codec) -{ - struct sigmatel_spec *spec = codec->spec; - int err; - - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg)) < 0) - return err; - - if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0) - return err; - - if (spec->autocfg.dig_out_pin) { - spec->multiout.dig_out_nid = 0x05; - stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN); - } - if (spec->autocfg.dig_in_pin) { - spec->dig_in_nid = 0x04; - stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN); - } - - if (spec->kctl_alloc) - spec->mixers[spec->num_mixers++] = spec->kctl_alloc; - - spec->input_mux = &spec->private_imux; - - return 1; -} - -static int stac92xx_init_pstate(struct hda_codec *codec) -{ - hda_nid_t nid, nid_start; - int nodes; - - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_POWER_STATE, 0x00); - - nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); - for (nid = nid_start; nid < nodes + nid_start; nid++) { - unsigned int wid_caps = snd_hda_param_read(codec, nid, - AC_PAR_AUDIO_WIDGET_CAP); - if (wid_caps & AC_WCAP_POWER) - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_POWER_STATE, 0x00); - } - - mdelay(100); - - return 0; -} - -static int stac92xx_init(struct hda_codec *codec) -{ - struct sigmatel_spec *spec = codec->spec; - - stac92xx_init_pstate(codec); - - snd_hda_sequence_write(codec, spec->init); - - stac92xx_auto_init_multi_out(codec); - stac92xx_auto_init_hp_out(codec); - - return 0; -} - static void stac92xx_free(struct hda_codec *codec) { - struct sigmatel_spec *spec = codec->spec; - int i; - - if (! spec) - return; - - if (spec->kctl_alloc) { - for (i = 0; i < spec->num_kctl_used; i++) - kfree(spec->kctl_alloc[i].name); - kfree(spec->kctl_alloc); - } - - kfree(spec); -} - -static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, - unsigned int flag) -{ - unsigned int pin_ctl = snd_hda_codec_read(codec, nid, - 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, - pin_ctl | flag); -} - -static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, - unsigned int flag) -{ - unsigned int pin_ctl = snd_hda_codec_read(codec, nid, - 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, - pin_ctl & ~flag); -} - -static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) -{ - struct sigmatel_spec *spec = codec->spec; - struct auto_pin_cfg *cfg = &spec->autocfg; - int i, presence; - - if ((res >> 26) != STAC_HP_EVENT) - return; - - presence = snd_hda_codec_read(codec, cfg->hp_pin, 0, - AC_VERB_GET_PIN_SENSE, 0x00) >> 31; - - if (presence) { - /* disable lineouts, enable hp */ - for (i = 0; i < cfg->line_outs; i++) - stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], - AC_PINCTL_OUT_EN); - stac92xx_set_pinctl(codec, cfg->hp_pin, AC_PINCTL_OUT_EN); - } else { - /* enable lineouts, disable hp */ - for (i = 0; i < cfg->line_outs; i++) - stac92xx_set_pinctl(codec, cfg->line_out_pins[i], - AC_PINCTL_OUT_EN); - stac92xx_reset_pinctl(codec, cfg->hp_pin, AC_PINCTL_OUT_EN); - } -} - -#ifdef CONFIG_PM -static int stac92xx_resume(struct hda_codec *codec) -{ - struct sigmatel_spec *spec = codec->spec; - int i; - - stac92xx_init(codec); - for (i = 0; i < spec->num_mixers; i++) - snd_hda_resume_ctls(codec, spec->mixers[i]); - if (spec->multiout.dig_out_nid) - snd_hda_resume_spdif_out(codec); - if (spec->dig_in_nid) - snd_hda_resume_spdif_in(codec); - - return 0; + kfree(codec->spec); } -#endif static struct hda_codec_ops stac92xx_patch_ops = { .build_controls = stac92xx_build_controls, .build_pcms = stac92xx_build_pcms, .init = stac92xx_init, .free = stac92xx_free, - .unsol_event = stac92xx_unsol_event, -#ifdef CONFIG_PM - .resume = stac92xx_resume, -#endif }; static int patch_stac9200(struct hda_codec *codec) { struct sigmatel_spec *spec; - int err; spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); if (spec == NULL) @@ -925,27 +589,26 @@ static int patch_stac9200(struct hda_codec *codec) codec->spec = spec; -#ifdef STAC_TEST - spec->pin_nids = stac9200_pin_nids; - spec->num_pins = 8; - spec->pin_configs = stac9200_pin_configs; - stac92xx_set_config_regs(codec); -#endif spec->multiout.max_channels = 2; spec->multiout.num_dacs = 1; spec->multiout.dac_nids = stac9200_dac_nids; + spec->multiout.dig_out_nid = 0x05; + spec->dig_in_nid = 0x04; spec->adc_nids = stac9200_adc_nids; spec->mux_nids = stac9200_mux_nids; spec->num_muxes = 1; - - spec->init = stac9200_core_init; + spec->input_mux.num_items = 0; + spec->pstate_nids = stac9200_pstate_nids; + spec->num_pstates = 3; + spec->pin_nids = stac9200_pin_nids; +#ifdef STAC_TEST + spec->pin_configs = stac9200_pin_configs; +#endif + spec->num_pins = 8; + spec->init = stac9200_ch2_init; spec->mixer = stac9200_mixer; - - err = stac9200_parse_auto_config(codec); - if (err < 0) { - stac92xx_free(codec); - return err; - } + spec->playback_nid = 0x02; + spec->capture_nid = 0x03; codec->patch_ops = stac92xx_patch_ops; @@ -955,7 +618,6 @@ static int patch_stac9200(struct hda_codec *codec) static int patch_stac922x(struct hda_codec *codec) { struct sigmatel_spec *spec; - int err; spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); if (spec == NULL) @@ -963,26 +625,26 @@ static int patch_stac922x(struct hda_codec *codec) codec->spec = spec; -#ifdef STAC_TEST - spec->num_pins = 10; - spec->pin_nids = stac922x_pin_nids; - spec->pin_configs = stac922x_pin_configs; - stac92xx_set_config_regs(codec); -#endif + spec->multiout.max_channels = 2; + spec->multiout.num_dacs = 4; + spec->multiout.dac_nids = stac922x_dac_nids; + spec->multiout.dig_out_nid = 0x08; + spec->dig_in_nid = 0x09; spec->adc_nids = stac922x_adc_nids; spec->mux_nids = stac922x_mux_nids; spec->num_muxes = 2; - - spec->init = stac922x_core_init; + spec->input_mux.num_items = 0; + spec->pstate_nids = stac922x_pstate_nids; + spec->num_pstates = 8; + spec->pin_nids = stac922x_pin_nids; +#ifdef STAC_TEST + spec->pin_configs = stac922x_pin_configs; +#endif + spec->num_pins = 10; + spec->init = stac922x_ch2_init; spec->mixer = stac922x_mixer; - - spec->multiout.dac_nids = spec->dac_nids; - - err = stac922x_parse_auto_config(codec); - if (err < 0) { - stac92xx_free(codec); - return err; - } + spec->playback_nid = 0x02; + spec->capture_nid = 0x06; codec->patch_ops = stac92xx_patch_ops; diff --git a/trunk/sound/pci/intel8x0.c b/trunk/sound/pci/intel8x0.c index 7c806bd9cc90..cc16f95f9cef 100644 --- a/trunk/sound/pci/intel8x0.c +++ b/trunk/sound/pci/intel8x0.c @@ -424,7 +424,6 @@ struct _snd_intel8x0 { unsigned xbox: 1; /* workaround for Xbox AC'97 detection */ int spdif_idx; /* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */ - unsigned int sdm_saved; /* SDM reg value */ ac97_bus_t *ac97_bus; ac97_t *ac97[3]; @@ -2374,8 +2373,6 @@ static int intel8x0_suspend(snd_card_t *card, pm_message_t state) for (i = 0; i < 3; i++) if (chip->ac97[i]) snd_ac97_suspend(chip->ac97[i]); - if (chip->device_type == DEVICE_INTEL_ICH4) - chip->sdm_saved = igetbyte(chip, ICHREG(SDM)); pci_disable_device(chip->pci); return 0; } @@ -2389,16 +2386,6 @@ static int intel8x0_resume(snd_card_t *card) pci_set_master(chip->pci); snd_intel8x0_chip_init(chip, 0); - /* re-initialize mixer stuff */ - if (chip->device_type == DEVICE_INTEL_ICH4) { - /* enable separate SDINs for ICH4 */ - iputbyte(chip, ICHREG(SDM), chip->sdm_saved); - /* use slot 10/11 for SPDIF */ - iputdword(chip, ICHREG(GLOB_CNT), - (igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_PCM_SPDIF_MASK) | - ICH_PCM_SPDIF_1011); - } - /* refill nocache */ if (chip->fix_nocache) fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 1); @@ -2464,7 +2451,8 @@ static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip) } do_gettimeofday(&start_time); spin_unlock_irq(&chip->reg_lock); - msleep(50); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 20); spin_lock_irq(&chip->reg_lock); /* check the position */ pos = ichdev->fragsize1; diff --git a/trunk/sound/pci/maestro3.c b/trunk/sound/pci/maestro3.c index 39b5e7db1543..52c585901c54 100644 --- a/trunk/sound/pci/maestro3.c +++ b/trunk/sound/pci/maestro3.c @@ -1050,6 +1050,11 @@ static struct m3_hv_quirk m3_hv_quirk_list[] = { * lowlevel functions */ +#define big_mdelay(msec) do {\ + set_current_state(TASK_UNINTERRUPTIBLE);\ + schedule_timeout(((msec) * HZ) / 1000);\ +} while (0) + static inline void snd_m3_outw(m3_t *chip, u16 value, unsigned long reg) { outw(value, chip->iobase + reg); @@ -1091,7 +1096,7 @@ static void snd_m3_assp_write(m3_t *chip, u16 region, u16 index, u16 data) static void snd_m3_assp_halt(m3_t *chip) { chip->reset_state = snd_m3_inb(chip, DSP_PORT_CONTROL_REG_B) & ~REGB_STOP_CLOCK; - msleep(10); + big_mdelay(10); snd_m3_outb(chip, chip->reset_state & ~REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B); } @@ -2103,9 +2108,9 @@ static void snd_m3_ac97_reset(m3_t *chip) */ tmp = inw(io + RING_BUS_CTRL_A); outw(RAC_SDFS_ENABLE|LAC_SDFS_ENABLE, io + RING_BUS_CTRL_A); - msleep(20); + big_mdelay(20); outw(tmp, io + RING_BUS_CTRL_A); - msleep(50); + big_mdelay(50); #endif } @@ -2520,13 +2525,9 @@ static void snd_m3_enable_ints(m3_t *chip) { unsigned long io = chip->iobase; - unsigned short val; /* TODO: MPU401 not supported yet */ - val = ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/; - if (chip->hv_quirk && (chip->hv_quirk->config & HV_CTRL_ENABLE)) - val |= HV_INT_ENABLE; - outw(val, io + HOST_INT_CTRL); + outw(ASSP_INT_ENABLE | HV_INT_ENABLE /*| MPU401_INT_ENABLE*/, io + HOST_INT_CTRL); outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE, io + ASSP_CONTROL_C); } @@ -2588,7 +2589,7 @@ static int m3_suspend(snd_card_t *card, pm_message_t state) snd_pcm_suspend_all(chip->pcm); snd_ac97_suspend(chip->ac97); - msleep(10); /* give the assp a chance to idle.. */ + big_mdelay(10); /* give the assp a chance to idle.. */ snd_m3_assp_halt(chip); @@ -2696,8 +2697,6 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, } spin_lock_init(&chip->reg_lock); - spin_lock_init(&chip->ac97_lock); - switch (pci->device) { case PCI_DEVICE_ID_ESS_ALLEGRO: case PCI_DEVICE_ID_ESS_ALLEGRO_1: @@ -2766,8 +2765,6 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, snd_m3_assp_init(chip); snd_m3_amp_enable(chip, 1); - tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip); - if (request_irq(pci->irq, snd_m3_interrupt, SA_INTERRUPT|SA_SHIRQ, card->driver, (void *)chip)) { snd_printk("unable to grab IRQ %d\n", pci->irq); @@ -2789,6 +2786,9 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, return err; } + spin_lock_init(&chip->ac97_lock); + tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip); + if ((err = snd_m3_mixer(chip)) < 0) return err; diff --git a/trunk/sound/pci/mixart/mixart.c b/trunk/sound/pci/mixart/mixart.c index 6c868d913634..082c0d0f73d2 100644 --- a/trunk/sound/pci/mixart/mixart.c +++ b/trunk/sound/pci/mixart/mixart.c @@ -445,9 +445,9 @@ static int snd_mixart_trigger(snd_pcm_substream_t *subs, int cmd) static int mixart_sync_nonblock_events(mixart_mgr_t *mgr) { - unsigned long timeout = jiffies + HZ; + int timeout = HZ; while (atomic_read(&mgr->msg_processed) > 0) { - if (time_after(jiffies, timeout)) { + if (! timeout--) { snd_printk(KERN_ERR "mixart: cannot process nonblock events!\n"); return -EBUSY; } diff --git a/trunk/sound/pci/rme9652/hdsp.c b/trunk/sound/pci/rme9652/hdsp.c index 796621de5009..a673cc438b91 100644 --- a/trunk/sound/pci/rme9652/hdsp.c +++ b/trunk/sound/pci/rme9652/hdsp.c @@ -445,7 +445,6 @@ struct _hdsp { u32 control2_register; /* cached value */ u32 creg_spdif; u32 creg_spdif_stream; - int clock_source_locked; char *card_name; /* digiface/multiface */ HDSP_IO_Type io_type; /* ditto, but for code use */ unsigned short firmware_rev; @@ -679,7 +678,8 @@ static int snd_hdsp_load_firmware_from_cache(hdsp_t *hdsp) { } if ((1000 / HZ) < 3000) { - ssleep(3); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((3000 * HZ + 999) / 1000); } else { mdelay(3000); } @@ -2095,34 +2095,6 @@ static int snd_hdsp_put_clock_source(snd_kcontrol_t * kcontrol, snd_ctl_elem_val return change; } -static int snd_hdsp_info_clock_source_lock(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int snd_hdsp_get_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) -{ - hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = hdsp->clock_source_locked; - return 0; -} - -static int snd_hdsp_put_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) -{ - hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); - int change; - - change = (int)ucontrol->value.integer.value[0] != hdsp->clock_source_locked; - if (change) - hdsp->clock_source_locked = ucontrol->value.integer.value[0]; - return change; -} - #define HDSP_DA_GAIN(xname, xindex) \ { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ .name = xname, \ @@ -3145,15 +3117,6 @@ HDSP_SPDIF_EMPHASIS("IEC958 Emphasis Bit", 0), HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0), /* 'Sample Clock Source' complies with the alsa control naming scheme */ HDSP_CLOCK_SOURCE("Sample Clock Source", 0), -{ - /* FIXME: should be PCM or MIXER? */ - /* .iface = SNDRV_CTL_ELEM_IFACE_PCM, */ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sample Clock Source Locking", - .info = snd_hdsp_info_clock_source_lock, - .get = snd_hdsp_get_clock_source_lock, - .put = snd_hdsp_put_clock_source_lock, -}, HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0), HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0), HDSP_AUTOSYNC_REF("AutoSync Reference", 0), @@ -3386,7 +3349,6 @@ snd_hdsp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer) snd_iprintf (buffer, "System Clock Mode: %s\n", system_clock_mode); snd_iprintf (buffer, "System Clock Frequency: %d\n", hdsp->system_sample_rate); - snd_iprintf (buffer, "System Clock Locked: %s\n", hdsp->clock_source_locked ? "Yes" : "No"); snd_iprintf(buffer, "\n"); @@ -3891,14 +3853,13 @@ static int snd_hdsp_hw_params(snd_pcm_substream_t *substream, */ spin_lock_irq(&hdsp->lock); - if (! hdsp->clock_source_locked) { - if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) { - spin_unlock_irq(&hdsp->lock); - _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE); - return err; - } + if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) { + spin_unlock_irq(&hdsp->lock); + _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE); + return err; + } else { + spin_unlock_irq(&hdsp->lock); } - spin_unlock_irq(&hdsp->lock); if ((err = hdsp_set_interrupt_interval(hdsp, params_period_size(params))) < 0) { _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE); @@ -4323,17 +4284,13 @@ static int snd_hdsp_playback_open(snd_pcm_substream_t *substream) snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes); - if (hdsp->clock_source_locked) { - runtime->hw.rate_min = runtime->hw.rate_max = hdsp->system_sample_rate; - } else if (hdsp->io_type == H9632) { + if (hdsp->io_type == H9632) { + runtime->hw.channels_min = hdsp->qs_out_channels; + runtime->hw.channels_max = hdsp->ss_out_channels; runtime->hw.rate_max = 192000; runtime->hw.rates = SNDRV_PCM_RATE_KNOT; snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hdsp_hw_constraints_9632_sample_rates); } - if (hdsp->io_type == H9632) { - runtime->hw.channels_min = hdsp->qs_out_channels; - runtime->hw.channels_max = hdsp->ss_out_channels; - } snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, snd_hdsp_hw_rule_out_channels, hdsp, @@ -5079,7 +5036,8 @@ static int __devinit snd_hdsp_create(snd_card_t *card, if (!is_9652 && !is_9632) { /* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */ if ((1000 / HZ) < 2000) { - ssleep(2); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((2000 * HZ + 999) / 1000); } else { mdelay(2000); } diff --git a/trunk/sound/pci/trident/trident_main.c b/trunk/sound/pci/trident/trident_main.c index 29d89bfba0a4..a09b0fb49e81 100644 --- a/trunk/sound/pci/trident/trident_main.c +++ b/trunk/sound/pci/trident/trident_main.c @@ -472,7 +472,6 @@ void snd_trident_write_voice_regs(trident_t * trident, break; default: snd_BUG(); - return; } outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); @@ -3153,7 +3152,8 @@ static int snd_trident_gameport_open(struct gameport *gameport, int mode) switch (mode) { case GAMEPORT_MODE_COOKED: outb(GAMEPORT_MODE_ADC, TRID_REG(chip, GAMEPORT_GCR)); - msleep(20); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1 + 20 * HZ / 1000); /* 20msec */ return 0; case GAMEPORT_MODE_RAW: outb(0, TRID_REG(chip, GAMEPORT_GCR)); diff --git a/trunk/sound/pci/via82xx.c b/trunk/sound/pci/via82xx.c index 4889600387c8..42c48f0ce8e8 100644 --- a/trunk/sound/pci/via82xx.c +++ b/trunk/sound/pci/via82xx.c @@ -547,7 +547,8 @@ static void snd_via82xx_codec_wait(ac97_t *ac97) int err; err = snd_via82xx_codec_ready(chip, ac97->num); /* here we need to wait fairly for long time.. */ - msleep(500); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/2); } static void snd_via82xx_codec_write(ac97_t *ac97, @@ -1846,7 +1847,7 @@ static void __devinit snd_via82xx_proc_init(via82xx_t *chip) static int snd_via82xx_chip_init(via82xx_t *chip) { unsigned int val; - unsigned long end_time; + int max_count; unsigned char pval; #if 0 /* broken on K7M? */ @@ -1888,14 +1889,14 @@ static int snd_via82xx_chip_init(via82xx_t *chip) } /* wait until codec ready */ - end_time = jiffies + msecs_to_jiffies(750); + max_count = ((3 * HZ) / 4) + 1; do { pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ break; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1); - } while (time_before(jiffies, end_time)); + } while (--max_count > 0); if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) snd_printk("AC'97 codec is not ready [0x%x]\n", val); @@ -1904,7 +1905,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip) snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ | VIA_REG_AC97_SECONDARY_VALID | (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT)); - end_time = jiffies + msecs_to_jiffies(750); + max_count = ((3 * HZ) / 4) + 1; snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ | VIA_REG_AC97_SECONDARY_VALID | (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT)); @@ -1915,7 +1916,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip) } set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1); - } while (time_before(jiffies, end_time)); + } while (--max_count > 0); /* This is ok, the most of motherboards have only one codec */ __ac97_ok2: @@ -2177,7 +2178,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci) { .subvendor = 0x147b, .subdevice = 0x1413, .action = VIA_DXS_ENABLE }, /* ABIT KV8 Pro */ { .subvendor = 0x147b, .subdevice = 0x1415, .action = VIA_DXS_NO_VRA }, /* Abit AV8 */ { .subvendor = 0x14ff, .subdevice = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */ - { .subvendor = 0x14ff, .subdevice = 0x0408, .action = VIA_DXS_SRC }, /* Twinhead laptop */ + { .subvendor = 0x14ff, .subdevice = 0x0408, .action = VIA_DXS_NO_VRA }, /* Twinhead mobo */ { .subvendor = 0x1584, .subdevice = 0x8120, .action = VIA_DXS_ENABLE }, /* Gericom/Targa/Vobis/Uniwill laptop */ { .subvendor = 0x1584, .subdevice = 0x8123, .action = VIA_DXS_NO_VRA }, /* Uniwill (Targa Visionary XP-210) */ { .subvendor = 0x161f, .subdevice = 0x202b, .action = VIA_DXS_NO_VRA }, /* Amira Note book */ @@ -2186,7 +2187,6 @@ static int __devinit check_dxs_list(struct pci_dev *pci) { .subvendor = 0x1695, .subdevice = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */ { .subvendor = 0x1849, .subdevice = 0x3059, .action = VIA_DXS_NO_VRA }, /* ASRock K7VM2 */ { .subvendor = 0x1919, .subdevice = 0x200a, .action = VIA_DXS_NO_VRA }, /* Soltek SL-K8Tpro-939 */ - { .subvendor = 0x4005, .subdevice = 0x4710, .action = VIA_DXS_SRC }, /* MSI K7T266 Pro2 (MS-6380 V2.0) BIOS 3.7 */ { } /* terminator */ }; struct dxs_whitelist *w; diff --git a/trunk/sound/pci/via82xx_modem.c b/trunk/sound/pci/via82xx_modem.c index 4a9779cc9733..5896d289f9ac 100644 --- a/trunk/sound/pci/via82xx_modem.c +++ b/trunk/sound/pci/via82xx_modem.c @@ -408,7 +408,8 @@ static void snd_via82xx_codec_wait(ac97_t *ac97) int err; err = snd_via82xx_codec_ready(chip, ac97->num); /* here we need to wait fairly for long time.. */ - msleep(500); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/2); } static void snd_via82xx_codec_write(ac97_t *ac97, @@ -922,7 +923,7 @@ static void __devinit snd_via82xx_proc_init(via82xx_t *chip) static int snd_via82xx_chip_init(via82xx_t *chip) { unsigned int val; - unsigned long end_time; + int max_count; unsigned char pval; pci_read_config_byte(chip->pci, VIA_MC97_CTRL, &pval); @@ -961,14 +962,14 @@ static int snd_via82xx_chip_init(via82xx_t *chip) } /* wait until codec ready */ - end_time = jiffies + msecs_to_jiffies(750); + max_count = ((3 * HZ) / 4) + 1; do { pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ break; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1); - } while (time_before(jiffies, end_time)); + } while (--max_count > 0); if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) snd_printk("AC'97 codec is not ready [0x%x]\n", val); @@ -976,7 +977,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip) snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ | VIA_REG_AC97_SECONDARY_VALID | (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT)); - end_time = jiffies + msecs_to_jiffies(750); + max_count = ((3 * HZ) / 4) + 1; snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ | VIA_REG_AC97_SECONDARY_VALID | (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT)); @@ -987,7 +988,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip) } set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1); - } while (time_before(jiffies, end_time)); + } while (--max_count > 0); /* This is ok, the most of motherboards have only one codec */ __ac97_ok2: diff --git a/trunk/sound/pci/ymfpci/ymfpci_main.c b/trunk/sound/pci/ymfpci/ymfpci_main.c index d54f88a1b525..2ae79610ecb5 100644 --- a/trunk/sound/pci/ymfpci/ymfpci_main.c +++ b/trunk/sound/pci/ymfpci/ymfpci_main.c @@ -84,16 +84,16 @@ static inline void snd_ymfpci_writel(ymfpci_t *chip, u32 offset, u32 val) static int snd_ymfpci_codec_ready(ymfpci_t *chip, int secondary) { - unsigned long end_time; + signed long end_time; u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR; - end_time = jiffies + msecs_to_jiffies(750); + end_time = (jiffies + ((3 * HZ) / 4)) + 1; do { if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0) return 0; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1); - } while (time_before(jiffies, end_time)); + } while (end_time - (signed long)jiffies >= 0); snd_printk("codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg)); return -EBUSY; } diff --git a/trunk/sound/pcmcia/Kconfig b/trunk/sound/pcmcia/Kconfig index 5d1b0b762efa..3611e298834f 100644 --- a/trunk/sound/pcmcia/Kconfig +++ b/trunk/sound/pcmcia/Kconfig @@ -8,12 +8,23 @@ config SND_VXPOCKET depends on SND && PCMCIA && ISA select SND_VX_LIB help - Say Y here to include support for Digigram VXpocket and - VXpocket 440 soundcards. + Say Y here to include support for Digigram VXpocket + soundcards. To compile this driver as a module, choose M here: the module will be called snd-vxpocket. +config SND_VXP440 + tristate "Digigram VXpocket 440" + depends on SND && PCMCIA && ISA + select SND_VX_LIB + help + Say Y here to include support for Digigram VXpocket 440 + soundcards. + + To compile this driver as a module, choose M here: the module + will be called snd-vxp440. + config SND_PDAUDIOCF tristate "Sound Core PDAudioCF" depends on SND && PCMCIA && ISA diff --git a/trunk/sound/pcmcia/vx/Makefile b/trunk/sound/pcmcia/vx/Makefile index 54971f01e968..f35dfa1af094 100644 --- a/trunk/sound/pcmcia/vx/Makefile +++ b/trunk/sound/pcmcia/vx/Makefile @@ -3,6 +3,9 @@ # Copyright (c) 2001 by Jaroslav Kysela # -snd-vxpocket-objs := vxpocket.o vxp_ops.o vxp_mixer.o +snd-vx-cs-objs := vx_entry.o vxp_ops.o vxp_mixer.o +snd-vxpocket-objs := vxpocket.o +snd-vxp440-objs := vxp440.o -obj-$(CONFIG_SND_VXPOCKET) += snd-vxpocket.o +obj-$(CONFIG_SND_VXPOCKET) += snd-vxpocket.o snd-vx-cs.o +obj-$(CONFIG_SND_VXP440) += snd-vxp440.o snd-vx-cs.o diff --git a/trunk/sound/pcmcia/vx/vx_entry.c b/trunk/sound/pcmcia/vx/vx_entry.c new file mode 100644 index 000000000000..df7a39ba9680 --- /dev/null +++ b/trunk/sound/pcmcia/vx/vx_entry.c @@ -0,0 +1,375 @@ +/* + * Driver for Digigram VXpocket soundcards + * + * PCMCIA entry part + * + * Copyright (c) 2002 by Takashi Iwai + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include "vxpocket.h" +#include +#include + + +MODULE_AUTHOR("Takashi Iwai "); +MODULE_DESCRIPTION("Common routines for Digigram PCMCIA VX drivers"); +MODULE_LICENSE("GPL"); + +/* + * prototypes + */ +static void vxpocket_config(dev_link_t *link); + + +static void vxpocket_release(dev_link_t *link) +{ + if (link->state & DEV_CONFIG) { + /* release cs resources */ + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; + } +} + +/* + * destructor + */ +static int snd_vxpocket_free(vx_core_t *chip) +{ + struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; + struct snd_vxp_entry *hw; + dev_link_t *link = &vxp->link; + + vxpocket_release(link); + + /* Break the link with Card Services */ + if (link->handle) + pcmcia_deregister_client(link->handle); + + hw = vxp->hw_entry; + if (hw) + hw->card_list[vxp->index] = NULL; + chip->card = NULL; + kfree(chip->dev); + + snd_vx_free_firmware(chip); + kfree(chip); + return 0; +} + +static int snd_vxpocket_dev_free(snd_device_t *device) +{ + vx_core_t *chip = device->device_data; + return snd_vxpocket_free(chip); +} + +/* + * snd_vxpocket_attach - attach callback for cs + * @hw: the hardware information + */ +dev_link_t *snd_vxpocket_attach(struct snd_vxp_entry *hw) +{ + client_reg_t client_reg; /* Register with cardmgr */ + dev_link_t *link; /* Info for cardmgr */ + int i, ret; + vx_core_t *chip; + struct snd_vxpocket *vxp; + snd_card_t *card; + static snd_device_ops_t ops = { + .dev_free = snd_vxpocket_dev_free, + }; + + snd_printdd(KERN_DEBUG "vxpocket_attach called\n"); + /* find an empty slot from the card list */ + for (i = 0; i < SNDRV_CARDS; i++) { + if (! hw->card_list[i]) + break; + } + if (i >= SNDRV_CARDS) { + snd_printk(KERN_ERR "vxpocket: too many cards found\n"); + return NULL; + } + if (! hw->enable_table[i]) + return NULL; /* disabled explicitly */ + + /* ok, create a card instance */ + card = snd_card_new(hw->index_table[i], hw->id_table[i], THIS_MODULE, 0); + if (card == NULL) { + snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n"); + return NULL; + } + + chip = snd_vx_create(card, hw->hardware, hw->ops, + sizeof(struct snd_vxpocket) - sizeof(vx_core_t)); + if (! chip) + return NULL; + +#ifdef SND_VX_FW_LOADER + /* fake a device here since pcmcia doesn't give a valid device... */ + chip->dev = kcalloc(1, sizeof(*chip->dev), GFP_KERNEL); + if (! chip->dev) { + snd_printk(KERN_ERR "vxp: can't malloc chip->dev\n"); + kfree(chip); + snd_card_free(card); + return NULL; + } + device_initialize(chip->dev); + sprintf(chip->dev->bus_id, "vxpocket%d", i); +#endif + + if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops) < 0) { + kfree(chip); + snd_card_free(card); + return NULL; + } + + vxp = (struct snd_vxpocket *)chip; + vxp->index = i; + vxp->hw_entry = hw; + chip->ibl.size = hw->ibl[i]; + hw->card_list[i] = chip; + + link = &vxp->link; + link->priv = chip; + + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + link->io.NumPorts1 = 16; + + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + // link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; + + link->irq.IRQInfo1 = IRQ_LEVEL_ID; + link->irq.Handler = &snd_vx_irq_handler; + link->irq.Instance = chip; + + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; + link->conf.ConfigIndex = 1; + link->conf.Present = PRESENT_OPTION; + + /* Register with Card Services */ + memset(&client_reg, 0, sizeof(client_reg)); + client_reg.dev_info = hw->dev_info; + client_reg.Version = 0x0210; + client_reg.event_callback_args.client_data = link; + + ret = pcmcia_register_client(&link->handle, &client_reg); + if (ret != CS_SUCCESS) { + cs_error(link->handle, RegisterClient, ret); + snd_card_free(card); + return NULL; + } + + /* Chain drivers */ + link->next = hw->dev_list; + hw->dev_list = link; + + /* snd_card_set_pm_callback(card, snd_vxpocket_suspend, snd_vxpocket_resume, chip); */ + + return link; +} + + +/** + * snd_vxpocket_assign_resources - initialize the hardware and card instance. + * @port: i/o port for the card + * @irq: irq number for the card + * + * this function assigns the specified port and irq, boot the card, + * create pcm and control instances, and initialize the rest hardware. + * + * returns 0 if successful, or a negative error code. + */ +static int snd_vxpocket_assign_resources(vx_core_t *chip, int port, int irq) +{ + int err; + snd_card_t *card = chip->card; + struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; + + snd_printdd(KERN_DEBUG "vxpocket assign resources: port = 0x%x, irq = %d\n", port, irq); + vxp->port = port; + + sprintf(card->shortname, "Digigram %s", card->driver); + sprintf(card->longname, "%s at 0x%x, irq %i", + card->shortname, port, irq); + + chip->irq = irq; + + if ((err = snd_vx_setup_firmware(chip)) < 0) + return err; + + return 0; +} + + +/* + * snd_vxpocket_detach - detach callback for cs + * @hw: the hardware information + */ +void snd_vxpocket_detach(struct snd_vxp_entry *hw, dev_link_t *link) +{ + vx_core_t *chip; + + if (! link) + return; + + chip = link->priv; + + snd_printdd(KERN_DEBUG "vxpocket_detach called\n"); + /* Remove the interface data from the linked list */ + if (hw) { + dev_link_t **linkp; + /* Locate device structure */ + for (linkp = &hw->dev_list; *linkp; linkp = &(*linkp)->next) + if (*linkp == link) { + *linkp = link->next; + break; + } + } + chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */ + snd_card_disconnect(chip->card); + snd_card_free_in_thread(chip->card); +} + +/* + * configuration callback + */ + +#define CS_CHECK(fn, ret) \ +do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) + +static void vxpocket_config(dev_link_t *link) +{ + client_handle_t handle = link->handle; + vx_core_t *chip = link->priv; + struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; + tuple_t tuple; + cisparse_t *parse = NULL; + u_short buf[32]; + int last_fn, last_ret; + + snd_printdd(KERN_DEBUG "vxpocket_config called\n"); + parse = kmalloc(sizeof(*parse), GFP_KERNEL); + if (! parse) { + snd_printk(KERN_ERR "vx: cannot allocate\n"); + return; + } + tuple.Attributes = 0; + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, parse)); + link->conf.ConfigBase = parse->config.base; + link->conf.Present = parse->config.rmask[0]; + + /* Configure card */ + link->state |= DEV_CONFIG; + + CS_CHECK(RequestIO, pcmcia_request_io(handle, &link->io)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); + + if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0) + goto failed; + + link->dev = &vxp->node; + link->state &= ~DEV_CONFIG_PENDING; + kfree(parse); + return; + +cs_failed: + cs_error(link->handle, last_fn, last_ret); +failed: + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; + kfree(parse); +} + + +/* + * event callback + */ +int vxpocket_event(event_t event, int priority, event_callback_args_t *args) +{ + dev_link_t *link = args->client_data; + vx_core_t *chip = link->priv; + + switch (event) { + case CS_EVENT_CARD_REMOVAL: + snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n"); + link->state &= ~DEV_PRESENT; + if (link->state & DEV_CONFIG) { + chip->chip_status |= VX_STAT_IS_STALE; + } + break; + case CS_EVENT_CARD_INSERTION: + snd_printdd(KERN_DEBUG "CARD_INSERTION..\n"); + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + vxpocket_config(link); + break; +#ifdef CONFIG_PM + case CS_EVENT_PM_SUSPEND: + snd_printdd(KERN_DEBUG "SUSPEND\n"); + link->state |= DEV_SUSPEND; + if (chip && chip->card->pm_suspend) { + snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n"); + chip->card->pm_suspend(chip->card, PMSG_SUSPEND); + } + /* Fall through... */ + case CS_EVENT_RESET_PHYSICAL: + snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n"); + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); + break; + case CS_EVENT_PM_RESUME: + snd_printdd(KERN_DEBUG "RESUME\n"); + link->state &= ~DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_CARD_RESET: + snd_printdd(KERN_DEBUG "CARD_RESET\n"); + if (DEV_OK(link)) { + //struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; + snd_printdd(KERN_DEBUG "requestconfig...\n"); + pcmcia_request_configuration(link->handle, &link->conf); + if (chip && chip->card->pm_resume) { + snd_printdd(KERN_DEBUG "calling snd_vx_resume\n"); + chip->card->pm_resume(chip->card); + } + } + snd_printdd(KERN_DEBUG "resume done!\n"); + break; +#endif + } + return 0; +} + +/* + * exported stuffs + */ +EXPORT_SYMBOL(snd_vxpocket_ops); +EXPORT_SYMBOL(snd_vxpocket_attach); +EXPORT_SYMBOL(vxpocket_event); +EXPORT_SYMBOL(snd_vxpocket_detach); diff --git a/trunk/sound/pcmcia/vx/vxp440.c b/trunk/sound/pcmcia/vx/vxp440.c new file mode 100644 index 000000000000..59190a833001 --- /dev/null +++ b/trunk/sound/pcmcia/vx/vxp440.c @@ -0,0 +1,14 @@ +#define COMPILE_VXP440 + +/* + add the following as /etc/pcmcia/vxp440.conf: + + device "snd-vxp440" + class "audio" module "snd-vxp440" + + card "Digigram VX-POCKET440" + manfid 0x01f1, 0x0100 + bind "snd-vxp440" +*/ + +#include "vxpocket.c" diff --git a/trunk/sound/pcmcia/vx/vxpocket.c b/trunk/sound/pcmcia/vx/vxpocket.c index 3a82161d3b24..62d6fa128148 100644 --- a/trunk/sound/pcmcia/vx/vxpocket.c +++ b/trunk/sound/pcmcia/vx/vxpocket.c @@ -24,17 +24,21 @@ #include #include #include "vxpocket.h" -#include -#include #include /* */ +#ifdef COMPILE_VXP440 +#define CARD_NAME "VXPocket440" +#else +#define CARD_NAME "VXPocket" +#endif + MODULE_AUTHOR("Takashi Iwai "); -MODULE_DESCRIPTION("Digigram VXPocket"); +MODULE_DESCRIPTION("Digigram " CARD_NAME); MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{Digigram,VXPocket},{Digigram,VXPocket440}}"); +MODULE_SUPPORTED_DEVICE("{{Digigram," CARD_NAME "}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ @@ -42,405 +46,82 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ static int ibl[SNDRV_CARDS]; module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for VXPocket soundcard."); +MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for VXPocket soundcard."); +MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard."); module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable VXPocket soundcard."); +MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard."); module_param_array(ibl, int, NULL, 0444); -MODULE_PARM_DESC(ibl, "Capture IBL size for VXPocket soundcard."); +MODULE_PARM_DESC(ibl, "Capture IBL size for " CARD_NAME " soundcard."); /* */ -static unsigned int card_alloc; -static dev_link_t *dev_list; /* Linked list of devices */ -static dev_info_t dev_info = "snd-vxpocket"; - - -static int vxpocket_event(event_t event, int priority, event_callback_args_t *args); - - -/* - */ -static void vxpocket_release(dev_link_t *link) -{ - if (link->state & DEV_CONFIG) { - /* release cs resources */ - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - link->state &= ~DEV_CONFIG; - } - if (link->handle) { - /* Break the link with Card Services */ - pcmcia_deregister_client(link->handle); - link->handle = NULL; - } -} - -/* - * destructor, called from snd_card_free_in_thread() - */ -static int snd_vxpocket_dev_free(snd_device_t *device) -{ - vx_core_t *chip = device->device_data; +#ifdef COMPILE_VXP440 - snd_vx_free_firmware(chip); - kfree(chip); - return 0; -} +/* 1 DSP, 1 sync UER, 1 sync World Clock (NIY) */ +/* SMPTE (NIY) */ +/* 2 stereo analog input (line/micro) */ +/* 2 stereo analog output */ +/* Only output levels can be modified */ +/* UER, but only for the first two inputs and outputs. */ +#define NUM_CODECS 2 +#define CARD_TYPE VX_TYPE_VXP440 +#define DEV_INFO "snd-vxp440" -/* - * Hardware information - */ +#else -/* VX-pocket V2 - * - * 1 DSP, 1 sync UER - * 1 programmable clock (NIY) - * 1 stereo analog input (line/micro) - * 1 stereo analog output - * Only output levels can be modified - */ +/* 1 DSP, 1 sync UER */ +/* 1 programmable clock (NIY) */ +/* 1 stereo analog input (line/micro) */ +/* 1 stereo analog output */ +/* Only output levels can be modified */ -static struct snd_vx_hardware vxpocket_hw = { - .name = "VXPocket", - .type = VX_TYPE_VXPOCKET, +#define NUM_CODECS 1 +#define CARD_TYPE VX_TYPE_VXPOCKET +#define DEV_INFO "snd-vxpocket" - /* hardware specs */ - .num_codecs = 1, - .num_ins = 1, - .num_outs = 1, - .output_level_max = VX_ANALOG_OUT_LEVEL_MAX, -}; +#endif -/* VX-pocket 440 - * - * 1 DSP, 1 sync UER, 1 sync World Clock (NIY) - * SMPTE (NIY) - * 2 stereo analog input (line/micro) - * 2 stereo analog output - * Only output levels can be modified - * UER, but only for the first two inputs and outputs. - */ +static dev_info_t dev_info = DEV_INFO; -static struct snd_vx_hardware vxp440_hw = { - .name = "VXPocket440", - .type = VX_TYPE_VXP440, +static struct snd_vx_hardware vxp_hw = { + .name = CARD_NAME, + .type = CARD_TYPE, /* hardware specs */ - .num_codecs = 2, - .num_ins = 2, - .num_outs = 2, + .num_codecs = NUM_CODECS, + .num_ins = NUM_CODECS, + .num_outs = NUM_CODECS, .output_level_max = VX_ANALOG_OUT_LEVEL_MAX, }; +static struct snd_vxp_entry hw_entry = { + .dev_info = &dev_info, -/* - * create vxpocket instance - */ -static struct snd_vxpocket *snd_vxpocket_new(snd_card_t *card, int ibl) -{ - client_reg_t client_reg; /* Register with cardmgr */ - dev_link_t *link; /* Info for cardmgr */ - vx_core_t *chip; - struct snd_vxpocket *vxp; - int ret; - static snd_device_ops_t ops = { - .dev_free = snd_vxpocket_dev_free, - }; - - chip = snd_vx_create(card, &vxpocket_hw, &snd_vxpocket_ops, - sizeof(struct snd_vxpocket) - sizeof(vx_core_t)); - if (! chip) - return NULL; - - if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops) < 0) { - kfree(chip); - return NULL; - } - chip->ibl.size = ibl; - - vxp = (struct snd_vxpocket *)chip; - - link = &vxp->link; - link->priv = chip; - - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.NumPorts1 = 16; - - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; - - link->irq.IRQInfo1 = IRQ_LEVEL_ID; - link->irq.Handler = &snd_vx_irq_handler; - link->irq.Instance = chip; - - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; - link->conf.IntType = INT_MEMORY_AND_IO; - link->conf.ConfigIndex = 1; - link->conf.Present = PRESENT_OPTION; - - /* Register with Card Services */ - memset(&client_reg, 0, sizeof(client_reg)); - client_reg.dev_info = &dev_info; - client_reg.EventMask = - CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL -#ifdef CONFIG_PM - | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET - | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME -#endif - ; - client_reg.event_handler = &vxpocket_event; - client_reg.Version = 0x0210; - client_reg.event_callback_args.client_data = link; - - ret = pcmcia_register_client(&link->handle, &client_reg); - if (ret != CS_SUCCESS) { - cs_error(link->handle, RegisterClient, ret); - return NULL; - } - - return vxp; -} - - -/** - * snd_vxpocket_assign_resources - initialize the hardware and card instance. - * @port: i/o port for the card - * @irq: irq number for the card - * - * this function assigns the specified port and irq, boot the card, - * create pcm and control instances, and initialize the rest hardware. - * - * returns 0 if successful, or a negative error code. - */ -static int snd_vxpocket_assign_resources(vx_core_t *chip, int port, int irq) -{ - int err; - snd_card_t *card = chip->card; - struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; - - snd_printdd(KERN_DEBUG "vxpocket assign resources: port = 0x%x, irq = %d\n", port, irq); - vxp->port = port; - - sprintf(card->shortname, "Digigram %s", card->driver); - sprintf(card->longname, "%s at 0x%x, irq %i", - card->shortname, port, irq); - - chip->irq = irq; - - if ((err = snd_vx_setup_firmware(chip)) < 0) - return err; - - return 0; -} - - -/* - * configuration callback - */ - -#define CS_CHECK(fn, ret) \ -do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) - -static void vxpocket_config(dev_link_t *link) -{ - client_handle_t handle = link->handle; - vx_core_t *chip = link->priv; - struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; - tuple_t tuple; - cisparse_t *parse; - u_short buf[32]; - int last_fn, last_ret; - - snd_printdd(KERN_DEBUG "vxpocket_config called\n"); - parse = kmalloc(sizeof(*parse), GFP_KERNEL); - if (! parse) { - snd_printk(KERN_ERR "vx: cannot allocate\n"); - return; - } - tuple.Attributes = 0; - tuple.TupleData = (cisdata_t *)buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; - tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, parse)); - link->conf.ConfigBase = parse->config.base; - link->conf.Present = parse->config.rmask[0]; - - /* redefine hardware record according to the VERSION1 string */ - tuple.DesiredTuple = CISTPL_VERS_1; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, parse)); - if (! strcmp(parse->version_1.str + parse->version_1.ofs[1], "VX-POCKET")) { - snd_printdd("VX-pocket is detected\n"); - } else { - snd_printdd("VX-pocket 440 is detected\n"); - /* overwrite the hardware information */ - chip->hw = &vxp440_hw; - chip->type = vxp440_hw.type; - strcpy(chip->card->driver, vxp440_hw.name); - } - - /* Configure card */ - link->state |= DEV_CONFIG; - - CS_CHECK(RequestIO, pcmcia_request_io(handle, &link->io)); - CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); - - chip->dev = &handle_to_dev(link->handle); - - if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0) - goto failed; - - link->dev = &vxp->node; - link->state &= ~DEV_CONFIG_PENDING; - kfree(parse); - return; - -cs_failed: - cs_error(link->handle, last_fn, last_ret); -failed: - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - link->state &= ~DEV_CONFIG; - kfree(parse); -} - - -/* - * event callback - */ -static int vxpocket_event(event_t event, int priority, event_callback_args_t *args) -{ - dev_link_t *link = args->client_data; - vx_core_t *chip = link->priv; - - switch (event) { - case CS_EVENT_CARD_REMOVAL: - snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n"); - link->state &= ~DEV_PRESENT; - if (link->state & DEV_CONFIG) - chip->chip_status |= VX_STAT_IS_STALE; - break; - case CS_EVENT_CARD_INSERTION: - snd_printdd(KERN_DEBUG "CARD_INSERTION..\n"); - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - vxpocket_config(link); - break; -#ifdef CONFIG_PM - case CS_EVENT_PM_SUSPEND: - snd_printdd(KERN_DEBUG "SUSPEND\n"); - link->state |= DEV_SUSPEND; - if (chip && chip->card->pm_suspend) { - snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n"); - chip->card->pm_suspend(chip->card, PMSG_SUSPEND); - } - /* Fall through... */ - case CS_EVENT_RESET_PHYSICAL: - snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n"); - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - break; - case CS_EVENT_PM_RESUME: - snd_printdd(KERN_DEBUG "RESUME\n"); - link->state &= ~DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_CARD_RESET: - snd_printdd(KERN_DEBUG "CARD_RESET\n"); - if (DEV_OK(link)) { - //struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; - snd_printdd(KERN_DEBUG "requestconfig...\n"); - pcmcia_request_configuration(link->handle, &link->conf); - if (chip && chip->card->pm_resume) { - snd_printdd(KERN_DEBUG "calling snd_vx_resume\n"); - chip->card->pm_resume(chip->card); - } - } - snd_printdd(KERN_DEBUG "resume done!\n"); - break; -#endif - } - return 0; -} + /* module parameters */ + .index_table = index, + .id_table = id, + .enable_table = enable, + .ibl = ibl, + /* h/w config */ + .hardware = &vxp_hw, + .ops = &snd_vxpocket_ops, +}; /* */ static dev_link_t *vxp_attach(void) { - snd_card_t *card; - struct snd_vxpocket *vxp; - int i; - - /* find an empty slot from the card list */ - for (i = 0; i < SNDRV_CARDS; i++) { - if (! card_alloc & (1 << i)) - break; - } - if (i >= SNDRV_CARDS) { - snd_printk(KERN_ERR "vxpocket: too many cards found\n"); - return NULL; - } - if (! enable[i]) - return NULL; /* disabled explicitly */ - - /* ok, create a card instance */ - card = snd_card_new(index[i], id[i], THIS_MODULE, 0); - if (card == NULL) { - snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n"); - return NULL; - } - - vxp = snd_vxpocket_new(card, ibl[i]); - if (! vxp) { - snd_card_free(card); - return NULL; - } - - vxp->index = index[i]; - card_alloc |= 1 << i; - - /* Chain drivers */ - vxp->link.next = dev_list; - dev_list = &vxp->link; - - return &vxp->link; + return snd_vxpocket_attach(&hw_entry); } static void vxp_detach(dev_link_t *link) { - struct snd_vxpocket *vxp; - vx_core_t *chip; - dev_link_t **linkp; - - if (! link) - return; - - vxp = link->priv; - chip = (vx_core_t *)vxp; - card_alloc &= ~(1 << vxp->index); - - /* Remove the interface data from the linked list */ - for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) - if (*linkp == link) { - *linkp = link->next; - break; - } - - chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */ - snd_card_disconnect(chip->card); - vxpocket_release(link); - snd_card_free_in_thread(chip->card); + snd_vxpocket_detach(&hw_entry, link); } /* @@ -456,7 +137,7 @@ MODULE_DEVICE_TABLE(pcmcia, vxp_ids); static struct pcmcia_driver vxp_cs_driver = { .owner = THIS_MODULE, .drv = { - .name = "snd-vxpocket", + .name = DEV_INFO, }, .attach = vxp_attach, .detach = vxp_detach, @@ -471,7 +152,7 @@ static int __init init_vxpocket(void) static void __exit exit_vxpocket(void) { pcmcia_unregister_driver(&vxp_cs_driver); - BUG_ON(dev_list != NULL); + BUG_ON(hw_entry.dev_list != NULL); } module_init(init_vxpocket); diff --git a/trunk/sound/pcmcia/vx/vxpocket.h b/trunk/sound/pcmcia/vx/vxpocket.h index 70754aa3dd11..4462c04a4e8f 100644 --- a/trunk/sound/pcmcia/vx/vxpocket.h +++ b/trunk/sound/pcmcia/vx/vxpocket.h @@ -28,6 +28,24 @@ #include #include +struct snd_vxp_entry { + dev_info_t *dev_info; + + /* module parameters */ + int *index_table; + char **id_table; + int *enable_table; + int *ibl; + + /* h/w config */ + struct snd_vx_hardware *hardware; + struct snd_vx_ops *ops; + + /* slots */ + vx_core_t *card_list[SNDRV_CARDS]; + dev_link_t *dev_list; /* Linked list of devices */ +}; + struct snd_vxpocket { vx_core_t core; @@ -39,7 +57,8 @@ struct snd_vxpocket { unsigned int regCDSP; /* current CDSP register */ unsigned int regDIALOG; /* current DIALOG register */ - int index; /* card index */ + int index; + struct snd_vxp_entry *hw_entry; /* pcmcia stuff */ dev_link_t link; @@ -51,6 +70,12 @@ extern struct snd_vx_ops snd_vxpocket_ops; void vx_set_mic_boost(vx_core_t *chip, int boost); void vx_set_mic_level(vx_core_t *chip, int level); +/* + * pcmcia stuff + */ +dev_link_t *snd_vxpocket_attach(struct snd_vxp_entry *hw); +void snd_vxpocket_detach(struct snd_vxp_entry *hw, dev_link_t *link); + int vxp_add_mic_controls(vx_core_t *chip); /* Constants used to access the CDSP register (0x08). */ diff --git a/trunk/sound/ppc/awacs.c b/trunk/sound/ppc/awacs.c index 758ca1bcbcf2..061e52d3d771 100644 --- a/trunk/sound/ppc/awacs.c +++ b/trunk/sound/ppc/awacs.c @@ -103,7 +103,7 @@ static void screamer_recalibrate(pmac_t *chip) snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]); if (chip->manufacturer == 0x1) /* delay for broken crystal part */ - msleep(750); + big_mdelay(750); snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1] | MASK_RECALIBRATE | MASK_CMUTE | MASK_AMUTE); snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]); @@ -653,10 +653,10 @@ static void snd_pmac_awacs_resume(pmac_t *chip) { if (machine_is_compatible("PowerBook3,1") || machine_is_compatible("PowerBook3,2")) { - msleep(100); + big_mdelay(100); snd_pmac_awacs_write_reg(chip, 1, chip->awacs_reg[1] & ~MASK_PAROUT); - msleep(300); + big_mdelay(300); } awacs_restore_all_regs(chip); diff --git a/trunk/sound/ppc/pmac.h b/trunk/sound/ppc/pmac.h index ae3bb6c6edff..582db5220119 100644 --- a/trunk/sound/ppc/pmac.h +++ b/trunk/sound/ppc/pmac.h @@ -212,4 +212,9 @@ int snd_pmac_boolean_mono_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *ui int snd_pmac_add_automute(pmac_t *chip); +#define big_mdelay(msec) do {\ + set_current_state(TASK_UNINTERRUPTIBLE);\ + schedule_timeout(((msec) * HZ + 999) / 1000);\ +} while (0) + #endif /* __PMAC_H */ diff --git a/trunk/sound/ppc/tumbler.c b/trunk/sound/ppc/tumbler.c index b94437c024b1..36c5d5d45bb1 100644 --- a/trunk/sound/ppc/tumbler.c +++ b/trunk/sound/ppc/tumbler.c @@ -945,7 +945,7 @@ static void device_change_handler(void *self) check_mute(chip, &mix->line_mute, 0, mix->auto_mute_notify, chip->lineout_sw_ctl); if (mix->anded_reset) - msleep(10); + big_mdelay(10); check_mute(chip, &mix->amp_mute, 1, mix->auto_mute_notify, chip->speaker_sw_ctl); mix->drc_enable = 0; @@ -954,7 +954,7 @@ static void device_change_handler(void *self) check_mute(chip, &mix->amp_mute, 0, mix->auto_mute_notify, chip->speaker_sw_ctl); if (mix->anded_reset) - msleep(10); + big_mdelay(10); check_mute(chip, &mix->hp_mute, 1, mix->auto_mute_notify, chip->master_sw_ctl); if (mix->line_mute.addr != 0) @@ -1109,22 +1109,22 @@ static void tumbler_reset_audio(pmac_t *chip) DBG("(I) codec anded reset !\n"); write_audio_gpio(&mix->hp_mute, 0); write_audio_gpio(&mix->amp_mute, 0); - msleep(200); + big_mdelay(200); write_audio_gpio(&mix->hp_mute, 1); write_audio_gpio(&mix->amp_mute, 1); - msleep(100); + big_mdelay(100); write_audio_gpio(&mix->hp_mute, 0); write_audio_gpio(&mix->amp_mute, 0); - msleep(100); + big_mdelay(100); } else { DBG("(I) codec normal reset !\n"); write_audio_gpio(&mix->audio_reset, 0); - msleep(200); + big_mdelay(200); write_audio_gpio(&mix->audio_reset, 1); - msleep(100); + big_mdelay(100); write_audio_gpio(&mix->audio_reset, 0); - msleep(100); + big_mdelay(100); } } diff --git a/trunk/sound/sparc/Kconfig b/trunk/sound/sparc/Kconfig index 25a8a558ef92..2358df1c45a9 100644 --- a/trunk/sound/sparc/Kconfig +++ b/trunk/sound/sparc/Kconfig @@ -7,30 +7,12 @@ config SND_SUN_AMD7930 tristate "Sun AMD7930" depends on SBUS && SND select SND_PCM - help - Say Y here to include support for AMD7930 sound device on Sun. - - To compile this driver as a module, choose M here: the module - will be called snd-sun-amd7930. +# dep_tristate 'Sun DBRI' CONFIG_SND_SUN_DBRI $CONFIG_SND config SND_SUN_CS4231 tristate "Sun CS4231" depends on SND select SND_PCM - help - Say Y here to include support for CS4231 sound device on Sun. - - To compile this driver as a module, choose M here: the module - will be called snd-sun-cs4231. - -config SND_SUN_DBRI - tristate "Sun DBRI" - depends on SND && SBUS - select SND_PCM - help - Say Y here to include support for DBRI sound device on Sun. - - To compile this driver as a module, choose M here: the module - will be called snd-sun-dbri. endmenu + diff --git a/trunk/sound/sparc/Makefile b/trunk/sound/sparc/Makefile index 3cd89c67c2f2..6809cc92d276 100644 --- a/trunk/sound/sparc/Makefile +++ b/trunk/sound/sparc/Makefile @@ -4,9 +4,9 @@ # snd-sun-amd7930-objs := amd7930.o +#snd-sun-dbri-objs := dbri.o snd-sun-cs4231-objs := cs4231.o -snd-sun-dbri-objs := dbri.o obj-$(CONFIG_SND_SUN_AMD7930) += snd-sun-amd7930.o +#obj-$(CONFIG_SND_SUN_DBRI) += snd-sun-dbri.o obj-$(CONFIG_SND_SUN_CS4231) += snd-sun-cs4231.o -obj-$(CONFIG_SND_SUN_DBRI) += snd-sun-dbri.o diff --git a/trunk/sound/sparc/dbri.c b/trunk/sound/sparc/dbri.c deleted file mode 100644 index 941c7b1e7ebb..000000000000 --- a/trunk/sound/sparc/dbri.c +++ /dev/null @@ -1,2729 +0,0 @@ -/* - * Driver for DBRI sound chip found on Sparcs. - * Copyright (C) 2004 Martin Habets (mhabets@users.sourceforge.net) - * - * Based entirely upon drivers/sbus/audio/dbri.c which is: - * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) - * Copyright (C) 1998, 1999 Brent Baccala (baccala@freesoft.org) - * - * This is the lowlevel driver for the DBRI & MMCODEC duo used for ISDN & AUDIO - * on Sun SPARCstation 10, 20, LX and Voyager models. - * - * - DBRI: AT&T T5900FX Dual Basic Rates ISDN Interface. It is a 32 channel - * data time multiplexer with ISDN support (aka T7259) - * Interfaces: SBus,ISDN NT & TE, CHI, 4 bits parallel. - * CHI: (spelled ki) Concentration Highway Interface (AT&T or Intel bus ?). - * Documentation: - * - "STP 4000SBus Dual Basic Rate ISDN (DBRI) Tranceiver" from - * Sparc Technology Business (courtesy of Sun Support) - * - Data sheet of the T7903, a newer but very similar ISA bus equivalent - * available from the Lucent (formarly AT&T microelectronics) home - * page. - * - http://www.freesoft.org/Linux/DBRI/ - * - MMCODEC: Crystal Semiconductor CS4215 16 bit Multimedia Audio Codec - * Interfaces: CHI, Audio In & Out, 2 bits parallel - * Documentation: from the Crystal Semiconductor home page. - * - * The DBRI is a 32 pipe machine, each pipe can transfer some bits between - * memory and a serial device (long pipes, nr 0-15) or between two serial - * devices (short pipes, nr 16-31), or simply send a fixed data to a serial - * device (short pipes). - * A timeslot defines the bit-offset and nr of bits read from a serial device. - * The timeslots are linked to 6 circular lists, one for each direction for - * each serial device (NT,TE,CHI). A timeslot is associated to 1 or 2 pipes - * (the second one is a monitor/tee pipe, valid only for serial input). - * - * The mmcodec is connected via the CHI bus and needs the data & some - * parameters (volume, balance, output selection) timemultiplexed in 8 byte - * chunks. It also has a control mode, which serves for audio format setting. - * - * Looking at the CS4215 data sheet it is easy to set up 2 or 4 codecs on - * the same CHI bus, so I thought perhaps it is possible to use the onboard - * & the speakerbox codec simultanously, giving 2 (not very independent :-) - * audio devices. But the SUN HW group decided against it, at least on my - * LX the speakerbox connector has at least 1 pin missing and 1 wrongly - * connected. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -MODULE_AUTHOR("Rudolf Koenig, Brent Baccala and Martin Habets"); -MODULE_DESCRIPTION("Sun DBRI"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{Sun,DBRI}}"); - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ - -module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for Sun DBRI soundcard."); -module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for Sun DBRI soundcard."); -module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable Sun DBRI soundcard."); - -#define DBRI_DEBUG - -#define D_INT (1<<0) -#define D_GEN (1<<1) -#define D_CMD (1<<2) -#define D_MM (1<<3) -#define D_USR (1<<4) -#define D_DESC (1<<5) - -static int dbri_debug = 0; -module_param(dbri_debug, int, 0444); -MODULE_PARM_DESC(dbri_debug, "Debug value for Sun DBRI soundcard."); - -#ifdef DBRI_DEBUG -static char *cmds[] = { - "WAIT", "PAUSE", "JUMP", "IIQ", "REX", "SDP", "CDP", "DTS", - "SSP", "CHI", "NT", "TE", "CDEC", "TEST", "CDM", "RESRV" -}; - -#define dprintk(a, x...) if(dbri_debug & a) printk(KERN_DEBUG x) - -#define DBRI_CMD(cmd, intr, value) ((cmd << 28) | \ - (1 << 27) | \ - value) -#else -#define dprintk(a, x...) - -#define DBRI_CMD(cmd, intr, value) ((cmd << 28) | \ - (intr << 27) | \ - value) -#endif /* DBRI_DEBUG */ - -/*************************************************************************** - CS4215 specific definitions and structures -****************************************************************************/ - -struct cs4215 { - __u8 data[4]; /* Data mode: Time slots 5-8 */ - __u8 ctrl[4]; /* Ctrl mode: Time slots 1-4 */ - __u8 onboard; - __u8 offset; /* Bit offset from frame sync to time slot 1 */ - volatile __u32 status; - volatile __u32 version; - __u8 precision; /* In bits, either 8 or 16 */ - __u8 channels; /* 1 or 2 */ -}; - -/* - * Control mode first - */ - -/* Time Slot 1, Status register */ -#define CS4215_CLB (1<<2) /* Control Latch Bit */ -#define CS4215_OLB (1<<3) /* 1: line: 2.0V, speaker 4V */ - /* 0: line: 2.8V, speaker 8V */ -#define CS4215_MLB (1<<4) /* 1: Microphone: 20dB gain disabled */ -#define CS4215_RSRVD_1 (1<<5) - -/* Time Slot 2, Data Format Register */ -#define CS4215_DFR_LINEAR16 0 -#define CS4215_DFR_ULAW 1 -#define CS4215_DFR_ALAW 2 -#define CS4215_DFR_LINEAR8 3 -#define CS4215_DFR_STEREO (1<<2) -static struct { - unsigned short freq; - unsigned char xtal; - unsigned char csval; -} CS4215_FREQ[] = { - { 8000, (1 << 4), (0 << 3) }, - { 16000, (1 << 4), (1 << 3) }, - { 27429, (1 << 4), (2 << 3) }, /* Actually 24428.57 */ - { 32000, (1 << 4), (3 << 3) }, - /* { NA, (1 << 4), (4 << 3) }, */ - /* { NA, (1 << 4), (5 << 3) }, */ - { 48000, (1 << 4), (6 << 3) }, - { 9600, (1 << 4), (7 << 3) }, - { 5513, (2 << 4), (0 << 3) }, /* Actually 5512.5 */ - { 11025, (2 << 4), (1 << 3) }, - { 18900, (2 << 4), (2 << 3) }, - { 22050, (2 << 4), (3 << 3) }, - { 37800, (2 << 4), (4 << 3) }, - { 44100, (2 << 4), (5 << 3) }, - { 33075, (2 << 4), (6 << 3) }, - { 6615, (2 << 4), (7 << 3) }, - { 0, 0, 0} -}; - -#define CS4215_HPF (1<<7) /* High Pass Filter, 1: Enabled */ - -#define CS4215_12_MASK 0xfcbf /* Mask off reserved bits in slot 1 & 2 */ - -/* Time Slot 3, Serial Port Control register */ -#define CS4215_XEN (1<<0) /* 0: Enable serial output */ -#define CS4215_XCLK (1<<1) /* 1: Master mode: Generate SCLK */ -#define CS4215_BSEL_64 (0<<2) /* Bitrate: 64 bits per frame */ -#define CS4215_BSEL_128 (1<<2) -#define CS4215_BSEL_256 (2<<2) -#define CS4215_MCK_MAST (0<<4) /* Master clock */ -#define CS4215_MCK_XTL1 (1<<4) /* 24.576 MHz clock source */ -#define CS4215_MCK_XTL2 (2<<4) /* 16.9344 MHz clock source */ -#define CS4215_MCK_CLK1 (3<<4) /* Clockin, 256 x Fs */ -#define CS4215_MCK_CLK2 (4<<4) /* Clockin, see DFR */ - -/* Time Slot 4, Test Register */ -#define CS4215_DAD (1<<0) /* 0:Digital-Dig loop, 1:Dig-Analog-Dig loop */ -#define CS4215_ENL (1<<1) /* Enable Loopback Testing */ - -/* Time Slot 5, Parallel Port Register */ -/* Read only here and the same as the in data mode */ - -/* Time Slot 6, Reserved */ - -/* Time Slot 7, Version Register */ -#define CS4215_VERSION_MASK 0xf /* Known versions 0/C, 1/D, 2/E */ - -/* Time Slot 8, Reserved */ - -/* - * Data mode - */ -/* Time Slot 1-2: Left Channel Data, 2-3: Right Channel Data */ - -/* Time Slot 5, Output Setting */ -#define CS4215_LO(v) v /* Left Output Attenuation 0x3f: -94.5 dB */ -#define CS4215_LE (1<<6) /* Line Out Enable */ -#define CS4215_HE (1<<7) /* Headphone Enable */ - -/* Time Slot 6, Output Setting */ -#define CS4215_RO(v) v /* Right Output Attenuation 0x3f: -94.5 dB */ -#define CS4215_SE (1<<6) /* Speaker Enable */ -#define CS4215_ADI (1<<7) /* A/D Data Invalid: Busy in calibration */ - -/* Time Slot 7, Input Setting */ -#define CS4215_LG(v) v /* Left Gain Setting 0xf: 22.5 dB */ -#define CS4215_IS (1<<4) /* Input Select: 1=Microphone, 0=Line */ -#define CS4215_OVR (1<<5) /* 1: Overrange condition occurred */ -#define CS4215_PIO0 (1<<6) /* Parallel I/O 0 */ -#define CS4215_PIO1 (1<<7) - -/* Time Slot 8, Input Setting */ -#define CS4215_RG(v) v /* Right Gain Setting 0xf: 22.5 dB */ -#define CS4215_MA(v) (v<<4) /* Monitor Path Attenuation 0xf: mute */ - -/*************************************************************************** - DBRI specific definitions and structures -****************************************************************************/ - -/* DBRI main registers */ -#define REG0 0x00UL /* Status and Control */ -#define REG1 0x04UL /* Mode and Interrupt */ -#define REG2 0x08UL /* Parallel IO */ -#define REG3 0x0cUL /* Test */ -#define REG8 0x20UL /* Command Queue Pointer */ -#define REG9 0x24UL /* Interrupt Queue Pointer */ - -#define DBRI_NO_CMDS 64 -#define DBRI_NO_INTS 1 /* Note: the value of this define was - * originally 2. The ringbuffer to store - * interrupts in dma is currently broken. - * This is a temporary fix until the ringbuffer - * is fixed. - */ -#define DBRI_INT_BLK 64 -#define DBRI_NO_DESCS 64 -#define DBRI_NO_PIPES 32 - -#define DBRI_MM_ONB 1 -#define DBRI_MM_SB 2 - -#define DBRI_REC 0 -#define DBRI_PLAY 1 -#define DBRI_NO_STREAMS 2 - -/* One transmit/receive descriptor */ -struct dbri_mem { - volatile __u32 word1; - volatile __u32 ba; /* Transmit/Receive Buffer Address */ - volatile __u32 nda; /* Next Descriptor Address */ - volatile __u32 word4; -}; - -/* This structure is in a DMA region where it can accessed by both - * the CPU and the DBRI - */ -struct dbri_dma { - volatile s32 cmd[DBRI_NO_CMDS]; /* Place for commands */ - volatile s32 intr[DBRI_NO_INTS * DBRI_INT_BLK]; /* Interrupt field */ - struct dbri_mem desc[DBRI_NO_DESCS]; /* Xmit/receive descriptors */ -}; - -#define dbri_dma_off(member, elem) \ - ((u32)(unsigned long) \ - (&(((struct dbri_dma *)0)->member[elem]))) - -enum in_or_out { PIPEinput, PIPEoutput }; - -struct dbri_pipe { - u32 sdp; /* SDP command word */ - enum in_or_out direction; - int nextpipe; /* Next pipe in linked list */ - int prevpipe; - int cycle; /* Offset of timeslot (bits) */ - int length; /* Length of timeslot (bits) */ - int first_desc; /* Index of first descriptor */ - int desc; /* Index of active descriptor */ - volatile __u32 *recv_fixed_ptr; /* Ptr to receive fixed data */ -}; - -struct dbri_desc { - int inuse; /* Boolean flag */ - int next; /* Index of next desc, or -1 */ - unsigned int len; -}; - -/* Per stream (playback or record) information */ -typedef struct dbri_streaminfo { - snd_pcm_substream_t *substream; - u32 dvma_buffer; /* Device view of Alsa DMA buffer */ - int left; /* # of bytes left in DMA buffer */ - int size; /* Size of DMA buffer */ - size_t offset; /* offset in user buffer */ - int pipe; /* Data pipe used */ - int left_gain; /* mixer elements */ - int right_gain; - int balance; -} dbri_streaminfo_t; - -/* This structure holds the information for both chips (DBRI & CS4215) */ -typedef struct snd_dbri { - snd_card_t *card; /* ALSA card */ - snd_pcm_t *pcm; - - int regs_size, irq; /* Needed for unload */ - struct sbus_dev *sdev; /* SBUS device info */ - spinlock_t lock; - - volatile struct dbri_dma *dma; /* Pointer to our DMA block */ - u32 dma_dvma; /* DBRI visible DMA address */ - - void __iomem *regs; /* dbri HW regs */ - int dbri_version; /* 'e' and up is OK */ - int dbri_irqp; /* intr queue pointer */ - int wait_seen; - - struct dbri_pipe pipes[DBRI_NO_PIPES]; /* DBRI's 32 data pipes */ - struct dbri_desc descs[DBRI_NO_DESCS]; - - int chi_in_pipe; - int chi_out_pipe; - int chi_bpf; - - struct cs4215 mm; /* mmcodec special info */ - /* per stream (playback/record) info */ - struct dbri_streaminfo stream_info[DBRI_NO_STREAMS]; - - struct snd_dbri *next; -} snd_dbri_t; - -/* Needed for the ALSA macros to work */ -#define chip_t snd_dbri_t - -#define DBRI_MAX_VOLUME 63 /* Output volume */ -#define DBRI_MAX_GAIN 15 /* Input gain */ -#define DBRI_RIGHT_BALANCE 255 -#define DBRI_MID_BALANCE (DBRI_RIGHT_BALANCE >> 1) - -/* DBRI Reg0 - Status Control Register - defines. (Page 17) */ -#define D_P (1<<15) /* Program command & queue pointer valid */ -#define D_G (1<<14) /* Allow 4-Word SBus Burst */ -#define D_S (1<<13) /* Allow 16-Word SBus Burst */ -#define D_E (1<<12) /* Allow 8-Word SBus Burst */ -#define D_X (1<<7) /* Sanity Timer Disable */ -#define D_T (1<<6) /* Permit activation of the TE interface */ -#define D_N (1<<5) /* Permit activation of the NT interface */ -#define D_C (1<<4) /* Permit activation of the CHI interface */ -#define D_F (1<<3) /* Force Sanity Timer Time-Out */ -#define D_D (1<<2) /* Disable Master Mode */ -#define D_H (1<<1) /* Halt for Analysis */ -#define D_R (1<<0) /* Soft Reset */ - -/* DBRI Reg1 - Mode and Interrupt Register - defines. (Page 18) */ -#define D_LITTLE_END (1<<8) /* Byte Order */ -#define D_BIG_END (0<<8) /* Byte Order */ -#define D_MRR (1<<4) /* Multiple Error Ack on SBus (readonly) */ -#define D_MLE (1<<3) /* Multiple Late Error on SBus (readonly) */ -#define D_LBG (1<<2) /* Lost Bus Grant on SBus (readonly) */ -#define D_MBE (1<<1) /* Burst Error on SBus (readonly) */ -#define D_IR (1<<0) /* Interrupt Indicator (readonly) */ - -/* DBRI Reg2 - Parallel IO Register - defines. (Page 18) */ -#define D_ENPIO3 (1<<7) /* Enable Pin 3 */ -#define D_ENPIO2 (1<<6) /* Enable Pin 2 */ -#define D_ENPIO1 (1<<5) /* Enable Pin 1 */ -#define D_ENPIO0 (1<<4) /* Enable Pin 0 */ -#define D_ENPIO (0xf0) /* Enable all the pins */ -#define D_PIO3 (1<<3) /* Pin 3: 1: Data mode, 0: Ctrl mode */ -#define D_PIO2 (1<<2) /* Pin 2: 1: Onboard PDN */ -#define D_PIO1 (1<<1) /* Pin 1: 0: Reset */ -#define D_PIO0 (1<<0) /* Pin 0: 1: Speakerbox PDN */ - -/* DBRI Commands (Page 20) */ -#define D_WAIT 0x0 /* Stop execution */ -#define D_PAUSE 0x1 /* Flush long pipes */ -#define D_JUMP 0x2 /* New command queue */ -#define D_IIQ 0x3 /* Initialize Interrupt Queue */ -#define D_REX 0x4 /* Report command execution via interrupt */ -#define D_SDP 0x5 /* Setup Data Pipe */ -#define D_CDP 0x6 /* Continue Data Pipe (reread NULL Pointer) */ -#define D_DTS 0x7 /* Define Time Slot */ -#define D_SSP 0x8 /* Set short Data Pipe */ -#define D_CHI 0x9 /* Set CHI Global Mode */ -#define D_NT 0xa /* NT Command */ -#define D_TE 0xb /* TE Command */ -#define D_CDEC 0xc /* Codec setup */ -#define D_TEST 0xd /* No comment */ -#define D_CDM 0xe /* CHI Data mode command */ - -/* Special bits for some commands */ -#define D_PIPE(v) ((v)<<0) /* Pipe Nr: 0-15 long, 16-21 short */ - -/* Setup Data Pipe */ -/* IRM */ -#define D_SDP_2SAME (1<<18) /* Report 2nd time in a row value rcvd */ -#define D_SDP_CHANGE (2<<18) /* Report any changes */ -#define D_SDP_EVERY (3<<18) /* Report any changes */ -#define D_SDP_EOL (1<<17) /* EOL interrupt enable */ -#define D_SDP_IDLE (1<<16) /* HDLC idle interrupt enable */ - -/* Pipe data MODE */ -#define D_SDP_MEM (0<<13) /* To/from memory */ -#define D_SDP_HDLC (2<<13) -#define D_SDP_HDLC_D (3<<13) /* D Channel (prio control) */ -#define D_SDP_SER (4<<13) /* Serial to serial */ -#define D_SDP_FIXED (6<<13) /* Short only */ -#define D_SDP_MODE(v) ((v)&(7<<13)) - -#define D_SDP_TO_SER (1<<12) /* Direction */ -#define D_SDP_FROM_SER (0<<12) /* Direction */ -#define D_SDP_MSB (1<<11) /* Bit order within Byte */ -#define D_SDP_LSB (0<<11) /* Bit order within Byte */ -#define D_SDP_P (1<<10) /* Pointer Valid */ -#define D_SDP_A (1<<8) /* Abort */ -#define D_SDP_C (1<<7) /* Clear */ - -/* Define Time Slot */ -#define D_DTS_VI (1<<17) /* Valid Input Time-Slot Descriptor */ -#define D_DTS_VO (1<<16) /* Valid Output Time-Slot Descriptor */ -#define D_DTS_INS (1<<15) /* Insert Time Slot */ -#define D_DTS_DEL (0<<15) /* Delete Time Slot */ -#define D_DTS_PRVIN(v) ((v)<<10) /* Previous In Pipe */ -#define D_DTS_PRVOUT(v) ((v)<<5) /* Previous Out Pipe */ - -/* Time Slot defines */ -#define D_TS_LEN(v) ((v)<<24) /* Number of bits in this time slot */ -#define D_TS_CYCLE(v) ((v)<<14) /* Bit Count at start of TS */ -#define D_TS_DI (1<<13) /* Data Invert */ -#define D_TS_1CHANNEL (0<<10) /* Single Channel / Normal mode */ -#define D_TS_MONITOR (2<<10) /* Monitor pipe */ -#define D_TS_NONCONTIG (3<<10) /* Non contiguous mode */ -#define D_TS_ANCHOR (7<<10) /* Starting short pipes */ -#define D_TS_MON(v) ((v)<<5) /* Monitor Pipe */ -#define D_TS_NEXT(v) ((v)<<0) /* Pipe Nr: 0-15 long, 16-21 short */ - -/* Concentration Highway Interface Modes */ -#define D_CHI_CHICM(v) ((v)<<16) /* Clock mode */ -#define D_CHI_IR (1<<15) /* Immediate Interrupt Report */ -#define D_CHI_EN (1<<14) /* CHIL Interrupt enabled */ -#define D_CHI_OD (1<<13) /* Open Drain Enable */ -#define D_CHI_FE (1<<12) /* Sample CHIFS on Rising Frame Edge */ -#define D_CHI_FD (1<<11) /* Frame Drive */ -#define D_CHI_BPF(v) ((v)<<0) /* Bits per Frame */ - -/* NT: These are here for completeness */ -#define D_NT_FBIT (1<<17) /* Frame Bit */ -#define D_NT_NBF (1<<16) /* Number of bad frames to loose framing */ -#define D_NT_IRM_IMM (1<<15) /* Interrupt Report & Mask: Immediate */ -#define D_NT_IRM_EN (1<<14) /* Interrupt Report & Mask: Enable */ -#define D_NT_ISNT (1<<13) /* Configfure interface as NT */ -#define D_NT_FT (1<<12) /* Fixed Timing */ -#define D_NT_EZ (1<<11) /* Echo Channel is Zeros */ -#define D_NT_IFA (1<<10) /* Inhibit Final Activation */ -#define D_NT_ACT (1<<9) /* Activate Interface */ -#define D_NT_MFE (1<<8) /* Multiframe Enable */ -#define D_NT_RLB(v) ((v)<<5) /* Remote Loopback */ -#define D_NT_LLB(v) ((v)<<2) /* Local Loopback */ -#define D_NT_FACT (1<<1) /* Force Activation */ -#define D_NT_ABV (1<<0) /* Activate Bipolar Violation */ - -/* Codec Setup */ -#define D_CDEC_CK(v) ((v)<<24) /* Clock Select */ -#define D_CDEC_FED(v) ((v)<<12) /* FSCOD Falling Edge Delay */ -#define D_CDEC_RED(v) ((v)<<0) /* FSCOD Rising Edge Delay */ - -/* Test */ -#define D_TEST_RAM(v) ((v)<<16) /* RAM Pointer */ -#define D_TEST_SIZE(v) ((v)<<11) /* */ -#define D_TEST_ROMONOFF 0x5 /* Toggle ROM opcode monitor on/off */ -#define D_TEST_PROC 0x6 /* MicroProcessor test */ -#define D_TEST_SER 0x7 /* Serial-Controller test */ -#define D_TEST_RAMREAD 0x8 /* Copy from Ram to system memory */ -#define D_TEST_RAMWRITE 0x9 /* Copy into Ram from system memory */ -#define D_TEST_RAMBIST 0xa /* RAM Built-In Self Test */ -#define D_TEST_MCBIST 0xb /* Microcontroller Built-In Self Test */ -#define D_TEST_DUMP 0xe /* ROM Dump */ - -/* CHI Data Mode */ -#define D_CDM_THI (1<<8) /* Transmit Data on CHIDR Pin */ -#define D_CDM_RHI (1<<7) /* Receive Data on CHIDX Pin */ -#define D_CDM_RCE (1<<6) /* Receive on Rising Edge of CHICK */ -#define D_CDM_XCE (1<<2) /* Transmit Data on Rising Edge of CHICK */ -#define D_CDM_XEN (1<<1) /* Transmit Highway Enable */ -#define D_CDM_REN (1<<0) /* Receive Highway Enable */ - -/* The Interrupts */ -#define D_INTR_BRDY 1 /* Buffer Ready for processing */ -#define D_INTR_MINT 2 /* Marked Interrupt in RD/TD */ -#define D_INTR_IBEG 3 /* Flag to idle transition detected (HDLC) */ -#define D_INTR_IEND 4 /* Idle to flag transition detected (HDLC) */ -#define D_INTR_EOL 5 /* End of List */ -#define D_INTR_CMDI 6 /* Command has bean read */ -#define D_INTR_XCMP 8 /* Transmission of frame complete */ -#define D_INTR_SBRI 9 /* BRI status change info */ -#define D_INTR_FXDT 10 /* Fixed data change */ -#define D_INTR_CHIL 11 /* CHI lost frame sync (channel 36 only) */ -#define D_INTR_COLL 11 /* Unrecoverable D-Channel collision */ -#define D_INTR_DBYT 12 /* Dropped by frame slip */ -#define D_INTR_RBYT 13 /* Repeated by frame slip */ -#define D_INTR_LINT 14 /* Lost Interrupt */ -#define D_INTR_UNDR 15 /* DMA underrun */ - -#define D_INTR_TE 32 -#define D_INTR_NT 34 -#define D_INTR_CHI 36 -#define D_INTR_CMD 38 - -#define D_INTR_GETCHAN(v) (((v)>>24) & 0x3f) -#define D_INTR_GETCODE(v) (((v)>>20) & 0xf) -#define D_INTR_GETCMD(v) (((v)>>16) & 0xf) -#define D_INTR_GETVAL(v) ((v) & 0xffff) -#define D_INTR_GETRVAL(v) ((v) & 0xfffff) - -#define D_P_0 0 /* TE receive anchor */ -#define D_P_1 1 /* TE transmit anchor */ -#define D_P_2 2 /* NT transmit anchor */ -#define D_P_3 3 /* NT receive anchor */ -#define D_P_4 4 /* CHI send data */ -#define D_P_5 5 /* CHI receive data */ -#define D_P_6 6 /* */ -#define D_P_7 7 /* */ -#define D_P_8 8 /* */ -#define D_P_9 9 /* */ -#define D_P_10 10 /* */ -#define D_P_11 11 /* */ -#define D_P_12 12 /* */ -#define D_P_13 13 /* */ -#define D_P_14 14 /* */ -#define D_P_15 15 /* */ -#define D_P_16 16 /* CHI anchor pipe */ -#define D_P_17 17 /* CHI send */ -#define D_P_18 18 /* CHI receive */ -#define D_P_19 19 /* CHI receive */ -#define D_P_20 20 /* CHI receive */ -#define D_P_21 21 /* */ -#define D_P_22 22 /* */ -#define D_P_23 23 /* */ -#define D_P_24 24 /* */ -#define D_P_25 25 /* */ -#define D_P_26 26 /* */ -#define D_P_27 27 /* */ -#define D_P_28 28 /* */ -#define D_P_29 29 /* */ -#define D_P_30 30 /* */ -#define D_P_31 31 /* */ - -/* Transmit descriptor defines */ -#define DBRI_TD_F (1<<31) /* End of Frame */ -#define DBRI_TD_D (1<<30) /* Do not append CRC */ -#define DBRI_TD_CNT(v) ((v)<<16) /* Number of valid bytes in the buffer */ -#define DBRI_TD_B (1<<15) /* Final interrupt */ -#define DBRI_TD_M (1<<14) /* Marker interrupt */ -#define DBRI_TD_I (1<<13) /* Transmit Idle Characters */ -#define DBRI_TD_FCNT(v) (v) /* Flag Count */ -#define DBRI_TD_UNR (1<<3) /* Underrun: transmitter is out of data */ -#define DBRI_TD_ABT (1<<2) /* Abort: frame aborted */ -#define DBRI_TD_TBC (1<<0) /* Transmit buffer Complete */ -#define DBRI_TD_STATUS(v) ((v)&0xff) /* Transmit status */ - /* Maximum buffer size per TD: almost 8Kb */ -#define DBRI_TD_MAXCNT ((1 << 13) - 1) - -/* Receive descriptor defines */ -#define DBRI_RD_F (1<<31) /* End of Frame */ -#define DBRI_RD_C (1<<30) /* Completed buffer */ -#define DBRI_RD_B (1<<15) /* Final interrupt */ -#define DBRI_RD_M (1<<14) /* Marker interrupt */ -#define DBRI_RD_BCNT(v) (v) /* Buffer size */ -#define DBRI_RD_CRC (1<<7) /* 0: CRC is correct */ -#define DBRI_RD_BBC (1<<6) /* 1: Bad Byte received */ -#define DBRI_RD_ABT (1<<5) /* Abort: frame aborted */ -#define DBRI_RD_OVRN (1<<3) /* Overrun: data lost */ -#define DBRI_RD_STATUS(v) ((v)&0xff) /* Receive status */ -#define DBRI_RD_CNT(v) (((v)>>16)&0x1fff) /* Valid bytes in the buffer */ - -/* stream_info[] access */ -/* Translate the ALSA direction into the array index */ -#define DBRI_STREAMNO(substream) \ - (substream->stream == \ - SNDRV_PCM_STREAM_PLAYBACK? DBRI_PLAY: DBRI_REC) - -/* Return a pointer to dbri_streaminfo */ -#define DBRI_STREAM(dbri, substream) &dbri->stream_info[DBRI_STREAMNO(substream)] - -static snd_dbri_t *dbri_list = NULL; /* All DBRI devices */ - -/* - * Short data pipes transmit LSB first. The CS4215 receives MSB first. Grrr. - * So we have to reverse the bits. Note: not all bit lengths are supported - */ -static __u32 reverse_bytes(__u32 b, int len) -{ - switch (len) { - case 32: - b = ((b & 0xffff0000) >> 16) | ((b & 0x0000ffff) << 16); - case 16: - b = ((b & 0xff00ff00) >> 8) | ((b & 0x00ff00ff) << 8); - case 8: - b = ((b & 0xf0f0f0f0) >> 4) | ((b & 0x0f0f0f0f) << 4); - case 4: - b = ((b & 0xcccccccc) >> 2) | ((b & 0x33333333) << 2); - case 2: - b = ((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1); - case 1: - case 0: - break; - default: - printk(KERN_ERR "DBRI reverse_bytes: unsupported length\n"); - }; - - return b; -} - -/* -**************************************************************************** -************** DBRI initialization and command synchronization ************* -**************************************************************************** - -Commands are sent to the DBRI by building a list of them in memory, -then writing the address of the first list item to DBRI register 8. -The list is terminated with a WAIT command, which can generate a -CPU interrupt if required. - -Since the DBRI can run in parallel with the CPU, several means of -synchronization present themselves. The original scheme (Rudolf's) -was to set a flag when we "cmdlock"ed the DBRI, clear the flag when -an interrupt signaled completion, and wait on a wait_queue if a routine -attempted to cmdlock while the flag was set. The problems arose when -we tried to cmdlock from inside an interrupt handler, which might -cause scheduling in an interrupt (if we waited), etc, etc - -A more sophisticated scheme might involve a circular command buffer -or an array of command buffers. A routine could fill one with -commands and link it onto a list. When a interrupt signaled -completion of the current command buffer, look on the list for -the next one. - -I've decided to implement something much simpler - after each command, -the CPU waits for the DBRI to finish the command by polling the P bit -in DBRI register 0. I've tried to implement this in such a way -that might make implementing a more sophisticated scheme easier. - -Every time a routine wants to write commands to the DBRI, it must -first call dbri_cmdlock() and get an initial pointer into dbri->dma->cmd -in return. After the commands have been writen, dbri_cmdsend() is -called with the final pointer value. - -*/ - -enum dbri_lock_t { NoGetLock, GetLock }; - -static volatile s32 *dbri_cmdlock(snd_dbri_t * dbri, enum dbri_lock_t get) -{ -#ifndef SMP - if ((get == GetLock) && spin_is_locked(&dbri->lock)) { - printk(KERN_ERR "DBRI: cmdlock called while in spinlock."); - } -#endif - - /*if (get == GetLock) spin_lock(&dbri->lock); */ - return &dbri->dma->cmd[0]; -} - -static void dbri_process_interrupt_buffer(snd_dbri_t *); - -static void dbri_cmdsend(snd_dbri_t * dbri, volatile s32 * cmd) -{ - int MAXLOOPS = 1000000; - int maxloops = MAXLOOPS; - volatile s32 *ptr; - - for (ptr = &dbri->dma->cmd[0]; ptr < cmd; ptr++) { - dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); - } - - if ((cmd - &dbri->dma->cmd[0]) >= DBRI_NO_CMDS - 1) { - printk("DBRI: Command buffer overflow! (bug in driver)\n"); - /* Ignore the last part. */ - cmd = &dbri->dma->cmd[DBRI_NO_CMDS - 3]; - } - - *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); - *(cmd++) = DBRI_CMD(D_WAIT, 1, 0); - dbri->wait_seen = 0; - sbus_writel(dbri->dma_dvma, dbri->regs + REG8); - while ((--maxloops) > 0 && (sbus_readl(dbri->regs + REG0) & D_P)) - barrier(); - if (maxloops == 0) { - printk(KERN_ERR "DBRI: Chip never completed command buffer\n"); - dprintk(D_CMD, "DBRI: Chip never completed command buffer\n"); - } else { - while ((--maxloops) > 0 && (!dbri->wait_seen)) - dbri_process_interrupt_buffer(dbri); - if (maxloops == 0) { - printk(KERN_ERR "DBRI: Chip never acked WAIT\n"); - dprintk(D_CMD, "DBRI: Chip never acked WAIT\n"); - } else { - dprintk(D_CMD, "Chip completed command " - "buffer (%d)\n", MAXLOOPS - maxloops); - } - } - - /*spin_unlock(&dbri->lock); */ -} - -/* Lock must be held when calling this */ -static void dbri_reset(snd_dbri_t * dbri) -{ - int i; - - dprintk(D_GEN, "reset 0:%x 2:%x 8:%x 9:%x\n", - sbus_readl(dbri->regs + REG0), - sbus_readl(dbri->regs + REG2), - sbus_readl(dbri->regs + REG8), sbus_readl(dbri->regs + REG9)); - - sbus_writel(D_R, dbri->regs + REG0); /* Soft Reset */ - for (i = 0; (sbus_readl(dbri->regs + REG0) & D_R) && i < 64; i++) - udelay(10); -} - -/* Lock must not be held before calling this */ -static void dbri_initialize(snd_dbri_t * dbri) -{ - volatile s32 *cmd; - u32 dma_addr, tmp; - unsigned long flags; - int n; - - spin_lock_irqsave(&dbri->lock, flags); - - dbri_reset(dbri); - - cmd = dbri_cmdlock(dbri, NoGetLock); - dprintk(D_GEN, "init: cmd: %p, int: %p\n", - &dbri->dma->cmd[0], &dbri->dma->intr[0]); - - /* - * Initialize the interrupt ringbuffer. - */ - for (n = 0; n < DBRI_NO_INTS - 1; n++) { - dma_addr = dbri->dma_dvma; - dma_addr += dbri_dma_off(intr, ((n + 1) & DBRI_INT_BLK)); - dbri->dma->intr[n * DBRI_INT_BLK] = dma_addr; - } - dma_addr = dbri->dma_dvma + dbri_dma_off(intr, 0); - dbri->dma->intr[n * DBRI_INT_BLK] = dma_addr; - dbri->dbri_irqp = 1; - - /* Initialize pipes */ - for (n = 0; n < DBRI_NO_PIPES; n++) - dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1; - - /* We should query the openprom to see what burst sizes this - * SBus supports. For now, just disable all SBus bursts */ - tmp = sbus_readl(dbri->regs + REG0); - tmp &= ~(D_G | D_S | D_E); - sbus_writel(tmp, dbri->regs + REG0); - - /* - * Set up the interrupt queue - */ - dma_addr = dbri->dma_dvma + dbri_dma_off(intr, 0); - *(cmd++) = DBRI_CMD(D_IIQ, 0, 0); - *(cmd++) = dma_addr; - - dbri_cmdsend(dbri, cmd); - spin_unlock_irqrestore(&dbri->lock, flags); -} - -/* -**************************************************************************** -************************** DBRI data pipe management *********************** -**************************************************************************** - -While DBRI control functions use the command and interrupt buffers, the -main data path takes the form of data pipes, which can be short (command -and interrupt driven), or long (attached to DMA buffers). These functions -provide a rudimentary means of setting up and managing the DBRI's pipes, -but the calling functions have to make sure they respect the pipes' linked -list ordering, among other things. The transmit and receive functions -here interface closely with the transmit and receive interrupt code. - -*/ -static int pipe_active(snd_dbri_t * dbri, int pipe) -{ - return ((pipe >= 0) && (dbri->pipes[pipe].desc != -1)); -} - -/* reset_pipe(dbri, pipe) - * - * Called on an in-use pipe to clear anything being transmitted or received - * Lock must be held before calling this. - */ -static void reset_pipe(snd_dbri_t * dbri, int pipe) -{ - int sdp; - int desc; - volatile int *cmd; - - if (pipe < 0 || pipe > 31) { - printk("DBRI: reset_pipe called with illegal pipe number\n"); - return; - } - - sdp = dbri->pipes[pipe].sdp; - if (sdp == 0) { - printk("DBRI: reset_pipe called on uninitialized pipe\n"); - return; - } - - cmd = dbri_cmdlock(dbri, NoGetLock); - *(cmd++) = DBRI_CMD(D_SDP, 0, sdp | D_SDP_C | D_SDP_P); - *(cmd++) = 0; - dbri_cmdsend(dbri, cmd); - - desc = dbri->pipes[pipe].first_desc; - while (desc != -1) { - dbri->descs[desc].inuse = 0; - desc = dbri->descs[desc].next; - } - - dbri->pipes[pipe].desc = -1; - dbri->pipes[pipe].first_desc = -1; -} - -/* FIXME: direction as an argument? */ -static void setup_pipe(snd_dbri_t * dbri, int pipe, int sdp) -{ - if (pipe < 0 || pipe > 31) { - printk("DBRI: setup_pipe called with illegal pipe number\n"); - return; - } - - if ((sdp & 0xf800) != sdp) { - printk("DBRI: setup_pipe called with strange SDP value\n"); - /* sdp &= 0xf800; */ - } - - /* If this is a fixed receive pipe, arrange for an interrupt - * every time its data changes - */ - if (D_SDP_MODE(sdp) == D_SDP_FIXED && !(sdp & D_SDP_TO_SER)) - sdp |= D_SDP_CHANGE; - - sdp |= D_PIPE(pipe); - dbri->pipes[pipe].sdp = sdp; - dbri->pipes[pipe].desc = -1; - dbri->pipes[pipe].first_desc = -1; - if (sdp & D_SDP_TO_SER) - dbri->pipes[pipe].direction = PIPEoutput; - else - dbri->pipes[pipe].direction = PIPEinput; - - reset_pipe(dbri, pipe); -} - -/* FIXME: direction not needed */ -static void link_time_slot(snd_dbri_t * dbri, int pipe, - enum in_or_out direction, int basepipe, - int length, int cycle) -{ - volatile s32 *cmd; - int val; - int prevpipe; - int nextpipe; - - if (pipe < 0 || pipe > 31 || basepipe < 0 || basepipe > 31) { - printk - ("DBRI: link_time_slot called with illegal pipe number\n"); - return; - } - - if (dbri->pipes[pipe].sdp == 0 || dbri->pipes[basepipe].sdp == 0) { - printk("DBRI: link_time_slot called on uninitialized pipe\n"); - return; - } - - /* Deal with CHI special case: - * "If transmission on edges 0 or 1 is desired, then cycle n - * (where n = # of bit times per frame...) must be used." - * - DBRI data sheet, page 11 - */ - if (basepipe == 16 && direction == PIPEoutput && cycle == 0) - cycle = dbri->chi_bpf; - - if (basepipe == pipe) { - prevpipe = pipe; - nextpipe = pipe; - } else { - /* We're not initializing a new linked list (basepipe != pipe), - * so run through the linked list and find where this pipe - * should be sloted in, based on its cycle. CHI confuses - * things a bit, since it has a single anchor for both its - * transmit and receive lists. - */ - if (basepipe == 16) { - if (direction == PIPEinput) { - prevpipe = dbri->chi_in_pipe; - } else { - prevpipe = dbri->chi_out_pipe; - } - } else { - prevpipe = basepipe; - } - - nextpipe = dbri->pipes[prevpipe].nextpipe; - - while (dbri->pipes[nextpipe].cycle < cycle - && dbri->pipes[nextpipe].nextpipe != basepipe) { - prevpipe = nextpipe; - nextpipe = dbri->pipes[nextpipe].nextpipe; - } - } - - if (prevpipe == 16) { - if (direction == PIPEinput) { - dbri->chi_in_pipe = pipe; - } else { - dbri->chi_out_pipe = pipe; - } - } else { - dbri->pipes[prevpipe].nextpipe = pipe; - } - - dbri->pipes[pipe].nextpipe = nextpipe; - dbri->pipes[pipe].cycle = cycle; - dbri->pipes[pipe].length = length; - - cmd = dbri_cmdlock(dbri, NoGetLock); - - if (direction == PIPEinput) { - val = D_DTS_VI | D_DTS_INS | D_DTS_PRVIN(prevpipe) | pipe; - *(cmd++) = DBRI_CMD(D_DTS, 0, val); - *(cmd++) = - D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe); - *(cmd++) = 0; - } else { - val = D_DTS_VO | D_DTS_INS | D_DTS_PRVOUT(prevpipe) | pipe; - *(cmd++) = DBRI_CMD(D_DTS, 0, val); - *(cmd++) = 0; - *(cmd++) = - D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe); - } - - dbri_cmdsend(dbri, cmd); -} - -static void unlink_time_slot(snd_dbri_t * dbri, int pipe, - enum in_or_out direction, int prevpipe, - int nextpipe) -{ - volatile s32 *cmd; - int val; - - if (pipe < 0 || pipe > 31 || prevpipe < 0 || prevpipe > 31) { - printk - ("DBRI: unlink_time_slot called with illegal pipe number\n"); - return; - } - - cmd = dbri_cmdlock(dbri, NoGetLock); - - if (direction == PIPEinput) { - val = D_DTS_VI | D_DTS_DEL | D_DTS_PRVIN(prevpipe) | pipe; - *(cmd++) = DBRI_CMD(D_DTS, 0, val); - *(cmd++) = D_TS_NEXT(nextpipe); - *(cmd++) = 0; - } else { - val = D_DTS_VO | D_DTS_DEL | D_DTS_PRVOUT(prevpipe) | pipe; - *(cmd++) = DBRI_CMD(D_DTS, 0, val); - *(cmd++) = 0; - *(cmd++) = D_TS_NEXT(nextpipe); - } - - dbri_cmdsend(dbri, cmd); -} - -/* xmit_fixed() / recv_fixed() - * - * Transmit/receive data on a "fixed" pipe - i.e, one whose contents are not - * expected to change much, and which we don't need to buffer. - * The DBRI only interrupts us when the data changes (receive pipes), - * or only changes the data when this function is called (transmit pipes). - * Only short pipes (numbers 16-31) can be used in fixed data mode. - * - * These function operate on a 32-bit field, no matter how large - * the actual time slot is. The interrupt handler takes care of bit - * ordering and alignment. An 8-bit time slot will always end up - * in the low-order 8 bits, filled either MSB-first or LSB-first, - * depending on the settings passed to setup_pipe() - */ -static void xmit_fixed(snd_dbri_t * dbri, int pipe, unsigned int data) -{ - volatile s32 *cmd; - - if (pipe < 16 || pipe > 31) { - printk("DBRI: xmit_fixed: Illegal pipe number\n"); - return; - } - - if (D_SDP_MODE(dbri->pipes[pipe].sdp) == 0) { - printk("DBRI: xmit_fixed: Uninitialized pipe %d\n", pipe); - return; - } - - if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) { - printk("DBRI: xmit_fixed: Non-fixed pipe %d\n", pipe); - return; - } - - if (!(dbri->pipes[pipe].sdp & D_SDP_TO_SER)) { - printk("DBRI: xmit_fixed: Called on receive pipe %d\n", pipe); - return; - } - - /* DBRI short pipes always transmit LSB first */ - - if (dbri->pipes[pipe].sdp & D_SDP_MSB) - data = reverse_bytes(data, dbri->pipes[pipe].length); - - cmd = dbri_cmdlock(dbri, GetLock); - - *(cmd++) = DBRI_CMD(D_SSP, 0, pipe); - *(cmd++) = data; - - dbri_cmdsend(dbri, cmd); -} - -static void recv_fixed(snd_dbri_t * dbri, int pipe, volatile __u32 * ptr) -{ - if (pipe < 16 || pipe > 31) { - printk("DBRI: recv_fixed called with illegal pipe number\n"); - return; - } - - if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) { - printk("DBRI: recv_fixed called on non-fixed pipe %d\n", pipe); - return; - } - - if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) { - printk("DBRI: recv_fixed called on transmit pipe %d\n", pipe); - return; - } - - dbri->pipes[pipe].recv_fixed_ptr = ptr; -} - -/* setup_descs() - * - * Setup transmit/receive data on a "long" pipe - i.e, one associated - * with a DMA buffer. - * - * Only pipe numbers 0-15 can be used in this mode. - * - * This function takes a stream number pointing to a data buffer, - * and work by building chains of descriptors which identify the - * data buffers. Buffers too large for a single descriptor will - * be spread across multiple descriptors. - */ -static int setup_descs(snd_dbri_t * dbri, int streamno, unsigned int period) -{ - dbri_streaminfo_t *info = &dbri->stream_info[streamno]; - __u32 dvma_buffer; - int desc = 0; - int len; - int first_desc = -1; - int last_desc = -1; - - if (info->pipe < 0 || info->pipe > 15) { - printk("DBRI: setup_descs: Illegal pipe number\n"); - return -2; - } - - if (dbri->pipes[info->pipe].sdp == 0) { - printk("DBRI: setup_descs: Uninitialized pipe %d\n", - info->pipe); - return -2; - } - - dvma_buffer = info->dvma_buffer; - len = info->size; - - if (streamno == DBRI_PLAY) { - if (!(dbri->pipes[info->pipe].sdp & D_SDP_TO_SER)) { - printk("DBRI: setup_descs: Called on receive pipe %d\n", - info->pipe); - return -2; - } - } else { - if (dbri->pipes[info->pipe].sdp & D_SDP_TO_SER) { - printk - ("DBRI: setup_descs: Called on transmit pipe %d\n", - info->pipe); - return -2; - } - /* Should be able to queue multiple buffers to receive on a pipe */ - if (pipe_active(dbri, info->pipe)) { - printk("DBRI: recv_on_pipe: Called on active pipe %d\n", - info->pipe); - return -2; - } - - /* Make sure buffer size is multiple of four */ - len &= ~3; - } - - while (len > 0) { - int mylen; - - for (; desc < DBRI_NO_DESCS; desc++) { - if (!dbri->descs[desc].inuse) - break; - } - if (desc == DBRI_NO_DESCS) { - printk("DBRI: setup_descs: No descriptors\n"); - return -1; - } - - if (len > DBRI_TD_MAXCNT) { - mylen = DBRI_TD_MAXCNT; /* 8KB - 1 */ - } else { - mylen = len; - } - if (mylen > period) { - mylen = period; - } - - dbri->descs[desc].inuse = 1; - dbri->descs[desc].next = -1; - dbri->dma->desc[desc].ba = dvma_buffer; - dbri->dma->desc[desc].nda = 0; - - if (streamno == DBRI_PLAY) { - dbri->descs[desc].len = mylen; - dbri->dma->desc[desc].word1 = DBRI_TD_CNT(mylen); - dbri->dma->desc[desc].word4 = 0; - if (first_desc != -1) - dbri->dma->desc[desc].word1 |= DBRI_TD_M; - } else { - dbri->descs[desc].len = 0; - dbri->dma->desc[desc].word1 = 0; - dbri->dma->desc[desc].word4 = - DBRI_RD_B | DBRI_RD_BCNT(mylen); - } - - if (first_desc == -1) { - first_desc = desc; - } else { - dbri->descs[last_desc].next = desc; - dbri->dma->desc[last_desc].nda = - dbri->dma_dvma + dbri_dma_off(desc, desc); - } - - last_desc = desc; - dvma_buffer += mylen; - len -= mylen; - } - - if (first_desc == -1 || last_desc == -1) { - printk("DBRI: setup_descs: Not enough descriptors available\n"); - return -1; - } - - dbri->dma->desc[last_desc].word1 &= ~DBRI_TD_M; - if (streamno == DBRI_PLAY) { - dbri->dma->desc[last_desc].word1 |= - DBRI_TD_I | DBRI_TD_F | DBRI_TD_B; - } - dbri->pipes[info->pipe].first_desc = first_desc; - dbri->pipes[info->pipe].desc = first_desc; - - for (desc = first_desc; desc != -1; desc = dbri->descs[desc].next) { - dprintk(D_DESC, "DESC %d: %08x %08x %08x %08x\n", - desc, - dbri->dma->desc[desc].word1, - dbri->dma->desc[desc].ba, - dbri->dma->desc[desc].nda, dbri->dma->desc[desc].word4); - } - return 0; -} - -/* -**************************************************************************** -************************** DBRI - CHI interface **************************** -**************************************************************************** - -The CHI is a four-wire (clock, frame sync, data in, data out) time-division -multiplexed serial interface which the DBRI can operate in either master -(give clock/frame sync) or slave (take clock/frame sync) mode. - -*/ - -enum master_or_slave { CHImaster, CHIslave }; - -static void reset_chi(snd_dbri_t * dbri, enum master_or_slave master_or_slave, - int bits_per_frame) -{ - volatile s32 *cmd; - int val; - static int chi_initialized = 0; /* FIXME: mutex? */ - - if (!chi_initialized) { - - cmd = dbri_cmdlock(dbri, GetLock); - - /* Set CHI Anchor: Pipe 16 */ - - val = D_DTS_VI | D_DTS_INS | D_DTS_PRVIN(16) | D_PIPE(16); - *(cmd++) = DBRI_CMD(D_DTS, 0, val); - *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16); - *(cmd++) = 0; - - val = D_DTS_VO | D_DTS_INS | D_DTS_PRVOUT(16) | D_PIPE(16); - *(cmd++) = DBRI_CMD(D_DTS, 0, val); - *(cmd++) = 0; - *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16); - - dbri->pipes[16].sdp = 1; - dbri->pipes[16].nextpipe = 16; - dbri->chi_in_pipe = 16; - dbri->chi_out_pipe = 16; - -#if 0 - chi_initialized++; -#endif - } else { - int pipe; - - for (pipe = dbri->chi_in_pipe; - pipe != 16; pipe = dbri->pipes[pipe].nextpipe) { - unlink_time_slot(dbri, pipe, PIPEinput, - 16, dbri->pipes[pipe].nextpipe); - } - for (pipe = dbri->chi_out_pipe; - pipe != 16; pipe = dbri->pipes[pipe].nextpipe) { - unlink_time_slot(dbri, pipe, PIPEoutput, - 16, dbri->pipes[pipe].nextpipe); - } - - dbri->chi_in_pipe = 16; - dbri->chi_out_pipe = 16; - - cmd = dbri_cmdlock(dbri, GetLock); - } - - if (master_or_slave == CHIslave) { - /* Setup DBRI for CHI Slave - receive clock, frame sync (FS) - * - * CHICM = 0 (slave mode, 8 kHz frame rate) - * IR = give immediate CHI status interrupt - * EN = give CHI status interrupt upon change - */ - *(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(0)); - } else { - /* Setup DBRI for CHI Master - generate clock, FS - * - * BPF = bits per 8 kHz frame - * 12.288 MHz / CHICM_divisor = clock rate - * FD = 1 - drive CHIFS on rising edge of CHICK - */ - int clockrate = bits_per_frame * 8; - int divisor = 12288 / clockrate; - - if (divisor > 255 || divisor * clockrate != 12288) - printk("DBRI: illegal bits_per_frame in setup_chi\n"); - - *(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(divisor) | D_CHI_FD - | D_CHI_BPF(bits_per_frame)); - } - - dbri->chi_bpf = bits_per_frame; - - /* CHI Data Mode - * - * RCE = 0 - receive on falling edge of CHICK - * XCE = 1 - transmit on rising edge of CHICK - * XEN = 1 - enable transmitter - * REN = 1 - enable receiver - */ - - *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); - *(cmd++) = DBRI_CMD(D_CDM, 0, D_CDM_XCE | D_CDM_XEN | D_CDM_REN); - - dbri_cmdsend(dbri, cmd); -} - -/* -**************************************************************************** -*********************** CS4215 audio codec management ********************** -**************************************************************************** - -In the standard SPARC audio configuration, the CS4215 codec is attached -to the DBRI via the CHI interface and few of the DBRI's PIO pins. - -*/ -static void cs4215_setup_pipes(snd_dbri_t * dbri) -{ - /* - * Data mode: - * Pipe 4: Send timeslots 1-4 (audio data) - * Pipe 20: Send timeslots 5-8 (part of ctrl data) - * Pipe 6: Receive timeslots 1-4 (audio data) - * Pipe 21: Receive timeslots 6-7. We can only receive 20 bits via - * interrupt, and the rest of the data (slot 5 and 8) is - * not relevant for us (only for doublechecking). - * - * Control mode: - * Pipe 17: Send timeslots 1-4 (slots 5-8 are readonly) - * Pipe 18: Receive timeslot 1 (clb). - * Pipe 19: Receive timeslot 7 (version). - */ - - setup_pipe(dbri, 4, D_SDP_MEM | D_SDP_TO_SER | D_SDP_MSB); - setup_pipe(dbri, 20, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB); - setup_pipe(dbri, 6, D_SDP_MEM | D_SDP_FROM_SER | D_SDP_MSB); - setup_pipe(dbri, 21, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB); - - setup_pipe(dbri, 17, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB); - setup_pipe(dbri, 18, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB); - setup_pipe(dbri, 19, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB); -} - -static int cs4215_init_data(struct cs4215 *mm) -{ - /* - * No action, memory resetting only. - * - * Data Time Slot 5-8 - * Speaker,Line and Headphone enable. Gain set to the half. - * Input is mike. - */ - mm->data[0] = CS4215_LO(0x20) | CS4215_HE | CS4215_LE; - mm->data[1] = CS4215_RO(0x20) | CS4215_SE; - mm->data[2] = CS4215_LG(0x8) | CS4215_IS | CS4215_PIO0 | CS4215_PIO1; - mm->data[3] = CS4215_RG(0x8) | CS4215_MA(0xf); - - /* - * Control Time Slot 1-4 - * 0: Default I/O voltage scale - * 1: 8 bit ulaw, 8kHz, mono, high pass filter disabled - * 2: Serial enable, CHI master, 128 bits per frame, clock 1 - * 3: Tests disabled - */ - mm->ctrl[0] = CS4215_RSRVD_1 | CS4215_MLB; - mm->ctrl[1] = CS4215_DFR_ULAW | CS4215_FREQ[0].csval; - mm->ctrl[2] = CS4215_XCLK | CS4215_BSEL_128 | CS4215_FREQ[0].xtal; - mm->ctrl[3] = 0; - - mm->status = 0; - mm->version = 0xff; - mm->precision = 8; /* For ULAW */ - mm->channels = 2; - - return 0; -} - -static void cs4215_setdata(snd_dbri_t * dbri, int muted) -{ - if (muted) { - dbri->mm.data[0] |= 63; - dbri->mm.data[1] |= 63; - dbri->mm.data[2] &= ~15; - dbri->mm.data[3] &= ~15; - } else { - /* Start by setting the playback attenuation. */ - dbri_streaminfo_t *info = &dbri->stream_info[DBRI_PLAY]; - int left_gain = info->left_gain % 64; - int right_gain = info->right_gain % 64; - - if (info->balance < DBRI_MID_BALANCE) { - right_gain *= info->balance; - right_gain /= DBRI_MID_BALANCE; - } else { - left_gain *= DBRI_RIGHT_BALANCE - info->balance; - left_gain /= DBRI_MID_BALANCE; - } - - dbri->mm.data[0] &= ~0x3f; /* Reset the volume bits */ - dbri->mm.data[1] &= ~0x3f; - dbri->mm.data[0] |= (DBRI_MAX_VOLUME - left_gain); - dbri->mm.data[1] |= (DBRI_MAX_VOLUME - right_gain); - - /* Now set the recording gain. */ - info = &dbri->stream_info[DBRI_REC]; - left_gain = info->left_gain % 16; - right_gain = info->right_gain % 16; - dbri->mm.data[2] |= CS4215_LG(left_gain); - dbri->mm.data[3] |= CS4215_RG(right_gain); - } - - xmit_fixed(dbri, 20, *(int *)dbri->mm.data); -} - -/* - * Set the CS4215 to data mode. - */ -static void cs4215_open(snd_dbri_t * dbri) -{ - int data_width; - u32 tmp; - - dprintk(D_MM, "cs4215_open: %d channels, %d bits\n", - dbri->mm.channels, dbri->mm.precision); - - /* Temporarily mute outputs, and wait 1/8000 sec (125 us) - * to make sure this takes. This avoids clicking noises. - */ - - cs4215_setdata(dbri, 1); - udelay(125); - - /* - * Data mode: - * Pipe 4: Send timeslots 1-4 (audio data) - * Pipe 20: Send timeslots 5-8 (part of ctrl data) - * Pipe 6: Receive timeslots 1-4 (audio data) - * Pipe 21: Receive timeslots 6-7. We can only receive 20 bits via - * interrupt, and the rest of the data (slot 5 and 8) is - * not relevant for us (only for doublechecking). - * - * Just like in control mode, the time slots are all offset by eight - * bits. The CS4215, it seems, observes TSIN (the delayed signal) - * even if it's the CHI master. Don't ask me... - */ - tmp = sbus_readl(dbri->regs + REG0); - tmp &= ~(D_C); /* Disable CHI */ - sbus_writel(tmp, dbri->regs + REG0); - - /* Switch CS4215 to data mode - set PIO3 to 1 */ - sbus_writel(D_ENPIO | D_PIO1 | D_PIO3 | - (dbri->mm.onboard ? D_PIO0 : D_PIO2), dbri->regs + REG2); - - reset_chi(dbri, CHIslave, 128); - - /* Note: this next doesn't work for 8-bit stereo, because the two - * channels would be on timeslots 1 and 3, with 2 and 4 idle. - * (See CS4215 datasheet Fig 15) - * - * DBRI non-contiguous mode would be required to make this work. - */ - data_width = dbri->mm.channels * dbri->mm.precision; - - link_time_slot(dbri, 20, PIPEoutput, 16, 32, dbri->mm.offset + 32); - link_time_slot(dbri, 4, PIPEoutput, 16, data_width, dbri->mm.offset); - link_time_slot(dbri, 6, PIPEinput, 16, data_width, dbri->mm.offset); - link_time_slot(dbri, 21, PIPEinput, 16, 16, dbri->mm.offset + 40); - - /* FIXME: enable CHI after _setdata? */ - tmp = sbus_readl(dbri->regs + REG0); - tmp |= D_C; /* Enable CHI */ - sbus_writel(tmp, dbri->regs + REG0); - - cs4215_setdata(dbri, 0); -} - -/* - * Send the control information (i.e. audio format) - */ -static int cs4215_setctrl(snd_dbri_t * dbri) -{ - int i, val; - u32 tmp; - - /* FIXME - let the CPU do something useful during these delays */ - - /* Temporarily mute outputs, and wait 1/8000 sec (125 us) - * to make sure this takes. This avoids clicking noises. - */ - - cs4215_setdata(dbri, 1); - udelay(125); - - /* - * Enable Control mode: Set DBRI's PIO3 (4215's D/~C) to 0, then wait - * 12 cycles <= 12/(5512.5*64) sec = 34.01 usec - */ - val = D_ENPIO | D_PIO1 | (dbri->mm.onboard ? D_PIO0 : D_PIO2); - sbus_writel(val, dbri->regs + REG2); - dprintk(D_MM, "cs4215_setctrl: reg2=0x%x\n", val); - udelay(34); - - /* In Control mode, the CS4215 is a slave device, so the DBRI must - * operate as CHI master, supplying clocking and frame synchronization. - * - * In Data mode, however, the CS4215 must be CHI master to insure - * that its data stream is synchronous with its codec. - * - * The upshot of all this? We start by putting the DBRI into master - * mode, program the CS4215 in Control mode, then switch the CS4215 - * into Data mode and put the DBRI into slave mode. Various timing - * requirements must be observed along the way. - * - * Oh, and one more thing, on a SPARCStation 20 (and maybe - * others?), the addressing of the CS4215's time slots is - * offset by eight bits, so we add eight to all the "cycle" - * values in the Define Time Slot (DTS) commands. This is - * done in hardware by a TI 248 that delays the DBRI->4215 - * frame sync signal by eight clock cycles. Anybody know why? - */ - tmp = sbus_readl(dbri->regs + REG0); - tmp &= ~D_C; /* Disable CHI */ - sbus_writel(tmp, dbri->regs + REG0); - - reset_chi(dbri, CHImaster, 128); - - /* - * Control mode: - * Pipe 17: Send timeslots 1-4 (slots 5-8 are readonly) - * Pipe 18: Receive timeslot 1 (clb). - * Pipe 19: Receive timeslot 7 (version). - */ - - link_time_slot(dbri, 17, PIPEoutput, 16, 32, dbri->mm.offset); - link_time_slot(dbri, 18, PIPEinput, 16, 8, dbri->mm.offset); - link_time_slot(dbri, 19, PIPEinput, 16, 8, dbri->mm.offset + 48); - - /* Wait for the chip to echo back CLB (Control Latch Bit) as zero */ - dbri->mm.ctrl[0] &= ~CS4215_CLB; - xmit_fixed(dbri, 17, *(int *)dbri->mm.ctrl); - - tmp = sbus_readl(dbri->regs + REG0); - tmp |= D_C; /* Enable CHI */ - sbus_writel(tmp, dbri->regs + REG0); - - for (i = 64; ((dbri->mm.status & 0xe4) != 0x20); --i) { - udelay(125); - } - if (i == 0) { - dprintk(D_MM, "CS4215 didn't respond to CLB (0x%02x)\n", - dbri->mm.status); - return -1; - } - - /* Disable changes to our copy of the version number, as we are about - * to leave control mode. - */ - recv_fixed(dbri, 19, NULL); - - /* Terminate CS4215 control mode - data sheet says - * "Set CLB=1 and send two more frames of valid control info" - */ - dbri->mm.ctrl[0] |= CS4215_CLB; - xmit_fixed(dbri, 17, *(int *)dbri->mm.ctrl); - - /* Two frames of control info @ 8kHz frame rate = 250 us delay */ - udelay(250); - - cs4215_setdata(dbri, 0); - - return 0; -} - -/* - * Setup the codec with the sampling rate, audio format and number of - * channels. - * As part of the process we resend the settings for the data - * timeslots as well. - */ -static int cs4215_prepare(snd_dbri_t * dbri, unsigned int rate, - snd_pcm_format_t format, unsigned int channels) -{ - int freq_idx; - int ret = 0; - - /* Lookup index for this rate */ - for (freq_idx = 0; CS4215_FREQ[freq_idx].freq != 0; freq_idx++) { - if (CS4215_FREQ[freq_idx].freq == rate) - break; - } - if (CS4215_FREQ[freq_idx].freq != rate) { - printk(KERN_WARNING "DBRI: Unsupported rate %d Hz\n", rate); - return -1; - } - - switch (format) { - case SNDRV_PCM_FORMAT_MU_LAW: - dbri->mm.ctrl[1] = CS4215_DFR_ULAW; - dbri->mm.precision = 8; - break; - case SNDRV_PCM_FORMAT_A_LAW: - dbri->mm.ctrl[1] = CS4215_DFR_ALAW; - dbri->mm.precision = 8; - break; - case SNDRV_PCM_FORMAT_U8: - dbri->mm.ctrl[1] = CS4215_DFR_LINEAR8; - dbri->mm.precision = 8; - break; - case SNDRV_PCM_FORMAT_S16_BE: - dbri->mm.ctrl[1] = CS4215_DFR_LINEAR16; - dbri->mm.precision = 16; - break; - default: - printk(KERN_WARNING "DBRI: Unsupported format %d\n", format); - return -1; - } - - /* Add rate parameters */ - dbri->mm.ctrl[1] |= CS4215_FREQ[freq_idx].csval; - dbri->mm.ctrl[2] = CS4215_XCLK | - CS4215_BSEL_128 | CS4215_FREQ[freq_idx].xtal; - - dbri->mm.channels = channels; - /* Stereo bit: 8 bit stereo not working yet. */ - if ((channels > 1) && (dbri->mm.precision == 16)) - dbri->mm.ctrl[1] |= CS4215_DFR_STEREO; - - ret = cs4215_setctrl(dbri); - if (ret == 0) - cs4215_open(dbri); /* set codec to data mode */ - - return ret; -} - -/* - * - */ -static int cs4215_init(snd_dbri_t * dbri) -{ - u32 reg2 = sbus_readl(dbri->regs + REG2); - dprintk(D_MM, "cs4215_init: reg2=0x%x\n", reg2); - - /* Look for the cs4215 chips */ - if (reg2 & D_PIO2) { - dprintk(D_MM, "Onboard CS4215 detected\n"); - dbri->mm.onboard = 1; - } - if (reg2 & D_PIO0) { - dprintk(D_MM, "Speakerbox detected\n"); - dbri->mm.onboard = 0; - - if (reg2 & D_PIO2) { - printk(KERN_INFO "DBRI: Using speakerbox / " - "ignoring onboard mmcodec.\n"); - sbus_writel(D_ENPIO2, dbri->regs + REG2); - } - } - - if (!(reg2 & (D_PIO0 | D_PIO2))) { - printk(KERN_ERR "DBRI: no mmcodec found.\n"); - return -EIO; - } - - cs4215_setup_pipes(dbri); - - cs4215_init_data(&dbri->mm); - - /* Enable capture of the status & version timeslots. */ - recv_fixed(dbri, 18, &dbri->mm.status); - recv_fixed(dbri, 19, &dbri->mm.version); - - dbri->mm.offset = dbri->mm.onboard ? 0 : 8; - if (cs4215_setctrl(dbri) == -1 || dbri->mm.version == 0xff) { - dprintk(D_MM, "CS4215 failed probe at offset %d\n", - dbri->mm.offset); - return -EIO; - } - dprintk(D_MM, "Found CS4215 at offset %d\n", dbri->mm.offset); - - return 0; -} - -/* -**************************************************************************** -*************************** DBRI interrupt handler ************************* -**************************************************************************** - -The DBRI communicates with the CPU mainly via a circular interrupt -buffer. When an interrupt is signaled, the CPU walks through the -buffer and calls dbri_process_one_interrupt() for each interrupt word. -Complicated interrupts are handled by dedicated functions (which -appear first in this file). Any pending interrupts can be serviced by -calling dbri_process_interrupt_buffer(), which works even if the CPU's -interrupts are disabled. This function is used by dbri_cmdsend() -to make sure we're synced up with the chip after each command sequence, -even if we're running cli'ed. - -*/ - -/* xmit_descs() - * - * Transmit the current TD's for recording/playing, if needed. - * For playback, ALSA has filled the DMA memory with new data (we hope). - */ -static void xmit_descs(unsigned long data) -{ - snd_dbri_t *dbri = (snd_dbri_t *) data; - dbri_streaminfo_t *info; - volatile s32 *cmd; - unsigned long flags; - int first_td; - - if (dbri == NULL) - return; /* Disabled */ - - /* First check the recording stream for buffer overflow */ - info = &dbri->stream_info[DBRI_REC]; - spin_lock_irqsave(&dbri->lock, flags); - - if ((info->left >= info->size) && (info->pipe >= 0)) { - first_td = dbri->pipes[info->pipe].first_desc; - - dprintk(D_DESC, "xmit_descs rec @ TD %d\n", first_td); - - /* Stream could be closed by the time we run. */ - if (first_td < 0) { - goto play; - } - - cmd = dbri_cmdlock(dbri, NoGetLock); - *(cmd++) = DBRI_CMD(D_SDP, 0, - dbri->pipes[info->pipe].sdp - | D_SDP_P | D_SDP_EVERY | D_SDP_C); - *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td); - dbri_cmdsend(dbri, cmd); - - /* Reset our admin of the pipe & bytes read. */ - dbri->pipes[info->pipe].desc = first_td; - info->left = 0; - } - -play: - spin_unlock_irqrestore(&dbri->lock, flags); - - /* Now check the playback stream for buffer underflow */ - info = &dbri->stream_info[DBRI_PLAY]; - spin_lock_irqsave(&dbri->lock, flags); - - if ((info->left <= 0) && (info->pipe >= 0)) { - first_td = dbri->pipes[info->pipe].first_desc; - - dprintk(D_DESC, "xmit_descs play @ TD %d\n", first_td); - - /* Stream could be closed by the time we run. */ - if (first_td < 0) { - spin_unlock_irqrestore(&dbri->lock, flags); - return; - } - - cmd = dbri_cmdlock(dbri, NoGetLock); - *(cmd++) = DBRI_CMD(D_SDP, 0, - dbri->pipes[info->pipe].sdp - | D_SDP_P | D_SDP_EVERY | D_SDP_C); - *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td); - dbri_cmdsend(dbri, cmd); - - /* Reset our admin of the pipe & bytes written. */ - dbri->pipes[info->pipe].desc = first_td; - info->left = info->size; - } - spin_unlock_irqrestore(&dbri->lock, flags); -} - -DECLARE_TASKLET(xmit_descs_task, xmit_descs, 0); - -/* transmission_complete_intr() - * - * Called by main interrupt handler when DBRI signals transmission complete - * on a pipe (interrupt triggered by the B bit in a transmit descriptor). - * - * Walks through the pipe's list of transmit buffer descriptors, releasing - * each one's DMA buffer (if present), flagging the descriptor available, - * and signaling its callback routine (if present), before proceeding - * to the next one. Stops when the first descriptor is found without - * TBC (Transmit Buffer Complete) set, or we've run through them all. - */ - -static void transmission_complete_intr(snd_dbri_t * dbri, int pipe) -{ - dbri_streaminfo_t *info; - int td; - int status; - - info = &dbri->stream_info[DBRI_PLAY]; - - td = dbri->pipes[pipe].desc; - while (td >= 0) { - if (td >= DBRI_NO_DESCS) { - printk(KERN_ERR "DBRI: invalid td on pipe %d\n", pipe); - return; - } - - status = DBRI_TD_STATUS(dbri->dma->desc[td].word4); - if (!(status & DBRI_TD_TBC)) { - break; - } - - dprintk(D_INT, "TD %d, status 0x%02x\n", td, status); - - dbri->dma->desc[td].word4 = 0; /* Reset it for next time. */ - info->offset += dbri->descs[td].len; - info->left -= dbri->descs[td].len; - - /* On the last TD, transmit them all again. */ - if (dbri->descs[td].next == -1) { - if (info->left > 0) { - printk(KERN_WARNING - "%d bytes left after last transfer.\n", - info->left); - info->left = 0; - } - tasklet_schedule(&xmit_descs_task); - } - - td = dbri->descs[td].next; - dbri->pipes[pipe].desc = td; - } - - /* Notify ALSA */ - if (spin_is_locked(&dbri->lock)) { - spin_unlock(&dbri->lock); - snd_pcm_period_elapsed(info->substream); - spin_lock(&dbri->lock); - } else - snd_pcm_period_elapsed(info->substream); -} - -static void reception_complete_intr(snd_dbri_t * dbri, int pipe) -{ - dbri_streaminfo_t *info; - int rd = dbri->pipes[pipe].desc; - s32 status; - - if (rd < 0 || rd >= DBRI_NO_DESCS) { - printk(KERN_ERR "DBRI: invalid rd on pipe %d\n", pipe); - return; - } - - dbri->descs[rd].inuse = 0; - dbri->pipes[pipe].desc = dbri->descs[rd].next; - status = dbri->dma->desc[rd].word1; - dbri->dma->desc[rd].word1 = 0; /* Reset it for next time. */ - - info = &dbri->stream_info[DBRI_REC]; - info->offset += DBRI_RD_CNT(status); - info->left += DBRI_RD_CNT(status); - - /* FIXME: Check status */ - - dprintk(D_INT, "Recv RD %d, status 0x%02x, len %d\n", - rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status)); - - /* On the last TD, transmit them all again. */ - if (dbri->descs[rd].next == -1) { - if (info->left > info->size) { - printk(KERN_WARNING - "%d bytes recorded in %d size buffer.\n", - info->left, info->size); - } - tasklet_schedule(&xmit_descs_task); - } - - /* Notify ALSA */ - if (spin_is_locked(&dbri->lock)) { - spin_unlock(&dbri->lock); - snd_pcm_period_elapsed(info->substream); - spin_lock(&dbri->lock); - } else - snd_pcm_period_elapsed(info->substream); -} - -static void dbri_process_one_interrupt(snd_dbri_t * dbri, int x) -{ - int val = D_INTR_GETVAL(x); - int channel = D_INTR_GETCHAN(x); - int command = D_INTR_GETCMD(x); - int code = D_INTR_GETCODE(x); -#ifdef DBRI_DEBUG - int rval = D_INTR_GETRVAL(x); -#endif - - if (channel == D_INTR_CMD) { - dprintk(D_CMD, "INTR: Command: %-5s Value:%d\n", - cmds[command], val); - } else { - dprintk(D_INT, "INTR: Chan:%d Code:%d Val:%#x\n", - channel, code, rval); - } - - if (channel == D_INTR_CMD && command == D_WAIT) { - dbri->wait_seen++; - return; - } - - switch (code) { - case D_INTR_BRDY: - reception_complete_intr(dbri, channel); - break; - case D_INTR_XCMP: - case D_INTR_MINT: - transmission_complete_intr(dbri, channel); - break; - case D_INTR_UNDR: - /* UNDR - Transmission underrun - * resend SDP command with clear pipe bit (C) set - */ - { - volatile s32 *cmd; - - int pipe = channel; - int td = dbri->pipes[pipe].desc; - - dbri->dma->desc[td].word4 = 0; - cmd = dbri_cmdlock(dbri, NoGetLock); - *(cmd++) = DBRI_CMD(D_SDP, 0, - dbri->pipes[pipe].sdp - | D_SDP_P | D_SDP_C | D_SDP_2SAME); - *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, td); - dbri_cmdsend(dbri, cmd); - } - break; - case D_INTR_FXDT: - /* FXDT - Fixed data change */ - if (dbri->pipes[channel].sdp & D_SDP_MSB) - val = reverse_bytes(val, dbri->pipes[channel].length); - - if (dbri->pipes[channel].recv_fixed_ptr) - *(dbri->pipes[channel].recv_fixed_ptr) = val; - break; - default: - if (channel != D_INTR_CMD) - printk(KERN_WARNING - "DBRI: Ignored Interrupt: %d (0x%x)\n", code, x); - } -} - -/* dbri_process_interrupt_buffer advances through the DBRI's interrupt - * buffer until it finds a zero word (indicating nothing more to do - * right now). Non-zero words require processing and are handed off - * to dbri_process_one_interrupt AFTER advancing the pointer. This - * order is important since we might recurse back into this function - * and need to make sure the pointer has been advanced first. - */ -static void dbri_process_interrupt_buffer(snd_dbri_t * dbri) -{ - s32 x; - - while ((x = dbri->dma->intr[dbri->dbri_irqp]) != 0) { - dbri->dma->intr[dbri->dbri_irqp] = 0; - dbri->dbri_irqp++; - if (dbri->dbri_irqp == (DBRI_NO_INTS * DBRI_INT_BLK)) - dbri->dbri_irqp = 1; - else if ((dbri->dbri_irqp & (DBRI_INT_BLK - 1)) == 0) - dbri->dbri_irqp++; - - dbri_process_one_interrupt(dbri, x); - } -} - -static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id, - struct pt_regs *regs) -{ - snd_dbri_t *dbri = dev_id; - static int errcnt = 0; - int x; - - if (dbri == NULL) - return IRQ_NONE; - spin_lock(&dbri->lock); - - /* - * Read it, so the interrupt goes away. - */ - x = sbus_readl(dbri->regs + REG1); - - if (x & (D_MRR | D_MLE | D_LBG | D_MBE)) { - u32 tmp; - - if (x & D_MRR) - printk(KERN_ERR - "DBRI: Multiple Error Ack on SBus reg1=0x%x\n", - x); - if (x & D_MLE) - printk(KERN_ERR - "DBRI: Multiple Late Error on SBus reg1=0x%x\n", - x); - if (x & D_LBG) - printk(KERN_ERR - "DBRI: Lost Bus Grant on SBus reg1=0x%x\n", x); - if (x & D_MBE) - printk(KERN_ERR - "DBRI: Burst Error on SBus reg1=0x%x\n", x); - - /* Some of these SBus errors cause the chip's SBus circuitry - * to be disabled, so just re-enable and try to keep going. - * - * The only one I've seen is MRR, which will be triggered - * if you let a transmit pipe underrun, then try to CDP it. - * - * If these things persist, we should probably reset - * and re-init the chip. - */ - if ((++errcnt) % 10 == 0) { - dprintk(D_INT, "Interrupt errors exceeded.\n"); - dbri_reset(dbri); - } else { - tmp = sbus_readl(dbri->regs + REG0); - tmp &= ~(D_D); - sbus_writel(tmp, dbri->regs + REG0); - } - } - - dbri_process_interrupt_buffer(dbri); - - /* FIXME: Write 0 into regs to ACK interrupt */ - - spin_unlock(&dbri->lock); - - return IRQ_HANDLED; -} - -/**************************************************************************** - PCM Interface -****************************************************************************/ -static snd_pcm_hardware_t snd_dbri_pcm_hw = { - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID), - .formats = SNDRV_PCM_FMTBIT_MU_LAW | - SNDRV_PCM_FMTBIT_A_LAW | - SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S16_BE, - .rates = SNDRV_PCM_RATE_8000_48000, - .rate_min = 8000, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = (64 * 1024), - .period_bytes_min = 1, - .period_bytes_max = DBRI_TD_MAXCNT, - .periods_min = 1, - .periods_max = 1024, -}; - -static int snd_dbri_open(snd_pcm_substream_t * substream) -{ - snd_dbri_t *dbri = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; - dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream); - unsigned long flags; - - dprintk(D_USR, "open audio output.\n"); - runtime->hw = snd_dbri_pcm_hw; - - spin_lock_irqsave(&dbri->lock, flags); - info->substream = substream; - info->left = 0; - info->offset = 0; - info->dvma_buffer = 0; - info->pipe = -1; - spin_unlock_irqrestore(&dbri->lock, flags); - - cs4215_open(dbri); - - return 0; -} - -static int snd_dbri_close(snd_pcm_substream_t * substream) -{ - snd_dbri_t *dbri = snd_pcm_substream_chip(substream); - dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream); - - dprintk(D_USR, "close audio output.\n"); - info->substream = NULL; - info->left = 0; - info->offset = 0; - - return 0; -} - -static int snd_dbri_hw_params(snd_pcm_substream_t * substream, - snd_pcm_hw_params_t * hw_params) -{ - snd_pcm_runtime_t *runtime = substream->runtime; - snd_dbri_t *dbri = snd_pcm_substream_chip(substream); - dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream); - int direction; - int ret; - - /* set sampling rate, audio format and number of channels */ - ret = cs4215_prepare(dbri, params_rate(hw_params), - params_format(hw_params), - params_channels(hw_params)); - if (ret != 0) - return ret; - - if ((ret = snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params))) < 0) { - snd_printk(KERN_ERR "malloc_pages failed with %d\n", ret); - return ret; - } - - /* hw_params can get called multiple times. Only map the DMA once. - */ - if (info->dvma_buffer == 0) { - if (DBRI_STREAMNO(substream) == DBRI_PLAY) - direction = SBUS_DMA_TODEVICE; - else - direction = SBUS_DMA_FROMDEVICE; - - info->dvma_buffer = sbus_map_single(dbri->sdev, - runtime->dma_area, - params_buffer_bytes(hw_params), - direction); - } - - direction = params_buffer_bytes(hw_params); - dprintk(D_USR, "hw_params: %d bytes, dvma=%x\n", - direction, info->dvma_buffer); - return 0; -} - -static int snd_dbri_hw_free(snd_pcm_substream_t * substream) -{ - snd_dbri_t *dbri = snd_pcm_substream_chip(substream); - dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream); - int direction; - dprintk(D_USR, "hw_free.\n"); - - /* hw_free can get called multiple times. Only unmap the DMA once. - */ - if (info->dvma_buffer) { - if (DBRI_STREAMNO(substream) == DBRI_PLAY) - direction = SBUS_DMA_TODEVICE; - else - direction = SBUS_DMA_FROMDEVICE; - - sbus_unmap_single(dbri->sdev, info->dvma_buffer, - substream->runtime->buffer_size, direction); - info->dvma_buffer = 0; - } - info->pipe = -1; - - return snd_pcm_lib_free_pages(substream); -} - -static int snd_dbri_prepare(snd_pcm_substream_t * substream) -{ - snd_dbri_t *dbri = snd_pcm_substream_chip(substream); - dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream); - snd_pcm_runtime_t *runtime = substream->runtime; - int ret; - - info->size = snd_pcm_lib_buffer_bytes(substream); - if (DBRI_STREAMNO(substream) == DBRI_PLAY) - info->pipe = 4; /* Send pipe */ - else { - info->pipe = 6; /* Receive pipe */ - info->left = info->size; /* To trigger submittal */ - } - - spin_lock_irq(&dbri->lock); - - /* Setup the all the transmit/receive desciptors to cover the - * whole DMA buffer. - */ - ret = setup_descs(dbri, DBRI_STREAMNO(substream), - snd_pcm_lib_period_bytes(substream)); - - runtime->stop_threshold = DBRI_TD_MAXCNT / runtime->channels; - - spin_unlock_irq(&dbri->lock); - - dprintk(D_USR, "prepare audio output. %d bytes\n", info->size); - return ret; -} - -static int snd_dbri_trigger(snd_pcm_substream_t * substream, int cmd) -{ - snd_dbri_t *dbri = snd_pcm_substream_chip(substream); - dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream); - int ret = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - dprintk(D_USR, "start audio, period is %d bytes\n", - (int)snd_pcm_lib_period_bytes(substream)); - /* Enable & schedule the tasklet that re-submits the TDs. */ - xmit_descs_task.data = (unsigned long)dbri; - tasklet_schedule(&xmit_descs_task); - break; - case SNDRV_PCM_TRIGGER_STOP: - dprintk(D_USR, "stop audio.\n"); - /* Make the tasklet bail out immediately. */ - xmit_descs_task.data = 0; - reset_pipe(dbri, info->pipe); - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static snd_pcm_uframes_t snd_dbri_pointer(snd_pcm_substream_t * substream) -{ - snd_dbri_t *dbri = snd_pcm_substream_chip(substream); - dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream); - snd_pcm_uframes_t ret; - - ret = bytes_to_frames(substream->runtime, info->offset) - % substream->runtime->buffer_size; - dprintk(D_USR, "I/O pointer: %ld frames, %d bytes left.\n", - ret, info->left); - return ret; -} - -static snd_pcm_ops_t snd_dbri_ops = { - .open = snd_dbri_open, - .close = snd_dbri_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_dbri_hw_params, - .hw_free = snd_dbri_hw_free, - .prepare = snd_dbri_prepare, - .trigger = snd_dbri_trigger, - .pointer = snd_dbri_pointer, -}; - -static int __devinit snd_dbri_pcm(snd_dbri_t * dbri) -{ - snd_pcm_t *pcm; - int err; - - if ((err = snd_pcm_new(dbri->card, - /* ID */ "sun_dbri", - /* device */ 0, - /* playback count */ 1, - /* capture count */ 1, &pcm)) < 0) - return err; - snd_assert(pcm != NULL, return -EINVAL); - - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dbri_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_dbri_ops); - - pcm->private_data = dbri; - pcm->info_flags = 0; - strcpy(pcm->name, dbri->card->shortname); - dbri->pcm = pcm; - - if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, - SNDRV_DMA_TYPE_CONTINUOUS, - snd_dma_continuous_data(GFP_KERNEL), - 64 * 1024, 64 * 1024)) < 0) { - return err; - } - - return 0; -} - -/***************************************************************************** - Mixer interface -*****************************************************************************/ - -static int snd_cs4215_info_volume(snd_kcontrol_t * kcontrol, - snd_ctl_elem_info_t * uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - if (kcontrol->private_value == DBRI_PLAY) { - uinfo->value.integer.max = DBRI_MAX_VOLUME; - } else { - uinfo->value.integer.max = DBRI_MAX_GAIN; - } - return 0; -} - -static int snd_cs4215_get_volume(snd_kcontrol_t * kcontrol, - snd_ctl_elem_value_t * ucontrol) -{ - snd_dbri_t *dbri = snd_kcontrol_chip(kcontrol); - dbri_streaminfo_t *info; - snd_assert(dbri != NULL, return -EINVAL); - info = &dbri->stream_info[kcontrol->private_value]; - snd_assert(info != NULL, return -EINVAL); - - ucontrol->value.integer.value[0] = info->left_gain; - ucontrol->value.integer.value[1] = info->right_gain; - return 0; -} - -static int snd_cs4215_put_volume(snd_kcontrol_t * kcontrol, - snd_ctl_elem_value_t * ucontrol) -{ - snd_dbri_t *dbri = snd_kcontrol_chip(kcontrol); - dbri_streaminfo_t *info = &dbri->stream_info[kcontrol->private_value]; - unsigned long flags; - int changed = 0; - - if (info->left_gain != ucontrol->value.integer.value[0]) { - info->left_gain = ucontrol->value.integer.value[0]; - changed = 1; - } - if (info->right_gain != ucontrol->value.integer.value[1]) { - info->right_gain = ucontrol->value.integer.value[1]; - changed = 1; - } - if (changed == 1) { - /* First mute outputs, and wait 1/8000 sec (125 us) - * to make sure this takes. This avoids clicking noises. - */ - spin_lock_irqsave(&dbri->lock, flags); - - cs4215_setdata(dbri, 1); - udelay(125); - cs4215_setdata(dbri, 0); - - spin_unlock_irqrestore(&dbri->lock, flags); - } - return changed; -} - -static int snd_cs4215_info_single(snd_kcontrol_t * kcontrol, - snd_ctl_elem_info_t * uinfo) -{ - int mask = (kcontrol->private_value >> 16) & 0xff; - - uinfo->type = (mask == 1) ? - SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = mask; - return 0; -} - -static int snd_cs4215_get_single(snd_kcontrol_t * kcontrol, - snd_ctl_elem_value_t * ucontrol) -{ - snd_dbri_t *dbri = snd_kcontrol_chip(kcontrol); - int elem = kcontrol->private_value & 0xff; - int shift = (kcontrol->private_value >> 8) & 0xff; - int mask = (kcontrol->private_value >> 16) & 0xff; - int invert = (kcontrol->private_value >> 24) & 1; - snd_assert(dbri != NULL, return -EINVAL); - - if (elem < 4) { - ucontrol->value.integer.value[0] = - (dbri->mm.data[elem] >> shift) & mask; - } else { - ucontrol->value.integer.value[0] = - (dbri->mm.ctrl[elem - 4] >> shift) & mask; - } - - if (invert == 1) { - ucontrol->value.integer.value[0] = - mask - ucontrol->value.integer.value[0]; - } - return 0; -} - -static int snd_cs4215_put_single(snd_kcontrol_t * kcontrol, - snd_ctl_elem_value_t * ucontrol) -{ - snd_dbri_t *dbri = snd_kcontrol_chip(kcontrol); - unsigned long flags; - int elem = kcontrol->private_value & 0xff; - int shift = (kcontrol->private_value >> 8) & 0xff; - int mask = (kcontrol->private_value >> 16) & 0xff; - int invert = (kcontrol->private_value >> 24) & 1; - int changed = 0; - unsigned short val; - snd_assert(dbri != NULL, return -EINVAL); - - val = (ucontrol->value.integer.value[0] & mask); - if (invert == 1) - val = mask - val; - val <<= shift; - - if (elem < 4) { - dbri->mm.data[elem] = (dbri->mm.data[elem] & - ~(mask << shift)) | val; - changed = (val != dbri->mm.data[elem]); - } else { - dbri->mm.ctrl[elem - 4] = (dbri->mm.ctrl[elem - 4] & - ~(mask << shift)) | val; - changed = (val != dbri->mm.ctrl[elem - 4]); - } - - dprintk(D_GEN, "put_single: mask=0x%x, changed=%d, " - "mixer-value=%ld, mm-value=0x%x\n", - mask, changed, ucontrol->value.integer.value[0], - dbri->mm.data[elem & 3]); - - if (changed) { - /* First mute outputs, and wait 1/8000 sec (125 us) - * to make sure this takes. This avoids clicking noises. - */ - spin_lock_irqsave(&dbri->lock, flags); - - cs4215_setdata(dbri, 1); - udelay(125); - cs4215_setdata(dbri, 0); - - spin_unlock_irqrestore(&dbri->lock, flags); - } - return changed; -} - -/* Entries 0-3 map to the 4 data timeslots, entries 4-7 map to the 4 control - timeslots. Shift is the bit offset in the timeslot, mask defines the - number of bits. invert is a boolean for use with attenuation. - */ -#define CS4215_SINGLE(xname, entry, shift, mask, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_cs4215_info_single, \ - .get = snd_cs4215_get_single, .put = snd_cs4215_put_single, \ - .private_value = entry | (shift << 8) | (mask << 16) | (invert << 24) }, - -static snd_kcontrol_new_t dbri_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Playback Volume", - .info = snd_cs4215_info_volume, - .get = snd_cs4215_get_volume, - .put = snd_cs4215_put_volume, - .private_value = DBRI_PLAY, - }, - CS4215_SINGLE("Headphone switch", 0, 7, 1, 0) - CS4215_SINGLE("Line out switch", 0, 6, 1, 0) - CS4215_SINGLE("Speaker switch", 1, 6, 1, 0) - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Volume", - .info = snd_cs4215_info_volume, - .get = snd_cs4215_get_volume, - .put = snd_cs4215_put_volume, - .private_value = DBRI_REC, - }, - /* FIXME: mic/line switch */ - CS4215_SINGLE("Line in switch", 2, 4, 1, 0) - CS4215_SINGLE("High Pass Filter switch", 5, 7, 1, 0) - CS4215_SINGLE("Monitor Volume", 3, 4, 0xf, 1) - CS4215_SINGLE("Mic boost", 4, 4, 1, 1) -}; - -#define NUM_CS4215_CONTROLS (sizeof(dbri_controls)/sizeof(snd_kcontrol_new_t)) - -static int __init snd_dbri_mixer(snd_dbri_t * dbri) -{ - snd_card_t *card; - int idx, err; - - snd_assert(dbri != NULL && dbri->card != NULL, return -EINVAL); - - card = dbri->card; - strcpy(card->mixername, card->shortname); - - for (idx = 0; idx < NUM_CS4215_CONTROLS; idx++) { - if ((err = snd_ctl_add(card, - snd_ctl_new1(&dbri_controls[idx], - dbri))) < 0) - return err; - } - - for (idx = DBRI_REC; idx < DBRI_NO_STREAMS; idx++) { - dbri->stream_info[idx].left_gain = 0; - dbri->stream_info[idx].right_gain = 0; - dbri->stream_info[idx].balance = DBRI_MID_BALANCE; - } - - return 0; -} - -/**************************************************************************** - /proc interface -****************************************************************************/ -static void dbri_regs_read(snd_info_entry_t * entry, snd_info_buffer_t * buffer) -{ - snd_dbri_t *dbri = entry->private_data; - - snd_iprintf(buffer, "REG0: 0x%x\n", sbus_readl(dbri->regs + REG0)); - snd_iprintf(buffer, "REG2: 0x%x\n", sbus_readl(dbri->regs + REG2)); - snd_iprintf(buffer, "REG8: 0x%x\n", sbus_readl(dbri->regs + REG8)); - snd_iprintf(buffer, "REG9: 0x%x\n", sbus_readl(dbri->regs + REG9)); -} - -#ifdef DBRI_DEBUG -static void dbri_debug_read(snd_info_entry_t * entry, - snd_info_buffer_t * buffer) -{ - snd_dbri_t *dbri = entry->private_data; - int pipe; - snd_iprintf(buffer, "debug=%d\n", dbri_debug); - - snd_iprintf(buffer, "CHI pipe in=%d, out=%d\n", - dbri->chi_in_pipe, dbri->chi_out_pipe); - for (pipe = 0; pipe < 32; pipe++) { - if (pipe_active(dbri, pipe)) { - struct dbri_pipe *pptr = &dbri->pipes[pipe]; - snd_iprintf(buffer, - "Pipe %d: %s SDP=0x%x desc=%d, " - "len=%d @ %d prev: %d next %d\n", - pipe, - (pptr->direction == - PIPEinput ? "input" : "output"), pptr->sdp, - pptr->desc, pptr->length, pptr->cycle, - pptr->prevpipe, pptr->nextpipe); - } - } -} - -static void dbri_debug_write(snd_info_entry_t * entry, - snd_info_buffer_t * buffer) -{ - char line[80]; - int i; - - if (snd_info_get_line(buffer, line, 80) == 0) { - sscanf(line, "%d\n", &i); - dbri_debug = i & 0x3f; - } -} -#endif - -void snd_dbri_proc(snd_dbri_t * dbri) -{ - snd_info_entry_t *entry; - int err; - - err = snd_card_proc_new(dbri->card, "regs", &entry); - snd_info_set_text_ops(entry, dbri, 1024, dbri_regs_read); - -#ifdef DBRI_DEBUG - err = snd_card_proc_new(dbri->card, "debug", &entry); - snd_info_set_text_ops(entry, dbri, 4096, dbri_debug_read); - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; /* Writable for root */ - entry->c.text.write_size = 256; - entry->c.text.write = dbri_debug_write; -#endif -} - -/* -**************************************************************************** -**************************** Initialization ******************************** -**************************************************************************** -*/ -static void snd_dbri_free(snd_dbri_t * dbri); - -static int __init snd_dbri_create(snd_card_t * card, - struct sbus_dev *sdev, - struct linux_prom_irqs *irq, int dev) -{ - snd_dbri_t *dbri = card->private_data; - int err; - - spin_lock_init(&dbri->lock); - dbri->card = card; - dbri->sdev = sdev; - dbri->irq = irq->pri; - dbri->dbri_version = sdev->prom_name[9]; - - dbri->dma = sbus_alloc_consistent(sdev, sizeof(struct dbri_dma), - &dbri->dma_dvma); - memset((void *)dbri->dma, 0, sizeof(struct dbri_dma)); - - dprintk(D_GEN, "DMA Cmd Block 0x%p (0x%08x)\n", - dbri->dma, dbri->dma_dvma); - - /* Map the registers into memory. */ - dbri->regs_size = sdev->reg_addrs[0].reg_size; - dbri->regs = sbus_ioremap(&sdev->resource[0], 0, - dbri->regs_size, "DBRI Registers"); - if (!dbri->regs) { - printk(KERN_ERR "DBRI: could not allocate registers\n"); - sbus_free_consistent(sdev, sizeof(struct dbri_dma), - (void *)dbri->dma, dbri->dma_dvma); - return -EIO; - } - - err = request_irq(dbri->irq, snd_dbri_interrupt, SA_SHIRQ, - "DBRI audio", dbri); - if (err) { - printk(KERN_ERR "DBRI: Can't get irq %d\n", dbri->irq); - sbus_iounmap(dbri->regs, dbri->regs_size); - sbus_free_consistent(sdev, sizeof(struct dbri_dma), - (void *)dbri->dma, dbri->dma_dvma); - return err; - } - - /* Do low level initialization of the DBRI and CS4215 chips */ - dbri_initialize(dbri); - err = cs4215_init(dbri); - if (err) { - snd_dbri_free(dbri); - return err; - } - - dbri->next = dbri_list; - dbri_list = dbri; - - return 0; -} - -static void snd_dbri_free(snd_dbri_t * dbri) -{ - dprintk(D_GEN, "snd_dbri_free\n"); - dbri_reset(dbri); - - if (dbri->irq) - free_irq(dbri->irq, dbri); - - if (dbri->regs) - sbus_iounmap(dbri->regs, dbri->regs_size); - - if (dbri->dma) - sbus_free_consistent(dbri->sdev, sizeof(struct dbri_dma), - (void *)dbri->dma, dbri->dma_dvma); -} - -static int __init dbri_attach(int prom_node, struct sbus_dev *sdev) -{ - snd_dbri_t *dbri; - struct linux_prom_irqs irq; - struct resource *rp; - snd_card_t *card; - static int dev = 0; - int err; - - if (sdev->prom_name[9] < 'e') { - printk(KERN_ERR "DBRI: unsupported chip version %c found.\n", - sdev->prom_name[9]); - return -EIO; - } - - if (dev >= SNDRV_CARDS) - return -ENODEV; - if (!enable[dev]) { - dev++; - return -ENOENT; - } - - prom_getproperty(prom_node, "intr", (char *)&irq, sizeof(irq)); - - card = snd_card_new(index[dev], id[dev], THIS_MODULE, - sizeof(snd_dbri_t)); - if (card == NULL) - return -ENOMEM; - - strcpy(card->driver, "DBRI"); - strcpy(card->shortname, "Sun DBRI"); - rp = &sdev->resource[0]; - sprintf(card->longname, "%s at 0x%02lx:0x%08lx, irq %s", - card->shortname, - rp->flags & 0xffL, rp->start, __irq_itoa(irq.pri)); - - if ((err = snd_dbri_create(card, sdev, &irq, dev)) < 0) { - snd_card_free(card); - return err; - } - - dbri = (snd_dbri_t *) card->private_data; - if ((err = snd_dbri_pcm(dbri)) < 0) { - snd_dbri_free(dbri); - snd_card_free(card); - return err; - } - - if ((err = snd_dbri_mixer(dbri)) < 0) { - snd_dbri_free(dbri); - snd_card_free(card); - return err; - } - - /* /proc file handling */ - snd_dbri_proc(dbri); - - if ((err = snd_card_register(card)) < 0) { - snd_dbri_free(dbri); - snd_card_free(card); - return err; - } - - printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n", - dev, dbri->regs, - dbri->irq, dbri->dbri_version, dbri->mm.version); - dev++; - - return 0; -} - -/* Probe for the dbri chip and then attach the driver. */ -static int __init dbri_init(void) -{ - struct sbus_bus *sbus; - struct sbus_dev *sdev; - int found = 0; - - /* Probe each SBUS for the DBRI chip(s). */ - for_all_sbusdev(sdev, sbus) { - /* - * The version is coded in the last character - */ - if (!strncmp(sdev->prom_name, "SUNW,DBRI", 9)) { - dprintk(D_GEN, "DBRI: Found %s in SBUS slot %d\n", - sdev->prom_name, sdev->slot); - - if (dbri_attach(sdev->prom_node, sdev) == 0) - found++; - } - } - - return (found > 0) ? 0 : -EIO; -} - -static void __exit dbri_exit(void) -{ - snd_dbri_t *this = dbri_list; - - while (this != NULL) { - snd_dbri_t *next = this->next; - snd_card_t *card = this->card; - - snd_dbri_free(this); - snd_card_free(card); - this = next; - } - dbri_list = NULL; -} - -module_init(dbri_init); -module_exit(dbri_exit); diff --git a/trunk/sound/usb/usbaudio.c b/trunk/sound/usb/usbaudio.c index 8298c462c291..b5e734d975e0 100644 --- a/trunk/sound/usb/usbaudio.c +++ b/trunk/sound/usb/usbaudio.c @@ -153,7 +153,6 @@ struct snd_usb_substream { unsigned int format; /* USB data format */ unsigned int datapipe; /* the data i/o pipe */ unsigned int syncpipe; /* 1 - async out or adaptive in */ - unsigned int datainterval; /* log_2 of data packet interval */ unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */ unsigned int freqm; /* momentary sampling rate in fs/fps in Q16.16 format */ @@ -519,8 +518,7 @@ static int prepare_playback_urb(snd_usb_substream_t *subs, if (subs->fill_max) counts = subs->maxframesize; /* fixed */ else { - subs->phase = (subs->phase & 0xffff) - + (subs->freqm << subs->datainterval); + subs->phase = (subs->phase & 0xffff) + subs->freqm; counts = subs->phase >> 16; if (counts > subs->maxframesize) counts = subs->maxframesize; @@ -792,7 +790,7 @@ static int start_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime) */ static int wait_clear_urbs(snd_usb_substream_t *subs) { - unsigned long end_time = jiffies + msecs_to_jiffies(1000); + int timeout = HZ; unsigned int i; int alive; @@ -812,7 +810,7 @@ static int wait_clear_urbs(snd_usb_substream_t *subs) break; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1); - } while (time_before(jiffies, end_time)); + } while (--timeout > 0); if (alive) snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive); return 0; @@ -901,19 +899,16 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by else subs->freqn = get_usb_high_speed_rate(rate); subs->freqm = subs->freqn; - /* calculate max. frequency */ - if (subs->maxpacksize) { - /* whatever fits into a max. size packet */ + subs->freqmax = subs->freqn + (subs->freqn >> 2); /* max. allowed frequency */ + subs->phase = 0; + + /* calculate the max. size of packet */ + maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3)) >> 16; + if (subs->maxpacksize && maxsize > subs->maxpacksize) { + //snd_printd(KERN_DEBUG "maxsize %d is greater than defined size %d\n", + // maxsize, subs->maxpacksize); maxsize = subs->maxpacksize; - subs->freqmax = (maxsize / (frame_bits >> 3)) - << (16 - subs->datainterval); - } else { - /* no max. packet size: just take 25% higher than nominal */ - subs->freqmax = subs->freqn + (subs->freqn >> 2); - maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3)) - >> (16 - subs->datainterval); } - subs->phase = 0; if (subs->fill_max) subs->curpacksize = subs->maxpacksize; @@ -923,7 +918,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) urb_packs = nrpacks; else - urb_packs = (nrpacks * 8) >> subs->datainterval; + urb_packs = nrpacks * 8; /* allocate a temporary buffer for playback */ if (is_playback) { @@ -996,7 +991,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by u->urb->pipe = subs->datapipe; u->urb->transfer_flags = URB_ISO_ASAP; u->urb->number_of_packets = u->packets; - u->urb->interval = 1 << subs->datainterval; + u->urb->interval = 1; u->urb->context = u; u->urb->complete = snd_usb_complete_callback(snd_complete_urb); } @@ -1200,12 +1195,6 @@ static int set_format(snd_usb_substream_t *subs, struct audioformat *fmt) subs->datapipe = usb_sndisocpipe(dev, ep); else subs->datapipe = usb_rcvisocpipe(dev, ep); - if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH && - get_endpoint(alts, 0)->bInterval >= 1 && - get_endpoint(alts, 0)->bInterval <= 4) - subs->datainterval = get_endpoint(alts, 0)->bInterval - 1; - else - subs->datainterval = 0; subs->syncpipe = subs->syncinterval = 0; subs->maxpacksize = fmt->maxpacksize; subs->fill_max = 0; @@ -2408,9 +2397,10 @@ static int parse_audio_format(snd_usb_audio_t *chip, struct audioformat *fp, if (chip->usb_id == USB_ID(0x041e, 0x3000) || chip->usb_id == USB_ID(0x041e, 0x3020)) { if (fmt[3] == USB_FORMAT_TYPE_I && + stream == SNDRV_PCM_STREAM_PLAYBACK && fp->rates != SNDRV_PCM_RATE_48000 && fp->rates != SNDRV_PCM_RATE_96000) - return -1; + return -1; /* use 48k only */ } #endif return 0; @@ -2502,10 +2492,8 @@ static int parse_audio_endpoints(snd_usb_audio_t *chip, int iface_no) fp->altset_idx = i; fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; + /* FIXME: decode wMaxPacketSize of high bandwith endpoints */ fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); - if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) - fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) - * (fp->maxpacksize & 0x7ff); fp->attributes = csep[3]; /* some quirks for attributes here */ @@ -2735,8 +2723,7 @@ static int create_standard_interface_quirk(snd_usb_audio_t *chip, * to detect the sample rate is by looking at wMaxPacketSize. */ static int create_ua700_ua25_quirk(snd_usb_audio_t *chip, - struct usb_interface *iface, - const snd_usb_audio_quirk_t *quirk) + struct usb_interface *iface) { static const struct audioformat ua_format = { .format = SNDRV_PCM_FORMAT_S24_3LE, @@ -2827,9 +2814,7 @@ static int create_ua700_ua25_quirk(snd_usb_audio_t *chip, /* * Create a stream for an Edirol UA-1000 interface. */ -static int create_ua1000_quirk(snd_usb_audio_t *chip, - struct usb_interface *iface, - const snd_usb_audio_quirk_t *quirk) +static int create_ua1000_quirk(snd_usb_audio_t *chip, struct usb_interface *iface) { static const struct audioformat ua1000_format = { .format = SNDRV_PCM_FORMAT_S32_LE, @@ -2906,13 +2891,6 @@ static int create_composite_quirk(snd_usb_audio_t *chip, return 0; } -static int ignore_interface_quirk(snd_usb_audio_t *chip, - struct usb_interface *iface, - const snd_usb_audio_quirk_t *quirk) -{ - return 0; -} - /* * boot quirks @@ -2948,6 +2926,8 @@ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interfac static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev) { +#if 0 + /* TODO: enable this when high speed synchronization actually works */ u8 buf = 1; snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a, @@ -2959,6 +2939,7 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev) 1, 2000, NULL, 0, 1000); return -ENODEV; } +#endif return 0; } @@ -2975,28 +2956,28 @@ static int snd_usb_create_quirk(snd_usb_audio_t *chip, struct usb_interface *iface, const snd_usb_audio_quirk_t *quirk) { - typedef int (*quirk_func_t)(snd_usb_audio_t *, struct usb_interface *, - const snd_usb_audio_quirk_t *); - static const quirk_func_t quirk_funcs[] = { - [QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk, - [QUIRK_COMPOSITE] = create_composite_quirk, - [QUIRK_MIDI_STANDARD_INTERFACE] = snd_usb_create_midi_interface, - [QUIRK_MIDI_FIXED_ENDPOINT] = snd_usb_create_midi_interface, - [QUIRK_MIDI_YAMAHA] = snd_usb_create_midi_interface, - [QUIRK_MIDI_MIDIMAN] = snd_usb_create_midi_interface, - [QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface, - [QUIRK_MIDI_RAW] = snd_usb_create_midi_interface, - [QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface, - [QUIRK_MIDI_MIDITECH] = snd_usb_create_midi_interface, - [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_interface_quirk, - [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, - [QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk, - [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk, - }; - - if (quirk->type < QUIRK_TYPE_COUNT) { - return quirk_funcs[quirk->type](chip, iface, quirk); - } else { + switch (quirk->type) { + case QUIRK_MIDI_FIXED_ENDPOINT: + case QUIRK_MIDI_YAMAHA: + case QUIRK_MIDI_MIDIMAN: + case QUIRK_MIDI_NOVATION: + case QUIRK_MIDI_MOTU: + case QUIRK_MIDI_EMAGIC: + return snd_usb_create_midi_interface(chip, iface, quirk); + case QUIRK_COMPOSITE: + return create_composite_quirk(chip, iface, quirk); + case QUIRK_AUDIO_FIXED_ENDPOINT: + return create_fixed_stream_quirk(chip, iface, quirk); + case QUIRK_AUDIO_STANDARD_INTERFACE: + case QUIRK_MIDI_STANDARD_INTERFACE: + return create_standard_interface_quirk(chip, iface, quirk); + case QUIRK_AUDIO_EDIROL_UA700_UA25: + return create_ua700_ua25_quirk(chip, iface); + case QUIRK_AUDIO_EDIROL_UA1000: + return create_ua1000_quirk(chip, iface); + case QUIRK_IGNORE_INTERFACE: + return 0; + default: snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); return -ENXIO; } diff --git a/trunk/sound/usb/usbaudio.h b/trunk/sound/usb/usbaudio.h index ad9eab211d8f..aedb42aaa749 100644 --- a/trunk/sound/usb/usbaudio.h +++ b/trunk/sound/usb/usbaudio.h @@ -153,24 +153,20 @@ struct snd_usb_audio { #define QUIRK_NO_INTERFACE -2 #define QUIRK_ANY_INTERFACE -1 -enum quirk_type { - QUIRK_IGNORE_INTERFACE, - QUIRK_COMPOSITE, - QUIRK_MIDI_STANDARD_INTERFACE, - QUIRK_MIDI_FIXED_ENDPOINT, - QUIRK_MIDI_YAMAHA, - QUIRK_MIDI_MIDIMAN, - QUIRK_MIDI_NOVATION, - QUIRK_MIDI_RAW, - QUIRK_MIDI_EMAGIC, - QUIRK_MIDI_MIDITECH, - QUIRK_AUDIO_STANDARD_INTERFACE, - QUIRK_AUDIO_FIXED_ENDPOINT, - QUIRK_AUDIO_EDIROL_UA700_UA25, - QUIRK_AUDIO_EDIROL_UA1000, - - QUIRK_TYPE_COUNT -}; +/* quirk type */ +#define QUIRK_MIDI_FIXED_ENDPOINT 0 +#define QUIRK_MIDI_YAMAHA 1 +#define QUIRK_MIDI_MIDIMAN 2 +#define QUIRK_COMPOSITE 3 +#define QUIRK_AUDIO_FIXED_ENDPOINT 4 +#define QUIRK_AUDIO_STANDARD_INTERFACE 5 +#define QUIRK_MIDI_STANDARD_INTERFACE 6 +#define QUIRK_AUDIO_EDIROL_UA700_UA25 7 +#define QUIRK_AUDIO_EDIROL_UA1000 8 +#define QUIRK_IGNORE_INTERFACE 9 +#define QUIRK_MIDI_NOVATION 10 +#define QUIRK_MIDI_MOTU 11 +#define QUIRK_MIDI_EMAGIC 12 typedef struct snd_usb_audio_quirk snd_usb_audio_quirk_t; typedef struct snd_usb_midi_endpoint_info snd_usb_midi_endpoint_info_t; @@ -179,7 +175,7 @@ struct snd_usb_audio_quirk { const char *vendor_name; const char *product_name; int16_t ifnum; - uint16_t type; + int16_t type; const void *data; }; @@ -209,13 +205,11 @@ struct snd_usb_midi_endpoint_info { /* for QUIRK_IGNORE_INTERFACE, data is NULL */ -/* for QUIRK_MIDI_NOVATION and _RAW, data is NULL */ +/* for QUIRK_MIDI_NOVATION and _MOTU, data is NULL */ /* for QUIRK_MIDI_EMAGIC, data points to a snd_usb_midi_endpoint_info * structure (out_cables and in_cables only) */ -/* for QUIRK_MIDI_MIDITECH, data is NULL */ - /* */ diff --git a/trunk/sound/usb/usbmidi.c b/trunk/sound/usb/usbmidi.c index 5778a9b725ec..bee70068dce0 100644 --- a/trunk/sound/usb/usbmidi.c +++ b/trunk/sound/usb/usbmidi.c @@ -524,16 +524,16 @@ static struct usb_protocol_ops snd_usbmidi_novation_ops = { }; /* - * "raw" protocol: used by the MOTU FastLane. + * Mark of the Unicorn USB MIDI protocol: raw MIDI. */ -static void snd_usbmidi_raw_input(snd_usb_midi_in_endpoint_t* ep, - uint8_t* buffer, int buffer_length) +static void snd_usbmidi_motu_input(snd_usb_midi_in_endpoint_t* ep, + uint8_t* buffer, int buffer_length) { snd_usbmidi_input_data(ep, 0, buffer, buffer_length); } -static void snd_usbmidi_raw_output(snd_usb_midi_out_endpoint_t* ep) +static void snd_usbmidi_motu_output(snd_usb_midi_out_endpoint_t* ep) { int count; @@ -549,9 +549,9 @@ static void snd_usbmidi_raw_output(snd_usb_midi_out_endpoint_t* ep) ep->urb->transfer_buffer_length = count; } -static struct usb_protocol_ops snd_usbmidi_raw_ops = { - .input = snd_usbmidi_raw_input, - .output = snd_usbmidi_raw_output, +static struct usb_protocol_ops snd_usbmidi_motu_ops = { + .input = snd_usbmidi_motu_input, + .output = snd_usbmidi_motu_output, }; /* @@ -1505,8 +1505,8 @@ int snd_usb_create_midi_interface(snd_usb_audio_t* chip, umidi->usb_protocol_ops = &snd_usbmidi_novation_ops; err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); break; - case QUIRK_MIDI_RAW: - umidi->usb_protocol_ops = &snd_usbmidi_raw_ops; + case QUIRK_MIDI_MOTU: + umidi->usb_protocol_ops = &snd_usbmidi_motu_ops; err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); break; case QUIRK_MIDI_EMAGIC: @@ -1515,9 +1515,6 @@ int snd_usb_create_midi_interface(snd_usb_audio_t* chip, sizeof(snd_usb_midi_endpoint_info_t)); err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1); break; - case QUIRK_MIDI_MIDITECH: - err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); - break; default: snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); err = -ENXIO; diff --git a/trunk/sound/usb/usbquirks.h b/trunk/sound/usb/usbquirks.h index f74e652a1e51..f5135641b3e2 100644 --- a/trunk/sound/usb/usbquirks.h +++ b/trunk/sound/usb/usbquirks.h @@ -116,7 +116,6 @@ YAMAHA_DEVICE(0x1039, NULL), YAMAHA_DEVICE(0x103a, NULL), YAMAHA_DEVICE(0x103b, NULL), YAMAHA_DEVICE(0x103c, NULL), -YAMAHA_DEVICE(0x103d, NULL), YAMAHA_DEVICE(0x2000, "DGP-7"), YAMAHA_DEVICE(0x2001, "DGP-5"), YAMAHA_DEVICE(0x2002, NULL), @@ -1260,12 +1259,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), /* Mark of the Unicorn devices */ { /* thanks to Robert A. Lerche */ - .match_flags = USB_DEVICE_ID_MATCH_VENDOR | - USB_DEVICE_ID_MATCH_PRODUCT | - USB_DEVICE_ID_MATCH_DEV_SUBCLASS, - .idVendor = 0x07fd, - .idProduct = 0x0001, - .bDeviceSubClass = 2, + USB_DEVICE(0x07fd, 0x0001), .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { .vendor_name = "MOTU", .product_name = "Fastlane", @@ -1274,7 +1268,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), .data = & (const snd_usb_audio_quirk_t[]) { { .ifnum = 0, - .type = QUIRK_MIDI_RAW + .type = QUIRK_MIDI_MOTU }, { .ifnum = 1, @@ -1378,25 +1372,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, -{ - USB_DEVICE(0x4752, 0x0011), - .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { - .vendor_name = "Miditech", - .product_name = "Midistart-2", - .ifnum = 0, - .type = QUIRK_MIDI_MIDITECH - } -}, -{ - USB_DEVICE(0x7104, 0x2202), - .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { - .vendor_name = "Miditech", - .product_name = "MidiStudio-2", - .ifnum = 0, - .type = QUIRK_MIDI_MIDITECH - } -}, - { /* * Some USB MIDI devices don't have an audio control interface, diff --git a/trunk/sound/usb/usx2y/usX2Yhwdep.c b/trunk/sound/usb/usx2y/usX2Yhwdep.c index 0281a362857a..bef9b0c142c4 100644 --- a/trunk/sound/usb/usx2y/usX2Yhwdep.c +++ b/trunk/sound/usb/usx2y/usX2Yhwdep.c @@ -232,7 +232,8 @@ static int snd_usX2Y_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t *dsp) if (err) return err; if (dsp->index == 1) { - msleep(250); // give the device some time + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/4); // give the device some time err = usX2Y_AsyncSeq04_init(priv); if (err) { snd_printk("usX2Y_AsyncSeq04_init error \n"); diff --git a/trunk/sound/usb/usx2y/usx2yhwdeppcm.c b/trunk/sound/usb/usx2y/usx2yhwdeppcm.c index ef28061287f2..bb2c8e9000c6 100644 --- a/trunk/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/trunk/sound/usb/usx2y/usx2yhwdeppcm.c @@ -50,7 +50,6 @@ Currently rawusb dma pcm buffer transport (this file) is only available to snd-usb-usx2y. */ -#include #include "usbusx2yaudio.c" #if defined(USX2Y_NRPACKS_VARIABLE) || (!defined(USX2Y_NRPACKS_VARIABLE) && USX2Y_NRPACKS == 1) @@ -521,8 +520,11 @@ static int snd_usX2Y_usbpcm_prepare(snd_pcm_substream_t *substream) usX2Y->hwdep_pcm_shm->playback_iso_start = -1; if (atomic_read(&subs->state) < state_PREPARED) { while (usX2Y_iso_frames_per_buffer(runtime, usX2Y) > usX2Y->hwdep_pcm_shm->captured_iso_frames) { + signed long timeout; snd_printd("Wait: iso_frames_per_buffer=%i,captured_iso_frames=%i\n", usX2Y_iso_frames_per_buffer(runtime, usX2Y), usX2Y->hwdep_pcm_shm->captured_iso_frames); - if (msleep_interruptible(10)) { + set_current_state(TASK_INTERRUPTIBLE); + timeout = schedule_timeout(HZ/100 + 1); + if (signal_pending(current)) { err = -ERESTARTSYS; goto up_prepare_mutex; }