diff options
242 files changed, 2028 insertions, 1973 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index e99028ca2f7..b2afc7ae965 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1676,10 +1676,8 @@ L: linux-kernel@vger.kernel.org S: Maintained LAPB module -P: Henner Eisen -M: eis@baty.hanse.de L: linux-x25@vger.kernel.org -S: Maintained +S: Orphan LASI 53c700 driver for PARISC P: James E.J. Bottomley diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index d00de17b377..a4dc61f3285 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S @@ -273,7 +273,7 @@ startup_continue: .Lbss_end: .long _end .Lparmaddr: .long PARMAREA .Lsccbaddr: .long .Lsccb - .align 4096 + .org 0x12000 .Lsccb: .hword 0x1000 # length, one page .byte 0x00,0x00,0x00 @@ -290,7 +290,7 @@ startup_continue: .Lscpincr2: .quad 0x00 .fill 3984,1,0 - .align 4096 + .org 0x13000 #ifdef CONFIG_SHARED_KERNEL .org 0x100000 diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 47744fcca93..9d80c5b1ef9 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S @@ -268,7 +268,7 @@ startup_continue: .Lparmaddr: .quad PARMAREA - .align 4096 + .org 0x12000 .Lsccb: .hword 0x1000 # length, one page .byte 0x00,0x00,0x00 @@ -285,7 +285,7 @@ startup_continue: .Lscpincr2: .quad 0x00 .fill 3984,1,0 - .align 4096 + .org 0x13000 #ifdef CONFIG_SHARED_KERNEL .org 0x100000 diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 1ca34f54ea8..c902f059c7a 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -877,31 +877,57 @@ static struct bin_attribute ipl_scp_data_attr = { static decl_subsys(ipl, NULL, NULL); +static int ipl_register_fcp_files(void) +{ + int rc; + + rc = sysfs_create_group(&ipl_subsys.kset.kobj, + &ipl_fcp_attr_group); + if (rc) + goto out; + rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj, + &ipl_parameter_attr); + if (rc) + goto out_ipl_parm; + rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj, + &ipl_scp_data_attr); + if (!rc) + goto out; + + sysfs_remove_bin_file(&ipl_subsys.kset.kobj, &ipl_parameter_attr); + +out_ipl_parm: + sysfs_remove_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group); +out: + return rc; +} + static int __init ipl_device_sysfs_register(void) { int rc; rc = firmware_register(&ipl_subsys); if (rc) - return rc; + goto out; switch (get_ipl_type()) { case ipl_type_ccw: - sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_ccw_attr_group); + rc = sysfs_create_group(&ipl_subsys.kset.kobj, + &ipl_ccw_attr_group); break; case ipl_type_fcp: - sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group); - sysfs_create_bin_file(&ipl_subsys.kset.kobj, - &ipl_parameter_attr); - sysfs_create_bin_file(&ipl_subsys.kset.kobj, - &ipl_scp_data_attr); + rc = ipl_register_fcp_files(); break; default: - sysfs_create_group(&ipl_subsys.kset.kobj, - &ipl_unknown_attr_group); + rc = sysfs_create_group(&ipl_subsys.kset.kobj, + &ipl_unknown_attr_group); break; } - return 0; + + if (rc) + firmware_unregister(&ipl_subsys); +out: + return rc; } __initcall(ipl_device_sysfs_register); diff --git a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c index adba9dfee35..af90a5f9ab5 100644 --- a/arch/sparc/kernel/devices.c +++ b/arch/sparc/kernel/devices.c @@ -15,6 +15,7 @@ #include <asm/page.h> #include <asm/oplib.h> +#include <asm/prom.h> #include <asm/smp.h> #include <asm/system.h> #include <asm/cpudata.h> @@ -34,12 +35,6 @@ static int check_cpu_node(int nd, int *cur_inst, int (*compare)(int, int, void *), void *compare_arg, int *prom_node, int *mid) { - char node_str[128]; - - prom_getstring(nd, "device_type", node_str, sizeof(node_str)); - if (strcmp(node_str, "cpu")) - return -ENODEV; - if (!compare(nd, *cur_inst, compare_arg)) { if (prom_node) *prom_node = nd; @@ -59,20 +54,14 @@ static int check_cpu_node(int nd, int *cur_inst, static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg, int *prom_node, int *mid) { - int nd, cur_inst, err; + struct device_node *dp; + int cur_inst; - nd = prom_root_node; cur_inst = 0; - - err = check_cpu_node(nd, &cur_inst, compare, compare_arg, - prom_node, mid); - if (!err) - return 0; - - nd = prom_getchild(nd); - while ((nd = prom_getsibling(nd)) != 0) { - err = check_cpu_node(nd, &cur_inst, compare, compare_arg, - prom_node, mid); + for_each_node_by_type(dp, "cpu") { + int err = check_cpu_node(dp->node, &cur_inst, + compare, compare_arg, + prom_node, mid); if (!err) return 0; } diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c index cde73327ca9..72f0201051a 100644 --- a/arch/sparc/kernel/irq.c +++ b/arch/sparc/kernel/irq.c @@ -329,7 +329,7 @@ void handler_irq(int irq, struct pt_regs * regs) disable_pil_irq(irq); #ifdef CONFIG_SMP /* Only rotate on lower priority IRQ's (scsi, ethernet, etc.). */ - if(irq < 10) + if((sparc_cpu_model==sun4m) && (irq < 10)) smp4m_irq_rotate(cpu); #endif action = sparc_irq[irq].action; diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index 5a2faad5d04..97bf87e8cdd 100644 --- a/arch/sparc/kernel/of_device.c +++ b/arch/sparc/kernel/of_device.c @@ -596,14 +596,41 @@ static struct of_device * __init scan_one_device(struct device_node *dp, static int pil_to_sbus[] = { 0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0, }; - struct device_node *busp = dp->parent; + struct device_node *io_unit, *sbi = dp->parent; struct linux_prom_registers *regs; - int board = of_getintprop_default(busp, "board#", 0); - int slot; + int board, slot; + + while (sbi) { + if (!strcmp(sbi->name, "sbi")) + break; + + sbi = sbi->parent; + } + if (!sbi) + goto build_resources; regs = of_get_property(dp, "reg", NULL); + if (!regs) + goto build_resources; + slot = regs->which_io; + /* If SBI's parent is not io-unit or the io-unit lacks + * a "board#" property, something is very wrong. + */ + if (!sbi->parent || strcmp(sbi->parent->name, "io-unit")) { + printk("%s: Error, parent is not io-unit.\n", + sbi->full_name); + goto build_resources; + } + io_unit = sbi->parent; + board = of_getintprop_default(io_unit, "board#", -1); + if (board == -1) { + printk("%s: Error, lacks board# property.\n", + io_unit->full_name); + goto build_resources; + } + for (i = 0; i < op->num_irqs; i++) { int this_irq = op->irqs[i]; int sbusl = pil_to_sbus[this_irq]; @@ -617,6 +644,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, } } +build_resources: build_device_resources(op, parent); op->dev.parent = parent; diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c index 4b06dcb00eb..4ca9e5fc97f 100644 --- a/arch/sparc/kernel/prom.c +++ b/arch/sparc/kernel/prom.c @@ -444,6 +444,7 @@ static struct property * __init build_one_prop(phandle node, char *prev, char *s static struct property *tmp = NULL; struct property *p; int len; + const char *name; if (tmp) { p = tmp; @@ -456,19 +457,21 @@ static struct property * __init build_one_prop(phandle node, char *prev, char *s p->name = (char *) (p + 1); if (special_name) { + strcpy(p->name, special_name); p->length = special_len; p->value = prom_early_alloc(special_len); memcpy(p->value, special_val, special_len); } else { if (prev == NULL) { - prom_firstprop(node, p->name); + name = prom_firstprop(node, NULL); } else { - prom_nextprop(node, prev, p->name); + name = prom_nextprop(node, prev, NULL); } - if (strlen(p->name) == 0) { + if (strlen(name) == 0) { tmp = p; return NULL; } + strcpy(p->name, name); p->length = prom_getproplen(node, p->name); if (p->length <= 0) { p->length = 0; diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c index 6135d4faeee..e311ade1b49 100644 --- a/arch/sparc/kernel/smp.c +++ b/arch/sparc/kernel/smp.c @@ -87,6 +87,7 @@ void __cpuinit smp_store_cpu_info(int id) void __init smp_cpus_done(unsigned int max_cpus) { extern void smp4m_smp_done(void); + extern void smp4d_smp_done(void); unsigned long bogosum = 0; int cpu, num; @@ -100,8 +101,34 @@ void __init smp_cpus_done(unsigned int max_cpus) num, bogosum/(500000/HZ), (bogosum/(5000/HZ))%100); - BUG_ON(sparc_cpu_model != sun4m); - smp4m_smp_done(); + switch(sparc_cpu_model) { + case sun4: + printk("SUN4\n"); + BUG(); + break; + case sun4c: + printk("SUN4C\n"); + BUG(); + break; + case sun4m: + smp4m_smp_done(); + break; + case sun4d: + smp4d_smp_done(); + break; + case sun4e: + printk("SUN4E\n"); + BUG(); + break; + case sun4u: + printk("SUN4U\n"); + BUG(); + break; + default: + printk("UNKNOWN!\n"); + BUG(); + break; + }; } void cpu_panic(void) @@ -267,9 +294,9 @@ int setup_profiling_timer(unsigned int multiplier) void __init smp_prepare_cpus(unsigned int max_cpus) { extern void smp4m_boot_cpus(void); + extern void smp4d_boot_cpus(void); int i, cpuid, extra; - BUG_ON(sparc_cpu_model != sun4m); printk("Entering SMP Mode...\n"); extra = 0; @@ -283,7 +310,34 @@ void __init smp_prepare_cpus(unsigned int max_cpus) smp_store_cpu_info(boot_cpu_id); - smp4m_boot_cpus(); + switch(sparc_cpu_model) { + case sun4: + printk("SUN4\n"); + BUG(); + break; + case sun4c: + printk("SUN4C\n"); + BUG(); + break; + case sun4m: + smp4m_boot_cpus(); + break; + case sun4d: + smp4d_boot_cpus(); + break; + case sun4e: + printk("SUN4E\n"); + BUG(); + break; + case sun4u: + printk("SUN4U\n"); + BUG(); + break; + default: + printk("UNKNOWN!\n"); + BUG(); + break; + }; } /* Set this up early so that things like the scheduler can init @@ -323,9 +377,37 @@ void __init smp_prepare_boot_cpu(void) int __cpuinit __cpu_up(unsigned int cpu) { extern int smp4m_boot_one_cpu(int); - int ret; - - ret = smp4m_boot_one_cpu(cpu); + extern int smp4d_boot_one_cpu(int); + int ret=0; + + switch(sparc_cpu_model) { + case sun4: + printk("SUN4\n"); + BUG(); + break; + case sun4c: + printk("SUN4C\n"); + BUG(); + break; + case sun4m: + ret = smp4m_boot_one_cpu(cpu); + break; + case sun4d: + ret = smp4d_boot_one_cpu(cpu); + break; + case sun4e: + printk("SUN4E\n"); + BUG(); + break; + case sun4u: + printk("SUN4U\n"); + BUG(); + break; + default: + printk("UNKNOWN!\n"); + BUG(); + break; + }; if (!ret) { cpu_set(cpu, smp_commenced_mask); diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index 5fb987fc3d6..4d441a554d3 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -237,7 +237,6 @@ EXPORT_SYMBOL(prom_node_has_property); EXPORT_SYMBOL(prom_setprop); EXPORT_SYMBOL(saved_command_line); EXPORT_SYMBOL(prom_apply_obio_ranges); -EXPORT_SYMBOL(prom_getname); EXPORT_SYMBOL(prom_feval); EXPORT_SYMBOL(prom_getbool); EXPORT_SYMBOL(prom_getstring); diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index b141b7ee671..ba843f6a283 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c @@ -43,15 +43,10 @@ extern ctxd_t *srmmu_ctx_table_phys; extern void calibrate_delay(void); extern volatile int smp_processors_ready; -extern int smp_num_cpus; static int smp_highest_cpu; extern volatile unsigned long cpu_callin_map[NR_CPUS]; extern cpuinfo_sparc cpu_data[NR_CPUS]; extern unsigned char boot_cpu_id; -extern int smp_activated; -extern volatile int __cpu_number_map[NR_CPUS]; -extern volatile int __cpu_logical_map[NR_CPUS]; -extern volatile unsigned long ipi_count; extern volatile int smp_process_available; extern cpumask_t smp_commenced_mask; @@ -144,6 +139,8 @@ void __init smp4d_callin(void) spin_lock_irqsave(&sun4d_imsk_lock, flags); cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */ spin_unlock_irqrestore(&sun4d_imsk_lock, flags); + cpu_set(cpuid, cpu_online_map); + } extern void init_IRQ(void); @@ -160,51 +157,24 @@ extern unsigned long trapbase_cpu3[]; void __init smp4d_boot_cpus(void) { - int cpucount = 0; - int i, mid; - - printk("Entering SMP Mode...\n"); - if (boot_cpu_id) current_set[0] = NULL; - - local_irq_enable(); - cpus_clear(cpu_present_map); - - /* XXX This whole thing has to go. See sparc64. */ - for (i = 0; !cpu_find_by_instance(i, NULL, &mid); i++) - cpu_set(mid, cpu_present_map); - SMP_PRINTK(("cpu_present_map %08lx\n", cpus_addr(cpu_present_map)[0])); - for(i=0; i < NR_CPUS; i++) - __cpu_number_map[i] = -1; - for(i=0; i < NR_CPUS; i++) - __cpu_logical_map[i] = -1; - __cpu_number_map[boot_cpu_id] = 0; - __cpu_logical_map[0] = boot_cpu_id; - current_thread_info()->cpu = boot_cpu_id; - smp_store_cpu_info(boot_cpu_id); smp_setup_percpu_timer(); local_flush_cache_all(); - if (cpu_find_by_instance(1, NULL, NULL)) - return; /* Not an MP box. */ - SMP_PRINTK(("Iterating over CPUs\n")); - for(i = 0; i < NR_CPUS; i++) { - if(i == boot_cpu_id) - continue; - - if (cpu_isset(i, cpu_present_map)) { +} + +int smp4d_boot_one_cpu(int i) +{ extern unsigned long sun4d_cpu_startup; unsigned long *entry = &sun4d_cpu_startup; struct task_struct *p; int timeout; - int no; + int cpu_node; + cpu_find_by_instance(i, &cpu_node,NULL); /* Cook up an idler for this guy. */ p = fork_idle(i); - cpucount++; current_set[i] = task_thread_info(p); - for (no = 0; !cpu_find_by_instance(no, NULL, &mid) - && mid != i; no++) ; /* * Initialize the contexts table @@ -216,9 +186,9 @@ void __init smp4d_boot_cpus(void) smp_penguin_ctable.reg_size = 0; /* whirrr, whirrr, whirrrrrrrrr... */ - SMP_PRINTK(("Starting CPU %d at %p task %d node %08x\n", i, entry, cpucount, cpu_data(no).prom_node)); + SMP_PRINTK(("Starting CPU %d at %p \n", i, entry)); local_flush_cache_all(); - prom_startcpu(cpu_data(no).prom_node, + prom_startcpu(cpu_node, &smp_penguin_ctable, 0, (char *)entry); SMP_PRINTK(("prom_startcpu returned :)\n")); @@ -230,39 +200,30 @@ void __init smp4d_boot_cpus(void) udelay(200); } - if(cpu_callin_map[i]) { - /* Another "Red Snapper". */ - __cpu_number_map[i] = cpucount; - __cpu_logical_map[cpucount] = i; - } else { - cpucount--; - printk("Processor %d is stuck.\n", i); - } - } - if(!(cpu_callin_map[i])) { - cpu_clear(i, cpu_present_map); - __cpu_number_map[i] = -1; - } + if (!(cpu_callin_map[i])) { + printk("Processor %d is stuck.\n", i); + return -ENODEV; + } local_flush_cache_all(); - if(cpucount == 0) { - printk("Error: only one Processor found.\n"); - cpu_present_map = cpumask_of_cpu(hard_smp4d_processor_id()); - } else { - unsigned long bogosum = 0; - - for_each_present_cpu(i) { - bogosum += cpu_data(i).udelay_val; - smp_highest_cpu = i; + return 0; +} + +void __init smp4d_smp_done(void) +{ + int i, first; + int *prev; + + /* setup cpu list for irq rotation */ + first = 0; + prev = &first; + for (i = 0; i < NR_CPUS; i++) + if (cpu_online(i)) { + *prev = i; + prev = &cpu_data(i).next; } - SMP_PRINTK(("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n", cpucount + 1, bogosum/(500000/HZ), (bogosum/(5000/HZ))%100)); - printk("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n", - cpucount + 1, - bogosum/(500000/HZ), - (bogosum/(5000/HZ))%100); - smp_activated = 1; - smp_num_cpus = cpucount + 1; - } + *prev = first; + local_flush_cache_all(); /* Free unneeded trap tables */ ClearPageReserved(virt_to_page(trapbase_cpu1)); @@ -334,7 +295,7 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, register int i; mask = cpumask_of_cpu(hard_smp4d_processor_id()); - cpus_andnot(mask, cpu_present_map, mask); + cpus_andnot(mask, cpu_online_map, mask); for(i = 0; i <= high; i++) { if (cpu_isset(i, mask)) { ccall_info.processors_in[i] = 0; diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index 0cdfc9d294b..a41c8a5c200 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c @@ -465,21 +465,21 @@ sys_rt_sigaction(int sig, asmlinkage int sys_getdomainname(char __user *name, int len) { - int nlen; - int err = -EFAULT; + int nlen, err; + if (len < 0 || len > __NEW_UTS_LEN) + return -EINVAL; + down_read(&uts_sem); nlen = strlen(system_utsname.domainname) + 1; - if (nlen < len) len = nlen; - if (len > __NEW_UTS_LEN) - goto done; - if (copy_to_user(name, system_utsname.domainname, len)) - goto done; - err = 0; -done: + + err = -EFAULT; + if (!copy_to_user(name, system_utsname.domainname, len)) + err = 0; + up_read(&uts_sem); return err; } diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index 42c1c700c0a..2bb1309003d 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -64,6 +64,7 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus) sbus->iommu = (struct iommu_struct *)iounit; iounit->page_table = xpt; + spin_lock_init(&iounit->lock); for (xptend = iounit->page_table + (16 * PAGE_SIZE) / sizeof(iopte_t); xpt < xptend;) diff --git a/arch/sparc/prom/tree.c b/arch/sparc/prom/tree.c index 2bf03ee8cde..5ec246573a9 100644 --- a/arch/sparc/prom/tree.c +++ b/arch/sparc/prom/tree.c @@ -205,24 +205,6 @@ int prom_searchsiblings(int node_start, char *nodename) return 0; } -/* Gets name in the form prom v2+ uses it (name@x,yyyyy or name (if no reg)) */ -int prom_getname (int node, char *buffer, int len) -{ - int i; - struct linux_prom_registers reg[PROMREG_MAX]; - - i = prom_getproperty (node, "name", buffer, len); - if (i <= 0) return -1; - buffer [i] = 0; - len -= i; - i = prom_getproperty (node, "reg", (char *)reg, sizeof (reg)); - if (i <= 0) return 0; - if (len < 11) return -1; - buffer = strchr (buffer, 0); - sprintf (buffer, "@%x,%x", reg[0].which_io, (uint)reg[0].phys_addr); - return 0; -} - /* Interal version of nextprop that does not alter return values. */ char * __prom_nextprop(int node, char * oprop) { diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 38353621069..43d9229fca0 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-rc1 -# Wed Jul 12 14:00:58 2006 +# Linux kernel version: 2.6.18-rc2 +# Fri Jul 21 14:19:24 2006 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -36,6 +36,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set @@ -1120,7 +1121,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set -# CONFIG_USB_CY7C63 is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set @@ -1279,7 +1280,6 @@ CONFIG_RAMFS=y # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set -# CONFIG_CIFS_DEBUG2 is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set diff --git a/arch/sparc64/kernel/devices.c b/arch/sparc64/kernel/devices.c index f8ef2f2b9b3..ec10f7edcf8 100644 --- a/arch/sparc64/kernel/devices.c +++ b/arch/sparc64/kernel/devices.c @@ -66,9 +66,6 @@ static int check_cpu_node(struct device_node *dp, int *cur_inst, void *compare_arg, struct device_node **dev_node, int *mid) { - if (strcmp(dp->type, "cpu")) - return -ENODEV; - if (!compare(dp, *cur_inst, compare_arg)) { if (dev_node) *dev_node = dp; diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 7064cee290a..238bbf6de07 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c @@ -542,9 +542,17 @@ static void __init build_device_resources(struct of_device *op, /* Convert to num-cells. */ num_reg /= 4; - /* Conver to num-entries. */ + /* Convert to num-entries. */ num_reg /= na + ns; + /* Prevent overruning the op->resources[] array. */ + if (num_reg > PROMREG_MAX) { + printk(KERN_WARNING "%s: Too many regs (%d), " + "limiting to %d.\n", + op->node->full_name, num_reg, PROMREG_MAX); + num_reg = PROMREG_MAX; + } + for (index = 0; index < num_reg; index++) { struct resource *r = &op->resource[index]; u32 addr[OF_MAX_ADDR_CELLS]; @@ -650,8 +658,22 @@ apply_interrupt_map(struct device_node *dp, struct device_node *pp, next: imap += (na + 3); } - if (i == imlen) + if (i == imlen) { + /* Psycho and Sabre PCI controllers can have 'interrupt-map' + * properties that do not include the on-board device + * interrupts. Instead, the device's 'interrupts' property + * is already a fully specified INO value. + * + * Handle this by deciding that, if we didn't get a + * match in the parent's 'interrupt-map', and the + * parent is an IRQ translater, then use the parent as + * our IRQ controller. + */ + if (pp->irq_trans) + return pp; + return NULL; + } *irq_p = irq; cp = of_find_node_by_phandle(handle); @@ -803,6 +825,14 @@ static struct of_device * __init scan_one_device(struct device_node *dp, op->num_irqs = 0; } + /* Prevent overruning the op->irqs[] array. */ + if (op->num_irqs > PROMINTR_MAX) { + printk(KERN_WARNING "%s: Too many irqs (%d), " + "limiting to %d.\n", + dp->full_name, op->num_irqs, PROMINTR_MAX); + op->num_irqs = PROMINTR_MAX; + } + build_device_resources(op, parent); for (i = 0; i < op->num_irqs; i++) op->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]); diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index c86007a2aa3..5cc5ab63293 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c @@ -344,10 +344,12 @@ static unsigned long __psycho_onboard_imap_off[] = { /*0x2f*/ PSYCHO_IMAP_CE, /*0x30*/ PSYCHO_IMAP_A_ERR, /*0x31*/ PSYCHO_IMAP_B_ERR, -/*0x32*/ PSYCHO_IMAP_PMGMT +/*0x32*/ PSYCHO_IMAP_PMGMT, +/*0x33*/ PSYCHO_IMAP_GFX, +/*0x34*/ PSYCHO_IMAP_EUPA, }; #define PSYCHO_ONBOARD_IRQ_BASE 0x20 -#define PSYCHO_ONBOARD_IRQ_LAST 0x32 +#define PSYCHO_ONBOARD_IRQ_LAST 0x34 #define psycho_onboard_imap_offset(__ino) \ __psycho_onboard_imap_off[(__ino) - PSYCHO_ONBOARD_IRQ_BASE] @@ -529,6 +531,10 @@ static unsigned long __sabre_onboard_imap_off[] = { /*0x2e*/ SABRE_IMAP_UE, /*0x2f*/ SABRE_IMAP_CE, /*0x30*/ SABRE_IMAP_PCIERR, +/*0x31*/ 0 /* reserved */, +/*0x32*/ 0 /* reserved */, +/*0x33*/ SABRE_IMAP_GFX, +/*0x34*/ SABRE_IMAP_EUPA, }; #define SABRE_ONBOARD_IRQ_BASE 0x20 #define SABRE_ONBOARD_IRQ_LAST 0x30 @@ -895,6 +901,8 @@ static unsigned long sysio_irq_offsets[] = { SYSIO_IMAP_CE, SYSIO_IMAP_SBERR, SYSIO_IMAP_PMGMT, + SYSIO_IMAP_GFX, + SYSIO_IMAP_EUPA, }; #undef bogon diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 237524d87ca..beffc82a1e8 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -254,7 +254,6 @@ EXPORT_SYMBOL(prom_getproperty); EXPORT_SYMBOL(prom_node_has_property); EXPORT_SYMBOL(prom_setprop); EXPORT_SYMBOL(saved_command_line); -EXPORT_SYMBOL(prom_getname); EXPORT_SYMBOL(prom_finddevice); EXPORT_SYMBOL(prom_feval); EXPORT_SYMBOL(prom_getbool); diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index 51c056df528..054d0abdb7e 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -701,21 +701,21 @@ extern void check_pending(int signum); asmlinkage long sys_getdomainname(char __user *name, int len) { - int nlen; - int err = -EFAULT; + int nlen, err; + + if (len < 0 || len > __NEW_UTS_LEN) + return -EINVAL; down_read(&uts_sem); nlen = strlen(system_utsname.domainname) + 1; - if (nlen < len) len = nlen; - if (len > __NEW_UTS_LEN) - goto done; - if (copy_to_user(name, system_utsname.domainname, len)) - goto done; - err = 0; -done: + + err = -EFAULT; + if (!copy_to_user(name, system_utsname.domainname, len)) + err = 0; + up_read(&uts_sem); return err; } diff --git a/arch/sparc64/prom/tree.c b/arch/sparc64/prom/tree.c index 49075abd7cb..500f05e2cfc 100644 --- a/arch/sparc64/prom/tree.c +++ b/arch/sparc64/prom/tree.c @@ -193,91 +193,6 @@ prom_searchsiblings(int node_start, const char *nodename) return 0; } -/* Gets name in the {name@x,yyyyy|name (if no reg)} form */ -int -prom_getname (int node, char *buffer, int len) -{ - int i, sbus = 0; - int pci = 0, ebus = 0, ide = 0; - struct linux_prom_registers *reg; - struct linux_prom64_registers reg64[PROMREG_MAX]; - - for (sbus = prom_getparent (node); sbus; sbus = prom_getparent (sbus)) { - i = prom_getproperty (sbus, "name", buffer, len); - if (i > 0) { - buffer [i] = 0; - if (!strcmp (buffer, "sbus")) - goto getit; - } - } - if ((pci = prom_getparent (node))) { - i = prom_getproperty (pci, "name", buffer, len); - if (i > 0) { - buffer [i] = 0; - if (!strcmp (buffer, "pci")) - goto getit; - } - pci = 0; - } - if ((ebus = prom_getparent (node))) { - i = prom_getproperty (ebus, "name", buffer, len); - if (i > 0) { - buffer[i] = 0; - if (!strcmp (buffer, "ebus")) - goto getit; - } - ebus = 0; - } - if ((ide = prom_getparent (node))) { - i = prom_getproperty (ide, "name", buffer, len); - if (i > 0) { - buffer [i] = 0; - if (!strcmp (buffer, "ide")) - goto getit; - } - ide = 0; - } -getit: - i = prom_getproperty (node, "name", buffer, len); - if (i <= 0) { - buffer [0] = 0; - return -1; - } - buffer [i] = 0; - len -= i; - i = prom_getproperty (node, "reg", (char *)reg64, sizeof (reg64)); - if (i <= 0) return 0; - if (len < 16) return -1; - buffer = strchr (buffer, 0); - if (sbus) { - reg = (struct linux_prom_registers *)reg64; - sprintf (buffer, "@%x,%x", reg[0].which_io, (uint)reg[0].phys_addr); - } else if (pci) { - int dev, fn; - reg = (struct linux_prom_registers *)reg64; - fn = (reg[0].which_io >> 8) & 0x07; - dev = (reg[0].which_io >> 11) & 0x1f; - if (fn) - sprintf (buffer, "@%x,%x", dev, fn); - else - sprintf (buffer, "@%x", dev); - } else if (ebus) { - reg = (struct linux_prom_registers *)reg64; - sprintf (buffer, "@%x,%x", reg[0].which_io, reg[0].phys_addr); - } else if (ide) { - reg = (struct linux_prom_registers *)reg64; - sprintf (buffer, "@%x,%x", reg[0].which_io, reg[0].phys_addr); - } else if (i == 4) { /* Happens on 8042's children on Ultra/PCI. */ - reg = (struct linux_prom_registers *)reg64; - sprintf (buffer, "@%x", reg[0].which_io); - } else { - sprintf (buffer, "@%x,%x", - (unsigned int)(reg64[0].phys_addr >> 36), - (unsigned int)(reg64[0].phys_addr)); - } - return 0; -} - /* Return the first property type for node 'node'. * buffer should be at least 32B in length */ diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 17bc8abd5df..00f574cbb0d 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -1174,8 +1174,12 @@ static void dcd_change(MGSLPC_INFO *info) else info->input_signal_events.dcd_down++; #ifdef CONFIG_HDLC - if (info->netcount) - hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, info->netdev); + if (info->netcount) { + if (info->serial_signals & SerialSignal_DCD) + netif_carrier_on(info->netdev); + else + netif_carrier_off(info->netdev); + } #endif wake_up_interruptible(&info->status_event_wait_q); wake_up_interruptible(&info->event_wait_q); @@ -4251,8 +4255,10 @@ static int hdlcdev_open(struct net_device *dev) spin_lock_irqsave(&info->lock, flags); get_signals(info); spin_unlock_irqrestore(&info->lock, flags); - hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, dev); - + if (info->serial_signals & SerialSignal_DCD) + netif_carrier_on(dev); + else + netif_carrier_off(dev); return 0; } diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index df782dd1098..78b1b1a2732 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c @@ -1344,8 +1344,12 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info ) } else info->input_signal_events.dcd_down++; #ifdef CONFIG_HDLC - if (info->netcount) - hdlc_set_carrier(status & MISCSTATUS_DCD, info->netdev); + if (info->netcount) { + if (status & MISCSTATUS_DCD) + netif_carrier_on(info->netdev); + else + netif_carrier_off(info->netdev); + } #endif } if (status & MISCSTATUS_CTS_LATCHED) @@ -7844,8 +7848,10 @@ static int hdlcdev_open(struct net_device *dev) spin_lock_irqsave(&info->irq_spinlock, flags); usc_get_serial_signals(info); spin_unlock_irqrestore(&info->irq_spinlock, flags); - hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, dev); - + if (info->serial_signals & SerialSignal_DCD) + netif_carrier_on(dev); + else + netif_carrier_off(dev); return 0; } diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index e829594195c..b2dbbdb1bf8 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c @@ -1497,8 +1497,10 @@ static int hdlcdev_open(struct net_device *dev) spin_lock_irqsave(&info->lock, flags); get_signals(info); spin_unlock_irqrestore(&info->lock, flags); - hdlc_set_carrier(info->signals & SerialSignal_DCD, dev); - + if (info->signals & SerialSignal_DCD) + netif_carrier_on(dev); + else + netif_carrier_off(dev); return 0; } @@ -1997,8 +1999,12 @@ static void dcd_change(struct slgt_info *info) info->input_signal_events.dcd_down++; } #ifdef CONFIG_HDLC - if (info->netcount) - hdlc_set_carrier(info->signals & SerialSignal_DCD, info->netdev); + if (info->netcount) { + if (info->signals & SerialSignal_DCD) + netif_carrier_on(info->netdev); + else + netif_carrier_off(info->netdev); + } #endif wake_up_interruptible(&info->status_event_wait_q); wake_up_interruptible(&info->event_wait_q); diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index 1e443a233f5..66f3754fbbd 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c @@ -1752,8 +1752,10 @@ static int hdlcdev_open(struct net_device *dev) spin_lock_irqsave(&info->lock, flags); get_signals(info); spin_unlock_irqrestore(&info->lock, flags); - hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, dev); - + if (info->serial_signals & SerialSignal_DCD) + netif_carrier_on(dev); + else + netif_carrier_off(dev); return 0; } @@ -2522,8 +2524,12 @@ void isr_io_pin( SLMP_INFO *info, u16 status ) } else info->input_signal_events.dcd_down++; #ifdef CONFIG_HDLC - if (info->netcount) - hdlc_set_carrier(status & SerialSignal_DCD, info->netdev); + if (info->netcount) { + if (status & SerialSignal_DCD) + netif_carrier_on(info->netdev); + else + netif_carrier_off(info->netdev); + } #endif } if (status & MISCSTATUS_CTS_LATCHED) diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 87299924e73..178f0c547eb 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -239,6 +239,8 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) total_ticks = (unsigned int) cputime64_sub(cur_jiffies, this_dbs_info->prev_cpu_wall); this_dbs_info->prev_cpu_wall = cur_jiffies; + if (!total_ticks) + return; /* * Every sampling_rate, we check, if current idle time is less * than 20% (default), then we try to increase frequency @@ -304,6 +306,9 @@ static void do_dbs_timer(void *data) unsigned int cpu = smp_processor_id(); struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); + if (!dbs_info->enable) + return; + dbs_check_cpu(dbs_info); queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); @@ -319,11 +324,11 @@ static inline void dbs_timer_init(unsigned int cpu) return; } -static inline void dbs_timer_exit(unsigned int cpu) +static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) { - struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); - - cancel_rearming_delayed_workqueue(kondemand_wq, &dbs_info->work); + dbs_info->enable = 0; + cancel_delayed_work(&dbs_info->work); + flush_workqueue(kondemand_wq); } static int cpufreq_governor_dbs(struct cpufreq_policy *policy, @@ -396,8 +401,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, case CPUFREQ_GOV_STOP: mutex_lock(&dbs_mutex); - dbs_timer_exit(policy->cpu); - this_dbs_info->enable = 0; + dbs_timer_exit(this_dbs_info); sysfs_remove_group(&policy->kobj, &dbs_attr_group); dbs_enable--; if (dbs_enable == 0) diff --git a/drivers/dma/ioatdma.c b/drivers/dma/ioatdma.c index 78bf46d917b..dbd4d6c3698 100644 --- a/drivers/dma/ioatdma.c +++ b/drivers/dma/ioatdma.c @@ -828,7 +828,7 @@ static int __init ioat_init_module(void) /* if forced, worst case is that rmmod hangs */ __unsafe(THIS_MODULE); - return pci_module_init(&ioat_pci_drv); + return pci_register_driver(&ioat_pci_drv); } module_init(ioat_init_module); diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c index 66d03f242d3..1a159e8843c 100644 --- a/drivers/fc4/fc.c +++ b/drivers/fc4/fc.c @@ -429,7 +429,7 @@ static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hd if (fcmd->data) { if (SCpnt->use_sg) - dma_unmap_sg(fc->dev, (struct scatterlist *)SCpnt->buffer, + dma_unmap_sg(fc->dev, (struct scatterlist *)SCpnt->request_buffer, SCpnt->use_sg, SCpnt->sc_data_direction); else @@ -810,7 +810,7 @@ static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, i SCpnt->request_bufflen, SCpnt->sc_data_direction); } else { - struct scatterlist *sg = (struct scatterlist *)SCpnt->buffer; + struct scatterlist *sg = (struct scatterlist *)SCpnt->request_buffer; int nents; FCD(("XXX: Use_sg %d %d\n", SCpnt->use_sg, sg->length)) diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig index bbc22985288..ea31d847051 100644 --- a/drivers/message/fusion/Kconfig +++ b/drivers/message/fusion/Kconfig @@ -48,10 +48,8 @@ config FUSION_SAS List of supported controllers: LSISAS1064 - LSISAS1066 LSISAS1068 LSISAS1064E - LSISAS1066E LSISAS1068E config FUSION_MAX_SGE diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile index b114236f439..341691390e8 100644 --- a/drivers/message/fusion/Makefile +++ b/drivers/message/fusion/Makefile @@ -9,7 +9,6 @@ #EXTRA_CFLAGS += -DMPT_DEBUG_EXIT #EXTRA_CFLAGS += -DMPT_DEBUG_FAIL - # # driver/module specifics... # diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 43308df6462..29d0635cce1 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -436,8 +436,6 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) */ if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) { freereq = 0; - devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n", - ioc->name, pEvReply)); } else { devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n", ioc->name, pEvReply)); @@ -678,19 +676,19 @@ int mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx) { MPT_ADAPTER *ioc; + const struct pci_device_id *id; - if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) { + if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) return -EINVAL; - } MptDeviceDriverHandlers[cb_idx] = dd_cbfunc; /* call per pci device probe entry point */ list_for_each_entry(ioc, &ioc_list, list) { - if(dd_cbfunc->probe) { - dd_cbfunc->probe(ioc->pcidev, - ioc->pcidev->driver->id_table); - } + id = ioc->pcidev->driver ? + ioc->pcidev->driver->id_table : NULL; + if (dd_cbfunc->probe) + dd_cbfunc->probe(ioc->pcidev, id); } return 0; @@ -1056,9 +1054,8 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init) dinitprintk((MYIOC_s_INFO_FMT "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n", - ioc->name, - ioc->HostPageBuffer, - ioc->HostPageBuffer_dma, + ioc->name, ioc->HostPageBuffer, + (u32)ioc->HostPageBuffer_dma, host_page_buffer_sz)); ioc->alloc_total += host_page_buffer_sz; ioc->HostPageBuffer_sz = host_page_buffer_sz; @@ -1380,6 +1377,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) printk(KERN_WARNING MYNAM ": WARNING - %s did not initialize properly! (%d)\n", ioc->name, r); + list_del(&ioc->list); if (ioc->alt_ioc) ioc->alt_ioc->alt_ioc = NULL; @@ -1762,9 +1760,9 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) * chips (mpt_adapter_disable, * mpt_diag_reset) */ - ioc->cached_fw = NULL; ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n", ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw)); + ioc->alt_ioc->cached_fw = NULL; } } else { printk(KERN_WARNING MYNAM ": firmware upload failure!\n"); @@ -1885,7 +1883,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) /* FIXME? Examine results here? */ } -out: + out: if ((ret != 0) && irq_allocated) { free_irq(ioc->pci_irq, ioc); if (mpt_msi_enable) @@ -2670,6 +2668,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n", ioc->name, count)); + ioc->aen_event_read_flag=0; return r; } @@ -2737,6 +2736,8 @@ mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size) if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) { ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */ ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma; + ioc->alloc_total += size; + ioc->alt_ioc->alloc_total -= size; } else { if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) ) ioc->alloc_total += size; @@ -3166,6 +3167,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag) static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) { + MPT_ADAPTER *iocp=NULL; u32 diag0val; u32 doorbell; int hard_reset_done = 0; @@ -3301,17 +3303,23 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) /* FIXME? Examine results here? */ } - if (ioc->cached_fw) { + if (ioc->cached_fw) + iocp = ioc; + else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) + iocp = ioc->alt_ioc; + if (iocp) { /* If the DownloadBoot operation fails, the * IOC will be left unusable. This is a fatal error * case. _diag_reset will return < 0 */ for (count = 0; count < 30; count ++) { - diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); + diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic); if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) { break; } + dprintk((MYIOC_s_INFO_FMT "cached_fw: diag0val=%x count=%d\n", + iocp->name, diag0val, count)); /* wait 1 sec */ if (sleepFlag == CAN_SLEEP) { msleep (1000); @@ -3320,7 +3328,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) } } if ((count = mpt_downloadboot(ioc, - (MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) { + (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) { printk(KERN_WARNING MYNAM ": firmware downloadboot failure (%d)!\n", count); } @@ -3907,18 +3915,18 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag) if (sleepFlag == CAN_SLEEP) { while (--cntdn) { + msleep (1); intstat = CHIPREG_READ32(&ioc->chip->IntStatus); if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) break; - msleep (1); count++; } } else { while (--cntdn) { + mdelay (1); intstat = CHIPREG_READ32(&ioc->chip->IntStatus); if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) break; - mdelay (1); count++; } } @@ -4883,6 +4891,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc) pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma); if (!pIoc4) return; + ioc->alloc_total += iocpage4sz; } else { ioc4_dma = ioc->spi_data.IocPg4_dma; iocpage4sz = ioc->spi_data.IocPg4Sz; @@ -4899,6 +4908,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc) } else { pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma); ioc->spi_data.pIocPg4 = NULL; + ioc->alloc_total -= iocpage4sz; } } @@ -5030,19 +5040,18 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp) EventAck_t *pAck; if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { - printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK " - "request frame for Event=%x EventContext=%x EventData=%x!\n", - ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext), - le32_to_cpu(evnp->Data[0])); + dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n", + ioc->name,__FUNCTION__)); return -1; } - memset(pAck, 0, sizeof(*pAck)); - dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name)); + devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name)); pAck->Function = MPI_FUNCTION_EVENT_ACK; pAck->ChainOffset = 0; + pAck->Reserved[0] = pAck->Reserved[1] = 0; pAck->MsgFlags = 0; + pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0; pAck->Event = evnp->Event; pAck->EventContext = evnp->EventContext; @@ -5704,9 +5713,9 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) break; case MPI_EVENT_EVENT_CHANGE: if (evData0) - ds = "Events(ON) Change"; + ds = "Events ON"; else - ds = "Events(OFF) Change"; + ds = "Events OFF"; break; case MPI_EVENT_INTEGRATED_RAID: { @@ -5777,8 +5786,27 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) break; case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED: snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS Device Status Change: No Persistancy " - "Added: id=%d", id); + "SAS Device Status Change: No Persistancy: id=%d", id); + break; + case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: + snprintf(evStr, EVENT_DESCR_STR_SZ, + "SAS Device Status Change: Internal Device Reset : id=%d", id); + break; + case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: + snprintf(evStr, EVENT_DESCR_STR_SZ, + "SAS Device Status Change: Internal Task Abort : id=%d", id); + break; + case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: + snprintf(evStr, EVENT_DESCR_STR_SZ, + "SAS Device Status Change: Internal Abort Task Set : id=%d", id); + break; + case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: + snprintf(evStr, EVENT_DESCR_STR_SZ, + "SAS Device Status Change: Internal Clear Task Set : id=%d", id); + break; + case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: + snprintf(evStr, EVENT_DESCR_STR_SZ, + "SAS Device Status Change: Internal Query Task : id=%d", id); break; default: snprintf(evStr, EVENT_DESCR_STR_SZ, @@ -6034,7 +6062,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply * @ioc: Pointer to MPT_ADAPTER structure * @log_info: U32 LogInfo reply word from the IOC * - * Refer to lsi/fc_log.h. + * Refer to lsi/mpi_log_fc.h. */ static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info) @@ -6131,8 +6159,10 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) "Invalid SAS Address", /* 01h */ NULL, /* 02h */ "Invalid Page", /* 03h */ - NULL, /* 04h */ - "Task Terminated" /* 05h */ + "Diag Message Error", /* 04h */ + "Task Terminated", /* 05h */ + "Enclosure Management", /* 06h */ + "Target Mode" /* 07h */ }; static char *pl_code_str[] = { NULL, /* 00h */ @@ -6158,7 +6188,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) "IO Executed", /* 14h */ "Persistant Reservation Out Not Affiliation Owner", /* 15h */ "Open Transmit DMA Abort", /* 16h */ - NULL, /* 17h */ + "IO Device Missing Delay Retry", /* 17h */ NULL, /* 18h */ NULL, /* 19h */ NULL, /* 1Ah */ @@ -6238,7 +6268,7 @@ static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) { u32 status = ioc_status & MPI_IOCSTATUS_MASK; - char *desc = ""; + char *desc = NULL; switch (status) { case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */ @@ -6348,7 +6378,7 @@ mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) desc = "Others"; break; } - if (desc != "") + if (desc != NULL) printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc); } @@ -6386,7 +6416,6 @@ EXPORT_SYMBOL(mpt_alloc_fw_memory); EXPORT_SYMBOL(mpt_free_fw_memory); EXPORT_SYMBOL(mptbase_sas_persist_operation); - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * fusion_init - Fusion MPT base driver initialization routine. diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index a5ce10b67d0..d4cb144ab40 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -75,8 +75,8 @@ #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "3.04.00" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.00" +#define MPT_LINUX_VERSION_COMMON "3.04.01" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.01" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ @@ -307,8 +307,8 @@ typedef struct _SYSIF_REGS u32 HostIndex; /* 50 Host Index register */ u32 Reserved4[15]; /* 54-8F */ u32 Fubar; /* 90 For Fubar usage */ - u32 Reserved5[1050];/* 94-10F8 */ - u32 Reset_1078; /* 10FC Reset 1078 */ + u32 Reserved5[1050];/* 94-10F8 */ + u32 Reset_1078; /* 10FC Reset 1078 */ } SYSIF_REGS; /* @@ -363,6 +363,7 @@ typedef struct _VirtDevice { #define MPT_TARGET_FLAGS_VALID_56 0x10 #define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20 #define MPT_TARGET_FLAGS_RAID_COMPONENT 0x40 +#define MPT_TARGET_FLAGS_LED_ON 0x80 /* * /proc/mpt interface @@ -634,7 +635,6 @@ typedef struct _MPT_ADAPTER u16 handle; int sas_index; /* index refrencing */ MPT_SAS_MGMT sas_mgmt; - int num_ports; struct work_struct sas_persist_task; struct work_struct fc_setup_reset_work; @@ -644,7 +644,6 @@ typedef struct _MPT_ADAPTER struct work_struct fc_rescan_work; char fc_rescan_work_q_name[KOBJ_NAME_LEN]; struct workqueue_struct *fc_rescan_work_q; - u8 port_serial_number; } MPT_ADAPTER; /* @@ -982,7 +981,7 @@ typedef struct _MPT_SCSI_HOST { wait_queue_head_t scandv_waitq; int scandv_wait_done; long last_queue_full; - u8 mpt_pq_filter; + u16 tm_iocstatus; } MPT_SCSI_HOST; /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index b4967bb8a7d..30975ccd994 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -2332,7 +2332,7 @@ done_free_mem: } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/* Prototype Routine for the HP HOST INFO command. +/* Prototype Routine for the HOST INFO command. * * Outputs: None. * Return: 0 if successful @@ -2568,7 +2568,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/* Prototype Routine for the HP TARGET INFO command. +/* Prototype Routine for the TARGET INFO command. * * Outputs: None. * Return: 0 if successful diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h index a2f8a97992e..043941882c6 100644 --- a/drivers/message/fusion/mptctl.h +++ b/drivers/message/fusion/mptctl.h @@ -354,9 +354,6 @@ struct mpt_ioctl_command32 { /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/* - * HP Specific IOCTL Defines and Structures - */ #define CPQFCTS_IOC_MAGIC 'Z' #define HP_IOC_MAGIC 'Z' @@ -364,8 +361,6 @@ struct mpt_ioctl_command32 { #define HP_GETHOSTINFO1 _IOR(HP_IOC_MAGIC, 20, hp_host_info_rev0_t) #define HP_GETTARGETINFO _IOR(HP_IOC_MAGIC, 21, hp_target_info_t) -/* All HP IOCTLs must include this header - */ typedef struct _hp_header { unsigned int iocnum; unsigned int host; diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index a8f2fa98545..90da7d63b08 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -77,10 +77,6 @@ MODULE_DESCRIPTION(my_NAME); MODULE_LICENSE("GPL"); /* Command line args */ -static int mpt_pq_filter = 0; -module_param(mpt_pq_filter, int, 0); -MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)"); - #define MPTFC_DEV_LOSS_TMO (60) static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; /* reasonable default */ module_param(mptfc_dev_loss_tmo, int, 0); @@ -513,8 +509,7 @@ mptfc_slave_alloc(struct scsi_device *sdev) if (vtarget->num_luns == 0) { vtarget->ioc_id = hd->ioc->id; - vtarget->tflags = MPT_TARGET_FLAGS_Q_YES | - MPT_TARGET_FLAGS_VALID_INQUIRY; + vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; hd->Targets[sdev->id] = vtarget; } @@ -1129,13 +1124,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) hd->timer.data = (unsigned long) hd; hd->timer.function = mptscsih_timer_expired; - hd->mpt_pq_filter = mpt_pq_filter; - - ddvprintk((MYIOC_s_INFO_FMT - "mpt_pq_filter %x\n", - ioc->name, - mpt_pq_filter)); - init_waitqueue_head(&hd->scandv_waitq); hd->scandv_wait_done = 0; hd->last_queue_full = 0; diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index f7bd8b11ed3..f66f2203143 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -67,20 +67,19 @@ #define my_VERSION MPT_LINUX_VERSION_COMMON #define MYNAM "mptsas" +/* + * Reserved channel for integrated raid + */ +#define MPTSAS_RAID_CHANNEL 1 + MODULE_AUTHOR(MODULEAUTHOR); MODULE_DESCRIPTION(my_NAME); MODULE_LICENSE("GPL"); -static int mpt_pq_filter; -module_param(mpt_pq_filter, int, 0); -MODULE_PARM_DESC(mpt_pq_filter, - "Enable peripheral qualifier filter: enable=1 " - "(default=0)"); - static int mpt_pt_clear; module_param(mpt_pt_clear, int, 0); MODULE_PARM_DESC(mpt_pt_clear, - "Clear persistency table: enable=1 " + " Clear persistency table: enable=1 " "(default=MPTSCSIH_PT_CLEAR=0)"); static int mptsasDoneCtx = -1; @@ -144,7 +143,6 @@ struct mptsas_devinfo { * Specific details on ports, wide/narrow */ struct mptsas_portinfo_details{ - u8 port_id; /* port number provided to transport */ u16 num_phys; /* number of phys belong to this port */ u64 phy_bitmask; /* TODO, extend support for 255 phys */ struct sas_rphy *rphy; /* transport layer rphy object */ @@ -350,10 +348,10 @@ mptsas_port_delete(struct mptsas_portinfo_details * port_details) port_info = port_details->port_info; phy_info = port_info->phy_info; - dsaswideprintk((KERN_DEBUG "%s: [%p]: port=%02d num_phys=%02d " + dsaswideprintk((KERN_DEBUG "%s: [%p]: num_phys=%02d " "bitmask=0x%016llX\n", - __FUNCTION__, port_details, port_details->port_id, - port_details->num_phys, port_details->phy_bitmask)); + __FUNCTION__, port_details, port_details->num_phys, + port_details->phy_bitmask)); for (i = 0; i < port_info->num_phys; i++, phy_info++) { if(phy_info->port_details != port_details) @@ -462,9 +460,8 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) * phy be removed by firmware events. */ dsaswideprintk((KERN_DEBUG - "%s: [%p]: port=%d deleting phy = %d\n", - __FUNCTION__, port_details, - port_details->port_id, i)); + "%s: [%p]: deleting phy = %d\n", + __FUNCTION__, port_details, i)); port_details->num_phys--; port_details->phy_bitmask &= ~ (1 << phy_info->phy_id); memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); @@ -493,7 +490,6 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) goto out; port_details->num_phys = 1; port_details->port_info = port_info; - port_details->port_id = ioc->port_serial_number++; if (phy_info->phy_id < 64 ) port_details->phy_bitmask |= (1 << phy_info->phy_id); @@ -525,12 +521,8 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) mptsas_get_port(phy_info_cmp); port_details->starget = mptsas_get_starget(phy_info_cmp); - port_details->port_id = - phy_info_cmp->port_details->port_id; port_details->num_phys = phy_info_cmp->port_details->num_phys; -// port_info->port_serial_number--; - ioc->port_serial_number--; if (!phy_info_cmp->port_details->num_phys) kfree(phy_info_cmp->port_details); } else @@ -554,11 +546,11 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) if (!port_details) continue; dsaswideprintk((KERN_DEBUG - "%s: [%p]: phy_id=%02d port_id=%02d num_phys=%02d " + "%s: [%p]: phy_id=%02d num_phys=%02d " "bitmask=0x%016llX\n", __FUNCTION__, - port_details, i, port_details->port_id, - port_details->num_phys, port_details->phy_bitmask)); + port_details, i, port_details->num_phys, + port_details->phy_bitmask)); dsaswideprintk((KERN_DEBUG"\t\tport = %p rphy=%p\n", port_details->port, port_details->rphy)); } @@ -651,16 +643,13 @@ mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure, static int mptsas_slave_configure(struct scsi_device *sdev) { - struct Scsi_Host *host = sdev->host; - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; - /* - * RAID volumes placed beyond the last expected port. - * Ignore sending sas mode pages in that case.. - */ - if (sdev->channel < hd->ioc->num_ports) - sas_read_port_mode_page(sdev); + if (sdev->channel == MPTSAS_RAID_CHANNEL) + goto out; + + sas_read_port_mode_page(sdev); + out: return mptscsih_slave_configure(sdev); } @@ -689,10 +678,7 @@ mptsas_target_alloc(struct scsi_target *starget) hd->Targets[target_id] = vtarget; - /* - * RAID volumes placed beyond the last expected port. - */ - if (starget->channel == hd->ioc->num_ports) + if (starget->channel == MPTSAS_RAID_CHANNEL) goto out; rphy = dev_to_rphy(starget->dev.parent); @@ -743,7 +729,7 @@ mptsas_target_destroy(struct scsi_target *starget) if (!starget->hostdata) return; - if (starget->channel == hd->ioc->num_ports) + if (starget->channel == MPTSAS_RAID_CHANNEL) goto out; rphy = dev_to_rphy(starget->dev.parent); @@ -783,10 +769,7 @@ mptsas_slave_alloc(struct scsi_device *sdev) starget = scsi_target(sdev); vdev->vtarget = starget->hostdata; - /* - * RAID volumes placed beyond the last expected port. - */ - if (sdev->channel == hd->ioc->num_ports) + if (sdev->channel == MPTSAS_RAID_CHANNEL) goto out; rphy = dev_to_rphy(sdev->sdev_target->dev.parent); @@ -1608,11 +1591,7 @@ static int mptsas_probe_one_phy(struct device *dev, if (phy_info->sas_port_add_phy) { if (!port) { - port = sas_port_alloc(dev, - phy_info->port_details->port_id); - dsaswideprintk((KERN_DEBUG - "sas_port_alloc: port=%p dev=%p port_id=%d\n", - port, dev, phy_info->port_details->port_id)); + port = sas_port_alloc_num(dev); if (!port) { error = -ENOMEM; goto out; @@ -1625,6 +1604,9 @@ static int mptsas_probe_one_phy(struct device *dev, goto out; } mptsas_set_port(phy_info, port); + dsaswideprintk((KERN_DEBUG + "sas_port_alloc: port=%p dev=%p port_id=%d\n", + port, dev, port->port_identifier)); } dsaswideprintk((KERN_DEBUG "sas_port_add_phy: phy_id=%d\n", phy_info->phy_id)); @@ -1736,7 +1718,6 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc) hba = NULL; } mutex_unlock(&ioc->sas_topology_mutex); - ioc->num_ports = port_info->num_phys; for (i = 0; i < port_info->num_phys; i++) { mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i], @@ -1939,7 +1920,8 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc) expander_sas_address) continue; #ifdef MPT_DEBUG_SAS_WIDE - dev_printk(KERN_DEBUG, &port->dev, "delete\n"); + dev_printk(KERN_DEBUG, &port->dev, + "delete port (%d)\n", port->port_identifier); #endif sas_port_delete(port); mptsas_port_delete(phy_info->port_details); @@ -1984,7 +1966,7 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc) if (!ioc->raid_data.pIocPg2->NumActiveVolumes) goto out; for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) { - scsi_add_device(ioc->sh, ioc->num_ports, + scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0); } out: @@ -2185,7 +2167,8 @@ mptsas_hotplug_work(void *arg) ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); #ifdef MPT_DEBUG_SAS_WIDE - dev_printk(KERN_DEBUG, &port->dev, "delete\n"); + dev_printk(KERN_DEBUG, &port->dev, + "delete port (%d)\n", port->port_identifier); #endif sas_port_delete(port); mptsas_port_delete(phy_info->port_details); @@ -2289,35 +2272,26 @@ mptsas_hotplug_work(void *arg) mptsas_set_rphy(phy_info, rphy); break; case MPTSAS_ADD_RAID: - sdev = scsi_device_lookup( - ioc->sh, - ioc->num_ports, - ev->id, - 0); + sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, + ev->id, 0); if (sdev) { scsi_device_put(sdev); break; } printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, id %d\n", - ioc->name, ioc->num_ports, ev->id); - scsi_add_device(ioc->sh, - ioc->num_ports, - ev->id, - 0); + ioc->name, MPTSAS_RAID_CHANNEL, ev->id); + scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ev->id, 0); mpt_findImVolumes(ioc); break; case MPTSAS_DEL_RAID: - sdev = scsi_device_lookup( - ioc->sh, - ioc->num_ports, - ev->id, - 0); + sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, + ev->id, 0); if (!sdev) break; printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, id %d\n", - ioc->name, ioc->num_ports, ev->id); + ioc->name, MPTSAS_RAID_CHANNEL, ev->id); vdevice = sdev->hostdata; vdevice->vtarget->deleted = 1; mptsas_target_reset(ioc, vdevice->vtarget); @@ -2723,7 +2697,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) hd->timer.data = (unsigned long) hd; hd->timer.function = mptscsih_timer_expired; - hd->mpt_pq_filter = mpt_pq_filter; ioc->sas_data.ptClear = mpt_pt_clear; if (ioc->sas_data.ptClear==1) { @@ -2731,12 +2704,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT); } - ddvprintk((MYIOC_s_INFO_FMT - "mpt_pq_filter %x mpt_pq_filter %x\n", - ioc->name, - mpt_pq_filter, - mpt_pq_filter)); - init_waitqueue_head(&hd->scandv_waitq); hd->scandv_wait_done = 0; hd->last_queue_full = 0; diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 8242b16e316..30524dc54b1 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -66,6 +66,7 @@ #include "mptbase.h" #include "mptscsih.h" +#include "lsi/mpi_log_sas.h" /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ #define my_NAME "Fusion MPT SCSI Host driver" @@ -127,7 +128,7 @@ static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx); static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply); static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd); static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); -static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); +static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); @@ -497,6 +498,34 @@ nextSGEset: return SUCCESS; } /* mptscsih_AddSGE() */ +static void +mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget, + U32 SlotStatus) +{ + MPT_FRAME_HDR *mf; + SEPRequest_t *SEPMsg; + + if (ioc->bus_type == FC) + return; + + if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) { + dfailprintk((MYIOC_s_WARN_FMT "%s: no msg frames!!\n", + ioc->name,__FUNCTION__)); + return; + } + + SEPMsg = (SEPRequest_t *)mf; + SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; + SEPMsg->Bus = vtarget->bus_id; + SEPMsg->TargetID = vtarget->target_id; + SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS; + SEPMsg->SlotStatus = SlotStatus; + devtverboseprintk((MYIOC_s_WARN_FMT + "Sending SEP cmd=%x id=%d bus=%d\n", + ioc->name, SlotStatus, SEPMsg->TargetID, SEPMsg->Bus)); + mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); +} + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * mptscsih_io_done - Main SCSI IO callback routine registered to @@ -520,6 +549,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) SCSIIORequest_t *pScsiReq; SCSIIOReply_t *pScsiReply; u16 req_idx, req_idx_MR; + VirtDevice *vdev; + VirtTarget *vtarget; hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; @@ -538,6 +569,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) } sc = hd->ScsiLookup[req_idx]; + hd->ScsiLookup[req_idx] = NULL; if (sc == NULL) { MPIHeader_t *hdr = (MPIHeader_t *)mf; @@ -553,6 +585,12 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) return 1; } + if ((unsigned char *)mf != sc->host_scribble) { + mptscsih_freeChainBuffers(ioc, req_idx); + return 1; + } + + sc->host_scribble = NULL; sc->result = DID_OK << 16; /* Set default reply as OK */ pScsiReq = (SCSIIORequest_t *) mf; pScsiReply = (SCSIIOReply_t *) mr; @@ -640,10 +678,36 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF) hd->sel_timeout[pScsiReq->TargetID]++; + + vdev = sc->device->hostdata; + if (!vdev) + break; + vtarget = vdev->vtarget; + if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) { + mptscsih_issue_sep_command(ioc, vtarget, + MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED); + vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON; + } break; - case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */ + if ( ioc->bus_type == SAS ) { + u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus); + if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { + u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo); + log_info &=SAS_LOGINFO_MASK; + if (log_info == SAS_LOGINFO_NEXUS_LOSS) { + sc->result = (DID_BUS_BUSY << 16); + break; + } + } + } + + /* + * Allow non-SAS & non-NEXUS_LOSS to drop into below code + */ + + case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */ /* Linux handles an unsolicited DID_RESET better * than an unsolicited DID_ABORT. @@ -658,7 +722,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) sc->result=DID_SOFT_ERROR << 16; else /* Sufficient data transfer occurred */ sc->result = (DID_OK << 16) | scsi_status; - dreplyprintk((KERN_NOTICE + dreplyprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id)); break; @@ -784,8 +848,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) sc->request_bufflen, sc->sc_data_direction); } - hd->ScsiLookup[req_idx] = NULL; - sc->scsi_done(sc); /* Issue the command callback */ /* Free Chain buffers */ @@ -827,9 +889,17 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n", mf, SCpnt)); + /* Free Chain buffers */ + mptscsih_freeChainBuffers(ioc, ii); + + /* Free Message frames */ + mpt_free_msg_frame(ioc, mf); + + if ((unsigned char *)mf != SCpnt->host_scribble) + continue; + /* Set status, free OS resources (SG DMA buffers) * Do OS callback - * Free driver resources (chain, msg buffers) */ if (SCpnt->use_sg) { pci_unmap_sg(ioc->pcidev, @@ -845,12 +915,6 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) SCpnt->result = DID_RESET << 16; SCpnt->host_scribble = NULL; - /* Free Chain buffers */ - mptscsih_freeChainBuffers(ioc, ii); - - /* Free Message frames */ - mpt_free_msg_frame(ioc, mf); - SCpnt->scsi_done(SCpnt); /* Issue the command callback */ } } @@ -887,10 +951,10 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) if ((sc = hd->ScsiLookup[ii]) != NULL) { mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii); - + if (mf == NULL) + continue; dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n", hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1])); - if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun))) continue; @@ -899,6 +963,8 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) hd->ScsiLookup[ii] = NULL; mptscsih_freeChainBuffers(hd->ioc, ii); mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf); + if ((unsigned char *)mf != sc->host_scribble) + continue; if (sc->use_sg) { pci_unmap_sg(hd->ioc->pcidev, (struct scatterlist *) sc->request_buffer, @@ -1341,8 +1407,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) goto fail; } + SCpnt->host_scribble = (unsigned char *)mf; hd->ScsiLookup[my_idx] = SCpnt; - SCpnt->host_scribble = NULL; mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf); dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n", @@ -1529,6 +1595,12 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP); } + /* + * Check IOCStatus from TM reply message + */ + if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS) + rc = FAILED; + dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc)); return rc; @@ -1654,6 +1726,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) int scpnt_idx; int retval; VirtDevice *vdev; + ulong sn = SCpnt->serial_number; /* If we can't locate our host adapter structure, return FAILED status. */ @@ -1707,6 +1780,11 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun, ctx2abort, mptscsih_get_tm_timeout(hd->ioc)); + if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx && + SCpnt->serial_number == sn) { + retval = FAILED; + } + printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", hd->ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt); @@ -2023,6 +2101,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply); iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK; + hd->tm_iocstatus = iocstatus; dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n", ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo))); /* Error? (anything non-zero?) */ @@ -2401,6 +2480,13 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12]; ioc->eventContext++; + if (hd->ioc->pcidev->vendor == + PCI_VENDOR_ID_IBM) { + mptscsih_issue_sep_command(hd->ioc, + vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT); + vdev->vtarget->tflags |= + MPT_TARGET_FLAGS_LED_ON; + } } } } else { @@ -2409,7 +2495,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR } } -static u32 +static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc) { MPT_SCSI_HOST *hd; diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 0a1ff762205..e4cc3dd5fc9 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -83,10 +83,6 @@ static int mpt_saf_te = MPTSCSIH_SAF_TE; module_param(mpt_saf_te, int, 0); MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1 (default=MPTSCSIH_SAF_TE=0)"); -static int mpt_pq_filter = 0; -module_param(mpt_pq_filter, int, 0); -MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)"); - static void mptspi_write_offset(struct scsi_target *, int); static void mptspi_write_width(struct scsi_target *, int); static int mptspi_write_spi_device_pg1(struct scsi_target *, @@ -1047,14 +1043,12 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) hd->timer.function = mptscsih_timer_expired; ioc->spi_data.Saf_Te = mpt_saf_te; - hd->mpt_pq_filter = mpt_pq_filter; hd->negoNvram = MPT_SCSICFG_USE_NVRAM; ddvprintk((MYIOC_s_INFO_FMT - "saf_te %x mpt_pq_filter %x\n", + "saf_te %x\n", ioc->name, - mpt_saf_te, - mpt_pq_filter)); + mpt_saf_te)); ioc->spi_data.noQas = 0; init_waitqueue_head(&hd->scandv_waitq); diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index 36d511729f7..2146cf74425 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -132,6 +132,7 @@ static int __init dummy_init_module(void) for (i = 0; i < numdummies && !err; i++) err = dummy_init_one(i); if (err) { + i--; while (--i >= 0) dummy_free_one(i); } diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index f411bbb44f8..d304297c496 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -110,6 +110,9 @@ struct e1000_adapter; #define E1000_MIN_RXD 80 #define E1000_MAX_82544_RXD 4096 +/* this is the size past which hardware will drop packets when setting LPE=0 */ +#define MAXIMUM_ETHERNET_VLAN_SIZE 1522 + /* Supported Rx Buffer Sizes */ #define E1000_RXBUFFER_128 128 /* Used for packet split */ #define E1000_RXBUFFER_256 256 /* Used for packet split */ diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 6d3d4193450..da62db89742 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -36,7 +36,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; #else #define DRIVERNAPI "-NAPI" #endif -#define DRV_VERSION "7.1.9-k2"DRIVERNAPI +#define DRV_VERSION "7.1.9-k4"DRIVERNAPI char e1000_driver_version[] = DRV_VERSION; static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; @@ -1068,7 +1068,7 @@ e1000_sw_init(struct e1000_adapter *adapter) pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); - adapter->rx_buffer_len = MAXIMUM_ETHERNET_FRAME_SIZE; + adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE; adapter->rx_ps_bsize0 = E1000_RXBUFFER_128; hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; @@ -3148,7 +3148,6 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) adapter->rx_buffer_len = E1000_RXBUFFER_16384; /* adjust allocation if LPE protects us, and we aren't using SBP */ -#define MAXIMUM_ETHERNET_VLAN_SIZE 1522 if (!adapter->hw.tbi_compatibility_on && ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) || (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE))) @@ -3387,8 +3386,8 @@ e1000_intr(int irq, void *data, struct pt_regs *regs) E1000_WRITE_REG(hw, IMC, ~0); E1000_WRITE_FLUSH(hw); } - if (likely(netif_rx_schedule_prep(&adapter->polling_netdev[0]))) - __netif_rx_schedule(&adapter->polling_netdev[0]); + if (likely(netif_rx_schedule_prep(netdev))) + __netif_rx_schedule(netdev); else e1000_irq_enable(adapter); #else @@ -3431,34 +3430,26 @@ e1000_clean(struct net_device *poll_dev, int *budget) { struct e1000_adapter *adapter; int work_to_do = min(*budget, poll_dev->quota); - int tx_cleaned = 0, i = 0, work_done = 0; + int tx_cleaned = 0, work_done = 0; /* Must NOT use netdev_priv macro here. */ adapter = poll_dev->priv; /* Keep link state information with original netdev */ - if (!netif_carrier_ok(adapter->netdev)) + if (!netif_carrier_ok(poll_dev)) goto quit_polling; - while (poll_dev != &adapter->polling_netdev[i]) { - i++; - BUG_ON(i == adapter->num_rx_queues); + /* e1000_clean is called per-cpu. This lock protects + * tx_ring[0] from being cleaned by multiple cpus + * simultaneously. A failure obtaining the lock means + * tx_ring[0] is currently being cleaned anyway. */ + if (spin_trylock(&adapter->tx_queue_lock)) { + tx_cleaned = e1000_clean_tx_irq(adapter, + &adapter->tx_ring[0]); + spin_unlock(&adapter->tx_queue_lock); } - if (likely(adapter->num_tx_queues == 1)) { - /* e1000_clean is called per-cpu. This lock protects - * tx_ring[0] from being cleaned by multiple cpus - * simultaneously. A failure obtaining the lock means - * tx_ring[0] is currently being cleaned anyway. */ - if (spin_trylock(&adapter->tx_queue_lock)) { - tx_cleaned = e1000_clean_tx_irq(adapter, - &adapter->tx_ring[0]); - spin_unlock(&adapter->tx_queue_lock); - } - } else - tx_cleaned = e1000_clean_tx_irq(adapter, &adapter->tx_ring[i]); - - adapter->clean_rx(adapter, &adapter->rx_ring[i], + adapter->clean_rx(adapter, &adapter->rx_ring[0], &work_done, work_to_do); *budget -= work_done; @@ -3466,7 +3457,7 @@ e1000_clean(struct net_device *poll_dev, int *budget) /* If no Tx and not enough Rx work done, exit the polling mode */ if ((!tx_cleaned && (work_done == 0)) || - !netif_running(adapter->netdev)) { + !netif_running(poll_dev)) { quit_polling: netif_rx_complete(poll_dev); e1000_irq_enable(adapter); @@ -3681,6 +3672,9 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, length = le16_to_cpu(rx_desc->length); + /* adjust length to remove Ethernet CRC */ + length -= 4; + if (unlikely(!(status & E1000_RXD_STAT_EOP))) { /* All receives must fit into a single buffer */ E1000_DBG("%s: Receive packet consumed multiple" @@ -3885,8 +3879,9 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, pci_dma_sync_single_for_device(pdev, ps_page_dma->ps_page_dma[0], PAGE_SIZE, PCI_DMA_FROMDEVICE); + /* remove the CRC */ + l1 -= 4; skb_put(skb, l1); - length += l1; goto copydone; } /* if */ } @@ -3905,6 +3900,10 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, skb->truesize += length; } + /* strip the ethernet crc, problem is we're using pages now so + * this whole operation can get a little cpu intensive */ + pskb_trim(skb, skb->len - 4); + copydone: e1000_rx_checksum(adapter, staterr, le16_to_cpu(rx_desc->wb.lower.hi_dword.csum_ip.csum), skb); @@ -4752,6 +4751,7 @@ static void e1000_netpoll(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); + disable_irq(adapter->pdev->irq); e1000_intr(adapter->pdev->irq, netdev, NULL); e1000_clean_tx_irq(adapter, adapter->tx_ring); diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 3a42afab503..43e3f33ed5e 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -271,6 +271,7 @@ static int __init ifb_init_module(void) for (i = 0; i < numifbs && !err; i++) err = ifb_init_one(i); if (err) { + i--; while (--i >= 0) ifb_free_one(i); } diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index d98f28c34e5..de91609ca11 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -50,7 +50,7 @@ #include "sky2.h" #define DRV_NAME "sky2" -#define DRV_VERSION "1.4" +#define DRV_VERSION "1.5" #define PFX DRV_NAME " " /* @@ -2204,9 +2204,6 @@ static int sky2_poll(struct net_device *dev0, int *budget) int work_done = 0; u32 status = sky2_read32(hw, B0_Y2_SP_EISR); - if (!~status) - goto out; - if (status & Y2_IS_HW_ERR) sky2_hw_intr(hw); @@ -2243,7 +2240,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) if (sky2_more_work(hw)) return 1; -out: + netif_rx_complete(dev0); sky2_read32(hw, B0_Y2_SP_LISR); diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index fb1d5a8a45c..647f62e9707 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -84,7 +84,7 @@ MODULE_DEVICE_TABLE(pci, spider_net_pci_tbl); * * returns the content of the specified SMMIO register. */ -static u32 +static inline u32 spider_net_read_reg(struct spider_net_card *card, u32 reg) { u32 value; @@ -101,7 +101,7 @@ spider_net_read_reg(struct spider_net_card *card, u32 reg) * @reg: register to write to * @value: value to write into the specified SMMIO register */ -static void +static inline void spider_net_write_reg(struct spider_net_card *card, u32 reg, u32 value) { value = cpu_to_le32(value); @@ -259,39 +259,10 @@ spider_net_get_mac_address(struct net_device *netdev) * * returns the status as in the dmac_cmd_status field of the descriptor */ -static enum spider_net_descr_status +static inline int spider_net_get_descr_status(struct spider_net_descr *descr) { - u32 cmd_status; - - cmd_status = descr->dmac_cmd_status; - cmd_status >>= SPIDER_NET_DESCR_IND_PROC_SHIFT; - /* no need to mask out any bits, as cmd_status is 32 bits wide only - * (and unsigned) */ - return cmd_status; -} - -/** - * spider_net_set_descr_status -- sets the status of a descriptor - * @descr: descriptor to change - * @status: status to set in the descriptor - * - * changes the status to the specified value. Doesn't change other bits - * in the status - */ -static void -spider_net_set_descr_status(struct spider_net_descr *descr, - enum spider_net_descr_status status) -{ - u32 cmd_status; - /* read the status */ - cmd_status = descr->dmac_cmd_status; - /* clean the upper 4 bits */ - cmd_status &= SPIDER_NET_DESCR_IND_PROC_MASKO; - /* add the status to it */ - cmd_status |= ((u32)status)<<SPIDER_NET_DESCR_IND_PROC_SHIFT; - /* and write it back */ - descr->dmac_cmd_status = cmd_status; + return descr->dmac_cmd_status & SPIDER_NET_DESCR_IND_PROC_MASK; } /** @@ -328,24 +299,23 @@ spider_net_free_chain(struct spider_net_card *card, static int spider_net_init_chain(struct spider_net_card *card, struct spider_net_descr_chain *chain, - struct spider_net_descr *start_descr, int no) + struct spider_net_descr *start_descr, + int direction, int no) { int i; struct spider_net_descr *descr; dma_addr_t buf; - atomic_set(&card->rx_chain_refill,0); - descr = start_descr; memset(descr, 0, sizeof(*descr) * no); /* set up the hardware pointers in each descriptor */ for (i=0; i<no; i++, descr++) { - spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); + descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; buf = pci_map_single(card->pdev, descr, SPIDER_NET_DESCR_SIZE, - PCI_DMA_BIDIRECTIONAL); + direction); if (buf == DMA_ERROR_CODE) goto iommu_error; @@ -360,10 +330,11 @@ spider_net_init_chain(struct spider_net_card *card, start_descr->prev = descr-1; descr = start_descr; - for (i=0; i < no; i++, descr++) { - descr->next_descr_addr = descr->next->bus_addr; - } + if (direction == PCI_DMA_FROMDEVICE) + for (i=0; i < no; i++, descr++) + descr->next_descr_addr = descr->next->bus_addr; + spin_lock_init(&chain->lock); chain->head = start_descr; chain->tail = start_descr; @@ -375,7 +346,7 @@ iommu_error: if (descr->bus_addr) pci_unmap_single(card->pdev, descr->bus_addr, SPIDER_NET_DESCR_SIZE, - PCI_DMA_BIDIRECTIONAL); + direction); return -ENOMEM; } @@ -396,7 +367,7 @@ spider_net_free_rx_chain_contents(struct spider_net_card *card) dev_kfree_skb(descr->skb); pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_FRAME, - PCI_DMA_BIDIRECTIONAL); + PCI_DMA_FROMDEVICE); } descr = descr->next; } @@ -446,15 +417,16 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, skb_reserve(descr->skb, SPIDER_NET_RXBUF_ALIGN - offset); /* io-mmu-map the skb */ buf = pci_map_single(card->pdev, descr->skb->data, - SPIDER_NET_MAX_FRAME, PCI_DMA_BIDIRECTIONAL); + SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); descr->buf_addr = buf; if (buf == DMA_ERROR_CODE) { dev_kfree_skb_any(descr->skb); if (netif_msg_rx_err(card) && net_ratelimit()) pr_err("Could not iommu-map rx buffer\n"); - spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); + descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; } else { - descr->dmac_cmd_status = SPIDER_NET_DMAC_RX_CARDOWNED; + descr->dmac_cmd_status = SPIDER_NET_DESCR_CARDOWNED | + SPIDER_NET_DMAC_NOINTR_COMPLETE; } return error; @@ -468,7 +440,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, * chip by writing to the appropriate register. DMA is enabled in * spider_net_enable_rxdmac. */ -static void +static inline void spider_net_enable_rxchtails(struct spider_net_card *card) { /* assume chain is aligned correctly */ @@ -483,7 +455,7 @@ spider_net_enable_rxchtails(struct spider_net_card *card) * spider_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN * in the GDADMACCNTR register */ -static void +static inline void spider_net_enable_rxdmac(struct spider_net_card *card) { wmb(); @@ -500,23 +472,24 @@ spider_net_enable_rxdmac(struct spider_net_card *card) static void spider_net_refill_rx_chain(struct spider_net_card *card) { - struct spider_net_descr_chain *chain; - - chain = &card->rx_chain; + struct spider_net_descr_chain *chain = &card->rx_chain; + unsigned long flags; /* one context doing the refill (and a second context seeing that * and omitting it) is ok. If called by NAPI, we'll be called again * as spider_net_decode_one_descr is called several times. If some * interrupt calls us, the NAPI is about to clean up anyway. */ - if (atomic_inc_return(&card->rx_chain_refill) == 1) - while (spider_net_get_descr_status(chain->head) == - SPIDER_NET_DESCR_NOT_IN_USE) { - if (spider_net_prepare_rx_descr(card, chain->head)) - break; - chain->head = chain->head->next; - } + if (!spin_trylock_irqsave(&chain->lock, flags)) + return; + + while (spider_net_get_descr_status(chain->head) == + SPIDER_NET_DESCR_NOT_IN_USE) { + if (spider_net_prepare_rx_descr(card, chain->head)) + break; + chain->head = chain->head->next; + } - atomic_dec(&card->rx_chain_refill); + spin_unlock_irqrestore(&chain->lock, flags); } /** @@ -554,111 +527,6 @@ error: } /** - * spider_net_release_tx_descr - processes a used tx descriptor - * @card: card structure - * @descr: descriptor to release - * - * releases a used tx descriptor (unmapping, freeing of skb) - */ -static void -spider_net_release_tx_descr(struct spider_net_card *card, - struct spider_net_descr *descr) -{ - struct sk_buff *skb; - - /* unmap the skb */ - skb = descr->skb; - pci_unmap_single(card->pdev, descr->buf_addr, skb->len, - PCI_DMA_BIDIRECTIONAL); - - dev_kfree_skb_any(skb); - - /* set status to not used */ - spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); -} - -/** - * spider_net_release_tx_chain - processes sent tx descriptors - * @card: adapter structure - * @brutal: if set, don't care about whether descriptor seems to be in use - * - * returns 0 if the tx ring is empty, otherwise 1. - * - * spider_net_release_tx_chain releases the tx descriptors that spider has - * finished with (if non-brutal) or simply release tx descriptors (if brutal). - * If some other context is calling this function, we return 1 so that we're - * scheduled again (if we were scheduled) and will not loose initiative. - */ -static int -spider_net_release_tx_chain(struct spider_net_card *card, int brutal) -{ - struct spider_net_descr_chain *tx_chain = &card->tx_chain; - enum spider_net_descr_status status; - - if (atomic_inc_return(&card->tx_chain_release) != 1) { - atomic_dec(&card->tx_chain_release); - return 1; - } - - for (;;) { - status = spider_net_get_descr_status(tx_chain->tail); - switch (status) { - case SPIDER_NET_DESCR_CARDOWNED: - if (!brutal) - goto out; - /* fallthrough, if we release the descriptors - * brutally (then we don't care about - * SPIDER_NET_DESCR_CARDOWNED) */ - case SPIDER_NET_DESCR_RESPONSE_ERROR: - case SPIDER_NET_DESCR_PROTECTION_ERROR: - case SPIDER_NET_DESCR_FORCE_END: - if (netif_msg_tx_err(card)) - pr_err("%s: forcing end of tx descriptor " - "with status x%02x\n", - card->netdev->name, status); - card->netdev_stats.tx_dropped++; - break; - - case SPIDER_NET_DESCR_COMPLETE: - card->netdev_stats.tx_packets++; - card->netdev_stats.tx_bytes += - tx_chain->tail->skb->len; - break; - - default: /* any other value (== SPIDER_NET_DESCR_NOT_IN_USE) */ - goto out; - } - spider_net_release_tx_descr(card, tx_chain->tail); - tx_chain->tail = tx_chain->tail->next; - } -out: - atomic_dec(&card->tx_chain_release); - - netif_wake_queue(card->netdev); - - if (status == SPIDER_NET_DESCR_CARDOWNED) - return 1; - return 0; -} - -/** - * spider_net_cleanup_tx_ring - cleans up the TX ring - * @card: card structure - * - * spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use - * interrupts to cleanup our TX ring) and returns sent packets to the stack - * by freeing them - */ -static void -spider_net_cleanup_tx_ring(struct spider_net_card *card) -{ - if ( (spider_net_release_tx_chain(card, 0)) && - (card->netdev->flags & IFF_UP) ) { - mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER); - } -} - -/** * spider_net_get_multicast_hash - generates hash for multicast filter table * @addr: multicast address * @@ -761,97 +629,6 @@ spider_net_disable_rxdmac(struct spider_net_card *card) } /** - * spider_net_stop - called upon ifconfig down - * @netdev: interface device structure - * - * always returns 0 - */ -int -spider_net_stop(struct net_device *netdev) -{ - struct spider_net_card *card = netdev_priv(netdev); - - tasklet_kill(&card->rxram_full_tl); - netif_poll_disable(netdev); - netif_carrier_off(netdev); - netif_stop_queue(netdev); - del_timer_sync(&card->tx_timer); - - /* disable/mask all interrupts */ - spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0); - spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0); - spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0); - - /* free_irq(netdev->irq, netdev);*/ - free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev); - - spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, - SPIDER_NET_DMA_TX_FEND_VALUE); - - /* turn off DMA, force end */ - spider_net_disable_rxdmac(card); - - /* release chains */ - spider_net_release_tx_chain(card, 1); - - spider_net_free_chain(card, &card->tx_chain); - spider_net_free_chain(card, &card->rx_chain); - - return 0; -} - -/** - * spider_net_get_next_tx_descr - returns the next available tx descriptor - * @card: device structure to get descriptor from - * - * returns the address of the next descriptor, or NULL if not available. - */ -static struct spider_net_descr * -spider_net_get_next_tx_descr(struct spider_net_card *card) -{ - /* check, if head points to not-in-use descr */ - if ( spider_net_get_descr_status(card->tx_chain.head) == - SPIDER_NET_DESCR_NOT_IN_USE ) { - return card->tx_chain.head; - } else { - return NULL; - } -} - -/** - * spider_net_set_txdescr_cmdstat - sets the tx descriptor command field - * @descr: descriptor structure to fill out - * @skb: packet to consider - * - * fills out the command and status field of the descriptor structure, - * depending on hardware checksum settings. - */ -static void -spider_net_set_txdescr_cmdstat(struct spider_net_descr *descr, - struct sk_buff *skb) -{ - /* make sure the other fields in the descriptor are written */ - wmb(); - - if (skb->ip_summed != CHECKSUM_HW) { - descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_NOCS; - return; - } - - /* is packet ip? - * if yes: tcp? udp? */ - if (skb->protocol == htons(ETH_P_IP)) { - if (skb->nh.iph->protocol == IPPROTO_TCP) - descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_TCPCS; - else if (skb->nh.iph->protocol == IPPROTO_UDP) - descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_UDPCS; - else /* the stack should checksum non-tcp and non-udp - packets on his own: NETIF_F_IP_CSUM */ - descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_NOCS; - } -} - -/** * spider_net_prepare_tx_descr - fill tx descriptor with skb data * @card: card structure * @descr: descriptor structure to fill out @@ -864,13 +641,12 @@ spider_net_set_txdescr_cmdstat(struct spider_net_descr *descr, */ static int spider_net_prepare_tx_descr(struct spider_net_card *card, - struct spider_net_descr *descr, struct sk_buff *skb) { + struct spider_net_descr *descr = card->tx_chain.head; dma_addr_t buf; - buf = pci_map_single(card->pdev, skb->data, - skb->len, PCI_DMA_BIDIRECTIONAL); + buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); if (buf == DMA_ERROR_CODE) { if (netif_msg_tx_err(card) && net_ratelimit()) pr_err("could not iommu-map packet (%p, %i). " @@ -880,10 +656,101 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, descr->buf_addr = buf; descr->buf_size = skb->len; + descr->next_descr_addr = 0; descr->skb = skb; descr->data_status = 0; - spider_net_set_txdescr_cmdstat(descr,skb); + descr->dmac_cmd_status = + SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS; + if (skb->protocol == htons(ETH_P_IP)) + switch (skb->nh.iph->protocol) { + case IPPROTO_TCP: + descr->dmac_cmd_status |= SPIDER_NET_DMAC_TCP; + break; + case IPPROTO_UDP: + descr->dmac_cmd_status |= SPIDER_NET_DMAC_UDP; + break; + } + + descr->prev->next_descr_addr = descr->bus_addr; + + return 0; +} + +/** + * spider_net_release_tx_descr - processes a used tx descriptor + * @card: card structure + * @descr: descriptor to release + * + * releases a used tx descriptor (unmapping, freeing of skb) + */ +static inline void +spider_net_release_tx_descr(struct spider_net_card *card) +{ + struct spider_net_descr *descr = card->tx_chain.tail; + struct sk_buff *skb; + + card->tx_chain.tail = card->tx_chain.tail->next; + descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE; + + /* unmap the skb */ + skb = descr->skb; + pci_unmap_single(card->pdev, descr->buf_addr, skb->len, + PCI_DMA_TODEVICE); + dev_kfree_skb_any(skb); +} + +/** + * spider_net_release_tx_chain - processes sent tx descriptors + * @card: adapter structure + * @brutal: if set, don't care about whether descriptor seems to be in use + * + * returns 0 if the tx ring is empty, otherwise 1. + * + * spider_net_release_tx_chain releases the tx descriptors that spider has + * finished with (if non-brutal) or simply release tx descriptors (if brutal). + * If some other context is calling this function, we return 1 so that we're + * scheduled again (if we were scheduled) and will not loose initiative. + */ +static int +spider_net_release_tx_chain(struct spider_net_card *card, int brutal) +{ + struct spider_net_descr_chain *chain = &card->tx_chain; + int status; + + spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR); + + while (chain->tail != chain->head) { + status = spider_net_get_descr_status(chain->tail); + switch (status) { + case SPIDER_NET_DESCR_COMPLETE: + card->netdev_stats.tx_packets++; + card->netdev_stats.tx_bytes += chain->tail->skb->len; + break; + + case SPIDER_NET_DESCR_CARDOWNED: + if (!brutal) + return 1; + /* fallthrough, if we release the descriptors + * brutally (then we don't care about + * SPIDER_NET_DESCR_CARDOWNED) */ + + case SPIDER_NET_DESCR_RESPONSE_ERROR: + case SPIDER_NET_DESCR_PROTECTION_ERROR: + case SPIDER_NET_DESCR_FORCE_END: + if (netif_msg_tx_err(card)) + pr_err("%s: forcing end of tx descriptor " + "with status x%02x\n", + card->netdev->name, status); + card->netdev_stats.tx_errors++; + break; + + default: + card->netdev_stats.tx_dropped++; + return 1; + } + spider_net_release_tx_descr(card); + } return 0; } @@ -896,18 +763,32 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, * spider_net_kick_tx_dma writes the current tx chain head as start address * of the tx descriptor chain and enables the transmission DMA engine */ -static void -spider_net_kick_tx_dma(struct spider_net_card *card, - struct spider_net_descr *descr) +static inline void +spider_net_kick_tx_dma(struct spider_net_card *card) { - /* this is the only descriptor in the output chain. - * Enable TX DMA */ + struct spider_net_descr *descr; - spider_net_write_reg(card, SPIDER_NET_GDTDCHA, - descr->bus_addr); + if (spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR) & + SPIDER_NET_TX_DMA_EN) + goto out; - spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, - SPIDER_NET_DMA_TX_VALUE); + descr = card->tx_chain.tail; + for (;;) { + if (spider_net_get_descr_status(descr) == + SPIDER_NET_DESCR_CARDOWNED) { + spider_net_write_reg(card, SPIDER_NET_GDTDCHA, + descr->bus_addr); + spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, + SPIDER_NET_DMA_TX_VALUE); + break; + } + if (descr == card->tx_chain.head) + break; + descr = descr->next; + } + +out: + mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER); } /** @@ -915,47 +796,69 @@ spider_net_kick_tx_dma(struct spider_net_card *card, * @skb: packet to send out * @netdev: interface device structure * - * returns 0 on success, <0 on failure + * returns 0 on success, !0 on failure */ static int spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) { struct spider_net_card *card = netdev_priv(netdev); - struct spider_net_descr *descr; + struct spider_net_descr_chain *chain = &card->tx_chain; + struct spider_net_descr *descr = chain->head; + unsigned long flags; int result; + spin_lock_irqsave(&chain->lock, flags); + spider_net_release_tx_chain(card, 0); - descr = spider_net_get_next_tx_descr(card); + if (chain->head->next == chain->tail->prev) { + card->netdev_stats.tx_dropped++; + result = NETDEV_TX_LOCKED; + goto out; + } - if (!descr) - goto error; + if (spider_net_get_descr_status(descr) != SPIDER_NET_DESCR_NOT_IN_USE) { + result = NETDEV_TX_LOCKED; + goto out; + } - result = spider_net_prepare_tx_descr(card, descr, skb); - if (result) - goto error; + if (spider_net_prepare_tx_descr(card, skb) != 0) { + card->netdev_stats.tx_dropped++; + result = NETDEV_TX_BUSY; + goto out; + } + + result = NETDEV_TX_OK; + spider_net_kick_tx_dma(card); card->tx_chain.head = card->tx_chain.head->next; - if (spider_net_get_descr_status(descr->prev) != - SPIDER_NET_DESCR_CARDOWNED) { - /* make sure the current descriptor is in memory. Then - * kicking it on again makes sense, if the previous is not - * card-owned anymore. Check the previous descriptor twice - * to omit an mb() in heavy traffic cases */ - mb(); - if (spider_net_get_descr_status(descr->prev) != - SPIDER_NET_DESCR_CARDOWNED) - spider_net_kick_tx_dma(card, descr); - } +out: + spin_unlock_irqrestore(&chain->lock, flags); + netif_wake_queue(netdev); + return result; +} - mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER); +/** + * spider_net_cleanup_tx_ring - cleans up the TX ring + * @card: card structure + * + * spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use + * interrupts to cleanup our TX ring) and returns sent packets to the stack + * by freeing them + */ +static void +spider_net_cleanup_tx_ring(struct spider_net_card *card) +{ + unsigned long flags; - return NETDEV_TX_OK; + spin_lock_irqsave(&card->tx_chain.lock, flags); -error: - card->netdev_stats.tx_dropped++; - return NETDEV_TX_BUSY; + if ((spider_net_release_tx_chain(card, 0) != 0) && + (card->netdev->flags & IFF_UP)) + spider_net_kick_tx_dma(card); + + spin_unlock_irqrestore(&card->tx_chain.lock, flags); } /** @@ -1002,7 +905,7 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, /* unmap descriptor */ pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_FRAME, - PCI_DMA_BIDIRECTIONAL); + PCI_DMA_FROMDEVICE); /* the cases we'll throw away the packet immediately */ if (data_error & SPIDER_NET_DESTROY_RX_FLAGS) { @@ -1067,14 +970,11 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, static int spider_net_decode_one_descr(struct spider_net_card *card, int napi) { - enum spider_net_descr_status status; - struct spider_net_descr *descr; - struct spider_net_descr_chain *chain; + struct spider_net_descr_chain *chain = &card->rx_chain; + struct spider_net_descr *descr = chain->tail; + int status; int result; - chain = &card->rx_chain; - descr = chain->tail; - status = spider_net_get_descr_status(descr); if (status == SPIDER_NET_DESCR_CARDOWNED) { @@ -1103,7 +1003,7 @@ spider_net_decode_one_descr(struct spider_net_card *card, int napi) card->netdev->name, status); card->netdev_stats.rx_dropped++; pci_unmap_single(card->pdev, descr->buf_addr, - SPIDER_NET_MAX_FRAME, PCI_DMA_BIDIRECTIONAL); + SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); dev_kfree_skb_irq(descr->skb); goto refill; } @@ -1119,7 +1019,7 @@ spider_net_decode_one_descr(struct spider_net_card *card, int napi) /* ok, we've got a packet in descr */ result = spider_net_pass_skb_up(descr, card, napi); refill: - spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); + descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; /* change the descriptor state: */ if (!napi) spider_net_refill_rx_chain(card); @@ -1291,21 +1191,6 @@ spider_net_set_mac(struct net_device *netdev, void *p) } /** - * spider_net_enable_txdmac - enables a TX DMA controller - * @card: card structure - * - * spider_net_enable_txdmac enables the TX DMA controller by setting the - * descriptor chain tail address - */ -static void -spider_net_enable_txdmac(struct spider_net_card *card) -{ - /* assume chain is aligned correctly */ - spider_net_write_reg(card, SPIDER_NET_GDTDCHA, - card->tx_chain.tail->bus_addr); -} - -/** * spider_net_handle_rxram_full - cleans up RX ring upon RX RAM full interrupt * @card: card structure * @@ -1653,7 +1538,6 @@ spider_net_enable_card(struct spider_net_card *card) { SPIDER_NET_GMRWOLCTRL, 0 }, { SPIDER_NET_GTESTMD, 0x10000000 }, { SPIDER_NET_GTTQMSK, 0x00400040 }, - { SPIDER_NET_GTESTMD, 0 }, { SPIDER_NET_GMACINTEN, 0 }, @@ -1692,9 +1576,6 @@ spider_net_enable_card(struct spider_net_card *card) spider_net_write_reg(card, SPIDER_NET_GRXDMAEN, SPIDER_NET_WOL_VALUE); - /* set chain tail adress for TX chain */ - spider_net_enable_txdmac(card); - spider_net_write_reg(card, SPIDER_NET_GMACLENLMT, SPIDER_NET_LENLMT_VALUE); spider_net_write_reg(card, SPIDER_NET_GMACMODE, @@ -1709,6 +1590,9 @@ spider_net_enable_card(struct spider_net_card *card) SPIDER_NET_INT1_MASK_VALUE); spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, SPIDER_NET_INT2_MASK_VALUE); + + spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, + SPIDER_NET_GDTDCEIDIS); } /** @@ -1728,10 +1612,12 @@ spider_net_open(struct net_device *netdev) result = -ENOMEM; if (spider_net_init_chain(card, &card->tx_chain, - card->descr, tx_descriptors)) + card->descr, + PCI_DMA_TODEVICE, tx_descriptors)) goto alloc_tx_failed; if (spider_net_init_chain(card, &card->rx_chain, - card->descr + tx_descriptors, rx_descriptors)) + card->descr + tx_descriptors, + PCI_DMA_FROMDEVICE, rx_descriptors)) goto alloc_rx_failed; /* allocate rx skbs */ @@ -1938,7 +1824,7 @@ spider_net_workaround_rxramfull(struct spider_net_card *card) /* empty sequencer data */ for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS; sequencer++) { - spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + + spider_net_write_reg(card, SPIDER_NET_GSnPRGADR + sequencer * 8, 0x0); for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) { spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + @@ -1955,6 +1841,49 @@ spider_net_workaround_rxramfull(struct spider_net_card *card) } /** + * spider_net_stop - called upon ifconfig down + * @netdev: interface device structure + * + * always returns 0 + */ +int +spider_net_stop(struct net_device *netdev) +{ + struct spider_net_card *card = netdev_priv(netdev); + + tasklet_kill(&card->rxram_full_tl); + netif_poll_disable(netdev); + netif_carrier_off(netdev); + netif_stop_queue(netdev); + del_timer_sync(&card->tx_timer); + + /* disable/mask all interrupts */ + spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0); + spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0); + spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0); + + /* free_irq(netdev->irq, netdev);*/ + free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev); + + spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, + SPIDER_NET_DMA_TX_FEND_VALUE); + + /* turn off DMA, force end */ + spider_net_disable_rxdmac(card); + + /* release chains */ + if (spin_trylock(&card->tx_chain.lock)) { + spider_net_release_tx_chain(card, 1); + spin_unlock(&card->tx_chain.lock); + } + + spider_net_free_chain(card, &card->tx_chain); + spider_net_free_chain(card, &card->rx_chain); + + return 0; +} + +/** * spider_net_tx_timeout_task - task scheduled by the watchdog timeout * function (to be called not under interrupt status) * @data: data, is interface device structure @@ -1982,7 +1911,7 @@ spider_net_tx_timeout_task(void *data) goto out; spider_net_open(netdev); - spider_net_kick_tx_dma(card, card->tx_chain.head); + spider_net_kick_tx_dma(card); netif_device_attach(netdev); out: @@ -2065,7 +1994,6 @@ spider_net_setup_netdev(struct spider_net_card *card) pci_set_drvdata(card->pdev, netdev); - atomic_set(&card->tx_chain_release,0); card->rxram_full_tl.data = (unsigned long) card; card->rxram_full_tl.func = (void (*)(unsigned long)) spider_net_handle_rxram_full; @@ -2079,7 +2007,7 @@ spider_net_setup_netdev(struct spider_net_card *card) spider_net_setup_netdev_ops(netdev); - netdev->features = NETIF_F_HW_CSUM; + netdev->features = NETIF_F_HW_CSUM | NETIF_F_LLTX; /* some time: NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | * NETIF_F_HW_VLAN_FILTER */ diff --git a/drivers/net/spider_net.h b/drivers/net/spider_net.h index 3b8d951cf73..f6dcf180ae3 100644 --- a/drivers/net/spider_net.h +++ b/drivers/net/spider_net.h @@ -208,7 +208,10 @@ extern char spider_net_driver_name[]; #define SPIDER_NET_DMA_RX_VALUE 0x80000000 #define SPIDER_NET_DMA_RX_FEND_VALUE 0x00030003 /* to set TX_DMA_EN */ -#define SPIDER_NET_DMA_TX_VALUE 0x80000000 +#define SPIDER_NET_TX_DMA_EN 0x80000000 +#define SPIDER_NET_GDTDCEIDIS 0x00000002 +#define SPIDER_NET_DMA_TX_VALUE SPIDER_NET_TX_DMA_EN | \ + SPIDER_NET_GDTDCEIDIS #define SPIDER_NET_DMA_TX_FEND_VALUE 0x00030003 /* SPIDER_NET_UA_DESCR_VALUE is OR'ed with the unicast address */ @@ -329,55 +332,23 @@ enum spider_net_int2_status { (~SPIDER_NET_TXINT) & \ (~SPIDER_NET_RXINT) ) -#define SPIDER_NET_GPREXEC 0x80000000 -#define SPIDER_NET_GPRDAT_MASK 0x0000ffff +#define SPIDER_NET_GPREXEC 0x80000000 +#define SPIDER_NET_GPRDAT_MASK 0x0000ffff -/* descriptor bits - * - * 1010 descriptor ready - * 0 descr in middle of chain - * 000 fixed to 0 - * - * 0 no interrupt on completion - * 000 fixed to 0 - * 1 no ipsec processing - * 1 last descriptor for this frame - * 00 no checksum - * 10 tcp checksum - * 11 udp checksum - * - * 00 fixed to 0 - * 0 fixed to 0 - * 0 no interrupt on response errors - * 0 no interrupt on invalid descr - * 0 no interrupt on dma process termination - * 0 no interrupt on descr chain end - * 0 no interrupt on descr complete - * - * 000 fixed to 0 - * 0 response error interrupt status - * 0 invalid descr status - * 0 dma termination status - * 0 descr chain end status - * 0 descr complete status */ -#define SPIDER_NET_DMAC_CMDSTAT_NOCS 0xa00c0000 -#define SPIDER_NET_DMAC_CMDSTAT_TCPCS 0xa00e0000 -#define SPIDER_NET_DMAC_CMDSTAT_UDPCS 0xa00f0000 -#define SPIDER_NET_DESCR_IND_PROC_SHIFT 28 -#define SPIDER_NET_DESCR_IND_PROC_MASKO 0x0fffffff - -/* descr ready, descr is in middle of chain, get interrupt on completion */ -#define SPIDER_NET_DMAC_RX_CARDOWNED 0xa0800000 - -enum spider_net_descr_status { - SPIDER_NET_DESCR_COMPLETE = 0x00, /* used in rx and tx */ - SPIDER_NET_DESCR_RESPONSE_ERROR = 0x01, /* used in rx and tx */ - SPIDER_NET_DESCR_PROTECTION_ERROR = 0x02, /* used in rx and tx */ - SPIDER_NET_DESCR_FRAME_END = 0x04, /* used in rx */ - SPIDER_NET_DESCR_FORCE_END = 0x05, /* used in rx and tx */ - SPIDER_NET_DESCR_CARDOWNED = 0x0a, /* used in rx and tx */ - SPIDER_NET_DESCR_NOT_IN_USE /* any other value */ -}; +#define SPIDER_NET_DMAC_NOINTR_COMPLETE 0x00800000 +#define SPIDER_NET_DMAC_NOCS 0x00040000 +#define SPIDER_NET_DMAC_TCP 0x00020000 +#define SPIDER_NET_DMAC_UDP 0x00030000 +#define SPIDER_NET_TXDCEST 0x08000000 + +#define SPIDER_NET_DESCR_IND_PROC_MASK 0xF0000000 +#define SPIDER_NET_DESCR_COMPLETE 0x00000000 /* used in rx and tx */ +#define SPIDER_NET_DESCR_RESPONSE_ERROR 0x10000000 /* used in rx and tx */ +#define SPIDER_NET_DESCR_PROTECTION_ERROR 0x20000000 /* used in rx and tx */ +#define SPIDER_NET_DESCR_FRAME_END 0x40000000 /* used in rx */ +#define SPIDER_NET_DESCR_FORCE_END 0x50000000 /* used in rx and tx */ +#define SPIDER_NET_DESCR_CARDOWNED 0xA0000000 /* used in rx and tx */ +#define SPIDER_NET_DESCR_NOT_IN_USE 0xF0000000 struct spider_net_descr { /* as defined by the hardware */ @@ -398,7 +369,7 @@ struct spider_net_descr { } __attribute__((aligned(32))); struct spider_net_descr_chain { - /* we walk from tail to head */ + spinlock_t lock; struct spider_net_descr *head; struct spider_net_descr *tail; }; @@ -453,8 +424,6 @@ struct spider_net_card { struct spider_net_descr_chain tx_chain; struct spider_net_descr_chain rx_chain; - atomic_t rx_chain_refill; - atomic_t tx_chain_release; struct net_device_stats netdev_stats; diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 8673fd4c08c..c6f5bc3c042 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -3255,12 +3255,7 @@ static void __devexit happy_meal_pci_remove(struct pci_dev *pdev) } static struct pci_device_id happymeal_pci_ids[] = { - { - .vendor = PCI_VENDOR_ID_SUN, - .device = PCI_DEVICE_ID_SUN_HAPPYMEAL, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, + { PCI_DEVICE(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_HAPPYMEAL) }, { } /* Terminating entry */ }; @@ -3275,7 +3270,7 @@ static struct pci_driver hme_pci_driver = { static int __init happy_meal_pci_init(void) { - return pci_module_init(&hme_pci_driver); + return pci_register_driver(&hme_pci_driver); } static void happy_meal_pci_exit(void) diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c index 2c09ec908a3..435e91ec462 100644 --- a/drivers/net/wan/c101.c +++ b/drivers/net/wan/c101.c @@ -197,7 +197,6 @@ static int c101_open(struct net_device *dev) sca_out(IE0_TXINT, MSCI0_OFFSET + IE0, port); set_carrier(port); - printk(KERN_DEBUG "0x%X\n", sca_in(MSCI1_OFFSET + ST3, port)); /* enable MSCI1 CDCD interrupt */ sca_out(IE1_CDCD, MSCI1_OFFSET + IE1, port); @@ -449,4 +448,5 @@ module_exit(c101_cleanup); MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); MODULE_DESCRIPTION("Moxa C101 serial port driver"); MODULE_LICENSE("GPL v2"); -module_param(hw, charp, 0444); /* hw=irq,ram:irq,... */ +module_param(hw, charp, 0444); +MODULE_PARM_DESC(hw, "irq,ram:irq,..."); diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c index b81263eaede..fbaab5bf71e 100644 --- a/drivers/net/wan/hdlc_ppp.c +++ b/drivers/net/wan/hdlc_ppp.c @@ -107,6 +107,7 @@ int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr) dev->hard_header = NULL; dev->type = ARPHRD_PPP; dev->addr_len = 0; + netif_dormant_off(dev); return 0; } diff --git a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c index 9456d31cb1c..f15aa6ba77f 100644 --- a/drivers/net/wan/hdlc_raw.c +++ b/drivers/net/wan/hdlc_raw.c @@ -82,6 +82,7 @@ int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr) dev->type = ARPHRD_RAWHDLC; dev->flags = IFF_POINTOPOINT | IFF_NOARP; dev->addr_len = 0; + netif_dormant_off(dev); return 0; } diff --git a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c index b1285cc8fee..d1884987f94 100644 --- a/drivers/net/wan/hdlc_raw_eth.c +++ b/drivers/net/wan/hdlc_raw_eth.c @@ -100,6 +100,7 @@ int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr) dev->tx_queue_len = old_qlen; memcpy(dev->dev_addr, "\x00\x01", 2); get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2); + netif_dormant_off(dev); return 0; } diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c index 07e5eef1fe0..a867fb411f8 100644 --- a/drivers/net/wan/hdlc_x25.c +++ b/drivers/net/wan/hdlc_x25.c @@ -212,6 +212,7 @@ int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr) dev->hard_header = NULL; dev->type = ARPHRD_X25; dev->addr_len = 0; + netif_dormant_off(dev); return 0; } diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c index e013b817cab..dcf46add3ad 100644 --- a/drivers/net/wan/n2.c +++ b/drivers/net/wan/n2.c @@ -564,4 +564,5 @@ module_exit(n2_cleanup); MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); MODULE_DESCRIPTION("RISCom/N2 serial port driver"); MODULE_LICENSE("GPL v2"); -module_param(hw, charp, 0444); /* hw=io,irq,ram,ports:io,irq,... */ +module_param(hw, charp, 0444); +MODULE_PARM_DESC(hw, "io,irq,ram,ports:io,irq,..."); diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index 4cd879cb9bd..1140302ff11 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c @@ -304,6 +304,7 @@ static int __init xpram_setup_sizes(unsigned long pages) { unsigned long mem_needed; unsigned long mem_auto; + unsigned long long size; int mem_auto_no; int i; @@ -321,9 +322,19 @@ static int __init xpram_setup_sizes(unsigned long pages) mem_needed = 0; mem_auto_no = 0; for (i = 0; i < xpram_devs; i++) { - if (sizes[i]) - xpram_sizes[i] = - (memparse(sizes[i], &sizes[i]) + 3) & -4UL; + if (sizes[i]) { + size = simple_strtoull(sizes[i], &sizes[i], 0); + switch (sizes[i][0]) { + case 'g': + case 'G': + size <<= 20; + break; + case 'm': + case 'M': + size <<= 10; + } + xpram_sizes[i] = (size + 3) & -4UL; + } if (xpram_sizes[i]) mem_needed += xpram_sizes[i]; else diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 95e285b2e25..7a84014f203 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -1106,10 +1106,10 @@ raw3270_delete_device(struct raw3270 *rp) /* Remove from device chain. */ mutex_lock(&raw3270_mutex); - if (rp->clttydev) + if (rp->clttydev && !IS_ERR(rp->clttydev)) class_device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor)); - if (rp->cltubdev) + if (rp->cltubdev && !IS_ERR(rp->cltubdev)) class_device_destroy(class3270, MKDEV(IBM_FS3270_MAJOR, rp->minor)); list_del_init(&rp->list); @@ -1173,21 +1173,37 @@ static struct attribute_group raw3270_attr_group = { .attrs = raw3270_attrs, }; -static void -raw3270_create_attributes(struct raw3270 *rp) +static int raw3270_create_attributes(struct raw3270 *rp) { - //FIXME: check return code - sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group); - rp->clttydev = - class_device_create(class3270, NULL, - MKDEV(IBM_TTY3270_MAJOR, rp->minor), - &rp->cdev->dev, "tty%s", - rp->cdev->dev.bus_id); - rp->cltubdev = - class_device_create(class3270, NULL, - MKDEV(IBM_FS3270_MAJOR, rp->minor), - &rp->cdev->dev, "tub%s", - rp->cdev->dev.bus_id); + int rc; + + rc = sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group); + if (rc) + goto out; + + rp->clttydev = class_device_create(class3270, NULL, + MKDEV(IBM_TTY3270_MAJOR, rp->minor), + &rp->cdev->dev, "tty%s", + rp->cdev->dev.bus_id); + if (IS_ERR(rp->clttydev)) { + rc = PTR_ERR(rp->clttydev); + goto out_ttydev; + } + + rp->cltubdev = class_device_create(class3270, NULL, + MKDEV(IBM_FS3270_MAJOR, rp->minor), + &rp->cdev->dev, "tub%s", + rp->cdev->dev.bus_id); + if (!IS_ERR(rp->cltubdev)) + goto out; + + rc = PTR_ERR(rp->cltubdev); + class_device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor)); + +out_ttydev: + sysfs_remove_group(&rp->cdev->dev.kobj, &raw3270_attr_group); +out: + return rc; } /* @@ -1255,7 +1271,9 @@ raw3270_set_online (struct ccw_device *cdev) rc = raw3270_reset_device(rp); if (rc) goto failure; - raw3270_create_attributes(rp); + rc = raw3270_create_attributes(rp); + if (rc) + goto failure; set_bit(RAW3270_FLAGS_READY, &rp->flags); mutex_lock(&raw3270_mutex); list_for_each_entry(np, &raw3270_notifier, list) diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c index a5c68e60fcf..643b6d07856 100644 --- a/drivers/s390/char/tape_class.c +++ b/drivers/s390/char/tape_class.c @@ -76,14 +76,22 @@ struct tape_class_device *register_tape_dev( device, "%s", tcd->device_name ); - sysfs_create_link( + rc = PTR_ERR(tcd->class_device); + if (rc) + goto fail_with_cdev; + rc = sysfs_create_link( &device->kobj, &tcd->class_device->kobj, tcd->mode_name ); + if (rc) + goto fail_with_class_device; return tcd; +fail_with_class_device: + class_device_destroy(tape_class, tcd->char_device->dev); + fail_with_cdev: cdev_del(tcd->char_device); diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 122b4d8965c..2826aed9104 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -543,20 +543,24 @@ int tape_generic_probe(struct ccw_device *cdev) { struct tape_device *device; + int ret; device = tape_alloc_device(); if (IS_ERR(device)) return -ENODEV; - PRINT_INFO("tape device %s found\n", cdev->dev.bus_id); + ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); + ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group); + if (ret) { + tape_put_device(device); + PRINT_ERR("probe failed for tape device %s\n", cdev->dev.bus_id); + return ret; + } cdev->dev.driver_data = device; + cdev->handler = __tape_do_irq; device->cdev = cdev; device->cdev_id = busid_to_int(cdev->dev.bus_id); - cdev->handler = __tape_do_irq; - - ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); - sysfs_create_group(&cdev->dev.kobj, &tape_attr_group); - - return 0; + PRINT_INFO("tape device %s found\n", cdev->dev.bus_id); + return ret; } static inline void diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index 0df3af1f08d..828b2d334f0 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c @@ -1068,6 +1068,7 @@ cmb_show_avg_sample_interval(struct device *dev, struct device_attribute *attr, if (count) { interval = cmb_data->last_update - cdev->private->cmb_start_time; + interval = (interval * 1000) >> 12; interval /= count; } else interval = -1; diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c index 20c8eb16f46..8a4b5812014 100644 --- a/drivers/s390/net/ctcmain.c +++ b/drivers/s390/net/ctcmain.c @@ -2686,9 +2686,17 @@ static struct attribute_group ctc_attr_group = { static int ctc_add_attributes(struct device *dev) { - device_create_file(dev, &dev_attr_loglevel); - device_create_file(dev, &dev_attr_stats); - return 0; + int rc; + + rc = device_create_file(dev, &dev_attr_loglevel); + if (rc) + goto out; + rc = device_create_file(dev, &dev_attr_stats); + if (!rc) + goto out; + device_remove_file(dev, &dev_attr_loglevel); +out: + return rc; } static void @@ -2901,7 +2909,12 @@ ctc_new_device(struct ccwgroup_device *cgdev) goto out; } - ctc_add_attributes(&cgdev->dev); + if (ctc_add_attributes(&cgdev->dev)) { + ctc_netdev_unregister(dev); + dev->priv = NULL; + ctc_free_netdevice(dev, 1); + goto out; + } strlcpy(privptr->fsm->name, dev->name, sizeof (privptr->fsm->name)); diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 103c41470bd..5fff1f93973 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -8451,10 +8451,11 @@ __qeth_reboot_event_card(struct device *dev, void *data) static int qeth_reboot_event(struct notifier_block *this, unsigned long event, void *ptr) { + int ret; - driver_for_each_device(&qeth_ccwgroup_driver.driver, NULL, NULL, - __qeth_reboot_event_card); - return NOTIFY_DONE; + ret = driver_for_each_device(&qeth_ccwgroup_driver.driver, NULL, NULL, + __qeth_reboot_event_card); + return ret ? NOTIFY_BAD : NOTIFY_DONE; } diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c index 16b59773c0b..935952ef88f 100644 --- a/drivers/sbus/sbus.c +++ b/drivers/sbus/sbus.c @@ -233,7 +233,7 @@ static void __init build_one_sbus(struct device_node *dp, int num_sbus) sbus->ofdev.node = dp; sbus->ofdev.dev.parent = NULL; sbus->ofdev.dev.bus = &sbus_bus_type; - strcpy(sbus->ofdev.dev.bus_id, dp->path_component_name); + sprintf(sbus->ofdev.dev.bus_id, "sbus%d", num_sbus); if (of_device_register(&sbus->ofdev) != 0) printk(KERN_DEBUG "sbus: device registration error for %s!\n", diff --git a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c index c690c2b89e4..acf292736b4 100644 --- a/drivers/scsi/53c7xx.c +++ b/drivers/scsi/53c7xx.c @@ -3451,12 +3451,12 @@ create_cmd (Scsi_Cmnd *cmd) { for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4, cmd_dataout += 4, ++i) { u32 vbuf = cmd->use_sg - ? (u32)page_address(((struct scatterlist *)cmd->buffer)[i].page)+ - ((struct scatterlist *)cmd->buffer)[i].offset + ? (u32)page_address(((struct scatterlist *)cmd->request_buffer)[i].page)+ + ((struct scatterlist *)cmd->request_buffer)[i].offset : (u32)(cmd->request_buffer); u32 bbuf = virt_to_bus((void *)vbuf); u32 count = cmd->use_sg ? - ((struct scatterlist *)cmd->buffer)[i].length : + ((struct scatterlist *)cmd->request_buffer)[i].length : cmd->request_bufflen; /* @@ -5417,7 +5417,7 @@ insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) { if ((buffers = cmd->use_sg)) { for (offset = 0, - segment = (struct scatterlist *) cmd->buffer; + segment = (struct scatterlist *) cmd->request_buffer; buffers && !((found = ((ptr >= (char *)page_address(segment->page)+segment->offset) && (ptr < ((char *)page_address(segment->page)+segment->offset+segment->length))))); --buffers, offset += segment->length, ++segment) diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c index 8a4659e9410..085db4826e0 100644 --- a/drivers/scsi/NCR53C9x.c +++ b/drivers/scsi/NCR53C9x.c @@ -911,7 +911,7 @@ static void esp_get_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp) sp->SCp.ptr = (char *) virt_to_phys(sp->request_buffer); } else { - sp->SCp.buffer = (struct scatterlist *) sp->buffer; + sp->SCp.buffer = (struct scatterlist *) sp->request_buffer; sp->SCp.buffers_residual = sp->use_sg - 1; sp->SCp.this_residual = sp->SCp.buffer->length; if (esp->dma_mmu_get_scsi_sgl) diff --git a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c index a06f547e87f..d05681f9d81 100644 --- a/drivers/scsi/NCR_D700.c +++ b/drivers/scsi/NCR_D700.c @@ -114,7 +114,7 @@ MODULE_DESCRIPTION("NCR Dual700 SCSI Driver"); MODULE_LICENSE("GPL"); module_param(NCR_D700, charp, 0); -static __u8 __initdata id_array[2*(MCA_MAX_SLOT_NR + 1)] = +static __u8 __devinitdata id_array[2*(MCA_MAX_SLOT_NR + 1)] = { [0 ... 2*(MCA_MAX_SLOT_NR + 1)-1] = 7 }; #ifdef MODULE @@ -173,7 +173,7 @@ struct NCR_D700_private { char pad; }; -static int +static int __devinit NCR_D700_probe_one(struct NCR_D700_private *p, int siop, int irq, int slot, u32 region, int differential) { @@ -243,7 +243,7 @@ NCR_D700_intr(int irq, void *data, struct pt_regs *regs) * essentially connectecd to the MCA bus independently, it is easier * to set them up as two separate host adapters, rather than one * adapter with two channels */ -static int +static int __devinit NCR_D700_probe(struct device *dev) { struct NCR_D700_private *p; @@ -329,7 +329,7 @@ NCR_D700_probe(struct device *dev) for (i = 0; i < 2; i++) { int err; - if ((err = NCR_D700_probe_one(p, i, slot, irq, + if ((err = NCR_D700_probe_one(p, i, irq, slot, offset_addr + (0x80 * i), differential)) != 0) printk("D700: SIOP%d: probe failed, error = %d\n", @@ -349,7 +349,7 @@ NCR_D700_probe(struct device *dev) return 0; } -static void +static void __devexit NCR_D700_remove_one(struct Scsi_Host *host) { scsi_remove_host(host); @@ -359,7 +359,7 @@ NCR_D700_remove_one(struct Scsi_Host *host) release_region(host->base, 64); } -static int +static int __devexit NCR_D700_remove(struct device *dev) { struct NCR_D700_private *p = dev_get_drvdata(dev); @@ -380,7 +380,7 @@ static struct mca_driver NCR_D700_driver = { .name = "NCR_D700", .bus = &mca_bus_type, .probe = NCR_D700_probe, - .remove = NCR_D700_remove, + .remove = __devexit_p(NCR_D700_remove), }, }; diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index 36e63f82d9f..f974869ea32 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -551,6 +551,11 @@ struct aha152x_hostdata { struct aha152x_scdata { Scsi_Cmnd *next; /* next sc in queue */ struct semaphore *sem; /* semaphore to block on */ + unsigned char cmd_len; + unsigned char cmnd[MAX_COMMAND_SIZE]; + unsigned short use_sg; + unsigned request_bufflen; + void *request_buffer; }; @@ -1006,11 +1011,20 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int p return FAILED; } } else { + struct aha152x_scdata *sc; + SCpnt->host_scribble = kmalloc(sizeof(struct aha152x_scdata), GFP_ATOMIC); if(SCpnt->host_scribble==0) { printk(ERR_LEAD "allocation failed\n", CMDINFO(SCpnt)); return FAILED; } + + sc = SCDATA(SCpnt); + memcpy(sc->cmnd, SCpnt->cmnd, sizeof(sc->cmnd)); + sc->request_buffer = SCpnt->request_buffer; + sc->request_bufflen = SCpnt->request_bufflen; + sc->use_sg = SCpnt->use_sg; + sc->cmd_len = SCpnt->cmd_len; } SCNEXT(SCpnt) = NULL; @@ -1165,6 +1179,10 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt) DECLARE_MUTEX_LOCKED(sem); struct timer_list timer; int ret, issued, disconnected; + unsigned char old_cmd_len = SCpnt->cmd_len; + unsigned short old_use_sg = SCpnt->use_sg; + void *old_buffer = SCpnt->request_buffer; + unsigned old_bufflen = SCpnt->request_bufflen; unsigned long flags; #if defined(AHA152X_DEBUG) @@ -1198,11 +1216,11 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt) add_timer(&timer); down(&sem); del_timer(&timer); - - SCpnt->cmd_len = SCpnt->old_cmd_len; - SCpnt->use_sg = SCpnt->old_use_sg; - SCpnt->request_buffer = SCpnt->buffer; - SCpnt->request_bufflen = SCpnt->bufflen; + + SCpnt->cmd_len = old_cmd_len; + SCpnt->use_sg = old_use_sg; + SCpnt->request_buffer = old_buffer; + SCpnt->request_bufflen = old_bufflen; DO_LOCK(flags); @@ -1565,6 +1583,9 @@ static void busfree_run(struct Scsi_Host *shpnt) #endif if(DONE_SC->SCp.phase & check_condition) { + struct scsi_cmnd *cmd = HOSTDATA(shpnt)->done_SC; + struct aha152x_scdata *sc = SCDATA(cmd); + #if 0 if(HOSTDATA(shpnt)->debug & debug_eh) { printk(ERR_LEAD "received sense: ", CMDINFO(DONE_SC)); @@ -1573,13 +1594,13 @@ static void busfree_run(struct Scsi_Host *shpnt) #endif /* restore old command */ - memcpy((void *) DONE_SC->cmnd, (void *) DONE_SC->data_cmnd, sizeof(DONE_SC->data_cmnd)); - DONE_SC->request_buffer = DONE_SC->buffer; - DONE_SC->request_bufflen = DONE_SC->bufflen; - DONE_SC->use_sg = DONE_SC->old_use_sg; - DONE_SC->cmd_len = DONE_SC->old_cmd_len; + memcpy(cmd->cmnd, sc->cmnd, sizeof(sc->cmnd)); + cmd->request_buffer = sc->request_buffer; + cmd->request_bufflen = sc->request_bufflen; + cmd->use_sg = sc->use_sg; + cmd->cmd_len = sc->cmd_len; - DONE_SC->SCp.Status = 0x02; + cmd->SCp.Status = 0x02; HOSTDATA(shpnt)->commands--; if (!HOSTDATA(shpnt)->commands) diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index a1e8ca75859..653818d2f80 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c @@ -7289,7 +7289,7 @@ ahd_reset_cmds_pending(struct ahd_softc *ahd) ahd->flags &= ~AHD_UPDATE_PEND_CMDS; } -void +static void ahd_done_with_status(struct ahd_softc *ahd, struct scb *scb, uint32_t status) { cam_status ostat; diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index b244c712417..998999c0a97 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -243,25 +243,6 @@ ahd_print_path(struct ahd_softc *ahd, struct scb *scb) static uint32_t aic79xx_no_reset; /* - * Certain PCI motherboards will scan PCI devices from highest to lowest, - * others scan from lowest to highest, and they tend to do all kinds of - * strange things when they come into contact with PCI bridge chips. The - * net result of all this is that the PCI card that is actually used to boot - * the machine is very hard to detect. Most motherboards go from lowest - * PCI slot number to highest, and the first SCSI controller found is the - * one you boot from. The only exceptions to this are when a controller - * has its BIOS disabled. So, we by default sort all of our SCSI controllers - * from lowest PCI slot number to highest PCI slot number. We also force - * all controllers with their BIOS disabled to the end of the list. This - * works on *almost* all computers. Where it doesn't work, we have this - * option. Setting this option to non-0 will reverse the order of the sort - * to highest first, then lowest, but will still leave cards with their BIOS - * disabled at the very end. That should fix everyone up unless there are - * really strange cirumstances. - */ -static uint32_t aic79xx_reverse_scan; - -/* * Should we force EXTENDED translation on a controller. * 0 == Use whatever is in the SEEPROM or default to off * 1 == Use whatever is in the SEEPROM or default to on @@ -350,7 +331,6 @@ MODULE_PARM_DESC(aic79xx, " periodically to prevent tag starvation.\n" " This may be required by some older disk\n" " or drives/RAID arrays.\n" -" reverse_scan Sort PCI devices highest Bus/Slot to lowest\n" " tag_info:<tag_str> Set per-target tag depth\n" " global_tag_depth:<int> Global tag depth for all targets on all buses\n" " slewrate:<slewrate_list>Set the signal slew rate (0-15).\n" @@ -1031,7 +1011,6 @@ aic79xx_setup(char *s) #ifdef AHD_DEBUG { "debug", &ahd_debug }, #endif - { "reverse_scan", &aic79xx_reverse_scan }, { "periodic_otag", &aic79xx_periodic_otag }, { "pci_parity", &aic79xx_pci_parity }, { "seltime", &aic79xx_seltime }, diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index debf3e2a079..aa4be8a3141 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -353,7 +353,6 @@ MODULE_PARM_DESC(aic7xxx, " periodically to prevent tag starvation.\n" " This may be required by some older disk\n" " drives or RAID arrays.\n" -" reverse_scan Sort PCI devices highest Bus/Slot to lowest\n" " tag_info:<tag_str> Set per-target tag depth\n" " global_tag_depth:<int> Global tag depth for every target\n" " on every bus\n" diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 007a14e5c3f..e397129c90d 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -507,7 +507,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd *cmd) */ if (cmd->use_sg) { - cmd->SCp.buffer = (struct scatterlist *) cmd->buffer; + cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer; cmd->SCp.buffers_residual = cmd->use_sg - 1; cmd->SCp.ptr = (char *)page_address(cmd->SCp.buffer->page)+ cmd->SCp.buffer->offset; diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index dddd2acce76..61f6024b61b 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -5,6 +5,7 @@ * Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002) * by D. Gilbert and aeb (20020609) * Additions for SPC-3 T10/1416-D Rev 21 22 Sept 2004, D. Gilbert 20041025 + * Update to SPC-4 T10/1713-D Rev 5a, 14 June 2006, D. Gilbert 20060702 */ #include <linux/blkdev.h> @@ -36,55 +37,56 @@ static const char * cdb_byte0_names[] = { /* 00-03 */ "Test Unit Ready", "Rezero Unit/Rewind", NULL, "Request Sense", /* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL, "Reasssign Blocks", -/* 08-0d */ "Read (6)", NULL, "Write (6)", "Seek (6)", NULL, NULL, +/* 08-0d */ "Read(6)", NULL, "Write(6)", "Seek(6)", NULL, NULL, /* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry", -/* 13-16 */ "Verify (6)", "Recover Buffered Data", "Mode Select (6)", - "Reserve (6)", -/* 17-1a */ "Release (6)", "Copy", "Erase", "Mode Sense (6)", +/* 13-16 */ "Verify(6)", "Recover Buffered Data", "Mode Select(6)", + "Reserve(6)", +/* 17-1a */ "Release(6)", "Copy", "Erase", "Mode Sense(6)", /* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic", /* 1e-1f */ "Prevent/Allow Medium Removal", NULL, /* 20-22 */ NULL, NULL, NULL, /* 23-28 */ "Read Format Capacities", "Set Window", - "Read Capacity (10)", NULL, NULL, "Read (10)", -/* 29-2d */ "Read Generation", "Write (10)", "Seek (10)", "Erase (10)", - "Read updated block", -/* 2e-31 */ "Write Verify (10)", "Verify (10)", "Search High", "Search Equal", + "Read Capacity(10)", NULL, NULL, "Read(10)", +/* 29-2d */ "Read Generation", "Write(10)", "Seek(10)", "Erase(10)", + "Read updated block", +/* 2e-31 */ "Write Verify(10)", "Verify(10)", "Search High", "Search Equal", /* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position", -/* 35-37 */ "Synchronize Cache (10)", "Lock/Unlock Cache (10)", +/* 35-37 */ "Synchronize Cache(10)", "Lock/Unlock Cache(10)", "Read Defect Data(10)", /* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer", "Read Buffer", -/* 3d-3f */ "Update Block", "Read Long (10)", "Write Long (10)", -/* 40-41 */ "Change Definition", "Write Same (10)", +/* 3d-3f */ "Update Block", "Read Long(10)", "Write Long(10)", +/* 40-41 */ "Change Definition", "Write Same(10)", /* 42-48 */ "Read sub-channel", "Read TOC/PMA/ATIP", "Read density support", - "Play audio (10)", "Get configuration", "Play audio msf", + "Play audio(10)", "Get configuration", "Play audio msf", "Play audio track/index", -/* 49-4f */ "Play track relative (10)", "Get event status notification", +/* 49-4f */ "Play track relative(10)", "Get event status notification", "Pause/resume", "Log Select", "Log Sense", "Stop play/scan", NULL, /* 50-55 */ "Xdwrite", "Xpwrite, Read disk info", "Xdread, Read track info", - "Reserve track", "Send OPC info", "Mode Select (10)", -/* 56-5b */ "Reserve (10)", "Release (10)", "Repair track", "Read master cue", - "Mode Sense (10)", "Close track/session", + "Reserve track", "Send OPC info", "Mode Select(10)", +/* 56-5b */ "Reserve(10)", "Release(10)", "Repair track", "Read master cue", + "Mode Sense(10)", "Close track/session", /* 5c-5f */ "Read buffer capacity", "Send cue sheet", "Persistent reserve in", "Persistent reserve out", /* 60-67 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 68-6f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 70-77 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 78-7f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Variable length", -/* 80-84 */ "Xdwrite (16)", "Rebuild (16)", "Regenerate (16)", "Extended copy", +/* 80-84 */ "Xdwrite(16)", "Rebuild(16)", "Regenerate(16)", "Extended copy", "Receive copy results", -/* 85-89 */ "Memory Export In (16)", "Access control in", "Access control out", - "Read (16)", "Memory Export Out (16)", -/* 8a-8f */ "Write (16)", NULL, "Read attributes", "Write attributes", - "Write and verify (16)", "Verify (16)", -/* 90-94 */ "Pre-fetch (16)", "Synchronize cache (16)", - "Lock/unlock cache (16)", "Write same (16)", NULL, +/* 85-89 */ "ATA command pass through(16)", "Access control in", + "Access control out", "Read(16)", "Memory Export Out(16)", +/* 8a-8f */ "Write(16)", NULL, "Read attributes", "Write attributes", + "Write and verify(16)", "Verify(16)", +/* 90-94 */ "Pre-fetch(16)", "Synchronize cache(16)", + "Lock/unlock cache(16)", "Write same(16)", NULL, /* 95-99 */ NULL, NULL, NULL, NULL, NULL, -/* 9a-9f */ NULL, NULL, NULL, NULL, "Service action in (16)", - "Service action out (16)", -/* a0-a5 */ "Report luns", "Blank", "Send event", "Maintenance in", - "Maintenance out", "Move medium/play audio(12)", +/* 9a-9f */ NULL, NULL, NULL, NULL, "Service action in(16)", + "Service action out(16)", +/* a0-a5 */ "Report luns", "ATA command pass through(12)/Blank", + "Security protocol in", "Maintenance in", "Maintenance out", + "Move medium/play audio(12)", /* a6-a9 */ "Exchange medium", "Move medium attached", "Read(12)", "Play track relative(12)", /* aa-ae */ "Write(12)", NULL, "Erase(12), Get Performance", @@ -92,12 +94,12 @@ static const char * cdb_byte0_names[] = { /* af-b1 */ "Verify(12)", "Search data high(12)", "Search data equal(12)", /* b2-b4 */ "Search data low(12)", "Set limits(12)", "Read element status attached", -/* b5-b6 */ "Request volume element address", "Send volume tag, set streaming", +/* b5-b6 */ "Security protocol out", "Send volume tag, set streaming", /* b7-b9 */ "Read defect data(12)", "Read element status", "Read CD msf", /* ba-bc */ "Redundancy group (in), Scan", - "Redundancy group (out), Set cd-rom speed", "Spare in, Play cd", -/* bd-bf */ "Spare out, Mechanism status", "Volume set in, Read cd", - "Volume set out, Send DVD structure", + "Redundancy group (out), Set cd-rom speed", "Spare (in), Play cd", +/* bd-bf */ "Spare (out), Mechanism status", "Volume set (in), Read cd", + "Volume set (out), Send DVD structure", }; struct value_name_pair { @@ -112,6 +114,7 @@ static const struct value_name_pair maint_in_arr[] = { {0xc, "Report supported operation codes"}, {0xd, "Report supported task management functions"}, {0xe, "Report priority"}, + {0xf, "Report timestamp"}, }; #define MAINT_IN_SZ ARRAY_SIZE(maint_in_arr) @@ -120,6 +123,7 @@ static const struct value_name_pair maint_out_arr[] = { {0xa, "Set target port groups"}, {0xb, "Change aliases"}, {0xe, "Set priority"}, + {0xe, "Set timestamp"}, }; #define MAINT_OUT_SZ ARRAY_SIZE(maint_out_arr) @@ -427,6 +431,7 @@ static struct error_info additional[] = {0x001A, "Rewind operation in progress"}, {0x001B, "Set capacity operation in progress"}, {0x001C, "Verify operation in progress"}, + {0x001D, "ATA pass through information available"}, {0x0100, "No index/sector signal"}, @@ -438,7 +443,7 @@ static struct error_info additional[] = {0x0400, "Logical unit not ready, cause not reportable"}, {0x0401, "Logical unit is in process of becoming ready"}, - {0x0402, "Logical unit not ready, initializing cmd. required"}, + {0x0402, "Logical unit not ready, initializing command required"}, {0x0403, "Logical unit not ready, manual intervention required"}, {0x0404, "Logical unit not ready, format in progress"}, {0x0405, "Logical unit not ready, rebuild in progress"}, @@ -478,6 +483,9 @@ static struct error_info additional[] = {0x0B00, "Warning"}, {0x0B01, "Warning - specified temperature exceeded"}, {0x0B02, "Warning - enclosure degraded"}, + {0x0B03, "Warning - background self-test failed"}, + {0x0B04, "Warning - background pre-scan detected medium error"}, + {0x0B05, "Warning - background medium scan detected medium error"}, {0x0C00, "Write error"}, {0x0C01, "Write error - recovered with auto reallocation"}, @@ -493,6 +501,7 @@ static struct error_info additional[] = {0x0C0B, "Auxiliary memory write error"}, {0x0C0C, "Write error - unexpected unsolicited data"}, {0x0C0D, "Write error - not enough unsolicited data"}, + {0x0C0F, "Defects in error window"}, {0x0D00, "Error detected by third party temporary initiator"}, {0x0D01, "Third party device failure"}, @@ -504,11 +513,12 @@ static struct error_info additional[] = {0x0E00, "Invalid information unit"}, {0x0E01, "Information unit too short"}, {0x0E02, "Information unit too long"}, + {0x0E03, "Invalid field in command information unit"}, {0x1000, "Id CRC or ECC error"}, - {0x1001, "Data block guard check failed"}, - {0x1002, "Data block application tag check failed"}, - {0x1003, "Data block reference tag check failed"}, + {0x1001, "Logical block guard check failed"}, + {0x1002, "Logical block application tag check failed"}, + {0x1003, "Logical block reference tag check failed"}, {0x1100, "Unrecovered read error"}, {0x1101, "Read retries exhausted"}, @@ -530,6 +540,7 @@ static struct error_info additional[] = {0x1111, "Read error - loss of streaming"}, {0x1112, "Auxiliary memory read error"}, {0x1113, "Read error - failed retransmission request"}, + {0x1114, "Read error - lba marked bad by application client"}, {0x1200, "Address mark not found for id field"}, @@ -610,11 +621,14 @@ static struct error_info additional[] = {0x2100, "Logical block address out of range"}, {0x2101, "Invalid element address"}, {0x2102, "Invalid address for write"}, + {0x2103, "Invalid write crossing layer jump"}, {0x2200, "Illegal function (use 20 00, 24 00, or 26 00)"}, {0x2400, "Invalid field in cdb"}, {0x2401, "CDB decryption error"}, + {0x2402, "Obsolete"}, + {0x2403, "Obsolete"}, {0x2404, "Security audit value frozen"}, {0x2405, "Security working key frozen"}, {0x2406, "Nonce not unique"}, @@ -637,7 +651,10 @@ static struct error_info additional[] = {0x260C, "Invalid operation for copy source or destination"}, {0x260D, "Copy segment granularity violation"}, {0x260E, "Invalid parameter while port is enabled"}, - {0x260F, "Invalid data-out buffer integrity"}, + {0x260F, "Invalid data-out buffer integrity check value"}, + {0x2610, "Data decryption key fail limit reached"}, + {0x2611, "Incomplete key-associated data set"}, + {0x2612, "Vendor specific key reference not found"}, {0x2700, "Write protected"}, {0x2701, "Hardware write protected"}, @@ -649,6 +666,7 @@ static struct error_info additional[] = {0x2800, "Not ready to ready change, medium may have changed"}, {0x2801, "Import or export element accessed"}, + {0x2802, "Format-layer may have changed"}, {0x2900, "Power on, reset, or bus device reset occurred"}, {0x2901, "Power on occurred"}, @@ -669,6 +687,11 @@ static struct error_info additional[] = {0x2A07, "Implicit asymmetric access state transition failed"}, {0x2A08, "Priority changed"}, {0x2A09, "Capacity data has changed"}, + {0x2A10, "Timestamp changed"}, + {0x2A11, "Data encryption parameters changed by another i_t nexus"}, + {0x2A12, "Data encryption parameters changed by vendor specific " + "event"}, + {0x2A13, "Data encryption key instance counter has changed"}, {0x2B00, "Copy cannot execute since host cannot disconnect"}, @@ -690,6 +713,7 @@ static struct error_info additional[] = {0x2E00, "Insufficient time for operation"}, {0x2F00, "Commands cleared by another initiator"}, + {0x2F01, "Commands cleared by power loss notification"}, {0x3000, "Incompatible medium installed"}, {0x3001, "Cannot read medium - unknown format"}, @@ -702,7 +726,8 @@ static struct error_info additional[] = {0x3008, "Cannot write - application code mismatch"}, {0x3009, "Current session not fixated for append"}, {0x300A, "Cleaning request rejected"}, - {0x300C, "WORM medium, overwrite attempted"}, + {0x300C, "WORM medium - overwrite attempted"}, + {0x300D, "WORM medium - integrity check"}, {0x3010, "Medium not formatted"}, {0x3100, "Medium format corrupted"}, @@ -790,6 +815,9 @@ static struct error_info additional[] = {0x3F0F, "Echo buffer overwritten"}, {0x3F10, "Medium loadable"}, {0x3F11, "Medium auxiliary memory accessible"}, + {0x3F12, "iSCSI IP address added"}, + {0x3F13, "iSCSI IP address removed"}, + {0x3F14, "iSCSI IP address changed"}, /* * {0x40NN, "Ram failure"}, * {0x40NN, "Diagnostic failure on component nn"}, @@ -799,6 +827,7 @@ static struct error_info additional[] = {0x4300, "Message error"}, {0x4400, "Internal target failure"}, + {0x4471, "ATA device failed set features"}, {0x4500, "Select or reselect failure"}, @@ -807,9 +836,10 @@ static struct error_info additional[] = {0x4700, "Scsi parity error"}, {0x4701, "Data phase CRC error detected"}, {0x4702, "Scsi parity error detected during st data phase"}, - {0x4703, "Information unit CRC error detected"}, + {0x4703, "Information unit iuCRC error detected"}, {0x4704, "Asynchronous information protection error detected"}, {0x4705, "Protocol service CRC error"}, + {0x4706, "Phy test function in progress"}, {0x477f, "Some commands cleared by iSCSI Protocol event"}, {0x4800, "Initiator detected error message received"}, @@ -844,6 +874,8 @@ static struct error_info additional[] = {0x5300, "Media load or eject failed"}, {0x5301, "Unload tape failure"}, {0x5302, "Medium removal prevented"}, + {0x5303, "Medium removal prevented by data transfer element"}, + {0x5304, "Medium thread or unthread failure"}, {0x5400, "Scsi to host system interface failure"}, @@ -855,6 +887,7 @@ static struct error_info additional[] = {0x5505, "Insufficient access control resources"}, {0x5506, "Auxiliary memory out of space"}, {0x5507, "Quota error"}, + {0x5508, "Maximum number of supplemental decryption keys exceeded"}, {0x5700, "Unable to recover table-of-contents"}, @@ -1004,6 +1037,7 @@ static struct error_info additional[] = {0x6708, "Assign failure occurred"}, {0x6709, "Multiply assigned logical unit"}, {0x670A, "Set target port groups command failed"}, + {0x670B, "ATA device feature not enabled"}, {0x6800, "Logical unit not configured"}, @@ -1030,6 +1064,8 @@ static struct error_info additional[] = {0x6F03, "Read of scrambled sector without authentication"}, {0x6F04, "Media region code is mismatched to logical unit region"}, {0x6F05, "Drive region must be permanent/region reset count error"}, + {0x6F06, "Insufficient block count for binding nonce recording"}, + {0x6F07, "Conflict in binding nonce recording"}, /* * {0x70NN, "Decompression exception short algorithm id of nn"}, */ @@ -1041,6 +1077,8 @@ static struct error_info additional[] = {0x7203, "Session fixation error - incomplete track in session"}, {0x7204, "Empty or partially written reserved track"}, {0x7205, "No more track reservations allowed"}, + {0x7206, "RMZ extension is not allowed"}, + {0x7207, "No more test zone extensions are allowed"}, {0x7300, "Cd control error"}, {0x7301, "Power calibration area almost full"}, @@ -1049,6 +1087,18 @@ static struct error_info additional[] = {0x7304, "Program memory area update failure"}, {0x7305, "Program memory area is full"}, {0x7306, "RMA/PMA is almost full"}, + {0x7310, "Current power calibration area almost full"}, + {0x7311, "Current power calibration area is full"}, + {0x7317, "RDZ is full"}, + + {0x7400, "Security error"}, + {0x7401, "Unable to decrypt data"}, + {0x7402, "Unencrypted data encountered while decrypting"}, + {0x7403, "Incorrect data encryption key"}, + {0x7404, "Cryptographic integrity validation failed"}, + {0x7405, "Error decrypting data"}, + {0x7471, "Logical unit access not authorized"}, + {0, NULL} }; diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c index 10573c24a50..eaf64c7e54e 100644 --- a/drivers/scsi/esp.c +++ b/drivers/scsi/esp.c @@ -1397,7 +1397,7 @@ static void esp_get_dmabufs(struct esp *esp, struct scsi_cmnd *sp) sp->SCp.ptr = NULL; } } else { - sp->SCp.buffer = (struct scatterlist *) sp->buffer; + sp->SCp.buffer = (struct scatterlist *) sp->request_buffer; sp->SCp.buffers_residual = sbus_map_sg(esp->sdev, sp->SCp.buffer, sp->use_sg, @@ -1410,7 +1410,7 @@ static void esp_get_dmabufs(struct esp *esp, struct scsi_cmnd *sp) static void esp_release_dmabufs(struct esp *esp, struct scsi_cmnd *sp) { if (sp->use_sg) { - sbus_unmap_sg(esp->sdev, sp->buffer, sp->use_sg, + sbus_unmap_sg(esp->sdev, sp->request_buffer, sp->use_sg, sp->sc_data_direction); } else if (sp->request_bufflen) { sbus_unmap_single(esp->sdev, diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c index 7eed0b09817..6aeb5f003c3 100644 --- a/drivers/scsi/ibmvscsi/iseries_vscsi.c +++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c @@ -81,7 +81,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, int rc; single_host_data = hostdata; - rc = viopath_open(viopath_hostLp, viomajorsubtype_scsi, 0); + rc = viopath_open(viopath_hostLp, viomajorsubtype_scsi, max_requests); if (rc < 0) { printk("viopath_open failed with rc %d in open_event_path\n", rc); diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 242b8873b33..ed22b96580c 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -238,6 +238,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, if (rc == 2) { /* Adapter is good, but other end is not ready */ printk(KERN_WARNING "ibmvscsi: Partner adapter not ready\n"); + retrc = 0; } else if (rc != 0) { printk(KERN_WARNING "ibmvscsi: Error %d opening adapter\n", rc); goto reg_crq_failed; diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c index 3fd8a96f2af..bfac4441d89 100644 --- a/drivers/scsi/jazz_esp.c +++ b/drivers/scsi/jazz_esp.c @@ -257,7 +257,7 @@ static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp) static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp) { int sz = sp->use_sg - 1; - struct scatterlist *sg = (struct scatterlist *)sp->buffer; + struct scatterlist *sg = (struct scatterlist *)sp->request_buffer; while(sz >= 0) { vdma_free(sg[sz].dma_address); diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index f81691fcf17..d44f9aac6b8 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -21,10 +21,12 @@ struct lpfc_sli2_slim; -#define LPFC_MAX_TARGET 256 /* max targets supported */ -#define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els req */ -#define LPFC_MAX_NS_RETRY 3 /* max NameServer retries */ +#define LPFC_MAX_TARGET 256 /* max number of targets supported */ +#define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els + requests */ +#define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact + the NameServer before giving up. */ #define LPFC_DFT_HBA_Q_DEPTH 2048 /* max cmds per hba */ #define LPFC_LC_HBA_Q_DEPTH 1024 /* max cmds per low cost hba */ #define LPFC_LP101_HBA_Q_DEPTH 128 /* max cmds per low cost hba */ @@ -41,7 +43,6 @@ struct lpfc_sli2_slim; (( (u64)(high)<<16 ) << 16)|( (u64)(low)))) /* Provide maximum configuration definitions. */ #define LPFC_DRVR_TIMEOUT 16 /* driver iocb timeout value in sec */ -#define MAX_FCP_TARGET 256 /* max num of FCP targets supported */ #define FC_MAX_ADPTMSG 64 #define MAX_HBAEVT 32 diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index b62a72dfab2..5c68cdd8736 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -219,9 +219,19 @@ lpfc_issue_lip(struct Scsi_Host *host) return -ENOMEM; memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); - lpfc_init_link(phba, pmboxq, phba->cfg_topology, phba->cfg_link_speed); + pmboxq->mb.mbxCommand = MBX_DOWN_LINK; + pmboxq->mb.mbxOwner = OWN_HOST; + mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); + if ((mbxstatus == MBX_SUCCESS) && (pmboxq->mb.mbxStatus == 0)) { + memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); + lpfc_init_link(phba, pmboxq, phba->cfg_topology, + phba->cfg_link_speed); + mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, + phba->fc_ratov * 2); + } + if (mbxstatus == MBX_TIMEOUT) pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; else @@ -233,51 +243,53 @@ lpfc_issue_lip(struct Scsi_Host *host) return 0; } -static ssize_t -lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf) +static int +lpfc_selective_reset(struct lpfc_hba *phba) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; - return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt); + struct completion online_compl; + int status = 0; + + init_completion(&online_compl); + lpfc_workq_post_event(phba, &status, &online_compl, + LPFC_EVT_OFFLINE); + wait_for_completion(&online_compl); + + if (status != 0) + return -EIO; + + init_completion(&online_compl); + lpfc_workq_post_event(phba, &status, &online_compl, + LPFC_EVT_ONLINE); + wait_for_completion(&online_compl); + + if (status != 0) + return -EIO; + + return 0; } static ssize_t -lpfc_board_online_show(struct class_device *cdev, char *buf) +lpfc_issue_reset(struct class_device *cdev, const char *buf, size_t count) { struct Scsi_Host *host = class_to_shost(cdev); struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + int status = -EINVAL; - if (phba->fc_flag & FC_OFFLINE_MODE) - return snprintf(buf, PAGE_SIZE, "0\n"); + if (strncmp(buf, "selective", sizeof("selective") - 1) == 0) + status = lpfc_selective_reset(phba); + + if (status == 0) + return strlen(buf); else - return snprintf(buf, PAGE_SIZE, "1\n"); + return status; } static ssize_t -lpfc_board_online_store(struct class_device *cdev, const char *buf, - size_t count) +lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; - struct completion online_compl; - int val=0, status=0; - - if (sscanf(buf, "%d", &val) != 1) - return -EINVAL; - - init_completion(&online_compl); - - if (val) - lpfc_workq_post_event(phba, &status, &online_compl, - LPFC_EVT_ONLINE); - else - lpfc_workq_post_event(phba, &status, &online_compl, - LPFC_EVT_OFFLINE); - wait_for_completion(&online_compl); - if (!status) - return strlen(buf); - else - return -EIO; + return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt); } static ssize_t @@ -532,10 +544,9 @@ static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show, NULL); static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show, NULL); -static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR, - lpfc_board_online_show, lpfc_board_online_store); static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR, lpfc_board_mode_show, lpfc_board_mode_store); +static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset); static int lpfc_poll = 0; module_param(lpfc_poll, int, 0); @@ -695,12 +706,12 @@ LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands " "during discovery"); /* -# lpfc_max_luns: maximum number of LUNs per target driver will support -# Value range is [1,32768]. Default value is 256. -# NOTE: The SCSI layer will scan each target for this many luns +# lpfc_max_luns: maximum allowed LUN. +# Value range is [0,65535]. Default value is 255. +# NOTE: The SCSI layer might probe all allowed LUN on some old targets. */ -LPFC_ATTR_R(max_luns, 256, 1, 32768, - "Maximum number of LUNs per target driver will support"); +LPFC_ATTR_R(max_luns, 255, 0, 65535, + "Maximum allowed LUN"); /* # lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring. @@ -739,8 +750,8 @@ struct class_device_attribute *lpfc_host_attrs[] = { &class_device_attr_lpfc_max_luns, &class_device_attr_nport_evt_cnt, &class_device_attr_management_version, - &class_device_attr_board_online, &class_device_attr_board_mode, + &class_device_attr_issue_reset, &class_device_attr_lpfc_poll, &class_device_attr_lpfc_poll_tmo, NULL, diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index ee22173fce4..517e9e4dd46 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -147,6 +147,7 @@ int lpfc_sli_hba_setup(struct lpfc_hba *); int lpfc_sli_hba_down(struct lpfc_hba *); int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); int lpfc_sli_handle_mb_event(struct lpfc_hba *); +int lpfc_sli_flush_mbox_queue(struct lpfc_hba *); int lpfc_sli_handle_slow_ring_event(struct lpfc_hba *, struct lpfc_sli_ring *, uint32_t); void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 4126fd87956..b89f6cb641e 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -648,33 +648,32 @@ lpfc_more_plogi(struct lpfc_hba * phba) } static struct lpfc_nodelist * -lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, +lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp, struct lpfc_nodelist *ndlp) { struct lpfc_nodelist *new_ndlp; - struct lpfc_dmabuf *pcmd, *prsp; uint32_t *lp; struct serv_parm *sp; uint8_t name[sizeof (struct lpfc_name)]; uint32_t rc; - pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; - prsp = (struct lpfc_dmabuf *) pcmd->list.next; lp = (uint32_t *) prsp->virt; sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); + memset(name, 0, sizeof (struct lpfc_name)); /* Now we to find out if the NPort we are logging into, matches the WWPN * we have for that ndlp. If not, we have some work to do. */ new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName); - memset(name, 0, sizeof (struct lpfc_name)); - rc = memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)); - if (!rc || (new_ndlp == ndlp)) { + if (new_ndlp == ndlp) return ndlp; - } if (!new_ndlp) { + rc = + memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)); + if (!rc) + return ndlp; new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); if (!new_ndlp) return ndlp; @@ -683,17 +682,21 @@ lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, } lpfc_unreg_rpi(phba, new_ndlp); - new_ndlp->nlp_prev_state = ndlp->nlp_state; new_ndlp->nlp_DID = ndlp->nlp_DID; - new_ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; - lpfc_nlp_list(phba, new_ndlp, NLP_PLOGI_LIST); + new_ndlp->nlp_prev_state = ndlp->nlp_prev_state; + new_ndlp->nlp_state = ndlp->nlp_state; + lpfc_nlp_list(phba, new_ndlp, ndlp->nlp_flag & NLP_LIST_MASK); /* Move this back to NPR list */ - lpfc_unreg_rpi(phba, ndlp); - ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ - ndlp->nlp_state = NLP_STE_NPR_NODE; - lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); - + if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) { + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + } + else { + lpfc_unreg_rpi(phba, ndlp); + ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); + } return new_ndlp; } @@ -703,6 +706,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, { IOCB_t *irsp; struct lpfc_nodelist *ndlp; + struct lpfc_dmabuf *prsp; int disc, rc, did, type; @@ -769,7 +773,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, } } else { /* Good status, call state machine */ - ndlp = lpfc_plogi_confirm_nport(phba, cmdiocb, ndlp); + prsp = list_entry(((struct lpfc_dmabuf *) + cmdiocb->context2)->list.next, + struct lpfc_dmabuf, list); + ndlp = lpfc_plogi_confirm_nport(phba, prsp, ndlp); rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_PLOGI); } @@ -3282,10 +3289,9 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) } else lpfc_sli_release_iocbq(phba, piocb); } - if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) { - phba->els_tmofunc.expires = jiffies + HZ * timeout; - add_timer(&phba->els_tmofunc); - } + if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) + mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout); + spin_unlock_irq(phba->host->host_lock); } @@ -3442,6 +3448,8 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) { ndlp->nlp_type |= NLP_FABRIC; } + ndlp->nlp_state = NLP_STE_UNUSED_NODE; + lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); } phba->fc_stat.elsRcvFrame++; @@ -3463,13 +3471,14 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, rjt_err = 1; break; } + ndlp = lpfc_plogi_confirm_nport(phba, mp, ndlp); lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PLOGI); break; case ELS_CMD_FLOGI: phba->fc_stat.elsRcvFLOGI++; lpfc_els_rcv_flogi(phba, elsiocb, ndlp, newnode); if (newnode) { - mempool_free( ndlp, phba->nlp_mem_pool); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); } break; case ELS_CMD_LOGO: @@ -3492,7 +3501,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, phba->fc_stat.elsRcvRSCN++; lpfc_els_rcv_rscn(phba, elsiocb, ndlp, newnode); if (newnode) { - mempool_free( ndlp, phba->nlp_mem_pool); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); } break; case ELS_CMD_ADISC: @@ -3535,28 +3544,28 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, phba->fc_stat.elsRcvLIRR++; lpfc_els_rcv_lirr(phba, elsiocb, ndlp); if (newnode) { - mempool_free( ndlp, phba->nlp_mem_pool); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); } break; case ELS_CMD_RPS: phba->fc_stat.elsRcvRPS++; lpfc_els_rcv_rps(phba, elsiocb, ndlp); if (newnode) { - mempool_free( ndlp, phba->nlp_mem_pool); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); } break; case ELS_CMD_RPL: phba->fc_stat.elsRcvRPL++; lpfc_els_rcv_rpl(phba, elsiocb, ndlp); if (newnode) { - mempool_free( ndlp, phba->nlp_mem_pool); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); } break; case ELS_CMD_RNID: phba->fc_stat.elsRcvRNID++; lpfc_els_rcv_rnid(phba, elsiocb, ndlp); if (newnode) { - mempool_free( ndlp, phba->nlp_mem_pool); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); } break; default: @@ -3568,7 +3577,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, "%d:0115 Unknown ELS command x%x received from " "NPORT x%x\n", phba->brd_no, cmd, did); if (newnode) { - mempool_free( ndlp, phba->nlp_mem_pool); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); } break; } diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index adb086009ae..4d6cf990c4f 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1084,7 +1084,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba, fc_remote_port_rolechg(rport, rport_ids.roles); if ((rport->scsi_target_id != -1) && - (rport->scsi_target_id < MAX_FCP_TARGET)) { + (rport->scsi_target_id < LPFC_MAX_TARGET)) { ndlp->nlp_sid = rport->scsi_target_id; } @@ -1313,7 +1313,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) if ((rport_add == mapped) && ((!nlp->rport) || (nlp->rport->scsi_target_id == -1) || - (nlp->rport->scsi_target_id >= MAX_FCP_TARGET))) { + (nlp->rport->scsi_target_id >= LPFC_MAX_TARGET))) { nlp->nlp_state = NLP_STE_UNMAPPED_NODE; spin_lock_irq(phba->host->host_lock); nlp->nlp_flag |= NLP_TGT_NO_SCSIID; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 81755a3f7c6..ef47b824cbe 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -71,6 +71,7 @@ lpfc_config_port_prep(struct lpfc_hba * phba) uint16_t offset = 0; static char licensed[56] = "key unlock for use with gnu public licensed code only\0"; + static int init_key = 1; pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!pmb) { @@ -82,10 +83,13 @@ lpfc_config_port_prep(struct lpfc_hba * phba) phba->hba_state = LPFC_INIT_MBX_CMDS; if (lpfc_is_LC_HBA(phba->pcidev->device)) { - uint32_t *ptext = (uint32_t *) licensed; + if (init_key) { + uint32_t *ptext = (uint32_t *) licensed; - for (i = 0; i < 56; i += sizeof (uint32_t), ptext++) - *ptext = cpu_to_be32(*ptext); + for (i = 0; i < 56; i += sizeof (uint32_t), ptext++) + *ptext = cpu_to_be32(*ptext); + init_key = 0; + } lpfc_read_nv(phba, pmb); memset((char*)mb->un.varRDnvp.rsvd3, 0, @@ -405,19 +409,26 @@ lpfc_config_port_post(struct lpfc_hba * phba) } /* MBOX buffer will be freed in mbox compl */ - i = 0; + return (0); +} + +static int +lpfc_discovery_wait(struct lpfc_hba *phba) +{ + int i = 0; + while ((phba->hba_state != LPFC_HBA_READY) || (phba->num_disc_nodes) || (phba->fc_prli_sent) || ((phba->fc_map_cnt == 0) && (i<2)) || - (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE)) { + (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE)) { /* Check every second for 30 retries. */ i++; if (i > 30) { - break; + return -ETIMEDOUT; } if ((i >= 15) && (phba->hba_state <= LPFC_LINK_DOWN)) { /* The link is down. Set linkdown timeout */ - break; + return -ETIMEDOUT; } /* Delay for 1 second to give discovery time to complete. */ @@ -425,12 +436,7 @@ lpfc_config_port_post(struct lpfc_hba * phba) } - /* Since num_disc_nodes keys off of PLOGI, delay a bit to let - * any potential PRLIs to flush thru the SLI sub-system. - */ - msleep(50); - - return (0); + return 0; } /************************************************************************/ @@ -1339,7 +1345,8 @@ lpfc_offline(struct lpfc_hba * phba) struct lpfc_sli_ring *pring; struct lpfc_sli *psli; unsigned long iflag; - int i = 0; + int i; + int cnt = 0; if (!phba) return 0; @@ -1348,17 +1355,27 @@ lpfc_offline(struct lpfc_hba * phba) return 0; psli = &phba->sli; - pring = &psli->ring[psli->fcp_ring]; lpfc_linkdown(phba); + lpfc_sli_flush_mbox_queue(phba); - /* The linkdown event takes 30 seconds to timeout. */ - while (pring->txcmplq_cnt) { - mdelay(10); - if (i++ > 3000) - break; + for (i = 0; i < psli->num_rings; i++) { + pring = &psli->ring[i]; + /* The linkdown event takes 30 seconds to timeout. */ + while (pring->txcmplq_cnt) { + mdelay(10); + if (cnt++ > 3000) { + lpfc_printf_log(phba, + KERN_WARNING, LOG_INIT, + "%d:0466 Outstanding IO when " + "bringing Adapter offline\n", + phba->brd_no); + break; + } + } } + /* stop all timers associated with this hba */ lpfc_stop_timer(phba); phba->work_hba_events = 0; @@ -1639,6 +1656,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) goto out_free_irq; } + lpfc_discovery_wait(phba); + if (phba->cfg_poll & DISABLE_FCP_RING_INT) { spin_lock_irq(phba->host->host_lock); lpfc_poll_start_timer(phba); diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 07017658ac5..066292d3995 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c @@ -133,6 +133,11 @@ lpfc_mem_free(struct lpfc_hba * phba) pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool); pci_pool_destroy(phba->lpfc_mbuf_pool); + + /* Free the iocb lookup array */ + kfree(psli->iocbq_lookup); + psli->iocbq_lookup = NULL; + } void * diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 27d60ad897c..bd0b0e293d6 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -1110,6 +1110,17 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, phba->brd_no, did, mb->mbxStatus, phba->hba_state); + /* + * If RegLogin failed due to lack of HBA resources do not + * retry discovery. + */ + if (mb->mbxStatus == MBXERR_RPI_FULL) { + ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; + ndlp->nlp_state = NLP_STE_UNUSED_NODE; + lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); + return ndlp->nlp_state; + } + /* Put ndlp in npr list set plogi timer for 1 sec */ mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); spin_lock_irq(phba->host->host_lock); diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index aea1ee472f3..a760a44173d 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -153,22 +153,6 @@ static void lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb) { unsigned long iflag = 0; - /* - * There are only two special cases to consider. (1) the scsi command - * requested scatter-gather usage or (2) the scsi command allocated - * a request buffer, but did not request use_sg. There is a third - * case, but it does not require resource deallocation. - */ - if ((psb->seg_cnt > 0) && (psb->pCmd->use_sg)) { - dma_unmap_sg(&phba->pcidev->dev, psb->pCmd->request_buffer, - psb->seg_cnt, psb->pCmd->sc_data_direction); - } else { - if ((psb->nonsg_phys) && (psb->pCmd->request_bufflen)) { - dma_unmap_single(&phba->pcidev->dev, psb->nonsg_phys, - psb->pCmd->request_bufflen, - psb->pCmd->sc_data_direction); - } - } spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); psb->pCmd = NULL; @@ -282,6 +266,27 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd) } static void +lpfc_scsi_unprep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb) +{ + /* + * There are only two special cases to consider. (1) the scsi command + * requested scatter-gather usage or (2) the scsi command allocated + * a request buffer, but did not request use_sg. There is a third + * case, but it does not require resource deallocation. + */ + if ((psb->seg_cnt > 0) && (psb->pCmd->use_sg)) { + dma_unmap_sg(&phba->pcidev->dev, psb->pCmd->request_buffer, + psb->seg_cnt, psb->pCmd->sc_data_direction); + } else { + if ((psb->nonsg_phys) && (psb->pCmd->request_bufflen)) { + dma_unmap_single(&phba->pcidev->dev, psb->nonsg_phys, + psb->pCmd->request_bufflen, + psb->pCmd->sc_data_direction); + } + } +} + +static void lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd) { struct scsi_cmnd *cmnd = lpfc_cmd->pCmd; @@ -454,6 +459,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, cmd->scsi_done(cmd); if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { + lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); lpfc_release_scsi_buf(phba, lpfc_cmd); return; } @@ -511,6 +517,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, } } + lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); lpfc_release_scsi_buf(phba, lpfc_cmd); } @@ -609,6 +616,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd, static int lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd, + unsigned int lun, uint8_t task_mgmt_cmd) { struct lpfc_sli *psli; @@ -627,8 +635,7 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, piocb = &piocbq->iocb; fcp_cmnd = lpfc_cmd->fcp_cmnd; - int_to_scsilun(lpfc_cmd->pCmd->device->lun, - &lpfc_cmd->fcp_cmnd->fcp_lun); + int_to_scsilun(lun, &lpfc_cmd->fcp_cmnd->fcp_lun); fcp_cmnd->fcpCntl2 = task_mgmt_cmd; piocb->ulpCommand = CMD_FCP_ICMND64_CR; @@ -655,14 +662,16 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, static int lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, - unsigned tgt_id, struct lpfc_rport_data *rdata) + unsigned tgt_id, unsigned int lun, + struct lpfc_rport_data *rdata) { struct lpfc_iocbq *iocbq; struct lpfc_iocbq *iocbqrsp; int ret; lpfc_cmd->rdata = rdata; - ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_TARGET_RESET); + ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, lun, + FCP_TARGET_RESET); if (!ret) return FAILED; @@ -822,6 +831,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) return 0; out_host_busy_free_buf: + lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); lpfc_release_scsi_buf(phba, lpfc_cmd); out_host_busy: return SCSI_MLQUEUE_HOST_BUSY; @@ -969,12 +979,12 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) if (lpfc_cmd == NULL) goto out; - lpfc_cmd->pCmd = cmnd; lpfc_cmd->timeout = 60; lpfc_cmd->scsi_hba = phba; lpfc_cmd->rdata = rdata; - ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_LUN_RESET); + ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, cmnd->device->lun, + FCP_LUN_RESET); if (!ret) goto out_free_scsi_buf; @@ -1001,7 +1011,6 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) cmd_status = iocbqrsp->iocb.ulpStatus; lpfc_sli_release_iocbq(phba, iocbqrsp); - lpfc_release_scsi_buf(phba, lpfc_cmd); /* * All outstanding txcmplq I/Os should have been aborted by the device. @@ -1040,6 +1049,8 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) } out_free_scsi_buf: + lpfc_release_scsi_buf(phba, lpfc_cmd); + lpfc_printf_log(phba, KERN_ERR, LOG_FCP, "%d:0713 SCSI layer issued LUN reset (%d, %d) " "Data: x%x x%x x%x\n", @@ -1070,7 +1081,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) /* The lpfc_cmd storage is reused. Set all loop invariants. */ lpfc_cmd->timeout = 60; - lpfc_cmd->pCmd = cmnd; lpfc_cmd->scsi_hba = phba; /* @@ -1078,7 +1088,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) * targets known to the driver. Should any target reset * fail, this routine returns failure to the midlayer. */ - for (i = 0; i < MAX_FCP_TARGET; i++) { + for (i = 0; i < LPFC_MAX_TARGET; i++) { /* Search the mapped list for this target ID */ match = 0; list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { @@ -1090,8 +1100,8 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) if (!match) continue; - ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, - i, ndlp->rport->dd_data); + ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, i, cmnd->device->lun, + ndlp->rport->dd_data); if (ret != SUCCESS) { lpfc_printf_log(phba, KERN_ERR, LOG_FCP, "%d:0713 Bus Reset on target %d failed\n", diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index bb69a7a1ec5..350a625fa22 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -191,35 +191,12 @@ static int lpfc_sli_ringtxcmpl_put(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, struct lpfc_iocbq * piocb) { - uint16_t iotag; - list_add_tail(&piocb->list, &pring->txcmplq); pring->txcmplq_cnt++; if (unlikely(pring->ringno == LPFC_ELS_RING)) mod_timer(&phba->els_tmofunc, jiffies + HZ * (phba->fc_ratov << 1)); - if (pring->fast_lookup) { - /* Setup fast lookup based on iotag for completion */ - iotag = piocb->iocb.ulpIoTag; - if (iotag && (iotag < pring->fast_iotag)) - *(pring->fast_lookup + iotag) = piocb; - else { - - /* Cmd ring <ringno> put: iotag <iotag> greater then - configured max <fast_iotag> wd0 <icmd> */ - lpfc_printf_log(phba, - KERN_ERR, - LOG_SLI, - "%d:0316 Cmd ring %d put: iotag x%x " - "greater then configured max x%x " - "wd0 x%x\n", - phba->brd_no, - pring->ringno, iotag, - pring->fast_iotag, - *(((uint32_t *)(&piocb->iocb)) + 7)); - } - } return (0); } @@ -601,7 +578,7 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba) /* Stray Mailbox Interrupt, mbxCommand <cmd> mbxStatus <status> */ lpfc_printf_log(phba, - KERN_ERR, + KERN_WARNING, LOG_MBOX | LOG_SLI, "%d:0304 Stray Mailbox Interrupt " "mbxCommand x%x mbxStatus x%x\n", @@ -1570,8 +1547,8 @@ lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask) void lpfc_reset_barrier(struct lpfc_hba * phba) { - uint32_t * resp_buf; - uint32_t * mbox_buf; + uint32_t __iomem *resp_buf; + uint32_t __iomem *mbox_buf; volatile uint32_t mbox; uint32_t hc_copy; int i; @@ -1587,7 +1564,7 @@ void lpfc_reset_barrier(struct lpfc_hba * phba) * Tell the other part of the chip to suspend temporarily all * its DMA activity. */ - resp_buf = (uint32_t *)phba->MBslimaddr; + resp_buf = phba->MBslimaddr; /* Disable the error attention */ hc_copy = readl(phba->HCregaddr); @@ -1605,7 +1582,7 @@ void lpfc_reset_barrier(struct lpfc_hba * phba) ((MAILBOX_t *)&mbox)->mbxOwner = OWN_CHIP; writel(BARRIER_TEST_PATTERN, (resp_buf + 1)); - mbox_buf = (uint32_t *)phba->MBslimaddr; + mbox_buf = phba->MBslimaddr; writel(mbox, mbox_buf); for (i = 0; @@ -1805,7 +1782,7 @@ lpfc_sli_brdrestart(struct lpfc_hba * phba) skip_post = 0; word0 = 0; /* This is really setting up word1 */ } - to_slim = (uint8_t *) phba->MBslimaddr + sizeof (uint32_t); + to_slim = phba->MBslimaddr + sizeof (uint32_t); writel(*(uint32_t *) mb, to_slim); readl(to_slim); /* flush */ @@ -2659,8 +2636,6 @@ lpfc_sli_hba_down(struct lpfc_hba * phba) INIT_LIST_HEAD(&(pring->txq)); - kfree(pring->fast_lookup); - pring->fast_lookup = NULL; } spin_unlock_irqrestore(phba->host->host_lock, flags); @@ -3110,6 +3085,24 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, return retval; } +int +lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba) +{ + int i = 0; + + while (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE && !phba->stopped) { + if (i++ > LPFC_MBOX_TMO * 1000) + return 1; + + if (lpfc_sli_handle_mb_event(phba) == 0) + i = 0; + + msleep(1); + } + + return (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) ? 1 : 0; +} + irqreturn_t lpfc_intr_handler(int irq, void *dev_id, struct pt_regs * regs) { diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index a52d6c6cf08..d8ef0d2894d 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h @@ -135,8 +135,6 @@ struct lpfc_sli_ring { uint32_t fast_iotag; /* max fastlookup based iotag */ uint32_t iotag_ctr; /* keeps track of the next iotag to use */ uint32_t iotag_max; /* max iotag value to use */ - struct lpfc_iocbq ** fast_lookup; /* array of IOCB ptrs indexed by - iotag */ struct list_head txq; uint16_t txq_cnt; /* current length of queue */ uint16_t txq_max; /* max length */ diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 6b737568b83..10e89c6ae82 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.1.6" +#define LPFC_DRIVER_VERSION "8.1.7" #define LPFC_DRIVER_NAME "lpfc" diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index 93edaa8696c..89ef34df5a1 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c @@ -378,7 +378,7 @@ static void set_dma_cmds(struct fsc_state *state, struct scsi_cmnd *cmd) int nseg; total = 0; - scl = (struct scatterlist *) cmd->buffer; + scl = (struct scatterlist *) cmd->request_buffer; nseg = pci_map_sg(state->pdev, scl, cmd->use_sg, cmd->sc_data_direction); for (i = 0; i < nseg; ++i) { diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c index c88717727be..5572981a9f9 100644 --- a/drivers/scsi/mesh.c +++ b/drivers/scsi/mesh.c @@ -1268,7 +1268,7 @@ static void set_dma_cmds(struct mesh_state *ms, struct scsi_cmnd *cmd) if (cmd->use_sg > 0) { int nseg; total = 0; - scl = (struct scatterlist *) cmd->buffer; + scl = (struct scatterlist *) cmd->request_buffer; off = ms->data_ptr; nseg = pci_map_sg(ms->pdev, scl, cmd->use_sg, cmd->sc_data_direction); diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c index 7abf64d1bfc..0bd9c60e645 100644 --- a/drivers/scsi/pluto.c +++ b/drivers/scsi/pluto.c @@ -169,8 +169,6 @@ int __init pluto_detect(struct scsi_host_template *tpnt) SCpnt->request->rq_status = RQ_SCSI_BUSY; SCpnt->done = pluto_detect_done; - SCpnt->bufflen = 256; - SCpnt->buffer = fcs[i].inquiry; SCpnt->request_bufflen = 256; SCpnt->request_buffer = fcs[i].inquiry; PLD(("set up %d %08lx\n", i, (long)SCpnt)) diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 69e0551a81d..5b2f0741a55 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -874,7 +874,7 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd, if (Cmnd->use_sg) { int sg_count; - sg = (struct scatterlist *) Cmnd->buffer; + sg = (struct scatterlist *) Cmnd->request_buffer; sg_count = sbus_map_sg(qpti->sdev, sg, Cmnd->use_sg, Cmnd->sc_data_direction); ds = cmd->dataseg; @@ -1278,7 +1278,7 @@ static struct scsi_cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti) if (Cmnd->use_sg) { sbus_unmap_sg(qpti->sdev, - (struct scatterlist *)Cmnd->buffer, + (struct scatterlist *)Cmnd->request_buffer, Cmnd->use_sg, Cmnd->sc_data_direction); } else { diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 2ab7df0dcfe..b332caddd5b 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -346,7 +346,7 @@ void scsi_log_send(struct scsi_cmnd *cmd) if (level > 3) { printk(KERN_INFO "buffer = 0x%p, bufflen = %d," " done = 0x%p, queuecommand 0x%p\n", - cmd->buffer, cmd->bufflen, + cmd->request_buffer, cmd->request_bufflen, cmd->done, sdev->host->hostt->queuecommand); @@ -661,11 +661,6 @@ void __scsi_done(struct scsi_cmnd *cmd) */ int scsi_retry_command(struct scsi_cmnd *cmd) { - /* - * Restore the SCSI command state. - */ - scsi_setup_cmd_retry(cmd); - /* * Zero the sense information from the last time we tried * this command. @@ -711,10 +706,6 @@ void scsi_finish_command(struct scsi_cmnd *cmd) "Notifying upper driver of completion " "(result %x)\n", cmd->result)); - /* - * We can get here with use_sg=0, causing a panic in the upper level - */ - cmd->use_sg = cmd->old_use_sg; cmd->done(cmd); } EXPORT_SYMBOL(scsi_finish_command); diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 9c63b00773c..a80303c6b3f 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -286,7 +286,7 @@ static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, int dev_id_num, const char * dev_id_str, int dev_id_str_len); static int inquiry_evpd_88(unsigned char * arr, int target_dev_id); -static void do_create_driverfs_files(void); +static int do_create_driverfs_files(void); static void do_remove_driverfs_files(void); static int sdebug_add_adapter(void); @@ -2487,19 +2487,22 @@ static ssize_t sdebug_add_host_store(struct device_driver * ddp, DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show, sdebug_add_host_store); -static void do_create_driverfs_files(void) +static int do_create_driverfs_files(void) { - driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host); - driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay); - driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb); - driver_create_file(&sdebug_driverfs_driver, &driver_attr_dsense); - driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth); - driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns); - driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts); - driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts); - driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype); - driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts); - driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level); + int ret; + + ret = driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host); + ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay); + ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb); + ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dsense); + ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth); + ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns); + ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts); + ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts); + ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype); + ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts); + ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level); + return ret; } static void do_remove_driverfs_files(void) @@ -2522,6 +2525,7 @@ static int __init scsi_debug_init(void) unsigned int sz; int host_to_add; int k; + int ret; if (scsi_debug_dev_size_mb < 1) scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ @@ -2560,12 +2564,32 @@ static int __init scsi_debug_init(void) if (scsi_debug_num_parts > 0) sdebug_build_parts(fake_storep); - init_all_queued(); + ret = device_register(&pseudo_primary); + if (ret < 0) { + printk(KERN_WARNING "scsi_debug: device_register error: %d\n", + ret); + goto free_vm; + } + ret = bus_register(&pseudo_lld_bus); + if (ret < 0) { + printk(KERN_WARNING "scsi_debug: bus_register error: %d\n", + ret); + goto dev_unreg; + } + ret = driver_register(&sdebug_driverfs_driver); + if (ret < 0) { + printk(KERN_WARNING "scsi_debug: driver_register error: %d\n", + ret); + goto bus_unreg; + } + ret = do_create_driverfs_files(); + if (ret < 0) { + printk(KERN_WARNING "scsi_debug: driver_create_file error: %d\n", + ret); + goto del_files; + } - device_register(&pseudo_primary); - bus_register(&pseudo_lld_bus); - driver_register(&sdebug_driverfs_driver); - do_create_driverfs_files(); + init_all_queued(); sdebug_driver_template.proc_name = (char *)sdebug_proc_name; @@ -2585,6 +2609,18 @@ static int __init scsi_debug_init(void) scsi_debug_add_host); } return 0; + +del_files: + do_remove_driverfs_files(); + driver_unregister(&sdebug_driverfs_driver); +bus_unreg: + bus_unregister(&pseudo_lld_bus); +dev_unreg: + device_unregister(&pseudo_primary); +free_vm: + vfree(fake_storep); + + return ret; } static void __exit scsi_debug_exit(void) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 6683d596234..6a5b731bd5b 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -460,19 +460,67 @@ static void scsi_eh_done(struct scsi_cmnd *scmd) * Return value: * SUCCESS or FAILED or NEEDS_RETRY **/ -static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout) +static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout, int copy_sense) { struct scsi_device *sdev = scmd->device; struct Scsi_Host *shost = sdev->host; + int old_result = scmd->result; DECLARE_COMPLETION(done); unsigned long timeleft; unsigned long flags; + unsigned char old_cmnd[MAX_COMMAND_SIZE]; + enum dma_data_direction old_data_direction; + unsigned short old_use_sg; + unsigned char old_cmd_len; + unsigned old_bufflen; + void *old_buffer; int rtn; + /* + * We need saved copies of a number of fields - this is because + * error handling may need to overwrite these with different values + * to run different commands, and once error handling is complete, + * we will need to restore these values prior to running the actual + * command. + */ + old_buffer = scmd->request_buffer; + old_bufflen = scmd->request_bufflen; + memcpy(old_cmnd, scmd->cmnd, sizeof(scmd->cmnd)); + old_data_direction = scmd->sc_data_direction; + old_cmd_len = scmd->cmd_len; + old_use_sg = scmd->use_sg; + + if (copy_sense) { + int gfp_mask = GFP_ATOMIC; + + if (shost->hostt->unchecked_isa_dma) + gfp_mask |= __GFP_DMA; + + scmd->sc_data_direction = DMA_FROM_DEVICE; + scmd->request_bufflen = 252; + scmd->request_buffer = kzalloc(scmd->request_bufflen, gfp_mask); + if (!scmd->request_buffer) + return FAILED; + } else { + scmd->request_buffer = NULL; + scmd->request_bufflen = 0; + scmd->sc_data_direction = DMA_NONE; + } + + scmd->underflow = 0; + scmd->use_sg = 0; + scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); + if (sdev->scsi_level <= SCSI_2) scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) | (sdev->lun << 5 & 0xe0); + /* + * Zero the sense buffer. The scsi spec mandates that any + * untransferred sense data should be interpreted as being zero. + */ + memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); + shost->eh_action = &done; spin_lock_irqsave(shost->host_lock, flags); @@ -522,6 +570,29 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout) rtn = FAILED; } + + /* + * Last chance to have valid sense data. + */ + if (copy_sense) { + if (!SCSI_SENSE_VALID(scmd)) { + memcpy(scmd->sense_buffer, scmd->request_buffer, + sizeof(scmd->sense_buffer)); + } + kfree(scmd->request_buffer); + } + + + /* + * Restore original data + */ + scmd->request_buffer = old_buffer; + scmd->request_bufflen = old_bufflen; + memcpy(scmd->cmnd, old_cmnd, sizeof(scmd->cmnd)); + scmd->sc_data_direction = old_data_direction; + scmd->cmd_len = old_cmd_len; + scmd->use_sg = old_use_sg; + scmd->result = old_result; return rtn; } @@ -537,56 +608,10 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout) static int scsi_request_sense(struct scsi_cmnd *scmd) { static unsigned char generic_sense[6] = - {REQUEST_SENSE, 0, 0, 0, 252, 0}; - unsigned char *scsi_result; - int saved_result; - int rtn; + {REQUEST_SENSE, 0, 0, 0, 252, 0}; memcpy(scmd->cmnd, generic_sense, sizeof(generic_sense)); - - scsi_result = kmalloc(252, GFP_ATOMIC | ((scmd->device->host->hostt->unchecked_isa_dma) ? __GFP_DMA : 0)); - - - if (unlikely(!scsi_result)) { - printk(KERN_ERR "%s: cannot allocate scsi_result.\n", - __FUNCTION__); - return FAILED; - } - - /* - * zero the sense buffer. some host adapters automatically always - * request sense, so it is not a good idea that - * scmd->request_buffer and scmd->sense_buffer point to the same - * address (db). 0 is not a valid sense code. - */ - memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); - memset(scsi_result, 0, 252); - - saved_result = scmd->result; - scmd->request_buffer = scsi_result; - scmd->request_bufflen = 252; - scmd->use_sg = 0; - scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); - scmd->sc_data_direction = DMA_FROM_DEVICE; - scmd->underflow = 0; - - rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT); - - /* last chance to have valid sense data */ - if(!SCSI_SENSE_VALID(scmd)) { - memcpy(scmd->sense_buffer, scmd->request_buffer, - sizeof(scmd->sense_buffer)); - } - - kfree(scsi_result); - - /* - * when we eventually call scsi_finish, we really wish to complete - * the original request, so let's restore the original data. (db) - */ - scsi_setup_cmd_retry(scmd); - scmd->result = saved_result; - return rtn; + return scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 1); } /** @@ -605,12 +630,6 @@ void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q) { scmd->device->host->host_failed--; scmd->eh_eflags = 0; - - /* - * set this back so that the upper level can correctly free up - * things. - */ - scsi_setup_cmd_retry(scmd); list_move_tail(&scmd->eh_entry, done_q); } EXPORT_SYMBOL(scsi_eh_finish_cmd); @@ -715,47 +734,26 @@ static int scsi_eh_tur(struct scsi_cmnd *scmd) { static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0}; int retry_cnt = 1, rtn; - int saved_result; retry_tur: memcpy(scmd->cmnd, tur_command, sizeof(tur_command)); - /* - * zero the sense buffer. the scsi spec mandates that any - * untransferred sense data should be interpreted as being zero. - */ - memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); - - saved_result = scmd->result; - scmd->request_buffer = NULL; - scmd->request_bufflen = 0; - scmd->use_sg = 0; - scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); - scmd->underflow = 0; - scmd->sc_data_direction = DMA_NONE; - rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT); + rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 0); - /* - * when we eventually call scsi_finish, we really wish to complete - * the original request, so let's restore the original data. (db) - */ - scsi_setup_cmd_retry(scmd); - scmd->result = saved_result; - - /* - * hey, we are done. let's look to see what happened. - */ SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n", __FUNCTION__, scmd, rtn)); - if (rtn == SUCCESS) - return 0; - else if (rtn == NEEDS_RETRY) { + + switch (rtn) { + case NEEDS_RETRY: if (retry_cnt--) goto retry_tur; + /*FALLTHRU*/ + case SUCCESS: return 0; + default: + return 1; } - return 1; } /** @@ -837,44 +835,16 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd) static int scsi_eh_try_stu(struct scsi_cmnd *scmd) { static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0}; - int rtn; - int saved_result; - if (!scmd->device->allow_restart) - return 1; - - memcpy(scmd->cmnd, stu_command, sizeof(stu_command)); - - /* - * zero the sense buffer. the scsi spec mandates that any - * untransferred sense data should be interpreted as being zero. - */ - memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); - - saved_result = scmd->result; - scmd->request_buffer = NULL; - scmd->request_bufflen = 0; - scmd->use_sg = 0; - scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); - scmd->underflow = 0; - scmd->sc_data_direction = DMA_NONE; + if (scmd->device->allow_restart) { + int rtn; - rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT); - - /* - * when we eventually call scsi_finish, we really wish to complete - * the original request, so let's restore the original data. (db) - */ - scsi_setup_cmd_retry(scmd); - scmd->result = saved_result; + memcpy(scmd->cmnd, stu_command, sizeof(stu_command)); + rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT, 0); + if (rtn == SUCCESS) + return 0; + } - /* - * hey, we are done. let's look to see what happened. - */ - SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n", - __FUNCTION__, scmd, rtn)); - if (rtn == SUCCESS) - return 0; return 1; } @@ -1684,8 +1654,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag) scmd->scsi_done = scsi_reset_provider_done_command; scmd->done = NULL; - scmd->buffer = NULL; - scmd->bufflen = 0; scmd->request_buffer = NULL; scmd->request_bufflen = 0; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 08af9aae7df..077c1c69121 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -436,60 +436,16 @@ EXPORT_SYMBOL_GPL(scsi_execute_async); * * Arguments: cmd - command that is ready to be queued. * - * Returns: Nothing - * * Notes: This function has the job of initializing a number of * fields related to error handling. Typically this will * be called once for each command, as required. */ -static int scsi_init_cmd_errh(struct scsi_cmnd *cmd) +static void scsi_init_cmd_errh(struct scsi_cmnd *cmd) { cmd->serial_number = 0; - memset(cmd->sense_buffer, 0, sizeof cmd->sense_buffer); - if (cmd->cmd_len == 0) cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); - - /* - * We need saved copies of a number of fields - this is because - * error handling may need to overwrite these with different values - * to run different commands, and once error handling is complete, - * we will need to restore these values prior to running the actual - * command. - */ - cmd->old_use_sg = cmd->use_sg; - cmd->old_cmd_len = cmd->cmd_len; - cmd->sc_old_data_direction = cmd->sc_data_direction; - cmd->old_underflow = cmd->underflow; - memcpy(cmd->data_cmnd, cmd->cmnd, sizeof(cmd->cmnd)); - cmd->buffer = cmd->request_buffer; - cmd->bufflen = cmd->request_bufflen; - - return 1; -} - -/* - * Function: scsi_setup_cmd_retry() - * - * Purpose: Restore the command state for a retry - * - * Arguments: cmd - command to be restored - * - * Returns: Nothing - * - * Notes: Immediately prior to retrying a command, we need - * to restore certain fields that we saved above. - */ -void scsi_setup_cmd_retry(struct scsi_cmnd *cmd) -{ - memcpy(cmd->cmnd, cmd->data_cmnd, sizeof(cmd->data_cmnd)); - cmd->request_buffer = cmd->buffer; - cmd->request_bufflen = cmd->bufflen; - cmd->use_sg = cmd->old_use_sg; - cmd->cmd_len = cmd->old_cmd_len; - cmd->sc_data_direction = cmd->sc_old_data_direction; - cmd->underflow = cmd->old_underflow; } void scsi_device_unbusy(struct scsi_device *sdev) @@ -807,22 +763,13 @@ static void scsi_free_sgtable(struct scatterlist *sgl, int index) */ static void scsi_release_buffers(struct scsi_cmnd *cmd) { - struct request *req = cmd->request; - - /* - * Free up any indirection buffers we allocated for DMA purposes. - */ if (cmd->use_sg) scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); - else if (cmd->request_buffer != req->buffer) - kfree(cmd->request_buffer); /* * Zero these out. They now point to freed memory, and it is * dangerous to hang onto the pointers. */ - cmd->buffer = NULL; - cmd->bufflen = 0; cmd->request_buffer = NULL; cmd->request_bufflen = 0; } @@ -858,7 +805,7 @@ static void scsi_release_buffers(struct scsi_cmnd *cmd) void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) { int result = cmd->result; - int this_count = cmd->bufflen; + int this_count = cmd->request_bufflen; request_queue_t *q = cmd->device->request_queue; struct request *req = cmd->request; int clear_errors = 1; @@ -866,28 +813,14 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) int sense_valid = 0; int sense_deferred = 0; - /* - * Free up any indirection buffers we allocated for DMA purposes. - * For the case of a READ, we need to copy the data out of the - * bounce buffer and into the real buffer. - */ - if (cmd->use_sg) - scsi_free_sgtable(cmd->buffer, cmd->sglist_len); - else if (cmd->buffer != req->buffer) { - if (rq_data_dir(req) == READ) { - unsigned long flags; - char *to = bio_kmap_irq(req->bio, &flags); - memcpy(to, cmd->buffer, cmd->bufflen); - bio_kunmap_irq(to, &flags); - } - kfree(cmd->buffer); - } + scsi_release_buffers(cmd); if (result) { sense_valid = scsi_command_normalize_sense(cmd, &sshdr); if (sense_valid) sense_deferred = scsi_sense_is_deferred(&sshdr); } + if (blk_pc_request(req)) { /* SG_IO ioctl from block level */ req->errors = result; if (result) { @@ -908,15 +841,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) } /* - * Zero these out. They now point to freed memory, and it is - * dangerous to hang onto the pointers. - */ - cmd->buffer = NULL; - cmd->bufflen = 0; - cmd->request_buffer = NULL; - cmd->request_bufflen = 0; - - /* * Next deal with any sectors which we were able to correctly * handle. */ @@ -1012,7 +936,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) if (!(req->flags & REQ_QUIET)) { scmd_printk(KERN_INFO, cmd, "Volume overflow, CDB: "); - __scsi_print_command(cmd->data_cmnd); + __scsi_print_command(cmd->cmnd); scsi_print_sense("", cmd); } /* See SSC3rXX or current. */ @@ -1143,7 +1067,7 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd) * successfully. Since this is a REQ_BLOCK_PC command the * caller should check the request's errors value */ - scsi_io_completion(cmd, cmd->bufflen); + scsi_io_completion(cmd, cmd->request_bufflen); } static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index e2fbe9a9d5a..ae24c85aaee 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -57,7 +57,6 @@ extern int scsi_eh_scmd_add(struct scsi_cmnd *, int); /* scsi_lib.c */ extern int scsi_maybe_unblock_host(struct scsi_device *sdev); -extern void scsi_setup_cmd_retry(struct scsi_cmnd *cmd); extern void scsi_device_unbusy(struct scsi_device *sdev); extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason); extern void scsi_next_command(struct scsi_cmnd *cmd); diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index dd075627e60..5a625c3fdda 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -41,6 +41,7 @@ struct sas_host_attrs { struct mutex lock; u32 next_target_id; u32 next_expander_id; + int next_port_id; }; #define to_sas_host_attrs(host) ((struct sas_host_attrs *)(host)->shost_data) @@ -146,6 +147,7 @@ static int sas_host_setup(struct transport_container *tc, struct device *dev, mutex_init(&sas_host->lock); sas_host->next_target_id = 0; sas_host->next_expander_id = 0; + sas_host->next_port_id = 0; return 0; } @@ -327,7 +329,7 @@ sas_phy_protocol_attr(identify.target_port_protocols, sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n", unsigned long long); sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8); -//sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", u8); +//sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", int); sas_phy_linkspeed_attr(negotiated_linkrate); sas_phy_linkspeed_attr(minimum_linkrate_hw); sas_phy_linkspeed_attr(minimum_linkrate); @@ -590,6 +592,38 @@ struct sas_port *sas_port_alloc(struct device *parent, int port_id) } EXPORT_SYMBOL(sas_port_alloc); +/** sas_port_alloc_num - allocate and initialize a SAS port structure + * + * @parent: parent device + * + * Allocates a SAS port structure and a number to go with it. This + * interface is really for adapters where the port number has no + * meansing, so the sas class should manage them. It will be added to + * the device tree below the device specified by @parent which must be + * either a Scsi_Host or a sas_expander_device. + * + * Returns %NULL on error + */ +struct sas_port *sas_port_alloc_num(struct device *parent) +{ + int index; + struct Scsi_Host *shost = dev_to_shost(parent); + struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); + + /* FIXME: use idr for this eventually */ + mutex_lock(&sas_host->lock); + if (scsi_is_sas_expander_device(parent)) { + struct sas_rphy *rphy = dev_to_rphy(parent); + struct sas_expander_device *exp = rphy_to_expander_device(rphy); + + index = exp->next_port_id++; + } else + index = sas_host->next_port_id++; + mutex_unlock(&sas_host->lock); + return sas_port_alloc(parent, index); +} +EXPORT_SYMBOL(sas_port_alloc_num); + /** * sas_port_add - add a SAS port to the device hierarchy * @@ -658,6 +692,13 @@ void sas_port_delete(struct sas_port *port) } mutex_unlock(&port->phy_list_mutex); + if (port->is_backlink) { + struct device *parent = port->dev.parent; + + sysfs_remove_link(&port->dev.kobj, parent->bus_id); + port->is_backlink = 0; + } + transport_remove_device(dev); device_del(dev); transport_destroy_device(dev); @@ -733,6 +774,19 @@ void sas_port_delete_phy(struct sas_port *port, struct sas_phy *phy) } EXPORT_SYMBOL(sas_port_delete_phy); +void sas_port_mark_backlink(struct sas_port *port) +{ + struct device *parent = port->dev.parent->parent->parent; + + if (port->is_backlink) + return; + port->is_backlink = 1; + sysfs_create_link(&port->dev.kobj, &parent->kobj, + parent->bus_id); + +} +EXPORT_SYMBOL(sas_port_mark_backlink); + /* * SAS remote PHY attributes. */ @@ -1140,7 +1194,7 @@ int sas_rphy_add(struct sas_rphy *rphy) if (identify->device_type == SAS_END_DEVICE && rphy->scsi_target_id != -1) { - scsi_scan_target(&rphy->dev, parent->port_identifier, + scsi_scan_target(&rphy->dev, 0, rphy->scsi_target_id, ~0, 0); } @@ -1242,15 +1296,13 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, mutex_lock(&sas_host->lock); list_for_each_entry(rphy, &sas_host->rphy_list, list) { - struct sas_port *parent = dev_to_sas_port(rphy->dev.parent); - if (rphy->identify.device_type != SAS_END_DEVICE || rphy->scsi_target_id == -1) continue; - if ((channel == SCAN_WILD_CARD || channel == parent->port_identifier) && + if ((channel == SCAN_WILD_CARD || channel == 0) && (id == SCAN_WILD_CARD || id == rphy->scsi_target_id)) { - scsi_scan_target(&rphy->dev, parent->port_identifier, + scsi_scan_target(&rphy->dev, 0, rphy->scsi_target_id, lun, 1); } } diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 3225d31449e..98bd3aab973 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -502,8 +502,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) SCpnt->cmnd[4] = (unsigned char) this_count; SCpnt->cmnd[5] = 0; } - SCpnt->request_bufflen = SCpnt->bufflen = - this_count * sdp->sector_size; + SCpnt->request_bufflen = this_count * sdp->sector_size; /* * We shouldn't disconnect in the middle of a sector, so with a dumb diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c index 3f312a84c6a..2679ea8bff1 100644 --- a/drivers/scsi/seagate.c +++ b/drivers/scsi/seagate.c @@ -1002,7 +1002,7 @@ connect_loop: } #endif - buffer = (struct scatterlist *) SCint->buffer; + buffer = (struct scatterlist *) SCint->request_buffer; len = buffer->length; data = page_address(buffer->page) + buffer->offset; } else { diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index fd94408577e..fae6e95a629 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -360,7 +360,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) "mismatch count %d, bytes %d\n", size, SCpnt->request_bufflen); if (SCpnt->request_bufflen > size) - SCpnt->request_bufflen = SCpnt->bufflen = size; + SCpnt->request_bufflen = size; } } @@ -387,8 +387,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) if (this_count > 0xffff) { this_count = 0xffff; - SCpnt->request_bufflen = SCpnt->bufflen = - this_count * s_size; + SCpnt->request_bufflen = this_count * s_size; } SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 756ceb93ddc..7f669b60067 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -368,7 +368,7 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt) SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2], SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]); if (cmdstatp->have_sense) - __scsi_print_sense("st", SRpnt->sense, SCSI_SENSE_BUFFERSIZE); + __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE); } ) /* end DEB */ if (!debugging) { /* Abnormal conditions for tape */ if (!cmdstatp->have_sense) @@ -384,9 +384,8 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt) scode != VOLUME_OVERFLOW && SRpnt->cmd[0] != MODE_SENSE && SRpnt->cmd[0] != TEST_UNIT_READY) { - printk(KERN_WARNING "%s: Error with sense data: ", name); - __scsi_print_sense("st", SRpnt->sense, - SCSI_SENSE_BUFFERSIZE); + + __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE); } } diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c index 2ebe0d66389..2f8073b73bf 100644 --- a/drivers/scsi/sun3_NCR5380.c +++ b/drivers/scsi/sun3_NCR5380.c @@ -517,7 +517,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd *cmd) */ if (cmd->use_sg) { - cmd->SCp.buffer = (struct scatterlist *) cmd->buffer; + cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer; cmd->SCp.buffers_residual = cmd->use_sg - 1; cmd->SCp.ptr = (char *) SGADDR(cmd->SCp.buffer); cmd->SCp.this_residual = cmd->SCp.buffer->length; diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c index 1f328cae5c0..6b60536ac92 100644 --- a/drivers/scsi/sun3x_esp.c +++ b/drivers/scsi/sun3x_esp.c @@ -347,7 +347,7 @@ static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp) static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp) { int sz = sp->use_sg - 1; - struct scatterlist *sg = (struct scatterlist *)sp->buffer; + struct scatterlist *sg = (struct scatterlist *)sp->request_buffer; while(sz >= 0) { dvma_unmap((char *)sg[sz].dma_address); diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c index 680f38ab60d..2083454db51 100644 --- a/drivers/scsi/wd33c93.c +++ b/drivers/scsi/wd33c93.c @@ -373,7 +373,7 @@ wd33c93_queuecommand(struct scsi_cmnd *cmd, */ if (cmd->use_sg) { - cmd->SCp.buffer = (struct scatterlist *) cmd->buffer; + cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer; cmd->SCp.buffers_residual = cmd->use_sg - 1; cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset; diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 979497f108c..dc673e1b6fd 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c @@ -1047,12 +1047,13 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id * up = &sunsab_ports[inst * 2]; err = sunsab_init_one(&up[0], op, - sizeof(union sab82532_async_regs), + 0, (inst * 2) + 0); if (err) return err; - err = sunsab_init_one(&up[1], op, 0, + err = sunsab_init_one(&up[1], op, + sizeof(union sab82532_async_regs), (inst * 2) + 1); if (err) { of_iounmap(up[0].port.membase, @@ -1117,7 +1118,7 @@ static int __init sunsab_init(void) int err; num_channels = 0; - for_each_node_by_name(dp, "su") + for_each_node_by_name(dp, "se") num_channels += 2; for_each_node_by_name(dp, "serial") { if (of_device_is_compatible(dp, "sab82532")) diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index a1456d9352c..47bc3d57e01 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c @@ -68,9 +68,6 @@ static int num_sunzilog; #define NUM_SUNZILOG num_sunzilog #define NUM_CHANNELS (NUM_SUNZILOG * 2) -#define KEYBOARD_LINE 0x2 -#define MOUSE_LINE 0x3 - #define ZS_CLOCK 4915200 /* Zilog input clock rate. */ #define ZS_CLOCK_DIVISOR 16 /* Divisor this driver uses. */ @@ -1225,12 +1222,10 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe { int baud, brg; - if (channel == KEYBOARD_LINE) { - up->flags |= SUNZILOG_FLAG_CONS_KEYB; + if (up->flags & SUNZILOG_FLAG_CONS_KEYB) { up->cflag = B1200 | CS8 | CLOCAL | CREAD; baud = 1200; } else { - up->flags |= SUNZILOG_FLAG_CONS_MOUSE; up->cflag = B4800 | CS8 | CLOCAL | CREAD; baud = 4800; } @@ -1243,14 +1238,14 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe } #ifdef CONFIG_SERIO -static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int channel) +static void __init sunzilog_register_serio(struct uart_sunzilog_port *up) { struct serio *serio = &up->serio; serio->port_data = up; serio->id.type = SERIO_RS232; - if (channel == KEYBOARD_LINE) { + if (up->flags & SUNZILOG_FLAG_CONS_KEYB) { serio->id.proto = SERIO_SUNKBD; strlcpy(serio->name, "zskbd", sizeof(serio->name)); } else { @@ -1259,7 +1254,8 @@ static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int ch strlcpy(serio->name, "zsms", sizeof(serio->name)); } strlcpy(serio->phys, - (channel == KEYBOARD_LINE ? "zs/serio0" : "zs/serio1"), + ((up->flags & SUNZILOG_FLAG_CONS_KEYB) ? + "zs/serio0" : "zs/serio1"), sizeof(serio->phys)); serio->write = sunzilog_serio_write; @@ -1286,8 +1282,8 @@ static void __init sunzilog_init_hw(struct uart_sunzilog_port *up) (void) read_zsreg(channel, R0); } - if (up->port.line == KEYBOARD_LINE || - up->port.line == MOUSE_LINE) { + if (up->flags & (SUNZILOG_FLAG_CONS_KEYB | + SUNZILOG_FLAG_CONS_MOUSE)) { sunzilog_init_kbdms(up, up->port.line); up->curregs[R9] |= (NV | MIE); write_zsreg(channel, R9, up->curregs[R9]); @@ -1313,37 +1309,26 @@ static void __init sunzilog_init_hw(struct uart_sunzilog_port *up) spin_unlock_irqrestore(&up->port.lock, flags); #ifdef CONFIG_SERIO - if (up->port.line == KEYBOARD_LINE || up->port.line == MOUSE_LINE) - sunzilog_register_serio(up, up->port.line); + if (up->flags & (SUNZILOG_FLAG_CONS_KEYB | + SUNZILOG_FLAG_CONS_MOUSE)) + sunzilog_register_serio(up); #endif } -static int __devinit zs_get_instance(struct device_node *dp) -{ - int ret; - - ret = of_getintprop_default(dp, "slave", -1); - if (ret != -1) - return ret; - - if (of_find_property(dp, "keyboard", NULL)) - ret = 1; - else - ret = 0; - - return ret; -} - static int zilog_irq = -1; -static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *match) +static int __devinit zs_probe(struct of_device *op, const struct of_device_id *match) { - struct of_device *op = to_of_device(&dev->dev); + static int inst; struct uart_sunzilog_port *up; struct zilog_layout __iomem *rp; - int inst = zs_get_instance(dev->node); + int keyboard_mouse; int err; + keyboard_mouse = 0; + if (of_find_property(op->node, "keyboard", NULL)) + keyboard_mouse = 1; + sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0, sizeof(struct zilog_layout), "zs"); @@ -1352,16 +1337,8 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id * rp = sunzilog_chip_regs[inst]; - if (zilog_irq == -1) { + if (zilog_irq == -1) zilog_irq = op->irqs[0]; - err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED, - "zs", sunzilog_irq_chain); - if (err) { - of_iounmap(rp, sizeof(struct zilog_layout)); - - return err; - } - } up = &sunzilog_port_table[inst * 2]; @@ -1378,7 +1355,7 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id * up[0].port.line = (inst * 2) + 0; up[0].port.dev = &op->dev; up[0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A; - if (inst == 1) + if (keyboard_mouse) up[0].flags |= SUNZILOG_FLAG_CONS_KEYB; sunzilog_init_hw(&up[0]); @@ -1395,11 +1372,11 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id * up[1].port.line = (inst * 2) + 1; up[1].port.dev = &op->dev; up[1].flags |= 0; - if (inst == 1) + if (keyboard_mouse) up[1].flags |= SUNZILOG_FLAG_CONS_MOUSE; sunzilog_init_hw(&up[1]); - if (inst != 1) { + if (!keyboard_mouse) { err = uart_add_one_port(&sunzilog_reg, &up[0].port); if (err) { of_iounmap(rp, sizeof(struct zilog_layout)); @@ -1411,9 +1388,18 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id * of_iounmap(rp, sizeof(struct zilog_layout)); return err; } + } else { + printk(KERN_INFO "%s: Keyboard at MMIO %lx (irq = %d) " + "is a zs\n", + op->dev.bus_id, up[0].port.mapbase, op->irqs[0]); + printk(KERN_INFO "%s: Mouse at MMIO %lx (irq = %d) " + "is a zs\n", + op->dev.bus_id, up[1].port.mapbase, op->irqs[0]); } - dev_set_drvdata(&dev->dev, &up[0]); + dev_set_drvdata(&op->dev, &up[0]); + + inst++; return 0; } @@ -1462,36 +1448,65 @@ static struct of_platform_driver zs_driver = { static int __init sunzilog_init(void) { struct device_node *dp; - int err; + int err, uart_count; + int num_keybms; NUM_SUNZILOG = 0; - for_each_node_by_name(dp, "zs") + num_keybms = 0; + for_each_node_by_name(dp, "zs") { NUM_SUNZILOG++; + if (of_find_property(dp, "keyboard", NULL)) + num_keybms++; + } + uart_count = 0; if (NUM_SUNZILOG) { int uart_count; err = sunzilog_alloc_tables(); if (err) - return err; + goto out; - /* Subtract 1 for keyboard, 1 for mouse. */ - uart_count = (NUM_SUNZILOG * 2) - 2; + uart_count = (NUM_SUNZILOG * 2) - (2 * num_keybms); sunzilog_reg.nr = uart_count; sunzilog_reg.minor = sunserial_current_minor; err = uart_register_driver(&sunzilog_reg); - if (err) { - sunzilog_free_tables(); - return err; - } + if (err) + goto out_free_tables; + sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64; sunzilog_reg.cons = SUNZILOG_CONSOLE(); sunserial_current_minor += uart_count; } - return of_register_driver(&zs_driver, &of_bus_type); + err = of_register_driver(&zs_driver, &of_bus_type); + if (err) + goto out_unregister_uart; + + if (zilog_irq != -1) { + err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED, + "zs", sunzilog_irq_chain); + if (err) + goto out_unregister_driver; + } + +out: + return err; + +out_unregister_driver: + of_unregister_driver(&zs_driver); + +out_unregister_uart: + if (NUM_SUNZILOG) { + uart_unregister_driver(&sunzilog_reg); + sunzilog_reg.cons = NULL; + } + +out_free_tables: + sunzilog_free_tables(); + goto out; } static void __exit sunzilog_exit(void) diff --git a/include/asm-m68k/oplib.h b/include/asm-m68k/oplib.h index c3594f473ef..06caa2d0845 100644 --- a/include/asm-m68k/oplib.h +++ b/include/asm-m68k/oplib.h @@ -244,11 +244,6 @@ extern void prom_getstring(int node, char *prop, char *buf, int bufsize); /* Does the passed node have the given "name"? YES=1 NO=0 */ extern int prom_nodematch(int thisnode, char *name); -/* Puts in buffer a prom name in the form name@x,y or name (x for which_io - * and y for first regs phys address - */ -extern int prom_getname(int node, char *buf, int buflen); - /* Search all siblings starting at the passed node for "name" matching * the given string. Returns the node on success, zero on failure. */ diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h index 36a3a85d611..16040048cd1 100644 --- a/include/asm-s390/system.h +++ b/include/asm-s390/system.h @@ -128,8 +128,13 @@ extern void account_system_vtime(struct task_struct *); #define nop() __asm__ __volatile__ ("nop") -#define xchg(ptr,x) \ - ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(void *)(ptr),sizeof(*(ptr)))) +#define xchg(ptr,x) \ +({ \ + __typeof__(*(ptr)) __ret; \ + __ret = (__typeof__(*(ptr))) \ + __xchg((unsigned long)(x), (void *)(ptr),sizeof(*(ptr))); \ + __ret; \ +}) static inline unsigned long __xchg(unsigned long x, void * ptr, int size) { diff --git a/include/asm-s390/timex.h b/include/asm-s390/timex.h index 4848057dafe..5d0332a4c2b 100644 --- a/include/asm-s390/timex.h +++ b/include/asm-s390/timex.h @@ -19,7 +19,7 @@ static inline cycles_t get_cycles(void) { cycles_t cycles; - __asm__("stck 0(%1)" : "=m" (cycles) : "a" (&cycles) : "cc"); + __asm__ __volatile__ ("stck 0(%1)" : "=m" (cycles) : "a" (&cycles) : "cc"); return cycles >> 2; } @@ -27,7 +27,7 @@ static inline unsigned long long get_clock (void) { unsigned long long clk; - __asm__("stck 0(%1)" : "=m" (clk) : "a" (&clk) : "cc"); + __asm__ __volatile__ ("stck 0(%1)" : "=m" (clk) : "a" (&clk) : "cc"); return clk; } diff --git a/include/asm-sparc/oplib.h b/include/asm-sparc/oplib.h index f283f8aaf6a..91691e52c05 100644 --- a/include/asm-sparc/oplib.h +++ b/include/asm-sparc/oplib.h @@ -267,11 +267,6 @@ extern void prom_getstring(int node, char *prop, char *buf, int bufsize); /* Does the passed node have the given "name"? YES=1 NO=0 */ extern int prom_nodematch(int thisnode, char *name); -/* Puts in buffer a prom name in the form name@x,y or name (x for which_io - * and y for first regs phys address - */ -extern int prom_getname(int node, char *buf, int buflen); - /* Search all siblings starting at the passed node for "name" matching * the given string. Returns the node on success, zero on failure. */ diff --git a/include/asm-sparc64/openprom.h b/include/asm-sparc64/openprom.h index b4959d2b0d9..e01b80559c9 100644 --- a/include/asm-sparc64/openprom.h +++ b/include/asm-sparc64/openprom.h @@ -175,7 +175,7 @@ struct linux_nodeops { }; /* More fun PROM structures for device probing. */ -#define PROMREG_MAX 16 +#define PROMREG_MAX 24 #define PROMVADDR_MAX 16 #define PROMINTR_MAX 15 diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h index a68b0bb0595..6a0da3b1695 100644 --- a/include/asm-sparc64/oplib.h +++ b/include/asm-sparc64/oplib.h @@ -287,11 +287,6 @@ extern void prom_getstring(int node, const char *prop, char *buf, int bufsize); /* Does the passed node have the given "name"? YES=1 NO=0 */ extern int prom_nodematch(int thisnode, const char *name); -/* Puts in buffer a prom name in the form name@x,y or name (x for which_io - * and y for first regs phys address - */ -extern int prom_getname(int node, char *buf, int buflen); - /* Search all siblings starting at the passed node for "name" matching * the given string. Returns the node on success, zero on failure. */ diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 44a11f1ccaf..8fb344a9abd 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -48,7 +48,6 @@ static inline void unregister_cpu_notifier(struct notifier_block *nb) { } #endif -extern int current_in_cpu_hotplug(void); int cpu_up(unsigned int cpu); @@ -61,10 +60,6 @@ static inline int register_cpu_notifier(struct notifier_block *nb) static inline void unregister_cpu_notifier(struct notifier_block *nb) { } -static inline int current_in_cpu_hotplug(void) -{ - return 0; -} #endif /* CONFIG_SMP */ extern struct sysdev_class cpu_sysdev_class; @@ -73,7 +68,6 @@ extern struct sysdev_class cpu_sysdev_class; /* Stop CPUs going up and down. */ extern void lock_cpu_hotplug(void); extern void unlock_cpu_hotplug(void); -extern int lock_cpu_hotplug_interruptible(void); #define hotcpu_notifier(fn, pri) { \ static struct notifier_block fn##_nb = \ { .notifier_call = fn, .priority = pri }; \ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 76cc099c858..75f02d8c6ed 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -924,10 +924,10 @@ static inline void netif_tx_lock_bh(struct net_device *dev) static inline int netif_tx_trylock(struct net_device *dev) { - int err = spin_trylock(&dev->_xmit_lock); - if (!err) + int ok = spin_trylock(&dev->_xmit_lock); + if (likely(ok)) dev->xmit_lock_owner = smp_processor_id(); - return err; + return ok; } static inline void netif_tx_unlock(struct net_device *dev) diff --git a/include/net/netdma.h b/include/net/netdma.h index 19760eb131a..ceae5ee85c0 100644 --- a/include/net/netdma.h +++ b/include/net/netdma.h @@ -37,7 +37,7 @@ static inline struct dma_chan *get_softnet_dma(void) } int dma_skb_copy_datagram_iovec(struct dma_chan* chan, - const struct sk_buff *skb, int offset, struct iovec *to, + struct sk_buff *skb, int offset, struct iovec *to, size_t len, struct dma_pinned_list *pinned_list); #endif /* CONFIG_NET_DMA */ diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 5f69158c100..e5aa7ff1f5b 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -445,6 +445,7 @@ typedef struct sctp_sender_hb_info { struct sctp_paramhdr param_hdr; union sctp_addr daddr; unsigned long sent_at; + __u64 hb_nonce; } __attribute__((packed)) sctp_sender_hb_info_t; /* @@ -730,13 +731,10 @@ void sctp_init_addrs(struct sctp_chunk *, union sctp_addr *, const union sctp_addr *sctp_source(const struct sctp_chunk *chunk); /* This is a structure for holding either an IPv6 or an IPv4 address. */ -/* sin_family -- AF_INET or AF_INET6 - * sin_port -- ordinary port number - * sin_addr -- cast to either (struct in_addr) or (struct in6_addr) - */ struct sctp_sockaddr_entry { struct list_head list; union sctp_addr a; + __u8 use_as_src; }; typedef struct sctp_chunk *(sctp_packet_phandler_t)(struct sctp_association *); @@ -984,6 +982,9 @@ struct sctp_transport { */ char cacc_saw_newack; } cacc; + + /* 64-bit random number sent with heartbeat. */ + __u64 hb_nonce; }; struct sctp_transport *sctp_transport_new(const union sctp_addr *, @@ -1138,7 +1139,7 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest, sctp_scope_t scope, gfp_t gfp, int flags); int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *, - gfp_t gfp); + __u8 use_as_src, gfp_t gfp); int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *); int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *, struct sctp_sock *); diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h index 8a6bef6f91e..1b7aae6cdd8 100644 --- a/include/net/sctp/user.h +++ b/include/net/sctp/user.h @@ -560,9 +560,18 @@ struct sctp_paddrinfo { } __attribute__((packed, aligned(4))); /* Peer addresses's state. */ +/* UNKNOWN: Peer address passed by the upper layer in sendmsg or connect[x] + * calls. + * UNCONFIRMED: Peer address received in INIT/INIT-ACK address parameters. + * Not yet confirmed by a heartbeat and not available for data + * transfers. + * ACTIVE : Peer address confirmed, active and available for data transfers. + * INACTIVE: Peer address inactive and not available for data transfers. + */ enum sctp_spinfo_state { SCTP_INACTIVE, SCTP_ACTIVE, + SCTP_UNCONFIRMED, SCTP_UNKNOWN = 0xffff /* Value used for transport state unknown */ }; diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 371f70d9aa9..58e6444eebe 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -58,9 +58,7 @@ struct scsi_cmnd { int timeout_per_command; unsigned char cmd_len; - unsigned char old_cmd_len; enum dma_data_direction sc_data_direction; - enum dma_data_direction sc_old_data_direction; /* These elements define the operation we are about to perform */ #define MAX_COMMAND_SIZE 16 @@ -71,18 +69,11 @@ struct scsi_cmnd { void *request_buffer; /* Actual requested buffer */ /* These elements define the operation we ultimately want to perform */ - unsigned char data_cmnd[MAX_COMMAND_SIZE]; - unsigned short old_use_sg; /* We save use_sg here when requesting - * sense info */ unsigned short use_sg; /* Number of pieces of scatter-gather */ unsigned short sglist_len; /* size of malloc'd scatter-gather list */ - unsigned bufflen; /* Size of data buffer */ - void *buffer; /* Data buffer */ unsigned underflow; /* Return error if less than this amount is transferred */ - unsigned old_underflow; /* save underflow here when reusing the - * command for error handling */ unsigned transfersize; /* How much we are guaranteed to transfer with each SCSI transfer diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index e3c503cd175..6cc2314098c 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h @@ -106,6 +106,7 @@ struct sas_end_device { struct sas_expander_device { int level; + int next_port_id; #define SAS_EXPANDER_VENDOR_ID_LEN 8 char vendor_id[SAS_EXPANDER_VENDOR_ID_LEN+1]; @@ -127,8 +128,10 @@ struct sas_expander_device { struct sas_port { struct device dev; - u8 port_identifier; + int port_identifier; int num_phys; + /* port flags */ + unsigned int is_backlink:1; /* the other end of the link */ struct sas_rphy *rphy; @@ -168,11 +171,13 @@ extern void sas_rphy_delete(struct sas_rphy *); extern int scsi_is_sas_rphy(const struct device *); struct sas_port *sas_port_alloc(struct device *, int); +struct sas_port *sas_port_alloc_num(struct device *); int sas_port_add(struct sas_port *); void sas_port_free(struct sas_port *); void sas_port_delete(struct sas_port *); void sas_port_add_phy(struct sas_port *, struct sas_phy *); void sas_port_delete_phy(struct sas_port *, struct sas_phy *); +void sas_port_mark_backlink(struct sas_port *); int scsi_is_sas_port(const struct device *); extern struct scsi_transport_template * diff --git a/kernel/cpu.c b/kernel/cpu.c index 70fbf2e8376..f230f9ae01c 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -16,56 +16,48 @@ #include <linux/mutex.h> /* This protects CPUs going up and down... */ -static DEFINE_MUTEX(cpucontrol); +static DEFINE_MUTEX(cpu_add_remove_lock); +static DEFINE_MUTEX(cpu_bitmask_lock); static __cpuinitdata BLOCKING_NOTIFIER_HEAD(cpu_chain); #ifdef CONFIG_HOTPLUG_CPU -static struct task_struct *lock_cpu_hotplug_owner; -static int lock_cpu_hotplug_depth; -static int __lock_cpu_hotplug(int interruptible) -{ - int ret = 0; - - if (lock_cpu_hotplug_owner != current) { - if (interruptible) - ret = mutex_lock_interruptible(&cpucontrol); - else - mutex_lock(&cpucontrol); - } - - /* - * Set only if we succeed in locking - */ - if (!ret) { - lock_cpu_hotplug_depth++; - lock_cpu_hotplug_owner = current; - } - - return ret; -} +/* Crappy recursive lock-takers in cpufreq! Complain loudly about idiots */ +static struct task_struct *recursive; +static int recursive_depth; void lock_cpu_hotplug(void) { - __lock_cpu_hotplug(0); + struct task_struct *tsk = current; + + if (tsk == recursive) { + static int warnings = 10; + if (warnings) { + printk(KERN_ERR "Lukewarm IQ detected in hotplug locking\n"); + WARN_ON(1); + warnings--; + } + recursive_depth++; + return; + } + mutex_lock(&cpu_bitmask_lock); + recursive = tsk; } EXPORT_SYMBOL_GPL(lock_cpu_hotplug); void unlock_cpu_hotplug(void) { - if (--lock_cpu_hotplug_depth == 0) { - lock_cpu_hotplug_owner = NULL; - mutex_unlock(&cpucontrol); + WARN_ON(recursive != current); + if (recursive_depth) { + recursive_depth--; + return; } + mutex_unlock(&cpu_bitmask_lock); + recursive = NULL; } EXPORT_SYMBOL_GPL(unlock_cpu_hotplug); -int lock_cpu_hotplug_interruptible(void) -{ - return __lock_cpu_hotplug(1); -} -EXPORT_SYMBOL_GPL(lock_cpu_hotplug_interruptible); #endif /* CONFIG_HOTPLUG_CPU */ /* Need to know about CPUs going up/down? */ @@ -122,9 +114,7 @@ int cpu_down(unsigned int cpu) struct task_struct *p; cpumask_t old_allowed, tmp; - if ((err = lock_cpu_hotplug_interruptible()) != 0) - return err; - + mutex_lock(&cpu_add_remove_lock); if (num_online_cpus() == 1) { err = -EBUSY; goto out; @@ -150,7 +140,10 @@ int cpu_down(unsigned int cpu) cpu_clear(cpu, tmp); set_cpus_allowed(current, tmp); + mutex_lock(&cpu_bitmask_lock); p = __stop_machine_run(take_cpu_down, NULL, cpu); + mutex_unlock(&cpu_bitmask_lock); + if (IS_ERR(p)) { /* CPU didn't die: tell everyone. Can't complain. */ if (blocking_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, @@ -187,7 +180,7 @@ out_thread: out_allowed: set_cpus_allowed(current, old_allowed); out: - unlock_cpu_hotplug(); + mutex_unlock(&cpu_add_remove_lock); return err; } #endif /*CONFIG_HOTPLUG_CPU*/ @@ -197,9 +190,7 @@ int __devinit cpu_up(unsigned int cpu) int ret; void *hcpu = (void *)(long)cpu; - if ((ret = lock_cpu_hotplug_interruptible()) != 0) - return ret; - + mutex_lock(&cpu_add_remove_lock); if (cpu_online(cpu) || !cpu_present(cpu)) { ret = -EINVAL; goto out; @@ -214,7 +205,9 @@ int __devinit cpu_up(unsigned int cpu) } /* Arch-specific enabling code. */ + mutex_lock(&cpu_bitmask_lock); ret = __cpu_up(cpu); + mutex_unlock(&cpu_bitmask_lock); if (ret != 0) goto out_notify; BUG_ON(!cpu_online(cpu)); @@ -227,6 +220,6 @@ out_notify: blocking_notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, hcpu); out: - unlock_cpu_hotplug(); + mutex_unlock(&cpu_add_remove_lock); return ret; } diff --git a/kernel/cpuset.c b/kernel/cpuset.c index c232dc07743..1a649f2bb9b 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -762,6 +762,8 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial) * * Call with manage_mutex held. May nest a call to the * lock_cpu_hotplug()/unlock_cpu_hotplug() pair. + * Must not be called holding callback_mutex, because we must + * not call lock_cpu_hotplug() while holding callback_mutex. */ static void update_cpu_domains(struct cpuset *cur) @@ -781,7 +783,7 @@ static void update_cpu_domains(struct cpuset *cur) if (is_cpu_exclusive(c)) cpus_andnot(pspan, pspan, c->cpus_allowed); } - if (is_removed(cur) || !is_cpu_exclusive(cur)) { + if (!is_cpu_exclusive(cur)) { cpus_or(pspan, pspan, cur->cpus_allowed); if (cpus_equal(pspan, cur->cpus_allowed)) return; @@ -1917,6 +1919,17 @@ static int cpuset_mkdir(struct inode *dir, struct dentry *dentry, int mode) return cpuset_create(c_parent, dentry->d_name.name, mode | S_IFDIR); } +/* + * Locking note on the strange update_flag() call below: + * + * If the cpuset being removed is marked cpu_exclusive, then simulate + * turning cpu_exclusive off, which will call update_cpu_domains(). + * The lock_cpu_hotplug() call in update_cpu_domains() must not be + * made while holding callback_mutex. Elsewhere the kernel nests + * callback_mutex inside lock_cpu_hotplug() calls. So the reverse + * nesting would risk an ABBA deadlock. + */ + static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry) { struct cpuset *cs = dentry->d_fsdata; @@ -1936,11 +1949,16 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry) mutex_unlock(&manage_mutex); return -EBUSY; } + if (is_cpu_exclusive(cs)) { + int retval = update_flag(CS_CPU_EXCLUSIVE, cs, "0"); + if (retval < 0) { + mutex_unlock(&manage_mutex); + return retval; + } + } parent = cs->parent; mutex_lock(&callback_mutex); set_bit(CS_REMOVED, &cs->flags); - if (is_cpu_exclusive(cs)) - update_cpu_domains(cs); list_del(&cs->sibling); /* delete my sibling from parent->children */ spin_lock(&cs->dentry->d_lock); d = dget(cs->dentry); diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 458031bfff5..0ade0c63fdf 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -542,12 +542,11 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, * so it cannot "appear" on us. */ if (!grp) { /* need to add a new group */ - grp = kmalloc(sizeof(struct vlan_group), GFP_KERNEL); + grp = kzalloc(sizeof(struct vlan_group), GFP_KERNEL); if (!grp) goto out_free_unregister; /* printk(KERN_ALERT "VLAN REGISTER: Allocated new group.\n"); */ - memset(grp, 0, sizeof(struct vlan_group)); grp->real_dev_ifindex = real_dev->ifindex; hlist_add_head_rcu(&grp->hlist, diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 5ee96d4b40e..96dc6bb52d1 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -227,12 +227,11 @@ static void atif_drop_device(struct net_device *dev) static struct atalk_iface *atif_add_device(struct net_device *dev, struct atalk_addr *sa) { - struct atalk_iface *iface = kmalloc(sizeof(*iface), GFP_KERNEL); + struct atalk_iface *iface = kzalloc(sizeof(*iface), GFP_KERNEL); if (!iface) goto out; - memset(iface, 0, sizeof(*iface)); dev_hold(dev); iface->dev = dev; dev->atalk_ptr = iface; @@ -559,12 +558,11 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint) } if (!rt) { - rt = kmalloc(sizeof(*rt), GFP_ATOMIC); + rt = kzalloc(sizeof(*rt), GFP_ATOMIC); retval = -ENOBUFS; if (!rt) goto out_unlock; - memset(rt, 0, sizeof(*rt)); rt->next = atalk_routes; atalk_routes = rt; diff --git a/net/atm/br2684.c b/net/atm/br2684.c index a487233dc46..d00cca97eb3 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c @@ -508,10 +508,9 @@ Note: we do not have explicit unassign, but look at _push() if (copy_from_user(&be, arg, sizeof be)) return -EFAULT; - brvcc = kmalloc(sizeof(struct br2684_vcc), GFP_KERNEL); + brvcc = kzalloc(sizeof(struct br2684_vcc), GFP_KERNEL); if (!brvcc) return -ENOMEM; - memset(brvcc, 0, sizeof(struct br2684_vcc)); write_lock_irq(&devs_lock); net_dev = br2684_find_dev(&be.ifspec); if (net_dev == NULL) { diff --git a/net/atm/clip.c b/net/atm/clip.c index 2e62105d91b..7ce7bfe3fba 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c @@ -929,12 +929,11 @@ static int arp_seq_open(struct inode *inode, struct file *file) struct seq_file *seq; int rc = -EAGAIN; - state = kmalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc(sizeof(*state), GFP_KERNEL); if (!state) { rc = -ENOMEM; goto out_kfree; } - memset(state, 0, sizeof(*state)); state->ns.neigh_sub_iter = clip_seq_sub_iter; rc = seq_open(file, &arp_seq_ops); diff --git a/net/atm/lec.c b/net/atm/lec.c index 4b68a18171c..b4aa489849d 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -1811,12 +1811,11 @@ make_entry(struct lec_priv *priv, unsigned char *mac_addr) { struct lec_arp_table *to_return; - to_return = kmalloc(sizeof(struct lec_arp_table), GFP_ATOMIC); + to_return = kzalloc(sizeof(struct lec_arp_table), GFP_ATOMIC); if (!to_return) { printk("LEC: Arp entry kmalloc failed\n"); return NULL; } - memset(to_return, 0, sizeof(struct lec_arp_table)); memcpy(to_return->mac_addr, mac_addr, ETH_ALEN); init_timer(&to_return->timer); to_return->timer.function = lec_arp_expire_arp; diff --git a/net/atm/mpc.c b/net/atm/mpc.c index 9aafe1e2f04..00704661e83 100644 --- a/net/atm/mpc.c +++ b/net/atm/mpc.c @@ -258,10 +258,9 @@ static struct mpoa_client *alloc_mpc(void) { struct mpoa_client *mpc; - mpc = kmalloc(sizeof (struct mpoa_client), GFP_KERNEL); + mpc = kzalloc(sizeof (struct mpoa_client), GFP_KERNEL); if (mpc == NULL) return NULL; - memset(mpc, 0, sizeof(struct mpoa_client)); rwlock_init(&mpc->ingress_lock); rwlock_init(&mpc->egress_lock); mpc->next = mpcs; diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c index 76a7d8ff6c0..19d5dfc0702 100644 --- a/net/atm/pppoatm.c +++ b/net/atm/pppoatm.c @@ -287,10 +287,9 @@ static int pppoatm_assign_vcc(struct atm_vcc *atmvcc, void __user *arg) if (be.encaps != PPPOATM_ENCAPS_AUTODETECT && be.encaps != PPPOATM_ENCAPS_VC && be.encaps != PPPOATM_ENCAPS_LLC) return -EINVAL; - pvcc = kmalloc(sizeof(*pvcc), GFP_KERNEL); + pvcc = kzalloc(sizeof(*pvcc), GFP_KERNEL); if (pvcc == NULL) return -ENOMEM; - memset(pvcc, 0, sizeof(*pvcc)); pvcc->atmvcc = atmvcc; pvcc->old_push = atmvcc->push; pvcc->old_pop = atmvcc->pop; diff --git a/net/atm/resources.c b/net/atm/resources.c index de25c6408b0..529f7e64aa2 100644 --- a/net/atm/resources.c +++ b/net/atm/resources.c @@ -33,10 +33,9 @@ static struct atm_dev *__alloc_atm_dev(const char *type) { struct atm_dev *dev; - dev = kmalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return NULL; - memset(dev, 0, sizeof(*dev)); dev->type = type; dev->signal = ATM_PHY_SIG_UNKNOWN; dev->link_rate = ATM_OC3_PCR; diff --git a/net/ax25/sysctl_net_ax25.c b/net/ax25/sysctl_net_ax25.c index 369a75b160f..867d4253797 100644 --- a/net/ax25/sysctl_net_ax25.c +++ b/net/ax25/sysctl_net_ax25.c @@ -203,13 +203,11 @@ void ax25_register_sysctl(void) for (ax25_table_size = sizeof(ctl_table), ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next) ax25_table_size += sizeof(ctl_table); - if ((ax25_table = kmalloc(ax25_table_size, GFP_ATOMIC)) == NULL) { + if ((ax25_table = kzalloc(ax25_table_size, GFP_ATOMIC)) == NULL) { spin_unlock_bh(&ax25_dev_lock); return; } - memset(ax25_table, 0x00, ax25_table_size); - for (n = 0, ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next) { ctl_table *child = kmalloc(sizeof(ax25_param_table), GFP_ATOMIC); if (!child) { diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index 159fb840982..4e4119a1213 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -162,12 +162,10 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (num > BR_MAX_PORTS) num = BR_MAX_PORTS; - indices = kmalloc(num*sizeof(int), GFP_KERNEL); + indices = kcalloc(num, sizeof(int), GFP_KERNEL); if (indices == NULL) return -ENOMEM; - memset(indices, 0, num*sizeof(int)); - get_port_ifindices(br, indices, num); if (copy_to_user((void __user *)args[1], indices, num*sizeof(int))) num = -EFAULT; @@ -327,11 +325,10 @@ static int old_deviceless(void __user *uarg) if (args[2] >= 2048) return -ENOMEM; - indices = kmalloc(args[2]*sizeof(int), GFP_KERNEL); + indices = kcalloc(args[2], sizeof(int), GFP_KERNEL); if (indices == NULL) return -ENOMEM; - memset(indices, 0, args[2]*sizeof(int)); args[2] = get_bridge_ifindices(indices, args[2]); ret = copy_to_user((void __user *)args[1], indices, args[2]*sizeof(int)) diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 27ce1683caf..2797e281541 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -437,7 +437,7 @@ static int ethtool_set_pauseparam(struct net_device *dev, void __user *useraddr) { struct ethtool_pauseparam pauseparam; - if (!dev->ethtool_ops->get_pauseparam) + if (!dev->ethtool_ops->set_pauseparam) return -EOPNOTSUPP; if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam))) diff --git a/net/core/user_dma.c b/net/core/user_dma.c index b7c98dbcdb8..248a6b666af 100644 --- a/net/core/user_dma.c +++ b/net/core/user_dma.c @@ -29,6 +29,7 @@ #include <linux/socket.h> #include <linux/rtnetlink.h> /* for BUG_TRAP */ #include <net/tcp.h> +#include <net/netdma.h> #define NET_DMA_DEFAULT_COPYBREAK 4096 diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 98a25208440..476455fbdb0 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -413,11 +413,7 @@ static struct dn_ifaddr *dn_dev_alloc_ifa(void) { struct dn_ifaddr *ifa; - ifa = kmalloc(sizeof(*ifa), GFP_KERNEL); - - if (ifa) { - memset(ifa, 0, sizeof(*ifa)); - } + ifa = kzalloc(sizeof(*ifa), GFP_KERNEL); return ifa; } @@ -1105,10 +1101,9 @@ struct dn_dev *dn_dev_create(struct net_device *dev, int *err) return NULL; *err = -ENOBUFS; - if ((dn_db = kmalloc(sizeof(struct dn_dev), GFP_ATOMIC)) == NULL) + if ((dn_db = kzalloc(sizeof(struct dn_dev), GFP_ATOMIC)) == NULL) return NULL; - memset(dn_db, 0, sizeof(struct dn_dev)); memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms)); smp_wmb(); dev->dn_ptr = dn_db; diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 0375077391b..fa20e2efcfc 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c @@ -283,11 +283,10 @@ struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r, struct dn_kern_rta goto err_inval; } - fi = kmalloc(sizeof(*fi)+nhs*sizeof(struct dn_fib_nh), GFP_KERNEL); + fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct dn_fib_nh), GFP_KERNEL); err = -ENOBUFS; if (fi == NULL) goto failure; - memset(fi, 0, sizeof(*fi)+nhs*sizeof(struct dn_fib_nh)); fi->fib_protocol = r->rtm_protocol; fi->fib_nhs = nhs; diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index 5ce9c9e0565..ff0ebe99137 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c @@ -580,12 +580,11 @@ static int dn_neigh_seq_open(struct inode *inode, struct file *file) { struct seq_file *seq; int rc = -ENOMEM; - struct neigh_seq_state *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct neigh_seq_state *s = kzalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; - memset(s, 0, sizeof(*s)); rc = seq_open(file, &dn_neigh_seq_ops); if (rc) goto out_kfree; diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index 22f321d9bf9..6986be754ef 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c @@ -151,10 +151,9 @@ int dn_fib_rtm_newrule(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) } } - new_r = kmalloc(sizeof(*new_r), GFP_KERNEL); + new_r = kzalloc(sizeof(*new_r), GFP_KERNEL); if (!new_r) return -ENOMEM; - memset(new_r, 0, sizeof(*new_r)); if (rta[RTA_SRC-1]) memcpy(&new_r->r_src, RTA_DATA(rta[RTA_SRC-1]), 2); diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index 37d9d0a1ac8..e926c952e36 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c @@ -158,12 +158,10 @@ static void dn_rehash_zone(struct dn_zone *dz) break; } - ht = kmalloc(new_divisor*sizeof(struct dn_fib_node*), GFP_KERNEL); - + ht = kcalloc(new_divisor, sizeof(struct dn_fib_node*), GFP_KERNEL); if (ht == NULL) return; - memset(ht, 0, new_divisor*sizeof(struct dn_fib_node *)); write_lock_bh(&dn_fib_tables_lock); old_ht = dz->dz_hash; dz->dz_hash = ht; @@ -184,11 +182,10 @@ static void dn_free_node(struct dn_fib_node *f) static struct dn_zone *dn_new_zone(struct dn_hash *table, int z) { int i; - struct dn_zone *dz = kmalloc(sizeof(struct dn_zone), GFP_KERNEL); + struct dn_zone *dz = kzalloc(sizeof(struct dn_zone), GFP_KERNEL); if (!dz) return NULL; - memset(dz, 0, sizeof(struct dn_zone)); if (z) { dz->dz_divisor = 16; dz->dz_hashmask = 0x0F; @@ -197,14 +194,12 @@ static struct dn_zone *dn_new_zone(struct dn_hash *table, int z) dz->dz_hashmask = 0; } - dz->dz_hash = kmalloc(dz->dz_divisor*sizeof(struct dn_fib_node *), GFP_KERNEL); - + dz->dz_hash = kcalloc(dz->dz_divisor, sizeof(struct dn_fib_node *), GFP_KERNEL); if (!dz->dz_hash) { kfree(dz); return NULL; } - memset(dz->dz_hash, 0, dz->dz_divisor*sizeof(struct dn_fib_node*)); dz->dz_order = z; dz->dz_mask = dnet_make_mask(z); diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index 309ae4c6549..4d66aac1348 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c @@ -673,12 +673,11 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg) edev = dev->ec_ptr; if (edev == NULL) { /* Magic up a new one. */ - edev = kmalloc(sizeof(struct ec_device), GFP_KERNEL); + edev = kzalloc(sizeof(struct ec_device), GFP_KERNEL); if (edev == NULL) { err = -ENOMEM; break; } - memset(edev, 0, sizeof(struct ec_device)); dev->ec_ptr = edev; } else net2dev_map[edev->net] = NULL; diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c index cb71d794a7d..5ed0a98b2d7 100644 --- a/net/ieee80211/ieee80211_crypt.c +++ b/net/ieee80211/ieee80211_crypt.c @@ -110,11 +110,10 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) unsigned long flags; struct ieee80211_crypto_alg *alg; - alg = kmalloc(sizeof(*alg), GFP_KERNEL); + alg = kzalloc(sizeof(*alg), GFP_KERNEL); if (alg == NULL) return -ENOMEM; - memset(alg, 0, sizeof(*alg)); alg->ops = ops; spin_lock_irqsave(&ieee80211_crypto_lock, flags); diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c index 492647382ad..ed90a8af144 100644 --- a/net/ieee80211/ieee80211_crypt_ccmp.c +++ b/net/ieee80211/ieee80211_crypt_ccmp.c @@ -76,10 +76,9 @@ static void *ieee80211_ccmp_init(int key_idx) { struct ieee80211_ccmp_data *priv; - priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; - memset(priv, 0, sizeof(*priv)); priv->key_idx = key_idx; priv->tfm = crypto_alloc_tfm("aes", 0); diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c index c5a87724aab..0ebf235f693 100644 --- a/net/ieee80211/ieee80211_crypt_wep.c +++ b/net/ieee80211/ieee80211_crypt_wep.c @@ -39,10 +39,9 @@ static void *prism2_wep_init(int keyidx) { struct prism2_wep_data *priv; - priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; - memset(priv, 0, sizeof(*priv)); priv->key_idx = keyidx; priv->tfm = crypto_alloc_tfm("arc4", 0); diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c index a78c4f845f6..5cb9cfd3539 100644 --- a/net/ieee80211/ieee80211_wx.c +++ b/net/ieee80211/ieee80211_wx.c @@ -369,11 +369,10 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee, struct ieee80211_crypt_data *new_crypt; /* take WEP into use */ - new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data), + new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL); if (new_crypt == NULL) return -ENOMEM; - memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ieee80211_get_crypto_ops("WEP"); if (!new_crypt->ops) { request_module("ieee80211_crypt_wep"); @@ -616,13 +615,11 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee, ieee80211_crypt_delayed_deinit(ieee, crypt); - new_crypt = (struct ieee80211_crypt_data *) - kmalloc(sizeof(*new_crypt), GFP_KERNEL); + new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL); if (new_crypt == NULL) { ret = -ENOMEM; goto done; } - memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ops; if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) new_crypt->priv = new_crypt->ops->init(idx); diff --git a/net/ieee80211/softmac/ieee80211softmac_io.c b/net/ieee80211/softmac/ieee80211softmac_io.c index 8cc8b20f5cd..6ae5a1dc795 100644 --- a/net/ieee80211/softmac/ieee80211softmac_io.c +++ b/net/ieee80211/softmac/ieee80211softmac_io.c @@ -96,8 +96,7 @@ ieee80211softmac_alloc_mgt(u32 size) if(size > IEEE80211_DATA_LEN) return NULL; /* Allocate the frame */ - data = kmalloc(size, GFP_ATOMIC); - memset(data, 0, size); + data = kzalloc(size, GFP_ATOMIC); return data; } diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index 8e748be36c5..1366bc6ce6a 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c @@ -215,12 +215,10 @@ static int ah_init_state(struct xfrm_state *x) if (x->encap) goto error; - ahp = kmalloc(sizeof(*ahp), GFP_KERNEL); + ahp = kzalloc(sizeof(*ahp), GFP_KERNEL); if (ahp == NULL) return -ENOMEM; - memset(ahp, 0, sizeof(*ahp)); - ahp->key = x->aalg->alg_key; ahp->key_len = (x->aalg->alg_key_len+7)/8; ahp->tfm = crypto_alloc_tfm(x->aalg->alg_name, 0); diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 7b51b3bdb54..c8a3723bc00 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -1372,12 +1372,11 @@ static int arp_seq_open(struct inode *inode, struct file *file) { struct seq_file *seq; int rc = -ENOMEM; - struct neigh_seq_state *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct neigh_seq_state *s = kzalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; - memset(s, 0, sizeof(*s)); rc = seq_open(file, &arp_seq_ops); if (rc) goto out_kfree; diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index a7c65e9e5ec..a6cc31d911e 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -93,10 +93,9 @@ static void devinet_sysctl_unregister(struct ipv4_devconf *p); static struct in_ifaddr *inet_alloc_ifa(void) { - struct in_ifaddr *ifa = kmalloc(sizeof(*ifa), GFP_KERNEL); + struct in_ifaddr *ifa = kzalloc(sizeof(*ifa), GFP_KERNEL); if (ifa) { - memset(ifa, 0, sizeof(*ifa)); INIT_RCU_HEAD(&ifa->rcu_head); } @@ -140,10 +139,9 @@ struct in_device *inetdev_init(struct net_device *dev) ASSERT_RTNL(); - in_dev = kmalloc(sizeof(*in_dev), GFP_KERNEL); + in_dev = kzalloc(sizeof(*in_dev), GFP_KERNEL); if (!in_dev) goto out; - memset(in_dev, 0, sizeof(*in_dev)); INIT_RCU_HEAD(&in_dev->rcu_head); memcpy(&in_dev->cnf, &ipv4_devconf_dflt, sizeof(in_dev->cnf)); in_dev->cnf.sysctl = NULL; diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 4e112738b3f..fc2f8ce441d 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -316,12 +316,10 @@ static int esp_init_state(struct xfrm_state *x) if (x->ealg == NULL) goto error; - esp = kmalloc(sizeof(*esp), GFP_KERNEL); + esp = kzalloc(sizeof(*esp), GFP_KERNEL); if (esp == NULL) return -ENOMEM; - memset(esp, 0, sizeof(*esp)); - if (x->aalg) { struct xfrm_algo_desc *aalg_desc; diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 3c1d32ad35f..72c633b357c 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c @@ -204,11 +204,10 @@ static struct fn_zone * fn_new_zone(struct fn_hash *table, int z) { int i; - struct fn_zone *fz = kmalloc(sizeof(struct fn_zone), GFP_KERNEL); + struct fn_zone *fz = kzalloc(sizeof(struct fn_zone), GFP_KERNEL); if (!fz) return NULL; - memset(fz, 0, sizeof(struct fn_zone)); if (z) { fz->fz_divisor = 16; } else { @@ -1046,7 +1045,7 @@ static int fib_seq_open(struct inode *inode, struct file *file) { struct seq_file *seq; int rc = -ENOMEM; - struct fib_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct fib_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; @@ -1057,7 +1056,6 @@ static int fib_seq_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = s; - memset(s, 0, sizeof(*s)); out: return rc; out_kfree: diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 773b12ba4e3..79b04718bdf 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c @@ -196,10 +196,9 @@ int inet_rtm_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) } } - new_r = kmalloc(sizeof(*new_r), GFP_KERNEL); + new_r = kzalloc(sizeof(*new_r), GFP_KERNEL); if (!new_r) return -ENOMEM; - memset(new_r, 0, sizeof(*new_r)); if (rta[RTA_SRC-1]) memcpy(&new_r->r_src, RTA_DATA(rta[RTA_SRC-1]), 4); diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 5f87533684d..9be53a8e72c 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -709,11 +709,10 @@ fib_create_info(const struct rtmsg *r, struct kern_rta *rta, goto failure; } - fi = kmalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL); + fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL); if (fi == NULL) goto failure; fib_info_cnt++; - memset(fi, 0, sizeof(*fi)+nhs*sizeof(struct fib_nh)); fi->fib_protocol = r->rtm_protocol; @@ -962,10 +961,6 @@ fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, rtm->rtm_protocol = fi->fib_protocol; if (fi->fib_priority) RTA_PUT(skb, RTA_PRIORITY, 4, &fi->fib_priority); -#ifdef CONFIG_NET_CLS_ROUTE - if (fi->fib_nh[0].nh_tclassid) - RTA_PUT(skb, RTA_FLOW, 4, &fi->fib_nh[0].nh_tclassid); -#endif if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0) goto rtattr_failure; if (fi->fib_prefsrc) @@ -975,6 +970,10 @@ fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, RTA_PUT(skb, RTA_GATEWAY, 4, &fi->fib_nh->nh_gw); if (fi->fib_nh->nh_oif) RTA_PUT(skb, RTA_OIF, sizeof(int), &fi->fib_nh->nh_oif); +#ifdef CONFIG_NET_CLS_ROUTE + if (fi->fib_nh[0].nh_tclassid) + RTA_PUT(skb, RTA_FLOW, 4, &fi->fib_nh[0].nh_tclassid); +#endif } #ifdef CONFIG_IP_ROUTE_MULTIPATH if (fi->fib_nhs > 1) { @@ -993,6 +992,10 @@ fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, nhp->rtnh_ifindex = nh->nh_oif; if (nh->nh_gw) RTA_PUT(skb, RTA_GATEWAY, 4, &nh->nh_gw); +#ifdef CONFIG_NET_CLS_ROUTE + if (nh->nh_tclassid) + RTA_PUT(skb, RTA_FLOW, 4, &nh->nh_tclassid); +#endif nhp->rtnh_len = skb->tail - (unsigned char*)nhp; } endfor_nexthops(fi); mp_head->rta_type = RTA_MULTIPATH; diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index d299c8e547d..9f4b752f5a3 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -1028,10 +1028,9 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im) * for deleted items allows change reports to use common code with * non-deleted or query-response MCA's. */ - pmc = kmalloc(sizeof(*pmc), GFP_KERNEL); + pmc = kzalloc(sizeof(*pmc), GFP_KERNEL); if (!pmc) return; - memset(pmc, 0, sizeof(*pmc)); spin_lock_bh(&im->lock); pmc->interface = im->interface; in_dev_hold(in_dev); @@ -1529,10 +1528,9 @@ static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode, psf_prev = psf; } if (!psf) { - psf = kmalloc(sizeof(*psf), GFP_ATOMIC); + psf = kzalloc(sizeof(*psf), GFP_ATOMIC); if (!psf) return -ENOBUFS; - memset(psf, 0, sizeof(*psf)); psf->sf_inaddr = *psfsrc; if (psf_prev) { psf_prev->sf_next = psf; @@ -2380,7 +2378,7 @@ static int igmp_mc_seq_open(struct inode *inode, struct file *file) { struct seq_file *seq; int rc = -ENOMEM; - struct igmp_mc_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct igmp_mc_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; @@ -2390,7 +2388,6 @@ static int igmp_mc_seq_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = s; - memset(s, 0, sizeof(*s)); out: return rc; out_kfree: @@ -2555,7 +2552,7 @@ static int igmp_mcf_seq_open(struct inode *inode, struct file *file) { struct seq_file *seq; int rc = -ENOMEM; - struct igmp_mcf_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct igmp_mcf_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; @@ -2565,7 +2562,6 @@ static int igmp_mcf_seq_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = s; - memset(s, 0, sizeof(*s)); out: return rc; out_kfree: diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 8e7e41b66c7..492858e6faf 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -909,11 +909,10 @@ static int __init inet_diag_init(void) sizeof(struct inet_diag_handler *)); int err = -ENOMEM; - inet_diag_table = kmalloc(inet_diag_table_size, GFP_KERNEL); + inet_diag_table = kzalloc(inet_diag_table_size, GFP_KERNEL); if (!inet_diag_table) goto out; - memset(inet_diag_table, 0, inet_diag_table_size); idiagnl = netlink_kernel_create(NETLINK_INET_DIAG, 0, inet_diag_rcv, THIS_MODULE); if (idiagnl == NULL) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 6ff9b10d956..0f9b3a31997 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -617,7 +617,6 @@ static int ipgre_rcv(struct sk_buff *skb) skb->mac.raw = skb->nh.raw; skb->nh.raw = __pskb_pull(skb, offset); skb_postpull_rcsum(skb, skb->h.raw, offset); - memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); skb->pkt_type = PACKET_HOST; #ifdef CONFIG_NET_IPGRE_BROADCAST if (MULTICAST(iph->daddr)) { diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index cbcae654462..406056edc02 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c @@ -256,7 +256,6 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb) if (!opt) { opt = &(IPCB(skb)->opt); - memset(opt, 0, sizeof(struct ip_options)); iph = skb->nh.raw; opt->optlen = ((struct iphdr *)iph)->ihl*4 - sizeof(struct iphdr); optptr = iph + sizeof(struct iphdr); diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 8a8b5cf2f7f..a0c28b2b756 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -410,11 +410,10 @@ static int ipcomp_init_state(struct xfrm_state *x) goto out; err = -ENOMEM; - ipcd = kmalloc(sizeof(*ipcd), GFP_KERNEL); + ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL); if (!ipcd) goto out; - memset(ipcd, 0, sizeof(*ipcd)); x->props.header_len = 0; if (x->props.mode) x->props.header_len += sizeof(struct iphdr); diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 3291d5192aa..76ab50b0d6e 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -487,7 +487,6 @@ static int ipip_rcv(struct sk_buff *skb) skb->mac.raw = skb->nh.raw; skb->nh.raw = skb->data; - memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); skb->protocol = htons(ETH_P_IP); skb->pkt_type = PACKET_HOST; diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index ba33f8621c6..9ccacf57f08 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1461,7 +1461,6 @@ int pim_rcv_v1(struct sk_buff * skb) skb_pull(skb, (u8*)encap - skb->data); skb->nh.iph = (struct iphdr *)skb->data; skb->dev = reg_dev; - memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); skb->protocol = htons(ETH_P_IP); skb->ip_summed = 0; skb->pkt_type = PACKET_HOST; @@ -1517,7 +1516,6 @@ static int pim_rcv(struct sk_buff * skb) skb_pull(skb, (u8*)encap - skb->data); skb->nh.iph = (struct iphdr *)skb->data; skb->dev = reg_dev; - memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); skb->protocol = htons(ETH_P_IP); skb->ip_summed = 0; skb->pkt_type = PACKET_HOST; diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c index f28ec688216..6a28fafe910 100644 --- a/net/ipv4/ipvs/ip_vs_ctl.c +++ b/net/ipv4/ipvs/ip_vs_ctl.c @@ -735,12 +735,11 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest, if (atype != RTN_LOCAL && atype != RTN_UNICAST) return -EINVAL; - dest = kmalloc(sizeof(struct ip_vs_dest), GFP_ATOMIC); + dest = kzalloc(sizeof(struct ip_vs_dest), GFP_ATOMIC); if (dest == NULL) { IP_VS_ERR("ip_vs_new_dest: kmalloc failed.\n"); return -ENOMEM; } - memset(dest, 0, sizeof(struct ip_vs_dest)); dest->protocol = svc->protocol; dest->vaddr = svc->addr; @@ -1050,14 +1049,12 @@ ip_vs_add_service(struct ip_vs_service_user *u, struct ip_vs_service **svc_p) goto out_mod_dec; } - svc = (struct ip_vs_service *) - kmalloc(sizeof(struct ip_vs_service), GFP_ATOMIC); + svc = kzalloc(sizeof(struct ip_vs_service), GFP_ATOMIC); if (svc == NULL) { IP_VS_DBG(1, "ip_vs_add_service: kmalloc failed.\n"); ret = -ENOMEM; goto out_err; } - memset(svc, 0, sizeof(struct ip_vs_service)); /* I'm the first user of the service */ atomic_set(&svc->usecnt, 1); @@ -1797,7 +1794,7 @@ static int ip_vs_info_open(struct inode *inode, struct file *file) { struct seq_file *seq; int rc = -ENOMEM; - struct ip_vs_iter *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct ip_vs_iter *s = kzalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; @@ -1808,7 +1805,6 @@ static int ip_vs_info_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = s; - memset(s, 0, sizeof(*s)); out: return rc; out_kfree: diff --git a/net/ipv4/ipvs/ip_vs_est.c b/net/ipv4/ipvs/ip_vs_est.c index 4c1940381ba..7d68b80c4c1 100644 --- a/net/ipv4/ipvs/ip_vs_est.c +++ b/net/ipv4/ipvs/ip_vs_est.c @@ -123,11 +123,10 @@ int ip_vs_new_estimator(struct ip_vs_stats *stats) { struct ip_vs_estimator *est; - est = kmalloc(sizeof(*est), GFP_KERNEL); + est = kzalloc(sizeof(*est), GFP_KERNEL); if (est == NULL) return -ENOMEM; - memset(est, 0, sizeof(*est)); est->stats = stats; est->last_conns = stats->conns; est->cps = stats->cps<<10; diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index cbffeae3f56..d994c5f5744 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -172,11 +172,10 @@ clusterip_config_init(struct ipt_clusterip_tgt_info *i, u_int32_t ip, struct clusterip_config *c; char buffer[16]; - c = kmalloc(sizeof(*c), GFP_ATOMIC); + c = kzalloc(sizeof(*c), GFP_ATOMIC); if (!c) return NULL; - memset(c, 0, sizeof(*c)); c->dev = dev; c->clusterip = ip; memcpy(&c->clustermac, &i->clustermac, ETH_ALEN); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index a891133f00e..f6f39e81429 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1640,10 +1640,9 @@ static int tcp_seq_open(struct inode *inode, struct file *file) if (unlikely(afinfo == NULL)) return -EINVAL; - s = kmalloc(sizeof(*s), GFP_KERNEL); + s = kzalloc(sizeof(*s), GFP_KERNEL); if (!s) return -ENOMEM; - memset(s, 0, sizeof(*s)); s->family = afinfo->family; s->seq_ops.start = tcp_seq_start; s->seq_ops.next = tcp_seq_next; diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 9bfcddad695..f136cec96d9 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1468,11 +1468,10 @@ static int udp_seq_open(struct inode *inode, struct file *file) struct udp_seq_afinfo *afinfo = PDE(inode)->data; struct seq_file *seq; int rc = -ENOMEM; - struct udp_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct udp_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; - memset(s, 0, sizeof(*s)); s->family = afinfo->family; s->seq_ops.start = udp_seq_start; s->seq_ops.next = udp_seq_next; diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c index f8d880beb12..13cafbe56ce 100644 --- a/net/ipv4/xfrm4_mode_tunnel.c +++ b/net/ipv4/xfrm4_mode_tunnel.c @@ -92,7 +92,6 @@ static int xfrm4_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) skb->mac.raw = memmove(skb->data - skb->mac_len, skb->mac.raw, skb->mac_len); skb->nh.raw = skb->data; - memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); err = 0; out: diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index bc77c0e1a94..84d7ebdb9d2 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -567,10 +567,9 @@ static inline struct ipv6_txoptions *create_tel(__u8 encap_limit) int opt_len = sizeof(*opt) + 8; - if (!(opt = kmalloc(opt_len, GFP_ATOMIC))) { + if (!(opt = kzalloc(opt_len, GFP_ATOMIC))) { return NULL; } - memset(opt, 0, opt_len); opt->tot_len = opt_len; opt->dst0opt = (struct ipv6_opt_hdr *) (opt + 1); opt->opt_nflen = 8; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index c56aeece2bf..836eecd7e62 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -380,7 +380,6 @@ static int ipip6_rcv(struct sk_buff *skb) secpath_reset(skb); skb->mac.raw = skb->nh.raw; skb->nh.raw = skb->data; - memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); IPCB(skb)->flags = 0; skb->protocol = htons(ETH_P_IPV6); skb->pkt_type = PACKET_HOST; diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 7fae48a53bf..17699eeb64d 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -308,7 +308,7 @@ static void irda_connect_response(struct irda_sock *self) IRDA_ASSERT(self != NULL, return;); - skb = dev_alloc_skb(64); + skb = alloc_skb(64, GFP_ATOMIC); if (skb == NULL) { IRDA_DEBUG(0, "%s() Unable to allocate sk_buff!\n", __FUNCTION__); diff --git a/net/irda/ircomm/ircomm_core.c b/net/irda/ircomm/ircomm_core.c index 9c4a902a9db..ad6b6af3dd9 100644 --- a/net/irda/ircomm/ircomm_core.c +++ b/net/irda/ircomm/ircomm_core.c @@ -115,12 +115,10 @@ struct ircomm_cb *ircomm_open(notify_t *notify, __u8 service_type, int line) IRDA_ASSERT(ircomm != NULL, return NULL;); - self = kmalloc(sizeof(struct ircomm_cb), GFP_ATOMIC); + self = kzalloc(sizeof(struct ircomm_cb), GFP_ATOMIC); if (self == NULL) return NULL; - memset(self, 0, sizeof(struct ircomm_cb)); - self->notify = *notify; self->magic = IRCOMM_MAGIC; diff --git a/net/irda/ircomm/ircomm_lmp.c b/net/irda/ircomm/ircomm_lmp.c index d9097207aed..959874b6451 100644 --- a/net/irda/ircomm/ircomm_lmp.c +++ b/net/irda/ircomm/ircomm_lmp.c @@ -81,7 +81,7 @@ static int ircomm_lmp_connect_response(struct ircomm_cb *self, /* Any userdata supplied? */ if (userdata == NULL) { - tx_skb = dev_alloc_skb(64); + tx_skb = alloc_skb(64, GFP_ATOMIC); if (!tx_skb) return -ENOMEM; @@ -115,7 +115,7 @@ static int ircomm_lmp_disconnect_request(struct ircomm_cb *self, IRDA_DEBUG(0, "%s()\n", __FUNCTION__ ); if (!userdata) { - tx_skb = dev_alloc_skb(64); + tx_skb = alloc_skb(64, GFP_ATOMIC); if (!tx_skb) return -ENOMEM; diff --git a/net/irda/ircomm/ircomm_param.c b/net/irda/ircomm/ircomm_param.c index 6009bab0509..a39f5735a90 100644 --- a/net/irda/ircomm/ircomm_param.c +++ b/net/irda/ircomm/ircomm_param.c @@ -121,7 +121,7 @@ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush) skb = self->ctrl_skb; if (!skb) { - skb = dev_alloc_skb(256); + skb = alloc_skb(256, GFP_ATOMIC); if (!skb) { spin_unlock_irqrestore(&self->spinlock, flags); return -ENOMEM; diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index b400f27851f..3bcdb467efc 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c @@ -379,12 +379,11 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) self = hashbin_lock_find(ircomm_tty, line, NULL); if (!self) { /* No, so make new instance */ - self = kmalloc(sizeof(struct ircomm_tty_cb), GFP_KERNEL); + self = kzalloc(sizeof(struct ircomm_tty_cb), GFP_KERNEL); if (self == NULL) { IRDA_ERROR("%s(), kmalloc failed!\n", __FUNCTION__); return -ENOMEM; } - memset(self, 0, sizeof(struct ircomm_tty_cb)); self->magic = IRCOMM_TTY_MAGIC; self->flow = FLOW_STOP; @@ -759,8 +758,9 @@ static int ircomm_tty_write(struct tty_struct *tty, } } else { /* Prepare a full sized frame */ - skb = dev_alloc_skb(self->max_data_size+ - self->max_header_size); + skb = alloc_skb(self->max_data_size+ + self->max_header_size, + GFP_ATOMIC); if (!skb) { spin_unlock_irqrestore(&self->spinlock, flags); return -ENOBUFS; diff --git a/net/irda/irda_device.c b/net/irda/irda_device.c index ba40e5495f5..7e7a31798d8 100644 --- a/net/irda/irda_device.c +++ b/net/irda/irda_device.c @@ -401,12 +401,10 @@ dongle_t *irda_device_dongle_init(struct net_device *dev, int type) } /* Allocate dongle info for this instance */ - dongle = kmalloc(sizeof(dongle_t), GFP_KERNEL); + dongle = kzalloc(sizeof(dongle_t), GFP_KERNEL); if (!dongle) goto out; - memset(dongle, 0, sizeof(dongle_t)); - /* Bind the registration info to this particular instance */ dongle->issue = reg; dongle->dev = dev; diff --git a/net/irda/iriap.c b/net/irda/iriap.c index a0472652a44..61128aa05b4 100644 --- a/net/irda/iriap.c +++ b/net/irda/iriap.c @@ -345,7 +345,7 @@ static void iriap_disconnect_request(struct iriap_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IAS_MAGIC, return;); - tx_skb = dev_alloc_skb(64); + tx_skb = alloc_skb(64, GFP_ATOMIC); if (tx_skb == NULL) { IRDA_DEBUG(0, "%s(), Could not allocate an sk_buff of length %d\n", __FUNCTION__, 64); @@ -396,7 +396,7 @@ int iriap_getvaluebyclass_request(struct iriap_cb *self, attr_len = strlen(attr); /* Up to IAS_MAX_ATTRIBNAME = 60 */ skb_len = self->max_header_size+2+name_len+1+attr_len+4; - tx_skb = dev_alloc_skb(skb_len); + tx_skb = alloc_skb(skb_len, GFP_ATOMIC); if (!tx_skb) return -ENOMEM; @@ -562,7 +562,8 @@ static void iriap_getvaluebyclass_response(struct iriap_cb *self, * value. We add 32 bytes because of the 6 bytes for the frame and * max 5 bytes for the value coding. */ - tx_skb = dev_alloc_skb(value->len + self->max_header_size + 32); + tx_skb = alloc_skb(value->len + self->max_header_size + 32, + GFP_ATOMIC); if (!tx_skb) return; @@ -700,7 +701,7 @@ void iriap_send_ack(struct iriap_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IAS_MAGIC, return;); - tx_skb = dev_alloc_skb(64); + tx_skb = alloc_skb(64, GFP_ATOMIC); if (!tx_skb) return; diff --git a/net/irda/iriap_event.c b/net/irda/iriap_event.c index a73607450de..da17395df05 100644 --- a/net/irda/iriap_event.c +++ b/net/irda/iriap_event.c @@ -365,7 +365,7 @@ static void state_r_disconnect(struct iriap_cb *self, IRIAP_EVENT event, switch (event) { case IAP_LM_CONNECT_INDICATION: - tx_skb = dev_alloc_skb(64); + tx_skb = alloc_skb(64, GFP_ATOMIC); if (tx_skb == NULL) { IRDA_WARNING("%s: unable to malloc!\n", __FUNCTION__); return; diff --git a/net/irda/irias_object.c b/net/irda/irias_object.c index 82e665c7999..a154b1d71c0 100644 --- a/net/irda/irias_object.c +++ b/net/irda/irias_object.c @@ -82,13 +82,12 @@ struct ias_object *irias_new_object( char *name, int id) IRDA_DEBUG( 4, "%s()\n", __FUNCTION__); - obj = kmalloc(sizeof(struct ias_object), GFP_ATOMIC); + obj = kzalloc(sizeof(struct ias_object), GFP_ATOMIC); if (obj == NULL) { IRDA_WARNING("%s(), Unable to allocate object!\n", __FUNCTION__); return NULL; } - memset(obj, 0, sizeof( struct ias_object)); obj->magic = IAS_OBJECT_MAGIC; obj->name = strndup(name, IAS_MAX_CLASSNAME); @@ -346,13 +345,12 @@ void irias_add_integer_attrib(struct ias_object *obj, char *name, int value, IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;); IRDA_ASSERT(name != NULL, return;); - attrib = kmalloc(sizeof(struct ias_attrib), GFP_ATOMIC); + attrib = kzalloc(sizeof(struct ias_attrib), GFP_ATOMIC); if (attrib == NULL) { IRDA_WARNING("%s: Unable to allocate attribute!\n", __FUNCTION__); return; } - memset(attrib, 0, sizeof( struct ias_attrib)); attrib->magic = IAS_ATTRIB_MAGIC; attrib->name = strndup(name, IAS_MAX_ATTRIBNAME); @@ -382,13 +380,12 @@ void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets, IRDA_ASSERT(name != NULL, return;); IRDA_ASSERT(octets != NULL, return;); - attrib = kmalloc(sizeof(struct ias_attrib), GFP_ATOMIC); + attrib = kzalloc(sizeof(struct ias_attrib), GFP_ATOMIC); if (attrib == NULL) { IRDA_WARNING("%s: Unable to allocate attribute!\n", __FUNCTION__); return; } - memset(attrib, 0, sizeof( struct ias_attrib)); attrib->magic = IAS_ATTRIB_MAGIC; attrib->name = strndup(name, IAS_MAX_ATTRIBNAME); @@ -416,13 +413,12 @@ void irias_add_string_attrib(struct ias_object *obj, char *name, char *value, IRDA_ASSERT(name != NULL, return;); IRDA_ASSERT(value != NULL, return;); - attrib = kmalloc(sizeof( struct ias_attrib), GFP_ATOMIC); + attrib = kzalloc(sizeof( struct ias_attrib), GFP_ATOMIC); if (attrib == NULL) { IRDA_WARNING("%s: Unable to allocate attribute!\n", __FUNCTION__); return; } - memset(attrib, 0, sizeof( struct ias_attrib)); attrib->magic = IAS_ATTRIB_MAGIC; attrib->name = strndup(name, IAS_MAX_ATTRIBNAME); @@ -443,12 +439,11 @@ struct ias_value *irias_new_integer_value(int integer) { struct ias_value *value; - value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC); + value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC); if (value == NULL) { IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__); return NULL; } - memset(value, 0, sizeof(struct ias_value)); value->type = IAS_INTEGER; value->len = 4; @@ -469,12 +464,11 @@ struct ias_value *irias_new_string_value(char *string) { struct ias_value *value; - value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC); + value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC); if (value == NULL) { IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__); return NULL; } - memset( value, 0, sizeof( struct ias_value)); value->type = IAS_STRING; value->charset = CS_ASCII; @@ -495,12 +489,11 @@ struct ias_value *irias_new_octseq_value(__u8 *octseq , int len) { struct ias_value *value; - value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC); + value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC); if (value == NULL) { IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__); return NULL; } - memset(value, 0, sizeof(struct ias_value)); value->type = IAS_OCT_SEQ; /* Check length */ @@ -522,12 +515,11 @@ struct ias_value *irias_new_missing_value(void) { struct ias_value *value; - value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC); + value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC); if (value == NULL) { IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__); return NULL; } - memset(value, 0, sizeof(struct ias_value)); value->type = IAS_MISSING; value->len = 0; diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c index bd659dd545a..7dd0a2fe1d2 100644 --- a/net/irda/irlan/irlan_common.c +++ b/net/irda/irlan/irlan_common.c @@ -636,7 +636,7 @@ void irlan_get_provider_info(struct irlan_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); - skb = dev_alloc_skb(64); + skb = alloc_skb(64, GFP_ATOMIC); if (!skb) return; @@ -668,7 +668,7 @@ void irlan_open_data_channel(struct irlan_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); - skb = dev_alloc_skb(64); + skb = alloc_skb(64, GFP_ATOMIC); if (!skb) return; @@ -704,7 +704,7 @@ void irlan_close_data_channel(struct irlan_cb *self) if (self->client.tsap_ctrl == NULL) return; - skb = dev_alloc_skb(64); + skb = alloc_skb(64, GFP_ATOMIC); if (!skb) return; @@ -739,7 +739,7 @@ static void irlan_open_unicast_addr(struct irlan_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); - skb = dev_alloc_skb(128); + skb = alloc_skb(128, GFP_ATOMIC); if (!skb) return; @@ -777,7 +777,7 @@ void irlan_set_broadcast_filter(struct irlan_cb *self, int status) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); - skb = dev_alloc_skb(128); + skb = alloc_skb(128, GFP_ATOMIC); if (!skb) return; @@ -816,7 +816,7 @@ void irlan_set_multicast_filter(struct irlan_cb *self, int status) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); - skb = dev_alloc_skb(128); + skb = alloc_skb(128, GFP_ATOMIC); if (!skb) return; @@ -856,7 +856,7 @@ static void irlan_get_unicast_addr(struct irlan_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); - skb = dev_alloc_skb(128); + skb = alloc_skb(128, GFP_ATOMIC); if (!skb) return; @@ -891,7 +891,7 @@ void irlan_get_media_char(struct irlan_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); - skb = dev_alloc_skb(64); + skb = alloc_skb(64, GFP_ATOMIC); if (!skb) return; diff --git a/net/irda/irlan/irlan_provider.c b/net/irda/irlan/irlan_provider.c index 39c202d1c37..9c0df86044d 100644 --- a/net/irda/irlan/irlan_provider.c +++ b/net/irda/irlan/irlan_provider.c @@ -296,7 +296,7 @@ void irlan_provider_send_reply(struct irlan_cb *self, int command, IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); - skb = dev_alloc_skb(128); + skb = alloc_skb(128, GFP_ATOMIC); if (!skb) return; diff --git a/net/irda/irlap.c b/net/irda/irlap.c index cade355ac8a..e7852a07495 100644 --- a/net/irda/irlap.c +++ b/net/irda/irlap.c @@ -116,11 +116,10 @@ struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos, IRDA_DEBUG(4, "%s()\n", __FUNCTION__); /* Initialize the irlap structure. */ - self = kmalloc(sizeof(struct irlap_cb), GFP_KERNEL); + self = kzalloc(sizeof(struct irlap_cb), GFP_KERNEL); if (self == NULL) return NULL; - memset(self, 0, sizeof(struct irlap_cb)); self->magic = LAP_MAGIC; /* Make a binding between the layers */ @@ -882,7 +881,7 @@ static void irlap_change_speed(struct irlap_cb *self, __u32 speed, int now) /* Change speed now, or just piggyback speed on frames */ if (now) { /* Send down empty frame to trigger speed change */ - skb = dev_alloc_skb(0); + skb = alloc_skb(0, GFP_ATOMIC); if (skb) irlap_queue_xmit(self, skb); } @@ -1222,7 +1221,7 @@ static int irlap_seq_open(struct inode *inode, struct file *file) { struct seq_file *seq; int rc = -ENOMEM; - struct irlap_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct irlap_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; @@ -1238,7 +1237,6 @@ static int irlap_seq_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = s; - memset(s, 0, sizeof(*s)); out: return rc; out_kfree: diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c index 3e9a06abbdd..ccb983bf0f4 100644 --- a/net/irda/irlap_frame.c +++ b/net/irda/irlap_frame.c @@ -117,7 +117,7 @@ void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos) IRDA_ASSERT(self->magic == LAP_MAGIC, return;); /* Allocate frame */ - tx_skb = dev_alloc_skb(64); + tx_skb = alloc_skb(64, GFP_ATOMIC); if (!tx_skb) return; @@ -210,7 +210,7 @@ void irlap_send_ua_response_frame(struct irlap_cb *self, struct qos_info *qos) IRDA_ASSERT(self->magic == LAP_MAGIC, return;); /* Allocate frame */ - tx_skb = dev_alloc_skb(64); + tx_skb = alloc_skb(64, GFP_ATOMIC); if (!tx_skb) return; @@ -250,7 +250,7 @@ void irlap_send_dm_frame( struct irlap_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == LAP_MAGIC, return;); - tx_skb = dev_alloc_skb(32); + tx_skb = alloc_skb(32, GFP_ATOMIC); if (!tx_skb) return; @@ -282,7 +282,7 @@ void irlap_send_disc_frame(struct irlap_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == LAP_MAGIC, return;); - tx_skb = dev_alloc_skb(16); + tx_skb = alloc_skb(16, GFP_ATOMIC); if (!tx_skb) return; @@ -315,7 +315,7 @@ void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s, IRDA_ASSERT(self->magic == LAP_MAGIC, return;); IRDA_ASSERT(discovery != NULL, return;); - tx_skb = dev_alloc_skb(64); + tx_skb = alloc_skb(64, GFP_ATOMIC); if (!tx_skb) return; @@ -422,11 +422,10 @@ static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self, return; } - if ((discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC)) == NULL) { + if ((discovery = kzalloc(sizeof(discovery_t), GFP_ATOMIC)) == NULL) { IRDA_WARNING("%s: kmalloc failed!\n", __FUNCTION__); return; } - memset(discovery, 0, sizeof(discovery_t)); discovery->data.daddr = info->daddr; discovery->data.saddr = self->saddr; @@ -576,7 +575,7 @@ void irlap_send_rr_frame(struct irlap_cb *self, int command) struct sk_buff *tx_skb; __u8 *frame; - tx_skb = dev_alloc_skb(16); + tx_skb = alloc_skb(16, GFP_ATOMIC); if (!tx_skb) return; @@ -601,7 +600,7 @@ void irlap_send_rd_frame(struct irlap_cb *self) struct sk_buff *tx_skb; __u8 *frame; - tx_skb = dev_alloc_skb(16); + tx_skb = alloc_skb(16, GFP_ATOMIC); if (!tx_skb) return; @@ -1215,7 +1214,7 @@ void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr, struct test_frame *frame; __u8 *info; - tx_skb = dev_alloc_skb(cmd->len+sizeof(struct test_frame)); + tx_skb = alloc_skb(cmd->len+sizeof(struct test_frame), GFP_ATOMIC); if (!tx_skb) return; diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c index 129ad64c15b..c440913dee1 100644 --- a/net/irda/irlmp.c +++ b/net/irda/irlmp.c @@ -78,10 +78,9 @@ int __init irlmp_init(void) { IRDA_DEBUG(1, "%s()\n", __FUNCTION__); /* Initialize the irlmp structure. */ - irlmp = kmalloc( sizeof(struct irlmp_cb), GFP_KERNEL); + irlmp = kzalloc( sizeof(struct irlmp_cb), GFP_KERNEL); if (irlmp == NULL) return -ENOMEM; - memset(irlmp, 0, sizeof(struct irlmp_cb)); irlmp->magic = LMP_MAGIC; @@ -160,12 +159,11 @@ struct lsap_cb *irlmp_open_lsap(__u8 slsap_sel, notify_t *notify, __u8 pid) return NULL; /* Allocate new instance of a LSAP connection */ - self = kmalloc(sizeof(struct lsap_cb), GFP_ATOMIC); + self = kzalloc(sizeof(struct lsap_cb), GFP_ATOMIC); if (self == NULL) { IRDA_ERROR("%s: can't allocate memory\n", __FUNCTION__); return NULL; } - memset(self, 0, sizeof(struct lsap_cb)); self->magic = LMP_LSAP_MAGIC; self->slsap_sel = slsap_sel; @@ -288,12 +286,11 @@ void irlmp_register_link(struct irlap_cb *irlap, __u32 saddr, notify_t *notify) /* * Allocate new instance of a LSAP connection */ - lap = kmalloc(sizeof(struct lap_cb), GFP_KERNEL); + lap = kzalloc(sizeof(struct lap_cb), GFP_KERNEL); if (lap == NULL) { IRDA_ERROR("%s: unable to kmalloc\n", __FUNCTION__); return; } - memset(lap, 0, sizeof(struct lap_cb)); lap->irlap = irlap; lap->magic = LMP_LAP_MAGIC; @@ -395,7 +392,7 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel, /* Any userdata? */ if (tx_skb == NULL) { - tx_skb = dev_alloc_skb(64); + tx_skb = alloc_skb(64, GFP_ATOMIC); if (!tx_skb) return -ENOMEM; diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c index e53bf9e0053..a1e502ff907 100644 --- a/net/irda/irnet/irnet_ppp.c +++ b/net/irda/irnet/irnet_ppp.c @@ -476,11 +476,10 @@ dev_irnet_open(struct inode * inode, #endif /* SECURE_DEVIRNET */ /* Allocate a private structure for this IrNET instance */ - ap = kmalloc(sizeof(*ap), GFP_KERNEL); + ap = kzalloc(sizeof(*ap), GFP_KERNEL); DABORT(ap == NULL, -ENOMEM, FS_ERROR, "Can't allocate struct irnet...\n"); /* initialize the irnet structure */ - memset(ap, 0, sizeof(*ap)); ap->file = file; /* PPP channel setup */ diff --git a/net/irda/irttp.c b/net/irda/irttp.c index 49c51c5f1a8..42acf1cde73 100644 --- a/net/irda/irttp.c +++ b/net/irda/irttp.c @@ -85,10 +85,9 @@ static pi_param_info_t param_info = { pi_major_call_table, 1, 0x0f, 4 }; */ int __init irttp_init(void) { - irttp = kmalloc(sizeof(struct irttp_cb), GFP_KERNEL); + irttp = kzalloc(sizeof(struct irttp_cb), GFP_KERNEL); if (irttp == NULL) return -ENOMEM; - memset(irttp, 0, sizeof(struct irttp_cb)); irttp->magic = TTP_MAGIC; @@ -306,7 +305,8 @@ static inline void irttp_fragment_skb(struct tsap_cb *self, IRDA_DEBUG(2, "%s(), fragmenting ...\n", __FUNCTION__); /* Make new segment */ - frag = dev_alloc_skb(self->max_seg_size+self->max_header_size); + frag = alloc_skb(self->max_seg_size+self->max_header_size, + GFP_ATOMIC); if (!frag) return; @@ -389,12 +389,11 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify) return NULL; } - self = kmalloc(sizeof(struct tsap_cb), GFP_ATOMIC); + self = kzalloc(sizeof(struct tsap_cb), GFP_ATOMIC); if (self == NULL) { IRDA_DEBUG(0, "%s(), unable to kmalloc!\n", __FUNCTION__); return NULL; } - memset(self, 0, sizeof(struct tsap_cb)); spin_lock_init(&self->lock); /* Initialise todo timer */ @@ -805,7 +804,7 @@ static inline void irttp_give_credit(struct tsap_cb *self) self->send_credit, self->avail_credit, self->remote_credit); /* Give credit to peer */ - tx_skb = dev_alloc_skb(64); + tx_skb = alloc_skb(64, GFP_ATOMIC); if (!tx_skb) return; @@ -1094,7 +1093,7 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel, /* Any userdata supplied? */ if (userdata == NULL) { - tx_skb = dev_alloc_skb(64); + tx_skb = alloc_skb(64, GFP_ATOMIC); if (!tx_skb) return -ENOMEM; @@ -1342,7 +1341,7 @@ int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size, /* Any userdata supplied? */ if (userdata == NULL) { - tx_skb = dev_alloc_skb(64); + tx_skb = alloc_skb(64, GFP_ATOMIC); if (!tx_skb) return -ENOMEM; @@ -1541,7 +1540,7 @@ int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *userdata, if (!userdata) { struct sk_buff *tx_skb; - tx_skb = dev_alloc_skb(64); + tx_skb = alloc_skb(64, GFP_ATOMIC); if (!tx_skb) return -ENOMEM; @@ -1876,7 +1875,7 @@ static int irttp_seq_open(struct inode *inode, struct file *file) int rc = -ENOMEM; struct irttp_iter_state *s; - s = kmalloc(sizeof(*s), GFP_KERNEL); + s = kzalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; @@ -1886,7 +1885,6 @@ static int irttp_seq_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = s; - memset(s, 0, sizeof(*s)); out: return rc; out_kfree: diff --git a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c index aea6616cea3..d504eed416f 100644 --- a/net/lapb/lapb_iface.c +++ b/net/lapb/lapb_iface.c @@ -115,14 +115,12 @@ static struct lapb_cb *lapb_devtostruct(struct net_device *dev) */ static struct lapb_cb *lapb_create_cb(void) { - struct lapb_cb *lapb = kmalloc(sizeof(*lapb), GFP_ATOMIC); + struct lapb_cb *lapb = kzalloc(sizeof(*lapb), GFP_ATOMIC); if (!lapb) goto out; - memset(lapb, 0x00, sizeof(*lapb)); - skb_queue_head_init(&lapb->write_queue); skb_queue_head_init(&lapb->ack_queue); diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c index bd242a49514..d12413cff5b 100644 --- a/net/llc/llc_core.c +++ b/net/llc/llc_core.c @@ -33,10 +33,9 @@ unsigned char llc_station_mac_sa[ETH_ALEN]; */ static struct llc_sap *llc_sap_alloc(void) { - struct llc_sap *sap = kmalloc(sizeof(*sap), GFP_ATOMIC); + struct llc_sap *sap = kzalloc(sizeof(*sap), GFP_ATOMIC); if (sap) { - memset(sap, 0, sizeof(*sap)); sap->state = LLC_SAP_STATE_ACTIVE; memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN); rwlock_init(&sap->sk_list.lock); diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 55c0adc8f11..b85c1f9f128 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -562,10 +562,9 @@ static int netlink_alloc_groups(struct sock *sk) if (err) return err; - nlk->groups = kmalloc(NLGRPSZ(groups), GFP_KERNEL); + nlk->groups = kzalloc(NLGRPSZ(groups), GFP_KERNEL); if (nlk->groups == NULL) return -ENOMEM; - memset(nlk->groups, 0, NLGRPSZ(groups)); nlk->ngroups = groups; return 0; } @@ -1393,11 +1392,10 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, struct sock *sk; struct netlink_sock *nlk; - cb = kmalloc(sizeof(*cb), GFP_KERNEL); + cb = kzalloc(sizeof(*cb), GFP_KERNEL); if (cb == NULL) return -ENOBUFS; - memset(cb, 0, sizeof(*cb)); cb->dump = dump; cb->done = done; cb->nlh = nlh; @@ -1668,7 +1666,7 @@ static int netlink_seq_open(struct inode *inode, struct file *file) struct nl_seq_iter *iter; int err; - iter = kmalloc(sizeof(*iter), GFP_KERNEL); + iter = kzalloc(sizeof(*iter), GFP_KERNEL); if (!iter) return -ENOMEM; @@ -1678,7 +1676,6 @@ static int netlink_seq_open(struct inode *inode, struct file *file) return err; } - memset(iter, 0, sizeof(*iter)); seq = file->private_data; seq->private = iter; return 0; @@ -1747,15 +1744,13 @@ static int __init netlink_proto_init(void) if (sizeof(struct netlink_skb_parms) > sizeof(dummy_skb->cb)) netlink_skb_parms_too_large(); - nl_table = kmalloc(sizeof(*nl_table) * MAX_LINKS, GFP_KERNEL); + nl_table = kcalloc(MAX_LINKS, sizeof(*nl_table), GFP_KERNEL); if (!nl_table) { enomem: printk(KERN_CRIT "netlink_init: Cannot allocate nl_table\n"); return -ENOMEM; } - memset(nl_table, 0, sizeof(*nl_table) * MAX_LINKS); - if (num_physpages >= (128 * 1024)) max = num_physpages >> (21 - PAGE_SHIFT); else diff --git a/net/rxrpc/connection.c b/net/rxrpc/connection.c index 573b572f8f9..93d2c55ad2d 100644 --- a/net/rxrpc/connection.c +++ b/net/rxrpc/connection.c @@ -58,13 +58,12 @@ static inline int __rxrpc_create_connection(struct rxrpc_peer *peer, _enter("%p",peer); /* allocate and initialise a connection record */ - conn = kmalloc(sizeof(struct rxrpc_connection), GFP_KERNEL); + conn = kzalloc(sizeof(struct rxrpc_connection), GFP_KERNEL); if (!conn) { _leave(" = -ENOMEM"); return -ENOMEM; } - memset(conn, 0, sizeof(struct rxrpc_connection)); atomic_set(&conn->usage, 1); INIT_LIST_HEAD(&conn->link); @@ -535,13 +534,12 @@ int rxrpc_conn_newmsg(struct rxrpc_connection *conn, return -EINVAL; } - msg = kmalloc(sizeof(struct rxrpc_message), alloc_flags); + msg = kzalloc(sizeof(struct rxrpc_message), alloc_flags); if (!msg) { _leave(" = -ENOMEM"); return -ENOMEM; } - memset(msg, 0, sizeof(*msg)); atomic_set(&msg->usage, 1); INIT_LIST_HEAD(&msg->link); diff --git a/net/rxrpc/peer.c b/net/rxrpc/peer.c index ed38f5b17c1..8a275157a3b 100644 --- a/net/rxrpc/peer.c +++ b/net/rxrpc/peer.c @@ -58,13 +58,12 @@ static int __rxrpc_create_peer(struct rxrpc_transport *trans, __be32 addr, _enter("%p,%08x", trans, ntohl(addr)); /* allocate and initialise a peer record */ - peer = kmalloc(sizeof(struct rxrpc_peer), GFP_KERNEL); + peer = kzalloc(sizeof(struct rxrpc_peer), GFP_KERNEL); if (!peer) { _leave(" = -ENOMEM"); return -ENOMEM; } - memset(peer, 0, sizeof(struct rxrpc_peer)); atomic_set(&peer->usage, 1); INIT_LIST_HEAD(&peer->link); diff --git a/net/rxrpc/transport.c b/net/rxrpc/transport.c index dbe6105e83a..465efc86fcc 100644 --- a/net/rxrpc/transport.c +++ b/net/rxrpc/transport.c @@ -68,11 +68,10 @@ int rxrpc_create_transport(unsigned short port, _enter("%hu", port); - trans = kmalloc(sizeof(struct rxrpc_transport), GFP_KERNEL); + trans = kzalloc(sizeof(struct rxrpc_transport), GFP_KERNEL); if (!trans) return -ENOMEM; - memset(trans, 0, sizeof(struct rxrpc_transport)); atomic_set(&trans->usage, 1); INIT_LIST_HEAD(&trans->services); INIT_LIST_HEAD(&trans->link); @@ -312,13 +311,12 @@ static int rxrpc_incoming_msg(struct rxrpc_transport *trans, _enter(""); - msg = kmalloc(sizeof(struct rxrpc_message), GFP_KERNEL); + msg = kzalloc(sizeof(struct rxrpc_message), GFP_KERNEL); if (!msg) { _leave(" = -ENOMEM"); return -ENOMEM; } - memset(msg, 0, sizeof(*msg)); atomic_set(&msg->usage, 1); list_add_tail(&msg->link,msgq); diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 9affeeedf10..a2587b52e53 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -312,10 +312,9 @@ struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est, } *err = -ENOMEM; - a = kmalloc(sizeof(*a), GFP_KERNEL); + a = kzalloc(sizeof(*a), GFP_KERNEL); if (a == NULL) goto err_mod; - memset(a, 0, sizeof(*a)); /* backward compatibility for policer */ if (name == NULL) @@ -492,10 +491,9 @@ tcf_action_get_1(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int *err) index = *(int *)RTA_DATA(tb[TCA_ACT_INDEX - 1]); *err = -ENOMEM; - a = kmalloc(sizeof(struct tc_action), GFP_KERNEL); + a = kzalloc(sizeof(struct tc_action), GFP_KERNEL); if (a == NULL) return NULL; - memset(a, 0, sizeof(struct tc_action)); *err = -EINVAL; a->ops = tc_lookup_action(tb[TCA_ACT_KIND - 1]); @@ -531,12 +529,11 @@ static struct tc_action *create_a(int i) { struct tc_action *act; - act = kmalloc(sizeof(*act), GFP_KERNEL); + act = kzalloc(sizeof(*act), GFP_KERNEL); if (act == NULL) { printk("create_a: failed to alloc!\n"); return NULL; } - memset(act, 0, sizeof(*act)); act->order = i; return act; } diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 58b3a865204..f257475e0e0 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -209,10 +209,9 @@ tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,int bind, int ref) s = sizeof(*opt) + p->nkeys * sizeof(struct tc_pedit_key); /* netlink spinlocks held above us - must use ATOMIC */ - opt = kmalloc(s, GFP_ATOMIC); + opt = kzalloc(s, GFP_ATOMIC); if (opt == NULL) return -ENOBUFS; - memset(opt, 0, s); memcpy(opt->keys, p->keys, p->nkeys * sizeof(struct tc_pedit_key)); opt->index = p->index; diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 47e00bd9625..da905d7b4b4 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -196,10 +196,9 @@ static int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est, return ret; } - p = kmalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc(sizeof(*p), GFP_KERNEL); if (p == NULL) return -ENOMEM; - memset(p, 0, sizeof(*p)); ret = ACT_P_CREATED; p->refcnt = 1; @@ -429,11 +428,10 @@ struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est) return p; } - p = kmalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc(sizeof(*p), GFP_KERNEL); if (p == NULL) return NULL; - memset(p, 0, sizeof(*p)); p->refcnt = 1; spin_lock_init(&p->lock); p->stats_lock = &p->lock; diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index 61507f006b1..86cac49a053 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -178,19 +178,17 @@ static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle, err = -ENOBUFS; if (head == NULL) { - head = kmalloc(sizeof(*head), GFP_KERNEL); + head = kzalloc(sizeof(*head), GFP_KERNEL); if (head == NULL) goto errout; - memset(head, 0, sizeof(*head)); INIT_LIST_HEAD(&head->flist); tp->root = head; } - f = kmalloc(sizeof(*f), GFP_KERNEL); + f = kzalloc(sizeof(*f), GFP_KERNEL); if (f == NULL) goto errout; - memset(f, 0, sizeof(*f)); err = -EINVAL; if (handle) diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index d41de91fc4f..e6973d9b686 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -267,20 +267,18 @@ static int fw_change(struct tcf_proto *tp, unsigned long base, return -EINVAL; if (head == NULL) { - head = kmalloc(sizeof(struct fw_head), GFP_KERNEL); + head = kzalloc(sizeof(struct fw_head), GFP_KERNEL); if (head == NULL) return -ENOBUFS; - memset(head, 0, sizeof(*head)); tcf_tree_lock(tp); tp->root = head; tcf_tree_unlock(tp); } - f = kmalloc(sizeof(struct fw_filter), GFP_KERNEL); + f = kzalloc(sizeof(struct fw_filter), GFP_KERNEL); if (f == NULL) return -ENOBUFS; - memset(f, 0, sizeof(*f)); f->id = handle; diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index c2e71900f7b..d3aea730d4c 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -396,10 +396,9 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base, h1 = to_hash(nhandle); if ((b = head->table[h1]) == NULL) { err = -ENOBUFS; - b = kmalloc(sizeof(struct route4_bucket), GFP_KERNEL); + b = kzalloc(sizeof(struct route4_bucket), GFP_KERNEL); if (b == NULL) goto errout; - memset(b, 0, sizeof(*b)); tcf_tree_lock(tp); head->table[h1] = b; @@ -475,20 +474,18 @@ static int route4_change(struct tcf_proto *tp, unsigned long base, err = -ENOBUFS; if (head == NULL) { - head = kmalloc(sizeof(struct route4_head), GFP_KERNEL); + head = kzalloc(sizeof(struct route4_head), GFP_KERNEL); if (head == NULL) goto errout; - memset(head, 0, sizeof(struct route4_head)); tcf_tree_lock(tp); tp->root = head; tcf_tree_unlock(tp); } - f = kmalloc(sizeof(struct route4_filter), GFP_KERNEL); + f = kzalloc(sizeof(struct route4_filter), GFP_KERNEL); if (f == NULL) goto errout; - memset(f, 0, sizeof(*f)); err = route4_set_parms(tp, base, f, handle, head, tb, tca[TCA_RATE-1], 1); diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index ba874197162..6e230ecfba0 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -240,9 +240,8 @@ static int rsvp_init(struct tcf_proto *tp) { struct rsvp_head *data; - data = kmalloc(sizeof(struct rsvp_head), GFP_KERNEL); + data = kzalloc(sizeof(struct rsvp_head), GFP_KERNEL); if (data) { - memset(data, 0, sizeof(struct rsvp_head)); tp->root = data; return 0; } @@ -446,11 +445,10 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, goto errout2; err = -ENOBUFS; - f = kmalloc(sizeof(struct rsvp_filter), GFP_KERNEL); + f = kzalloc(sizeof(struct rsvp_filter), GFP_KERNEL); if (f == NULL) goto errout2; - memset(f, 0, sizeof(*f)); h2 = 16; if (tb[TCA_RSVP_SRC-1]) { err = -EINVAL; @@ -532,10 +530,9 @@ insert: /* No session found. Create new one. */ err = -ENOBUFS; - s = kmalloc(sizeof(struct rsvp_session), GFP_KERNEL); + s = kzalloc(sizeof(struct rsvp_session), GFP_KERNEL); if (s == NULL) goto errout; - memset(s, 0, sizeof(*s)); memcpy(s->dst, dst, sizeof(s->dst)); if (pinfo) { diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index 7870e7bb0ba..5af8a59e150 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -148,11 +148,10 @@ static int tcindex_init(struct tcf_proto *tp) struct tcindex_data *p; DPRINTK("tcindex_init(tp %p)\n",tp); - p = kmalloc(sizeof(struct tcindex_data),GFP_KERNEL); + p = kzalloc(sizeof(struct tcindex_data),GFP_KERNEL); if (!p) return -ENOMEM; - memset(p, 0, sizeof(*p)); p->mask = 0xffff; p->hash = DEFAULT_HASH_SIZE; p->fall_through = 1; @@ -296,16 +295,14 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, err = -ENOMEM; if (!cp.perfect && !cp.h) { if (valid_perfect_hash(&cp)) { - cp.perfect = kmalloc(cp.hash * sizeof(*r), GFP_KERNEL); + cp.perfect = kcalloc(cp.hash, sizeof(*r), GFP_KERNEL); if (!cp.perfect) goto errout; - memset(cp.perfect, 0, cp.hash * sizeof(*r)); balloc = 1; } else { - cp.h = kmalloc(cp.hash * sizeof(f), GFP_KERNEL); + cp.h = kcalloc(cp.hash, sizeof(f), GFP_KERNEL); if (!cp.h) goto errout; - memset(cp.h, 0, cp.hash * sizeof(f)); balloc = 2; } } @@ -316,10 +313,9 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, r = tcindex_lookup(&cp, handle) ? : &new_filter_result; if (r == &new_filter_result) { - f = kmalloc(sizeof(*f), GFP_KERNEL); + f = kzalloc(sizeof(*f), GFP_KERNEL); if (!f) goto errout_alloc; - memset(f, 0, sizeof(*f)); } if (tb[TCA_TCINDEX_CLASSID-1]) { diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index d712edcd1bc..eea36696674 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -307,23 +307,21 @@ static int u32_init(struct tcf_proto *tp) if (tp_c->q == tp->q) break; - root_ht = kmalloc(sizeof(*root_ht), GFP_KERNEL); + root_ht = kzalloc(sizeof(*root_ht), GFP_KERNEL); if (root_ht == NULL) return -ENOBUFS; - memset(root_ht, 0, sizeof(*root_ht)); root_ht->divisor = 0; root_ht->refcnt++; root_ht->handle = tp_c ? gen_new_htid(tp_c) : 0x80000000; root_ht->prio = tp->prio; if (tp_c == NULL) { - tp_c = kmalloc(sizeof(*tp_c), GFP_KERNEL); + tp_c = kzalloc(sizeof(*tp_c), GFP_KERNEL); if (tp_c == NULL) { kfree(root_ht); return -ENOBUFS; } - memset(tp_c, 0, sizeof(*tp_c)); tp_c->q = tp->q; tp_c->next = u32_list; u32_list = tp_c; @@ -571,10 +569,9 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, if (handle == 0) return -ENOMEM; } - ht = kmalloc(sizeof(*ht) + divisor*sizeof(void*), GFP_KERNEL); + ht = kzalloc(sizeof(*ht) + divisor*sizeof(void*), GFP_KERNEL); if (ht == NULL) return -ENOBUFS; - memset(ht, 0, sizeof(*ht) + divisor*sizeof(void*)); ht->tp_c = tp_c; ht->refcnt = 0; ht->divisor = divisor; @@ -617,18 +614,16 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, s = RTA_DATA(tb[TCA_U32_SEL-1]); - n = kmalloc(sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key), GFP_KERNEL); + n = kzalloc(sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key), GFP_KERNEL); if (n == NULL) return -ENOBUFS; - memset(n, 0, sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key)); #ifdef CONFIG_CLS_U32_PERF - n->pf = kmalloc(sizeof(struct tc_u32_pcnt) + s->nkeys*sizeof(u64), GFP_KERNEL); + n->pf = kzalloc(sizeof(struct tc_u32_pcnt) + s->nkeys*sizeof(u64), GFP_KERNEL); if (n->pf == NULL) { kfree(n); return -ENOBUFS; } - memset(n->pf, 0, sizeof(struct tc_u32_pcnt) + s->nkeys*sizeof(u64)); #endif memcpy(&n->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key)); diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 698372954f4..61e3b740ab1 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -773,10 +773,9 @@ static int em_meta_change(struct tcf_proto *tp, void *data, int len, TCF_META_ID(hdr->right.kind) > TCF_META_ID_MAX) goto errout; - meta = kmalloc(sizeof(*meta), GFP_KERNEL); + meta = kzalloc(sizeof(*meta), GFP_KERNEL); if (meta == NULL) goto errout; - memset(meta, 0, sizeof(*meta)); memcpy(&meta->lvalue.hdr, &hdr->left, sizeof(hdr->left)); memcpy(&meta->rvalue.hdr, &hdr->right, sizeof(hdr->right)); diff --git a/net/sched/ematch.c b/net/sched/ematch.c index 2405a86093a..0fd0768a17c 100644 --- a/net/sched/ematch.c +++ b/net/sched/ematch.c @@ -321,10 +321,9 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta, list_len = RTA_PAYLOAD(rt_list); matches_len = tree_hdr->nmatches * sizeof(*em); - tree->matches = kmalloc(matches_len, GFP_KERNEL); + tree->matches = kzalloc(matches_len, GFP_KERNEL); if (tree->matches == NULL) goto errout; - memset(tree->matches, 0, matches_len); /* We do not use rtattr_parse_nested here because the maximum * number of attributes is unknown. This saves us the allocation diff --git a/net/sched/estimator.c b/net/sched/estimator.c index 5d3ae03e22a..0ebc98e9be2 100644 --- a/net/sched/estimator.c +++ b/net/sched/estimator.c @@ -139,11 +139,10 @@ int qdisc_new_estimator(struct tc_stats *stats, spinlock_t *stats_lock, struct r if (parm->interval < -2 || parm->interval > 3) return -EINVAL; - est = kmalloc(sizeof(*est), GFP_KERNEL); + est = kzalloc(sizeof(*est), GFP_KERNEL); if (est == NULL) return -ENOBUFS; - memset(est, 0, sizeof(*est)); est->interval = parm->interval + 2; est->stats = stats; est->stats_lock = stats_lock; diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 80b7f6a8d00..bac881bfe36 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -1926,10 +1926,9 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t } err = -ENOBUFS; - cl = kmalloc(sizeof(*cl), GFP_KERNEL); + cl = kzalloc(sizeof(*cl), GFP_KERNEL); if (cl == NULL) goto failure; - memset(cl, 0, sizeof(*cl)); cl->R_tab = rtab; rtab = NULL; cl->refcnt = 1; diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index d735f51686a..0834c2ee917 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -432,10 +432,9 @@ struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops) size = QDISC_ALIGN(sizeof(*sch)); size += ops->priv_size + (QDISC_ALIGNTO - 1); - p = kmalloc(size, GFP_KERNEL); + p = kzalloc(size, GFP_KERNEL); if (!p) goto errout; - memset(p, 0, size); sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p); sch->padded = (char *) sch - (char *) p; diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index 0cafdd5feb1..18e81a8ffb0 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c @@ -406,10 +406,9 @@ static inline int gred_change_vq(struct Qdisc *sch, int dp, struct gred_sched_data *q; if (table->tab[dp] == NULL) { - table->tab[dp] = kmalloc(sizeof(*q), GFP_KERNEL); + table->tab[dp] = kzalloc(sizeof(*q), GFP_KERNEL); if (table->tab[dp] == NULL) return -ENOMEM; - memset(table->tab[dp], 0, sizeof(*q)); } q = table->tab[dp]; diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 6b1b4a981e8..6a6735a2ed3 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -1123,10 +1123,9 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (rsc == NULL && fsc == NULL) return -EINVAL; - cl = kmalloc(sizeof(struct hfsc_class), GFP_KERNEL); + cl = kzalloc(sizeof(struct hfsc_class), GFP_KERNEL); if (cl == NULL) return -ENOBUFS; - memset(cl, 0, sizeof(struct hfsc_class)); if (rsc != NULL) hfsc_change_rsc(cl, rsc, 0); diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index cc5f339e6f9..880a3394a51 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -1559,10 +1559,9 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, goto failure; } err = -ENOBUFS; - if ((cl = kmalloc(sizeof(*cl), GFP_KERNEL)) == NULL) + if ((cl = kzalloc(sizeof(*cl), GFP_KERNEL)) == NULL) goto failure; - memset(cl, 0, sizeof(*cl)); cl->refcnt = 1; INIT_LIST_HEAD(&cl->sibling); INIT_LIST_HEAD(&cl->hlist); diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index c5bd8064e6d..a08ec4c7c55 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -148,7 +148,8 @@ static long tabledist(unsigned long mu, long sigma, static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) { struct netem_sched_data *q = qdisc_priv(sch); - struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb; + /* We don't fill cb now as skb_unshare() may invalidate it */ + struct netem_skb_cb *cb; struct sk_buff *skb2; int ret; int count = 1; @@ -200,6 +201,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8); } + cb = (struct netem_skb_cb *)skb->cb; if (q->gap == 0 /* not doing reordering */ || q->counter < q->gap /* inside last reordering gap */ || q->reorder < get_crandom(&q->reorder_cor)) { diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 9d05e13e92f..27329ce9c31 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -441,7 +441,8 @@ void sctp_assoc_set_primary(struct sctp_association *asoc, /* If the primary path is changing, assume that the * user wants to use this new path. */ - if (transport->state != SCTP_INACTIVE) + if ((transport->state == SCTP_ACTIVE) || + (transport->state == SCTP_UNKNOWN)) asoc->peer.active_path = transport; /* @@ -532,11 +533,11 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, port = addr->v4.sin_port; SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_add_peer:association %p addr: ", - " port: %d state:%s\n", + " port: %d state:%d\n", asoc, addr, addr->v4.sin_port, - peer_state == SCTP_UNKNOWN?"UNKNOWN":"ACTIVE"); + peer_state); /* Set the port if it has not been set yet. */ if (0 == asoc->peer.port) @@ -545,9 +546,12 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, /* Check to see if this is a duplicate. */ peer = sctp_assoc_lookup_paddr(asoc, addr); if (peer) { - if (peer_state == SCTP_ACTIVE && - peer->state == SCTP_UNKNOWN) - peer->state = SCTP_ACTIVE; + if (peer->state == SCTP_UNKNOWN) { + if (peer_state == SCTP_ACTIVE) + peer->state = SCTP_ACTIVE; + if (peer_state == SCTP_UNCONFIRMED) + peer->state = SCTP_UNCONFIRMED; + } return peer; } @@ -739,7 +743,8 @@ void sctp_assoc_control_transport(struct sctp_association *asoc, list_for_each(pos, &asoc->peer.transport_addr_list) { t = list_entry(pos, struct sctp_transport, transports); - if (t->state == SCTP_INACTIVE) + if ((t->state == SCTP_INACTIVE) || + (t->state == SCTP_UNCONFIRMED)) continue; if (!first || t->last_time_heard > first->last_time_heard) { second = first; @@ -759,7 +764,8 @@ void sctp_assoc_control_transport(struct sctp_association *asoc, * [If the primary is active but not most recent, bump the most * recently used transport.] */ - if (asoc->peer.primary_path->state != SCTP_INACTIVE && + if (((asoc->peer.primary_path->state == SCTP_ACTIVE) || + (asoc->peer.primary_path->state == SCTP_UNKNOWN)) && first != asoc->peer.primary_path) { second = first; first = asoc->peer.primary_path; @@ -1054,7 +1060,7 @@ void sctp_assoc_update(struct sctp_association *asoc, transports); if (!sctp_assoc_lookup_paddr(asoc, &trans->ipaddr)) sctp_assoc_add_peer(asoc, &trans->ipaddr, - GFP_ATOMIC, SCTP_ACTIVE); + GFP_ATOMIC, trans->state); } asoc->ctsn_ack_point = asoc->next_tsn - 1; @@ -1094,7 +1100,8 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc) /* Try to find an active transport. */ - if (t->state != SCTP_INACTIVE) { + if ((t->state == SCTP_ACTIVE) || + (t->state == SCTP_UNKNOWN)) { break; } else { /* Keep track of the next transport in case diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index 2b962627f63..2b9c12a170e 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c @@ -146,7 +146,7 @@ void sctp_bind_addr_free(struct sctp_bind_addr *bp) /* Add an address to the bind address list in the SCTP_bind_addr structure. */ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, - gfp_t gfp) + __u8 use_as_src, gfp_t gfp) { struct sctp_sockaddr_entry *addr; @@ -163,6 +163,8 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, if (!addr->a.v4.sin_port) addr->a.v4.sin_port = bp->port; + addr->use_as_src = use_as_src; + INIT_LIST_HEAD(&addr->list); list_add_tail(&addr->list, &bp->address_list); SCTP_DBG_OBJCNT_INC(addr); @@ -274,7 +276,7 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list, } af->from_addr_param(&addr, rawaddr, port, 0); - retval = sctp_add_bind_addr(bp, &addr, gfp); + retval = sctp_add_bind_addr(bp, &addr, 1, gfp); if (retval) { /* Can't finish building the list, clean up. */ sctp_bind_addr_clean(bp); @@ -367,7 +369,7 @@ static int sctp_copy_one_addr(struct sctp_bind_addr *dest, (((AF_INET6 == addr->sa.sa_family) && (flags & SCTP_ADDR6_ALLOWED) && (flags & SCTP_ADDR6_PEERSUPP)))) - error = sctp_add_bind_addr(dest, addr, gfp); + error = sctp_add_bind_addr(dest, addr, 1, gfp); } return error; diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 67bd53070ee..ffda1d68052 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c @@ -158,6 +158,12 @@ void sctp_endpoint_add_asoc(struct sctp_endpoint *ep, void sctp_endpoint_free(struct sctp_endpoint *ep) { ep->base.dead = 1; + + ep->base.sk->sk_state = SCTP_SS_CLOSED; + + /* Unlink this endpoint, so we can't find it again! */ + sctp_unhash_endpoint(ep); + sctp_endpoint_put(ep); } @@ -166,11 +172,6 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep) { SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return); - ep->base.sk->sk_state = SCTP_SS_CLOSED; - - /* Unlink this endpoint, so we can't find it again! */ - sctp_unhash_endpoint(ep); - /* Free up the HMAC transform. */ sctp_crypto_free_tfm(sctp_sk(ep->base.sk)->hmac); diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 8ef08070c8b..99c0cefc04e 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -290,7 +290,8 @@ static void sctp_v6_get_saddr(struct sctp_association *asoc, sctp_read_lock(addr_lock); list_for_each(pos, &bp->address_list) { laddr = list_entry(pos, struct sctp_sockaddr_entry, list); - if ((laddr->a.sa.sa_family == AF_INET6) && + if ((laddr->use_as_src) && + (laddr->a.sa.sa_family == AF_INET6) && (scope <= sctp_scope(&laddr->a))) { bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a); if (!baddr || (matchlen < bmatchlen)) { diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index e5faa351aaa..30b710c54e6 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -691,7 +691,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) if (!new_transport) { new_transport = asoc->peer.active_path; - } else if (new_transport->state == SCTP_INACTIVE) { + } else if ((new_transport->state == SCTP_INACTIVE) || + (new_transport->state == SCTP_UNCONFIRMED)) { /* If the chunk is Heartbeat or Heartbeat Ack, * send it to chunk->transport, even if it's * inactive. @@ -848,7 +849,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) */ new_transport = chunk->transport; if (!new_transport || - new_transport->state == SCTP_INACTIVE) + ((new_transport->state == SCTP_INACTIVE) || + (new_transport->state == SCTP_UNCONFIRMED))) new_transport = asoc->peer.active_path; /* Change packets if necessary. */ @@ -1464,7 +1466,8 @@ static void sctp_check_transmitted(struct sctp_outq *q, /* Mark the destination transport address as * active if it is not so marked. */ - if (transport->state == SCTP_INACTIVE) { + if ((transport->state == SCTP_INACTIVE) || + (transport->state == SCTP_UNCONFIRMED)) { sctp_assoc_control_transport( transport->asoc, transport, diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 816c033d788..1ab03a27a76 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -240,7 +240,7 @@ int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope, (((AF_INET6 == addr->a.sa.sa_family) && (copy_flags & SCTP_ADDR6_ALLOWED) && (copy_flags & SCTP_ADDR6_PEERSUPP)))) { - error = sctp_add_bind_addr(bp, &addr->a, + error = sctp_add_bind_addr(bp, &addr->a, 1, GFP_ATOMIC); if (error) goto end_copy; @@ -486,6 +486,8 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, list_for_each(pos, &bp->address_list) { laddr = list_entry(pos, struct sctp_sockaddr_entry, list); + if (!laddr->use_as_src) + continue; sctp_v4_dst_saddr(&dst_saddr, dst, bp->port); if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a)) goto out_unlock; @@ -506,7 +508,8 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, list_for_each(pos, &bp->address_list) { laddr = list_entry(pos, struct sctp_sockaddr_entry, list); - if (AF_INET == laddr->a.sa.sa_family) { + if ((laddr->use_as_src) && + (AF_INET == laddr->a.sa.sa_family)) { fl.fl4_src = laddr->a.v4.sin_addr.s_addr; if (!ip_route_output_key(&rt, &fl)) { dst = &rt->u.dst; diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 2a877369169..4f11f585820 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -1493,7 +1493,7 @@ no_hmac: /* Also, add the destination address. */ if (list_empty(&retval->base.bind_addr.address_list)) { - sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest, + sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest, 1, GFP_ATOMIC); } @@ -2017,7 +2017,7 @@ static int sctp_process_param(struct sctp_association *asoc, af->from_addr_param(&addr, param.addr, asoc->peer.port, 0); scope = sctp_scope(peer_addr); if (sctp_in_scope(&addr, scope)) - if (!sctp_assoc_add_peer(asoc, &addr, gfp, SCTP_ACTIVE)) + if (!sctp_assoc_add_peer(asoc, &addr, gfp, SCTP_UNCONFIRMED)) return 0; break; @@ -2418,7 +2418,7 @@ static __u16 sctp_process_asconf_param(struct sctp_association *asoc, * Due to Resource Shortage'. */ - peer = sctp_assoc_add_peer(asoc, &addr, GFP_ATOMIC, SCTP_ACTIVE); + peer = sctp_assoc_add_peer(asoc, &addr, GFP_ATOMIC, SCTP_UNCONFIRMED); if (!peer) return SCTP_ERROR_RSRC_LOW; @@ -2565,6 +2565,7 @@ static int sctp_asconf_param_success(struct sctp_association *asoc, union sctp_addr_param *addr_param; struct list_head *pos; struct sctp_transport *transport; + struct sctp_sockaddr_entry *saddr; int retval = 0; addr_param = (union sctp_addr_param *) @@ -2578,7 +2579,11 @@ static int sctp_asconf_param_success(struct sctp_association *asoc, case SCTP_PARAM_ADD_IP: sctp_local_bh_disable(); sctp_write_lock(&asoc->base.addr_lock); - retval = sctp_add_bind_addr(bp, &addr, GFP_ATOMIC); + list_for_each(pos, &bp->address_list) { + saddr = list_entry(pos, struct sctp_sockaddr_entry, list); + if (sctp_cmp_addr_exact(&saddr->a, &addr)) + saddr->use_as_src = 1; + } sctp_write_unlock(&asoc->base.addr_lock); sctp_local_bh_enable(); break; @@ -2591,6 +2596,7 @@ static int sctp_asconf_param_success(struct sctp_association *asoc, list_for_each(pos, &asoc->peer.transport_addr_list) { transport = list_entry(pos, struct sctp_transport, transports); + dst_release(transport->dst); sctp_transport_route(transport, NULL, sctp_sk(asoc->base.sk)); } diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index c5beb2ad7ef..9c10bdec1af 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -430,7 +430,11 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, /* The check for association's overall error counter exceeding the * threshold is done in the state function. */ - asoc->overall_error_count++; + /* When probing UNCONFIRMED addresses, the association overall + * error count is NOT incremented + */ + if (transport->state != SCTP_UNCONFIRMED) + asoc->overall_error_count++; if (transport->state != SCTP_INACTIVE && (transport->error_count++ >= transport->pathmaxrxt)) { @@ -610,7 +614,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, /* Mark the destination transport address as active if it is not so * marked. */ - if (t->state == SCTP_INACTIVE) + if ((t->state == SCTP_INACTIVE) || (t->state == SCTP_UNCONFIRMED)) sctp_assoc_control_transport(asoc, t, SCTP_TRANSPORT_UP, SCTP_HEARTBEAT_SUCCESS); @@ -620,6 +624,10 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, */ hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data; sctp_transport_update_rto(t, (jiffies - hbinfo->sent_at)); + + /* Update the heartbeat timer. */ + if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t))) + sctp_transport_hold(t); } /* Helper function to do a transport reset at the expiry of the hearbeat diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 9e58144f485..ead3f1b0ea3 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -846,6 +846,7 @@ static sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep, hbinfo.param_hdr.length = htons(sizeof(sctp_sender_hb_info_t)); hbinfo.daddr = transport->ipaddr; hbinfo.sent_at = jiffies; + hbinfo.hb_nonce = transport->hb_nonce; /* Send a heartbeat to our peer. */ paylen = sizeof(sctp_sender_hb_info_t); @@ -1048,6 +1049,10 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep, return SCTP_DISPOSITION_DISCARD; } + /* Validate the 64-bit random nonce. */ + if (hbinfo->hb_nonce != link->hb_nonce) + return SCTP_DISPOSITION_DISCARD; + max_interval = link->hbinterval + link->rto; /* Check if the timestamp looks valid. */ @@ -5278,7 +5283,6 @@ static int sctp_eat_data(const struct sctp_association *asoc, datalen -= sizeof(sctp_data_chunk_t); deliver = SCTP_CMD_CHUNK_ULP; - chunk->data_accepted = 1; /* Think about partial delivery. */ if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) { @@ -5357,6 +5361,8 @@ static int sctp_eat_data(const struct sctp_association *asoc, if (SCTP_CMD_CHUNK_ULP == deliver) sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn)); + chunk->data_accepted = 1; + /* Note: Some chunks may get overcounted (if we drop) or overcounted * if we renege and the chunk arrives again. */ diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 0a2c71d0d8a..54722e622e6 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -369,7 +369,7 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len) /* Use GFP_ATOMIC since BHs are disabled. */ addr->v4.sin_port = ntohs(addr->v4.sin_port); - ret = sctp_add_bind_addr(bp, addr, GFP_ATOMIC); + ret = sctp_add_bind_addr(bp, addr, 1, GFP_ATOMIC); addr->v4.sin_port = htons(addr->v4.sin_port); sctp_write_unlock(&ep->base.addr_lock); sctp_local_bh_enable(); @@ -491,6 +491,7 @@ static int sctp_send_asconf_add_ip(struct sock *sk, struct sctp_chunk *chunk; struct sctp_sockaddr_entry *laddr; union sctp_addr *addr; + union sctp_addr saveaddr; void *addr_buf; struct sctp_af *af; struct list_head *pos; @@ -558,14 +559,26 @@ static int sctp_send_asconf_add_ip(struct sock *sk, } retval = sctp_send_asconf(asoc, chunk); + if (retval) + goto out; - /* FIXME: After sending the add address ASCONF chunk, we - * cannot append the address to the association's binding - * address list, because the new address may be used as the - * source of a message sent to the peer before the ASCONF - * chunk is received by the peer. So we should wait until - * ASCONF_ACK is received. + /* Add the new addresses to the bind address list with + * use_as_src set to 0. */ + sctp_local_bh_disable(); + sctp_write_lock(&asoc->base.addr_lock); + addr_buf = addrs; + for (i = 0; i < addrcnt; i++) { + addr = (union sctp_addr *)addr_buf; + af = sctp_get_af_specific(addr->v4.sin_family); + memcpy(&saveaddr, addr, af->sockaddr_len); + saveaddr.v4.sin_port = ntohs(saveaddr.v4.sin_port); + retval = sctp_add_bind_addr(bp, &saveaddr, 0, + GFP_ATOMIC); + addr_buf += af->sockaddr_len; + } + sctp_write_unlock(&asoc->base.addr_lock); + sctp_local_bh_enable(); } out: @@ -676,12 +689,15 @@ static int sctp_send_asconf_del_ip(struct sock *sk, struct sctp_sock *sp; struct sctp_endpoint *ep; struct sctp_association *asoc; + struct sctp_transport *transport; struct sctp_bind_addr *bp; struct sctp_chunk *chunk; union sctp_addr *laddr; + union sctp_addr saveaddr; void *addr_buf; struct sctp_af *af; - struct list_head *pos; + struct list_head *pos, *pos1; + struct sctp_sockaddr_entry *saddr; int i; int retval = 0; @@ -748,14 +764,42 @@ static int sctp_send_asconf_del_ip(struct sock *sk, goto out; } - retval = sctp_send_asconf(asoc, chunk); + /* Reset use_as_src flag for the addresses in the bind address + * list that are to be deleted. + */ + sctp_local_bh_disable(); + sctp_write_lock(&asoc->base.addr_lock); + addr_buf = addrs; + for (i = 0; i < addrcnt; i++) { + laddr = (union sctp_addr *)addr_buf; + af = sctp_get_af_specific(laddr->v4.sin_family); + memcpy(&saveaddr, laddr, af->sockaddr_len); + saveaddr.v4.sin_port = ntohs(saveaddr.v4.sin_port); + list_for_each(pos1, &bp->address_list) { + saddr = list_entry(pos1, + struct sctp_sockaddr_entry, + list); + if (sctp_cmp_addr_exact(&saddr->a, &saveaddr)) + saddr->use_as_src = 0; + } + addr_buf += af->sockaddr_len; + } + sctp_write_unlock(&asoc->base.addr_lock); + sctp_local_bh_enable(); - /* FIXME: After sending the delete address ASCONF chunk, we - * cannot remove the addresses from the association's bind - * address list, because there maybe some packet send to - * the delete addresses, so we should wait until ASCONF_ACK - * packet is received. + /* Update the route and saddr entries for all the transports + * as some of the addresses in the bind address list are + * about to be deleted and cannot be used as source addresses. */ + list_for_each(pos1, &asoc->peer.transport_addr_list) { + transport = list_entry(pos1, struct sctp_transport, + transports); + dst_release(transport->dst); + sctp_transport_route(transport, NULL, + sctp_sk(asoc->base.sk)); + } + + retval = sctp_send_asconf(asoc, chunk); } out: return retval; @@ -4977,7 +5021,7 @@ static struct sctp_bind_bucket *sctp_bucket_create( /* Caller must hold hashbucket lock for this tb with local BH disabled */ static void sctp_bucket_destroy(struct sctp_bind_bucket *pp) { - if (hlist_empty(&pp->owner)) { + if (pp && hlist_empty(&pp->owner)) { if (pp->next) pp->next->pprev = pp->pprev; *(pp->pprev) = pp->next; diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 160f62ad1cc..2763aa93de1 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -49,6 +49,7 @@ */ #include <linux/types.h> +#include <linux/random.h> #include <net/sctp/sctp.h> #include <net/sctp/sm.h> @@ -85,7 +86,6 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, peer->init_sent_count = 0; - peer->state = SCTP_ACTIVE; peer->param_flags = SPP_HB_DISABLE | SPP_PMTUD_ENABLE | SPP_SACKDELAY_ENABLE; @@ -109,6 +109,9 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, peer->hb_timer.function = sctp_generate_heartbeat_event; peer->hb_timer.data = (unsigned long)peer; + /* Initialize the 64-bit random nonce sent with heartbeat. */ + get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce)); + atomic_set(&peer->refcnt, 1); peer->dead = 0; @@ -517,7 +520,9 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, unsigned long sctp_transport_timeout(struct sctp_transport *t) { unsigned long timeout; - timeout = t->hbinterval + t->rto + sctp_jitter(t->rto); + timeout = t->rto + sctp_jitter(t->rto); + if (t->state != SCTP_UNCONFIRMED) + timeout += t->hbinterval; timeout += jiffies; return timeout; } diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 519ebc17c02..4a9aa9393b9 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -225,9 +225,8 @@ gss_alloc_context(void) { struct gss_cl_ctx *ctx; - ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (ctx != NULL) { - memset(ctx, 0, sizeof(*ctx)); ctx->gc_proc = RPC_GSS_PROC_DATA; ctx->gc_seq = 1; /* NetApp 6.4R1 doesn't accept seq. no. 0 */ spin_lock_init(&ctx->gc_seq_lock); @@ -391,9 +390,8 @@ gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid) { struct gss_upcall_msg *gss_msg; - gss_msg = kmalloc(sizeof(*gss_msg), GFP_KERNEL); + gss_msg = kzalloc(sizeof(*gss_msg), GFP_KERNEL); if (gss_msg != NULL) { - memset(gss_msg, 0, sizeof(*gss_msg)); INIT_LIST_HEAD(&gss_msg->list); rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); init_waitqueue_head(&gss_msg->waitqueue); @@ -776,10 +774,9 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) dprintk("RPC: gss_create_cred for uid %d, flavor %d\n", acred->uid, auth->au_flavor); - if (!(cred = kmalloc(sizeof(*cred), GFP_KERNEL))) + if (!(cred = kzalloc(sizeof(*cred), GFP_KERNEL))) goto out_err; - memset(cred, 0, sizeof(*cred)); atomic_set(&cred->gc_count, 1); cred->gc_uid = acred->uid; /* diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index b8714a87b34..70e1e53a632 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -129,9 +129,8 @@ gss_import_sec_context_kerberos(const void *p, const void *end = (const void *)((const char *)p + len); struct krb5_ctx *ctx; - if (!(ctx = kmalloc(sizeof(*ctx), GFP_KERNEL))) + if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL))) goto out_err; - memset(ctx, 0, sizeof(*ctx)); p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate)); if (IS_ERR(p)) diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c index d88468d21c3..3db745379d0 100644 --- a/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/net/sunrpc/auth_gss/gss_mech_switch.c @@ -237,9 +237,8 @@ gss_import_sec_context(const void *input_token, size_t bufsize, struct gss_api_mech *mech, struct gss_ctx **ctx_id) { - if (!(*ctx_id = kmalloc(sizeof(**ctx_id), GFP_KERNEL))) + if (!(*ctx_id = kzalloc(sizeof(**ctx_id), GFP_KERNEL))) return GSS_S_FAILURE; - memset(*ctx_id, 0, sizeof(**ctx_id)); (*ctx_id)->mech_type = gss_mech_get(mech); return mech->gm_ops diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c index 3d0432aa45c..88dcb52d171 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_mech.c +++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c @@ -152,9 +152,8 @@ gss_import_sec_context_spkm3(const void *p, size_t len, const void *end = (const void *)((const char *)p + len); struct spkm3_ctx *ctx; - if (!(ctx = kmalloc(sizeof(*ctx), GFP_KERNEL))) + if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL))) goto out_err; - memset(ctx, 0, sizeof(*ctx)); p = simple_get_netobj(p, end, &ctx->ctx_id); if (IS_ERR(p)) diff --git a/net/sunrpc/auth_gss/gss_spkm3_token.c b/net/sunrpc/auth_gss/gss_spkm3_token.c index af0d7ce7468..854a983ccf2 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_token.c +++ b/net/sunrpc/auth_gss/gss_spkm3_token.c @@ -90,10 +90,9 @@ asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits) int decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen, int explen) { - if (!(out->data = kmalloc(explen,GFP_KERNEL))) + if (!(out->data = kzalloc(explen,GFP_KERNEL))) return 0; out->len = explen; - memset(out->data, 0, explen); memcpy(out->data, in, enclen); return 1; } diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index aa8965e9d30..4ba271f892c 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -125,10 +125,9 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname, goto out_err; err = -ENOMEM; - clnt = kmalloc(sizeof(*clnt), GFP_KERNEL); + clnt = kzalloc(sizeof(*clnt), GFP_KERNEL); if (!clnt) goto out_err; - memset(clnt, 0, sizeof(*clnt)); atomic_set(&clnt->cl_users, 0); atomic_set(&clnt->cl_count, 1); clnt->cl_parent = clnt; diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c index 15c2db26767..bd98124c3a6 100644 --- a/net/sunrpc/stats.c +++ b/net/sunrpc/stats.c @@ -114,13 +114,8 @@ void svc_seq_show(struct seq_file *seq, const struct svc_stat *statp) { */ struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) { - unsigned int ops = clnt->cl_maxproc; - size_t size = ops * sizeof(struct rpc_iostats); struct rpc_iostats *new; - - new = kmalloc(size, GFP_KERNEL); - if (new) - memset(new, 0 , size); + new = kcalloc(clnt->cl_maxproc, sizeof(struct rpc_iostats), GFP_KERNEL); return new; } EXPORT_SYMBOL(rpc_alloc_iostats); diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 01ba60a4957..b76a227dd3a 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -32,9 +32,8 @@ svc_create(struct svc_program *prog, unsigned int bufsize) int vers; unsigned int xdrsize; - if (!(serv = kmalloc(sizeof(*serv), GFP_KERNEL))) + if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL))) return NULL; - memset(serv, 0, sizeof(*serv)); serv->sv_name = prog->pg_name; serv->sv_program = prog; serv->sv_nrthreads = 1; @@ -159,11 +158,10 @@ svc_create_thread(svc_thread_fn func, struct svc_serv *serv) struct svc_rqst *rqstp; int error = -ENOMEM; - rqstp = kmalloc(sizeof(*rqstp), GFP_KERNEL); + rqstp = kzalloc(sizeof(*rqstp), GFP_KERNEL); if (!rqstp) goto out; - memset(rqstp, 0, sizeof(*rqstp)); init_waitqueue_head(&rqstp->rq_wait); if (!(rqstp->rq_argp = kmalloc(serv->sv_xdrsize, GFP_KERNEL)) diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index a27905a0ad2..d9a95732df4 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -1322,11 +1322,10 @@ svc_setup_socket(struct svc_serv *serv, struct socket *sock, struct sock *inet; dprintk("svc: svc_setup_socket %p\n", sock); - if (!(svsk = kmalloc(sizeof(*svsk), GFP_KERNEL))) { + if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) { *errp = -ENOMEM; return NULL; } - memset(svsk, 0, sizeof(*svsk)); inet = sock->sk; diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 02060d0e7be..313b68d892c 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -908,9 +908,8 @@ static struct rpc_xprt *xprt_setup(int proto, struct sockaddr_in *ap, struct rpc struct rpc_xprt *xprt; struct rpc_rqst *req; - if ((xprt = kmalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL) + if ((xprt = kzalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL) return ERR_PTR(-ENOMEM); - memset(xprt, 0, sizeof(*xprt)); /* Nnnngh! */ xprt->addr = *ap; diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 21006b10910..ee678ed13b6 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -1276,10 +1276,9 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) xprt->max_reqs = xprt_udp_slot_table_entries; slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); - xprt->slot = kmalloc(slot_table_size, GFP_KERNEL); + xprt->slot = kzalloc(slot_table_size, GFP_KERNEL); if (xprt->slot == NULL) return -ENOMEM; - memset(xprt->slot, 0, slot_table_size); xprt->prot = IPPROTO_UDP; xprt->port = xs_get_random_port(); @@ -1318,10 +1317,9 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) xprt->max_reqs = xprt_tcp_slot_table_entries; slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); - xprt->slot = kmalloc(slot_table_size, GFP_KERNEL); + xprt->slot = kzalloc(slot_table_size, GFP_KERNEL); if (xprt->slot == NULL) return -ENOMEM; - memset(xprt->slot, 0, slot_table_size); xprt->prot = IPPROTO_TCP; xprt->port = xs_get_random_port(); diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 7ef17a449cf..75a5968c213 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -665,11 +665,9 @@ int tipc_bearer_init(void) int res; write_lock_bh(&tipc_net_lock); - tipc_bearers = kmalloc(MAX_BEARERS * sizeof(struct bearer), GFP_ATOMIC); - media_list = kmalloc(MAX_MEDIA * sizeof(struct media), GFP_ATOMIC); + tipc_bearers = kcalloc(MAX_BEARERS, sizeof(struct bearer), GFP_ATOMIC); + media_list = kcalloc(MAX_MEDIA, sizeof(struct media), GFP_ATOMIC); if (tipc_bearers && media_list) { - memset(tipc_bearers, 0, MAX_BEARERS * sizeof(struct bearer)); - memset(media_list, 0, MAX_MEDIA * sizeof(struct media)); res = TIPC_OK; } else { kfree(tipc_bearers); diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c index 1dcb6940e33..b46b5188a9f 100644 --- a/net/tipc/cluster.c +++ b/net/tipc/cluster.c @@ -57,29 +57,25 @@ struct cluster *tipc_cltr_create(u32 addr) struct _zone *z_ptr; struct cluster *c_ptr; int max_nodes; - int alloc; - c_ptr = (struct cluster *)kmalloc(sizeof(*c_ptr), GFP_ATOMIC); + c_ptr = kzalloc(sizeof(*c_ptr), GFP_ATOMIC); if (c_ptr == NULL) { warn("Cluster creation failure, no memory\n"); return NULL; } - memset(c_ptr, 0, sizeof(*c_ptr)); c_ptr->addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0); if (in_own_cluster(addr)) max_nodes = LOWEST_SLAVE + tipc_max_slaves; else max_nodes = tipc_max_nodes + 1; - alloc = sizeof(void *) * (max_nodes + 1); - c_ptr->nodes = (struct node **)kmalloc(alloc, GFP_ATOMIC); + c_ptr->nodes = kcalloc(max_nodes + 1, sizeof(void*), GFP_ATOMIC); if (c_ptr->nodes == NULL) { warn("Cluster creation failure, no memory for node area\n"); kfree(c_ptr); return NULL; } - memset(c_ptr->nodes, 0, alloc); if (in_own_cluster(addr)) tipc_local_nodes = c_ptr->nodes; diff --git a/net/tipc/discover.c b/net/tipc/discover.c index 2b844120312..ee94de92ae9 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -295,7 +295,7 @@ struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr, { struct link_req *req; - req = (struct link_req *)kmalloc(sizeof(*req), GFP_ATOMIC); + req = kmalloc(sizeof(*req), GFP_ATOMIC); if (!req) return NULL; diff --git a/net/tipc/link.c b/net/tipc/link.c index c10e18a49b9..693f02eca6d 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -417,12 +417,11 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, struct tipc_msg *msg; char *if_name; - l_ptr = (struct link *)kmalloc(sizeof(*l_ptr), GFP_ATOMIC); + l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC); if (!l_ptr) { warn("Link creation failed, no memory\n"); return NULL; } - memset(l_ptr, 0, sizeof(*l_ptr)); l_ptr->addr = peer; if_name = strchr(b_ptr->publ.name, ':') + 1; diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index a6926ff07bc..049242ea5c3 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -117,14 +117,12 @@ static struct publication *publ_create(u32 type, u32 lower, u32 upper, u32 scope, u32 node, u32 port_ref, u32 key) { - struct publication *publ = - (struct publication *)kmalloc(sizeof(*publ), GFP_ATOMIC); + struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC); if (publ == NULL) { warn("Publication creation failure, no memory\n"); return NULL; } - memset(publ, 0, sizeof(*publ)); publ->type = type; publ->lower = lower; publ->upper = upper; @@ -144,11 +142,7 @@ static struct publication *publ_create(u32 type, u32 lower, u32 upper, static struct sub_seq *tipc_subseq_alloc(u32 cnt) { - u32 sz = cnt * sizeof(struct sub_seq); - struct sub_seq *sseq = (struct sub_seq *)kmalloc(sz, GFP_ATOMIC); - - if (sseq) - memset(sseq, 0, sz); + struct sub_seq *sseq = kcalloc(cnt, sizeof(struct sub_seq), GFP_ATOMIC); return sseq; } @@ -160,8 +154,7 @@ static struct sub_seq *tipc_subseq_alloc(u32 cnt) static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_head) { - struct name_seq *nseq = - (struct name_seq *)kmalloc(sizeof(*nseq), GFP_ATOMIC); + struct name_seq *nseq = kzalloc(sizeof(*nseq), GFP_ATOMIC); struct sub_seq *sseq = tipc_subseq_alloc(1); if (!nseq || !sseq) { @@ -171,7 +164,6 @@ static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_hea return NULL; } - memset(nseq, 0, sizeof(*nseq)); spin_lock_init(&nseq->lock); nseq->type = type; nseq->sseqs = sseq; @@ -1060,7 +1052,7 @@ int tipc_nametbl_init(void) { int array_size = sizeof(struct hlist_head) * tipc_nametbl_size; - table.types = (struct hlist_head *)kmalloc(array_size, GFP_ATOMIC); + table.types = kmalloc(array_size, GFP_ATOMIC); if (!table.types) return -ENOMEM; diff --git a/net/tipc/net.c b/net/tipc/net.c index e5a359ab493..a991bf8a7f7 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c @@ -160,14 +160,11 @@ void tipc_net_send_external_routes(u32 dest) static int net_init(void) { - u32 sz = sizeof(struct _zone *) * (tipc_max_zones + 1); - memset(&tipc_net, 0, sizeof(tipc_net)); - tipc_net.zones = (struct _zone **)kmalloc(sz, GFP_ATOMIC); + tipc_net.zones = kcalloc(tipc_max_zones + 1, sizeof(struct _zone *), GFP_ATOMIC); if (!tipc_net.zones) { return -ENOMEM; } - memset(tipc_net.zones, 0, sz); return TIPC_OK; } diff --git a/net/tipc/port.c b/net/tipc/port.c index 3251c8d8e53..b9c8c6b9e94 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -226,12 +226,11 @@ u32 tipc_createport_raw(void *usr_handle, struct tipc_msg *msg; u32 ref; - p_ptr = kmalloc(sizeof(*p_ptr), GFP_ATOMIC); + p_ptr = kzalloc(sizeof(*p_ptr), GFP_ATOMIC); if (!p_ptr) { warn("Port creation failed, no memory\n"); return 0; } - memset(p_ptr, 0, sizeof(*p_ptr)); ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock); if (!ref) { warn("Port creation failed, reference table exhausted\n"); @@ -1058,7 +1057,7 @@ int tipc_createport(u32 user_ref, struct port *p_ptr; u32 ref; - up_ptr = (struct user_port *)kmalloc(sizeof(*up_ptr), GFP_ATOMIC); + up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); if (!up_ptr) { warn("Port creation failed, no memory\n"); return -ENOMEM; diff --git a/net/tipc/ref.c b/net/tipc/ref.c index 596d3c8ff75..e6d6ae22ea4 100644 --- a/net/tipc/ref.c +++ b/net/tipc/ref.c @@ -79,7 +79,7 @@ int tipc_ref_table_init(u32 requested_size, u32 start) while (sz < requested_size) { sz <<= 1; } - table = (struct reference *)vmalloc(sz * sizeof(struct reference)); + table = vmalloc(sz * sizeof(*table)); if (table == NULL) return -ENOMEM; diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index e19b4bcd67e..c51600ba5f4 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -393,12 +393,11 @@ static void subscr_named_msg_event(void *usr_handle, /* Create subscriber object */ - subscriber = kmalloc(sizeof(struct subscriber), GFP_ATOMIC); + subscriber = kzalloc(sizeof(struct subscriber), GFP_ATOMIC); if (subscriber == NULL) { warn("Subscriber rejected, no memory\n"); return; } - memset(subscriber, 0, sizeof(struct subscriber)); INIT_LIST_HEAD(&subscriber->subscription_list); INIT_LIST_HEAD(&subscriber->subscriber_list); subscriber->ref = tipc_ref_acquire(subscriber, &subscriber->lock); diff --git a/net/tipc/user_reg.c b/net/tipc/user_reg.c index 1e3ae57c722..04d1b9be9c5 100644 --- a/net/tipc/user_reg.c +++ b/net/tipc/user_reg.c @@ -82,9 +82,8 @@ static int reg_init(void) spin_lock_bh(®_lock); if (!users) { - users = (struct tipc_user *)kmalloc(USER_LIST_SIZE, GFP_ATOMIC); + users = kzalloc(USER_LIST_SIZE, GFP_ATOMIC); if (users) { - memset(users, 0, USER_LIST_SIZE); for (i = 1; i <= MAX_USERID; i++) { users[i].next = i - 1; } diff --git a/net/tipc/zone.c b/net/tipc/zone.c index 316c4872ff5..f5b00ea2d5a 100644 --- a/net/tipc/zone.c +++ b/net/tipc/zone.c @@ -52,13 +52,12 @@ struct _zone *tipc_zone_create(u32 addr) return NULL; } - z_ptr = (struct _zone *)kmalloc(sizeof(*z_ptr), GFP_ATOMIC); + z_ptr = kzalloc(sizeof(*z_ptr), GFP_ATOMIC); if (!z_ptr) { warn("Zone creation failed, insufficient memory\n"); return NULL; } - memset(z_ptr, 0, sizeof(*z_ptr)); z_num = tipc_zone(addr); z_ptr->addr = tipc_addr(z_num, 0, 0); tipc_net.zones[z_num] = z_ptr; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index f70475bfb62..6f290927926 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -663,11 +663,10 @@ static int unix_autobind(struct socket *sock) goto out; err = -ENOMEM; - addr = kmalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL); + addr = kzalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL); if (!addr) goto out; - memset(addr, 0, sizeof(*addr) + sizeof(short) + 16); addr->name->sun_family = AF_UNIX; atomic_set(&addr->refcnt, 1); diff --git a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c index a690cf773b6..6f39faa1583 100644 --- a/net/wanrouter/af_wanpipe.c +++ b/net/wanrouter/af_wanpipe.c @@ -370,12 +370,11 @@ static int wanpipe_listen_rcv (struct sk_buff *skb, struct sock *sk) * used by the ioctl call to read call information * and to execute commands. */ - if ((mbox_ptr = kmalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL) { + if ((mbox_ptr = kzalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL) { wanpipe_kill_sock_irq (newsk); release_device(dev); return -ENOMEM; } - memset(mbox_ptr, 0, sizeof(mbox_cmd_t)); memcpy(mbox_ptr,skb->data,skb->len); /* Register the lcn on which incoming call came @@ -507,11 +506,10 @@ static struct sock *wanpipe_alloc_socket(void) if ((sk = sk_alloc(PF_WANPIPE, GFP_ATOMIC, &wanpipe_proto, 1)) == NULL) return NULL; - if ((wan_opt = kmalloc(sizeof(struct wanpipe_opt), GFP_ATOMIC)) == NULL) { + if ((wan_opt = kzalloc(sizeof(struct wanpipe_opt), GFP_ATOMIC)) == NULL) { sk_free(sk); return NULL; } - memset(wan_opt, 0x00, sizeof(struct wanpipe_opt)); wp_sk(sk) = wan_opt; @@ -2011,10 +2009,9 @@ static int set_ioctl_cmd (struct sock *sk, void *arg) dev_put(dev); - if ((mbox_ptr = kmalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL) + if ((mbox_ptr = kzalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL) return -ENOMEM; - memset(mbox_ptr, 0, sizeof(mbox_cmd_t)); wp_sk(sk)->mbox = mbox_ptr; wanpipe_link_driver(dev,sk); diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c index ad8e8a79779..9479659277a 100644 --- a/net/wanrouter/wanmain.c +++ b/net/wanrouter/wanmain.c @@ -642,18 +642,16 @@ static int wanrouter_device_new_if(struct wan_device *wandev, if (cnf->config_id == WANCONFIG_MPPP) { #ifdef CONFIG_WANPIPE_MULTPPP - pppdev = kmalloc(sizeof(struct ppp_device), GFP_KERNEL); + pppdev = kzalloc(sizeof(struct ppp_device), GFP_KERNEL); err = -ENOBUFS; if (pppdev == NULL) goto out; - memset(pppdev, 0, sizeof(struct ppp_device)); - pppdev->dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); + pppdev->dev = kzalloc(sizeof(struct net_device), GFP_KERNEL); if (pppdev->dev == NULL) { kfree(pppdev); err = -ENOBUFS; goto out; } - memset(pppdev->dev, 0, sizeof(struct net_device)); err = wandev->new_if(wandev, (struct net_device *)pppdev, cnf); dev = pppdev->dev; #else @@ -663,11 +661,10 @@ static int wanrouter_device_new_if(struct wan_device *wandev, goto out; #endif } else { - dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); + dev = kzalloc(sizeof(struct net_device), GFP_KERNEL); err = -ENOBUFS; if (dev == NULL) goto out; - memset(dev, 0, sizeof(struct net_device)); err = wandev->new_if(wandev, dev, cnf); } diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 405b741dff4..f35bc676128 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -307,10 +307,9 @@ struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp) { struct xfrm_policy *policy; - policy = kmalloc(sizeof(struct xfrm_policy), gfp); + policy = kzalloc(sizeof(struct xfrm_policy), gfp); if (policy) { - memset(policy, 0, sizeof(struct xfrm_policy)); atomic_set(&policy->refcnt, 1); rwlock_init(&policy->lock); init_timer(&policy->timer); diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 43f00fc28a3..0021aad5db4 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -194,10 +194,9 @@ struct xfrm_state *xfrm_state_alloc(void) { struct xfrm_state *x; - x = kmalloc(sizeof(struct xfrm_state), GFP_ATOMIC); + x = kzalloc(sizeof(struct xfrm_state), GFP_ATOMIC); if (x) { - memset(x, 0, sizeof(struct xfrm_state)); atomic_set(&x->refcnt, 1); atomic_set(&x->tunnel_users, 0); INIT_LIST_HEAD(&x->bydst); |