diff --git a/[refs] b/[refs] index e20642b60439..c8c95394f3db 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f6c427663a158056cd8ca71c01f30653e4b313f7 +refs/heads/master: 486d0a0079eb782cdb73f18246e26076c615a020 diff --git a/trunk/Documentation/networking/tcp.txt b/trunk/Documentation/networking/tcp.txt index 7d11bb5dc30a..0121edc3ba06 100644 --- a/trunk/Documentation/networking/tcp.txt +++ b/trunk/Documentation/networking/tcp.txt @@ -1,7 +1,7 @@ TCP protocol ============ -Last updated: 9 February 2008 +Last updated: 21 June 2005 Contents ======== @@ -52,9 +52,9 @@ research and RFC's before developing new modules. The method that is used to determine which congestion control mechanism is determined by the setting of the sysctl net.ipv4.tcp_congestion_control. The default congestion control will be the last one registered (LIFO); -so if you built everything as modules, the default will be reno. If you -build with the defaults from Kconfig, then CUBIC will be builtin (not a -module) and it will end up the default. +so if you built everything as modules. the default will be reno. If you +build with the default's from Kconfig, then BIC will be builtin (not a module) +and it will end up the default. If you really want a particular default value then you will need to set it with the sysctl. If you use a sysctl, the module will be autoloaded diff --git a/trunk/arch/sparc/kernel/process.c b/trunk/arch/sparc/kernel/process.c index 0bd69d0b5cd7..19186ce8850d 100644 --- a/trunk/arch/sparc/kernel/process.c +++ b/trunk/arch/sparc/kernel/process.c @@ -141,12 +141,16 @@ void cpu_idle(void) extern char reboot_command []; +extern void (*prom_palette)(int); + /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */ void machine_halt(void) { local_irq_enable(); mdelay(8); local_irq_disable(); + if (prom_palette) + prom_palette (1); prom_halt(); panic("Halt failed!"); } @@ -161,6 +165,8 @@ void machine_restart(char * cmd) p = strchr (reboot_command, '\n'); if (p) *p = 0; + if (prom_palette) + prom_palette (1); if (cmd) prom_reboot(cmd); if (*reboot_command) diff --git a/trunk/arch/sparc/kernel/setup.c b/trunk/arch/sparc/kernel/setup.c index 3c13137685da..3cf78f160846 100644 --- a/trunk/arch/sparc/kernel/setup.c +++ b/trunk/arch/sparc/kernel/setup.c @@ -65,6 +65,7 @@ struct screen_info screen_info = { */ extern unsigned long trapbase; +void (*prom_palette)(int); /* Pretty sick eh? */ void prom_sync_me(void) @@ -79,6 +80,8 @@ void prom_sync_me(void) "nop\n\t" "nop\n\t" : : "r" (&trapbase)); + if (prom_palette) + prom_palette(1); prom_printf("PROM SYNC COMMAND...\n"); show_free_areas(); if(current->pid != 0) { @@ -188,6 +191,7 @@ extern int prom_probe_memory(void); extern void sun4c_probe_vac(void); extern char cputypval; extern unsigned long start, end; +extern void panic_setup(char *, int *); extern unsigned short root_flags; extern unsigned short root_dev; diff --git a/trunk/arch/sparc/mm/sun4c.c b/trunk/arch/sparc/mm/sun4c.c index 2375fe9dc312..c0442e8c4b15 100644 --- a/trunk/arch/sparc/mm/sun4c.c +++ b/trunk/arch/sparc/mm/sun4c.c @@ -1941,7 +1941,9 @@ static pte_t *sun4c_pte_alloc_one_kernel(struct mm_struct *mm, unsigned long add if ((pte = sun4c_pte_alloc_one_fast(mm, address)) != NULL) return pte; - pte = (pte_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); + pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); + if (pte) + memset(pte, 0, PAGE_SIZE); return pte; } diff --git a/trunk/arch/sparc/prom/misc.c b/trunk/arch/sparc/prom/misc.c index d9fb3af41c1f..37cff5f54704 100644 --- a/trunk/arch/sparc/prom/misc.c +++ b/trunk/arch/sparc/prom/misc.c @@ -45,6 +45,9 @@ prom_feval(char *fstring) spin_unlock_irqrestore(&prom_lock, flags); } +/* We want to do this more nicely some day. */ +extern void (*prom_palette)(int); + /* Drop into the prom, with the chance to continue with the 'go' * prom command. */ @@ -55,6 +58,8 @@ prom_cmdline(void) extern void install_linux_ticker(void); unsigned long flags; + if (prom_palette) + prom_palette (1); spin_lock_irqsave(&prom_lock, flags); install_obp_ticker(); (*(romvec->pv_abort))(); @@ -64,6 +69,8 @@ prom_cmdline(void) #ifdef CONFIG_SUN_AUXIO set_auxio(AUXIO_LED, 0); #endif + if (prom_palette) + prom_palette (0); } /* Drop into the prom, but completely terminate the program. diff --git a/trunk/arch/sparc64/Kconfig.debug b/trunk/arch/sparc64/Kconfig.debug index 6a4d28a4076d..a5faa3683bd6 100644 --- a/trunk/arch/sparc64/Kconfig.debug +++ b/trunk/arch/sparc64/Kconfig.debug @@ -23,6 +23,10 @@ config STACK_DEBUG depends on DEBUG_KERNEL bool "Stack Overflow Detection Support" +config DEBUG_BOOTMEM + depends on DEBUG_KERNEL + bool "Debug BOOTMEM initialization" + config DEBUG_PAGEALLOC bool "Debug page memory allocations" depends on DEBUG_KERNEL && !HIBERNATION diff --git a/trunk/arch/sparc64/Makefile b/trunk/arch/sparc64/Makefile index f0c22f826982..01159cb5f16d 100644 --- a/trunk/arch/sparc64/Makefile +++ b/trunk/arch/sparc64/Makefile @@ -12,13 +12,39 @@ CHECKFLAGS += -D__sparc__ -D__sparc_v9__ -m64 CPPFLAGS_vmlinux.lds += -Usparc +CC := $(shell if $(CC) -m64 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo $(CC); else echo sparc64-linux-gcc; fi ) + +NEW_GCC := $(call cc-option-yn, -m64 -mcmodel=medlow) +NEW_GAS := $(shell if $(LD) -V 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi) +UNDECLARED_REGS := $(shell if $(CC) -c -x assembler /dev/null -Wa,--help | grep undeclared-regs > /dev/null; then echo y; else echo n; fi; ) + +ifneq ($(NEW_GAS),y) +AS = sparc64-linux-as +LD = sparc64-linux-ld +NM = sparc64-linux-nm +AR = sparc64-linux-ar +RANLIB = sparc64-linux-ranlib +else +AS := $(AS) -64 LDFLAGS := -m elf64_sparc +endif -KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \ - -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \ - -Wa,--undeclared-regs -KBUILD_CFLAGS += $(call cc-option,-mtune=ultrasparc3) -KBUILD_AFLAGS += -m64 -mcpu=ultrasparc -Wa,--undeclared-regs +ifneq ($(UNDECLARED_REGS),y) +CC_UNDECL = +else +CC_UNDECL = -Wa,--undeclared-regs +AS := $(AS) --undeclared-regs +endif + +ifneq ($(NEW_GCC),y) + KBUILD_CFLAGS += -pipe -mno-fpu -mtune=ultrasparc -mmedlow \ + -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare +else + KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \ + -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \ + $(CC_UNDECL) + KBUILD_AFLAGS += -m64 -mcpu=ultrasparc $(CC_UNDECL) +endif ifeq ($(CONFIG_MCOUNT),y) KBUILD_CFLAGS += -pg diff --git a/trunk/arch/sparc64/defconfig b/trunk/arch/sparc64/defconfig index 250958d1e3cb..833d74b2b192 100644 --- a/trunk/arch/sparc64/defconfig +++ b/trunk/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25-rc1 -# Sun Feb 17 22:44:12 2008 +# Linux kernel version: 2.6.24 +# Tue Feb 5 17:28:19 2008 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -10,7 +10,6 @@ CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_64BIT=y CONFIG_MMU=y -CONFIG_IOMMU_HELPER=y CONFIG_QUICKLIST=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y @@ -22,7 +21,6 @@ CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_OF=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_ARCH_SUPPORTS_AOUT=y CONFIG_SPARC64_PAGE_SIZE_8KB=y # CONFIG_SPARC64_PAGE_SIZE_64KB is not set # CONFIG_SPARC64_PAGE_SIZE_512KB is not set @@ -51,6 +49,8 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=18 @@ -60,11 +60,6 @@ CONFIG_FAIR_USER_SCHED=y # CONFIG_FAIR_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_RELAY=y -CONFIG_NAMESPACES=y -# CONFIG_UTS_NS is not set -# CONFIG_IPC_NS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -79,7 +74,6 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y @@ -182,13 +176,13 @@ CONFIG_PCI_MSI=y CONFIG_SUN_OPENPROMFS=m CONFIG_SPARC32_COMPAT=y CONFIG_COMPAT=y +CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_AOUT32 is not set # # Executable file formats # CONFIG_BINFMT_ELF=y -CONFIG_COMPAT_BINFMT_ELF=y CONFIG_BINFMT_MISC=m CONFIG_SOLARIS_EMUL=y CONFIG_SCHED_SMT=y @@ -360,8 +354,6 @@ CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_93CX6 is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set -# CONFIG_ENCLOSURE_SERVICES is not set -CONFIG_HAVE_IDE=y CONFIG_IDE=y CONFIG_BLK_DEV_IDE=y @@ -384,7 +376,6 @@ CONFIG_IDE_PROC_FS=y # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_PLATFORM is not set -CONFIG_BLK_DEV_IDEDMA_SFF=y # # PCI IDE chipsets support @@ -784,6 +775,7 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_TPS65010 is not set # CONFIG_SENSORS_MAX6875 is not set @@ -839,7 +831,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_ADS7828 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_VT1211 is not set @@ -849,11 +840,9 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83793 is not set # CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set -# CONFIG_THERMAL is not set # CONFIG_WATCHDOG is not set # @@ -1212,7 +1201,6 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_TEST is not set # CONFIG_USB_GADGET is not set # CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_INFINIBAND is not set # CONFIG_RTC_CLASS is not set @@ -1254,10 +1242,12 @@ CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -CONFIG_DNOTIFY=y +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -1301,10 +1291,8 @@ CONFIG_HUGETLB_PAGE=y # CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set CONFIG_NETWORK_FILESYSTEMS=y @@ -1382,7 +1370,6 @@ CONFIG_DETECT_SOFTLOCKUP=y CONFIG_SCHEDSTATS=y # CONFIG_TIMER_STATS is not set # CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_SLUB_STATS is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -1398,6 +1385,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +CONFIG_FORCED_INLINING=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_KPROBES_SANITY_TEST is not set @@ -1408,6 +1396,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_DCFLUSH is not set # CONFIG_STACK_DEBUG is not set +# CONFIG_DEBUG_BOOTMEM is not set # CONFIG_DEBUG_PAGEALLOC is not set # diff --git a/trunk/arch/sparc64/kernel/iommu.c b/trunk/arch/sparc64/kernel/iommu.c index 0e347ff812a3..d3276ebcfb47 100644 --- a/trunk/arch/sparc64/kernel/iommu.c +++ b/trunk/arch/sparc64/kernel/iommu.c @@ -200,11 +200,12 @@ int iommu_table_init(struct iommu *iommu, int tsbsize, /* Allocate and initialize the dummy page which we * set inactive IO PTEs to point to. */ - iommu->dummy_page = get_zeroed_page(GFP_KERNEL); + iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0); if (!iommu->dummy_page) { printk(KERN_ERR "IOMMU: Error, gfp(dummy_page) failed.\n"); goto out_free_map; } + memset((void *)iommu->dummy_page, 0, PAGE_SIZE); iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page); /* Now allocate and setup the IOMMU page table itself. */ diff --git a/trunk/arch/sparc64/kernel/pci.c b/trunk/arch/sparc64/kernel/pci.c index 545356b00e2e..a61c38fe75ea 100644 --- a/trunk/arch/sparc64/kernel/pci.c +++ b/trunk/arch/sparc64/kernel/pci.c @@ -225,6 +225,20 @@ static int __init pci_controller_init(const char *model_name, int namelen, struc return 0; } +static int __init pci_is_controller(const char *model_name, int namelen, struct device_node *dp) +{ + int i; + + for (i = 0; i < PCI_NUM_CONTROLLER_TYPES; i++) { + if (!strncmp(model_name, + pci_controller_table[i].model_name, + namelen)) { + return 1; + } + } + return 0; +} + static int __init pci_controller_scan(int (*handler)(const char *, int, struct device_node *)) { struct device_node *dp; @@ -259,6 +273,13 @@ static int __init pci_controller_scan(int (*handler)(const char *, int, struct d return count; } + +/* Is there some PCI controller in the system? */ +int __init pcic_present(void) +{ + return pci_controller_scan(pci_is_controller); +} + /* Find each controller in the system, attach and initialize * software state structure for each and link into the * pci_pbm_root. Setup the controller enough such diff --git a/trunk/arch/sparc64/kernel/process.c b/trunk/arch/sparc64/kernel/process.c index 6eceac51ae62..1b2379174988 100644 --- a/trunk/arch/sparc64/kernel/process.c +++ b/trunk/arch/sparc64/kernel/process.c @@ -113,9 +113,16 @@ void cpu_idle(void) extern char reboot_command []; +extern void (*prom_palette)(int); +extern void (*prom_keyboard)(void); + void machine_halt(void) { sstate_halt(); + if (prom_palette) + prom_palette (1); + if (prom_keyboard) + prom_keyboard(); prom_halt(); panic("Halt failed!"); } @@ -123,6 +130,10 @@ void machine_halt(void) void machine_alt_power_off(void) { sstate_poweroff(); + if (prom_palette) + prom_palette(1); + if (prom_keyboard) + prom_keyboard(); prom_halt_power_off(); panic("Power-off failed!"); } @@ -134,6 +145,10 @@ void machine_restart(char * cmd) sstate_reboot(); p = strchr (reboot_command, '\n'); if (p) *p = 0; + if (prom_palette) + prom_palette (1); + if (prom_keyboard) + prom_keyboard(); if (cmd) prom_reboot(cmd); if (*reboot_command) diff --git a/trunk/arch/sparc64/kernel/prom.c b/trunk/arch/sparc64/kernel/prom.c index 68964ddcde1e..a246e962e5a7 100644 --- a/trunk/arch/sparc64/kernel/prom.c +++ b/trunk/arch/sparc64/kernel/prom.c @@ -1716,6 +1716,7 @@ static void __init of_console_init(void) of_console_device = dp; + prom_printf(msg, of_console_path); printk(msg, of_console_path); } diff --git a/trunk/arch/sparc64/kernel/setup.c b/trunk/arch/sparc64/kernel/setup.c index d036dbe72864..5964d8653ade 100644 --- a/trunk/arch/sparc64/kernel/setup.c +++ b/trunk/arch/sparc64/kernel/setup.c @@ -68,22 +68,33 @@ struct screen_info screen_info = { 16 /* orig-video-points */ }; +void (*prom_palette)(int); +void (*prom_keyboard)(void); + static void prom_console_write(struct console *con, const char *s, unsigned n) { prom_write(s, n); } +unsigned int boot_flags = 0; +#define BOOTME_DEBUG 0x1 + /* Exported for mm/init.c:paging_init. */ unsigned long cmdline_memory_size = 0; -static struct console prom_early_console = { - .name = "earlyprom", +static struct console prom_debug_console = { + .name = "debug", .write = prom_console_write, - .flags = CON_PRINTBUFFER | CON_BOOT, + .flags = CON_PRINTBUFFER, .index = -1, }; +/* XXX Implement this at some point... */ +void kernel_enter_debugger(void) +{ +} + /* * Process kernel command line switches that are specific to the * SPARC or that require special low-level processing. @@ -92,6 +103,8 @@ static void __init process_switch(char c) { switch (c) { case 'd': + boot_flags |= BOOTME_DEBUG; + break; case 's': break; case 'h': @@ -99,7 +112,8 @@ static void __init process_switch(char c) prom_halt(); break; case 'p': - /* Just ignore, this behavior is now the default. */ + /* Use PROM debug console. */ + register_console(&prom_debug_console); break; case 'P': /* Force UltraSPARC-III P-Cache on. */ @@ -154,6 +168,8 @@ static void __init boot_flags_init(char *commands) } } +extern void panic_setup(char *, int *); + extern unsigned short root_flags; extern unsigned short root_dev; extern unsigned short ram_flags; @@ -280,9 +296,6 @@ void __init setup_arch(char **cmdline_p) *cmdline_p = prom_getbootargs(); strcpy(boot_command_line, *cmdline_p); - boot_flags_init(*cmdline_p); - register_console(&prom_early_console); - if (tlb_type == hypervisor) printk("ARCH: SUN4V\n"); else @@ -294,6 +307,8 @@ void __init setup_arch(char **cmdline_p) conswitchp = &prom_con; #endif + boot_flags_init(*cmdline_p); + idprom_init(); if (!root_flags) diff --git a/trunk/arch/sparc64/kernel/sparc64_ksyms.c b/trunk/arch/sparc64/kernel/sparc64_ksyms.c index 51fa773f38c9..68db08930399 100644 --- a/trunk/arch/sparc64/kernel/sparc64_ksyms.c +++ b/trunk/arch/sparc64/kernel/sparc64_ksyms.c @@ -85,6 +85,7 @@ extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *); extern long sparc32_open(const char __user * filename, int flags, int mode); extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot); +extern void (*prom_palette)(int); extern int __ashrdi3(int, int); @@ -354,3 +355,5 @@ EXPORT_SYMBOL(xor_niagara_2); EXPORT_SYMBOL(xor_niagara_3); EXPORT_SYMBOL(xor_niagara_4); EXPORT_SYMBOL(xor_niagara_5); + +EXPORT_SYMBOL(prom_palette); diff --git a/trunk/arch/sparc64/kernel/unaligned.c b/trunk/arch/sparc64/kernel/unaligned.c index 1a511e9f0d3e..dc7bf1b6321c 100644 --- a/trunk/arch/sparc64/kernel/unaligned.c +++ b/trunk/arch/sparc64/kernel/unaligned.c @@ -7,7 +7,6 @@ */ -#include #include #include #include @@ -284,7 +283,7 @@ static void log_unaligned(struct pt_regs *regs) { static unsigned long count, last_time; - if (time_after(jiffies, last_time + 5 * HZ)) + if (jiffies - last_time > 5 * HZ) count = 0; if (count < 5) { last_time = jiffies; diff --git a/trunk/arch/sparc64/mm/init.c b/trunk/arch/sparc64/mm/init.c index 9e6bca266d88..e726c45645ff 100644 --- a/trunk/arch/sparc64/mm/init.c +++ b/trunk/arch/sparc64/mm/init.c @@ -618,9 +618,9 @@ static void __init inherit_prom_mappings(void) read_obp_translations(); /* Now fixup OBP's idea about where we really are mapped. */ - printk("Remapping the kernel... "); + prom_printf("Remapping the kernel... "); remap_kernel(); - printk("done.\n"); + prom_printf("done.\n"); } void prom_world(int enter) @@ -739,6 +739,11 @@ static unsigned long __init choose_bootmap_pfn(unsigned long start_pfn, avoid_end = PAGE_ALIGN(initrd_end); #endif +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("choose_bootmap_pfn: kern[%lx:%lx] avoid[%lx:%lx]\n", + kern_base, PAGE_ALIGN(kern_base + kern_size), + avoid_start, avoid_end); +#endif for (i = 0; i < pavail_ents; i++) { unsigned long start, end; @@ -772,6 +777,10 @@ static unsigned long __init choose_bootmap_pfn(unsigned long start_pfn, } /* OK, it doesn't overlap anything, use it. */ +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("choose_bootmap_pfn: Using %lx [%lx]\n", + start >> PAGE_SHIFT, start); +#endif return start >> PAGE_SHIFT; } } @@ -911,6 +920,10 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail, unsigned long bootmap_pfn, bytes_avail, size; int i; +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("bootmem_init: Scan pavail, "); +#endif + bytes_avail = 0UL; for (i = 0; i < pavail_ents; i++) { end_of_phys_memory = pavail[i].phys_addr + @@ -957,20 +970,33 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail, bootmap_pfn = choose_bootmap_pfn(min_low_pfn, end_pfn); +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("init_bootmem(min[%lx], bootmap[%lx], max[%lx])\n", + min_low_pfn, bootmap_pfn, max_low_pfn); +#endif bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, min_low_pfn, end_pfn); /* Now register the available physical memory with the * allocator. */ - for (i = 0; i < pavail_ents; i++) + for (i = 0; i < pavail_ents; i++) { +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("free_bootmem(pavail:%d): base[%lx] size[%lx]\n", + i, pavail[i].phys_addr, pavail[i].reg_size); +#endif free_bootmem(pavail[i].phys_addr, pavail[i].reg_size); + } #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) { size = initrd_end - initrd_start; /* Reserve the initrd image area. */ +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("reserve_bootmem(initrd): base[%llx] size[%lx]\n", + initrd_start, initrd_end); +#endif reserve_bootmem(initrd_start, size, BOOTMEM_DEFAULT); initrd_start += PAGE_OFFSET; @@ -978,6 +1004,9 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail, } #endif /* Reserve the kernel text/data/bss. */ +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("reserve_bootmem(kernel): base[%lx] size[%lx]\n", kern_base, kern_size); +#endif reserve_bootmem(kern_base, kern_size, BOOTMEM_DEFAULT); *pages_avail -= PAGE_ALIGN(kern_size) >> PAGE_SHIFT; @@ -991,6 +1020,10 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail, * in free_all_bootmem. */ size = bootmap_size; +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("reserve_bootmem(bootmap): base[%lx] size[%lx]\n", + (bootmap_pfn << PAGE_SHIFT), size); +#endif reserve_bootmem((bootmap_pfn << PAGE_SHIFT), size, BOOTMEM_DEFAULT); for (i = 0; i < pavail_ents; i++) { @@ -998,6 +1031,10 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail, start_pfn = pavail[i].phys_addr >> PAGE_SHIFT; end_pfn = (start_pfn + (pavail[i].reg_size >> PAGE_SHIFT)); +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("memory_present(0, %lx, %lx)\n", + start_pfn, end_pfn); +#endif memory_present(0, start_pfn, end_pfn); } @@ -1414,7 +1451,7 @@ void __init paging_init(void) zholes_size); } - printk("Booting Linux...\n"); + prom_printf("Booting Linux...\n"); central_probe(); cpu_probe(); @@ -1512,6 +1549,10 @@ void __init mem_init(void) high_memory = __va(last_valid_pfn << PAGE_SHIFT); +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("mem_init: Calling free_all_bootmem().\n"); +#endif + /* We subtract one to account for the mem_map_zero page * allocated below. */ diff --git a/trunk/arch/sparc64/prom/misc.c b/trunk/arch/sparc64/prom/misc.c index 47a877a15abd..bbec7522826c 100644 --- a/trunk/arch/sparc64/prom/misc.c +++ b/trunk/arch/sparc64/prom/misc.c @@ -55,6 +55,9 @@ void prom_feval(const char *fstring) P1275_INOUT(1, 1), fstring); } +/* We want to do this more nicely some day. */ +extern void (*prom_palette)(int); + #ifdef CONFIG_SMP extern void smp_capture(void); extern void smp_release(void); @@ -69,6 +72,9 @@ void prom_cmdline(void) local_irq_save(flags); + if (prom_palette) + prom_palette(1); + #ifdef CONFIG_SMP smp_capture(); #endif @@ -79,6 +85,9 @@ void prom_cmdline(void) smp_release(); #endif + if (prom_palette) + prom_palette(0); + local_irq_restore(flags); } diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index 775c8516abf5..e9754dc98ec4 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -38,7 +38,7 @@ static int __make_request(struct request_queue *q, struct bio *bio); /* * For the allocated request tables */ -static struct kmem_cache *request_cachep; +struct kmem_cache *request_cachep; /* * For queue allocation @@ -127,7 +127,6 @@ void rq_init(struct request_queue *q, struct request *rq) rq->nr_hw_segments = 0; rq->ioprio = 0; rq->special = NULL; - rq->raw_data_len = 0; rq->buffer = NULL; rq->tag = -1; rq->errors = 0; @@ -2016,7 +2015,6 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq, rq->hard_cur_sectors = rq->current_nr_sectors; rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio); rq->buffer = bio_data(bio); - rq->raw_data_len = bio->bi_size; rq->data_len = bio->bi_size; rq->bio = rq->biotail = bio; diff --git a/trunk/block/blk-ioc.c b/trunk/block/blk-ioc.c index e34df7c9fc36..80245dc30c75 100644 --- a/trunk/block/blk-ioc.c +++ b/trunk/block/blk-ioc.c @@ -17,13 +17,17 @@ static struct kmem_cache *iocontext_cachep; static void cfq_dtor(struct io_context *ioc) { - if (!hlist_empty(&ioc->cic_list)) { - struct cfq_io_context *cic; + struct cfq_io_context *cic[1]; + int r; - cic = list_entry(ioc->cic_list.first, struct cfq_io_context, - cic_list); - cic->dtor(ioc); - } + /* + * We don't have a specific key to lookup with, so use the gang + * lookup to just retrieve the first item stored. The cfq exit + * function will iterate the full tree, so any member will do. + */ + r = radix_tree_gang_lookup(&ioc->radix_root, (void **) cic, 0, 1); + if (r > 0) + cic[0]->dtor(ioc); } /* @@ -53,16 +57,18 @@ EXPORT_SYMBOL(put_io_context); static void cfq_exit(struct io_context *ioc) { - rcu_read_lock(); - - if (!hlist_empty(&ioc->cic_list)) { - struct cfq_io_context *cic; + struct cfq_io_context *cic[1]; + int r; - cic = list_entry(ioc->cic_list.first, struct cfq_io_context, - cic_list); - cic->exit(ioc); - } + rcu_read_lock(); + /* + * See comment for cfq_dtor() + */ + r = radix_tree_gang_lookup(&ioc->radix_root, (void **) cic, 0, 1); rcu_read_unlock(); + + if (r > 0) + cic[0]->exit(ioc); } /* Called by the exitting task */ @@ -99,7 +105,6 @@ struct io_context *alloc_io_context(gfp_t gfp_flags, int node) ret->nr_batch_requests = 0; /* because this is 0 */ ret->aic = NULL; INIT_RADIX_TREE(&ret->radix_root, GFP_ATOMIC | __GFP_HIGH); - INIT_HLIST_HEAD(&ret->cic_list); ret->ioc_data = NULL; } @@ -171,7 +176,7 @@ void copy_io_context(struct io_context **pdst, struct io_context **psrc) } EXPORT_SYMBOL(copy_io_context); -static int __init blk_ioc_init(void) +int __init blk_ioc_init(void) { iocontext_cachep = kmem_cache_create("blkdev_ioc", sizeof(struct io_context), 0, SLAB_PANIC, NULL); diff --git a/trunk/block/blk-map.c b/trunk/block/blk-map.c index 09f7fd0bcb73..955d75c1a58f 100644 --- a/trunk/block/blk-map.c +++ b/trunk/block/blk-map.c @@ -19,7 +19,6 @@ int blk_rq_append_bio(struct request_queue *q, struct request *rq, rq->biotail->bi_next = bio; rq->biotail = bio; - rq->raw_data_len += bio->bi_size; rq->data_len += bio->bi_size; } return 0; @@ -140,29 +139,10 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq, ubuf += ret; } - /* - * __blk_rq_map_user() copies the buffers if starting address - * or length isn't aligned. As the copied buffer is always - * page aligned, we know that there's enough room for padding. - * Extend the last bio and update rq->data_len accordingly. - * - * On unmap, bio_uncopy_user() will use unmodified - * bio_map_data pointed to by bio->bi_private. - */ - if (len & queue_dma_alignment(q)) { - unsigned int pad_len = (queue_dma_alignment(q) & ~len) + 1; - struct bio *bio = rq->biotail; - - bio->bi_io_vec[bio->bi_vcnt - 1].bv_len += pad_len; - bio->bi_size += pad_len; - rq->data_len += pad_len; - } - rq->buffer = rq->data = NULL; return 0; unmap_rq: blk_rq_unmap_user(bio); - rq->bio = NULL; return ret; } EXPORT_SYMBOL(blk_rq_map_user); diff --git a/trunk/block/blk-merge.c b/trunk/block/blk-merge.c index 7506c4fe0264..d3b84bbb776a 100644 --- a/trunk/block/blk-merge.c +++ b/trunk/block/blk-merge.c @@ -220,10 +220,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq, bvprv = bvec; } /* segments in rq */ - if (q->dma_drain_size && q->dma_drain_needed(rq)) { - if (rq->cmd_flags & REQ_RW) - memset(q->dma_drain_buffer, 0, q->dma_drain_size); - + if (q->dma_drain_size) { sg->page_link &= ~0x02; sg = sg_next(sg); sg_set_page(sg, virt_to_page(q->dma_drain_buffer), @@ -231,7 +228,6 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq, ((unsigned long)q->dma_drain_buffer) & (PAGE_SIZE - 1)); nsegs++; - rq->data_len += q->dma_drain_size; } if (sg) diff --git a/trunk/block/blk-settings.c b/trunk/block/blk-settings.c index 9a8ffdd0ce3d..c8d0c5724098 100644 --- a/trunk/block/blk-settings.c +++ b/trunk/block/blk-settings.c @@ -296,7 +296,6 @@ EXPORT_SYMBOL(blk_queue_stack_limits); * blk_queue_dma_drain - Set up a drain buffer for excess dma. * * @q: the request queue for the device - * @dma_drain_needed: fn which returns non-zero if drain is necessary * @buf: physically contiguous buffer * @size: size of the buffer in bytes * @@ -316,16 +315,14 @@ EXPORT_SYMBOL(blk_queue_stack_limits); * device can support otherwise there won't be room for the drain * buffer. */ -extern int blk_queue_dma_drain(struct request_queue *q, - dma_drain_needed_fn *dma_drain_needed, - void *buf, unsigned int size) +int blk_queue_dma_drain(struct request_queue *q, void *buf, + unsigned int size) { if (q->max_hw_segments < 2 || q->max_phys_segments < 2) return -EINVAL; /* make room for appending the drain */ --q->max_hw_segments; --q->max_phys_segments; - q->dma_drain_needed = dma_drain_needed; q->dma_drain_buffer = buf; q->dma_drain_size = size; @@ -389,7 +386,7 @@ void blk_queue_update_dma_alignment(struct request_queue *q, int mask) } EXPORT_SYMBOL(blk_queue_update_dma_alignment); -static int __init blk_settings_init(void) +int __init blk_settings_init(void) { blk_max_low_pfn = max_low_pfn - 1; blk_max_pfn = max_pfn - 1; diff --git a/trunk/block/bsg.c b/trunk/block/bsg.c index 7f3c09549e4b..8917c5174dc2 100644 --- a/trunk/block/bsg.c +++ b/trunk/block/bsg.c @@ -437,14 +437,14 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, } if (rq->next_rq) { - hdr->dout_resid = rq->raw_data_len; - hdr->din_resid = rq->next_rq->raw_data_len; + hdr->dout_resid = rq->data_len; + hdr->din_resid = rq->next_rq->data_len; blk_rq_unmap_user(bidi_bio); blk_put_request(rq->next_rq); } else if (rq_data_dir(rq) == READ) - hdr->din_resid = rq->raw_data_len; + hdr->din_resid = rq->data_len; else - hdr->dout_resid = rq->raw_data_len; + hdr->dout_resid = rq->data_len; /* * If the request generated a negative error number, return it diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index 0f962ecae91f..ca198e61fa65 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -1145,19 +1145,38 @@ static void cfq_put_queue(struct cfq_queue *cfqq) /* * Call func for each cic attached to this ioc. Returns number of cic's seen. */ +#define CIC_GANG_NR 16 static unsigned int call_for_each_cic(struct io_context *ioc, void (*func)(struct io_context *, struct cfq_io_context *)) { - struct cfq_io_context *cic; - struct hlist_node *n; - int called = 0; + struct cfq_io_context *cics[CIC_GANG_NR]; + unsigned long index = 0; + unsigned int called = 0; + int nr; rcu_read_lock(); - hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list) { - func(ioc, cic); - called++; - } + + do { + int i; + + /* + * Perhaps there's a better way - this just gang lookups from + * 0 to the end, restarting after each CIC_GANG_NR from the + * last key + 1. + */ + nr = radix_tree_gang_lookup(&ioc->radix_root, (void **) cics, + index, CIC_GANG_NR); + if (!nr) + break; + + called += nr; + index = 1 + (unsigned long) cics[nr - 1]->key; + + for (i = 0; i < nr; i++) + func(ioc, cics[i]); + } while (nr == CIC_GANG_NR); + rcu_read_unlock(); return called; @@ -1171,7 +1190,6 @@ static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic) spin_lock_irqsave(&ioc->lock, flags); radix_tree_delete(&ioc->radix_root, cic->dead_key); - hlist_del_rcu(&cic->cic_list); spin_unlock_irqrestore(&ioc->lock, flags); kmem_cache_free(cfq_ioc_pool, cic); @@ -1262,7 +1280,6 @@ cfq_alloc_io_context(struct cfq_data *cfqd, gfp_t gfp_mask) if (cic) { cic->last_end_request = jiffies; INIT_LIST_HEAD(&cic->queue_list); - INIT_HLIST_NODE(&cic->cic_list); cic->dtor = cfq_free_io_context; cic->exit = cfq_exit_io_context; elv_ioc_count_inc(ioc_count); @@ -1484,7 +1501,6 @@ cfq_drop_dead_cic(struct cfq_data *cfqd, struct io_context *ioc, rcu_assign_pointer(ioc->ioc_data, NULL); radix_tree_delete(&ioc->radix_root, (unsigned long) cfqd); - hlist_del_rcu(&cic->cic_list); spin_unlock_irqrestore(&ioc->lock, flags); cfq_cic_free(cic); @@ -1545,8 +1561,6 @@ static int cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc, spin_lock_irqsave(&ioc->lock, flags); ret = radix_tree_insert(&ioc->radix_root, (unsigned long) cfqd, cic); - if (!ret) - hlist_add_head_rcu(&cic->cic_list, &ioc->cic_list); spin_unlock_irqrestore(&ioc->lock, flags); radix_tree_preload_end(); diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index 88318c383608..bafbae0344d3 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -134,21 +134,6 @@ static struct elevator_type *elevator_get(const char *name) spin_lock(&elv_list_lock); e = elevator_find(name); - if (!e) { - char elv[ELV_NAME_MAX + strlen("-iosched")]; - - spin_unlock(&elv_list_lock); - - if (!strcmp(name, "anticipatory")) - sprintf(elv, "as-iosched"); - else - sprintf(elv, "%s-iosched", name); - - request_module(elv); - spin_lock(&elv_list_lock); - e = elevator_find(name); - } - if (e && !try_module_get(e->elevator_owner)) e = NULL; diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index e993cac4911d..9675b34638d4 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -266,7 +266,7 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, hdr->info = 0; if (hdr->masked_status || hdr->host_status || hdr->driver_status) hdr->info |= SG_INFO_CHECK; - hdr->resid = rq->raw_data_len; + hdr->resid = rq->data_len; hdr->sb_len_wr = 0; if (rq->sense_len && hdr->sbp) { @@ -528,7 +528,6 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk, rq = blk_get_request(q, WRITE, __GFP_WAIT); rq->cmd_type = REQ_TYPE_BLOCK_PC; rq->data = NULL; - rq->raw_data_len = 0; rq->data_len = 0; rq->timeout = BLK_DEFAULT_SG_TIMEOUT; memset(rq->cmd, 0, sizeof(rq->cmd)); diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index 3c06e457b4dc..29e71bddd6ff 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -1975,11 +1975,16 @@ static int ahci_port_start(struct ata_port *ap) struct ahci_port_priv *pp; void *mem; dma_addr_t mem_dma; + int rc; pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); if (!pp) return -ENOMEM; + rc = ata_pad_alloc(ap, dev); + if (rc) + return rc; + mem = dmam_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); if (!mem) diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index def3682f416a..f46eb6f6dc9f 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -4493,13 +4493,30 @@ void ata_sg_clean(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; struct scatterlist *sg = qc->sg; int dir = qc->dma_dir; + void *pad_buf = NULL; WARN_ON(sg == NULL); - VPRINTK("unmapping %u sg elements\n", qc->n_elem); + VPRINTK("unmapping %u sg elements\n", qc->mapped_n_elem); - if (qc->n_elem) - dma_unmap_sg(ap->dev, sg, qc->n_elem, dir); + /* if we padded the buffer out to 32-bit bound, and data + * xfer direction is from-device, we must copy from the + * pad buffer back into the supplied buffer + */ + if (qc->pad_len && !(qc->tf.flags & ATA_TFLAG_WRITE)) + pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); + + if (qc->mapped_n_elem) + dma_unmap_sg(ap->dev, sg, qc->mapped_n_elem, dir); + /* restore last sg */ + if (qc->last_sg) + *qc->last_sg = qc->saved_last_sg; + if (pad_buf) { + struct scatterlist *psg = &qc->extra_sg[1]; + void *addr = kmap_atomic(sg_page(psg), KM_IRQ0); + memcpy(addr + psg->offset, pad_buf, qc->pad_len); + kunmap_atomic(addr, KM_IRQ0); + } qc->flags &= ~ATA_QCFLAG_DMAMAP; qc->sg = NULL; @@ -4641,6 +4658,43 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc) return 0; } +/** + * atapi_qc_may_overflow - Check whether data transfer may overflow + * @qc: ATA command in question + * + * ATAPI commands which transfer variable length data to host + * might overflow due to application error or hardare bug. This + * function checks whether overflow should be drained and ignored + * for @qc. + * + * LOCKING: + * None. + * + * RETURNS: + * 1 if @qc may overflow; otherwise, 0. + */ +static int atapi_qc_may_overflow(struct ata_queued_cmd *qc) +{ + if (qc->tf.protocol != ATAPI_PROT_PIO && + qc->tf.protocol != ATAPI_PROT_DMA) + return 0; + + if (qc->tf.flags & ATA_TFLAG_WRITE) + return 0; + + switch (qc->cdb[0]) { + case READ_10: + case READ_12: + case WRITE_10: + case WRITE_12: + case GPCMD_READ_CD: + case GPCMD_READ_CD_MSF: + return 0; + } + + return 1; +} + /** * ata_std_qc_defer - Check whether a qc needs to be deferred * @qc: ATA command in question @@ -4728,6 +4782,97 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, qc->cursg = qc->sg; } +static unsigned int ata_sg_setup_extra(struct ata_queued_cmd *qc, + unsigned int *n_elem_extra, + unsigned int *nbytes_extra) +{ + struct ata_port *ap = qc->ap; + unsigned int n_elem = qc->n_elem; + struct scatterlist *lsg, *copy_lsg = NULL, *tsg = NULL, *esg = NULL; + + *n_elem_extra = 0; + *nbytes_extra = 0; + + /* needs padding? */ + qc->pad_len = qc->nbytes & 3; + + if (likely(!qc->pad_len)) + return n_elem; + + /* locate last sg and save it */ + lsg = sg_last(qc->sg, n_elem); + qc->last_sg = lsg; + qc->saved_last_sg = *lsg; + + sg_init_table(qc->extra_sg, ARRAY_SIZE(qc->extra_sg)); + + if (qc->pad_len) { + struct scatterlist *psg = &qc->extra_sg[1]; + void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); + unsigned int offset; + + WARN_ON(qc->dev->class != ATA_DEV_ATAPI); + + memset(pad_buf, 0, ATA_DMA_PAD_SZ); + + /* psg->page/offset are used to copy to-be-written + * data in this function or read data in ata_sg_clean. + */ + offset = lsg->offset + lsg->length - qc->pad_len; + sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT), + qc->pad_len, offset_in_page(offset)); + + if (qc->tf.flags & ATA_TFLAG_WRITE) { + void *addr = kmap_atomic(sg_page(psg), KM_IRQ0); + memcpy(pad_buf, addr + psg->offset, qc->pad_len); + kunmap_atomic(addr, KM_IRQ0); + } + + sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ); + sg_dma_len(psg) = ATA_DMA_PAD_SZ; + + /* Trim the last sg entry and chain the original and + * padding sg lists. + * + * Because chaining consumes one sg entry, one extra + * sg entry is allocated and the last sg entry is + * copied to it if the length isn't zero after padded + * amount is removed. + * + * If the last sg entry is completely replaced by + * padding sg entry, the first sg entry is skipped + * while chaining. + */ + lsg->length -= qc->pad_len; + if (lsg->length) { + copy_lsg = &qc->extra_sg[0]; + tsg = &qc->extra_sg[0]; + } else { + n_elem--; + tsg = &qc->extra_sg[1]; + } + + esg = &qc->extra_sg[1]; + + (*n_elem_extra)++; + (*nbytes_extra) += 4 - qc->pad_len; + } + + if (copy_lsg) + sg_set_page(copy_lsg, sg_page(lsg), lsg->length, lsg->offset); + + sg_chain(lsg, 1, tsg); + sg_mark_end(esg); + + /* sglist can't start with chaining sg entry, fast forward */ + if (qc->sg == lsg) { + qc->sg = tsg; + qc->cursg = tsg; + } + + return n_elem; +} + /** * ata_sg_setup - DMA-map the scatter-gather table associated with a command. * @qc: Command with scatter-gather table to be mapped. @@ -4744,17 +4889,26 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, static int ata_sg_setup(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - unsigned int n_elem; + unsigned int n_elem, n_elem_extra, nbytes_extra; VPRINTK("ENTER, ata%u\n", ap->print_id); - n_elem = dma_map_sg(ap->dev, qc->sg, qc->n_elem, qc->dma_dir); - if (n_elem < 1) - return -1; + n_elem = ata_sg_setup_extra(qc, &n_elem_extra, &nbytes_extra); - DPRINTK("%d sg elements mapped\n", n_elem); + if (n_elem) { + n_elem = dma_map_sg(ap->dev, qc->sg, n_elem, qc->dma_dir); + if (n_elem < 1) { + /* restore last sg */ + if (qc->last_sg) + *qc->last_sg = qc->saved_last_sg; + return -1; + } + DPRINTK("%d sg elements mapped\n", n_elem); + } - qc->n_elem = n_elem; + qc->n_elem = qc->mapped_n_elem = n_elem; + qc->n_elem += n_elem_extra; + qc->nbytes += nbytes_extra; qc->flags |= ATA_QCFLAG_DMAMAP; return 0; @@ -4992,22 +5146,46 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc) */ static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) { - int rw = (qc->tf.flags & ATA_TFLAG_WRITE) ? WRITE : READ; + int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); struct ata_port *ap = qc->ap; - struct ata_device *dev = qc->dev; - struct ata_eh_info *ehi = &dev->link->eh_info; + struct ata_eh_info *ehi = &qc->dev->link->eh_info; struct scatterlist *sg; struct page *page; unsigned char *buf; - unsigned int offset, count, consumed; + unsigned int offset, count; next_sg: sg = qc->cursg; if (unlikely(!sg)) { - ata_ehi_push_desc(ehi, "unexpected or too much trailing data " - "buf=%u cur=%u bytes=%u", - qc->nbytes, qc->curbytes, bytes); - return -1; + /* + * The end of qc->sg is reached and the device expects + * more data to transfer. In order not to overrun qc->sg + * and fulfill length specified in the byte count register, + * - for read case, discard trailing data from the device + * - for write case, padding zero data to the device + */ + u16 pad_buf[1] = { 0 }; + unsigned int i; + + if (bytes > qc->curbytes - qc->nbytes + ATAPI_MAX_DRAIN) { + ata_ehi_push_desc(ehi, "too much trailing data " + "buf=%u cur=%u bytes=%u", + qc->nbytes, qc->curbytes, bytes); + return -1; + } + + /* overflow is exptected for misc ATAPI commands */ + if (bytes && !atapi_qc_may_overflow(qc)) + ata_dev_printk(qc->dev, KERN_WARNING, "ATAPI %u bytes " + "trailing data (cdb=%02x nbytes=%u)\n", + bytes, qc->cdb[0], qc->nbytes); + + for (i = 0; i < (bytes + 1) / 2; i++) + ap->ops->data_xfer(qc->dev, (unsigned char *)pad_buf, 2, do_write); + + qc->curbytes += bytes; + + return 0; } page = sg_page(sg); @@ -5033,16 +5211,18 @@ static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) buf = kmap_atomic(page, KM_IRQ0); /* do the actual data transfer */ - consumed = ap->ops->data_xfer(dev, buf + offset, count, rw); + ap->ops->data_xfer(qc->dev, buf + offset, count, do_write); kunmap_atomic(buf, KM_IRQ0); local_irq_restore(flags); } else { buf = page_address(page); - consumed = ap->ops->data_xfer(dev, buf + offset, count, rw); + ap->ops->data_xfer(qc->dev, buf + offset, count, do_write); } - bytes -= min(bytes, consumed); + bytes -= count; + if ((count & 1) && bytes) + bytes--; qc->curbytes += count; qc->cursg_ofs += count; @@ -5051,11 +5231,9 @@ static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) qc->cursg_ofs = 0; } - /* consumed can be larger than count only for the last transfer */ - WARN_ON(qc->cursg && count != consumed); - if (bytes) goto next_sg; + return 0; } @@ -5073,7 +5251,6 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct ata_device *dev = qc->dev; - struct ata_eh_info *ehi = &dev->link->eh_info; unsigned int ireason, bc_lo, bc_hi, bytes; int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0; @@ -5091,28 +5268,26 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) /* shall be cleared to zero, indicating xfer of data */ if (unlikely(ireason & (1 << 0))) - goto atapi_check; + goto err_out; /* make sure transfer direction matches expected */ i_write = ((ireason & (1 << 1)) == 0) ? 1 : 0; if (unlikely(do_write != i_write)) - goto atapi_check; + goto err_out; if (unlikely(!bytes)) - goto atapi_check; + goto err_out; VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes); - if (unlikely(__atapi_pio_bytes(qc, bytes))) + if (__atapi_pio_bytes(qc, bytes)) goto err_out; ata_altstatus(ap); /* flush */ return; - atapi_check: - ata_ehi_push_desc(ehi, "ATAPI check failed (ireason=0x%x bytes=%u)", - ireason, bytes); - err_out: +err_out: + ata_dev_printk(dev, KERN_INFO, "ATAPI check failed\n"); qc->err_mask |= AC_ERR_HSM; ap->hsm_task_state = HSM_ST_ERR; } @@ -5797,6 +5972,9 @@ void ata_qc_issue(struct ata_queued_cmd *qc) */ BUG_ON(ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes)); + /* ata_sg_setup() may update nbytes */ + qc->raw_nbytes = qc->nbytes; + if (ata_is_dma(prot) || (ata_is_pio(prot) && (ap->flags & ATA_FLAG_PIO_DMA))) if (ata_sg_setup(qc)) @@ -6405,12 +6583,19 @@ void ata_host_resume(struct ata_host *host) int ata_port_start(struct ata_port *ap) { struct device *dev = ap->dev; + int rc; ap->prd = dmam_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL); if (!ap->prd) return -ENOMEM; + rc = ata_pad_alloc(ap, dev); + if (rc) + return rc; + + DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd, + (unsigned long long)ap->prd_dma); return 0; } diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index dd41b1a1b304..1cea18f62abc 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -826,61 +826,30 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev) sdev->max_device_blocked = 1; } -/** - * atapi_drain_needed - Check whether data transfer may overflow - * @request: request to be checked - * - * ATAPI commands which transfer variable length data to host - * might overflow due to application error or hardare bug. This - * function checks whether overflow should be drained and ignored - * for @request. - * - * LOCKING: - * None. - * - * RETURNS: - * 1 if ; otherwise, 0. - */ -static int atapi_drain_needed(struct request *rq) -{ - if (likely(!blk_pc_request(rq))) - return 0; - - if (!rq->data_len || (rq->cmd_flags & REQ_RW)) - return 0; - - return atapi_cmd_type(rq->cmd[0]) == ATAPI_MISC; -} - -static int ata_scsi_dev_config(struct scsi_device *sdev, - struct ata_device *dev) +static void ata_scsi_dev_config(struct scsi_device *sdev, + struct ata_device *dev) { /* configure max sectors */ blk_queue_max_sectors(sdev->request_queue, dev->max_sectors); + /* SATA DMA transfers must be multiples of 4 byte, so + * we need to pad ATAPI transfers using an extra sg. + * Decrement max hw segments accordingly. + */ if (dev->class == ATA_DEV_ATAPI) { struct request_queue *q = sdev->request_queue; - void *buf; + blk_queue_max_hw_segments(q, q->max_hw_segments - 1); /* set the min alignment */ blk_queue_update_dma_alignment(sdev->request_queue, ATA_DMA_PAD_SZ - 1); - - /* configure draining */ - buf = kmalloc(ATAPI_MAX_DRAIN, q->bounce_gfp | GFP_KERNEL); - if (!buf) { - ata_dev_printk(dev, KERN_ERR, - "drain buffer allocation failed\n"); - return -ENOMEM; - } - - blk_queue_dma_drain(q, atapi_drain_needed, buf, ATAPI_MAX_DRAIN); - } else { + } else /* ATA devices must be sector aligned */ blk_queue_update_dma_alignment(sdev->request_queue, ATA_SECT_SIZE - 1); + + if (dev->class == ATA_DEV_ATA) sdev->manage_start_stop = 1; - } if (dev->flags & ATA_DFLAG_AN) set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events); @@ -892,8 +861,6 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, depth = min(ATA_MAX_QUEUE - 1, depth); scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth); } - - return 0; } /** @@ -912,14 +879,13 @@ int ata_scsi_slave_config(struct scsi_device *sdev) { struct ata_port *ap = ata_shost_to_port(sdev->host); struct ata_device *dev = __ata_scsi_find_dev(ap, sdev); - int rc = 0; ata_scsi_sdev_config(sdev); if (dev) - rc = ata_scsi_dev_config(sdev, dev); + ata_scsi_dev_config(sdev, dev); - return rc; + return 0; } /** @@ -939,7 +905,6 @@ int ata_scsi_slave_config(struct scsi_device *sdev) void ata_scsi_slave_destroy(struct scsi_device *sdev) { struct ata_port *ap = ata_shost_to_port(sdev->host); - struct request_queue *q = sdev->request_queue; unsigned long flags; struct ata_device *dev; @@ -955,10 +920,6 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) ata_port_schedule_eh(ap); } spin_unlock_irqrestore(ap->lock, flags); - - kfree(q->dma_drain_buffer); - q->dma_drain_buffer = NULL; - q->dma_drain_size = 0; } /** @@ -2539,7 +2500,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) * want to set it properly, and for DMA where it is * effectively meaningless. */ - nbytes = min(scmd->request->raw_data_len, (unsigned int)63 * 1024); + nbytes = min(qc->nbytes, (unsigned int)63 * 1024); /* Most ATAPI devices which honor transfer chunk size don't * behave according to the spec when odd chunk size which @@ -3594,7 +3555,7 @@ EXPORT_SYMBOL_GPL(ata_sas_port_alloc); * @ap: Port to initialize * * Called just after data structures for each port are - * initialized. + * initialized. Allocates DMA pad. * * May be used as the port_start() entry in ata_port_operations. * @@ -3603,7 +3564,7 @@ EXPORT_SYMBOL_GPL(ata_sas_port_alloc); */ int ata_sas_port_start(struct ata_port *ap) { - return 0; + return ata_pad_alloc(ap, ap->dev); } EXPORT_SYMBOL_GPL(ata_sas_port_start); @@ -3611,6 +3572,8 @@ EXPORT_SYMBOL_GPL(ata_sas_port_start); * ata_port_stop - Undo ata_sas_port_start() * @ap: Port to shut down * + * Frees the DMA pad. + * * May be used as the port_stop() entry in ata_port_operations. * * LOCKING: @@ -3619,6 +3582,7 @@ EXPORT_SYMBOL_GPL(ata_sas_port_start); void ata_sas_port_stop(struct ata_port *ap) { + ata_pad_free(ap, ap->dev); } EXPORT_SYMBOL_GPL(ata_sas_port_stop); diff --git a/trunk/drivers/ata/pata_icside.c b/trunk/drivers/ata/pata_icside.c index f97068be2d79..5b8586dac63b 100644 --- a/trunk/drivers/ata/pata_icside.c +++ b/trunk/drivers/ata/pata_icside.c @@ -304,6 +304,12 @@ static int icside_dma_init(struct pata_icside_info *info) } +static int pata_icside_port_start(struct ata_port *ap) +{ + /* No PRD to alloc */ + return ata_pad_alloc(ap, ap->dev); +} + static struct scsi_host_template pata_icside_sht = { .module = THIS_MODULE, .name = DRV_NAME, @@ -383,6 +389,8 @@ static struct ata_port_operations pata_icside_port_ops = { .irq_clear = ata_dummy_noret, .irq_on = ata_irq_on, + .port_start = pata_icside_port_start, + .bmdma_stop = pata_icside_bmdma_stop, .bmdma_status = pata_icside_bmdma_status, }; diff --git a/trunk/drivers/ata/sata_fsl.c b/trunk/drivers/ata/sata_fsl.c index 9323dd0c7d8d..efcb66b6ccef 100644 --- a/trunk/drivers/ata/sata_fsl.c +++ b/trunk/drivers/ata/sata_fsl.c @@ -601,9 +601,21 @@ static int sata_fsl_port_start(struct ata_port *ap) if (!pp) return -ENOMEM; + /* + * allocate per command dma alignment pad buffer, which is used + * internally by libATA to ensure that all transfers ending on + * unaligned boundaries are padded, to align on Dword boundaries + */ + retval = ata_pad_alloc(ap, dev); + if (retval) { + kfree(pp); + return retval; + } + mem = dma_alloc_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); if (!mem) { + ata_pad_free(ap, dev); kfree(pp); return -ENOMEM; } @@ -682,6 +694,7 @@ static void sata_fsl_port_stop(struct ata_port *ap) dma_free_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ, pp->cmdslot, pp->cmdslot_paddr); + ata_pad_free(ap, dev); kfree(pp); } diff --git a/trunk/drivers/ata/sata_mv.c b/trunk/drivers/ata/sata_mv.c index 1c1fbf375d9a..2ecd44db4142 100644 --- a/trunk/drivers/ata/sata_mv.c +++ b/trunk/drivers/ata/sata_mv.c @@ -1158,13 +1158,17 @@ static int mv_port_start(struct ata_port *ap) struct mv_port_priv *pp; void __iomem *port_mmio = mv_ap_base(ap); unsigned long flags; - int tag; + int tag, rc; pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); if (!pp) return -ENOMEM; ap->private_data = pp; + rc = ata_pad_alloc(ap, dev); + if (rc) + return rc; + pp->crqb = dma_pool_alloc(hpriv->crqb_pool, GFP_KERNEL, &pp->crqb_dma); if (!pp->crqb) return -ENOMEM; diff --git a/trunk/drivers/ata/sata_sil24.c b/trunk/drivers/ata/sata_sil24.c index df7988df7908..b4b1f91ea693 100644 --- a/trunk/drivers/ata/sata_sil24.c +++ b/trunk/drivers/ata/sata_sil24.c @@ -1234,6 +1234,7 @@ static int sil24_port_start(struct ata_port *ap) union sil24_cmd_block *cb; size_t cb_size = sizeof(*cb) * SIL24_MAX_CMDS; dma_addr_t cb_dma; + int rc; pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); if (!pp) @@ -1246,6 +1247,10 @@ static int sil24_port_start(struct ata_port *ap) return -ENOMEM; memset(cb, 0, cb_size); + rc = ata_pad_alloc(ap, dev); + if (rc) + return rc; + pp->cmd_block = cb; pp->cmd_block_dma = cb_dma; diff --git a/trunk/drivers/net/e1000/e1000_ethtool.c b/trunk/drivers/net/e1000/e1000_ethtool.c index 85e66f4c7886..d876787ce336 100644 --- a/trunk/drivers/net/e1000/e1000_ethtool.c +++ b/trunk/drivers/net/e1000/e1000_ethtool.c @@ -50,7 +50,7 @@ struct e1000_stats { int stat_offset; }; -#define E1000_STAT(m) FIELD_SIZEOF(struct e1000_adapter, m), \ +#define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \ offsetof(struct e1000_adapter, m) static const struct e1000_stats e1000_gstrings_stats[] = { { "rx_packets", E1000_STAT(stats.gprc) }, diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index 0991648c53dc..d4ee8ec34b56 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -1195,14 +1195,6 @@ e1000_probe(struct pci_dev *pdev, printk("%s\n", print_mac(mac, netdev->dev_addr)); - if (adapter->hw.bus_type == e1000_bus_type_pci_express) { - DPRINTK(PROBE, WARNING, "This device (id %04x:%04x) will no " - "longer be supported by this driver in the future.\n", - pdev->vendor, pdev->device); - DPRINTK(PROBE, WARNING, "please use the \"e1000e\" " - "driver instead.\n"); - } - /* reset the hardware with the new settings */ e1000_reset(adapter); diff --git a/trunk/drivers/net/e1000e/netdev.c b/trunk/drivers/net/e1000e/netdev.c index 3031d6d16247..f58f017ee47a 100644 --- a/trunk/drivers/net/e1000e/netdev.c +++ b/trunk/drivers/net/e1000e/netdev.c @@ -1055,6 +1055,23 @@ static void e1000_release_hw_control(struct e1000_adapter *adapter) } } +static void e1000_release_manageability(struct e1000_adapter *adapter) +{ + if (adapter->flags & FLAG_MNG_PT_ENABLED) { + struct e1000_hw *hw = &adapter->hw; + + u32 manc = er32(MANC); + + /* re-enable hardware interception of ARP */ + manc |= E1000_MANC_ARP_EN; + manc &= ~E1000_MANC_EN_MNG2HOST; + + /* don't explicitly have to mess with MANC2H since + * MANC has an enable disable that gates MANC2H */ + ew32(MANC, manc); + } +} + /** * @e1000_alloc_ring - allocate memory for a ring structure **/ @@ -1544,6 +1561,9 @@ static void e1000_init_manageability(struct e1000_adapter *adapter) manc = er32(MANC); + /* disable hardware interception of ARP */ + manc &= ~(E1000_MANC_ARP_EN); + /* enable receiving management packets to the host. this will probably * generate destination unreachable messages from the host OS, but * the packets will be handled on SMBUS */ @@ -1670,9 +1690,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) else rctl |= E1000_RCTL_LPE; - /* Enable hardware CRC frame stripping */ - rctl |= E1000_RCTL_SECRC; - /* Setup buffer sizes */ rctl &= ~E1000_RCTL_SZ_4096; rctl |= E1000_RCTL_BSEX; @@ -1738,6 +1755,9 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) /* Enable Packet split descriptors */ rctl |= E1000_RCTL_DTYP_PS; + + /* Enable hardware CRC frame stripping */ + rctl |= E1000_RCTL_SECRC; psrctl |= adapter->rx_ps_bsize0 >> E1000_PSRCTL_BSIZE0_SHIFT; @@ -1988,7 +2008,7 @@ static void e1000_power_down_phy(struct e1000_adapter *adapter) u16 mii_reg; /* WoL is enabled */ - if (adapter->wol) + if (!adapter->wol) return; /* non-copper PHY? */ @@ -2120,6 +2140,8 @@ void e1000e_reset(struct e1000_adapter *adapter) phy_data &= ~IGP02E1000_PM_SPD; e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, phy_data); } + + e1000_release_manageability(adapter); } int e1000e_up(struct e1000_adapter *adapter) @@ -3465,6 +3487,8 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) pci_enable_wake(pdev, PCI_D3cold, 0); } + e1000_release_manageability(adapter); + /* make sure adapter isn't asleep if manageability is enabled */ if (adapter->flags & FLAG_MNG_PT_ENABLED) { pci_enable_wake(pdev, PCI_D3hot, 1); @@ -4030,6 +4054,8 @@ static void __devexit e1000_remove(struct pci_dev *pdev) flush_scheduled_work(); + e1000_release_manageability(adapter); + /* Release control of h/w to f/w. If f/w is AMT enabled, this * would have already happened in close and is redundant. */ e1000_release_hw_control(adapter); diff --git a/trunk/drivers/net/gianfar.c b/trunk/drivers/net/gianfar.c index 4244fc282f21..0431e9ed0fac 100644 --- a/trunk/drivers/net/gianfar.c +++ b/trunk/drivers/net/gianfar.c @@ -130,8 +130,8 @@ static void free_skb_resources(struct gfar_private *priv); static void gfar_set_multi(struct net_device *dev); static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr); static void gfar_configure_serdes(struct net_device *dev); -extern int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, int regnum, u16 value); -extern int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum); +extern int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id, int regnum, u16 value); +extern int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum); #ifdef CONFIG_GFAR_NAPI static int gfar_poll(struct napi_struct *napi, int budget); #endif diff --git a/trunk/drivers/net/gianfar_mii.c b/trunk/drivers/net/gianfar_mii.c index 24327629bf03..6a647d95e6ea 100644 --- a/trunk/drivers/net/gianfar_mii.c +++ b/trunk/drivers/net/gianfar_mii.c @@ -51,7 +51,7 @@ * the local mdio pins, which may not be the same as system mdio bus, used for * controlling the external PHYs, for example. */ -int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, +int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id, int regnum, u16 value) { /* Set the PHY address and the register address we want to write */ @@ -77,7 +77,7 @@ int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, * and are always tied to the local mdio pins, which may not be the * same as system mdio bus, used for controlling the external PHYs, for eg. */ -int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum) +int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum) { u16 value; diff --git a/trunk/drivers/net/hamradio/mkiss.c b/trunk/drivers/net/hamradio/mkiss.c index 30c9b3b0d131..cfcd15af501e 100644 --- a/trunk/drivers/net/hamradio/mkiss.c +++ b/trunk/drivers/net/hamradio/mkiss.c @@ -289,6 +289,7 @@ static void ax_bump(struct mkiss *ax) *ax->rbuff &= ~0x20; } } + spin_unlock_bh(&ax->buflock); count = ax->rcount; @@ -296,17 +297,17 @@ static void ax_bump(struct mkiss *ax) printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n", ax->dev->name); ax->stats.rx_dropped++; - spin_unlock_bh(&ax->buflock); return; } + spin_lock_bh(&ax->buflock); memcpy(skb_put(skb,count), ax->rbuff, count); + spin_unlock_bh(&ax->buflock); skb->protocol = ax25_type_trans(skb, ax->dev); netif_rx(skb); ax->dev->last_rx = jiffies; ax->stats.rx_packets++; ax->stats.rx_bytes += count; - spin_unlock_bh(&ax->buflock); } static void kiss_unesc(struct mkiss *ax, unsigned char s) diff --git a/trunk/drivers/net/igb/igb_ethtool.c b/trunk/drivers/net/igb/igb_ethtool.c index 0447f9bcd27a..f69721e4eaa1 100644 --- a/trunk/drivers/net/igb/igb_ethtool.c +++ b/trunk/drivers/net/igb/igb_ethtool.c @@ -43,7 +43,7 @@ struct igb_stats { int stat_offset; }; -#define IGB_STAT(m) FIELD_SIZEOF(struct igb_adapter, m), \ +#define IGB_STAT(m) sizeof(((struct igb_adapter *)0)->m), \ offsetof(struct igb_adapter, m) static const struct igb_stats igb_gstrings_stats[] = { { "rx_packets", IGB_STAT(stats.gprc) }, diff --git a/trunk/drivers/net/igb/igb_main.c b/trunk/drivers/net/igb/igb_main.c index bff280eff5e3..d4eb8e2d8720 100644 --- a/trunk/drivers/net/igb/igb_main.c +++ b/trunk/drivers/net/igb/igb_main.c @@ -606,6 +606,9 @@ static void igb_init_manageability(struct igb_adapter *adapter) u32 manc2h = rd32(E1000_MANC2H); u32 manc = rd32(E1000_MANC); + /* disable hardware interception of ARP */ + manc &= ~(E1000_MANC_ARP_EN); + /* enable receiving management packets to the host */ /* this will probably generate destination unreachable messages * from the host OS, but the packets will be handled on SMBUS */ @@ -620,6 +623,25 @@ static void igb_init_manageability(struct igb_adapter *adapter) } } +static void igb_release_manageability(struct igb_adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + + if (adapter->en_mng_pt) { + u32 manc = rd32(E1000_MANC); + + /* re-enable hardware interception of ARP */ + manc |= E1000_MANC_ARP_EN; + manc &= ~E1000_MANC_EN_MNG2HOST; + + /* don't explicitly have to mess with MANC2H since + * MANC has an enable disable that gates MANC2H */ + + /* XXX stop the hardware watchdog ? */ + wr32(E1000_MANC, manc); + } +} + /** * igb_configure - configure the hardware for RX and TX * @adapter: private board structure @@ -822,6 +844,7 @@ void igb_reset(struct igb_adapter *adapter) igb_reset_adaptive(&adapter->hw); adapter->hw.phy.ops.get_phy_info(&adapter->hw); + igb_release_manageability(adapter); } /** @@ -1155,6 +1178,9 @@ static void __devexit igb_remove(struct pci_dev *pdev) flush_scheduled_work(); + + igb_release_manageability(adapter); + /* Release control of h/w to f/w. If f/w is AMT enabled, this * would have already happened in close and is redundant. */ igb_release_hw_control(adapter); @@ -3929,6 +3955,8 @@ static int igb_suspend(struct pci_dev *pdev, pm_message_t state) pci_enable_wake(pdev, PCI_D3cold, 0); } + igb_release_manageability(adapter); + /* make sure adapter isn't asleep if manageability is enabled */ if (adapter->en_mng_pt) { pci_enable_wake(pdev, PCI_D3hot, 1); diff --git a/trunk/drivers/net/ixgb/ixgb_ethtool.c b/trunk/drivers/net/ixgb/ixgb_ethtool.c index 53a9fd086f96..a267dd862520 100644 --- a/trunk/drivers/net/ixgb/ixgb_ethtool.c +++ b/trunk/drivers/net/ixgb/ixgb_ethtool.c @@ -49,7 +49,7 @@ struct ixgb_stats { int stat_offset; }; -#define IXGB_STAT(m) FIELD_SIZEOF(struct ixgb_adapter, m), \ +#define IXGB_STAT(m) sizeof(((struct ixgb_adapter *)0)->m), \ offsetof(struct ixgb_adapter, m) static struct ixgb_stats ixgb_gstrings_stats[] = { {"rx_packets", IXGB_STAT(net_stats.rx_packets)}, diff --git a/trunk/drivers/net/ixgbe/ixgbe_main.c b/trunk/drivers/net/ixgbe/ixgbe_main.c index 23d0a4afe0e1..ead49e54f31b 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ixgbe/ixgbe_main.c @@ -220,6 +220,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter, tx_ring->stats.bytes += tx_buffer_info->length; if (cleaned) { struct sk_buff *skb = tx_buffer_info->skb; +#ifdef NETIF_F_TSO unsigned int segs, bytecount; segs = skb_shinfo(skb)->gso_segs ?: 1; /* multiply data chunks by size of headers */ @@ -227,6 +228,10 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter, skb->len; total_tx_packets += segs; total_tx_bytes += bytecount; +#else + total_tx_packets++; + total_tx_bytes += skb->len; +#endif } ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); @@ -1937,10 +1942,6 @@ static int ixgbe_open(struct net_device *netdev) int err; u32 num_rx_queues = adapter->num_rx_queues; - /* disallow open during test */ - if (test_bit(__IXGBE_TESTING, &adapter->state)) - return -EBUSY; - try_intr_reinit: /* allocate transmit descriptors */ err = ixgbe_setup_all_tx_resources(adapter); @@ -2277,29 +2278,11 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, IXGBE_ADVTXD_DTYP_CTXT); if (skb->ip_summed == CHECKSUM_PARTIAL) { - switch (skb->protocol) { - case __constant_htons(ETH_P_IP): + if (skb->protocol == htons(ETH_P_IP)) type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4; - if (ip_hdr(skb)->protocol == IPPROTO_TCP) - type_tucmd_mlhl |= - IXGBE_ADVTXD_TUCMD_L4T_TCP; - break; - - case __constant_htons(ETH_P_IPV6): - /* XXX what about other V6 headers?? */ - if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) - type_tucmd_mlhl |= - IXGBE_ADVTXD_TUCMD_L4T_TCP; - break; - default: - if (unlikely(net_ratelimit())) { - DPRINTK(PROBE, WARNING, - "partial checksum but proto=%x!\n", - skb->protocol); - } - break; - } + if (skb->sk->sk_protocol == IPPROTO_TCP) + type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP; } context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl); @@ -2795,14 +2778,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, hw->mac.type, hw->phy.type, (part_num >> 8), (part_num & 0xff)); - if (link_width <= IXGBE_PCI_LINK_WIDTH_4) { - dev_warn(&pdev->dev, "PCI-Express bandwidth available for " - "this card is not sufficient for optimal " - "performance.\n"); - dev_warn(&pdev->dev, "For optimal performance a x8 " - "PCI-Express slot is required.\n"); - } - /* reset the hardware with the new settings */ ixgbe_start_hw(hw); diff --git a/trunk/drivers/net/niu.c b/trunk/drivers/net/niu.c index e98ce1e4965b..2fe14b0c5c67 100644 --- a/trunk/drivers/net/niu.c +++ b/trunk/drivers/net/niu.c @@ -33,8 +33,8 @@ #define DRV_MODULE_NAME "niu" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "0.7" -#define DRV_MODULE_RELDATE "February 18, 2008" +#define DRV_MODULE_VERSION "0.6" +#define DRV_MODULE_RELDATE "January 5, 2008" static char version[] __devinitdata = DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; @@ -5147,12 +5147,7 @@ static void niu_set_rx_mode(struct net_device *dev) index++; } } else { - int alt_start; - if (np->flags & NIU_FLAGS_XMAC) - alt_start = 0; - else - alt_start = 1; - for (i = alt_start; i < niu_num_alt_addr(np); i++) { + for (i = 0; i < niu_num_alt_addr(np); i++) { err = niu_enable_alt_mac(np, i, 0); if (err) printk(KERN_WARNING PFX "%s: Error %d " diff --git a/trunk/drivers/net/pcmcia/smc91c92_cs.c b/trunk/drivers/net/pcmcia/smc91c92_cs.c index 250eb1954c34..f18eca9831e8 100644 --- a/trunk/drivers/net/pcmcia/smc91c92_cs.c +++ b/trunk/drivers/net/pcmcia/smc91c92_cs.c @@ -559,16 +559,8 @@ static int mhz_setup(struct pcmcia_device *link) /* Read the station address from the CIS. It is stored as the last (fourth) string in the Version 1 Version/ID tuple. */ - tuple->DesiredTuple = CISTPL_VERS_1; - if (first_tuple(link, tuple, parse) != CS_SUCCESS) { - rc = -1; - goto free_cfg_mem; - } - /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ - if (next_tuple(link, tuple, parse) != CS_SUCCESS) - first_tuple(link, tuple, parse); - if (parse->version_1.ns > 3) { - station_addr = parse->version_1.str + parse->version_1.ofs[3]; + if (link->prod_id[3]) { + station_addr = link->prod_id[3]; if (cvt_ascii_address(dev, station_addr) == 0) { rc = 0; goto free_cfg_mem; diff --git a/trunk/drivers/net/tsi108_eth.c b/trunk/drivers/net/tsi108_eth.c index 6f33f84d37b0..35d15e850075 100644 --- a/trunk/drivers/net/tsi108_eth.c +++ b/trunk/drivers/net/tsi108_eth.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -298,11 +297,18 @@ static void tsi108_check_phy(struct net_device *dev) u32 speed; unsigned long flags; + /* Do a dummy read, as for some reason the first read + * after a link becomes up returns link down, even if + * it's been a while since the link came up. + */ + spin_lock_irqsave(&phy_lock, flags); if (!data->phy_ok) goto out; + tsi108_read_mii(data, MII_BMSR); + duplex = mii_check_media(&data->mii_if, netif_msg_link(data), data->init_media); data->init_media = 0; @@ -339,21 +345,22 @@ static void tsi108_check_phy(struct net_device *dev) TSI_WRITE(TSI108_MAC_CFG2, mac_cfg2_reg); TSI_WRITE(TSI108_EC_PORTCTRL, portctrl_reg); - } - if (data->link_up == 0) { - /* The manual says it can take 3-4 usecs for the speed change - * to take effect. - */ - udelay(5); + if (data->link_up == 0) { + /* The manual says it can take 3-4 usecs for the speed change + * to take effect. + */ + udelay(5); - spin_lock(&data->txlock); - if (is_valid_ether_addr(dev->dev_addr) && data->txfree) - netif_wake_queue(dev); + spin_lock(&data->txlock); + if (is_valid_ether_addr(dev->dev_addr) && data->txfree) + netif_wake_queue(dev); - data->link_up = 1; - spin_unlock(&data->txlock); + data->link_up = 1; + spin_unlock(&data->txlock); + } } + } else { if (data->link_up == 1) { netif_stop_queue(dev); @@ -1267,11 +1274,12 @@ static void tsi108_init_phy(struct net_device *dev) * PHY_STAT register before the link up status bit is set. */ - data->link_up = 0; + data->link_up = 1; while (!((phyval = tsi108_read_mii(data, MII_BMSR)) & BMSR_LSTATUS)) { if (i++ > (MII_READ_DELAY / 10)) { + data->link_up = 0; break; } spin_unlock_irqrestore(&phy_lock, flags); @@ -1279,7 +1287,6 @@ static void tsi108_init_phy(struct net_device *dev) spin_lock_irqsave(&phy_lock, flags); } - data->mii_if.supports_gmii = mii_check_gmii_support(&data->mii_if); printk(KERN_DEBUG "PHY_STAT reg contains %08x\n", phyval); data->phy_ok = 1; data->init_media = 1; @@ -1520,46 +1527,12 @@ static void tsi108_init_mac(struct net_device *dev) TSI_WRITE(TSI108_EC_INTMASK, ~0); } -static int tsi108_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct tsi108_prv_data *data = netdev_priv(dev); - unsigned long flags; - int rc; - - spin_lock_irqsave(&data->txlock, flags); - rc = mii_ethtool_gset(&data->mii_if, cmd); - spin_unlock_irqrestore(&data->txlock, flags); - - return rc; -} - -static int tsi108_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct tsi108_prv_data *data = netdev_priv(dev); - unsigned long flags; - int rc; - - spin_lock_irqsave(&data->txlock, flags); - rc = mii_ethtool_sset(&data->mii_if, cmd); - spin_unlock_irqrestore(&data->txlock, flags); - - return rc; -} - static int tsi108_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct tsi108_prv_data *data = netdev_priv(dev); - if (!netif_running(dev)) - return -EINVAL; return generic_mii_ioctl(&data->mii_if, if_mii(rq), cmd, NULL); } -static const struct ethtool_ops tsi108_ethtool_ops = { - .get_link = ethtool_op_get_link, - .get_settings = tsi108_get_settings, - .set_settings = tsi108_set_settings, -}; - static int tsi108_init_one(struct platform_device *pdev) { @@ -1611,6 +1584,7 @@ tsi108_init_one(struct platform_device *pdev) data->mii_if.phy_id = einfo->phy; data->mii_if.phy_id_mask = 0x1f; data->mii_if.reg_num_mask = 0x1f; + data->mii_if.supports_gmii = mii_check_gmii_support(&data->mii_if); data->phy = einfo->phy; data->phy_type = einfo->phy_type; @@ -1624,7 +1598,6 @@ tsi108_init_one(struct platform_device *pdev) dev->get_stats = tsi108_get_stats; netif_napi_add(dev, &data->napi, tsi108_poll, 64); dev->do_ioctl = tsi108_do_ioctl; - dev->ethtool_ops = &tsi108_ethtool_ops; /* Apparently, the Linux networking code won't use scatter-gather * if the hardware doesn't do checksums. However, it's faster @@ -1656,7 +1629,6 @@ tsi108_init_one(struct platform_device *pdev) goto register_fail; } - platform_set_drvdata(pdev, dev); printk(KERN_INFO "%s: Tsi108 Gigabit Ethernet, MAC: %s\n", dev->name, print_mac(mac, dev->dev_addr)); #ifdef DEBUG diff --git a/trunk/drivers/net/wireless/ath5k/base.c b/trunk/drivers/net/wireless/ath5k/base.c index dfdaec020739..ddc87149fe31 100644 --- a/trunk/drivers/net/wireless/ath5k/base.c +++ b/trunk/drivers/net/wireless/ath5k/base.c @@ -1256,7 +1256,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, if (ctl->flags & IEEE80211_TXCTL_NO_ACK) flags |= AR5K_TXDESC_NOACK; - pktlen = skb->len; + pktlen = skb->len + FCS_LEN; if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) { keyidx = ctl->key_idx; @@ -1952,7 +1952,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, } ds->ds_data = bf->skbaddr; - ret = ah->ah_setup_tx_desc(ah, ds, skb->len, + ret = ah->ah_setup_tx_desc(ah, ds, skb->len + FCS_LEN, ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_BEACON, (ctl->power_level * 2), ctl->tx_rate, 1, AR5K_TXKEYIX_INVALID, antenna, flags, 0, 0); diff --git a/trunk/drivers/net/wireless/ath5k/hw.c b/trunk/drivers/net/wireless/ath5k/hw.c index 1ab57aa6e4dc..3a4bf4035a23 100644 --- a/trunk/drivers/net/wireless/ath5k/hw.c +++ b/trunk/drivers/net/wireless/ath5k/hw.c @@ -3506,7 +3506,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, { u32 frame_type; struct ath5k_hw_2w_tx_desc *tx_desc; - unsigned int frame_len; + unsigned int buff_len; tx_desc = (struct ath5k_hw_2w_tx_desc *)&desc->ds_ctl0; @@ -3537,25 +3537,22 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, /* Setup control descriptor */ /* Verify and set frame length */ - - /* remove padding we might have added before */ - frame_len = pkt_len - (hdr_len & 3) + FCS_LEN; - - if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) + if (pkt_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) return -EINVAL; - tx_desc->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN; + tx_desc->tx_control_0 = pkt_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN; /* Verify and set buffer length */ + buff_len = pkt_len - FCS_LEN; /* NB: beacon's BufLen must be a multiple of 4 bytes */ if(type == AR5K_PKT_TYPE_BEACON) - pkt_len = roundup(pkt_len, 4); + buff_len = roundup(buff_len, 4); - if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN) + if (buff_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN) return -EINVAL; - tx_desc->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN; + tx_desc->tx_control_1 = buff_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN; /* * Verify and set header length @@ -3637,7 +3634,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, { struct ath5k_hw_4w_tx_desc *tx_desc; struct ath5k_hw_tx_status *tx_status; - unsigned int frame_len; + unsigned int buff_len; ATH5K_TRACE(ah->ah_sc); tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0; @@ -3672,25 +3669,22 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, /* Setup control descriptor */ /* Verify and set frame length */ - - /* remove padding we might have added before */ - frame_len = pkt_len - (hdr_len & 3) + FCS_LEN; - - if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) + if (pkt_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) return -EINVAL; - tx_desc->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; + tx_desc->tx_control_0 = pkt_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; /* Verify and set buffer length */ + buff_len = pkt_len - FCS_LEN; /* NB: beacon's BufLen must be a multiple of 4 bytes */ if(type == AR5K_PKT_TYPE_BEACON) - pkt_len = roundup(pkt_len, 4); + buff_len = roundup(buff_len, 4); - if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) + if (buff_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) return -EINVAL; - tx_desc->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; + tx_desc->tx_control_1 = buff_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; tx_desc->tx_control_0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | diff --git a/trunk/drivers/net/wireless/b43/b43.h b/trunk/drivers/net/wireless/b43/b43.h index f13346ba9dd2..08a011f0834a 100644 --- a/trunk/drivers/net/wireless/b43/b43.h +++ b/trunk/drivers/net/wireless/b43/b43.h @@ -14,12 +14,6 @@ #include "lo.h" #include "phy.h" - -/* The unique identifier of the firmware that's officially supported by - * this driver version. */ -#define B43_SUPPORTED_FIRMWARE_ID "FW13" - - #ifdef CONFIG_B43_DEBUG # define B43_DEBUG 1 #else diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index 51dfce16178a..ef65c41af00f 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -58,8 +58,6 @@ MODULE_AUTHOR("Stefano Brivio"); MODULE_AUTHOR("Michael Buesch"); MODULE_LICENSE("GPL"); -MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID); - static int modparam_bad_frames_preempt; module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); @@ -1861,11 +1859,11 @@ static int b43_upload_microcode(struct b43_wldev *dev) err = -EOPNOTSUPP; goto error; } - b43info(dev->wl, "Loading firmware version %u.%u " - "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", - fwrev, fwpatch, - (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF, - (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F); + b43dbg(dev->wl, "Loading firmware version %u.%u " + "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", + fwrev, fwpatch, + (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF, + (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F); dev->fw.rev = fwrev; dev->fw.patch = fwpatch; @@ -4202,33 +4200,6 @@ static struct ssb_driver b43_ssb_driver = { .resume = b43_resume, }; -static void b43_print_driverinfo(void) -{ - const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", - *feat_leds = "", *feat_rfkill = ""; - -#ifdef CONFIG_B43_PCI_AUTOSELECT - feat_pci = "P"; -#endif -#ifdef CONFIG_B43_PCMCIA - feat_pcmcia = "M"; -#endif -#ifdef CONFIG_B43_NPHY - feat_nphy = "N"; -#endif -#ifdef CONFIG_B43_LEDS - feat_leds = "L"; -#endif -#ifdef CONFIG_B43_RFKILL - feat_rfkill = "R"; -#endif - printk(KERN_INFO "Broadcom 43xx driver loaded " - "[ Features: %s%s%s%s%s, Firmware-ID: " - B43_SUPPORTED_FIRMWARE_ID " ]\n", - feat_pci, feat_pcmcia, feat_nphy, - feat_leds, feat_rfkill); -} - static int __init b43_init(void) { int err; @@ -4240,7 +4211,6 @@ static int __init b43_init(void) err = ssb_driver_register(&b43_ssb_driver); if (err) goto err_pcmcia_exit; - b43_print_driverinfo(); return err; diff --git a/trunk/drivers/net/wireless/b43legacy/b43legacy.h b/trunk/drivers/net/wireless/b43legacy/b43legacy.h index 93d45b71799a..c80edd2b9044 100644 --- a/trunk/drivers/net/wireless/b43legacy/b43legacy.h +++ b/trunk/drivers/net/wireless/b43legacy/b43legacy.h @@ -23,10 +23,6 @@ #include "phy.h" -/* The unique identifier of the firmware that's officially supported by this - * driver version. */ -#define B43legacy_SUPPORTED_FIRMWARE_ID "FW10" - #define B43legacy_IRQWAIT_MAX_RETRIES 20 #define B43legacy_RX_MAX_SSI 60 /* best guess at max ssi */ diff --git a/trunk/drivers/net/wireless/b43legacy/dma.c b/trunk/drivers/net/wireless/b43legacy/dma.c index e87b427d5e43..6e08405e8026 100644 --- a/trunk/drivers/net/wireless/b43legacy/dma.c +++ b/trunk/drivers/net/wireless/b43legacy/dma.c @@ -354,8 +354,7 @@ return 0; } -static u16 b43legacy_dmacontroller_base(enum b43legacy_dmatype type, - int controller_idx) +u16 b43legacy_dmacontroller_base(int dma64bit, int controller_idx) { static const u16 map64[] = { B43legacy_MMIO_DMA64_BASE0, @@ -374,7 +373,7 @@ static u16 b43legacy_dmacontroller_base(enum b43legacy_dmatype type, B43legacy_MMIO_DMA32_BASE5, }; - if (type == B43legacy_DMA_64BIT) { + if (dma64bit) { B43legacy_WARN_ON(!(controller_idx >= 0 && controller_idx < ARRAY_SIZE(map64))); return map64[controller_idx]; @@ -481,9 +480,8 @@ static void free_ringmemory(struct b43legacy_dmaring *ring) } /* Reset the RX DMA channel */ -static int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev, - u16 mmio_base, - enum b43legacy_dmatype type) +int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev, + u16 mmio_base, int dma64) { int i; u32 value; @@ -491,14 +489,13 @@ static int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev, might_sleep(); - offset = (type == B43legacy_DMA_64BIT) ? - B43legacy_DMA64_RXCTL : B43legacy_DMA32_RXCTL; + offset = dma64 ? B43legacy_DMA64_RXCTL : B43legacy_DMA32_RXCTL; b43legacy_write32(dev, mmio_base + offset, 0); for (i = 0; i < 10; i++) { - offset = (type == B43legacy_DMA_64BIT) ? - B43legacy_DMA64_RXSTATUS : B43legacy_DMA32_RXSTATUS; + offset = dma64 ? B43legacy_DMA64_RXSTATUS : + B43legacy_DMA32_RXSTATUS; value = b43legacy_read32(dev, mmio_base + offset); - if (type == B43legacy_DMA_64BIT) { + if (dma64) { value &= B43legacy_DMA64_RXSTAT; if (value == B43legacy_DMA64_RXSTAT_DISABLED) { i = -1; @@ -522,9 +519,8 @@ static int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev, } /* Reset the RX DMA channel */ -static int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev, - u16 mmio_base, - enum b43legacy_dmatype type) +int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev, + u16 mmio_base, int dma64) { int i; u32 value; @@ -533,10 +529,10 @@ static int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev, might_sleep(); for (i = 0; i < 10; i++) { - offset = (type == B43legacy_DMA_64BIT) ? - B43legacy_DMA64_TXSTATUS : B43legacy_DMA32_TXSTATUS; + offset = dma64 ? B43legacy_DMA64_TXSTATUS : + B43legacy_DMA32_TXSTATUS; value = b43legacy_read32(dev, mmio_base + offset); - if (type == B43legacy_DMA_64BIT) { + if (dma64) { value &= B43legacy_DMA64_TXSTAT; if (value == B43legacy_DMA64_TXSTAT_DISABLED || value == B43legacy_DMA64_TXSTAT_IDLEWAIT || @@ -551,14 +547,13 @@ static int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev, } msleep(1); } - offset = (type == B43legacy_DMA_64BIT) ? B43legacy_DMA64_TXCTL : - B43legacy_DMA32_TXCTL; + offset = dma64 ? B43legacy_DMA64_TXCTL : B43legacy_DMA32_TXCTL; b43legacy_write32(dev, mmio_base + offset, 0); for (i = 0; i < 10; i++) { - offset = (type == B43legacy_DMA_64BIT) ? - B43legacy_DMA64_TXSTATUS : B43legacy_DMA32_TXSTATUS; + offset = dma64 ? B43legacy_DMA64_TXSTATUS : + B43legacy_DMA32_TXSTATUS; value = b43legacy_read32(dev, mmio_base + offset); - if (type == B43legacy_DMA_64BIT) { + if (dma64) { value &= B43legacy_DMA64_TXSTAT; if (value == B43legacy_DMA64_TXSTAT_DISABLED) { i = -1; @@ -583,32 +578,6 @@ static int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev, return 0; } -/* Check if a DMA mapping address is invalid. */ -static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring, - dma_addr_t addr, - size_t buffersize) -{ - if (unlikely(dma_mapping_error(addr))) - return 1; - - switch (ring->type) { - case B43legacy_DMA_30BIT: - if ((u64)addr + buffersize > (1ULL << 30)) - return 1; - break; - case B43legacy_DMA_32BIT: - if ((u64)addr + buffersize > (1ULL << 32)) - return 1; - break; - case B43legacy_DMA_64BIT: - /* Currently we can't have addresses beyond 64 bits in the kernel. */ - break; - } - - /* The address is OK. */ - return 0; -} - static int setup_rx_descbuffer(struct b43legacy_dmaring *ring, struct b43legacy_dmadesc_generic *desc, struct b43legacy_dmadesc_meta *meta, @@ -626,7 +595,7 @@ static int setup_rx_descbuffer(struct b43legacy_dmaring *ring, return -ENOMEM; dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); - if (b43legacy_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) { + if (dma_mapping_error(dmaaddr)) { /* ugh. try to realloc in zone_dma */ gfp_flags |= GFP_DMA; @@ -639,7 +608,7 @@ static int setup_rx_descbuffer(struct b43legacy_dmaring *ring, ring->rx_buffersize, 0); } - if (b43legacy_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) { + if (dma_mapping_error(dmaaddr)) { dev_kfree_skb_any(skb); return -EIO; } @@ -705,7 +674,7 @@ static int dmacontroller_setup(struct b43legacy_dmaring *ring) u32 trans = ssb_dma_translation(ring->dev->dev); if (ring->tx) { - if (ring->type == B43legacy_DMA_64BIT) { + if (ring->dma64) { u64 ringbase = (u64)(ring->dmabase); addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK) @@ -740,7 +709,7 @@ static int dmacontroller_setup(struct b43legacy_dmaring *ring) err = alloc_initial_descbuffers(ring); if (err) goto out; - if (ring->type == B43legacy_DMA_64BIT) { + if (ring->dma64) { u64 ringbase = (u64)(ring->dmabase); addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK) @@ -791,16 +760,16 @@ static void dmacontroller_cleanup(struct b43legacy_dmaring *ring) { if (ring->tx) { b43legacy_dmacontroller_tx_reset(ring->dev, ring->mmio_base, - ring->type); - if (ring->type == B43legacy_DMA_64BIT) { + ring->dma64); + if (ring->dma64) { b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGLO, 0); b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGHI, 0); } else b43legacy_dma_write(ring, B43legacy_DMA32_TXRING, 0); } else { b43legacy_dmacontroller_rx_reset(ring->dev, ring->mmio_base, - ring->type); - if (ring->type == B43legacy_DMA_64BIT) { + ring->dma64); + if (ring->dma64) { b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGLO, 0); b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGHI, 0); } else @@ -855,10 +824,11 @@ static u64 supported_dma_mask(struct b43legacy_wldev *dev) /* Main initialization function. */ static -struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, - int controller_index, - int for_tx, - enum b43legacy_dmatype type) +struct b43legacy_dmaring *b43legacy_setup_dmaring( + struct b43legacy_wldev *dev, + int controller_index, + int for_tx, + int dma64) { struct b43legacy_dmaring *ring; int err; @@ -868,7 +838,6 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, ring = kzalloc(sizeof(*ring), GFP_KERNEL); if (!ring) goto out; - ring->type = type; nr_slots = B43legacy_RXRING_SLOTS; if (for_tx) @@ -886,12 +855,12 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, goto err_kfree_meta; /* test for ability to dma to txhdr_cache */ - dma_test = dma_map_single(dev->dev->dev, ring->txhdr_cache, - sizeof(struct b43legacy_txhdr_fw3), - DMA_TO_DEVICE); + dma_test = dma_map_single(dev->dev->dev, + ring->txhdr_cache, + sizeof(struct b43legacy_txhdr_fw3), + DMA_TO_DEVICE); - if (b43legacy_dma_mapping_error(ring, dma_test, - sizeof(struct b43legacy_txhdr_fw3))) { + if (dma_mapping_error(dma_test)) { /* ugh realloc */ kfree(ring->txhdr_cache); ring->txhdr_cache = kcalloc(nr_slots, @@ -905,8 +874,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, sizeof(struct b43legacy_txhdr_fw3), DMA_TO_DEVICE); - if (b43legacy_dma_mapping_error(ring, dma_test, - sizeof(struct b43legacy_txhdr_fw3))) + if (dma_mapping_error(dma_test)) goto err_kfree_txhdr_cache; } @@ -917,9 +885,11 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, ring->dev = dev; ring->nr_slots = nr_slots; - ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index); + ring->mmio_base = b43legacy_dmacontroller_base(dma64, + controller_index); ring->index = controller_index; - if (type == B43legacy_DMA_64BIT) + ring->dma64 = !!dma64; + if (dma64) ring->ops = &dma64_ops; else ring->ops = &dma32_ops; @@ -969,10 +939,10 @@ static void b43legacy_destroy_dmaring(struct b43legacy_dmaring *ring) if (!ring) return; - b43legacydbg(ring->dev->wl, "DMA-%u 0x%04X (%s) max used slots:" - " %d/%d\n", (unsigned int)(ring->type), ring->mmio_base, - (ring->tx) ? "TX" : "RX", ring->max_used_slots, - ring->nr_slots); + b43legacydbg(ring->dev->wl, "DMA-%s 0x%04X (%s) max used slots:" + " %d/%d\n", (ring->dma64) ? "64" : "32", ring->mmio_base, + (ring->tx) ? "TX" : "RX", + ring->max_used_slots, ring->nr_slots); /* Device IRQs are disabled prior entering this function, * so no need to take care of concurrency with rx handler stuff. */ @@ -1018,22 +988,11 @@ int b43legacy_dma_init(struct b43legacy_wldev *dev) struct b43legacy_dmaring *ring; int err; u64 dmamask; - enum b43legacy_dmatype type; + int dma64 = 0; dmamask = supported_dma_mask(dev); - switch (dmamask) { - default: - B43legacy_WARN_ON(1); - case DMA_30BIT_MASK: - type = B43legacy_DMA_30BIT; - break; - case DMA_32BIT_MASK: - type = B43legacy_DMA_32BIT; - break; - case DMA_64BIT_MASK: - type = B43legacy_DMA_64BIT; - break; - } + if (dmamask == DMA_64BIT_MASK) + dma64 = 1; err = ssb_dma_set_mask(dev->dev, dmamask); if (err) { @@ -1051,50 +1010,52 @@ int b43legacy_dma_init(struct b43legacy_wldev *dev) err = -ENOMEM; /* setup TX DMA channels. */ - ring = b43legacy_setup_dmaring(dev, 0, 1, type); + ring = b43legacy_setup_dmaring(dev, 0, 1, dma64); if (!ring) goto out; dma->tx_ring0 = ring; - ring = b43legacy_setup_dmaring(dev, 1, 1, type); + ring = b43legacy_setup_dmaring(dev, 1, 1, dma64); if (!ring) goto err_destroy_tx0; dma->tx_ring1 = ring; - ring = b43legacy_setup_dmaring(dev, 2, 1, type); + ring = b43legacy_setup_dmaring(dev, 2, 1, dma64); if (!ring) goto err_destroy_tx1; dma->tx_ring2 = ring; - ring = b43legacy_setup_dmaring(dev, 3, 1, type); + ring = b43legacy_setup_dmaring(dev, 3, 1, dma64); if (!ring) goto err_destroy_tx2; dma->tx_ring3 = ring; - ring = b43legacy_setup_dmaring(dev, 4, 1, type); + ring = b43legacy_setup_dmaring(dev, 4, 1, dma64); if (!ring) goto err_destroy_tx3; dma->tx_ring4 = ring; - ring = b43legacy_setup_dmaring(dev, 5, 1, type); + ring = b43legacy_setup_dmaring(dev, 5, 1, dma64); if (!ring) goto err_destroy_tx4; dma->tx_ring5 = ring; /* setup RX DMA channels. */ - ring = b43legacy_setup_dmaring(dev, 0, 0, type); + ring = b43legacy_setup_dmaring(dev, 0, 0, dma64); if (!ring) goto err_destroy_tx5; dma->rx_ring0 = ring; if (dev->dev->id.revision < 5) { - ring = b43legacy_setup_dmaring(dev, 3, 0, type); + ring = b43legacy_setup_dmaring(dev, 3, 0, dma64); if (!ring) goto err_destroy_rx0; dma->rx_ring3 = ring; } - b43legacydbg(dev->wl, "%u-bit DMA initialized\n", (unsigned int)type); + b43legacydbg(dev->wl, "%d-bit DMA initialized\n", + (dmamask == DMA_64BIT_MASK) ? 64 : + (dmamask == DMA_32BIT_MASK) ? 32 : 30); err = 0; out: return err; @@ -1233,13 +1194,9 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, } meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, - sizeof(struct b43legacy_txhdr_fw3), 1); - if (b43legacy_dma_mapping_error(ring, meta_hdr->dmaaddr, - sizeof(struct b43legacy_txhdr_fw3))) { - ring->current_slot = old_top_slot; - ring->used_slots = old_used_slots; + sizeof(struct b43legacy_txhdr_fw3), 1); + if (dma_mapping_error(meta_hdr->dmaaddr)) return -EIO; - } ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr, sizeof(struct b43legacy_txhdr_fw3), 1, 0, 0); @@ -1254,7 +1211,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); /* create a bounce buffer in zone_dma on mapping failure. */ - if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len)) { + if (dma_mapping_error(meta->dmaaddr)) { bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); if (!bounce_skb) { ring->current_slot = old_top_slot; @@ -1268,7 +1225,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, skb = bounce_skb; meta->skb = skb; meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); - if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len)) { + if (dma_mapping_error(meta->dmaaddr)) { ring->current_slot = old_top_slot; ring->used_slots = old_used_slots; err = -EIO; diff --git a/trunk/drivers/net/wireless/b43legacy/dma.h b/trunk/drivers/net/wireless/b43legacy/dma.h index 2dd488c5be2d..26f6ab08de75 100644 --- a/trunk/drivers/net/wireless/b43legacy/dma.h +++ b/trunk/drivers/net/wireless/b43legacy/dma.h @@ -218,12 +218,6 @@ struct b43legacy_dma_ops { void (*set_current_rxslot)(struct b43legacy_dmaring *ring, int slot); }; -enum b43legacy_dmatype { - B43legacy_DMA_30BIT = 30, - B43legacy_DMA_32BIT = 32, - B43legacy_DMA_64BIT = 64, -}; - struct b43legacy_dmaring { /* Lowlevel DMA ops. */ const struct b43legacy_dma_ops *ops; @@ -256,8 +250,8 @@ struct b43legacy_dmaring { int index; /* Boolean. Is this a TX ring? */ bool tx; - /* The type of DMA engine used. */ - enum b43legacy_dmatype type; + /* Boolean. 64bit DMA if true, 32bit DMA otherwise. */ + bool dma64; /* Boolean. Is this ring stopped at ieee80211 level? */ bool stopped; /* Lock, only used for TX. */ @@ -290,6 +284,15 @@ void b43legacy_dma_write(struct b43legacy_dmaring *ring, int b43legacy_dma_init(struct b43legacy_wldev *dev); void b43legacy_dma_free(struct b43legacy_wldev *dev); +int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev, + u16 dmacontroller_mmio_base, + int dma64); +int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev, + u16 dmacontroller_mmio_base, + int dma64); + +u16 b43legacy_dmacontroller_base(int dma64bit, int dmacontroller_idx); + void b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev); void b43legacy_dma_tx_resume(struct b43legacy_wldev *dev); @@ -317,6 +320,20 @@ void b43legacy_dma_free(struct b43legacy_wldev *dev) { } static inline +int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev, + u16 dmacontroller_mmio_base, + int dma64) +{ + return 0; +} +static inline +int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev, + u16 dmacontroller_mmio_base, + int dma64) +{ + return 0; +} +static inline void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev, struct ieee80211_tx_queue_stats *stats) { diff --git a/trunk/drivers/net/wireless/b43legacy/main.c b/trunk/drivers/net/wireless/b43legacy/main.c index c39de422e220..53f7f2e97615 100644 --- a/trunk/drivers/net/wireless/b43legacy/main.c +++ b/trunk/drivers/net/wireless/b43legacy/main.c @@ -3,7 +3,7 @@ * Broadcom B43legacy wireless driver * * Copyright (c) 2005 Martin Langer - * Copyright (c) 2005-2008 Stefano Brivio + * Copyright (c) 2005-2007 Stefano Brivio * Copyright (c) 2005, 2006 Michael Buesch * Copyright (c) 2005 Danny van Dyk * Copyright (c) 2005 Andreas Jaggi @@ -60,8 +60,6 @@ MODULE_AUTHOR("Stefano Brivio"); MODULE_AUTHOR("Michael Buesch"); MODULE_LICENSE("GPL"); -MODULE_FIRMWARE(B43legacy_SUPPORTED_FIRMWARE_ID); - #if defined(CONFIG_B43LEGACY_DMA) && defined(CONFIG_B43LEGACY_PIO) static int modparam_pio; module_param_named(pio, modparam_pio, int, 0444); @@ -1642,11 +1640,10 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) err = -EOPNOTSUPP; goto error; } - b43legacyinfo(dev->wl, "Loading firmware version 0x%X, patch level %u " - "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", fwrev, fwpatch, - (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF, - (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, - fwtime & 0x1F); + b43legacydbg(dev->wl, "Loading firmware version 0x%X, patch level %u " + "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", fwrev, fwpatch, + (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF, + (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F); dev->fw.rev = fwrev; dev->fw.patch = fwpatch; @@ -3809,32 +3806,6 @@ static struct ssb_driver b43legacy_ssb_driver = { .resume = b43legacy_resume, }; -static void b43legacy_print_driverinfo(void) -{ - const char *feat_pci = "", *feat_leds = "", *feat_rfkill = "", - *feat_pio = "", *feat_dma = ""; - -#ifdef CONFIG_B43LEGACY_PCI_AUTOSELECT - feat_pci = "P"; -#endif -#ifdef CONFIG_B43LEGACY_LEDS - feat_leds = "L"; -#endif -#ifdef CONFIG_B43LEGACY_RFKILL - feat_rfkill = "R"; -#endif -#ifdef CONFIG_B43LEGACY_PIO - feat_pio = "I"; -#endif -#ifdef CONFIG_B43LEGACY_DMA - feat_dma = "D"; -#endif - printk(KERN_INFO "Broadcom 43xx driver loaded " - "[ Features: %s%s%s%s%s, Firmware-ID: " - B43legacy_SUPPORTED_FIRMWARE_ID " ]\n", - feat_pci, feat_leds, feat_rfkill, feat_pio, feat_dma); -} - static int __init b43legacy_init(void) { int err; @@ -3845,8 +3816,6 @@ static int __init b43legacy_init(void) if (err) goto err_dfs_exit; - b43legacy_print_driverinfo(); - return err; err_dfs_exit: diff --git a/trunk/drivers/net/wireless/ipw2200.c b/trunk/drivers/net/wireless/ipw2200.c index a56d9fc6354f..3e6ad7b92c83 100644 --- a/trunk/drivers/net/wireless/ipw2200.c +++ b/trunk/drivers/net/wireless/ipw2200.c @@ -3365,6 +3365,7 @@ static void ipw_rx_queue_reset(struct ipw_priv *priv, /* Set us so that we have processed and used all buffers, but have * not restocked the Rx queue with fresh buffers */ rxq->read = rxq->write = 0; + rxq->processed = RX_QUEUE_SIZE - 1; rxq->free_count = 0; spin_unlock_irqrestore(&rxq->lock, flags); } @@ -3606,22 +3607,7 @@ static int ipw_load(struct ipw_priv *priv) * Driver allocates buffers of this size for Rx */ -/** - * ipw_rx_queue_space - Return number of free slots available in queue. - */ -static int ipw_rx_queue_space(const struct ipw_rx_queue *q) -{ - int s = q->read - q->write; - if (s <= 0) - s += RX_QUEUE_SIZE; - /* keep some buffer to not confuse full and empty queue */ - s -= 2; - if (s < 0) - s = 0; - return s; -} - -static inline int ipw_tx_queue_space(const struct clx2_queue *q) +static inline int ipw_queue_space(const struct clx2_queue *q) { int s = q->last_used - q->first_empty; if (s <= 0) @@ -4961,7 +4947,7 @@ static int ipw_queue_tx_reclaim(struct ipw_priv *priv, priv->tx_packets++; } done: - if ((ipw_tx_queue_space(q) > q->low_mark) && + if ((ipw_queue_space(q) > q->low_mark) && (qindex >= 0) && (priv->status & STATUS_ASSOCIATED) && netif_running(priv->net_dev)) netif_wake_queue(priv->net_dev); @@ -4979,7 +4965,7 @@ static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf, struct clx2_queue *q = &txq->q; struct tfd_frame *tfd; - if (ipw_tx_queue_space(q) < (sync ? 1 : 2)) { + if (ipw_queue_space(q) < (sync ? 1 : 2)) { IPW_ERROR("No space for Tx\n"); return -EBUSY; } @@ -5084,7 +5070,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv) spin_lock_irqsave(&rxq->lock, flags); write = rxq->write; - while ((ipw_rx_queue_space(rxq) > 0) && (rxq->free_count)) { + while ((rxq->write != rxq->processed) && (rxq->free_count)) { element = rxq->rx_free.next; rxb = list_entry(element, struct ipw_rx_mem_buffer, list); list_del(element); @@ -5201,6 +5187,7 @@ static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv) /* Set us so that we have processed and used all buffers, but have * not restocked the Rx queue with fresh buffers */ rxq->read = rxq->write = 0; + rxq->processed = RX_QUEUE_SIZE - 1; rxq->free_count = 0; return rxq; @@ -8236,17 +8223,13 @@ static void ipw_rx(struct ipw_priv *priv) struct ieee80211_hdr_4addr *header; u32 r, w, i; u8 network_packet; - u8 fill_rx = 0; DECLARE_MAC_BUF(mac); DECLARE_MAC_BUF(mac2); DECLARE_MAC_BUF(mac3); r = ipw_read32(priv, IPW_RX_READ_INDEX); w = ipw_read32(priv, IPW_RX_WRITE_INDEX); - i = priv->rxq->read; - - if (ipw_rx_queue_space (priv->rxq) > (RX_QUEUE_SIZE / 2)) - fill_rx = 1; + i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE; while (i != r) { rxb = priv->rxq->queue[i]; @@ -8421,17 +8404,11 @@ static void ipw_rx(struct ipw_priv *priv) list_add_tail(&rxb->list, &priv->rxq->rx_used); i = (i + 1) % RX_QUEUE_SIZE; - - /* If there are a lot of unsued frames, restock the Rx queue - * so the ucode won't assert */ - if (fill_rx) { - priv->rxq->read = i; - ipw_rx_queue_replenish(priv); - } } /* Backtrack one entry */ - priv->rxq->read = i; + priv->rxq->processed = (i ? i : RX_QUEUE_SIZE) - 1; + ipw_rx_queue_restock(priv); } @@ -10359,7 +10336,7 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd); ipw_write32(priv, q->reg_w, q->first_empty); - if (ipw_tx_queue_space(q) < q->high_mark) + if (ipw_queue_space(q) < q->high_mark) netif_stop_queue(priv->net_dev); return NETDEV_TX_OK; @@ -10380,7 +10357,7 @@ static int ipw_net_is_queue_full(struct net_device *dev, int pri) struct clx2_tx_queue *txq = &priv->txq[0]; #endif /* CONFIG_IPW2200_QOS */ - if (ipw_tx_queue_space(&txq->q) < txq->q.high_mark) + if (ipw_queue_space(&txq->q) < txq->q.high_mark) return 1; return 0; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c index 40b71bc2c4a4..5ee1ad69898b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -687,12 +687,6 @@ static int iwl3945_enqueue_hcmd(struct iwl3945_priv *priv, struct iwl3945_host_c BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && !(cmd->meta.flags & CMD_SIZE_HUGE)); - - if (iwl3945_is_rfkill(priv)) { - IWL_DEBUG_INFO("Not sending command - RF KILL"); - return -EIO; - } - if (iwl3945_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) { IWL_ERROR("No space for Tx\n"); return -ENOSPC; @@ -1586,7 +1580,7 @@ static inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv) */ int iwl3945_eeprom_init(struct iwl3945_priv *priv) { - u16 *e = (u16 *)&priv->eeprom; + __le16 *e = (__le16 *)&priv->eeprom; u32 gp = iwl3945_read32(priv, CSR_EEPROM_GP); u32 r; int sz = sizeof(priv->eeprom); @@ -1629,7 +1623,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv) IWL_ERROR("Time out reading EEPROM[%d]", addr); return -ETIMEDOUT; } - e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16)); + e[addr / 2] = cpu_to_le16(r >> 16); } return 0; @@ -2812,8 +2806,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, #endif /* drop all data frame if we are not associated */ - if ((!iwl3945_is_associated(priv) || - ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) && + if ((!iwl3945_is_associated(priv) || !priv->assoc_id) && ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); goto drop_unlock; @@ -4288,7 +4281,7 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv) int reclaim; unsigned long flags; u8 fill_rx = 0; - u32 count = 8; + u32 count = 0; /* uCode's read index (stored in shared DRAM) indicates the last Rx * buffer that the driver may process (last buffer filled by ucode). */ @@ -6263,8 +6256,6 @@ static void __iwl3945_down(struct iwl3945_priv *priv) STATUS_RF_KILL_HW | test_bit(STATUS_RF_KILL_SW, &priv->status) << STATUS_RF_KILL_SW | - test_bit(STATUS_GEO_CONFIGURED, &priv->status) << - STATUS_GEO_CONFIGURED | test_bit(STATUS_IN_SUSPEND, &priv->status) << STATUS_IN_SUSPEND; goto exit; @@ -6276,8 +6267,6 @@ static void __iwl3945_down(struct iwl3945_priv *priv) STATUS_RF_KILL_HW | test_bit(STATUS_RF_KILL_SW, &priv->status) << STATUS_RF_KILL_SW | - test_bit(STATUS_GEO_CONFIGURED, &priv->status) << - STATUS_GEO_CONFIGURED | test_bit(STATUS_IN_SUSPEND, &priv->status) << STATUS_IN_SUSPEND | test_bit(STATUS_FW_ERROR, &priv->status) << diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl4965-base.c b/trunk/drivers/net/wireless/iwlwifi/iwl4965-base.c index a23d4798653b..f423241b9567 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -692,11 +692,6 @@ static int iwl4965_enqueue_hcmd(struct iwl4965_priv *priv, struct iwl4965_host_c BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && !(cmd->meta.flags & CMD_SIZE_HUGE)); - if (iwl4965_is_rfkill(priv)) { - IWL_DEBUG_INFO("Not sending command - RF KILL"); - return -EIO; - } - if (iwl4965_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) { IWL_ERROR("No space for Tx\n"); return -ENOSPC; @@ -1659,7 +1654,7 @@ static inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv) */ int iwl4965_eeprom_init(struct iwl4965_priv *priv) { - u16 *e = (u16 *)&priv->eeprom; + __le16 *e = (__le16 *)&priv->eeprom; u32 gp = iwl4965_read32(priv, CSR_EEPROM_GP); u32 r; int sz = sizeof(priv->eeprom); @@ -1703,7 +1698,7 @@ int iwl4965_eeprom_init(struct iwl4965_priv *priv) rc = -ETIMEDOUT; goto done; } - e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16)); + e[addr / 2] = cpu_to_le16(r >> 16); } rc = 0; @@ -2940,7 +2935,7 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, /* drop all data frame if we are not associated */ if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && (!iwl4965_is_associated(priv) || - ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) || + !priv->assoc_id || !priv->assoc_station_added)) { IWL_DEBUG_DROP("Dropping - !iwl4965_is_associated\n"); goto drop_unlock; @@ -4669,7 +4664,7 @@ static void iwl4965_rx_handle(struct iwl4965_priv *priv) int reclaim; unsigned long flags; u8 fill_rx = 0; - u32 count = 8; + u32 count = 0; /* uCode's read index (stored in shared DRAM) indicates the last Rx * buffer that the driver may process (last buffer filled by ucode). */ @@ -6685,8 +6680,6 @@ static void __iwl4965_down(struct iwl4965_priv *priv) STATUS_RF_KILL_HW | test_bit(STATUS_RF_KILL_SW, &priv->status) << STATUS_RF_KILL_SW | - test_bit(STATUS_GEO_CONFIGURED, &priv->status) << - STATUS_GEO_CONFIGURED | test_bit(STATUS_IN_SUSPEND, &priv->status) << STATUS_IN_SUSPEND; goto exit; @@ -6698,8 +6691,6 @@ static void __iwl4965_down(struct iwl4965_priv *priv) STATUS_RF_KILL_HW | test_bit(STATUS_RF_KILL_SW, &priv->status) << STATUS_RF_KILL_SW | - test_bit(STATUS_GEO_CONFIGURED, &priv->status) << - STATUS_GEO_CONFIGURED | test_bit(STATUS_IN_SUSPEND, &priv->status) << STATUS_IN_SUSPEND | test_bit(STATUS_FW_ERROR, &priv->status) << diff --git a/trunk/drivers/net/wireless/rndis_wlan.c b/trunk/drivers/net/wireless/rndis_wlan.c index 8ce2ddf8024f..d3ecf89abd93 100644 --- a/trunk/drivers/net/wireless/rndis_wlan.c +++ b/trunk/drivers/net/wireless/rndis_wlan.c @@ -2300,7 +2300,7 @@ static void rndis_update_wireless_stats(struct work_struct *work) struct usbnet *usbdev = priv->usbdev; struct iw_statistics iwstats; __le32 rssi, tmp; - int len, ret, j; + int len, ret, bitrate, j; unsigned long flags; int update_jiffies = STATS_UPDATE_JIFFIES; void *buf; @@ -2352,10 +2352,14 @@ static void rndis_update_wireless_stats(struct work_struct *work) if (ret == 0) iwstats.discard.misc += le32_to_cpu(tmp); - /* Workaround transfer stalls on poor quality links. - * TODO: find right way to fix these stalls (as stalls do not happen - * with ndiswrapper/windows driver). */ - if (iwstats.qual.qual <= 25) { + /* Workaround transfer stalls on poor quality links. */ + len = sizeof(tmp); + ret = rndis_query_oid(usbdev, OID_GEN_LINK_SPEED, &tmp, &len); + if (ret == 0) { + bitrate = le32_to_cpu(tmp) * 100; + if (bitrate > 11000000) + goto end; + /* Decrease stats worker interval to catch stalls. * faster. Faster than 400-500ms causes packet loss, * Slower doesn't catch stalls fast enough. diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c index 4ca9730e5e92..86ded4066f5b 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1839,11 +1839,11 @@ static struct usb_device_id rt2500usb_device_table[] = { /* Hercules */ { USB_DEVICE(0x06f8, 0xe000), USB_DEVICE_DATA(&rt2500usb_ops) }, /* Melco */ - { USB_DEVICE(0x0411, 0x005e), USB_DEVICE_DATA(&rt2500usb_ops) }, { USB_DEVICE(0x0411, 0x0066), USB_DEVICE_DATA(&rt2500usb_ops) }, { USB_DEVICE(0x0411, 0x0067), USB_DEVICE_DATA(&rt2500usb_ops) }, { USB_DEVICE(0x0411, 0x008b), USB_DEVICE_DATA(&rt2500usb_ops) }, { USB_DEVICE(0x0411, 0x0097), USB_DEVICE_DATA(&rt2500usb_ops) }, + /* MSI */ { USB_DEVICE(0x0db0, 0x6861), USB_DEVICE_DATA(&rt2500usb_ops) }, { USB_DEVICE(0x0db0, 0x6865), USB_DEVICE_DATA(&rt2500usb_ops) }, diff --git a/trunk/drivers/net/wireless/wavelan.h b/trunk/drivers/net/wireless/wavelan.h index 9ab360558ffd..27172cde5a39 100644 --- a/trunk/drivers/net/wireless/wavelan.h +++ b/trunk/drivers/net/wireless/wavelan.h @@ -85,7 +85,7 @@ union hacs_u #define HASR_MMC_INTR 0x0002 /* Interrupt request from MMC */ #define HASR_MMC_BUSY 0x0004 /* MMC busy indication */ #define HASR_PSA_BUSY 0x0008 /* LAN parameter storage area busy */ -} __attribute__ ((packed)); +}; typedef struct ha_t ha_t; struct ha_t @@ -292,7 +292,7 @@ struct mmw_t #define MMW_EXT_ANT_INTERNAL 0x00 /* Internal antenna */ #define MMW_EXT_ANT_EXTERNAL 0x03 /* External antenna */ #define MMW_EXT_ANT_IQ_TEST 0x1C /* IQ test pattern (set to 0) */ -} __attribute__ ((packed)); +}; #define MMW_SIZE 37 @@ -347,7 +347,7 @@ struct mmr_t unsigned char mmr_unused4[1]; /* unused */ unsigned char mmr_fee_data_l; /* Read data from EEPROM (low) */ unsigned char mmr_fee_data_h; /* Read data from EEPROM (high) */ -} __attribute__ ((packed)); +}; #define MMR_SIZE 36 diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index d35dc3f25d06..676b47e07ed0 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -32,7 +32,7 @@ #include "io_sch.h" static struct timer_list recovery_timer; -static spinlock_t recovery_lock; +static DEFINE_SPINLOCK(recovery_lock); static int recovery_phase; static const unsigned long recovery_delay[] = { 3, 30, 300 }; diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index c72014a3e7d4..2074701f7e76 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -5140,7 +5140,7 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd, struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; struct ipr_ioadl_desc *last_ioadl = NULL; - int len = qc->nbytes; + int len = qc->nbytes + qc->pad_len; struct scatterlist *sg; unsigned int si; @@ -5206,7 +5206,7 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU; ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC; ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; - ipr_cmd->dma_use_sg = qc->n_elem; + ipr_cmd->dma_use_sg = qc->pad_len ? qc->n_elem + 1 : qc->n_elem; ipr_build_ata_ioadl(ipr_cmd, qc); regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION; diff --git a/trunk/drivers/scsi/libsas/sas_ata.c b/trunk/drivers/scsi/libsas/sas_ata.c index 7cd05b599a12..0996f866f14c 100644 --- a/trunk/drivers/scsi/libsas/sas_ata.c +++ b/trunk/drivers/scsi/libsas/sas_ata.c @@ -178,8 +178,8 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) task->uldd_task = qc; if (ata_is_atapi(qc->tf.protocol)) { memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len); - task->total_xfer_len = qc->nbytes; - task->num_scatter = qc->n_elem; + task->total_xfer_len = qc->nbytes + qc->pad_len; + task->num_scatter = qc->pad_len ? qc->n_elem + 1 : qc->n_elem; } else { for_each_sg(qc->sg, sg, qc->n_elem, si) xfer += sg->length; diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index ba21d97d1855..135c1d054701 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -1014,6 +1014,10 @@ static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb, } req->buffer = NULL; + if (blk_pc_request(req)) + sdb->length = req->data_len; + else + sdb->length = req->nr_sectors << 9; /* * Next, walk the list, and fill in the addresses and sizes of @@ -1022,10 +1026,6 @@ static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb, count = blk_rq_map_sg(req->q, req, sdb->table.sgl); BUG_ON(count > sdb->table.nents); sdb->table.nents = count; - if (blk_pc_request(req)) - sdb->length = req->data_len; - else - sdb->length = req->nr_sectors << 9; return BLKPREP_OK; } diff --git a/trunk/drivers/video/aty/atyfb_base.c b/trunk/drivers/video/aty/atyfb_base.c index 62f9c6e387cc..d775eb6590b6 100644 --- a/trunk/drivers/video/aty/atyfb_base.c +++ b/trunk/drivers/video/aty/atyfb_base.c @@ -1913,6 +1913,61 @@ static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma) par->mmaped = 1; return 0; } + +static struct { + u32 yoffset; + u8 r[2][256]; + u8 g[2][256]; + u8 b[2][256]; +} atyfb_save; + +static void atyfb_save_palette(struct atyfb_par *par, int enter) +{ + int i, tmp; + + for (i = 0; i < 256; i++) { + tmp = aty_ld_8(DAC_CNTL, par) & 0xfc; + if (M64_HAS(EXTRA_BRIGHT)) + tmp |= 0x2; + aty_st_8(DAC_CNTL, tmp, par); + aty_st_8(DAC_MASK, 0xff, par); + + aty_st_8(DAC_R_INDEX, i, par); + atyfb_save.r[enter][i] = aty_ld_8(DAC_DATA, par); + atyfb_save.g[enter][i] = aty_ld_8(DAC_DATA, par); + atyfb_save.b[enter][i] = aty_ld_8(DAC_DATA, par); + aty_st_8(DAC_W_INDEX, i, par); + aty_st_8(DAC_DATA, atyfb_save.r[1 - enter][i], par); + aty_st_8(DAC_DATA, atyfb_save.g[1 - enter][i], par); + aty_st_8(DAC_DATA, atyfb_save.b[1 - enter][i], par); + } +} + +static void atyfb_palette(int enter) +{ + struct atyfb_par *par; + struct fb_info *info; + int i; + + for (i = 0; i < FB_MAX; i++) { + info = registered_fb[i]; + if (info && info->fbops == &atyfb_ops) { + par = (struct atyfb_par *) info->par; + + atyfb_save_palette(par, enter); + if (enter) { + atyfb_save.yoffset = info->var.yoffset; + info->var.yoffset = 0; + set_off_pitch(par, info); + } else { + info->var.yoffset = atyfb_save.yoffset; + set_off_pitch(par, info); + } + aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par); + break; + } + } +} #endif /* __sparc__ */ @@ -2615,6 +2670,10 @@ static int __devinit aty_init(struct fb_info *info) goto aty_init_exit; } +#ifdef __sparc__ + atyfb_save_palette(par, 0); +#endif + #ifdef CONFIG_FB_ATY_CT if (!noaccel && M64_HAS(INTEGRATED)) aty_init_cursor(info); @@ -2841,6 +2900,8 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, #ifdef __sparc__ +extern void (*prom_palette) (int); + static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, struct fb_info *info, unsigned long addr) { @@ -3475,6 +3536,9 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi goto err_release_io; #ifdef __sparc__ + if (!prom_palette) + prom_palette = atyfb_palette; + /* * Add /dev/fb mmap values. */ diff --git a/trunk/drivers/video/cg14.c b/trunk/drivers/video/cg14.c index fdc9f43ec30a..41f6dbf61be7 100644 --- a/trunk/drivers/video/cg14.c +++ b/trunk/drivers/video/cg14.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/video/sbuslib.c b/trunk/drivers/video/sbuslib.c index 4deaac05b938..963a454b7074 100644 --- a/trunk/drivers/video/sbuslib.c +++ b/trunk/drivers/video/sbuslib.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/watchdog/Kconfig b/trunk/drivers/watchdog/Kconfig index 254d115cafab..afcdc69e37d6 100644 --- a/trunk/drivers/watchdog/Kconfig +++ b/trunk/drivers/watchdog/Kconfig @@ -402,18 +402,6 @@ config IT8712F_WDT To compile this driver as a module, choose M here: the module will be called it8712f_wdt. -config HP_WATCHDOG - tristate "HP Proliant iLO 2 Hardware Watchdog Timer" - depends on X86 - help - A software monitoring watchdog and NMI sourcing driver. This driver - will detect lockups and provide stack trace. Also, when an NMI - occurs this driver will make the necessary BIOS calls to log - the cause of the NMI. This is a driver that will only load on a - HP ProLiant system with a minimum of iLO2 support. - To compile this driver as a module, choose M here: the - module will be called hpwdt. - config SC1200_WDT tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog" depends on X86 @@ -645,19 +633,6 @@ config WDT_RM9K_GPI To compile this driver as a module, choose M here: the module will be called rm9k_wdt. -config SIBYTE_WDOG - tristate "Sibyte SoC hardware watchdog" - depends on CPU_SB1 - help - Watchdog driver for the built in watchdog hardware in Sibyte - SoC processors. There are apparently two watchdog timers - on such processors; this driver supports only the first one, - because currently Linux only supports exporting one watchdog - to userspace. - - To compile this driver as a loadable module, choose M here. - The module will be called sb_wdog. - config AR7_WDT tristate "TI AR7 Watchdog Timer" depends on AR7 diff --git a/trunk/drivers/watchdog/Makefile b/trunk/drivers/watchdog/Makefile index f3fb170fe5c6..ebc21146d40c 100644 --- a/trunk/drivers/watchdog/Makefile +++ b/trunk/drivers/watchdog/Makefile @@ -67,7 +67,6 @@ obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o iTCO_vendor_support.o obj-$(CONFIG_IT8712F_WDT) += it8712f_wdt.o -obj-$(CONFIG_HP_WATCHDOG) += hpwdt.o obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o obj-$(CONFIG_PC87413_WDT) += pc87413_wdt.o @@ -93,7 +92,6 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o obj-$(CONFIG_INDYDOG) += indydog.o obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o -obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o obj-$(CONFIG_AR7_WDT) += ar7_wdt.o obj-$(CONFIG_TXX9_WDT) += txx9wdt.o diff --git a/trunk/drivers/watchdog/bfin_wdt.c b/trunk/drivers/watchdog/bfin_wdt.c index 1237113dc14a..472be10f0686 100644 --- a/trunk/drivers/watchdog/bfin_wdt.c +++ b/trunk/drivers/watchdog/bfin_wdt.c @@ -29,7 +29,6 @@ #define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args) #define stampit() stamp("here i am") -#define pr_init(fmt, args...) ({ static const __initdata char __fmt[] = fmt; printk(__fmt, ## args); }) #define WATCHDOG_NAME "bfin-wdt" #define PFX WATCHDOG_NAME ": " @@ -446,19 +445,19 @@ static int __init bfin_wdt_init(void) ret = register_reboot_notifier(&bfin_wdt_notifier); if (ret) { - pr_init(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); + printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); return ret; } ret = misc_register(&bfin_wdt_miscdev); if (ret) { - pr_init(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", + printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret); unregister_reboot_notifier(&bfin_wdt_notifier); return ret; } - pr_init(KERN_INFO PFX "initialized: timeout=%d sec (nowayout=%d)\n", + printk(KERN_INFO PFX "initialized: timeout=%d sec (nowayout=%d)\n", timeout, nowayout); return 0; diff --git a/trunk/drivers/watchdog/hpwdt.c b/trunk/drivers/watchdog/hpwdt.c deleted file mode 100644 index a2e174b09fe7..000000000000 --- a/trunk/drivers/watchdog/hpwdt.c +++ /dev/null @@ -1,926 +0,0 @@ -/* - * HP WatchDog Driver - * based on - * - * SoftDog 0.05: A Software Watchdog Device - * - * (c) Copyright 2007 Hewlett-Packard Development Company, L.P. - * Thomas Mingarelli - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */ -#define CRU_BIOS_SIGNATURE_VALUE 0x55524324 -#define PCI_BIOS32_PARAGRAPH_LEN 16 -#define PCI_ROM_BASE1 0x000F0000 -#define ROM_SIZE 0x10000 - -struct bios32_service_dir { - u32 signature; - u32 entry_point; - u8 revision; - u8 length; - u8 checksum; - u8 reserved[5]; -}; - -/* - * smbios_entry_point - defines SMBIOS entry point structure - * - * anchor[4] - anchor string (_SM_) - * checksum - checksum of the entry point structure - * length - length of the entry point structure - * major_ver - major version (02h for revision 2.1) - * minor_ver - minor version (01h for revision 2.1) - * max_struct_size - size of the largest SMBIOS structure - * revision - entry point structure revision implemented - * formatted_area[5] - reserved - * intermediate_anchor[5] - intermediate anchor string (_DMI_) - * intermediate_checksum - intermediate checksum - * table_length - structure table length - * table_address - structure table address - * table_num_structs - number of SMBIOS structures present - * bcd_revision - BCD revision - */ -struct smbios_entry_point { - u8 anchor[4]; - u8 checksum; - u8 length; - u8 major_ver; - u8 minor_ver; - u16 max_struct_size; - u8 revision; - u8 formatted_area[5]; - u8 intermediate_anchor[5]; - u8 intermediate_checksum; - u16 table_length; - u64 table_address; - u16 table_num_structs; - u8 bcd_revision; -}; - -/* type 212 */ -struct smbios_cru64_info { - u8 type; - u8 byte_length; - u16 handle; - u32 signature; - u64 physical_address; - u32 double_length; - u32 double_offset; -}; -#define SMBIOS_CRU64_INFORMATION 212 - -struct cmn_registers { - union { - struct { - u8 ral; - u8 rah; - u16 rea2; - }; - u32 reax; - } u1; - union { - struct { - u8 rbl; - u8 rbh; - u8 reb2l; - u8 reb2h; - }; - u32 rebx; - } u2; - union { - struct { - u8 rcl; - u8 rch; - u16 rec2; - }; - u32 recx; - } u3; - union { - struct { - u8 rdl; - u8 rdh; - u16 red2; - }; - u32 redx; - } u4; - - u32 resi; - u32 redi; - u16 rds; - u16 res; - u32 reflags; -} __attribute__((packed)); - -#define DEFAULT_MARGIN 30 -static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */ -static unsigned int reload; /* the computed soft_margin */ -static int nowayout = WATCHDOG_NOWAYOUT; -static char expect_release; -static unsigned long hpwdt_is_open; - -static void __iomem *pci_mem_addr; /* the PCI-memory address */ -static unsigned long __iomem *hpwdt_timer_reg; -static unsigned long __iomem *hpwdt_timer_con; - -static DEFINE_SPINLOCK(rom_lock); - -static void *cru_rom_addr; - -static struct cmn_registers cmn_regs; - -static struct pci_device_id hpwdt_devices[] = { - { - .vendor = PCI_VENDOR_ID_COMPAQ, - .device = 0xB203, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - {0}, /* terminate list */ -}; -MODULE_DEVICE_TABLE(pci, hpwdt_devices); - -/* - * bios_checksum - */ -static int __devinit bios_checksum(const char __iomem *ptr, int len) -{ - char sum = 0; - int i; - - /* - * calculate checksum of size bytes. This should add up - * to zero if we have a valid header. - */ - for (i = 0; i < len; i++) - sum += ptr[i]; - - return ((sum == 0) && (len > 0)); -} - -#ifndef CONFIG_X86_64 -/* --32 Bit Bios------------------------------------------------------------ */ - -#define HPWDT_ARCH 32 - -asmlinkage void asminline_call(struct cmn_registers *pi86Regs, - unsigned long *pRomEntry) -{ - asm("pushl %ebp \n\t" - "movl %esp, %ebp \n\t" - "pusha \n\t" - "pushf \n\t" - "push %es \n\t" - "push %ds \n\t" - "pop %es \n\t" - "movl 8(%ebp),%eax \n\t" - "movl 4(%eax),%ebx \n\t" - "movl 8(%eax),%ecx \n\t" - "movl 12(%eax),%edx \n\t" - "movl 16(%eax),%esi \n\t" - "movl 20(%eax),%edi \n\t" - "movl (%eax),%eax \n\t" - "push %cs \n\t" - "call *12(%ebp) \n\t" - "pushf \n\t" - "pushl %eax \n\t" - "movl 8(%ebp),%eax \n\t" - "movl %ebx,4(%eax) \n\t" - "movl %ecx,8(%eax) \n\t" - "movl %edx,12(%eax) \n\t" - "movl %esi,16(%eax) \n\t" - "movl %edi,20(%eax) \n\t" - "movw %ds,24(%eax) \n\t" - "movw %es,26(%eax) \n\t" - "popl %ebx \n\t" - "movl %ebx,(%eax) \n\t" - "popl %ebx \n\t" - "movl %ebx,28(%eax) \n\t" - "pop %es \n\t" - "popf \n\t" - "popa \n\t" - "leave \n\t" "ret"); -} - -/* - * cru_detect - * - * Routine Description: - * This function uses the 32-bit BIOS Service Directory record to - * search for a $CRU record. - * - * Return Value: - * 0 : SUCCESS - * <0 : FAILURE - */ -static int __devinit cru_detect(unsigned long map_entry, - unsigned long map_offset) -{ - void *bios32_map; - unsigned long *bios32_entrypoint; - unsigned long cru_physical_address; - unsigned long cru_length; - unsigned long physical_bios_base = 0; - unsigned long physical_bios_offset = 0; - int retval = -ENODEV; - - bios32_map = ioremap(map_entry, (2 * PAGE_SIZE)); - - if (bios32_map == NULL) - return -ENODEV; - - bios32_entrypoint = bios32_map + map_offset; - - cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE; - - asminline_call(&cmn_regs, bios32_entrypoint); - - if (cmn_regs.u1.ral != 0) { - printk(KERN_WARNING - "hpwdt: Call succeeded but with an error: 0x%x\n", - cmn_regs.u1.ral); - } else { - physical_bios_base = cmn_regs.u2.rebx; - physical_bios_offset = cmn_regs.u4.redx; - cru_length = cmn_regs.u3.recx; - cru_physical_address = - physical_bios_base + physical_bios_offset; - - /* If the values look OK, then map it in. */ - if ((physical_bios_base + physical_bios_offset)) { - cru_rom_addr = - ioremap(cru_physical_address, cru_length); - if (cru_rom_addr) - retval = 0; - } - - printk(KERN_DEBUG "hpwdt: CRU Base Address: 0x%lx\n", - physical_bios_base); - printk(KERN_DEBUG "hpwdt: CRU Offset Address: 0x%lx\n", - physical_bios_offset); - printk(KERN_DEBUG "hpwdt: CRU Length: 0x%lx\n", - cru_length); - printk(KERN_DEBUG "hpwdt: CRU Mapped Address: 0x%x\n", - (unsigned int)&cru_rom_addr); - } - iounmap(bios32_map); - return retval; -} - -/* - * bios32_present - * - * Routine Description: - * This function finds the 32-bit BIOS Service Directory - * - * Return Value: - * 0 : SUCCESS - * <0 : FAILURE - */ -static int __devinit bios32_present(const char __iomem *p) -{ - struct bios32_service_dir *bios_32_ptr; - int length; - unsigned long map_entry, map_offset; - - bios_32_ptr = (struct bios32_service_dir *) p; - - /* - * Search for signature by checking equal to the swizzled value - * instead of calling another routine to perform a strcmp. - */ - if (bios_32_ptr->signature == PCI_BIOS32_SD_VALUE) { - length = bios_32_ptr->length * PCI_BIOS32_PARAGRAPH_LEN; - if (bios_checksum(p, length)) { - /* - * According to the spec, we're looking for the - * first 4KB-aligned address below the entrypoint - * listed in the header. The Service Directory code - * is guaranteed to occupy no more than 2 4KB pages. - */ - map_entry = bios_32_ptr->entry_point & ~(PAGE_SIZE - 1); - map_offset = bios_32_ptr->entry_point - map_entry; - - return cru_detect(map_entry, map_offset); - } - } - return -ENODEV; -} - -static int __devinit detect_cru_service(void) -{ - char __iomem *p, *q; - int rc = -1; - - /* - * Search from 0x0f0000 through 0x0fffff, inclusive. - */ - p = ioremap(PCI_ROM_BASE1, ROM_SIZE); - if (p == NULL) - return -ENOMEM; - - for (q = p; q < p + ROM_SIZE; q += 16) { - rc = bios32_present(q); - if (!rc) - break; - } - iounmap(p); - return rc; -} - -#else -/* --64 Bit Bios------------------------------------------------------------ */ - -#define HPWDT_ARCH 64 - -asmlinkage void asminline_call(struct cmn_registers *pi86Regs, - unsigned long *pRomEntry) -{ - asm("pushq %rbp \n\t" - "movq %rsp, %rbp \n\t" - "pushq %rax \n\t" - "pushq %rbx \n\t" - "pushq %rdx \n\t" - "pushq %r12 \n\t" - "pushq %r9 \n\t" - "movq %rsi, %r12 \n\t" - "movq %rdi, %r9 \n\t" - "movl 4(%r9),%ebx \n\t" - "movl 8(%r9),%ecx \n\t" - "movl 12(%r9),%edx \n\t" - "movl 16(%r9),%esi \n\t" - "movl 20(%r9),%edi \n\t" - "movl (%r9),%eax \n\t" - "call *%r12 \n\t" - "pushfq \n\t" - "popq %r12 \n\t" - "popfq \n\t" - "movl %eax, (%r9) \n\t" - "movl %ebx, 4(%r9) \n\t" - "movl %ecx, 8(%r9) \n\t" - "movl %edx, 12(%r9) \n\t" - "movl %esi, 16(%r9) \n\t" - "movl %edi, 20(%r9) \n\t" - "movq %r12, %rax \n\t" - "movl %eax, 28(%r9) \n\t" - "popq %r9 \n\t" - "popq %r12 \n\t" - "popq %rdx \n\t" - "popq %rbx \n\t" - "popq %rax \n\t" - "leave \n\t" "ret"); -} - -/* - * dmi_find_cru - * - * Routine Description: - * This function checks wether or not a SMBIOS/DMI record is - * the 64bit CRU info or not - * - * Return Value: - * 0 : SUCCESS - if record found - * <0 : FAILURE - if record not found - */ -static void __devinit dmi_find_cru(const struct dmi_header *dm) -{ - struct smbios_cru64_info *smbios_cru64_ptr; - unsigned long cru_physical_address; - - if (dm->type == SMBIOS_CRU64_INFORMATION) { - smbios_cru64_ptr = (struct smbios_cru64_info *) dm; - if (smbios_cru64_ptr->signature == CRU_BIOS_SIGNATURE_VALUE) { - cru_physical_address = - smbios_cru64_ptr->physical_address + - smbios_cru64_ptr->double_offset; - cru_rom_addr = ioremap(cru_physical_address, - smbios_cru64_ptr->double_length); - } - } -} - -/* - * dmi_table - * - * Routine Description: - * Decode the SMBIOS/DMI table and check if we have a 64bit CRU record - * or not. - * - * We have to be cautious here. We have seen BIOSes with DMI pointers - * pointing to completely the wrong place for example - */ -static void __devinit dmi_table(u8 *buf, int len, int num, - void (*decode)(const struct dmi_header *)) -{ - u8 *data = buf; - int i = 0; - - /* - * Stop when we see all the items the table claimed to have - * OR we run off the end of the table (also happens) - */ - while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { - const struct dmi_header *dm = (const struct dmi_header *)data; - - /* - * We want to know the total length (formated area and strings) - * before decoding to make sure we won't run off the table in - * dmi_decode or dmi_string - */ - data += dm->length; - while ((data - buf < len - 1) && (data[0] || data[1])) - data++; - if (data - buf < len - 1) - decode(dm); - data += 2; - i++; - } -} - -/* - * smbios_present - * - * Routine Description: - * This function parses the SMBIOS entry point table to retrieve - * the 64 bit CRU Service. - * - * Return Value: - * 0 : SUCCESS - * <0 : FAILURE - */ -static int __devinit smbios_present(const char __iomem *p) -{ - struct smbios_entry_point *eps = - (struct smbios_entry_point *) p; - int length; - u8 *buf; - - /* check if we have indeed the SMBIOS table entry point */ - if ((strncmp((char *)eps->anchor, "_SM_", - sizeof(eps->anchor))) == 0) { - length = eps->length; - - /* SMBIOS v2.1 implementation might use 0x1e */ - if ((length == 0x1e) && - (eps->major_ver == 2) && - (eps->minor_ver == 1)) - length = 0x1f; - - /* - * Now we will check: - * - SMBIOS checksum must be 0 - * - intermediate anchor should be _DMI_ - * - intermediate checksum should be 0 - */ - if ((bios_checksum(p, length)) && - (strncmp((char *)eps->intermediate_anchor, "_DMI_", - sizeof(eps->intermediate_anchor)) == 0) && - (bios_checksum(p+0x10, 15))) { - buf = ioremap(eps->table_address, eps->table_length); - if (buf == NULL) - return -ENODEV; - - - /* Scan the DMI table for the 64 bit CRU service */ - dmi_table(buf, eps->table_length, - eps->table_num_structs, dmi_find_cru); - - iounmap(buf); - return 0; - } - } - - return -ENODEV; -} - -static int __devinit smbios_scan_machine(void) -{ - char __iomem *p, *q; - int rc; - - if (efi_enabled) { - if (efi.smbios == EFI_INVALID_TABLE_ADDR) - return -ENODEV; - - p = ioremap(efi.smbios, 32); - if (p == NULL) - return -ENOMEM; - - rc = smbios_present(p); - iounmap(p); - } else { - /* - * Search from 0x0f0000 through 0x0fffff, inclusive. - */ - p = ioremap(PCI_ROM_BASE1, ROM_SIZE); - if (p == NULL) - return -ENOMEM; - - for (q = p; q < p + ROM_SIZE; q += 16) { - rc = smbios_present(q); - if (!rc) { - break; - } - } - iounmap(p); - } -} - -static int __devinit detect_cru_service(void) -{ - cru_rom_addr = NULL; - - smbios_scan_machine(); /* will become dmi_walk(dmi_find_cru); */ - - /* if cru_rom_addr has been set then we found a CRU service */ - return ((cru_rom_addr != NULL)? 0: -ENODEV); -} - -/* ------------------------------------------------------------------------- */ - -#endif - -/* - * NMI Handler - */ -static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason, - void *data) -{ - static unsigned long rom_pl; - static int die_nmi_called; - - if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI) - return NOTIFY_OK; - - spin_lock_irqsave(&rom_lock, rom_pl); - if (!die_nmi_called) - asminline_call(&cmn_regs, cru_rom_addr); - die_nmi_called = 1; - spin_unlock_irqrestore(&rom_lock, rom_pl); - if (cmn_regs.u1.ral == 0) { - printk(KERN_WARNING "hpwdt: An NMI occurred, " - "but unable to determine source.\n"); - } else { - panic("An NMI occurred, please see the Integrated " - "Management Log for details.\n"); - } - - return NOTIFY_STOP; -} - -/* - * Watchdog operations - */ -static void hpwdt_start(void) -{ - reload = (soft_margin * 1000) / 128; - iowrite16(reload, hpwdt_timer_reg); - iowrite16(0x85, hpwdt_timer_con); -} - -static void hpwdt_stop(void) -{ - unsigned long data; - - data = ioread16(hpwdt_timer_con); - data &= 0xFE; - iowrite16(data, hpwdt_timer_con); -} - -static void hpwdt_ping(void) -{ - iowrite16(reload, hpwdt_timer_reg); -} - -static int hpwdt_change_timer(int new_margin) -{ - /* Arbitrary, can't find the card's limits */ - if (new_margin < 30 || new_margin > 600) { - printk(KERN_WARNING - "hpwdt: New value passed in is invalid: %d seconds.\n", - new_margin); - return -EINVAL; - } - - soft_margin = new_margin; - printk(KERN_DEBUG - "hpwdt: New timer passed in is %d seconds.\n", - new_margin); - reload = (soft_margin * 1000) / 128; - - return 0; -} - -/* - * /dev/watchdog handling - */ -static int hpwdt_open(struct inode *inode, struct file *file) -{ - /* /dev/watchdog can only be opened once */ - if (test_and_set_bit(0, &hpwdt_is_open)) - return -EBUSY; - - /* Start the watchdog */ - hpwdt_start(); - hpwdt_ping(); - - return nonseekable_open(inode, file); -} - -static int hpwdt_release(struct inode *inode, struct file *file) -{ - /* Stop the watchdog */ - if (expect_release == 42) { - hpwdt_stop(); - } else { - printk(KERN_CRIT - "hpwdt: Unexpected close, not stopping watchdog!\n"); - hpwdt_ping(); - } - - expect_release = 0; - - /* /dev/watchdog is being closed, make sure it can be re-opened */ - clear_bit(0, &hpwdt_is_open); - - return 0; -} - -static ssize_t hpwdt_write(struct file *file, const char __user *data, - size_t len, loff_t *ppos) -{ - /* See if we got the magic character 'V' and reload the timer */ - if (len) { - if (!nowayout) { - size_t i; - - /* note: just in case someone wrote the magic character - * five months ago... */ - expect_release = 0; - - /* scan to see whether or not we got the magic char. */ - for (i = 0; i != len; i++) { - char c; - if (get_user(c, data+i)) - return -EFAULT; - if (c == 'V') - expect_release = 42; - } - } - - /* someone wrote to us, we should reload the timer */ - hpwdt_ping(); - } - - return len; -} - -static struct watchdog_info ident = { - .options = WDIOF_SETTIMEOUT | - WDIOF_KEEPALIVEPING | - WDIOF_MAGICCLOSE, - .identity = "HP iLO2 HW Watchdog Timer", -}; - -static long hpwdt_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - void __user *argp = (void __user *)arg; - int __user *p = argp; - int new_margin; - int ret = -ENOTTY; - - switch (cmd) { - case WDIOC_GETSUPPORT: - ret = 0; - if (copy_to_user(argp, &ident, sizeof(ident))) - ret = -EFAULT; - break; - - case WDIOC_GETSTATUS: - case WDIOC_GETBOOTSTATUS: - ret = put_user(0, p); - break; - - case WDIOC_KEEPALIVE: - hpwdt_ping(); - ret = 0; - break; - - case WDIOC_SETTIMEOUT: - ret = get_user(new_margin, p); - if (ret) - break; - - ret = hpwdt_change_timer(new_margin); - if (ret) - break; - - hpwdt_ping(); - /* Fall */ - case WDIOC_GETTIMEOUT: - ret = put_user(soft_margin, p); - break; - } - return ret; -} - -/* - * Kernel interfaces - */ -static struct file_operations hpwdt_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .write = hpwdt_write, - .unlocked_ioctl = hpwdt_ioctl, - .open = hpwdt_open, - .release = hpwdt_release, -}; - -static struct miscdevice hpwdt_miscdev = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &hpwdt_fops, -}; - -static struct notifier_block die_notifier = { - .notifier_call = hpwdt_pretimeout, - .priority = 0x7FFFFFFF, -}; - -/* - * Init & Exit - */ - -static int __devinit hpwdt_init_one(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - int retval; - - /* - * First let's find out if we are on an iLO2 server. We will - * not run on a legacy ASM box. - */ - if (dev->subsystem_vendor != PCI_VENDOR_ID_HP) { - dev_warn(&dev->dev, - "This server does not have an iLO2 ASIC.\n"); - return -ENODEV; - } - - if (pci_enable_device(dev)) { - dev_warn(&dev->dev, - "Not possible to enable PCI Device: 0x%x:0x%x.\n", - ent->vendor, ent->device); - return -ENODEV; - } - - pci_mem_addr = pci_iomap(dev, 1, 0x80); - if (!pci_mem_addr) { - dev_warn(&dev->dev, - "Unable to detect the iLO2 server memory.\n"); - retval = -ENOMEM; - goto error_pci_iomap; - } - hpwdt_timer_reg = pci_mem_addr + 0x70; - hpwdt_timer_con = pci_mem_addr + 0x72; - - /* Make sure that we have a valid soft_margin */ - if (hpwdt_change_timer(soft_margin)) - hpwdt_change_timer(DEFAULT_MARGIN); - - /* - * We need to map the ROM to get the CRU service. - * For 32 bit Operating Systems we need to go through the 32 Bit - * BIOS Service Directory - * For 64 bit Operating Systems we get that service through SMBIOS. - */ - retval = detect_cru_service(); - if (retval < 0) { - dev_warn(&dev->dev, - "Unable to detect the %d Bit CRU Service.\n", - HPWDT_ARCH); - goto error_get_cru; - } - - /* - * We know this is the only CRU call we need to make so lets keep as - * few instructions as possible once the NMI comes in. - */ - cmn_regs.u1.rah = 0x0D; - cmn_regs.u1.ral = 0x02; - - retval = register_die_notifier(&die_notifier); - if (retval != 0) { - dev_warn(&dev->dev, - "Unable to register a die notifier (err=%d).\n", - retval); - goto error_die_notifier; - } - - retval = misc_register(&hpwdt_miscdev); - if (retval < 0) { - dev_warn(&dev->dev, - "Unable to register miscdev on minor=%d (err=%d).\n", - WATCHDOG_MINOR, retval); - goto error_misc_register; - } - - printk(KERN_INFO - "hp Watchdog Timer Driver: 1.00" - ", timer margin: %d seconds( nowayout=%d).\n", - soft_margin, nowayout); - - return 0; - -error_misc_register: - unregister_die_notifier(&die_notifier); -error_die_notifier: - if (cru_rom_addr) - iounmap(cru_rom_addr); -error_get_cru: - pci_iounmap(dev, pci_mem_addr); -error_pci_iomap: - pci_disable_device(dev); - return retval; -} - -static void __devexit hpwdt_exit(struct pci_dev *dev) -{ - if (!nowayout) - hpwdt_stop(); - - misc_deregister(&hpwdt_miscdev); - unregister_die_notifier(&die_notifier); - - if (cru_rom_addr) - iounmap(cru_rom_addr); - pci_iounmap(dev, pci_mem_addr); - pci_disable_device(dev); -} - -static struct pci_driver hpwdt_driver = { - .name = "hpwdt", - .id_table = hpwdt_devices, - .probe = hpwdt_init_one, - .remove = __devexit_p(hpwdt_exit), -}; - -static void __exit hpwdt_cleanup(void) -{ - pci_unregister_driver(&hpwdt_driver); -} - -static int __init hpwdt_init(void) -{ - return pci_register_driver(&hpwdt_driver); -} - -MODULE_AUTHOR("Tom Mingarelli"); -MODULE_DESCRIPTION("hp watchdog driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); - -module_param(soft_margin, int, 0); -MODULE_PARM_DESC(soft_margin, "Watchdog timeout in seconds"); - -module_param(nowayout, int, 0); -MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); - -module_init(hpwdt_init); -module_exit(hpwdt_cleanup); diff --git a/trunk/drivers/watchdog/mtx-1_wdt.c b/trunk/drivers/watchdog/mtx-1_wdt.c index 789831b3fa00..98451747d3cd 100644 --- a/trunk/drivers/watchdog/mtx-1_wdt.c +++ b/trunk/drivers/watchdog/mtx-1_wdt.c @@ -45,13 +45,10 @@ #include #include #include -#include - #include #include #include -#include #define MTX1_WDT_INTERVAL (5 * HZ) @@ -64,7 +61,6 @@ static struct { volatile int queue; int default_ticks; unsigned long inuse; - unsigned gpio; } mtx1_wdt_device; static void mtx1_wdt_trigger(unsigned long unused) @@ -77,8 +73,7 @@ static void mtx1_wdt_trigger(unsigned long unused) * toggle GPIO2_15 */ tmp = au_readl(GPIO2_DIR); - tmp = (tmp & ~(1 << mtx1_wdt_device.gpio)) | - ((~tmp) & (1 << mtx1_wdt_device.gpio)); + tmp = (tmp & ~(1<<15)) | ((~tmp) & (1<<15)); au_writel (tmp, GPIO2_DIR); if (mtx1_wdt_device.queue && ticks) @@ -98,7 +93,7 @@ static void mtx1_wdt_start(void) { if (!mtx1_wdt_device.queue) { mtx1_wdt_device.queue = 1; - gpio_set_value(mtx1_wdt_device.gpio, 1); + au_writel (au_readl(GPIO2_DIR) | (u32)(1<<15), GPIO2_DIR); mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); } mtx1_wdt_device.running++; @@ -108,7 +103,7 @@ static int mtx1_wdt_stop(void) { if (mtx1_wdt_device.queue) { mtx1_wdt_device.queue = 0; - gpio_set_value(mtx1_wdt_device.gpio, 0); + au_writel (au_readl(GPIO2_DIR) & ~((u32)(1<<15)), GPIO2_DIR); } ticks = mtx1_wdt_device.default_ticks; @@ -202,12 +197,10 @@ static struct miscdevice mtx1_wdt_misc = { }; -static int mtx1_wdt_probe(struct platform_device *pdev) +static int __init mtx1_wdt_init(void) { int ret; - mtx1_wdt_device.gpio = pdev->resource[0].start; - if ((ret = misc_register(&mtx1_wdt_misc)) < 0) { printk(KERN_ERR " mtx-1_wdt : failed to register\n"); return ret; @@ -229,30 +222,13 @@ static int mtx1_wdt_probe(struct platform_device *pdev) return 0; } -static int mtx1_wdt_remove(struct platform_device *pdev) +static void __exit mtx1_wdt_exit(void) { if (mtx1_wdt_device.queue) { mtx1_wdt_device.queue = 0; wait_for_completion(&mtx1_wdt_device.stop); } misc_deregister(&mtx1_wdt_misc); - return 0; -} - -static struct platform_driver mtx1_wdt = { - .probe = mtx1_wdt_probe, - .remove = mtx1_wdt_remove, - .driver.name = "mtx1-wdt", -}; - -static int __init mtx1_wdt_init(void) -{ - return platform_driver_register(&mtx1_wdt); -} - -static void __exit mtx1_wdt_exit(void) -{ - platform_driver_unregister(&mtx1_wdt); } module_init(mtx1_wdt_init); @@ -261,4 +237,3 @@ module_exit(mtx1_wdt_exit); MODULE_AUTHOR("Michael Stickel, Florian Fainelli"); MODULE_DESCRIPTION("Driver for the MTX-1 watchdog"); MODULE_LICENSE("GPL"); -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); diff --git a/trunk/drivers/watchdog/sb_wdog.c b/trunk/drivers/watchdog/sb_wdog.c deleted file mode 100644 index b94431433695..000000000000 --- a/trunk/drivers/watchdog/sb_wdog.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Watchdog driver for SiByte SB1 SoCs - * - * Copyright (C) 2007 OnStor, Inc. * Andrew Sharp - * - * This driver is intended to make the second of two hardware watchdogs - * on the Sibyte 12XX and 11XX SoCs available to the user. There are two - * such devices available on the SoC, but it seems that there isn't an - * enumeration class for watchdogs in Linux like there is for RTCs. - * The second is used rather than the first because it uses IRQ 1, - * thereby avoiding all that IRQ 0 problematic nonsense. - * - * I have not tried this driver on a 1480 processor; it might work - * just well enough to really screw things up. - * - * It is a simple timer, and there is an interrupt that is raised the - * first time the timer expires. The second time it expires, the chip - * is reset and there is no way to redirect that NMI. Which could - * be problematic in some cases where this chip is sitting on the HT - * bus and has just taken responsibility for providing a cache block. - * Since the reset can't be redirected to the external reset pin, it is - * possible that other HT connected processors might hang and not reset. - * For Linux, a soft reset would probably be even worse than a hard reset. - * There you have it. - * - * The timer takes 23 bits of a 64 bit register (?) as a count value, - * and decrements the count every microsecond, for a max value of - * 0x7fffff usec or about 8.3ish seconds. - * - * This watchdog borrows some user semantics from the softdog driver, - * in that if you close the fd, it leaves the watchdog running, unless - * you previously wrote a 'V' to the fd, in which case it disables - * the watchdog when you close the fd like some other drivers. - * - * Based on various other watchdog drivers, which are probably all - * loosely based on something Alan Cox wrote years ago. - * - * (c) Copyright 1996 Alan Cox , All Rights Reserved. - * http://www.redhat.com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 1 or 2 as published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - - -/* - * set the initial count value of a timer - * - * wdog is the iomem address of the cfg register - */ -void sbwdog_set(char __iomem *wdog, unsigned long t) -{ - __raw_writeb(0, wdog - 0x10); - __raw_writeq(t & 0x7fffffUL, wdog); -} - -/* - * cause the timer to [re]load it's initial count and start counting - * all over again - * - * wdog is the iomem address of the cfg register - */ -void sbwdog_pet(char __iomem *wdog) -{ - __raw_writeb(__raw_readb(wdog) | 1, wdog); -} - -static unsigned long sbwdog_gate; /* keeps it to one thread only */ -static char __iomem *kern_dog = (char __iomem *)(IO_BASE + (A_SCD_WDOG_CFG_0)); -static char __iomem *user_dog = (char __iomem *)(IO_BASE + (A_SCD_WDOG_CFG_1)); -static unsigned long timeout = 0x7fffffUL; /* useconds: 8.3ish secs. */ -static int expect_close; - -static struct watchdog_info ident = { - .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, - .identity = "SiByte Watchdog", -}; - -/* - * Allow only a single thread to walk the dog - */ -static int sbwdog_open(struct inode *inode, struct file *file) -{ - nonseekable_open(inode, file); - if (test_and_set_bit(0, &sbwdog_gate)) { - return -EBUSY; - } - __module_get(THIS_MODULE); - - /* - * Activate the timer - */ - sbwdog_set(user_dog, timeout); - __raw_writeb(1, user_dog); - - return 0; -} - -/* - * Put the dog back in the kennel. - */ -static int sbwdog_release(struct inode *inode, struct file *file) -{ - if (expect_close == 42) { - __raw_writeb(0, user_dog); - module_put(THIS_MODULE); - } else { - printk(KERN_CRIT "%s: Unexpected close, not stopping watchdog!\n", - ident.identity); - sbwdog_pet(user_dog); - } - clear_bit(0, &sbwdog_gate); - expect_close = 0; - - return 0; -} - -/* - * 42 - the answer - */ -static ssize_t sbwdog_write(struct file *file, const char __user *data, - size_t len, loff_t *ppos) -{ - int i; - - if (len) { - /* - * restart the timer - */ - expect_close = 0; - - for (i = 0; i != len; i++) { - char c; - - if (get_user(c, data + i)) { - return -EFAULT; - } - if (c == 'V') { - expect_close = 42; - } - } - sbwdog_pet(user_dog); - } - - return len; -} - -static int sbwdog_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - int ret = -ENOTTY; - unsigned long time; - void __user *argp = (void __user *)arg; - int __user *p = argp; - - switch (cmd) { - case WDIOC_GETSUPPORT: - ret = copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; - break; - - case WDIOC_GETSTATUS: - case WDIOC_GETBOOTSTATUS: - ret = put_user(0, p); - break; - - case WDIOC_SETTIMEOUT: - ret = get_user(time, p); - if (ret) { - break; - } - - time *= 1000000; - if (time > 0x7fffffUL) { - ret = -EINVAL; - break; - } - timeout = time; - sbwdog_set(user_dog, timeout); - sbwdog_pet(user_dog); - - case WDIOC_GETTIMEOUT: - /* - * get the remaining count from the ... count register - * which is 1*8 before the config register - */ - ret = put_user(__raw_readq(user_dog - 8) / 1000000, p); - break; - - case WDIOC_KEEPALIVE: - sbwdog_pet(user_dog); - ret = 0; - break; - } - return ret; -} - -/* - * Notifier for system down - */ -static int -sbwdog_notify_sys(struct notifier_block *this, unsigned long code, void *erf) -{ - if (code == SYS_DOWN || code == SYS_HALT) { - /* - * sit and sit - */ - __raw_writeb(0, user_dog); - __raw_writeb(0, kern_dog); - } - - return NOTIFY_DONE; -} - -static const struct file_operations sbwdog_fops = -{ - .owner = THIS_MODULE, - .llseek = no_llseek, - .write = sbwdog_write, - .ioctl = sbwdog_ioctl, - .open = sbwdog_open, - .release = sbwdog_release, -}; - -static struct miscdevice sbwdog_miscdev = -{ - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &sbwdog_fops, -}; - -static struct notifier_block sbwdog_notifier = { - .notifier_call = sbwdog_notify_sys, -}; - -/* - * interrupt handler - * - * doesn't do a whole lot for user, but oh so cleverly written so kernel - * code can use it to re-up the watchdog, thereby saving the kernel from - * having to create and maintain a timer, just to tickle another timer, - * which is just so wrong. - */ -irqreturn_t sbwdog_interrupt(int irq, void *addr) -{ - unsigned long wd_init; - char *wd_cfg_reg = (char *)addr; - u8 cfg; - - cfg = __raw_readb(wd_cfg_reg); - wd_init = __raw_readq(wd_cfg_reg - 8) & 0x7fffff; - - /* - * if it's the second watchdog timer, it's for those users - */ - if (wd_cfg_reg == user_dog) { - printk(KERN_CRIT - "%s in danger of initiating system reset in %ld.%01ld seconds\n", - ident.identity, wd_init / 1000000, (wd_init / 100000) % 10); - } else { - cfg |= 1; - } - - __raw_writeb(cfg, wd_cfg_reg); - - return IRQ_HANDLED; -} - -static int __init sbwdog_init(void) -{ - int ret; - - /* - * register a reboot notifier - */ - ret = register_reboot_notifier(&sbwdog_notifier); - if (ret) { - printk (KERN_ERR "%s: cannot register reboot notifier (err=%d)\n", - ident.identity, ret); - return ret; - } - - /* - * get the resources - */ - ret = misc_register(&sbwdog_miscdev); - if (ret == 0) { - printk(KERN_INFO "%s: timeout is %ld.%ld secs\n", ident.identity, - timeout / 1000000, (timeout / 100000) % 10); - } - - ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, - ident.identity, (void *)user_dog); - if (ret) { - printk(KERN_ERR "%s: failed to request irq 1 - %d\n", ident.identity, - ret); - misc_deregister(&sbwdog_miscdev); - } - - return ret; -} - -static void __exit sbwdog_exit(void) -{ - misc_deregister(&sbwdog_miscdev); -} - -module_init(sbwdog_init); -module_exit(sbwdog_exit); - -MODULE_AUTHOR("Andrew Sharp "); -MODULE_DESCRIPTION("SiByte Watchdog"); - -module_param(timeout, ulong, 0); -MODULE_PARM_DESC(timeout, - "Watchdog timeout in microseconds (max/default 8388607 or 8.3ish secs)"); - -MODULE_LICENSE("GPL"); -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); - -/* - * example code that can be put in a platform code area to utilize the - * first watchdog timer for the kernels own purpose. - - void -platform_wd_setup(void) -{ - int ret; - - ret = request_irq(0, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, - "Kernel Watchdog", IOADDR(A_SCD_WDOG_CFG_0)); - if (ret) { - printk(KERN_CRIT "Watchdog IRQ zero(0) failed to be requested - %d\n", - ret); - } -} - - - */ diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index 3312fcc3c098..242e409dab4b 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -903,7 +903,7 @@ void bio_set_pages_dirty(struct bio *bio) } } -static void bio_release_pages(struct bio *bio) +void bio_release_pages(struct bio *bio) { struct bio_vec *bvec = bio->bi_io_vec; int i; diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index 7d822fae7765..67fe72ce6ac7 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -31,8 +31,6 @@ struct bdev_inode { struct inode vfs_inode; }; -static const struct address_space_operations def_blk_aops; - static inline struct bdev_inode *BDEV_I(struct inode *inode) { return container_of(inode, struct bdev_inode, vfs_inode); @@ -173,6 +171,203 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, iov, offset, nr_segs, blkdev_get_blocks, NULL); } +#if 0 +static void blk_end_aio(struct bio *bio, int error) +{ + struct kiocb *iocb = bio->bi_private; + atomic_t *bio_count = &iocb->ki_bio_count; + + if (bio_data_dir(bio) == READ) + bio_check_pages_dirty(bio); + else { + bio_release_pages(bio); + bio_put(bio); + } + + /* iocb->ki_nbytes stores error code from LLDD */ + if (error) + iocb->ki_nbytes = -EIO; + + if (atomic_dec_and_test(bio_count)) { + if ((long)iocb->ki_nbytes < 0) + aio_complete(iocb, iocb->ki_nbytes, 0); + else + aio_complete(iocb, iocb->ki_left, 0); + } + + return 0; +} + +#define VEC_SIZE 16 +struct pvec { + unsigned short nr; + unsigned short idx; + struct page *page[VEC_SIZE]; +}; + +#define PAGES_SPANNED(addr, len) \ + (DIV_ROUND_UP((addr) + (len), PAGE_SIZE) - (addr) / PAGE_SIZE); + +/* + * get page pointer for user addr, we internally cache struct page array for + * (addr, count) range in pvec to avoid frequent call to get_user_pages. If + * internal page list is exhausted, a batch count of up to VEC_SIZE is used + * to get next set of page struct. + */ +static struct page *blk_get_page(unsigned long addr, size_t count, int rw, + struct pvec *pvec) +{ + int ret, nr_pages; + if (pvec->idx == pvec->nr) { + nr_pages = PAGES_SPANNED(addr, count); + nr_pages = min(nr_pages, VEC_SIZE); + down_read(¤t->mm->mmap_sem); + ret = get_user_pages(current, current->mm, addr, nr_pages, + rw == READ, 0, pvec->page, NULL); + up_read(¤t->mm->mmap_sem); + if (ret < 0) + return ERR_PTR(ret); + pvec->nr = ret; + pvec->idx = 0; + } + return pvec->page[pvec->idx++]; +} + +/* return a page back to pvec array */ +static void blk_unget_page(struct page *page, struct pvec *pvec) +{ + pvec->page[--pvec->idx] = page; +} + +static ssize_t +blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, + loff_t pos, unsigned long nr_segs) +{ + struct inode *inode = iocb->ki_filp->f_mapping->host; + unsigned blkbits = blksize_bits(bdev_hardsect_size(I_BDEV(inode))); + unsigned blocksize_mask = (1 << blkbits) - 1; + unsigned long seg = 0; /* iov segment iterator */ + unsigned long nvec; /* number of bio vec needed */ + unsigned long cur_off; /* offset into current page */ + unsigned long cur_len; /* I/O len of current page, up to PAGE_SIZE */ + + unsigned long addr; /* user iovec address */ + size_t count; /* user iovec len */ + size_t nbytes = iocb->ki_nbytes = iocb->ki_left; /* total xfer size */ + loff_t size; /* size of block device */ + struct bio *bio; + atomic_t *bio_count = &iocb->ki_bio_count; + struct page *page; + struct pvec pvec; + + pvec.nr = 0; + pvec.idx = 0; + + if (pos & blocksize_mask) + return -EINVAL; + + size = i_size_read(inode); + if (pos + nbytes > size) { + nbytes = size - pos; + iocb->ki_left = nbytes; + } + + /* + * check first non-zero iov alignment, the remaining + * iov alignment is checked inside bio loop below. + */ + do { + addr = (unsigned long) iov[seg].iov_base; + count = min(iov[seg].iov_len, nbytes); + if (addr & blocksize_mask || count & blocksize_mask) + return -EINVAL; + } while (!count && ++seg < nr_segs); + atomic_set(bio_count, 1); + + while (nbytes) { + /* roughly estimate number of bio vec needed */ + nvec = (nbytes + PAGE_SIZE - 1) / PAGE_SIZE; + nvec = max(nvec, nr_segs - seg); + nvec = min(nvec, (unsigned long) BIO_MAX_PAGES); + + /* bio_alloc should not fail with GFP_KERNEL flag */ + bio = bio_alloc(GFP_KERNEL, nvec); + bio->bi_bdev = I_BDEV(inode); + bio->bi_end_io = blk_end_aio; + bio->bi_private = iocb; + bio->bi_sector = pos >> blkbits; +same_bio: + cur_off = addr & ~PAGE_MASK; + cur_len = PAGE_SIZE - cur_off; + if (count < cur_len) + cur_len = count; + + page = blk_get_page(addr, count, rw, &pvec); + if (unlikely(IS_ERR(page))) + goto backout; + + if (bio_add_page(bio, page, cur_len, cur_off)) { + pos += cur_len; + addr += cur_len; + count -= cur_len; + nbytes -= cur_len; + + if (count) + goto same_bio; + while (++seg < nr_segs) { + addr = (unsigned long) iov[seg].iov_base; + count = iov[seg].iov_len; + if (!count) + continue; + if (unlikely(addr & blocksize_mask || + count & blocksize_mask)) { + page = ERR_PTR(-EINVAL); + goto backout; + } + count = min(count, nbytes); + goto same_bio; + } + } else { + blk_unget_page(page, &pvec); + } + + /* bio is ready, submit it */ + if (rw == READ) + bio_set_pages_dirty(bio); + atomic_inc(bio_count); + submit_bio(rw, bio); + } + +completion: + iocb->ki_left -= nbytes; + nbytes = iocb->ki_left; + iocb->ki_pos += nbytes; + + blk_run_address_space(inode->i_mapping); + if (atomic_dec_and_test(bio_count)) + aio_complete(iocb, nbytes, 0); + + return -EIOCBQUEUED; + +backout: + /* + * back out nbytes count constructed so far for this bio, + * we will throw away current bio. + */ + nbytes += bio->bi_size; + bio_release_pages(bio); + bio_put(bio); + + /* + * if no bio was submmitted, return the error code. + * otherwise, proceed with pending I/O completion. + */ + if (atomic_read(bio_count) == 1) + return PTR_ERR(page); + goto completion; +} +#endif + static int blkdev_writepage(struct page *page, struct writeback_control *wbc) { return block_write_full_page(page, blkdev_get_block, wbc); @@ -1139,7 +1334,7 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) return blkdev_ioctl(file->f_mapping->host, file, cmd, arg); } -static const struct address_space_operations def_blk_aops = { +const struct address_space_operations def_blk_aops = { .readpage = blkdev_readpage, .writepage = blkdev_writepage, .sync_page = block_sync_page, diff --git a/trunk/include/asm-sparc64/ptrace.h b/trunk/include/asm-sparc64/ptrace.h index 67341cff2e6b..8617c3a5143b 100644 --- a/trunk/include/asm-sparc64/ptrace.h +++ b/trunk/include/asm-sparc64/ptrace.h @@ -102,7 +102,6 @@ do { current_thread_info()->syscall_noerror = 1; \ } while (0) #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV)) #define instruction_pointer(regs) ((regs)->tpc) -#define regs_return_value(regs) ((regs)->u_regs[UREG_I0]) #ifdef CONFIG_SMP extern unsigned long profile_pc(struct pt_regs *); #else diff --git a/trunk/include/linux/aio.h b/trunk/include/linux/aio.h index 0d0b7f629bd3..a9931e2e5624 100644 --- a/trunk/include/linux/aio.h +++ b/trunk/include/linux/aio.h @@ -105,6 +105,7 @@ struct kiocb { wait_queue_t ki_wait; loff_t ki_pos; + atomic_t ki_bio_count; /* num bio used for this iocb */ void *private; /* State that we remember to be able to restart/retry */ unsigned short ki_opcode; diff --git a/trunk/include/linux/bio.h b/trunk/include/linux/bio.h index 4c59bdccd3ee..4da441337d6e 100644 --- a/trunk/include/linux/bio.h +++ b/trunk/include/linux/bio.h @@ -326,6 +326,7 @@ extern struct bio *bio_map_kern(struct request_queue *, void *, unsigned int, gfp_t); extern void bio_set_pages_dirty(struct bio *bio); extern void bio_check_pages_dirty(struct bio *bio); +extern void bio_release_pages(struct bio *bio); extern struct bio *bio_copy_user(struct request_queue *, unsigned long, unsigned int, int); extern int bio_uncopy_user(struct bio *); void zero_fill_bio(struct bio *bio); diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h index 6fe67d1939c2..e1888cc5b8ae 100644 --- a/trunk/include/linux/blkdev.h +++ b/trunk/include/linux/blkdev.h @@ -216,7 +216,6 @@ struct request { unsigned int cmd_len; unsigned char cmd[BLK_MAX_CDB]; - unsigned int raw_data_len; unsigned int data_len; unsigned int sense_len; void *data; @@ -259,7 +258,6 @@ struct bio_vec; typedef int (merge_bvec_fn) (struct request_queue *, struct bio *, struct bio_vec *); typedef void (prepare_flush_fn) (struct request_queue *, struct request *); typedef void (softirq_done_fn)(struct request *); -typedef int (dma_drain_needed_fn)(struct request *); enum blk_queue_state { Queue_down, @@ -296,7 +294,6 @@ struct request_queue merge_bvec_fn *merge_bvec_fn; prepare_flush_fn *prepare_flush_fn; softirq_done_fn *softirq_done_fn; - dma_drain_needed_fn *dma_drain_needed; /* * Dispatch queue sorting @@ -701,9 +698,8 @@ extern void blk_queue_max_hw_segments(struct request_queue *, unsigned short); extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); extern void blk_queue_hardsect_size(struct request_queue *, unsigned short); extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b); -extern int blk_queue_dma_drain(struct request_queue *q, - dma_drain_needed_fn *dma_drain_needed, - void *buf, unsigned int size); +extern int blk_queue_dma_drain(struct request_queue *q, void *buf, + unsigned int size); extern void blk_queue_segment_boundary(struct request_queue *, unsigned long); extern void blk_queue_prep_rq(struct request_queue *, prep_rq_fn *pfn); extern void blk_queue_merge_bvec(struct request_queue *, merge_bvec_fn *); diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index b84b848431f2..98ffb6ead434 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -1590,6 +1590,7 @@ extern void bd_set_size(struct block_device *, loff_t size); extern void bd_forget(struct inode *inode); extern void bdput(struct block_device *); extern struct block_device *open_by_devnum(dev_t, unsigned); +extern const struct address_space_operations def_blk_aops; #else static inline void bd_forget(struct inode *inode) {} #endif diff --git a/trunk/include/linux/if_ether.h b/trunk/include/linux/if_ether.h index 42dc6a3571ec..e157c1399b61 100644 --- a/trunk/include/linux/if_ether.h +++ b/trunk/include/linux/if_ether.h @@ -129,7 +129,8 @@ extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len); /* * Display a 6 byte device address (MAC) in a readable format. */ -extern __pure char *print_mac(char *buf, const unsigned char *addr); +extern char *print_mac(char *buf, const unsigned char *addr); +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" #define MAC_BUF_SIZE 18 #define DECLARE_MAC_BUF(var) char var[MAC_BUF_SIZE] __maybe_unused diff --git a/trunk/include/linux/iocontext.h b/trunk/include/linux/iocontext.h index 1b4ccf25b4d2..593b222d9dcc 100644 --- a/trunk/include/linux/iocontext.h +++ b/trunk/include/linux/iocontext.h @@ -50,7 +50,6 @@ struct cfq_io_context { sector_t seek_mean; struct list_head queue_list; - struct hlist_node cic_list; void (*dtor)(struct io_context *); /* destructor */ void (*exit)(struct io_context *); /* called on task exit */ @@ -78,7 +77,6 @@ struct io_context { struct as_io_context *aic; struct radix_tree_root radix_root; - struct hlist_head cic_list; void *ioc_data; }; diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index 2e098f940cec..bc5a8d0c7090 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -278,6 +278,7 @@ enum { /* size of buffer to pad xfers ending on unaligned boundaries */ ATA_DMA_PAD_SZ = 4, + ATA_DMA_PAD_BUF_SZ = ATA_DMA_PAD_SZ * ATA_MAX_QUEUE, /* ering size */ ATA_ERING_SIZE = 32, @@ -456,18 +457,24 @@ struct ata_queued_cmd { unsigned long flags; /* ATA_QCFLAG_xxx */ unsigned int tag; unsigned int n_elem; + unsigned int mapped_n_elem; int dma_dir; + unsigned int pad_len; unsigned int sect_size; unsigned int nbytes; + unsigned int raw_nbytes; unsigned int curbytes; struct scatterlist *cursg; unsigned int cursg_ofs; + struct scatterlist *last_sg; + struct scatterlist saved_last_sg; struct scatterlist sgent; + struct scatterlist extra_sg[2]; struct scatterlist *sg; @@ -612,6 +619,9 @@ struct ata_port { struct ata_prd *prd; /* our SG list */ dma_addr_t prd_dma; /* and its DMA mapping */ + void *pad; /* array of DMA pad buffers */ + dma_addr_t pad_dma; + struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */ u8 ctl; /* cache of ATA control register */ @@ -1353,9 +1363,12 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc) qc->flags = 0; qc->cursg = NULL; qc->cursg_ofs = 0; - qc->nbytes = qc->curbytes = 0; + qc->nbytes = qc->raw_nbytes = qc->curbytes = 0; qc->n_elem = 0; + qc->mapped_n_elem = 0; qc->err_mask = 0; + qc->pad_len = 0; + qc->last_sg = NULL; qc->sect_size = ATA_SECT_SIZE; ata_tf_init(qc->dev, &qc->tf); @@ -1410,6 +1423,19 @@ static inline unsigned int __ac_err_mask(u8 status) return mask; } +static inline int ata_pad_alloc(struct ata_port *ap, struct device *dev) +{ + ap->pad_dma = 0; + ap->pad = dmam_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ, + &ap->pad_dma, GFP_KERNEL); + return (ap->pad == NULL) ? -ENOMEM : 0; +} + +static inline void ata_pad_free(struct ata_port *ap, struct device *dev) +{ + dmam_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma); +} + static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host) { return *(struct ata_port **)&host->hostdata[0]; diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index bbd8d0027e2f..412672a79e8a 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -232,8 +232,6 @@ typedef unsigned char *sk_buff_data_t; * @mark: Generic packet mark * @nfct: Associated connection, if any * @ipvs_property: skbuff is owned by ipvs - * @peeked: this packet has been seen already, so stats have been - * done for it, don't do them again * @nf_trace: netfilter packet trace flag * @nfctinfo: Relationship of this skb to the connection * @nfct_reasm: netfilter conntrack re-assembly pointer diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index fd9876087651..8a7889b35810 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -180,7 +180,6 @@ struct sock_common { * @sk_sndmsg_off: cached offset for sendmsg * @sk_send_head: front of stuff to transmit * @sk_security: used by security modules - * @sk_mark: generic packet mark * @sk_write_pending: a write to stream socket waits to start * @sk_state_change: callback to indicate change in the state of the sock * @sk_data_ready: callback to indicate there is data to be processed diff --git a/trunk/kernel/irq/chip.c b/trunk/kernel/irq/chip.c index fdb3fbe2b0c4..cc54c6276356 100644 --- a/trunk/kernel/irq/chip.c +++ b/trunk/kernel/irq/chip.c @@ -245,17 +245,6 @@ static unsigned int default_startup(unsigned int irq) return 0; } -/* - * default shutdown function - */ -static void default_shutdown(unsigned int irq) -{ - struct irq_desc *desc = irq_desc + irq; - - desc->chip->mask(irq); - desc->status |= IRQ_MASKED; -} - /* * Fixup enable/disable function pointers */ @@ -267,15 +256,8 @@ void irq_chip_set_defaults(struct irq_chip *chip) chip->disable = default_disable; if (!chip->startup) chip->startup = default_startup; - /* - * We use chip->disable, when the user provided its own. When - * we have default_disable set for chip->disable, then we need - * to use default_shutdown, otherwise the irq line is not - * disabled on free_irq(): - */ if (!chip->shutdown) - chip->shutdown = chip->disable != default_disable ? - chip->disable : default_shutdown; + chip->shutdown = chip->disable; if (!chip->name) chip->name = chip->typename; if (!chip->end) diff --git a/trunk/kernel/irq/spurious.c b/trunk/kernel/irq/spurious.c index 088dabbf2d6a..a6b2bc831dd0 100644 --- a/trunk/kernel/irq/spurious.c +++ b/trunk/kernel/irq/spurious.c @@ -6,7 +6,6 @@ * This file contains spurious interrupt handling. */ -#include #include #include #include @@ -180,7 +179,7 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc, * otherwise the couter becomes a doomsday timer for otherwise * working systems */ - if (time_after(jiffies, desc->last_unhandled + HZ/10)) + if (jiffies - desc->last_unhandled > HZ/10) desc->irqs_unhandled = 1; else desc->irqs_unhandled++; diff --git a/trunk/net/8021q/vlan_dev.c b/trunk/net/8021q/vlan_dev.c index fc60c6d096b9..77f04e49a1a0 100644 --- a/trunk/net/8021q/vlan_dev.c +++ b/trunk/net/8021q/vlan_dev.c @@ -366,8 +366,7 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_device_stats *stats = &dev->stats; struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); - DECLARE_MAC_BUF(mac); - DECLARE_MAC_BUF(mac2); + /* Handle non-VLAN frames if they are sent to us, for example by DHCP. * * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING @@ -405,8 +404,11 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) pr_debug("%s: about to send skb: %p to dev: %s\n", __FUNCTION__, skb, skb->dev->name); - pr_debug(" %s %s %4hx %4hx %4hx\n", - print_mac(mac, veth->h_dest), print_mac(mac2, veth->h_source), + pr_debug(" " MAC_FMT " " MAC_FMT " %4hx %4hx %4hx\n", + veth->h_dest[0], veth->h_dest[1], veth->h_dest[2], + veth->h_dest[3], veth->h_dest[4], veth->h_dest[5], + veth->h_source[0], veth->h_source[1], veth->h_source[2], + veth->h_source[3], veth->h_source[4], veth->h_source[5], veth->h_vlan_proto, veth->h_vlan_TCI, veth->h_vlan_encapsulated_proto); diff --git a/trunk/net/9p/trans_virtio.c b/trunk/net/9p/trans_virtio.c index 9e3d81cb9f08..0117b9fb8480 100644 --- a/trunk/net/9p/trans_virtio.c +++ b/trunk/net/9p/trans_virtio.c @@ -183,7 +183,8 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data, sg_set_buf(&sg[index++], data, s); count -= s; data += s; - BUG_ON(index > limit); + if (index > limit) + BUG(); } return index-start; diff --git a/trunk/net/ax25/ax25_out.c b/trunk/net/ax25/ax25_out.c index bf706f83a5c9..92b517af7260 100644 --- a/trunk/net/ax25/ax25_out.c +++ b/trunk/net/ax25/ax25_out.c @@ -117,12 +117,6 @@ void ax25_output(ax25_cb *ax25, int paclen, struct sk_buff *skb) unsigned char *p; int frontlen, len, fragno, ka9qfrag, first = 1; - if (paclen < 16) { - WARN_ON_ONCE(1); - kfree_skb(skb); - return; - } - if ((skb->len - 1) > paclen) { if (*skb->data == AX25_P_TEXT) { skb_pull(skb, 1); /* skip PID */ @@ -257,6 +251,8 @@ void ax25_kick(ax25_cb *ax25) if (start == end) return; + ax25->vs = start; + /* * Transmit data until either we're out of data to send or * the window is full. Send a poll on the final I frame if @@ -265,13 +261,8 @@ void ax25_kick(ax25_cb *ax25) /* * Dequeue the frame and copy it. - * Check for race with ax25_clear_queues(). */ skb = skb_dequeue(&ax25->write_queue); - if (!skb) - return; - - ax25->vs = start; do { if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) { diff --git a/trunk/net/bluetooth/hci_conn.c b/trunk/net/bluetooth/hci_conn.c index f8880261da0e..5fc7be206f62 100644 --- a/trunk/net/bluetooth/hci_conn.c +++ b/trunk/net/bluetooth/hci_conn.c @@ -260,6 +260,7 @@ int hci_conn_del(struct hci_conn *conn) tasklet_enable(&hdev->tx_task); skb_queue_purge(&conn->data_q); hci_conn_del_sysfs(conn); + hci_dev_put(hdev); return 0; } diff --git a/trunk/net/bluetooth/hci_core.c b/trunk/net/bluetooth/hci_core.c index 930b58e7149a..372b0d3b75a8 100644 --- a/trunk/net/bluetooth/hci_core.c +++ b/trunk/net/bluetooth/hci_core.c @@ -24,7 +24,6 @@ /* Bluetooth HCI core. */ -#include #include #include @@ -1322,7 +1321,7 @@ static inline void hci_sched_acl(struct hci_dev *hdev) if (!test_bit(HCI_RAW, &hdev->flags)) { /* ACL tx timeout must be longer than maximum * link supervision timeout (40.9 seconds) */ - if (!hdev->acl_cnt && time_after(jiffies, hdev->acl_last_tx + HZ * 45)) + if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45)) hci_acl_tx_to(hdev); } @@ -1544,7 +1543,7 @@ static void hci_cmd_task(unsigned long arg) BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt)); - if (!atomic_read(&hdev->cmd_cnt) && time_after(jiffies, hdev->cmd_last_tx + HZ)) { + if (!atomic_read(&hdev->cmd_cnt) && (jiffies - hdev->cmd_last_tx) > HZ) { BT_ERR("%s command tx timeout", hdev->name); atomic_set(&hdev->cmd_cnt, 1); } diff --git a/trunk/net/bluetooth/hci_sysfs.c b/trunk/net/bluetooth/hci_sysfs.c index 84360c117d4e..e13cf5ef144c 100644 --- a/trunk/net/bluetooth/hci_sysfs.c +++ b/trunk/net/bluetooth/hci_sysfs.c @@ -320,34 +320,28 @@ void hci_conn_add_sysfs(struct hci_conn *conn) queue_work(btaddconn, &conn->work); } -/* - * The rfcomm tty device will possibly retain even when conn - * is down, and sysfs doesn't support move zombie device, - * so we should move the device before conn device is destroyed. - */ static int __match_tty(struct device *dev, void *data) { - return !strncmp(dev->bus_id, "rfcomm", 6); + /* The rfcomm tty device will possibly retain even when conn + * is down, and sysfs doesn't support move zombie device, + * so we should move the device before conn device is destroyed. + * Due to the only child device of hci_conn dev is rfcomm + * tty_dev, here just return 1 + */ + return 1; } static void del_conn(struct work_struct *work) { + struct device *dev; struct hci_conn *conn = container_of(work, struct hci_conn, work); - struct hci_dev *hdev = conn->hdev; - - while (1) { - struct device *dev; - dev = device_find_child(&conn->dev, NULL, __match_tty); - if (!dev) - break; + while (dev = device_find_child(&conn->dev, NULL, __match_tty)) { device_move(dev, NULL); put_device(dev); } - device_del(&conn->dev); put_device(&conn->dev); - hci_dev_put(hdev); } void hci_conn_del_sysfs(struct hci_conn *conn) diff --git a/trunk/net/core/neighbour.c b/trunk/net/core/neighbour.c index a16cf1ec5e5e..7bb6a9a1256d 100644 --- a/trunk/net/core/neighbour.c +++ b/trunk/net/core/neighbour.c @@ -834,18 +834,12 @@ static void neigh_timer_handler(unsigned long arg) } if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) { struct sk_buff *skb = skb_peek(&neigh->arp_queue); - /* keep skb alive even if arp_queue overflows */ - if (skb) - skb_get(skb); - write_unlock(&neigh->lock); + neigh->ops->solicit(neigh, skb); atomic_inc(&neigh->probes); - if (skb) - kfree_skb(skb); - } else { -out: - write_unlock(&neigh->lock); } +out: + write_unlock(&neigh->lock); if (notify) neigh_update_notify(neigh); diff --git a/trunk/net/core/rtnetlink.c b/trunk/net/core/rtnetlink.c index 61ac8d06292c..ecb02afd52dc 100644 --- a/trunk/net/core/rtnetlink.c +++ b/trunk/net/core/rtnetlink.c @@ -504,7 +504,7 @@ int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst, u32 id, EXPORT_SYMBOL_GPL(rtnl_put_cacheinfo); -static void set_operstate(struct net_device *dev, unsigned char transition) +static int set_operstate(struct net_device *dev, unsigned char transition, bool send_notification) { unsigned char operstate = dev->operstate; @@ -527,8 +527,12 @@ static void set_operstate(struct net_device *dev, unsigned char transition) write_lock_bh(&dev_base_lock); dev->operstate = operstate; write_unlock_bh(&dev_base_lock); - netdev_state_change(dev); - } + + if (send_notification) + netdev_state_change(dev); + return 1; + } else + return 0; } static void copy_rtnl_link_stats(struct rtnl_link_stats *a, @@ -822,6 +826,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, if (tb[IFLA_BROADCAST]) { nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len); send_addr_notify = 1; + modified = 1; } if (ifm->ifi_flags || ifm->ifi_change) { @@ -834,16 +839,23 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, dev_change_flags(dev, flags); } - if (tb[IFLA_TXQLEN]) - dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); + if (tb[IFLA_TXQLEN]) { + if (dev->tx_queue_len != nla_get_u32(tb[IFLA_TXQLEN])) { + dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); + modified = 1; + } + } if (tb[IFLA_OPERSTATE]) - set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); + modified |= set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]), false); if (tb[IFLA_LINKMODE]) { - write_lock_bh(&dev_base_lock); - dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); - write_unlock_bh(&dev_base_lock); + if (dev->link_mode != nla_get_u8(tb[IFLA_LINKMODE])) { + write_lock_bh(&dev_base_lock); + dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); + write_lock_bh(&dev_base_lock); + modified = 1; + } } err = 0; @@ -857,6 +869,10 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, if (send_addr_notify) call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); + + if (modified) + netdev_state_change(dev); + return err; } @@ -974,7 +990,7 @@ struct net_device *rtnl_create_link(struct net *net, char *ifname, if (tb[IFLA_TXQLEN]) dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); if (tb[IFLA_OPERSTATE]) - set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); + set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]), true); if (tb[IFLA_LINKMODE]) dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); diff --git a/trunk/net/ipv4/arp.c b/trunk/net/ipv4/arp.c index 8e17f65f4002..c663fa5339ee 100644 --- a/trunk/net/ipv4/arp.c +++ b/trunk/net/ipv4/arp.c @@ -368,7 +368,6 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) if (!(neigh->nud_state&NUD_VALID)) printk(KERN_DEBUG "trying to ucast probe in NUD_INVALID\n"); dst_ha = neigh->ha; - read_lock_bh(&neigh->lock); } else if ((probes -= neigh->parms->app_probes) < 0) { #ifdef CONFIG_ARPD neigh_app_ns(neigh); @@ -378,8 +377,6 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr, dst_ha, dev->dev_addr, NULL); - if (dst_ha) - read_unlock_bh(&neigh->lock); } static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip) diff --git a/trunk/net/ipv4/ipconfig.c b/trunk/net/ipv4/ipconfig.c index 10013ccee8dd..a52b5853aaa8 100644 --- a/trunk/net/ipv4/ipconfig.c +++ b/trunk/net/ipv4/ipconfig.c @@ -1390,7 +1390,7 @@ static int __init ip_auto_config(void) * Clue in the operator. */ printk("IP-Config: Complete:"); - printk("\n device=%s", ic_dev->name); + printk("\n device=%s", ic_dev->name); printk(", addr=%u.%u.%u.%u", NIPQUAD(ic_myaddr)); printk(", mask=%u.%u.%u.%u", NIPQUAD(ic_netmask)); printk(", gw=%u.%u.%u.%u", NIPQUAD(ic_gateway)); diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index 00156bf421ca..63414ea427c5 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -719,7 +719,7 @@ static void tcp_v4_reqsk_send_ack(struct sk_buff *skb, } /* - * Send a SYN-ACK after having received a SYN. + * Send a SYN-ACK after having received an ACK. * This still operates on a request_sock only, not on a big * socket. */ diff --git a/trunk/net/ipv6/af_inet6.c b/trunk/net/ipv6/af_inet6.c index f0aa97738746..bddac0e8780f 100644 --- a/trunk/net/ipv6/af_inet6.c +++ b/trunk/net/ipv6/af_inet6.c @@ -752,6 +752,14 @@ static int __init inet6_init(void) BUILD_BUG_ON(sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb)); +#ifdef MODULE +#if 0 /* FIXME --RR */ + if (!mod_member_present(&__this_module, can_unload)) + return -EINVAL; + + __this_module.can_unload = &ipv6_unload; +#endif +#endif err = proto_register(&tcpv6_prot, 1); if (err) goto out; diff --git a/trunk/net/ipv6/ip6_fib.c b/trunk/net/ipv6/ip6_fib.c index bab72b6f1444..f93407cf6515 100644 --- a/trunk/net/ipv6/ip6_fib.c +++ b/trunk/net/ipv6/ip6_fib.c @@ -1151,7 +1151,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, fn = fn->parent; } /* No more references are possible at this point. */ - BUG_ON(atomic_read(&rt->rt6i_ref) != 1); + if (atomic_read(&rt->rt6i_ref) != 1) BUG(); } inet6_rt_notify(RTM_DELROUTE, rt, info); diff --git a/trunk/net/ipv6/ip6_tunnel.c b/trunk/net/ipv6/ip6_tunnel.c index cd940647bd12..9031e521c1df 100644 --- a/trunk/net/ipv6/ip6_tunnel.c +++ b/trunk/net/ipv6/ip6_tunnel.c @@ -550,7 +550,6 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ip_rt_put(rt); goto out; } - skb2->dst = (struct dst_entry *)rt; } else { ip_rt_put(rt); if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, diff --git a/trunk/net/mac80211/ieee80211.c b/trunk/net/mac80211/ieee80211.c index 28bcdf9fc3df..67b7c75c430d 100644 --- a/trunk/net/mac80211/ieee80211.c +++ b/trunk/net/mac80211/ieee80211.c @@ -165,7 +165,6 @@ static int ieee80211_open(struct net_device *dev) struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_if_init_conf conf; int res; - bool need_hw_reconfig = 0; sdata = IEEE80211_DEV_TO_SUB_IF(dev); @@ -219,7 +218,7 @@ static int ieee80211_open(struct net_device *dev) res = local->ops->start(local_to_hw(local)); if (res) return res; - need_hw_reconfig = 1; + ieee80211_hw_config(local); ieee80211_led_radio(local, local->hw.conf.radio_enabled); } @@ -283,8 +282,6 @@ static int ieee80211_open(struct net_device *dev) atomic_inc(&local->iff_promiscs); local->open_count++; - if (need_hw_reconfig) - ieee80211_hw_config(local); netif_start_queue(dev); diff --git a/trunk/net/netlabel/netlabel_cipso_v4.c b/trunk/net/netlabel/netlabel_cipso_v4.c index fdc14a0d21af..c7ad64d664ad 100644 --- a/trunk/net/netlabel/netlabel_cipso_v4.c +++ b/trunk/net/netlabel/netlabel_cipso_v4.c @@ -718,35 +718,36 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info) * NetLabel Generic NETLINK Command Definitions */ -static struct genl_ops netlbl_cipsov4_ops[] = { - { +static struct genl_ops netlbl_cipsov4_genl_c_add = { .cmd = NLBL_CIPSOV4_C_ADD, .flags = GENL_ADMIN_PERM, .policy = netlbl_cipsov4_genl_policy, .doit = netlbl_cipsov4_add, .dumpit = NULL, - }, - { +}; + +static struct genl_ops netlbl_cipsov4_genl_c_remove = { .cmd = NLBL_CIPSOV4_C_REMOVE, .flags = GENL_ADMIN_PERM, .policy = netlbl_cipsov4_genl_policy, .doit = netlbl_cipsov4_remove, .dumpit = NULL, - }, - { +}; + +static struct genl_ops netlbl_cipsov4_genl_c_list = { .cmd = NLBL_CIPSOV4_C_LIST, .flags = 0, .policy = netlbl_cipsov4_genl_policy, .doit = netlbl_cipsov4_list, .dumpit = NULL, - }, - { +}; + +static struct genl_ops netlbl_cipsov4_genl_c_listall = { .cmd = NLBL_CIPSOV4_C_LISTALL, .flags = 0, .policy = netlbl_cipsov4_genl_policy, .doit = NULL, .dumpit = netlbl_cipsov4_listall, - }, }; /* @@ -761,20 +762,30 @@ static struct genl_ops netlbl_cipsov4_ops[] = { * mechanism. Returns zero on success, negative values on failure. * */ -int __init netlbl_cipsov4_genl_init(void) +int netlbl_cipsov4_genl_init(void) { - int ret_val, i; + int ret_val; ret_val = genl_register_family(&netlbl_cipsov4_gnl_family); if (ret_val != 0) return ret_val; - for (i = 0; i < ARRAY_SIZE(netlbl_cipsov4_ops); i++) { - ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family, - &netlbl_cipsov4_ops[i]); - if (ret_val != 0) - return ret_val; - } + ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family, + &netlbl_cipsov4_genl_c_add); + if (ret_val != 0) + return ret_val; + ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family, + &netlbl_cipsov4_genl_c_remove); + if (ret_val != 0) + return ret_val; + ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family, + &netlbl_cipsov4_genl_c_list); + if (ret_val != 0) + return ret_val; + ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family, + &netlbl_cipsov4_genl_c_listall); + if (ret_val != 0) + return ret_val; return 0; } diff --git a/trunk/net/netlabel/netlabel_domainhash.c b/trunk/net/netlabel/netlabel_domainhash.c index 02c2f7c0b255..fd462313471c 100644 --- a/trunk/net/netlabel/netlabel_domainhash.c +++ b/trunk/net/netlabel/netlabel_domainhash.c @@ -171,7 +171,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain) * values on error. * */ -int __init netlbl_domhsh_init(u32 size) +int netlbl_domhsh_init(u32 size) { u32 iter; struct netlbl_domhsh_tbl *hsh_tbl; diff --git a/trunk/net/netlabel/netlabel_mgmt.c b/trunk/net/netlabel/netlabel_mgmt.c index 22c191267808..e2258dc3c845 100644 --- a/trunk/net/netlabel/netlabel_mgmt.c +++ b/trunk/net/netlabel/netlabel_mgmt.c @@ -517,63 +517,68 @@ static int netlbl_mgmt_version(struct sk_buff *skb, struct genl_info *info) * NetLabel Generic NETLINK Command Definitions */ -static struct genl_ops netlbl_mgmt_genl_ops[] = { - { +static struct genl_ops netlbl_mgmt_genl_c_add = { .cmd = NLBL_MGMT_C_ADD, .flags = GENL_ADMIN_PERM, .policy = netlbl_mgmt_genl_policy, .doit = netlbl_mgmt_add, .dumpit = NULL, - }, - { +}; + +static struct genl_ops netlbl_mgmt_genl_c_remove = { .cmd = NLBL_MGMT_C_REMOVE, .flags = GENL_ADMIN_PERM, .policy = netlbl_mgmt_genl_policy, .doit = netlbl_mgmt_remove, .dumpit = NULL, - }, - { +}; + +static struct genl_ops netlbl_mgmt_genl_c_listall = { .cmd = NLBL_MGMT_C_LISTALL, .flags = 0, .policy = netlbl_mgmt_genl_policy, .doit = NULL, .dumpit = netlbl_mgmt_listall, - }, - { +}; + +static struct genl_ops netlbl_mgmt_genl_c_adddef = { .cmd = NLBL_MGMT_C_ADDDEF, .flags = GENL_ADMIN_PERM, .policy = netlbl_mgmt_genl_policy, .doit = netlbl_mgmt_adddef, .dumpit = NULL, - }, - { +}; + +static struct genl_ops netlbl_mgmt_genl_c_removedef = { .cmd = NLBL_MGMT_C_REMOVEDEF, .flags = GENL_ADMIN_PERM, .policy = netlbl_mgmt_genl_policy, .doit = netlbl_mgmt_removedef, .dumpit = NULL, - }, - { +}; + +static struct genl_ops netlbl_mgmt_genl_c_listdef = { .cmd = NLBL_MGMT_C_LISTDEF, .flags = 0, .policy = netlbl_mgmt_genl_policy, .doit = netlbl_mgmt_listdef, .dumpit = NULL, - }, - { +}; + +static struct genl_ops netlbl_mgmt_genl_c_protocols = { .cmd = NLBL_MGMT_C_PROTOCOLS, .flags = 0, .policy = netlbl_mgmt_genl_policy, .doit = NULL, .dumpit = netlbl_mgmt_protocols, - }, - { +}; + +static struct genl_ops netlbl_mgmt_genl_c_version = { .cmd = NLBL_MGMT_C_VERSION, .flags = 0, .policy = netlbl_mgmt_genl_policy, .doit = netlbl_mgmt_version, .dumpit = NULL, - }, }; /* @@ -588,20 +593,46 @@ static struct genl_ops netlbl_mgmt_genl_ops[] = { * mechanism. Returns zero on success, negative values on failure. * */ -int __init netlbl_mgmt_genl_init(void) +int netlbl_mgmt_genl_init(void) { - int ret_val, i; + int ret_val; ret_val = genl_register_family(&netlbl_mgmt_gnl_family); if (ret_val != 0) return ret_val; - for (i = 0; i < ARRAY_SIZE(netlbl_mgmt_genl_ops); i++) { - ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, - &netlbl_mgmt_genl_ops[i]); - if (ret_val != 0) - return ret_val; - } + ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, + &netlbl_mgmt_genl_c_add); + if (ret_val != 0) + return ret_val; + ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, + &netlbl_mgmt_genl_c_remove); + if (ret_val != 0) + return ret_val; + ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, + &netlbl_mgmt_genl_c_listall); + if (ret_val != 0) + return ret_val; + ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, + &netlbl_mgmt_genl_c_adddef); + if (ret_val != 0) + return ret_val; + ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, + &netlbl_mgmt_genl_c_removedef); + if (ret_val != 0) + return ret_val; + ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, + &netlbl_mgmt_genl_c_listdef); + if (ret_val != 0) + return ret_val; + ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, + &netlbl_mgmt_genl_c_protocols); + if (ret_val != 0) + return ret_val; + ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, + &netlbl_mgmt_genl_c_version); + if (ret_val != 0) + return ret_val; return 0; } diff --git a/trunk/net/netlabel/netlabel_unlabeled.c b/trunk/net/netlabel/netlabel_unlabeled.c index 4478f2f6079d..3e745b72fded 100644 --- a/trunk/net/netlabel/netlabel_unlabeled.c +++ b/trunk/net/netlabel/netlabel_unlabeled.c @@ -1553,63 +1553,68 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb, * NetLabel Generic NETLINK Command Definitions */ -static struct genl_ops netlbl_unlabel_genl_ops[] = { - { +static struct genl_ops netlbl_unlabel_genl_c_staticadd = { .cmd = NLBL_UNLABEL_C_STATICADD, .flags = GENL_ADMIN_PERM, .policy = netlbl_unlabel_genl_policy, .doit = netlbl_unlabel_staticadd, .dumpit = NULL, - }, - { +}; + +static struct genl_ops netlbl_unlabel_genl_c_staticremove = { .cmd = NLBL_UNLABEL_C_STATICREMOVE, .flags = GENL_ADMIN_PERM, .policy = netlbl_unlabel_genl_policy, .doit = netlbl_unlabel_staticremove, .dumpit = NULL, - }, - { +}; + +static struct genl_ops netlbl_unlabel_genl_c_staticlist = { .cmd = NLBL_UNLABEL_C_STATICLIST, .flags = 0, .policy = netlbl_unlabel_genl_policy, .doit = NULL, .dumpit = netlbl_unlabel_staticlist, - }, - { +}; + +static struct genl_ops netlbl_unlabel_genl_c_staticadddef = { .cmd = NLBL_UNLABEL_C_STATICADDDEF, .flags = GENL_ADMIN_PERM, .policy = netlbl_unlabel_genl_policy, .doit = netlbl_unlabel_staticadddef, .dumpit = NULL, - }, - { +}; + +static struct genl_ops netlbl_unlabel_genl_c_staticremovedef = { .cmd = NLBL_UNLABEL_C_STATICREMOVEDEF, .flags = GENL_ADMIN_PERM, .policy = netlbl_unlabel_genl_policy, .doit = netlbl_unlabel_staticremovedef, .dumpit = NULL, - }, - { +}; + +static struct genl_ops netlbl_unlabel_genl_c_staticlistdef = { .cmd = NLBL_UNLABEL_C_STATICLISTDEF, .flags = 0, .policy = netlbl_unlabel_genl_policy, .doit = NULL, .dumpit = netlbl_unlabel_staticlistdef, - }, - { +}; + +static struct genl_ops netlbl_unlabel_genl_c_accept = { .cmd = NLBL_UNLABEL_C_ACCEPT, .flags = GENL_ADMIN_PERM, .policy = netlbl_unlabel_genl_policy, .doit = netlbl_unlabel_accept, .dumpit = NULL, - }, - { +}; + +static struct genl_ops netlbl_unlabel_genl_c_list = { .cmd = NLBL_UNLABEL_C_LIST, .flags = 0, .policy = netlbl_unlabel_genl_policy, .doit = netlbl_unlabel_list, .dumpit = NULL, - }, }; /* @@ -1624,20 +1629,53 @@ static struct genl_ops netlbl_unlabel_genl_ops[] = { * mechanism. Returns zero on success, negative values on failure. * */ -int __init netlbl_unlabel_genl_init(void) +int netlbl_unlabel_genl_init(void) { - int ret_val, i; + int ret_val; ret_val = genl_register_family(&netlbl_unlabel_gnl_family); if (ret_val != 0) return ret_val; - for (i = 0; i < ARRAY_SIZE(netlbl_unlabel_genl_ops); i++) { - ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, - &netlbl_unlabel_genl_ops[i]); - if (ret_val != 0) - return ret_val; - } + ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, + &netlbl_unlabel_genl_c_staticadd); + if (ret_val != 0) + return ret_val; + + ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, + &netlbl_unlabel_genl_c_staticremove); + if (ret_val != 0) + return ret_val; + + ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, + &netlbl_unlabel_genl_c_staticlist); + if (ret_val != 0) + return ret_val; + + ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, + &netlbl_unlabel_genl_c_staticadddef); + if (ret_val != 0) + return ret_val; + + ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, + &netlbl_unlabel_genl_c_staticremovedef); + if (ret_val != 0) + return ret_val; + + ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, + &netlbl_unlabel_genl_c_staticlistdef); + if (ret_val != 0) + return ret_val; + + ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, + &netlbl_unlabel_genl_c_accept); + if (ret_val != 0) + return ret_val; + + ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, + &netlbl_unlabel_genl_c_list); + if (ret_val != 0) + return ret_val; return 0; } @@ -1661,7 +1699,7 @@ static struct notifier_block netlbl_unlhsh_netdev_notifier = { * non-zero values on error. * */ -int __init netlbl_unlabel_init(u32 size) +int netlbl_unlabel_init(u32 size) { u32 iter; struct netlbl_unlhsh_tbl *hsh_tbl; @@ -1765,7 +1803,7 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb, * and to send unlabeled network traffic by default. * */ -int __init netlbl_unlabel_defconf(void) +int netlbl_unlabel_defconf(void) { int ret_val; struct netlbl_dom_map *entry; diff --git a/trunk/net/netlabel/netlabel_user.c b/trunk/net/netlabel/netlabel_user.c index b17d4203806e..023fc8fe840d 100644 --- a/trunk/net/netlabel/netlabel_user.c +++ b/trunk/net/netlabel/netlabel_user.c @@ -59,7 +59,7 @@ * non-zero on failure. * */ -int __init netlbl_netlink_init(void) +int netlbl_netlink_init(void) { int ret_val; diff --git a/trunk/net/rxrpc/ar-accept.c b/trunk/net/rxrpc/ar-accept.c index bdfb77417794..92a87fde8bfe 100644 --- a/trunk/net/rxrpc/ar-accept.c +++ b/trunk/net/rxrpc/ar-accept.c @@ -156,7 +156,8 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local, false); spin_unlock(&call->lock); notification = NULL; - BUG_ON(ret < 0); + if (ret < 0) + BUG(); } spin_unlock(&call->conn->state_lock); diff --git a/trunk/net/rxrpc/ar-ack.c b/trunk/net/rxrpc/ar-ack.c index 3ac1672e1070..657ee69f2133 100644 --- a/trunk/net/rxrpc/ar-ack.c +++ b/trunk/net/rxrpc/ar-ack.c @@ -814,7 +814,8 @@ static int rxrpc_post_message(struct rxrpc_call *call, u32 mark, u32 error, spin_lock_bh(&call->lock); ret = rxrpc_queue_rcv_skb(call, skb, true, fatal); spin_unlock_bh(&call->lock); - BUG_ON(ret < 0); + if (ret < 0) + BUG(); } return 0; diff --git a/trunk/net/xfrm/xfrm_policy.c b/trunk/net/xfrm/xfrm_policy.c index 9fc4c315f6cd..47219f98053f 100644 --- a/trunk/net/xfrm/xfrm_policy.c +++ b/trunk/net/xfrm/xfrm_policy.c @@ -331,31 +331,15 @@ static void xfrm_dst_hash_transfer(struct hlist_head *list, struct hlist_head *ndsttable, unsigned int nhashmask) { - struct hlist_node *entry, *tmp, *entry0 = NULL; + struct hlist_node *entry, *tmp; struct xfrm_policy *pol; - unsigned int h0 = 0; -redo: hlist_for_each_entry_safe(pol, entry, tmp, list, bydst) { unsigned int h; h = __addr_hash(&pol->selector.daddr, &pol->selector.saddr, pol->family, nhashmask); - if (!entry0) { - hlist_del(entry); - hlist_add_head(&pol->bydst, ndsttable+h); - h0 = h; - } else { - if (h != h0) - continue; - hlist_del(entry); - hlist_add_after(entry0, &pol->bydst); - } - entry0 = entry; - } - if (!hlist_empty(list)) { - entry0 = NULL; - goto redo; + hlist_add_head(&pol->bydst, ndsttable+h); } } diff --git a/trunk/security/smack/smack_lsm.c b/trunk/security/smack/smack_lsm.c index 25cbfa3f71f4..2b5d6f72f678 100644 --- a/trunk/security/smack/smack_lsm.c +++ b/trunk/security/smack/smack_lsm.c @@ -1251,8 +1251,9 @@ static void smack_to_secattr(char *smack, struct netlbl_lsm_secattr *nlsp) switch (smack_net_nltype) { case NETLBL_NLTYPE_CIPSOV4: - nlsp->domain = kstrdup(smack, GFP_ATOMIC); - nlsp->flags = NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL; + nlsp->domain = NULL; + nlsp->flags = NETLBL_SECATTR_DOMAIN; + nlsp->flags |= NETLBL_SECATTR_MLS_LVL; rc = smack_to_cipso(smack, &cipso); if (rc == 0) { @@ -1281,14 +1282,15 @@ static int smack_netlabel(struct sock *sk) { struct socket_smack *ssp; struct netlbl_lsm_secattr secattr; - int rc; + int rc = 0; ssp = sk->sk_security; netlbl_secattr_init(&secattr); smack_to_secattr(ssp->smk_out, &secattr); - rc = netlbl_sock_setattr(sk, &secattr); - netlbl_secattr_destroy(&secattr); + if (secattr.flags != NETLBL_SECATTR_NONE) + rc = netlbl_sock_setattr(sk, &secattr); + netlbl_secattr_destroy(&secattr); return rc; } @@ -1311,7 +1313,6 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, struct inode_smack *nsp = inode->i_security; struct socket_smack *ssp; struct socket *sock; - int rc = 0; if (value == NULL || size > SMK_LABELLEN) return -EACCES; @@ -1340,10 +1341,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, ssp->smk_in = sp; else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { ssp->smk_out = sp; - rc = smack_netlabel(sock->sk); - if (rc != 0) - printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n", - __func__, -rc); + return smack_netlabel(sock->sk); } else return -EOPNOTSUPP; @@ -2216,9 +2214,6 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent) ssp->smk_packet[0] = '\0'; rc = smack_netlabel(sk); - if (rc != 0) - printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n", - __func__, -rc); } /** @@ -2350,20 +2345,6 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) return 0; } -/* - * smack_secctx_to_secid - return the secid for a smack label - * @secdata: smack label - * @seclen: how long result is - * @secid: outgoing integer - * - * Exists for audit and networking code. - */ -static int smack_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) -{ - *secid = smack_to_secid(secdata); - return 0; -} - /* * smack_release_secctx - don't do anything. * @key_ref: unused @@ -2494,7 +2475,6 @@ static struct security_operations smack_ops = { .key_permission = smack_key_permission, #endif /* CONFIG_KEYS */ .secid_to_secctx = smack_secid_to_secctx, - .secctx_to_secid = smack_secctx_to_secid, .release_secctx = smack_release_secctx, }; diff --git a/trunk/security/smack/smackfs.c b/trunk/security/smack/smackfs.c index 358c92c1a153..15aa37f65b39 100644 --- a/trunk/security/smack/smackfs.c +++ b/trunk/security/smack/smackfs.c @@ -24,7 +24,6 @@ #include #include #include -#include #include "smack.h" /* @@ -46,7 +45,6 @@ enum smk_inos { */ static DEFINE_MUTEX(smack_list_lock); static DEFINE_MUTEX(smack_cipso_lock); -static DEFINE_MUTEX(smack_ambient_lock); /* * This is the "ambient" label for network traffic. @@ -344,9 +342,6 @@ void smk_cipso_doi(void) struct cipso_v4_doi *doip; struct netlbl_audit audit_info; - audit_info.loginuid = audit_get_loginuid(current); - audit_info.secid = smack_to_secid(current->security); - rc = netlbl_cfg_map_del(NULL, &audit_info); if (rc != 0) printk(KERN_WARNING "%s:%d remove rc = %d\n", @@ -368,30 +363,6 @@ void smk_cipso_doi(void) __func__, __LINE__, rc); } -/** - * smk_unlbl_ambient - initialize the unlabeled domain - */ -void smk_unlbl_ambient(char *oldambient) -{ - int rc; - struct netlbl_audit audit_info; - - audit_info.loginuid = audit_get_loginuid(current); - audit_info.secid = smack_to_secid(current->security); - - if (oldambient != NULL) { - rc = netlbl_cfg_map_del(oldambient, &audit_info); - if (rc != 0) - printk(KERN_WARNING "%s:%d remove rc = %d\n", - __func__, __LINE__, rc); - } - - rc = netlbl_cfg_unlbl_add_map(smack_net_ambient, &audit_info); - if (rc != 0) - printk(KERN_WARNING "%s:%d add rc = %d\n", - __func__, __LINE__, rc); -} - /* * Seq_file read operations for /smack/cipso */ @@ -738,6 +709,7 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf, size_t cn, loff_t *ppos) { ssize_t rc; + char out[SMK_LABELLEN]; int asize; if (*ppos != 0) @@ -745,18 +717,23 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf, /* * Being careful to avoid a problem in the case where * smack_net_ambient gets changed in midstream. + * Since smack_net_ambient is always set with a value + * from the label list, including initially, and those + * never get freed, the worst case is that the pointer + * gets changed just after this strncpy, in which case + * the value passed up is incorrect. Locking around + * smack_net_ambient wouldn't be any better than this + * copy scheme as by the time the caller got to look + * at the ambient value it would have cleared the lock + * and been changed. */ - mutex_lock(&smack_ambient_lock); + strncpy(out, smack_net_ambient, SMK_LABELLEN); + asize = strlen(out) + 1; - asize = strlen(smack_net_ambient) + 1; - - if (cn >= asize) - rc = simple_read_from_buffer(buf, cn, ppos, - smack_net_ambient, asize); - else - rc = -EINVAL; + if (cn < asize) + return -EINVAL; - mutex_unlock(&smack_ambient_lock); + rc = simple_read_from_buffer(buf, cn, ppos, out, asize); return rc; } @@ -774,7 +751,6 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { char in[SMK_LABELLEN]; - char *oldambient; char *smack; if (!capable(CAP_MAC_ADMIN)) @@ -790,13 +766,7 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf, if (smack == NULL) return -EINVAL; - mutex_lock(&smack_ambient_lock); - - oldambient = smack_net_ambient; smack_net_ambient = smack; - smk_unlbl_ambient(oldambient); - - mutex_unlock(&smack_ambient_lock); return count; } @@ -1004,7 +974,6 @@ static int __init init_smk_fs(void) sema_init(&smack_write_sem, 1); smk_cipso_doi(); - smk_unlbl_ambient(NULL); return err; }