Merge branch 'master'

This commit is contained in:
Steven Whitehouse 2006-07-31 08:59:59 -04:00
commit b1b934d31d
350 changed files with 3224 additions and 2744 deletions

View File

@ -258,3 +258,19 @@ Why: These drivers never compiled since they were added to the kernel
Who: Jean Delvare <khali@linux-fr.org> Who: Jean Delvare <khali@linux-fr.org>
--------------------------- ---------------------------
What: Bridge netfilter deferred IPv4/IPv6 output hook calling
When: January 2007
Why: The deferred output hooks are a layering violation causing unusual
and broken behaviour on bridge devices. Examples of things they
break include QoS classifation using the MARK or CLASSIFY targets,
the IPsec policy match and connection tracking with VLANs on a
bridge. Their only use is to enable bridge output port filtering
within iptables with the physdev match, which can also be done by
combining iptables and ebtables using netfilter marks. Until it
will get removed the hook deferral is disabled by default and is
only enabled when needed.
Who: Patrick McHardy <kaber@trash.net>
---------------------------

View File

@ -238,6 +238,13 @@ Debugging
pagefaulttrace Dump all page faults. Only useful for extreme debugging pagefaulttrace Dump all page faults. Only useful for extreme debugging
and will create a lot of output. and will create a lot of output.
call_trace=[old|both|newfallback|new]
old: use old inexact backtracer
new: use new exact dwarf2 unwinder
both: print entries from both
newfallback: use new unwinder but fall back to old if it gets
stuck (default)
Misc Misc
noreplacement Don't replace instructions with more appropriate ones noreplacement Don't replace instructions with more appropriate ones

View File

@ -1694,10 +1694,8 @@ L: linux-kernel@vger.kernel.org
S: Maintained S: Maintained
LAPB module LAPB module
P: Henner Eisen
M: eis@baty.hanse.de
L: linux-x25@vger.kernel.org L: linux-x25@vger.kernel.org
S: Maintained S: Orphan
LASI 53c700 driver for PARISC LASI 53c700 driver for PARISC
P: James E.J. Bottomley P: James E.J. Bottomley

View File

@ -1,7 +1,7 @@
VERSION = 2 VERSION = 2
PATCHLEVEL = 6 PATCHLEVEL = 6
SUBLEVEL = 18 SUBLEVEL = 18
EXTRAVERSION = -rc2 EXTRAVERSION = -rc3
NAME=Crazed Snow-Weasel NAME=Crazed Snow-Weasel
# *DOCUMENTATION* # *DOCUMENTATION*

View File

@ -1,7 +1,7 @@
# #
# Automatically generated make config: don't edit # Automatically generated make config: don't edit
# Linux kernel version: 2.6.18-rc1 # Linux kernel version: 2.6.18-rc1-git9
# Sun Jul 9 15:21:30 2006 # Sat Jul 15 15:08:10 2006
# #
CONFIG_ARM=y CONFIG_ARM=y
CONFIG_MMU=y CONFIG_MMU=y
@ -30,6 +30,7 @@ CONFIG_SWAP=y
CONFIG_SYSVIPC=y CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set # CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
CONFIG_SYSCTL=y CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set # CONFIG_AUDIT is not set
CONFIG_IKCONFIG=y CONFIG_IKCONFIG=y
@ -749,7 +750,7 @@ CONFIG_VIDEO_V4L2=y
# USB support # USB support
# #
CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_USB_ARCH_HAS_OHCI is not set CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_USB_ARCH_HAS_EHCI is not set # CONFIG_USB_ARCH_HAS_EHCI is not set
CONFIG_USB=y CONFIG_USB=y
CONFIG_USB_DEBUG=y CONFIG_USB_DEBUG=y
@ -766,6 +767,9 @@ CONFIG_USB_DYNAMIC_MINORS=y
# USB Host Controller Drivers # USB Host Controller Drivers
# #
# CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_SL811_HCD is not set # CONFIG_USB_SL811_HCD is not set
# #
@ -855,6 +859,7 @@ CONFIG_USB_SERIAL_CONSOLE=y
CONFIG_USB_SERIAL_PL2303=y CONFIG_USB_SERIAL_PL2303=y
# CONFIG_USB_SERIAL_HP4X is not set # CONFIG_USB_SERIAL_HP4X is not set
# CONFIG_USB_SERIAL_SAFE is not set # CONFIG_USB_SERIAL_SAFE is not set
# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
# CONFIG_USB_SERIAL_TI is not set # CONFIG_USB_SERIAL_TI is not set
# CONFIG_USB_SERIAL_CYBERJACK is not set # CONFIG_USB_SERIAL_CYBERJACK is not set
# CONFIG_USB_SERIAL_XIRCOM is not set # CONFIG_USB_SERIAL_XIRCOM is not set
@ -871,7 +876,7 @@ CONFIG_USB_SERIAL_PL2303=y
# CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set # CONFIG_USB_LCD is not set
# CONFIG_USB_LED 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_CYTHERM is not set
# CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_PHIDGETSERVO is not set
@ -916,6 +921,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_X1205 is not set # CONFIG_RTC_DRV_X1205 is not set
# CONFIG_RTC_DRV_DS1307 is not set # CONFIG_RTC_DRV_DS1307 is not set
# CONFIG_RTC_DRV_DS1553 is not set # CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_ISL1208 is not set
# CONFIG_RTC_DRV_DS1672 is not set # CONFIG_RTC_DRV_DS1672 is not set
# CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8563 is not set
@ -1023,7 +1029,6 @@ CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set # CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set # CONFIG_CIFS is not set
# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_NCP_FS is not set # CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set # CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set # CONFIG_AFS_FS is not set

View File

@ -114,9 +114,9 @@ ENTRY(secondary_startup)
* Use the page tables supplied from __cpu_up. * Use the page tables supplied from __cpu_up.
*/ */
adr r4, __secondary_data adr r4, __secondary_data
ldmia r4, {r5, r6, r13} @ address to jump to after ldmia r4, {r5, r7, r13} @ address to jump to after
sub r4, r4, r5 @ mmu has been enabled sub r4, r4, r5 @ mmu has been enabled
ldr r4, [r6, r4] @ get secondary_data.pgdir ldr r4, [r7, r4] @ get secondary_data.pgdir
adr lr, __enable_mmu @ return address adr lr, __enable_mmu @ return address
add pc, r10, #12 @ initialise processor add pc, r10, #12 @ initialise processor
@ (return control reg) @ (return control reg)
@ -125,7 +125,7 @@ ENTRY(secondary_startup)
* r6 = &secondary_data * r6 = &secondary_data
*/ */
ENTRY(__secondary_switched) ENTRY(__secondary_switched)
ldr sp, [r6, #4] @ get secondary_data.stack ldr sp, [r7, #4] @ get secondary_data.stack
mov fp, #0 mov fp, #0
b secondary_start_kernel b secondary_start_kernel

View File

@ -8,7 +8,7 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/tty.h> #include <linux/screen_info.h>
#include <asm/hardware/dec21285.h> #include <asm/hardware/dec21285.h>
#include <asm/io.h> #include <asm/io.h>

View File

@ -60,11 +60,12 @@ static struct map_desc anubis_iodesc[] __initdata = {
.virtual = (u32)S3C24XX_VA_ISA_BYTE, .virtual = (u32)S3C24XX_VA_ISA_BYTE,
.pfn = __phys_to_pfn(0x0), .pfn = __phys_to_pfn(0x0),
.length = SZ_4M, .length = SZ_4M,
.type = MT_DEVICE .type = MT_DEVICE,
}, { }, {
.virtual = (u32)S3C24XX_VA_ISA_WORD, .virtual = (u32)S3C24XX_VA_ISA_WORD,
.pfn = __phys_to_pfn(0x0), .pfn = __phys_to_pfn(0x0),
.length = SZ_4M, MT_DEVICE .length = SZ_4M,
.type = MT_DEVICE,
}, },
/* we could possibly compress the next set down into a set of smaller tables /* we could possibly compress the next set down into a set of smaller tables
@ -78,36 +79,12 @@ static struct map_desc anubis_iodesc[] __initdata = {
.virtual = (u32)ANUBIS_VA_CTRL1, .virtual = (u32)ANUBIS_VA_CTRL1,
.pfn = __phys_to_pfn(ANUBIS_PA_CTRL1), .pfn = __phys_to_pfn(ANUBIS_PA_CTRL1),
.length = SZ_4K, .length = SZ_4K,
.type = MT_DEVICE .type = MT_DEVICE,
}, { }, {
.virtual = (u32)ANUBIS_VA_CTRL2, .virtual = (u32)ANUBIS_VA_CTRL2,
.pfn = __phys_to_pfn(ANUBIS_PA_CTRL2), .pfn = __phys_to_pfn(ANUBIS_PA_CTRL2),
.length = SZ_4K, .length = SZ_4K,
.type =MT_DEVICE .type = MT_DEVICE,
},
/* IDE drives */
{
.virtual = (u32)ANUBIS_IDEPRI,
.pfn = __phys_to_pfn(S3C2410_CS3),
.length = SZ_1M,
.type = MT_DEVICE
}, {
.virtual = (u32)ANUBIS_IDEPRIAUX,
.pfn = __phys_to_pfn(S3C2410_CS3+(1<<26)),
.length = SZ_1M,
.type = MT_DEVICE
}, {
.virtual = (u32)ANUBIS_IDESEC,
.pfn = __phys_to_pfn(S3C2410_CS4),
.length = SZ_1M,
.type = MT_DEVICE
}, {
.virtual = (u32)ANUBIS_IDESECAUX,
.pfn = __phys_to_pfn(S3C2410_CS4+(1<<26)),
.length = SZ_1M,
.type = MT_DEVICE
}, },
}; };
@ -126,7 +103,7 @@ static struct s3c24xx_uart_clksrc anubis_serial_clocks[] = {
.name = "pclk", .name = "pclk",
.divisor = 1, .divisor = 1,
.min_baud = 0, .min_baud = 0,
.max_baud = 0. .max_baud = 0,
} }
}; };
@ -139,7 +116,7 @@ static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
.ulcon = ULCON, .ulcon = ULCON,
.ufcon = UFCON, .ufcon = UFCON,
.clocks = anubis_serial_clocks, .clocks = anubis_serial_clocks,
.clocks_size = ARRAY_SIZE(anubis_serial_clocks) .clocks_size = ARRAY_SIZE(anubis_serial_clocks),
}, },
[1] = { [1] = {
.hwport = 2, .hwport = 2,
@ -148,7 +125,7 @@ static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
.ulcon = ULCON, .ulcon = ULCON,
.ufcon = UFCON, .ufcon = UFCON,
.clocks = anubis_serial_clocks, .clocks = anubis_serial_clocks,
.clocks_size = ARRAY_SIZE(anubis_serial_clocks) .clocks_size = ARRAY_SIZE(anubis_serial_clocks),
}, },
}; };
@ -162,7 +139,7 @@ static struct mtd_partition anubis_default_nand_part[] = {
[0] = { [0] = {
.name = "Boot Agent", .name = "Boot Agent",
.size = SZ_16K, .size = SZ_16K,
.offset = 0 .offset = 0,
}, },
[1] = { [1] = {
.name = "/boot", .name = "/boot",
@ -194,21 +171,21 @@ static struct s3c2410_nand_set anubis_nand_sets[] = {
.nr_chips = 1, .nr_chips = 1,
.nr_map = external_map, .nr_map = external_map,
.nr_partitions = ARRAY_SIZE(anubis_default_nand_part), .nr_partitions = ARRAY_SIZE(anubis_default_nand_part),
.partitions = anubis_default_nand_part .partitions = anubis_default_nand_part,
}, },
[0] = { [0] = {
.name = "chip0", .name = "chip0",
.nr_chips = 1, .nr_chips = 1,
.nr_map = chip0_map, .nr_map = chip0_map,
.nr_partitions = ARRAY_SIZE(anubis_default_nand_part), .nr_partitions = ARRAY_SIZE(anubis_default_nand_part),
.partitions = anubis_default_nand_part .partitions = anubis_default_nand_part,
}, },
[2] = { [2] = {
.name = "chip1", .name = "chip1",
.nr_chips = 1, .nr_chips = 1,
.nr_map = chip1_map, .nr_map = chip1_map,
.nr_partitions = ARRAY_SIZE(anubis_default_nand_part), .nr_partitions = ARRAY_SIZE(anubis_default_nand_part),
.partitions = anubis_default_nand_part .partitions = anubis_default_nand_part,
}, },
}; };
@ -313,7 +290,7 @@ static struct s3c24xx_board anubis_board __initdata = {
.devices = anubis_devices, .devices = anubis_devices,
.devices_count = ARRAY_SIZE(anubis_devices), .devices_count = ARRAY_SIZE(anubis_devices),
.clocks = anubis_clocks, .clocks = anubis_clocks,
.clocks_count = ARRAY_SIZE(anubis_clocks) .clocks_count = ARRAY_SIZE(anubis_clocks),
}; };
static void __init anubis_map_io(void) static void __init anubis_map_io(void)

View File

@ -67,12 +67,12 @@ static struct map_desc osiris_iodesc[] __initdata = {
.virtual = (u32)OSIRIS_VA_CTRL1, .virtual = (u32)OSIRIS_VA_CTRL1,
.pfn = __phys_to_pfn(OSIRIS_PA_CTRL1), .pfn = __phys_to_pfn(OSIRIS_PA_CTRL1),
.length = SZ_16K, .length = SZ_16K,
.type = MT_DEVICE .type = MT_DEVICE,
}, { }, {
.virtual = (u32)OSIRIS_VA_CTRL2, .virtual = (u32)OSIRIS_VA_CTRL2,
.pfn = __phys_to_pfn(OSIRIS_PA_CTRL2), .pfn = __phys_to_pfn(OSIRIS_PA_CTRL2),
.length = SZ_16K, .length = SZ_16K,
.type = MT_DEVICE .type = MT_DEVICE,
}, },
}; };
@ -91,7 +91,7 @@ static struct s3c24xx_uart_clksrc osiris_serial_clocks[] = {
.name = "pclk", .name = "pclk",
.divisor = 1, .divisor = 1,
.min_baud = 0, .min_baud = 0,
.max_baud = 0. .max_baud = 0,
} }
}; };
@ -103,7 +103,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
.ulcon = ULCON, .ulcon = ULCON,
.ufcon = UFCON, .ufcon = UFCON,
.clocks = osiris_serial_clocks, .clocks = osiris_serial_clocks,
.clocks_size = ARRAY_SIZE(osiris_serial_clocks) .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
}, },
[1] = { [1] = {
.hwport = 1, .hwport = 1,
@ -112,7 +112,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
.ulcon = ULCON, .ulcon = ULCON,
.ufcon = UFCON, .ufcon = UFCON,
.clocks = osiris_serial_clocks, .clocks = osiris_serial_clocks,
.clocks_size = ARRAY_SIZE(osiris_serial_clocks) .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
}, },
}; };
@ -126,7 +126,7 @@ static struct mtd_partition osiris_default_nand_part[] = {
[0] = { [0] = {
.name = "Boot Agent", .name = "Boot Agent",
.size = SZ_16K, .size = SZ_16K,
.offset = 0 .offset = 0,
}, },
[1] = { [1] = {
.name = "/boot", .name = "/boot",
@ -158,21 +158,21 @@ static struct s3c2410_nand_set osiris_nand_sets[] = {
.nr_chips = 1, .nr_chips = 1,
.nr_map = external_map, .nr_map = external_map,
.nr_partitions = ARRAY_SIZE(osiris_default_nand_part), .nr_partitions = ARRAY_SIZE(osiris_default_nand_part),
.partitions = osiris_default_nand_part .partitions = osiris_default_nand_part,
}, },
[0] = { [0] = {
.name = "chip0", .name = "chip0",
.nr_chips = 1, .nr_chips = 1,
.nr_map = chip0_map, .nr_map = chip0_map,
.nr_partitions = ARRAY_SIZE(osiris_default_nand_part), .nr_partitions = ARRAY_SIZE(osiris_default_nand_part),
.partitions = osiris_default_nand_part .partitions = osiris_default_nand_part,
}, },
[2] = { [2] = {
.name = "chip1", .name = "chip1",
.nr_chips = 1, .nr_chips = 1,
.nr_map = chip1_map, .nr_map = chip1_map,
.nr_partitions = ARRAY_SIZE(osiris_default_nand_part), .nr_partitions = ARRAY_SIZE(osiris_default_nand_part),
.partitions = osiris_default_nand_part .partitions = osiris_default_nand_part,
}, },
}; };
@ -245,7 +245,7 @@ static struct s3c24xx_board osiris_board __initdata = {
.devices = osiris_devices, .devices = osiris_devices,
.devices_count = ARRAY_SIZE(osiris_devices), .devices_count = ARRAY_SIZE(osiris_devices),
.clocks = osiris_clocks, .clocks = osiris_clocks,
.clocks_count = ARRAY_SIZE(osiris_clocks) .clocks_count = ARRAY_SIZE(osiris_clocks),
}; };
static void __init osiris_map_io(void) static void __init osiris_map_io(void)

View File

@ -363,7 +363,9 @@ EXPORT_SYMBOL(__ioremap);
void __iounmap(void __iomem *addr) void __iounmap(void __iomem *addr)
{ {
#ifndef CONFIG_SMP
struct vm_struct **p, *tmp; struct vm_struct **p, *tmp;
#endif
unsigned int section_mapping = 0; unsigned int section_mapping = 0;
addr = (void __iomem *)(PAGE_MASK & (unsigned long)addr); addr = (void __iomem *)(PAGE_MASK & (unsigned long)addr);

View File

@ -13,6 +13,7 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/proc-fns.h> #include <asm/proc-fns.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <asm/page.h>
#ifndef MULTI_CPU #ifndef MULTI_CPU
EXPORT_SYMBOL(cpu_dcache_clean_area); EXPORT_SYMBOL(cpu_dcache_clean_area);
@ -30,6 +31,13 @@ EXPORT_SYMBOL(__cpuc_coherent_kern_range);
EXPORT_SYMBOL(cpu_cache); EXPORT_SYMBOL(cpu_cache);
#endif #endif
#ifndef MULTI_USER
EXPORT_SYMBOL(__cpu_clear_user_page);
EXPORT_SYMBOL(__cpu_copy_user_page);
#else
EXPORT_SYMBOL(cpu_user);
#endif
/* /*
* No module should need to touch the TLB (and currently * No module should need to touch the TLB (and currently
* no modules do. We export this for "loadkernel" support * no modules do. We export this for "loadkernel" support

View File

@ -536,6 +536,11 @@ cpu_80200_name:
.asciz "XScale-80200" .asciz "XScale-80200"
.size cpu_80200_name, . - cpu_80200_name .size cpu_80200_name, . - cpu_80200_name
.type cpu_80219_name, #object
cpu_80219_name:
.asciz "XScale-80219"
.size cpu_80219_name, . - cpu_80219_name
.type cpu_8032x_name, #object .type cpu_8032x_name, #object
cpu_8032x_name: cpu_8032x_name:
.asciz "XScale-IOP8032x Family" .asciz "XScale-IOP8032x Family"
@ -613,10 +618,33 @@ __80200_proc_info:
.long xscale_cache_fns .long xscale_cache_fns
.size __80200_proc_info, . - __80200_proc_info .size __80200_proc_info, . - __80200_proc_info
.type __80219_proc_info,#object
__80219_proc_info:
.long 0x69052e20
.long 0xffffffe0
.long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
.long PMD_TYPE_SECT | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
b __xscale_setup
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
.long cpu_80219_name
.long xscale_processor_functions
.long v4wbi_tlb_fns
.long xscale_mc_user_fns
.long xscale_cache_fns
.size __80219_proc_info, . - __80219_proc_info
.type __8032x_proc_info,#object .type __8032x_proc_info,#object
__8032x_proc_info: __8032x_proc_info:
.long 0x69052420 .long 0x69052420
.long 0xfffff5e0 @ mask should accomodate IOP80219 also .long 0xffffffe0
.long PMD_TYPE_SECT | \ .long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \ PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \ PMD_SECT_CACHEABLE | \

View File

@ -690,8 +690,8 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
/* /*
* Now maybe handle debug registers and/or IO bitmaps * Now maybe handle debug registers and/or IO bitmaps
*/ */
if (unlikely((task_thread_info(next_p)->flags & _TIF_WORK_CTXSW)) if (unlikely((task_thread_info(next_p)->flags & _TIF_WORK_CTXSW)
|| test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) || test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)))
__switch_to_xtra(next_p, tss); __switch_to_xtra(next_p, tss);
disable_tsc(prev_p, next_p); disable_tsc(prev_p, next_p);

View File

@ -135,7 +135,7 @@ unsigned long profile_pc(struct pt_regs *regs)
{ {
unsigned long pc = instruction_pointer(regs); unsigned long pc = instruction_pointer(regs);
if (in_lock_functions(pc)) if (!user_mode_vm(regs) && in_lock_functions(pc))
return *(unsigned long *)(regs->ebp + 4); return *(unsigned long *)(regs->ebp + 4);
return pc; return pc;

View File

@ -187,10 +187,21 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
if (unwind_init_blocked(&info, task) == 0) if (unwind_init_blocked(&info, task) == 0)
unw_ret = show_trace_unwind(&info, log_lvl); unw_ret = show_trace_unwind(&info, log_lvl);
} }
if (unw_ret > 0) { if (unw_ret > 0 && !arch_unw_user_mode(&info)) {
if (call_trace > 0) #ifdef CONFIG_STACK_UNWIND
print_symbol("DWARF2 unwinder stuck at %s\n",
UNW_PC(&info));
if (call_trace == 1) {
printk("Leftover inexact backtrace:\n");
if (UNW_SP(&info))
stack = (void *)UNW_SP(&info);
} else if (call_trace > 1)
return; return;
printk("%sLegacy call trace:\n", log_lvl); else
printk("Full inexact backtrace again:\n");
#else
printk("Inexact backtrace:\n");
#endif
} }
} }
@ -1238,8 +1249,10 @@ static int __init call_trace_setup(char *s)
call_trace = -1; call_trace = -1;
else if (strcmp(s, "both") == 0) else if (strcmp(s, "both") == 0)
call_trace = 0; call_trace = 0;
else if (strcmp(s, "new") == 0) else if (strcmp(s, "newfallback") == 0)
call_trace = 1; call_trace = 1;
else if (strcmp(s, "new") == 2)
call_trace = 2;
return 1; return 1;
} }
__setup("call_trace=", call_trace_setup); __setup("call_trace=", call_trace_setup);

View File

@ -1,13 +1,16 @@
# #
# Automatically generated make config: don't edit # Automatically generated make config: don't edit
# Linux kernel version: 2.6.17-rc1 # Linux kernel version: 2.6.18-rc2
# Mon Apr 3 14:34:15 2006 # Thu Jul 27 13:51:07 2006
# #
CONFIG_MMU=y CONFIG_MMU=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_S390=y CONFIG_S390=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
# #
# Code maturity level options # Code maturity level options
@ -25,6 +28,7 @@ CONFIG_SWAP=y
CONFIG_SYSVIPC=y CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
CONFIG_SYSCTL=y CONFIG_SYSCTL=y
CONFIG_AUDIT=y CONFIG_AUDIT=y
# CONFIG_AUDITSYSCALL is not set # CONFIG_AUDITSYSCALL is not set
@ -43,10 +47,12 @@ CONFIG_PRINTK=y
CONFIG_BUG=y CONFIG_BUG=y
CONFIG_ELF_CORE=y CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y CONFIG_BASE_FULL=y
CONFIG_RT_MUTEXES=y
CONFIG_FUTEX=y CONFIG_FUTEX=y
CONFIG_EPOLL=y CONFIG_EPOLL=y
CONFIG_SHMEM=y CONFIG_SHMEM=y
CONFIG_SLAB=y CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
# CONFIG_TINY_SHMEM is not set # CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0 CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set # CONFIG_SLOB is not set
@ -94,7 +100,6 @@ CONFIG_HOTPLUG_CPU=y
CONFIG_DEFAULT_MIGRATION_COST=1000000 CONFIG_DEFAULT_MIGRATION_COST=1000000
CONFIG_COMPAT=y CONFIG_COMPAT=y
CONFIG_SYSVIPC_COMPAT=y CONFIG_SYSVIPC_COMPAT=y
CONFIG_BINFMT_ELF32=y
# #
# Code generation options # Code generation options
@ -115,6 +120,7 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set # CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_RESOURCES_64BIT=y
# #
# I/O subsystem configuration # I/O subsystem configuration
@ -142,6 +148,7 @@ CONFIG_VIRT_CPU_ACCOUNTING=y
# CONFIG_APPLDATA_BASE is not set # CONFIG_APPLDATA_BASE is not set
CONFIG_NO_IDLE_HZ=y CONFIG_NO_IDLE_HZ=y
CONFIG_NO_IDLE_HZ_INIT=y CONFIG_NO_IDLE_HZ_INIT=y
CONFIG_S390_HYPFS_FS=y
CONFIG_KEXEC=y CONFIG_KEXEC=y
# #
@ -174,6 +181,8 @@ CONFIG_IP_FIB_HASH=y
# CONFIG_INET_IPCOMP is not set # CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set # CONFIG_INET_TUNNEL is not set
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_DIAG=y CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set # CONFIG_TCP_CONG_ADVANCED is not set
@ -186,7 +195,10 @@ CONFIG_IPV6=y
# CONFIG_INET6_IPCOMP is not set # CONFIG_INET6_IPCOMP is not set
# CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set
CONFIG_INET6_XFRM_MODE_TRANSPORT=y
CONFIG_INET6_XFRM_MODE_TUNNEL=y
# CONFIG_IPV6_TUNNEL is not set # CONFIG_IPV6_TUNNEL is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set # CONFIG_NETFILTER is not set
# #
@ -263,6 +275,7 @@ CONFIG_NET_ESTIMATOR=y
# Network testing # Network testing
# #
# CONFIG_NET_PKTGEN is not set # CONFIG_NET_PKTGEN is not set
# CONFIG_NET_TCPPROBE is not set
# CONFIG_HAMRADIO is not set # CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set # CONFIG_IRDA is not set
# CONFIG_BT is not set # CONFIG_BT is not set
@ -276,6 +289,7 @@ CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set # CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DRIVER is not set
CONFIG_SYS_HYPERVISOR=y
# #
# Connector - unified userspace <-> kernelspace linker # Connector - unified userspace <-> kernelspace linker
@ -334,6 +348,7 @@ CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set # CONFIG_CDROM_PKTCDVD is not set
@ -359,9 +374,7 @@ CONFIG_MD_LINEAR=m
CONFIG_MD_RAID0=m CONFIG_MD_RAID0=m
CONFIG_MD_RAID1=m CONFIG_MD_RAID1=m
# CONFIG_MD_RAID10 is not set # CONFIG_MD_RAID10 is not set
CONFIG_MD_RAID5=m # CONFIG_MD_RAID456 is not set
# CONFIG_MD_RAID5_RESHAPE is not set
# CONFIG_MD_RAID6 is not set
CONFIG_MD_MULTIPATH=m CONFIG_MD_MULTIPATH=m
# CONFIG_MD_FAULTY is not set # CONFIG_MD_FAULTY is not set
CONFIG_BLK_DEV_DM=y CONFIG_BLK_DEV_DM=y
@ -419,7 +432,8 @@ CONFIG_S390_TAPE_34XX=m
# #
# Cryptographic devices # Cryptographic devices
# #
CONFIG_Z90CRYPT=m CONFIG_ZCRYPT=m
# CONFIG_ZCRYPT_MONOLITHIC is not set
# #
# Network device support # Network device support
@ -509,6 +523,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_MINIX_FS is not set # CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set # CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set # CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS_FS is not set
@ -614,26 +629,36 @@ CONFIG_MSDOS_PARTITION=y
# Instrumentation Support # Instrumentation Support
# #
# CONFIG_PROFILING is not set # CONFIG_PROFILING is not set
# CONFIG_STATISTICS is not set CONFIG_STATISTICS=y
CONFIG_KPROBES=y
# #
# Kernel hacking # Kernel hacking
# #
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set # CONFIG_PRINTK_TIME is not set
CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=17 CONFIG_LOG_BUF_SHIFT=17
# CONFIG_DETECT_SOFTLOCKUP is not set # CONFIG_DETECT_SOFTLOCKUP is not set
# CONFIG_SCHEDSTATS is not set # CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SLAB is not set
CONFIG_DEBUG_PREEMPT=y CONFIG_DEBUG_PREEMPT=y
CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_RWSEMS is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
CONFIG_DEBUG_SPINLOCK_SLEEP=y CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_INFO is not set
CONFIG_DEBUG_FS=y CONFIG_DEBUG_FS=y
# CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_VM is not set
# CONFIG_FRAME_POINTER is not set
# CONFIG_UNWIND_INFO is not set # CONFIG_UNWIND_INFO is not set
CONFIG_FORCED_INLINING=y CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_TORTURE_TEST is not set
@ -688,3 +713,4 @@ CONFIG_CRYPTO=y
# CONFIG_CRC16 is not set # CONFIG_CRC16 is not set
CONFIG_CRC32=m CONFIG_CRC32=m
# CONFIG_LIBCRC32C is not set # CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y

View File

@ -273,7 +273,7 @@ startup_continue:
.Lbss_end: .long _end .Lbss_end: .long _end
.Lparmaddr: .long PARMAREA .Lparmaddr: .long PARMAREA
.Lsccbaddr: .long .Lsccb .Lsccbaddr: .long .Lsccb
.align 4096 .org 0x12000
.Lsccb: .Lsccb:
.hword 0x1000 # length, one page .hword 0x1000 # length, one page
.byte 0x00,0x00,0x00 .byte 0x00,0x00,0x00
@ -290,7 +290,7 @@ startup_continue:
.Lscpincr2: .Lscpincr2:
.quad 0x00 .quad 0x00
.fill 3984,1,0 .fill 3984,1,0
.align 4096 .org 0x13000
#ifdef CONFIG_SHARED_KERNEL #ifdef CONFIG_SHARED_KERNEL
.org 0x100000 .org 0x100000

View File

@ -268,7 +268,7 @@ startup_continue:
.Lparmaddr: .Lparmaddr:
.quad PARMAREA .quad PARMAREA
.align 4096 .org 0x12000
.Lsccb: .Lsccb:
.hword 0x1000 # length, one page .hword 0x1000 # length, one page
.byte 0x00,0x00,0x00 .byte 0x00,0x00,0x00
@ -285,7 +285,7 @@ startup_continue:
.Lscpincr2: .Lscpincr2:
.quad 0x00 .quad 0x00
.fill 3984,1,0 .fill 3984,1,0
.align 4096 .org 0x13000
#ifdef CONFIG_SHARED_KERNEL #ifdef CONFIG_SHARED_KERNEL
.org 0x100000 .org 0x100000

View File

@ -877,31 +877,57 @@ static struct bin_attribute ipl_scp_data_attr = {
static decl_subsys(ipl, NULL, NULL); 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 static int __init
ipl_device_sysfs_register(void) { ipl_device_sysfs_register(void) {
int rc; int rc;
rc = firmware_register(&ipl_subsys); rc = firmware_register(&ipl_subsys);
if (rc) if (rc)
return rc; goto out;
switch (get_ipl_type()) { switch (get_ipl_type()) {
case ipl_type_ccw: 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; break;
case ipl_type_fcp: case ipl_type_fcp:
sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group); rc = ipl_register_fcp_files();
sysfs_create_bin_file(&ipl_subsys.kset.kobj,
&ipl_parameter_attr);
sysfs_create_bin_file(&ipl_subsys.kset.kobj,
&ipl_scp_data_attr);
break; break;
default: default:
sysfs_create_group(&ipl_subsys.kset.kobj, rc = sysfs_create_group(&ipl_subsys.kset.kobj,
&ipl_unknown_attr_group); &ipl_unknown_attr_group);
break; break;
} }
return 0;
if (rc)
firmware_unregister(&ipl_subsys);
out:
return rc;
} }
__initcall(ipl_device_sysfs_register); __initcall(ipl_device_sysfs_register);

View File

@ -15,6 +15,7 @@
#include <asm/page.h> #include <asm/page.h>
#include <asm/oplib.h> #include <asm/oplib.h>
#include <asm/prom.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/cpudata.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 (*compare)(int, int, void *), void *compare_arg,
int *prom_node, int *mid) 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 (!compare(nd, *cur_inst, compare_arg)) {
if (prom_node) if (prom_node)
*prom_node = nd; *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, static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg,
int *prom_node, int *mid) int *prom_node, int *mid)
{ {
int nd, cur_inst, err; struct device_node *dp;
int cur_inst;
nd = prom_root_node;
cur_inst = 0; cur_inst = 0;
for_each_node_by_type(dp, "cpu") {
err = check_cpu_node(nd, &cur_inst, compare, compare_arg, int err = check_cpu_node(dp->node, &cur_inst,
prom_node, mid); compare, compare_arg,
if (!err) prom_node, mid);
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);
if (!err) if (!err)
return 0; return 0;
} }

View File

@ -329,7 +329,7 @@ void handler_irq(int irq, struct pt_regs * regs)
disable_pil_irq(irq); disable_pil_irq(irq);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* Only rotate on lower priority IRQ's (scsi, ethernet, etc.). */ /* Only rotate on lower priority IRQ's (scsi, ethernet, etc.). */
if(irq < 10) if((sparc_cpu_model==sun4m) && (irq < 10))
smp4m_irq_rotate(cpu); smp4m_irq_rotate(cpu);
#endif #endif
action = sparc_irq[irq].action; action = sparc_irq[irq].action;

View File

@ -596,14 +596,41 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
static int pil_to_sbus[] = { static int pil_to_sbus[] = {
0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0, 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; struct linux_prom_registers *regs;
int board = of_getintprop_default(busp, "board#", 0); int board, slot;
int slot;
while (sbi) {
if (!strcmp(sbi->name, "sbi"))
break;
sbi = sbi->parent;
}
if (!sbi)
goto build_resources;
regs = of_get_property(dp, "reg", NULL); regs = of_get_property(dp, "reg", NULL);
if (!regs)
goto build_resources;
slot = regs->which_io; 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++) { for (i = 0; i < op->num_irqs; i++) {
int this_irq = op->irqs[i]; int this_irq = op->irqs[i];
int sbusl = pil_to_sbus[this_irq]; 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); build_device_resources(op, parent);
op->dev.parent = parent; op->dev.parent = parent;

View File

@ -444,6 +444,7 @@ static struct property * __init build_one_prop(phandle node, char *prev, char *s
static struct property *tmp = NULL; static struct property *tmp = NULL;
struct property *p; struct property *p;
int len; int len;
const char *name;
if (tmp) { if (tmp) {
p = 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); p->name = (char *) (p + 1);
if (special_name) { if (special_name) {
strcpy(p->name, special_name);
p->length = special_len; p->length = special_len;
p->value = prom_early_alloc(special_len); p->value = prom_early_alloc(special_len);
memcpy(p->value, special_val, special_len); memcpy(p->value, special_val, special_len);
} else { } else {
if (prev == NULL) { if (prev == NULL) {
prom_firstprop(node, p->name); name = prom_firstprop(node, NULL);
} else { } else {
prom_nextprop(node, prev, p->name); name = prom_nextprop(node, prev, NULL);
} }
if (strlen(p->name) == 0) { if (strlen(name) == 0) {
tmp = p; tmp = p;
return NULL; return NULL;
} }
strcpy(p->name, name);
p->length = prom_getproplen(node, p->name); p->length = prom_getproplen(node, p->name);
if (p->length <= 0) { if (p->length <= 0) {
p->length = 0; p->length = 0;

View File

@ -87,6 +87,7 @@ void __cpuinit smp_store_cpu_info(int id)
void __init smp_cpus_done(unsigned int max_cpus) void __init smp_cpus_done(unsigned int max_cpus)
{ {
extern void smp4m_smp_done(void); extern void smp4m_smp_done(void);
extern void smp4d_smp_done(void);
unsigned long bogosum = 0; unsigned long bogosum = 0;
int cpu, num; int cpu, num;
@ -100,8 +101,34 @@ void __init smp_cpus_done(unsigned int max_cpus)
num, bogosum/(500000/HZ), num, bogosum/(500000/HZ),
(bogosum/(5000/HZ))%100); (bogosum/(5000/HZ))%100);
BUG_ON(sparc_cpu_model != sun4m); switch(sparc_cpu_model) {
smp4m_smp_done(); 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) void cpu_panic(void)
@ -267,9 +294,9 @@ int setup_profiling_timer(unsigned int multiplier)
void __init smp_prepare_cpus(unsigned int max_cpus) void __init smp_prepare_cpus(unsigned int max_cpus)
{ {
extern void smp4m_boot_cpus(void); extern void smp4m_boot_cpus(void);
extern void smp4d_boot_cpus(void);
int i, cpuid, extra; int i, cpuid, extra;
BUG_ON(sparc_cpu_model != sun4m);
printk("Entering SMP Mode...\n"); printk("Entering SMP Mode...\n");
extra = 0; extra = 0;
@ -283,7 +310,34 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
smp_store_cpu_info(boot_cpu_id); 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 /* 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) int __cpuinit __cpu_up(unsigned int cpu)
{ {
extern int smp4m_boot_one_cpu(int); extern int smp4m_boot_one_cpu(int);
int ret; extern int smp4d_boot_one_cpu(int);
int ret=0;
ret = smp4m_boot_one_cpu(cpu); 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) { if (!ret) {
cpu_set(cpu, smp_commenced_mask); cpu_set(cpu, smp_commenced_mask);

View File

@ -237,7 +237,6 @@ EXPORT_SYMBOL(prom_node_has_property);
EXPORT_SYMBOL(prom_setprop); EXPORT_SYMBOL(prom_setprop);
EXPORT_SYMBOL(saved_command_line); EXPORT_SYMBOL(saved_command_line);
EXPORT_SYMBOL(prom_apply_obio_ranges); EXPORT_SYMBOL(prom_apply_obio_ranges);
EXPORT_SYMBOL(prom_getname);
EXPORT_SYMBOL(prom_feval); EXPORT_SYMBOL(prom_feval);
EXPORT_SYMBOL(prom_getbool); EXPORT_SYMBOL(prom_getbool);
EXPORT_SYMBOL(prom_getstring); EXPORT_SYMBOL(prom_getstring);

View File

@ -43,15 +43,10 @@ extern ctxd_t *srmmu_ctx_table_phys;
extern void calibrate_delay(void); extern void calibrate_delay(void);
extern volatile int smp_processors_ready; extern volatile int smp_processors_ready;
extern int smp_num_cpus;
static int smp_highest_cpu; static int smp_highest_cpu;
extern volatile unsigned long cpu_callin_map[NR_CPUS]; extern volatile unsigned long cpu_callin_map[NR_CPUS];
extern cpuinfo_sparc cpu_data[NR_CPUS]; extern cpuinfo_sparc cpu_data[NR_CPUS];
extern unsigned char boot_cpu_id; 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 volatile int smp_process_available;
extern cpumask_t smp_commenced_mask; extern cpumask_t smp_commenced_mask;
@ -144,6 +139,8 @@ void __init smp4d_callin(void)
spin_lock_irqsave(&sun4d_imsk_lock, flags); spin_lock_irqsave(&sun4d_imsk_lock, flags);
cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */ cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */
spin_unlock_irqrestore(&sun4d_imsk_lock, flags); spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
cpu_set(cpuid, cpu_online_map);
} }
extern void init_IRQ(void); extern void init_IRQ(void);
@ -160,51 +157,24 @@ extern unsigned long trapbase_cpu3[];
void __init smp4d_boot_cpus(void) void __init smp4d_boot_cpus(void)
{ {
int cpucount = 0;
int i, mid;
printk("Entering SMP Mode...\n");
if (boot_cpu_id) if (boot_cpu_id)
current_set[0] = NULL; 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(); smp_setup_percpu_timer();
local_flush_cache_all(); 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; extern unsigned long sun4d_cpu_startup;
unsigned long *entry = &sun4d_cpu_startup; unsigned long *entry = &sun4d_cpu_startup;
struct task_struct *p; struct task_struct *p;
int timeout; int timeout;
int no; int cpu_node;
cpu_find_by_instance(i, &cpu_node,NULL);
/* Cook up an idler for this guy. */ /* Cook up an idler for this guy. */
p = fork_idle(i); p = fork_idle(i);
cpucount++;
current_set[i] = task_thread_info(p); current_set[i] = task_thread_info(p);
for (no = 0; !cpu_find_by_instance(no, NULL, &mid)
&& mid != i; no++) ;
/* /*
* Initialize the contexts table * Initialize the contexts table
@ -216,9 +186,9 @@ void __init smp4d_boot_cpus(void)
smp_penguin_ctable.reg_size = 0; smp_penguin_ctable.reg_size = 0;
/* whirrr, whirrr, whirrrrrrrrr... */ /* 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(); local_flush_cache_all();
prom_startcpu(cpu_data(no).prom_node, prom_startcpu(cpu_node,
&smp_penguin_ctable, 0, (char *)entry); &smp_penguin_ctable, 0, (char *)entry);
SMP_PRINTK(("prom_startcpu returned :)\n")); SMP_PRINTK(("prom_startcpu returned :)\n"));
@ -230,39 +200,30 @@ void __init smp4d_boot_cpus(void)
udelay(200); udelay(200);
} }
if(cpu_callin_map[i]) { if (!(cpu_callin_map[i])) {
/* Another "Red Snapper". */ printk("Processor %d is stuck.\n", i);
__cpu_number_map[i] = cpucount; return -ENODEV;
__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;
}
} }
local_flush_cache_all(); local_flush_cache_all();
if(cpucount == 0) { return 0;
printk("Error: only one Processor found.\n"); }
cpu_present_map = cpumask_of_cpu(hard_smp4d_processor_id());
} else { void __init smp4d_smp_done(void)
unsigned long bogosum = 0; {
int i, first;
for_each_present_cpu(i) { int *prev;
bogosum += cpu_data(i).udelay_val;
smp_highest_cpu = i; /* 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)); *prev = first;
printk("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n", local_flush_cache_all();
cpucount + 1,
bogosum/(500000/HZ),
(bogosum/(5000/HZ))%100);
smp_activated = 1;
smp_num_cpus = cpucount + 1;
}
/* Free unneeded trap tables */ /* Free unneeded trap tables */
ClearPageReserved(virt_to_page(trapbase_cpu1)); 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; register int i;
mask = cpumask_of_cpu(hard_smp4d_processor_id()); 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++) { for(i = 0; i <= high; i++) {
if (cpu_isset(i, mask)) { if (cpu_isset(i, mask)) {
ccall_info.processors_in[i] = 0; ccall_info.processors_in[i] = 0;

View File

@ -465,21 +465,21 @@ sys_rt_sigaction(int sig,
asmlinkage int sys_getdomainname(char __user *name, int len) asmlinkage int sys_getdomainname(char __user *name, int len)
{ {
int nlen; int nlen, err;
int err = -EFAULT;
if (len < 0 || len > __NEW_UTS_LEN)
return -EINVAL;
down_read(&uts_sem); down_read(&uts_sem);
nlen = strlen(system_utsname.domainname) + 1; nlen = strlen(system_utsname.domainname) + 1;
if (nlen < len) if (nlen < len)
len = nlen; len = nlen;
if (len > __NEW_UTS_LEN)
goto done; err = -EFAULT;
if (copy_to_user(name, system_utsname.domainname, len)) if (!copy_to_user(name, system_utsname.domainname, len))
goto done; err = 0;
err = 0;
done:
up_read(&uts_sem); up_read(&uts_sem);
return err; return err;
} }

View File

@ -225,6 +225,32 @@ static __inline__ int has_low_battery(void)
return (data1 == data2); /* Was the write blocked? */ return (data1 == data2); /* Was the write blocked? */
} }
static void __init mostek_set_system_time(void)
{
unsigned int year, mon, day, hour, min, sec;
struct mostek48t02 *mregs;
mregs = (struct mostek48t02 *)mstk48t02_regs;
if(!mregs) {
prom_printf("Something wrong, clock regs not mapped yet.\n");
prom_halt();
}
spin_lock_irq(&mostek_lock);
mregs->creg |= MSTK_CREG_READ;
sec = MSTK_REG_SEC(mregs);
min = MSTK_REG_MIN(mregs);
hour = MSTK_REG_HOUR(mregs);
day = MSTK_REG_DOM(mregs);
mon = MSTK_REG_MONTH(mregs);
year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
set_normalized_timespec(&wall_to_monotonic,
-xtime.tv_sec, -xtime.tv_nsec);
mregs->creg &= ~MSTK_CREG_READ;
spin_unlock_irq(&mostek_lock);
}
/* Probe for the real time clock chip on Sun4 */ /* Probe for the real time clock chip on Sun4 */
static __inline__ void sun4_clock_probe(void) static __inline__ void sun4_clock_probe(void)
{ {
@ -273,6 +299,7 @@ static __inline__ void sun4_clock_probe(void)
#endif #endif
} }
#ifndef CONFIG_SUN4
static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match) static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match)
{ {
struct device_node *dp = op->node; struct device_node *dp = op->node;
@ -307,6 +334,8 @@ static int __devinit clock_probe(struct of_device *op, const struct of_device_id
if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP) if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
kick_start_clock(); kick_start_clock();
mostek_set_system_time();
return 0; return 0;
} }
@ -325,56 +354,37 @@ static struct of_platform_driver clock_driver = {
/* Probe for the mostek real time clock chip. */ /* Probe for the mostek real time clock chip. */
static void clock_init(void) static int __init clock_init(void)
{ {
of_register_driver(&clock_driver, &of_bus_type); return of_register_driver(&clock_driver, &of_bus_type);
} }
/* Must be after subsys_initcall() so that busses are probed. Must
* be before device_initcall() because things like the RTC driver
* need to see the clock registers.
*/
fs_initcall(clock_init);
#endif /* !CONFIG_SUN4 */
void __init sbus_time_init(void) void __init sbus_time_init(void)
{ {
unsigned int year, mon, day, hour, min, sec;
struct mostek48t02 *mregs;
#ifdef CONFIG_SUN4
int temp;
struct intersil *iregs;
#endif
BTFIXUPSET_CALL(bus_do_settimeofday, sbus_do_settimeofday, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(bus_do_settimeofday, sbus_do_settimeofday, BTFIXUPCALL_NORM);
btfixup(); btfixup();
if (ARCH_SUN4) if (ARCH_SUN4)
sun4_clock_probe(); sun4_clock_probe();
else
clock_init();
sparc_init_timers(timer_interrupt); sparc_init_timers(timer_interrupt);
#ifdef CONFIG_SUN4 #ifdef CONFIG_SUN4
if(idprom->id_machtype == (SM_SUN4 | SM_4_330)) { if(idprom->id_machtype == (SM_SUN4 | SM_4_330)) {
#endif mostek_set_system_time();
mregs = (struct mostek48t02 *)mstk48t02_regs;
if(!mregs) {
prom_printf("Something wrong, clock regs not mapped yet.\n");
prom_halt();
}
spin_lock_irq(&mostek_lock);
mregs->creg |= MSTK_CREG_READ;
sec = MSTK_REG_SEC(mregs);
min = MSTK_REG_MIN(mregs);
hour = MSTK_REG_HOUR(mregs);
day = MSTK_REG_DOM(mregs);
mon = MSTK_REG_MONTH(mregs);
year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
set_normalized_timespec(&wall_to_monotonic,
-xtime.tv_sec, -xtime.tv_nsec);
mregs->creg &= ~MSTK_CREG_READ;
spin_unlock_irq(&mostek_lock);
#ifdef CONFIG_SUN4
} else if(idprom->id_machtype == (SM_SUN4 | SM_4_260) ) { } else if(idprom->id_machtype == (SM_SUN4 | SM_4_260) ) {
/* initialise the intersil on sun4 */ /* initialise the intersil on sun4 */
unsigned int year, mon, day, hour, min, sec;
int temp;
struct intersil *iregs;
iregs=intersil_clock; iregs=intersil_clock;
if(!iregs) { if(!iregs) {

View File

@ -64,6 +64,7 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus)
sbus->iommu = (struct iommu_struct *)iounit; sbus->iommu = (struct iommu_struct *)iounit;
iounit->page_table = xpt; iounit->page_table = xpt;
spin_lock_init(&iounit->lock);
for (xptend = iounit->page_table + (16 * PAGE_SIZE) / sizeof(iopte_t); for (xptend = iounit->page_table + (16 * PAGE_SIZE) / sizeof(iopte_t);
xpt < xptend;) xpt < xptend;)

View File

@ -205,24 +205,6 @@ int prom_searchsiblings(int node_start, char *nodename)
return 0; 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. */ /* Interal version of nextprop that does not alter return values. */
char * __prom_nextprop(int node, char * oprop) char * __prom_nextprop(int node, char * oprop)
{ {

View File

@ -1,7 +1,7 @@
# #
# Automatically generated make config: don't edit # Automatically generated make config: don't edit
# Linux kernel version: 2.6.18-rc1 # Linux kernel version: 2.6.18-rc2
# Wed Jul 12 14:00:58 2006 # Fri Jul 21 14:19:24 2006
# #
CONFIG_SPARC=y CONFIG_SPARC=y
CONFIG_SPARC64=y CONFIG_SPARC64=y
@ -36,6 +36,7 @@ CONFIG_SWAP=y
CONFIG_SYSVIPC=y CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
CONFIG_SYSCTL=y CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set # CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set # CONFIG_IKCONFIG is not set
@ -1120,7 +1121,7 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set # CONFIG_USB_LCD is not set
# CONFIG_USB_LED 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_CYTHERM is not set
# CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_PHIDGETSERVO is not set
@ -1279,7 +1280,6 @@ CONFIG_RAMFS=y
# CONFIG_NFSD is not set # CONFIG_NFSD is not set
# CONFIG_SMB_FS is not set # CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set # CONFIG_CIFS is not set
# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_NCP_FS is not set # CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set # CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set # CONFIG_AFS_FS is not set

View File

@ -66,9 +66,6 @@ static int check_cpu_node(struct device_node *dp, int *cur_inst,
void *compare_arg, void *compare_arg,
struct device_node **dev_node, int *mid) struct device_node **dev_node, int *mid)
{ {
if (strcmp(dp->type, "cpu"))
return -ENODEV;
if (!compare(dp, *cur_inst, compare_arg)) { if (!compare(dp, *cur_inst, compare_arg)) {
if (dev_node) if (dev_node)
*dev_node = dp; *dev_node = dp;

View File

@ -542,9 +542,17 @@ static void __init build_device_resources(struct of_device *op,
/* Convert to num-cells. */ /* Convert to num-cells. */
num_reg /= 4; num_reg /= 4;
/* Conver to num-entries. */ /* Convert to num-entries. */
num_reg /= na + ns; 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++) { for (index = 0; index < num_reg; index++) {
struct resource *r = &op->resource[index]; struct resource *r = &op->resource[index];
u32 addr[OF_MAX_ADDR_CELLS]; u32 addr[OF_MAX_ADDR_CELLS];
@ -650,8 +658,22 @@ apply_interrupt_map(struct device_node *dp, struct device_node *pp,
next: next:
imap += (na + 3); 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; return NULL;
}
*irq_p = irq; *irq_p = irq;
cp = of_find_node_by_phandle(handle); 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; 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); build_device_resources(op, parent);
for (i = 0; i < op->num_irqs; i++) for (i = 0; i < op->num_irqs; i++)
op->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]); op->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]);

View File

@ -344,10 +344,12 @@ static unsigned long __psycho_onboard_imap_off[] = {
/*0x2f*/ PSYCHO_IMAP_CE, /*0x2f*/ PSYCHO_IMAP_CE,
/*0x30*/ PSYCHO_IMAP_A_ERR, /*0x30*/ PSYCHO_IMAP_A_ERR,
/*0x31*/ PSYCHO_IMAP_B_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_BASE 0x20
#define PSYCHO_ONBOARD_IRQ_LAST 0x32 #define PSYCHO_ONBOARD_IRQ_LAST 0x34
#define psycho_onboard_imap_offset(__ino) \ #define psycho_onboard_imap_offset(__ino) \
__psycho_onboard_imap_off[(__ino) - PSYCHO_ONBOARD_IRQ_BASE] __psycho_onboard_imap_off[(__ino) - PSYCHO_ONBOARD_IRQ_BASE]
@ -529,6 +531,10 @@ static unsigned long __sabre_onboard_imap_off[] = {
/*0x2e*/ SABRE_IMAP_UE, /*0x2e*/ SABRE_IMAP_UE,
/*0x2f*/ SABRE_IMAP_CE, /*0x2f*/ SABRE_IMAP_CE,
/*0x30*/ SABRE_IMAP_PCIERR, /*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_BASE 0x20
#define SABRE_ONBOARD_IRQ_LAST 0x30 #define SABRE_ONBOARD_IRQ_LAST 0x30
@ -895,6 +901,8 @@ static unsigned long sysio_irq_offsets[] = {
SYSIO_IMAP_CE, SYSIO_IMAP_CE,
SYSIO_IMAP_SBERR, SYSIO_IMAP_SBERR,
SYSIO_IMAP_PMGMT, SYSIO_IMAP_PMGMT,
SYSIO_IMAP_GFX,
SYSIO_IMAP_EUPA,
}; };
#undef bogon #undef bogon

View File

@ -254,7 +254,6 @@ EXPORT_SYMBOL(prom_getproperty);
EXPORT_SYMBOL(prom_node_has_property); EXPORT_SYMBOL(prom_node_has_property);
EXPORT_SYMBOL(prom_setprop); EXPORT_SYMBOL(prom_setprop);
EXPORT_SYMBOL(saved_command_line); EXPORT_SYMBOL(saved_command_line);
EXPORT_SYMBOL(prom_getname);
EXPORT_SYMBOL(prom_finddevice); EXPORT_SYMBOL(prom_finddevice);
EXPORT_SYMBOL(prom_feval); EXPORT_SYMBOL(prom_feval);
EXPORT_SYMBOL(prom_getbool); EXPORT_SYMBOL(prom_getbool);

View File

@ -701,21 +701,21 @@ extern void check_pending(int signum);
asmlinkage long sys_getdomainname(char __user *name, int len) asmlinkage long sys_getdomainname(char __user *name, int len)
{ {
int nlen; int nlen, err;
int err = -EFAULT;
if (len < 0 || len > __NEW_UTS_LEN)
return -EINVAL;
down_read(&uts_sem); down_read(&uts_sem);
nlen = strlen(system_utsname.domainname) + 1; nlen = strlen(system_utsname.domainname) + 1;
if (nlen < len) if (nlen < len)
len = nlen; len = nlen;
if (len > __NEW_UTS_LEN)
goto done; err = -EFAULT;
if (copy_to_user(name, system_utsname.domainname, len)) if (!copy_to_user(name, system_utsname.domainname, len))
goto done; err = 0;
err = 0;
done:
up_read(&uts_sem); up_read(&uts_sem);
return err; return err;
} }

View File

@ -19,6 +19,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/kprobes.h> #include <linux/kprobes.h>
#include <linux/kallsyms.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
@ -132,6 +133,8 @@ static void bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr)
printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n", printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n",
regs->tpc); regs->tpc);
printk(KERN_CRIT "OOPS: RPC [%016lx]\n", regs->u_regs[15]);
print_symbol("RPC: <%s>\n", regs->u_regs[15]);
printk(KERN_CRIT "OOPS: Fault was to vaddr[%lx]\n", vaddr); printk(KERN_CRIT "OOPS: Fault was to vaddr[%lx]\n", vaddr);
__asm__("mov %%sp, %0" : "=r" (ksp)); __asm__("mov %%sp, %0" : "=r" (ksp));
show_stack(current, ksp); show_stack(current, ksp);

View File

@ -193,91 +193,6 @@ prom_searchsiblings(int node_start, const char *nodename)
return 0; 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'. /* Return the first property type for node 'node'.
* buffer should be at least 32B in length * buffer should be at least 32B in length
*/ */

View File

@ -1,7 +1,7 @@
# #
# Automatically generated make config: don't edit # Automatically generated make config: don't edit
# Linux kernel version: 2.6.17-git22 # Linux kernel version: 2.6.18-rc2
# Tue Jul 4 14:24:40 2006 # Tue Jul 18 17:13:20 2006
# #
CONFIG_X86_64=y CONFIG_X86_64=y
CONFIG_64BIT=y CONFIG_64BIT=y
@ -37,6 +37,7 @@ CONFIG_SWAP=y
CONFIG_SYSVIPC=y CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
CONFIG_SYSCTL=y CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set # CONFIG_AUDIT is not set
CONFIG_IKCONFIG=y CONFIG_IKCONFIG=y
@ -413,6 +414,7 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set # CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set # CONFIG_ATA_OVER_ETH is not set
@ -1195,7 +1197,7 @@ CONFIG_USB_MON=y
# CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set # CONFIG_USB_LCD is not set
# CONFIG_USB_LED 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_CYTHERM is not set
# CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_PHIDGETSERVO is not set
@ -1373,7 +1375,6 @@ CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set # CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set # CONFIG_CIFS is not set
# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_NCP_FS is not set # CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set # CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set # CONFIG_AFS_FS is not set

View File

@ -103,7 +103,7 @@ ENTRY(ia32_sysenter_target)
pushq %rax pushq %rax
CFI_ADJUST_CFA_OFFSET 8 CFI_ADJUST_CFA_OFFSET 8
cld cld
SAVE_ARGS 0,0,1 SAVE_ARGS 0,0,0
/* no need to do an access_ok check here because rbp has been /* no need to do an access_ok check here because rbp has been
32bit zero extended */ 32bit zero extended */
1: movl (%rbp),%r9d 1: movl (%rbp),%r9d

View File

@ -85,7 +85,8 @@
#define CSR_AGENT_MASK 0xffe0ffff #define CSR_AGENT_MASK 0xffe0ffff
#define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */ #define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */
#define MAX_PHB_BUS_NUM (MAX_NUM_OF_PHBS * 2) /* max dev->bus->number */ #define MAX_NUM_CHASSIS 8 /* max number of chassis */
#define MAX_PHB_BUS_NUM (MAX_NUM_OF_PHBS * MAX_NUM_CHASSIS * 2) /* max dev->bus->number */
#define PHBS_PER_CALGARY 4 #define PHBS_PER_CALGARY 4
/* register offsets in Calgary's internal register space */ /* register offsets in Calgary's internal register space */
@ -110,7 +111,8 @@ static const unsigned long phb_offsets[] = {
0xB000 /* PHB3 */ 0xB000 /* PHB3 */
}; };
void* tce_table_kva[MAX_NUM_OF_PHBS * MAX_NUMNODES]; static char bus_to_phb[MAX_PHB_BUS_NUM];
void* tce_table_kva[MAX_PHB_BUS_NUM];
unsigned int specified_table_size = TCE_TABLE_SIZE_UNSPECIFIED; unsigned int specified_table_size = TCE_TABLE_SIZE_UNSPECIFIED;
static int translate_empty_slots __read_mostly = 0; static int translate_empty_slots __read_mostly = 0;
static int calgary_detected __read_mostly = 0; static int calgary_detected __read_mostly = 0;
@ -119,7 +121,7 @@ static int calgary_detected __read_mostly = 0;
* the bitmap of PHBs the user requested that we disable * the bitmap of PHBs the user requested that we disable
* translation on. * translation on.
*/ */
static DECLARE_BITMAP(translation_disabled, MAX_NUMNODES * MAX_PHB_BUS_NUM); static DECLARE_BITMAP(translation_disabled, MAX_PHB_BUS_NUM);
static void tce_cache_blast(struct iommu_table *tbl); static void tce_cache_blast(struct iommu_table *tbl);
@ -452,7 +454,7 @@ static struct dma_mapping_ops calgary_dma_ops = {
static inline int busno_to_phbid(unsigned char num) static inline int busno_to_phbid(unsigned char num)
{ {
return bus_to_phb(num) % PHBS_PER_CALGARY; return bus_to_phb[num];
} }
static inline unsigned long split_queue_offset(unsigned char num) static inline unsigned long split_queue_offset(unsigned char num)
@ -812,7 +814,7 @@ static int __init calgary_init(void)
int i, ret = -ENODEV; int i, ret = -ENODEV;
struct pci_dev *dev = NULL; struct pci_dev *dev = NULL;
for (i = 0; i <= num_online_nodes() * MAX_NUM_OF_PHBS; i++) { for (i = 0; i < MAX_PHB_BUS_NUM; i++) {
dev = pci_get_device(PCI_VENDOR_ID_IBM, dev = pci_get_device(PCI_VENDOR_ID_IBM,
PCI_DEVICE_ID_IBM_CALGARY, PCI_DEVICE_ID_IBM_CALGARY,
dev); dev);
@ -822,7 +824,7 @@ static int __init calgary_init(void)
calgary_init_one_nontraslated(dev); calgary_init_one_nontraslated(dev);
continue; continue;
} }
if (!tce_table_kva[i] && !translate_empty_slots) { if (!tce_table_kva[dev->bus->number] && !translate_empty_slots) {
pci_dev_put(dev); pci_dev_put(dev);
continue; continue;
} }
@ -842,7 +844,7 @@ static int __init calgary_init(void)
pci_dev_put(dev); pci_dev_put(dev);
continue; continue;
} }
if (!tce_table_kva[i] && !translate_empty_slots) if (!tce_table_kva[dev->bus->number] && !translate_empty_slots)
continue; continue;
calgary_disable_translation(dev); calgary_disable_translation(dev);
calgary_free_tar(dev); calgary_free_tar(dev);
@ -876,9 +878,10 @@ static inline int __init determine_tce_table_size(u64 ram)
void __init detect_calgary(void) void __init detect_calgary(void)
{ {
u32 val; u32 val;
int bus, table_idx; int bus;
void *tbl; void *tbl;
int detected = 0; int calgary_found = 0;
int phb = -1;
/* /*
* if the user specified iommu=off or iommu=soft or we found * if the user specified iommu=off or iommu=soft or we found
@ -889,38 +892,46 @@ void __init detect_calgary(void)
specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE); specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE);
for (bus = 0, table_idx = 0; for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) {
bus <= num_online_nodes() * MAX_PHB_BUS_NUM; int dev;
bus++) {
BUG_ON(bus > MAX_NUMNODES * MAX_PHB_BUS_NUM); tce_table_kva[bus] = NULL;
bus_to_phb[bus] = -1;
if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY) if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY)
continue; continue;
/*
* There are 4 PHBs per Calgary chip. Set phb to which phb (0-3)
* it is connected to releative to the clagary chip.
*/
phb = (phb + 1) % PHBS_PER_CALGARY;
if (test_bit(bus, translation_disabled)) { if (test_bit(bus, translation_disabled)) {
printk(KERN_INFO "Calgary: translation is disabled for " printk(KERN_INFO "Calgary: translation is disabled for "
"PHB 0x%x\n", bus); "PHB 0x%x\n", bus);
/* skip this phb, don't allocate a tbl for it */ /* skip this phb, don't allocate a tbl for it */
tce_table_kva[table_idx] = NULL;
table_idx++;
continue; continue;
} }
/* /*
* scan the first slot of the PCI bus to see if there * Scan the slots of the PCI bus to see if there is a device present.
* are any devices present * The parent bus will be the zero-ith device, so start at 1.
*/ */
val = read_pci_config(bus, 1, 0, 0); for (dev = 1; dev < 8; dev++) {
if (val != 0xffffffff || translate_empty_slots) { val = read_pci_config(bus, dev, 0, 0);
tbl = alloc_tce_table(); if (val != 0xffffffff || translate_empty_slots) {
if (!tbl) tbl = alloc_tce_table();
goto cleanup; if (!tbl)
detected = 1; goto cleanup;
} else tce_table_kva[bus] = tbl;
tbl = NULL; bus_to_phb[bus] = phb;
calgary_found = 1;
tce_table_kva[table_idx] = tbl; break;
table_idx++; }
}
} }
if (detected) { if (calgary_found) {
iommu_detected = 1; iommu_detected = 1;
calgary_detected = 1; calgary_detected = 1;
printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected. " printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected. "
@ -929,9 +940,9 @@ void __init detect_calgary(void)
return; return;
cleanup: cleanup:
for (--table_idx; table_idx >= 0; --table_idx) for (--bus; bus >= 0; --bus)
if (tce_table_kva[table_idx]) if (tce_table_kva[bus])
free_tce_table(tce_table_kva[table_idx]); free_tce_table(tce_table_kva[bus]);
} }
int __init calgary_iommu_init(void) int __init calgary_iommu_init(void)
@ -1002,7 +1013,7 @@ static int __init calgary_parse_options(char *p)
if (p == endp) if (p == endp)
break; break;
if (bridge <= (num_online_nodes() * MAX_PHB_BUS_NUM)) { if (bridge < MAX_PHB_BUS_NUM) {
printk(KERN_INFO "Calgary: disabling " printk(KERN_INFO "Calgary: disabling "
"translation for PHB 0x%x\n", bridge); "translation for PHB 0x%x\n", bridge);
set_bit(bridge, translation_disabled); set_bit(bridge, translation_disabled);

View File

@ -31,9 +31,10 @@ struct dma_mapping_ops swiotlb_dma_ops = {
void pci_swiotlb_init(void) void pci_swiotlb_init(void)
{ {
/* don't initialize swiotlb if iommu=off (no_iommu=1) */ /* don't initialize swiotlb if iommu=off (no_iommu=1) */
if (!iommu_detected && !no_iommu && if (!iommu_detected && !no_iommu && end_pfn > MAX_DMA32_PFN)
(end_pfn > MAX_DMA32_PFN || force_iommu))
swiotlb = 1; swiotlb = 1;
if (swiotlb_force)
swiotlb = 1;
if (swiotlb) { if (swiotlb) {
printk(KERN_INFO "PCI-DMA: Using software bounce buffering for IO (SWIOTLB)\n"); printk(KERN_INFO "PCI-DMA: Using software bounce buffering for IO (SWIOTLB)\n");
swiotlb_init(); swiotlb_init();

View File

@ -96,7 +96,6 @@ static inline unsigned int table_size_to_number_of_entries(unsigned char size)
static int tce_table_setparms(struct pci_dev *dev, struct iommu_table *tbl) static int tce_table_setparms(struct pci_dev *dev, struct iommu_table *tbl)
{ {
unsigned int bitmapsz; unsigned int bitmapsz;
unsigned int tce_table_index;
unsigned long bmppages; unsigned long bmppages;
int ret; int ret;
@ -105,8 +104,7 @@ static int tce_table_setparms(struct pci_dev *dev, struct iommu_table *tbl)
/* set the tce table size - measured in entries */ /* set the tce table size - measured in entries */
tbl->it_size = table_size_to_number_of_entries(specified_table_size); tbl->it_size = table_size_to_number_of_entries(specified_table_size);
tce_table_index = bus_to_phb(tbl->it_busno); tbl->it_base = (unsigned long)tce_table_kva[dev->bus->number];
tbl->it_base = (unsigned long)tce_table_kva[tce_table_index];
if (!tbl->it_base) { if (!tbl->it_base) {
printk(KERN_ERR "Calgary: iommu_table_setparms: " printk(KERN_ERR "Calgary: iommu_table_setparms: "
"no table allocated?!\n"); "no table allocated?!\n");

View File

@ -28,6 +28,7 @@
#include <linux/acpi.h> #include <linux/acpi.h>
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
#include <acpi/achware.h> /* for PM timer frequency */ #include <acpi/achware.h> /* for PM timer frequency */
#include <acpi/acpi_bus.h>
#endif #endif
#include <asm/8253pit.h> #include <asm/8253pit.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
@ -193,7 +194,7 @@ unsigned long profile_pc(struct pt_regs *regs)
is just accounted to the spinlock function. is just accounted to the spinlock function.
Better would be to write these functions in assembler again Better would be to write these functions in assembler again
and check exactly. */ and check exactly. */
if (in_lock_functions(pc)) { if (!user_mode(regs) && in_lock_functions(pc)) {
char *v = *(char **)regs->rsp; char *v = *(char **)regs->rsp;
if ((v >= _stext && v <= _etext) || if ((v >= _stext && v <= _etext) ||
(v >= _sinittext && v <= _einittext) || (v >= _sinittext && v <= _einittext) ||
@ -953,11 +954,18 @@ __cpuinit int unsynchronized_tsc(void)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
if (apic_is_clustered_box()) if (apic_is_clustered_box())
return 1; return 1;
/* Intel systems are normally all synchronized. Exceptions
are handled in the check above. */
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
return 0;
#endif #endif
/* Most intel systems have synchronized TSCs except for
multi node systems */
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
#ifdef CONFIG_ACPI
/* But TSC doesn't tick in C3 so don't use it there */
if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 100)
return 1;
#endif
return 0;
}
/* Assume multi socket systems are not synchronized */ /* Assume multi socket systems are not synchronized */
return num_present_cpus() > 1; return num_present_cpus() > 1;
} }

View File

@ -254,7 +254,6 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
{ {
const unsigned cpu = safe_smp_processor_id(); const unsigned cpu = safe_smp_processor_id();
unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr;
int i = 11;
unsigned used = 0; unsigned used = 0;
printk("\nCall Trace:\n"); printk("\nCall Trace:\n");
@ -275,11 +274,20 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
if (unwind_init_blocked(&info, tsk) == 0) if (unwind_init_blocked(&info, tsk) == 0)
unw_ret = show_trace_unwind(&info, NULL); unw_ret = show_trace_unwind(&info, NULL);
} }
if (unw_ret > 0) { if (unw_ret > 0 && !arch_unw_user_mode(&info)) {
if (call_trace > 0) #ifdef CONFIG_STACK_UNWIND
unsigned long rip = info.regs.rip;
print_symbol("DWARF2 unwinder stuck at %s\n", rip);
if (call_trace == 1) {
printk("Leftover inexact backtrace:\n");
stack = (unsigned long *)info.regs.rsp;
} else if (call_trace > 1)
return; return;
printk("Legacy call trace:"); else
i = 18; printk("Full inexact backtrace again:\n");
#else
printk("Inexact backtrace:\n");
#endif
} }
} }
@ -1118,8 +1126,10 @@ static int __init call_trace_setup(char *s)
call_trace = -1; call_trace = -1;
else if (strcmp(s, "both") == 0) else if (strcmp(s, "both") == 0)
call_trace = 0; call_trace = 0;
else if (strcmp(s, "new") == 0) else if (strcmp(s, "newfallback") == 0)
call_trace = 1; call_trace = 1;
else if (strcmp(s, "new") == 0)
call_trace = 2;
return 1; return 1;
} }
__setup("call_trace=", call_trace_setup); __setup("call_trace=", call_trace_setup);

View File

@ -2,7 +2,6 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <asm/mpspec.h> #include <asm/mpspec.h>
#include <linux/cpumask.h> #include <linux/cpumask.h>
#include <asm/k8.h>
/* /*
* This discovers the pcibus <-> node mapping on AMD K8. * This discovers the pcibus <-> node mapping on AMD K8.
@ -19,6 +18,7 @@
#define NR_LDT_BUS_NUMBER_REGISTERS 3 #define NR_LDT_BUS_NUMBER_REGISTERS 3
#define SECONDARY_LDT_BUS_NUMBER(dword) ((dword >> 8) & 0xFF) #define SECONDARY_LDT_BUS_NUMBER(dword) ((dword >> 8) & 0xFF)
#define SUBORDINATE_LDT_BUS_NUMBER(dword) ((dword >> 16) & 0xFF) #define SUBORDINATE_LDT_BUS_NUMBER(dword) ((dword >> 16) & 0xFF)
#define PCI_DEVICE_ID_K8HTCONFIG 0x1100
/** /**
* fill_mp_bus_to_cpumask() * fill_mp_bus_to_cpumask()
@ -28,7 +28,8 @@
__init static int __init static int
fill_mp_bus_to_cpumask(void) fill_mp_bus_to_cpumask(void)
{ {
int i, j, k; struct pci_dev *nb_dev = NULL;
int i, j;
u32 ldtbus, nid; u32 ldtbus, nid;
static int lbnr[3] = { static int lbnr[3] = {
LDT_BUS_NUMBER_REGISTER_0, LDT_BUS_NUMBER_REGISTER_0,
@ -36,9 +37,8 @@ fill_mp_bus_to_cpumask(void)
LDT_BUS_NUMBER_REGISTER_2 LDT_BUS_NUMBER_REGISTER_2
}; };
cache_k8_northbridges(); while ((nb_dev = pci_get_device(PCI_VENDOR_ID_AMD,
for (k = 0; k < num_k8_northbridges; k++) { PCI_DEVICE_ID_K8HTCONFIG, nb_dev))) {
struct pci_dev *nb_dev = k8_northbridges[k];
pci_read_config_dword(nb_dev, NODE_ID_REGISTER, &nid); pci_read_config_dword(nb_dev, NODE_ID_REGISTER, &nid);
for (i = 0; i < NR_LDT_BUS_NUMBER_REGISTERS; i++) { for (i = 0; i < NR_LDT_BUS_NUMBER_REGISTERS; i++) {

View File

@ -80,7 +80,7 @@ static u32 bio_act[5] __read_mostly = { 0, BLK_TC_ACT(BLK_TC_BARRIER), BLK_TC_AC
#define trace_sync_bit(rw) \ #define trace_sync_bit(rw) \
(((rw) & (1 << BIO_RW_SYNC)) >> (BIO_RW_SYNC - 1)) (((rw) & (1 << BIO_RW_SYNC)) >> (BIO_RW_SYNC - 1))
#define trace_ahead_bit(rw) \ #define trace_ahead_bit(rw) \
(((rw) & (1 << BIO_RW_AHEAD)) << (BIO_RW_AHEAD - 0)) (((rw) & (1 << BIO_RW_AHEAD)) << (2 - BIO_RW_AHEAD))
/* /*
* The worker for the various blk_add_trace*() types. Fills out a * The worker for the various blk_add_trace*() types. Fills out a

View File

@ -936,7 +936,7 @@ static int cfq_arm_slice_timer(struct cfq_data *cfqd, struct cfq_queue *cfqq)
* seeks. so allow a little bit of time for him to submit a new rq * seeks. so allow a little bit of time for him to submit a new rq
*/ */
if (sample_valid(cic->seek_samples) && CIC_SEEKY(cic)) if (sample_valid(cic->seek_samples) && CIC_SEEKY(cic))
sl = 2; sl = min(sl, msecs_to_jiffies(2));
mod_timer(&cfqd->idle_slice_timer, jiffies + sl); mod_timer(&cfqd->idle_slice_timer, jiffies + sl);
return 1; return 1;

View File

@ -1233,6 +1233,50 @@ static inline void complete_buffers(struct bio *bio, int status)
} }
} }
static void cciss_check_queues(ctlr_info_t *h)
{
int start_queue = h->next_to_run;
int i;
/* check to see if we have maxed out the number of commands that can
* be placed on the queue. If so then exit. We do this check here
* in case the interrupt we serviced was from an ioctl and did not
* free any new commands.
*/
if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS)
return;
/* We have room on the queue for more commands. Now we need to queue
* them up. We will also keep track of the next queue to run so
* that every queue gets a chance to be started first.
*/
for (i = 0; i < h->highest_lun + 1; i++) {
int curr_queue = (start_queue + i) % (h->highest_lun + 1);
/* make sure the disk has been added and the drive is real
* because this can be called from the middle of init_one.
*/
if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads))
continue;
blk_start_queue(h->gendisk[curr_queue]->queue);
/* check to see if we have maxed out the number of commands
* that can be placed on the queue.
*/
if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) {
if (curr_queue == start_queue) {
h->next_to_run =
(start_queue + 1) % (h->highest_lun + 1);
break;
} else {
h->next_to_run = curr_queue;
break;
}
} else {
curr_queue = (curr_queue + 1) % (h->highest_lun + 1);
}
}
}
static void cciss_softirq_done(struct request *rq) static void cciss_softirq_done(struct request *rq)
{ {
CommandList_struct *cmd = rq->completion_data; CommandList_struct *cmd = rq->completion_data;
@ -1264,6 +1308,7 @@ static void cciss_softirq_done(struct request *rq)
spin_lock_irqsave(&h->lock, flags); spin_lock_irqsave(&h->lock, flags);
end_that_request_last(rq, rq->errors); end_that_request_last(rq, rq->errors);
cmd_free(h, cmd, 1); cmd_free(h, cmd, 1);
cciss_check_queues(h);
spin_unlock_irqrestore(&h->lock, flags); spin_unlock_irqrestore(&h->lock, flags);
} }
@ -2528,8 +2573,6 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
CommandList_struct *c; CommandList_struct *c;
unsigned long flags; unsigned long flags;
__u32 a, a1, a2; __u32 a, a1, a2;
int j;
int start_queue = h->next_to_run;
if (interrupt_not_for_us(h)) if (interrupt_not_for_us(h))
return IRQ_NONE; return IRQ_NONE;
@ -2588,45 +2631,6 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
} }
} }
/* check to see if we have maxed out the number of commands that can
* be placed on the queue. If so then exit. We do this check here
* in case the interrupt we serviced was from an ioctl and did not
* free any new commands.
*/
if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS)
goto cleanup;
/* We have room on the queue for more commands. Now we need to queue
* them up. We will also keep track of the next queue to run so
* that every queue gets a chance to be started first.
*/
for (j = 0; j < h->highest_lun + 1; j++) {
int curr_queue = (start_queue + j) % (h->highest_lun + 1);
/* make sure the disk has been added and the drive is real
* because this can be called from the middle of init_one.
*/
if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads))
continue;
blk_start_queue(h->gendisk[curr_queue]->queue);
/* check to see if we have maxed out the number of commands
* that can be placed on the queue.
*/
if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) {
if (curr_queue == start_queue) {
h->next_to_run =
(start_queue + 1) % (h->highest_lun + 1);
goto cleanup;
} else {
h->next_to_run = curr_queue;
goto cleanup;
}
} else {
curr_queue = (curr_queue + 1) % (h->highest_lun + 1);
}
}
cleanup:
spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
return IRQ_HANDLED; return IRQ_HANDLED;
} }

View File

@ -67,6 +67,8 @@ static int ignore = 0;
static int ignore_dga = 0; static int ignore_dga = 0;
static int ignore_csr = 0; static int ignore_csr = 0;
static int ignore_sniffer = 0; static int ignore_sniffer = 0;
static int disable_scofix = 0;
static int force_scofix = 0;
static int reset = 0; static int reset = 0;
#ifdef CONFIG_BT_HCIUSB_SCO #ifdef CONFIG_BT_HCIUSB_SCO
@ -107,9 +109,12 @@ static struct usb_device_id blacklist_ids[] = {
{ USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE }, { USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE },
/* Broadcom BCM2035 */ /* Broadcom BCM2035 */
{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET | HCI_BROKEN_ISOC }, { USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 }, { USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 },
/* IBM/Lenovo ThinkPad with Broadcom chip */
{ USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_WRONG_SCO_MTU },
/* Microsoft Wireless Transceiver for Bluetooth 2.0 */ /* Microsoft Wireless Transceiver for Bluetooth 2.0 */
{ USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET }, { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET },
@ -119,11 +124,13 @@ static struct usb_device_id blacklist_ids[] = {
/* ISSC Bluetooth Adapter v3.1 */ /* ISSC Bluetooth Adapter v3.1 */
{ USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET }, { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
/* RTX Telecom based adapter with buggy SCO support */ /* RTX Telecom based adapters with buggy SCO support */
{ USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC }, { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC },
{ USB_DEVICE(0x0400, 0x080a), .driver_info = HCI_BROKEN_ISOC },
/* Belkin F8T012 */ /* Belkin F8T012 and F8T013 devices */
{ USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_WRONG_SCO_MTU }, { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_WRONG_SCO_MTU },
{ USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_WRONG_SCO_MTU },
/* Digianswer devices */ /* Digianswer devices */
{ USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER }, { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER },
@ -990,8 +997,10 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
if (reset || id->driver_info & HCI_RESET) if (reset || id->driver_info & HCI_RESET)
set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks); set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
if (id->driver_info & HCI_WRONG_SCO_MTU) if (force_scofix || id->driver_info & HCI_WRONG_SCO_MTU) {
set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks); if (!disable_scofix)
set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
}
if (id->driver_info & HCI_SNIFFER) { if (id->driver_info & HCI_SNIFFER) {
if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997) if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
@ -1161,6 +1170,12 @@ MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
module_param(ignore_sniffer, bool, 0644); module_param(ignore_sniffer, bool, 0644);
MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002"); MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");
module_param(disable_scofix, bool, 0644);
MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size");
module_param(force_scofix, bool, 0644);
MODULE_PARM_DESC(force_scofix, "Force fixup of wrong SCO buffers size");
module_param(reset, bool, 0644); module_param(reset, bool, 0644);
MODULE_PARM_DESC(reset, "Send HCI reset command on initialization"); MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");

View File

@ -1174,8 +1174,12 @@ static void dcd_change(MGSLPC_INFO *info)
else else
info->input_signal_events.dcd_down++; info->input_signal_events.dcd_down++;
#ifdef CONFIG_HDLC #ifdef CONFIG_HDLC
if (info->netcount) if (info->netcount) {
hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, info->netdev); if (info->serial_signals & SerialSignal_DCD)
netif_carrier_on(info->netdev);
else
netif_carrier_off(info->netdev);
}
#endif #endif
wake_up_interruptible(&info->status_event_wait_q); wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->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); spin_lock_irqsave(&info->lock, flags);
get_signals(info); get_signals(info);
spin_unlock_irqrestore(&info->lock, flags); 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; return 0;
} }

View File

@ -1344,8 +1344,12 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info )
} else } else
info->input_signal_events.dcd_down++; info->input_signal_events.dcd_down++;
#ifdef CONFIG_HDLC #ifdef CONFIG_HDLC
if (info->netcount) if (info->netcount) {
hdlc_set_carrier(status & MISCSTATUS_DCD, info->netdev); if (status & MISCSTATUS_DCD)
netif_carrier_on(info->netdev);
else
netif_carrier_off(info->netdev);
}
#endif #endif
} }
if (status & MISCSTATUS_CTS_LATCHED) if (status & MISCSTATUS_CTS_LATCHED)
@ -7844,8 +7848,10 @@ static int hdlcdev_open(struct net_device *dev)
spin_lock_irqsave(&info->irq_spinlock, flags); spin_lock_irqsave(&info->irq_spinlock, flags);
usc_get_serial_signals(info); usc_get_serial_signals(info);
spin_unlock_irqrestore(&info->irq_spinlock, flags); 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; return 0;
} }

View File

@ -1497,8 +1497,10 @@ static int hdlcdev_open(struct net_device *dev)
spin_lock_irqsave(&info->lock, flags); spin_lock_irqsave(&info->lock, flags);
get_signals(info); get_signals(info);
spin_unlock_irqrestore(&info->lock, flags); 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; return 0;
} }
@ -1997,8 +1999,12 @@ static void dcd_change(struct slgt_info *info)
info->input_signal_events.dcd_down++; info->input_signal_events.dcd_down++;
} }
#ifdef CONFIG_HDLC #ifdef CONFIG_HDLC
if (info->netcount) if (info->netcount) {
hdlc_set_carrier(info->signals & SerialSignal_DCD, info->netdev); if (info->signals & SerialSignal_DCD)
netif_carrier_on(info->netdev);
else
netif_carrier_off(info->netdev);
}
#endif #endif
wake_up_interruptible(&info->status_event_wait_q); wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->event_wait_q); wake_up_interruptible(&info->event_wait_q);

View File

@ -1752,8 +1752,10 @@ static int hdlcdev_open(struct net_device *dev)
spin_lock_irqsave(&info->lock, flags); spin_lock_irqsave(&info->lock, flags);
get_signals(info); get_signals(info);
spin_unlock_irqrestore(&info->lock, flags); 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; return 0;
} }
@ -2522,8 +2524,12 @@ void isr_io_pin( SLMP_INFO *info, u16 status )
} else } else
info->input_signal_events.dcd_down++; info->input_signal_events.dcd_down++;
#ifdef CONFIG_HDLC #ifdef CONFIG_HDLC
if (info->netcount) if (info->netcount) {
hdlc_set_carrier(status & SerialSignal_DCD, info->netdev); if (status & SerialSignal_DCD)
netif_carrier_on(info->netdev);
else
netif_carrier_off(info->netdev);
}
#endif #endif
} }
if (status & MISCSTATUS_CTS_LATCHED) if (status & MISCSTATUS_CTS_LATCHED)

View File

@ -364,10 +364,12 @@ static ssize_t store_##file_name \
if (ret != 1) \ if (ret != 1) \
return -EINVAL; \ return -EINVAL; \
\ \
lock_cpu_hotplug(); \
mutex_lock(&policy->lock); \ mutex_lock(&policy->lock); \
ret = __cpufreq_set_policy(policy, &new_policy); \ ret = __cpufreq_set_policy(policy, &new_policy); \
policy->user_policy.object = policy->object; \ policy->user_policy.object = policy->object; \
mutex_unlock(&policy->lock); \ mutex_unlock(&policy->lock); \
unlock_cpu_hotplug(); \
\ \
return ret ? ret : count; \ return ret ? ret : count; \
} }
@ -1197,20 +1199,18 @@ EXPORT_SYMBOL(cpufreq_unregister_notifier);
*********************************************************************/ *********************************************************************/
/* Must be called with lock_cpu_hotplug held */
int __cpufreq_driver_target(struct cpufreq_policy *policy, int __cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int target_freq, unsigned int target_freq,
unsigned int relation) unsigned int relation)
{ {
int retval = -EINVAL; int retval = -EINVAL;
lock_cpu_hotplug();
dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu, dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
target_freq, relation); target_freq, relation);
if (cpu_online(policy->cpu) && cpufreq_driver->target) if (cpu_online(policy->cpu) && cpufreq_driver->target)
retval = cpufreq_driver->target(policy, target_freq, relation); retval = cpufreq_driver->target(policy, target_freq, relation);
unlock_cpu_hotplug();
return retval; return retval;
} }
EXPORT_SYMBOL_GPL(__cpufreq_driver_target); EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
@ -1225,17 +1225,23 @@ int cpufreq_driver_target(struct cpufreq_policy *policy,
if (!policy) if (!policy)
return -EINVAL; return -EINVAL;
lock_cpu_hotplug();
mutex_lock(&policy->lock); mutex_lock(&policy->lock);
ret = __cpufreq_driver_target(policy, target_freq, relation); ret = __cpufreq_driver_target(policy, target_freq, relation);
mutex_unlock(&policy->lock); mutex_unlock(&policy->lock);
unlock_cpu_hotplug();
cpufreq_cpu_put(policy); cpufreq_cpu_put(policy);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(cpufreq_driver_target); EXPORT_SYMBOL_GPL(cpufreq_driver_target);
/*
* Locking: Must be called with the lock_cpu_hotplug() lock held
* when "event" is CPUFREQ_GOV_LIMITS
*/
static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
{ {
@ -1257,24 +1263,6 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
} }
int cpufreq_governor(unsigned int cpu, unsigned int event)
{
int ret = 0;
struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
if (!policy)
return -EINVAL;
mutex_lock(&policy->lock);
ret = __cpufreq_governor(policy, event);
mutex_unlock(&policy->lock);
cpufreq_cpu_put(policy);
return ret;
}
EXPORT_SYMBOL_GPL(cpufreq_governor);
int cpufreq_register_governor(struct cpufreq_governor *governor) int cpufreq_register_governor(struct cpufreq_governor *governor)
{ {
struct cpufreq_governor *t; struct cpufreq_governor *t;
@ -1342,6 +1330,9 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
EXPORT_SYMBOL(cpufreq_get_policy); EXPORT_SYMBOL(cpufreq_get_policy);
/*
* Locking: Must be called with the lock_cpu_hotplug() lock held
*/
static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_policy *policy) static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_policy *policy)
{ {
int ret = 0; int ret = 0;
@ -1436,6 +1427,8 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
if (!data) if (!data)
return -EINVAL; return -EINVAL;
lock_cpu_hotplug();
/* lock this CPU */ /* lock this CPU */
mutex_lock(&data->lock); mutex_lock(&data->lock);
@ -1446,6 +1439,8 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
data->user_policy.governor = data->governor; data->user_policy.governor = data->governor;
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
unlock_cpu_hotplug();
cpufreq_cpu_put(data); cpufreq_cpu_put(data);
return ret; return ret;
@ -1469,6 +1464,7 @@ int cpufreq_update_policy(unsigned int cpu)
if (!data) if (!data)
return -ENODEV; return -ENODEV;
lock_cpu_hotplug();
mutex_lock(&data->lock); mutex_lock(&data->lock);
dprintk("updating policy for CPU %u\n", cpu); dprintk("updating policy for CPU %u\n", cpu);
@ -1494,7 +1490,7 @@ int cpufreq_update_policy(unsigned int cpu)
ret = __cpufreq_set_policy(data, &policy); ret = __cpufreq_set_policy(data, &policy);
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
unlock_cpu_hotplug();
cpufreq_cpu_put(data); cpufreq_cpu_put(data);
return ret; return ret;
} }

View File

@ -525,7 +525,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
break; break;
case CPUFREQ_GOV_LIMITS: case CPUFREQ_GOV_LIMITS:
lock_cpu_hotplug();
mutex_lock(&dbs_mutex); mutex_lock(&dbs_mutex);
if (policy->max < this_dbs_info->cur_policy->cur) if (policy->max < this_dbs_info->cur_policy->cur)
__cpufreq_driver_target( __cpufreq_driver_target(
@ -536,7 +535,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
this_dbs_info->cur_policy, this_dbs_info->cur_policy,
policy->min, CPUFREQ_RELATION_L); policy->min, CPUFREQ_RELATION_L);
mutex_unlock(&dbs_mutex); mutex_unlock(&dbs_mutex);
unlock_cpu_hotplug();
break; break;
} }
return 0; return 0;

View File

@ -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, total_ticks = (unsigned int) cputime64_sub(cur_jiffies,
this_dbs_info->prev_cpu_wall); this_dbs_info->prev_cpu_wall);
this_dbs_info->prev_cpu_wall = cur_jiffies; this_dbs_info->prev_cpu_wall = cur_jiffies;
if (!total_ticks)
return;
/* /*
* Every sampling_rate, we check, if current idle time is less * Every sampling_rate, we check, if current idle time is less
* than 20% (default), then we try to increase frequency * than 20% (default), then we try to increase frequency
@ -304,7 +306,12 @@ static void do_dbs_timer(void *data)
unsigned int cpu = smp_processor_id(); unsigned int cpu = smp_processor_id();
struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu);
if (!dbs_info->enable)
return;
lock_cpu_hotplug();
dbs_check_cpu(dbs_info); dbs_check_cpu(dbs_info);
unlock_cpu_hotplug();
queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work,
usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
} }
@ -319,11 +326,11 @@ static inline void dbs_timer_init(unsigned int cpu)
return; 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); dbs_info->enable = 0;
cancel_delayed_work(&dbs_info->work);
cancel_rearming_delayed_workqueue(kondemand_wq, &dbs_info->work); flush_workqueue(kondemand_wq);
} }
static int cpufreq_governor_dbs(struct cpufreq_policy *policy, static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
@ -396,8 +403,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
case CPUFREQ_GOV_STOP: case CPUFREQ_GOV_STOP:
mutex_lock(&dbs_mutex); mutex_lock(&dbs_mutex);
dbs_timer_exit(policy->cpu); dbs_timer_exit(this_dbs_info);
this_dbs_info->enable = 0;
sysfs_remove_group(&policy->kobj, &dbs_attr_group); sysfs_remove_group(&policy->kobj, &dbs_attr_group);
dbs_enable--; dbs_enable--;
if (dbs_enable == 0) if (dbs_enable == 0)
@ -408,7 +414,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
break; break;
case CPUFREQ_GOV_LIMITS: case CPUFREQ_GOV_LIMITS:
lock_cpu_hotplug();
mutex_lock(&dbs_mutex); mutex_lock(&dbs_mutex);
if (policy->max < this_dbs_info->cur_policy->cur) if (policy->max < this_dbs_info->cur_policy->cur)
__cpufreq_driver_target(this_dbs_info->cur_policy, __cpufreq_driver_target(this_dbs_info->cur_policy,
@ -419,7 +424,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
policy->min, policy->min,
CPUFREQ_RELATION_L); CPUFREQ_RELATION_L);
mutex_unlock(&dbs_mutex); mutex_unlock(&dbs_mutex);
unlock_cpu_hotplug();
break; break;
} }
return 0; return 0;

View File

@ -18,6 +18,7 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#include <linux/cpu.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
@ -70,6 +71,7 @@ static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy)
dprintk("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq); dprintk("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq);
lock_cpu_hotplug();
mutex_lock(&userspace_mutex); mutex_lock(&userspace_mutex);
if (!cpu_is_managed[policy->cpu]) if (!cpu_is_managed[policy->cpu])
goto err; goto err;
@ -92,6 +94,7 @@ static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy)
err: err:
mutex_unlock(&userspace_mutex); mutex_unlock(&userspace_mutex);
unlock_cpu_hotplug();
return ret; return ret;
} }

View File

@ -828,7 +828,7 @@ static int __init ioat_init_module(void)
/* if forced, worst case is that rmmod hangs */ /* if forced, worst case is that rmmod hangs */
__unsafe(THIS_MODULE); __unsafe(THIS_MODULE);
return pci_module_init(&ioat_pci_drv); return pci_register_driver(&ioat_pci_drv);
} }
module_init(ioat_init_module); module_init(ioat_init_module);

View File

@ -429,7 +429,7 @@ static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hd
if (fcmd->data) { if (fcmd->data) {
if (SCpnt->use_sg) 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->use_sg,
SCpnt->sc_data_direction); SCpnt->sc_data_direction);
else 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->request_bufflen,
SCpnt->sc_data_direction); SCpnt->sc_data_direction);
} else { } else {
struct scatterlist *sg = (struct scatterlist *)SCpnt->buffer; struct scatterlist *sg = (struct scatterlist *)SCpnt->request_buffer;
int nents; int nents;
FCD(("XXX: Use_sg %d %d\n", SCpnt->use_sg, sg->length)) FCD(("XXX: Use_sg %d %d\n", SCpnt->use_sg, sg->length))

View File

@ -776,7 +776,7 @@ static void update_ordered(ide_drive_t *drive)
* not available so we don't need to recheck that. * not available so we don't need to recheck that.
*/ */
capacity = idedisk_capacity(drive); capacity = idedisk_capacity(drive);
barrier = ide_id_has_flush_cache(id) && barrier = ide_id_has_flush_cache(id) && !drive->noflush &&
(drive->addressing == 0 || capacity <= (1ULL << 28) || (drive->addressing == 0 || capacity <= (1ULL << 28) ||
ide_id_has_flush_cache_ext(id)); ide_id_has_flush_cache_ext(id));

View File

@ -750,7 +750,7 @@ void ide_dma_verbose(ide_drive_t *drive)
goto bug_dma_off; goto bug_dma_off;
printk(", DMA"); printk(", DMA");
} else if (id->field_valid & 1) { } else if (id->field_valid & 1) {
printk(", BUG"); goto bug_dma_off;
} }
return; return;
bug_dma_off: bug_dma_off:

View File

@ -1539,7 +1539,7 @@ static int __init ide_setup(char *s)
const char *hd_words[] = { const char *hd_words[] = {
"none", "noprobe", "nowerr", "cdrom", "serialize", "none", "noprobe", "nowerr", "cdrom", "serialize",
"autotune", "noautotune", "minus8", "swapdata", "bswap", "autotune", "noautotune", "minus8", "swapdata", "bswap",
"minus11", "remap", "remap63", "scsi", NULL }; "noflush", "remap", "remap63", "scsi", NULL };
unit = s[2] - 'a'; unit = s[2] - 'a';
hw = unit / MAX_DRIVES; hw = unit / MAX_DRIVES;
unit = unit % MAX_DRIVES; unit = unit % MAX_DRIVES;
@ -1578,6 +1578,9 @@ static int __init ide_setup(char *s)
case -10: /* "bswap" */ case -10: /* "bswap" */
drive->bswap = 1; drive->bswap = 1;
goto done; goto done;
case -11: /* noflush */
drive->noflush = 1;
goto done;
case -12: /* "remap" */ case -12: /* "remap" */
drive->remap_0_to_1 = 1; drive->remap_0_to_1 = 1;
goto done; goto done;

View File

@ -498,9 +498,14 @@ static int config_chipset_for_dma (ide_drive_t *drive)
{ {
u8 speed = ide_dma_speed(drive, it821x_ratemask(drive)); u8 speed = ide_dma_speed(drive, it821x_ratemask(drive));
config_it821x_chipset_for_pio(drive, !speed); if (speed) {
it821x_tune_chipset(drive, speed); config_it821x_chipset_for_pio(drive, 0);
return ide_dma_enable(drive); it821x_tune_chipset(drive, speed);
return ide_dma_enable(drive);
}
return 0;
} }
/** /**

View File

@ -167,6 +167,15 @@ static int is_vendor_method_in_use(
return 0; return 0;
} }
int ib_response_mad(struct ib_mad *mad)
{
return ((mad->mad_hdr.method & IB_MGMT_METHOD_RESP) ||
(mad->mad_hdr.method == IB_MGMT_METHOD_TRAP_REPRESS) ||
((mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_BM) &&
(mad->mad_hdr.attr_mod & IB_BM_ATTR_MOD_RESP)));
}
EXPORT_SYMBOL(ib_response_mad);
/* /*
* ib_register_mad_agent - Register to send/receive MADs * ib_register_mad_agent - Register to send/receive MADs
*/ */
@ -570,13 +579,6 @@ int ib_unregister_mad_agent(struct ib_mad_agent *mad_agent)
} }
EXPORT_SYMBOL(ib_unregister_mad_agent); EXPORT_SYMBOL(ib_unregister_mad_agent);
static inline int response_mad(struct ib_mad *mad)
{
/* Trap represses are responses although response bit is reset */
return ((mad->mad_hdr.method == IB_MGMT_METHOD_TRAP_REPRESS) ||
(mad->mad_hdr.method & IB_MGMT_METHOD_RESP));
}
static void dequeue_mad(struct ib_mad_list_head *mad_list) static void dequeue_mad(struct ib_mad_list_head *mad_list)
{ {
struct ib_mad_queue *mad_queue; struct ib_mad_queue *mad_queue;
@ -723,7 +725,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
switch (ret) switch (ret)
{ {
case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY: case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY:
if (response_mad(&mad_priv->mad.mad) && if (ib_response_mad(&mad_priv->mad.mad) &&
mad_agent_priv->agent.recv_handler) { mad_agent_priv->agent.recv_handler) {
local->mad_priv = mad_priv; local->mad_priv = mad_priv;
local->recv_mad_agent = mad_agent_priv; local->recv_mad_agent = mad_agent_priv;
@ -1551,7 +1553,7 @@ find_mad_agent(struct ib_mad_port_private *port_priv,
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&port_priv->reg_lock, flags); spin_lock_irqsave(&port_priv->reg_lock, flags);
if (response_mad(mad)) { if (ib_response_mad(mad)) {
u32 hi_tid; u32 hi_tid;
struct ib_mad_agent_private *entry; struct ib_mad_agent_private *entry;
@ -1799,7 +1801,7 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
} }
/* Complete corresponding request */ /* Complete corresponding request */
if (response_mad(mad_recv_wc->recv_buf.mad)) { if (ib_response_mad(mad_recv_wc->recv_buf.mad)) {
spin_lock_irqsave(&mad_agent_priv->lock, flags); spin_lock_irqsave(&mad_agent_priv->lock, flags);
mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc); mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc);
if (!mad_send_wr) { if (!mad_send_wr) {

View File

@ -112,8 +112,10 @@ struct ib_umad_device {
struct ib_umad_file { struct ib_umad_file {
struct ib_umad_port *port; struct ib_umad_port *port;
struct list_head recv_list; struct list_head recv_list;
struct list_head send_list;
struct list_head port_list; struct list_head port_list;
spinlock_t recv_lock; spinlock_t recv_lock;
spinlock_t send_lock;
wait_queue_head_t recv_wait; wait_queue_head_t recv_wait;
struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS]; struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS];
int agents_dead; int agents_dead;
@ -177,12 +179,21 @@ static int queue_packet(struct ib_umad_file *file,
return ret; return ret;
} }
static void dequeue_send(struct ib_umad_file *file,
struct ib_umad_packet *packet)
{
spin_lock_irq(&file->send_lock);
list_del(&packet->list);
spin_unlock_irq(&file->send_lock);
}
static void send_handler(struct ib_mad_agent *agent, static void send_handler(struct ib_mad_agent *agent,
struct ib_mad_send_wc *send_wc) struct ib_mad_send_wc *send_wc)
{ {
struct ib_umad_file *file = agent->context; struct ib_umad_file *file = agent->context;
struct ib_umad_packet *packet = send_wc->send_buf->context[0]; struct ib_umad_packet *packet = send_wc->send_buf->context[0];
dequeue_send(file, packet);
ib_destroy_ah(packet->msg->ah); ib_destroy_ah(packet->msg->ah);
ib_free_send_mad(packet->msg); ib_free_send_mad(packet->msg);
@ -370,6 +381,51 @@ static int copy_rmpp_mad(struct ib_mad_send_buf *msg, const char __user *buf)
return 0; return 0;
} }
static int same_destination(struct ib_user_mad_hdr *hdr1,
struct ib_user_mad_hdr *hdr2)
{
if (!hdr1->grh_present && !hdr2->grh_present)
return (hdr1->lid == hdr2->lid);
if (hdr1->grh_present && hdr2->grh_present)
return !memcmp(hdr1->gid, hdr2->gid, 16);
return 0;
}
static int is_duplicate(struct ib_umad_file *file,
struct ib_umad_packet *packet)
{
struct ib_umad_packet *sent_packet;
struct ib_mad_hdr *sent_hdr, *hdr;
hdr = (struct ib_mad_hdr *) packet->mad.data;
list_for_each_entry(sent_packet, &file->send_list, list) {
sent_hdr = (struct ib_mad_hdr *) sent_packet->mad.data;
if ((hdr->tid != sent_hdr->tid) ||
(hdr->mgmt_class != sent_hdr->mgmt_class))
continue;
/*
* No need to be overly clever here. If two new operations have
* the same TID, reject the second as a duplicate. This is more
* restrictive than required by the spec.
*/
if (!ib_response_mad((struct ib_mad *) hdr)) {
if (!ib_response_mad((struct ib_mad *) sent_hdr))
return 1;
continue;
} else if (!ib_response_mad((struct ib_mad *) sent_hdr))
continue;
if (same_destination(&packet->mad.hdr, &sent_packet->mad.hdr))
return 1;
}
return 0;
}
static ssize_t ib_umad_write(struct file *filp, const char __user *buf, static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
size_t count, loff_t *pos) size_t count, loff_t *pos)
{ {
@ -379,7 +435,6 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
struct ib_ah_attr ah_attr; struct ib_ah_attr ah_attr;
struct ib_ah *ah; struct ib_ah *ah;
struct ib_rmpp_mad *rmpp_mad; struct ib_rmpp_mad *rmpp_mad;
u8 method;
__be64 *tid; __be64 *tid;
int ret, data_len, hdr_len, copy_offset, rmpp_active; int ret, data_len, hdr_len, copy_offset, rmpp_active;
@ -473,28 +528,36 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
} }
/* /*
* If userspace is generating a request that will generate a * Set the high-order part of the transaction ID to make MADs from
* response, we need to make sure the high-order part of the * different agents unique, and allow routing responses back to the
* transaction ID matches the agent being used to send the * original requestor.
* MAD.
*/ */
method = ((struct ib_mad_hdr *) packet->msg->mad)->method; if (!ib_response_mad(packet->msg->mad)) {
if (!(method & IB_MGMT_METHOD_RESP) &&
method != IB_MGMT_METHOD_TRAP_REPRESS &&
method != IB_MGMT_METHOD_SEND) {
tid = &((struct ib_mad_hdr *) packet->msg->mad)->tid; tid = &((struct ib_mad_hdr *) packet->msg->mad)->tid;
*tid = cpu_to_be64(((u64) agent->hi_tid) << 32 | *tid = cpu_to_be64(((u64) agent->hi_tid) << 32 |
(be64_to_cpup(tid) & 0xffffffff)); (be64_to_cpup(tid) & 0xffffffff));
rmpp_mad->mad_hdr.tid = *tid;
}
spin_lock_irq(&file->send_lock);
ret = is_duplicate(file, packet);
if (!ret)
list_add_tail(&packet->list, &file->send_list);
spin_unlock_irq(&file->send_lock);
if (ret) {
ret = -EINVAL;
goto err_msg;
} }
ret = ib_post_send_mad(packet->msg, NULL); ret = ib_post_send_mad(packet->msg, NULL);
if (ret) if (ret)
goto err_msg; goto err_send;
up_read(&file->port->mutex); up_read(&file->port->mutex);
return count; return count;
err_send:
dequeue_send(file, packet);
err_msg: err_msg:
ib_free_send_mad(packet->msg); ib_free_send_mad(packet->msg);
err_ah: err_ah:
@ -657,7 +720,9 @@ static int ib_umad_open(struct inode *inode, struct file *filp)
} }
spin_lock_init(&file->recv_lock); spin_lock_init(&file->recv_lock);
spin_lock_init(&file->send_lock);
INIT_LIST_HEAD(&file->recv_list); INIT_LIST_HEAD(&file->recv_list);
INIT_LIST_HEAD(&file->send_list);
init_waitqueue_head(&file->recv_wait); init_waitqueue_head(&file->recv_wait);
file->port = port; file->port = port;

View File

@ -42,6 +42,13 @@
#include "uverbs.h" #include "uverbs.h"
static struct lock_class_key pd_lock_key;
static struct lock_class_key mr_lock_key;
static struct lock_class_key cq_lock_key;
static struct lock_class_key qp_lock_key;
static struct lock_class_key ah_lock_key;
static struct lock_class_key srq_lock_key;
#define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \ #define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \
do { \ do { \
(udata)->inbuf = (void __user *) (ibuf); \ (udata)->inbuf = (void __user *) (ibuf); \
@ -76,12 +83,13 @@
*/ */
static void init_uobj(struct ib_uobject *uobj, u64 user_handle, static void init_uobj(struct ib_uobject *uobj, u64 user_handle,
struct ib_ucontext *context) struct ib_ucontext *context, struct lock_class_key *key)
{ {
uobj->user_handle = user_handle; uobj->user_handle = user_handle;
uobj->context = context; uobj->context = context;
kref_init(&uobj->ref); kref_init(&uobj->ref);
init_rwsem(&uobj->mutex); init_rwsem(&uobj->mutex);
lockdep_set_class(&uobj->mutex, key);
uobj->live = 0; uobj->live = 0;
} }
@ -470,7 +478,7 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
if (!uobj) if (!uobj)
return -ENOMEM; return -ENOMEM;
init_uobj(uobj, 0, file->ucontext); init_uobj(uobj, 0, file->ucontext, &pd_lock_key);
down_write(&uobj->mutex); down_write(&uobj->mutex);
pd = file->device->ib_dev->alloc_pd(file->device->ib_dev, pd = file->device->ib_dev->alloc_pd(file->device->ib_dev,
@ -591,7 +599,7 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
if (!obj) if (!obj)
return -ENOMEM; return -ENOMEM;
init_uobj(&obj->uobject, 0, file->ucontext); init_uobj(&obj->uobject, 0, file->ucontext, &mr_lock_key);
down_write(&obj->uobject.mutex); down_write(&obj->uobject.mutex);
/* /*
@ -770,7 +778,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
if (!obj) if (!obj)
return -ENOMEM; return -ENOMEM;
init_uobj(&obj->uobject, cmd.user_handle, file->ucontext); init_uobj(&obj->uobject, cmd.user_handle, file->ucontext, &cq_lock_key);
down_write(&obj->uobject.mutex); down_write(&obj->uobject.mutex);
if (cmd.comp_channel >= 0) { if (cmd.comp_channel >= 0) {
@ -1051,13 +1059,14 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
if (!obj) if (!obj)
return -ENOMEM; return -ENOMEM;
init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext); init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext, &qp_lock_key);
down_write(&obj->uevent.uobject.mutex); down_write(&obj->uevent.uobject.mutex);
srq = cmd.is_srq ? idr_read_srq(cmd.srq_handle, file->ucontext) : NULL;
pd = idr_read_pd(cmd.pd_handle, file->ucontext); pd = idr_read_pd(cmd.pd_handle, file->ucontext);
scq = idr_read_cq(cmd.send_cq_handle, file->ucontext); scq = idr_read_cq(cmd.send_cq_handle, file->ucontext);
rcq = idr_read_cq(cmd.recv_cq_handle, file->ucontext); rcq = cmd.recv_cq_handle == cmd.send_cq_handle ?
srq = cmd.is_srq ? idr_read_srq(cmd.srq_handle, file->ucontext) : NULL; scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext);
if (!pd || !scq || !rcq || (cmd.is_srq && !srq)) { if (!pd || !scq || !rcq || (cmd.is_srq && !srq)) {
ret = -EINVAL; ret = -EINVAL;
@ -1125,7 +1134,8 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
put_pd_read(pd); put_pd_read(pd);
put_cq_read(scq); put_cq_read(scq);
put_cq_read(rcq); if (rcq != scq)
put_cq_read(rcq);
if (srq) if (srq)
put_srq_read(srq); put_srq_read(srq);
@ -1150,7 +1160,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
put_pd_read(pd); put_pd_read(pd);
if (scq) if (scq)
put_cq_read(scq); put_cq_read(scq);
if (rcq) if (rcq && rcq != scq)
put_cq_read(rcq); put_cq_read(rcq);
if (srq) if (srq)
put_srq_read(srq); put_srq_read(srq);
@ -1751,7 +1761,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
if (!uobj) if (!uobj)
return -ENOMEM; return -ENOMEM;
init_uobj(uobj, cmd.user_handle, file->ucontext); init_uobj(uobj, cmd.user_handle, file->ucontext, &ah_lock_key);
down_write(&uobj->mutex); down_write(&uobj->mutex);
pd = idr_read_pd(cmd.pd_handle, file->ucontext); pd = idr_read_pd(cmd.pd_handle, file->ucontext);
@ -1775,7 +1785,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
ah = ib_create_ah(pd, &attr); ah = ib_create_ah(pd, &attr);
if (IS_ERR(ah)) { if (IS_ERR(ah)) {
ret = PTR_ERR(ah); ret = PTR_ERR(ah);
goto err; goto err_put;
} }
ah->uobject = uobj; ah->uobject = uobj;
@ -1811,6 +1821,9 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
err_destroy: err_destroy:
ib_destroy_ah(ah); ib_destroy_ah(ah);
err_put:
put_pd_read(pd);
err: err:
put_uobj_write(uobj); put_uobj_write(uobj);
return ret; return ret;
@ -1963,7 +1976,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
if (!obj) if (!obj)
return -ENOMEM; return -ENOMEM;
init_uobj(&obj->uobject, cmd.user_handle, file->ucontext); init_uobj(&obj->uobject, cmd.user_handle, file->ucontext, &srq_lock_key);
down_write(&obj->uobject.mutex); down_write(&obj->uobject.mutex);
pd = idr_read_pd(cmd.pd_handle, file->ucontext); pd = idr_read_pd(cmd.pd_handle, file->ucontext);
@ -1984,7 +1997,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
srq = pd->device->create_srq(pd, &attr, &udata); srq = pd->device->create_srq(pd, &attr, &udata);
if (IS_ERR(srq)) { if (IS_ERR(srq)) {
ret = PTR_ERR(srq); ret = PTR_ERR(srq);
goto err; goto err_put;
} }
srq->device = pd->device; srq->device = pd->device;
@ -2029,6 +2042,9 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
err_destroy: err_destroy:
ib_destroy_srq(srq); ib_destroy_srq(srq);
err_put:
put_pd_read(pd);
err: err:
put_uobj_write(&obj->uobject); put_uobj_write(&obj->uobject);
return ret; return ret;

View File

@ -859,6 +859,38 @@ static void ipath_rcv_layer(struct ipath_devdata *dd, u32 etail,
__ipath_layer_rcv_lid(dd, hdr); __ipath_layer_rcv_lid(dd, hdr);
} }
static void ipath_rcv_hdrerr(struct ipath_devdata *dd,
u32 eflags,
u32 l,
u32 etail,
u64 *rc)
{
char emsg[128];
struct ipath_message_header *hdr;
get_rhf_errstring(eflags, emsg, sizeof emsg);
hdr = (struct ipath_message_header *)&rc[1];
ipath_cdbg(PKT, "RHFerrs %x hdrqtail=%x typ=%u "
"tlen=%x opcode=%x egridx=%x: %s\n",
eflags, l,
ipath_hdrget_rcv_type((__le32 *) rc),
ipath_hdrget_length_in_bytes((__le32 *) rc),
be32_to_cpu(hdr->bth[0]) >> 24,
etail, emsg);
/* Count local link integrity errors. */
if (eflags & (INFINIPATH_RHF_H_ICRCERR | INFINIPATH_RHF_H_VCRCERR)) {
u8 n = (dd->ipath_ibcctrl >>
INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT) &
INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK;
if (++dd->ipath_lli_counter > n) {
dd->ipath_lli_counter = 0;
dd->ipath_lli_errors++;
}
}
}
/* /*
* ipath_kreceive - receive a packet * ipath_kreceive - receive a packet
* @dd: the infinipath device * @dd: the infinipath device
@ -875,7 +907,6 @@ void ipath_kreceive(struct ipath_devdata *dd)
struct ipath_message_header *hdr; struct ipath_message_header *hdr;
u32 eflags, i, etype, tlen, pkttot = 0, updegr=0, reloop=0; u32 eflags, i, etype, tlen, pkttot = 0, updegr=0, reloop=0;
static u64 totcalls; /* stats, may eventually remove */ static u64 totcalls; /* stats, may eventually remove */
char emsg[128];
if (!dd->ipath_hdrqtailptr) { if (!dd->ipath_hdrqtailptr) {
ipath_dev_err(dd, ipath_dev_err(dd,
@ -938,26 +969,9 @@ void ipath_kreceive(struct ipath_devdata *dd)
"%x\n", etype); "%x\n", etype);
} }
if (eflags & ~(INFINIPATH_RHF_H_TIDERR | if (unlikely(eflags))
INFINIPATH_RHF_H_IHDRERR)) { ipath_rcv_hdrerr(dd, eflags, l, etail, rc);
get_rhf_errstring(eflags, emsg, sizeof emsg); else if (etype == RCVHQ_RCV_TYPE_NON_KD) {
ipath_cdbg(PKT, "RHFerrs %x hdrqtail=%x typ=%u "
"tlen=%x opcode=%x egridx=%x: %s\n",
eflags, l, etype, tlen, bthbytes[0],
ipath_hdrget_index((__le32 *) rc), emsg);
/* Count local link integrity errors. */
if (eflags & (INFINIPATH_RHF_H_ICRCERR |
INFINIPATH_RHF_H_VCRCERR)) {
u8 n = (dd->ipath_ibcctrl >>
INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT) &
INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK;
if (++dd->ipath_lli_counter > n) {
dd->ipath_lli_counter = 0;
dd->ipath_lli_errors++;
}
}
} else if (etype == RCVHQ_RCV_TYPE_NON_KD) {
int ret = __ipath_verbs_rcv(dd, rc + 1, int ret = __ipath_verbs_rcv(dd, rc + 1,
ebuf, tlen); ebuf, tlen);
if (ret == -ENODEV) if (ret == -ENODEV)
@ -981,25 +995,7 @@ void ipath_kreceive(struct ipath_devdata *dd)
else if (etype == RCVHQ_RCV_TYPE_EXPECTED) else if (etype == RCVHQ_RCV_TYPE_EXPECTED)
ipath_dbg("Bug: Expected TID, opcode %x; ignored\n", ipath_dbg("Bug: Expected TID, opcode %x; ignored\n",
be32_to_cpu(hdr->bth[0]) & 0xff); be32_to_cpu(hdr->bth[0]) & 0xff);
else if (eflags & (INFINIPATH_RHF_H_TIDERR | else {
INFINIPATH_RHF_H_IHDRERR)) {
/*
* This is a type 3 packet, only the LRH is in the
* rcvhdrq, the rest of the header is in the eager
* buffer.
*/
u8 opcode;
if (ebuf) {
bthbytes = (u8 *) ebuf;
opcode = *bthbytes;
}
else
opcode = 0;
get_rhf_errstring(eflags, emsg, sizeof emsg);
ipath_dbg("Err %x (%s), opcode %x, egrbuf %x, "
"len %x\n", eflags, emsg, opcode, etail,
tlen);
} else {
/* /*
* error packet, type of error unknown. * error packet, type of error unknown.
* Probably type 3, but we don't know, so don't * Probably type 3, but we don't know, so don't

View File

@ -197,6 +197,21 @@ int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
size_t off; size_t off;
int ret; int ret;
/*
* We use RKEY == zero for physical addresses
* (see ipath_get_dma_mr).
*/
if (rkey == 0) {
sge->mr = NULL;
sge->vaddr = phys_to_virt(vaddr);
sge->length = len;
sge->sge_length = len;
ss->sg_list = NULL;
ss->num_sge = 1;
ret = 1;
goto bail;
}
mr = rkt->table[(rkey >> (32 - ib_ipath_lkey_table_size))]; mr = rkt->table[(rkey >> (32 - ib_ipath_lkey_table_size))];
if (unlikely(mr == NULL || mr->lkey != rkey)) { if (unlikely(mr == NULL || mr->lkey != rkey)) {
ret = 0; ret = 0;

View File

@ -191,10 +191,6 @@ void ipath_skip_sge(struct ipath_sge_state *ss, u32 length)
{ {
struct ipath_sge *sge = &ss->sge; struct ipath_sge *sge = &ss->sge;
while (length > sge->sge_length) {
length -= sge->sge_length;
ss->sge = *ss->sg_list++;
}
while (length) { while (length) {
u32 len = sge->length; u32 len = sge->length;
@ -627,6 +623,7 @@ static int ipath_query_device(struct ib_device *ibdev,
props->device_cap_flags = IB_DEVICE_BAD_PKEY_CNTR | props->device_cap_flags = IB_DEVICE_BAD_PKEY_CNTR |
IB_DEVICE_BAD_QKEY_CNTR | IB_DEVICE_SHUTDOWN_PORT | IB_DEVICE_BAD_QKEY_CNTR | IB_DEVICE_SHUTDOWN_PORT |
IB_DEVICE_SYS_IMAGE_GUID; IB_DEVICE_SYS_IMAGE_GUID;
props->page_size_cap = PAGE_SIZE;
props->vendor_id = ipath_layer_get_vendorid(dev->dd); props->vendor_id = ipath_layer_get_vendorid(dev->dd);
props->vendor_part_id = ipath_layer_get_deviceid(dev->dd); props->vendor_part_id = ipath_layer_get_deviceid(dev->dd);
props->hw_ver = ipath_layer_get_pcirev(dev->dd); props->hw_ver = ipath_layer_get_pcirev(dev->dd);

View File

@ -778,11 +778,12 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status)
((dev->fw_ver & 0xffff0000ull) >> 16) | ((dev->fw_ver & 0xffff0000ull) >> 16) |
((dev->fw_ver & 0x0000ffffull) << 16); ((dev->fw_ver & 0x0000ffffull) << 16);
MTHCA_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET);
dev->cmd.max_cmds = 1 << lg;
mthca_dbg(dev, "FW version %012llx, max commands %d\n", mthca_dbg(dev, "FW version %012llx, max commands %d\n",
(unsigned long long) dev->fw_ver, dev->cmd.max_cmds); (unsigned long long) dev->fw_ver, dev->cmd.max_cmds);
MTHCA_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET);
dev->cmd.max_cmds = 1 << lg;
MTHCA_GET(dev->catas_err.addr, outbox, QUERY_FW_ERR_START_OFFSET); MTHCA_GET(dev->catas_err.addr, outbox, QUERY_FW_ERR_START_OFFSET);
MTHCA_GET(dev->catas_err.size, outbox, QUERY_FW_ERR_SIZE_OFFSET); MTHCA_GET(dev->catas_err.size, outbox, QUERY_FW_ERR_SIZE_OFFSET);

View File

@ -370,7 +370,8 @@ int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
return -EINVAL; return -EINVAL;
if (attr_mask & IB_SRQ_LIMIT) { if (attr_mask & IB_SRQ_LIMIT) {
if (attr->srq_limit > srq->max) u32 max_wr = mthca_is_memfree(dev) ? srq->max - 1 : srq->max;
if (attr->srq_limit > max_wr)
return -EINVAL; return -EINVAL;
mutex_lock(&srq->mutex); mutex_lock(&srq->mutex);

View File

@ -212,6 +212,7 @@ struct ipoib_path {
struct ipoib_neigh { struct ipoib_neigh {
struct ipoib_ah *ah; struct ipoib_ah *ah;
union ib_gid dgid;
struct sk_buff_head queue; struct sk_buff_head queue;
struct neighbour *neighbour; struct neighbour *neighbour;

View File

@ -404,6 +404,8 @@ static void path_rec_completion(int status,
list_for_each_entry(neigh, &path->neigh_list, list) { list_for_each_entry(neigh, &path->neigh_list, list) {
kref_get(&path->ah->ref); kref_get(&path->ah->ref);
neigh->ah = path->ah; neigh->ah = path->ah;
memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw,
sizeof(union ib_gid));
while ((skb = __skb_dequeue(&neigh->queue))) while ((skb = __skb_dequeue(&neigh->queue)))
__skb_queue_tail(&skqueue, skb); __skb_queue_tail(&skqueue, skb);
@ -510,6 +512,8 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
if (path->ah) { if (path->ah) {
kref_get(&path->ah->ref); kref_get(&path->ah->ref);
neigh->ah = path->ah; neigh->ah = path->ah;
memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw,
sizeof(union ib_gid));
ipoib_send(dev, skb, path->ah, ipoib_send(dev, skb, path->ah,
be32_to_cpup((__be32 *) skb->dst->neighbour->ha)); be32_to_cpup((__be32 *) skb->dst->neighbour->ha));
@ -633,6 +637,25 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
neigh = *to_ipoib_neigh(skb->dst->neighbour); neigh = *to_ipoib_neigh(skb->dst->neighbour);
if (likely(neigh->ah)) { if (likely(neigh->ah)) {
if (unlikely(memcmp(&neigh->dgid.raw,
skb->dst->neighbour->ha + 4,
sizeof(union ib_gid)))) {
spin_lock(&priv->lock);
/*
* It's safe to call ipoib_put_ah() inside
* priv->lock here, because we know that
* path->ah will always hold one more reference,
* so ipoib_put_ah() will never do more than
* decrement the ref count.
*/
ipoib_put_ah(neigh->ah);
list_del(&neigh->list);
ipoib_neigh_free(neigh);
spin_unlock(&priv->lock);
ipoib_path_lookup(skb, dev);
goto out;
}
ipoib_send(dev, skb, neigh->ah, ipoib_send(dev, skb, neigh->ah,
be32_to_cpup((__be32 *) skb->dst->neighbour->ha)); be32_to_cpup((__be32 *) skb->dst->neighbour->ha));
goto out; goto out;

View File

@ -264,6 +264,10 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
if (!ah) { if (!ah) {
ipoib_warn(priv, "ib_address_create failed\n"); ipoib_warn(priv, "ib_address_create failed\n");
} else { } else {
spin_lock_irq(&priv->lock);
mcast->ah = ah;
spin_unlock_irq(&priv->lock);
ipoib_dbg_mcast(priv, "MGID " IPOIB_GID_FMT ipoib_dbg_mcast(priv, "MGID " IPOIB_GID_FMT
" AV %p, LID 0x%04x, SL %d\n", " AV %p, LID 0x%04x, SL %d\n",
IPOIB_GID_ARG(mcast->mcmember.mgid), IPOIB_GID_ARG(mcast->mcmember.mgid),
@ -271,10 +275,6 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
be16_to_cpu(mcast->mcmember.mlid), be16_to_cpu(mcast->mcmember.mlid),
mcast->mcmember.sl); mcast->mcmember.sl);
} }
spin_lock_irq(&priv->lock);
mcast->ah = ah;
spin_unlock_irq(&priv->lock);
} }
/* actually send any queued packets */ /* actually send any queued packets */

View File

@ -48,10 +48,8 @@ config FUSION_SAS
List of supported controllers: List of supported controllers:
LSISAS1064 LSISAS1064
LSISAS1066
LSISAS1068 LSISAS1068
LSISAS1064E LSISAS1064E
LSISAS1066E
LSISAS1068E LSISAS1068E
config FUSION_MAX_SGE config FUSION_MAX_SGE

View File

@ -9,7 +9,6 @@
#EXTRA_CFLAGS += -DMPT_DEBUG_EXIT #EXTRA_CFLAGS += -DMPT_DEBUG_EXIT
#EXTRA_CFLAGS += -DMPT_DEBUG_FAIL #EXTRA_CFLAGS += -DMPT_DEBUG_FAIL
# #
# driver/module specifics... # driver/module specifics...
# #

View File

@ -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) { if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
freereq = 0; freereq = 0;
devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
ioc->name, pEvReply));
} else { } else {
devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n", devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
ioc->name, pEvReply)); ioc->name, pEvReply));
@ -678,19 +676,19 @@ int
mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx) mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
{ {
MPT_ADAPTER *ioc; 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; return -EINVAL;
}
MptDeviceDriverHandlers[cb_idx] = dd_cbfunc; MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
/* call per pci device probe entry point */ /* call per pci device probe entry point */
list_for_each_entry(ioc, &ioc_list, list) { list_for_each_entry(ioc, &ioc_list, list) {
if(dd_cbfunc->probe) { id = ioc->pcidev->driver ?
dd_cbfunc->probe(ioc->pcidev, ioc->pcidev->driver->id_table : NULL;
ioc->pcidev->driver->id_table); if (dd_cbfunc->probe)
} dd_cbfunc->probe(ioc->pcidev, id);
} }
return 0; return 0;
@ -1056,9 +1054,8 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
dinitprintk((MYIOC_s_INFO_FMT dinitprintk((MYIOC_s_INFO_FMT
"host_page_buffer @ %p, dma @ %x, sz=%d bytes\n", "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
ioc->name, ioc->name, ioc->HostPageBuffer,
ioc->HostPageBuffer, (u32)ioc->HostPageBuffer_dma,
ioc->HostPageBuffer_dma,
host_page_buffer_sz)); host_page_buffer_sz));
ioc->alloc_total += host_page_buffer_sz; ioc->alloc_total += host_page_buffer_sz;
ioc->HostPageBuffer_sz = 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 printk(KERN_WARNING MYNAM
": WARNING - %s did not initialize properly! (%d)\n", ": WARNING - %s did not initialize properly! (%d)\n",
ioc->name, r); ioc->name, r);
list_del(&ioc->list); list_del(&ioc->list);
if (ioc->alt_ioc) if (ioc->alt_ioc)
ioc->alt_ioc->alt_ioc = NULL; 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, * chips (mpt_adapter_disable,
* mpt_diag_reset) * mpt_diag_reset)
*/ */
ioc->cached_fw = NULL;
ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n", 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->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
ioc->alt_ioc->cached_fw = NULL;
} }
} else { } else {
printk(KERN_WARNING MYNAM ": firmware upload failure!\n"); 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? */ /* FIXME? Examine results here? */
} }
out: out:
if ((ret != 0) && irq_allocated) { if ((ret != 0) && irq_allocated) {
free_irq(ioc->pci_irq, ioc); free_irq(ioc->pci_irq, ioc);
if (mpt_msi_enable) 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", dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
ioc->name, count)); ioc->name, count));
ioc->aen_event_read_flag=0;
return r; return r;
} }
@ -2737,6 +2736,8 @@ mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) { 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 = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma; ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
ioc->alloc_total += size;
ioc->alt_ioc->alloc_total -= size;
} else { } else {
if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) ) if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
ioc->alloc_total += size; ioc->alloc_total += size;
@ -3166,6 +3167,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
static int static int
mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
{ {
MPT_ADAPTER *iocp=NULL;
u32 diag0val; u32 diag0val;
u32 doorbell; u32 doorbell;
int hard_reset_done = 0; int hard_reset_done = 0;
@ -3301,17 +3303,23 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
/* FIXME? Examine results here? */ /* 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 /* If the DownloadBoot operation fails, the
* IOC will be left unusable. This is a fatal error * IOC will be left unusable. This is a fatal error
* case. _diag_reset will return < 0 * case. _diag_reset will return < 0
*/ */
for (count = 0; count < 30; count ++) { for (count = 0; count < 30; count ++) {
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) { if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
break; break;
} }
dprintk((MYIOC_s_INFO_FMT "cached_fw: diag0val=%x count=%d\n",
iocp->name, diag0val, count));
/* wait 1 sec */ /* wait 1 sec */
if (sleepFlag == CAN_SLEEP) { if (sleepFlag == CAN_SLEEP) {
msleep (1000); msleep (1000);
@ -3320,7 +3328,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
} }
} }
if ((count = mpt_downloadboot(ioc, if ((count = mpt_downloadboot(ioc,
(MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) { (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
printk(KERN_WARNING MYNAM printk(KERN_WARNING MYNAM
": firmware downloadboot failure (%d)!\n", count); ": firmware downloadboot failure (%d)!\n", count);
} }
@ -3907,18 +3915,18 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
if (sleepFlag == CAN_SLEEP) { if (sleepFlag == CAN_SLEEP) {
while (--cntdn) { while (--cntdn) {
msleep (1);
intstat = CHIPREG_READ32(&ioc->chip->IntStatus); intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
break; break;
msleep (1);
count++; count++;
} }
} else { } else {
while (--cntdn) { while (--cntdn) {
mdelay (1);
intstat = CHIPREG_READ32(&ioc->chip->IntStatus); intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
break; break;
mdelay (1);
count++; count++;
} }
} }
@ -4883,6 +4891,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma); pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
if (!pIoc4) if (!pIoc4)
return; return;
ioc->alloc_total += iocpage4sz;
} else { } else {
ioc4_dma = ioc->spi_data.IocPg4_dma; ioc4_dma = ioc->spi_data.IocPg4_dma;
iocpage4sz = ioc->spi_data.IocPg4Sz; iocpage4sz = ioc->spi_data.IocPg4Sz;
@ -4899,6 +4908,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
} else { } else {
pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma); pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
ioc->spi_data.pIocPg4 = NULL; ioc->spi_data.pIocPg4 = NULL;
ioc->alloc_total -= iocpage4sz;
} }
} }
@ -5030,19 +5040,18 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
EventAck_t *pAck; EventAck_t *pAck;
if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK " dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
"request frame for Event=%x EventContext=%x EventData=%x!\n", ioc->name,__FUNCTION__));
ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext),
le32_to_cpu(evnp->Data[0]));
return -1; 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->Function = MPI_FUNCTION_EVENT_ACK;
pAck->ChainOffset = 0; pAck->ChainOffset = 0;
pAck->Reserved[0] = pAck->Reserved[1] = 0;
pAck->MsgFlags = 0; pAck->MsgFlags = 0;
pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
pAck->Event = evnp->Event; pAck->Event = evnp->Event;
pAck->EventContext = evnp->EventContext; pAck->EventContext = evnp->EventContext;
@ -5704,9 +5713,9 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
break; break;
case MPI_EVENT_EVENT_CHANGE: case MPI_EVENT_EVENT_CHANGE:
if (evData0) if (evData0)
ds = "Events(ON) Change"; ds = "Events ON";
else else
ds = "Events(OFF) Change"; ds = "Events OFF";
break; break;
case MPI_EVENT_INTEGRATED_RAID: case MPI_EVENT_INTEGRATED_RAID:
{ {
@ -5777,8 +5786,27 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
break; break;
case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED: case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
snprintf(evStr, EVENT_DESCR_STR_SZ, snprintf(evStr, EVENT_DESCR_STR_SZ,
"SAS Device Status Change: No Persistancy " "SAS Device Status Change: No Persistancy: id=%d", id);
"Added: 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; break;
default: default:
snprintf(evStr, EVENT_DESCR_STR_SZ, snprintf(evStr, EVENT_DESCR_STR_SZ,
@ -6034,7 +6062,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
* @ioc: Pointer to MPT_ADAPTER structure * @ioc: Pointer to MPT_ADAPTER structure
* @log_info: U32 LogInfo reply word from the IOC * @log_info: U32 LogInfo reply word from the IOC
* *
* Refer to lsi/fc_log.h. * Refer to lsi/mpi_log_fc.h.
*/ */
static void static void
mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info) 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 */ "Invalid SAS Address", /* 01h */
NULL, /* 02h */ NULL, /* 02h */
"Invalid Page", /* 03h */ "Invalid Page", /* 03h */
NULL, /* 04h */ "Diag Message Error", /* 04h */
"Task Terminated" /* 05h */ "Task Terminated", /* 05h */
"Enclosure Management", /* 06h */
"Target Mode" /* 07h */
}; };
static char *pl_code_str[] = { static char *pl_code_str[] = {
NULL, /* 00h */ NULL, /* 00h */
@ -6158,7 +6188,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
"IO Executed", /* 14h */ "IO Executed", /* 14h */
"Persistant Reservation Out Not Affiliation Owner", /* 15h */ "Persistant Reservation Out Not Affiliation Owner", /* 15h */
"Open Transmit DMA Abort", /* 16h */ "Open Transmit DMA Abort", /* 16h */
NULL, /* 17h */ "IO Device Missing Delay Retry", /* 17h */
NULL, /* 18h */ NULL, /* 18h */
NULL, /* 19h */ NULL, /* 19h */
NULL, /* 1Ah */ NULL, /* 1Ah */
@ -6238,7 +6268,7 @@ static void
mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
{ {
u32 status = ioc_status & MPI_IOCSTATUS_MASK; u32 status = ioc_status & MPI_IOCSTATUS_MASK;
char *desc = ""; char *desc = NULL;
switch (status) { switch (status) {
case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */ 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"; desc = "Others";
break; break;
} }
if (desc != "") if (desc != NULL)
printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc); 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(mpt_free_fw_memory);
EXPORT_SYMBOL(mptbase_sas_persist_operation); EXPORT_SYMBOL(mptbase_sas_persist_operation);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* fusion_init - Fusion MPT base driver initialization routine. * fusion_init - Fusion MPT base driver initialization routine.

View File

@ -75,8 +75,8 @@
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
#endif #endif
#define MPT_LINUX_VERSION_COMMON "3.04.00" #define MPT_LINUX_VERSION_COMMON "3.04.01"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.00" #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.01"
#define WHAT_MAGIC_STRING "@" "(" "#" ")" #define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \ #define show_mptmod_ver(s,ver) \
@ -307,8 +307,8 @@ typedef struct _SYSIF_REGS
u32 HostIndex; /* 50 Host Index register */ u32 HostIndex; /* 50 Host Index register */
u32 Reserved4[15]; /* 54-8F */ u32 Reserved4[15]; /* 54-8F */
u32 Fubar; /* 90 For Fubar usage */ u32 Fubar; /* 90 For Fubar usage */
u32 Reserved5[1050];/* 94-10F8 */ u32 Reserved5[1050];/* 94-10F8 */
u32 Reset_1078; /* 10FC Reset 1078 */ u32 Reset_1078; /* 10FC Reset 1078 */
} SYSIF_REGS; } SYSIF_REGS;
/* /*
@ -363,6 +363,7 @@ typedef struct _VirtDevice {
#define MPT_TARGET_FLAGS_VALID_56 0x10 #define MPT_TARGET_FLAGS_VALID_56 0x10
#define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20 #define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20
#define MPT_TARGET_FLAGS_RAID_COMPONENT 0x40 #define MPT_TARGET_FLAGS_RAID_COMPONENT 0x40
#define MPT_TARGET_FLAGS_LED_ON 0x80
/* /*
* /proc/mpt interface * /proc/mpt interface
@ -634,7 +635,6 @@ typedef struct _MPT_ADAPTER
u16 handle; u16 handle;
int sas_index; /* index refrencing */ int sas_index; /* index refrencing */
MPT_SAS_MGMT sas_mgmt; MPT_SAS_MGMT sas_mgmt;
int num_ports;
struct work_struct sas_persist_task; struct work_struct sas_persist_task;
struct work_struct fc_setup_reset_work; struct work_struct fc_setup_reset_work;
@ -644,7 +644,6 @@ typedef struct _MPT_ADAPTER
struct work_struct fc_rescan_work; struct work_struct fc_rescan_work;
char fc_rescan_work_q_name[KOBJ_NAME_LEN]; char fc_rescan_work_q_name[KOBJ_NAME_LEN];
struct workqueue_struct *fc_rescan_work_q; struct workqueue_struct *fc_rescan_work_q;
u8 port_serial_number;
} MPT_ADAPTER; } MPT_ADAPTER;
/* /*
@ -982,7 +981,7 @@ typedef struct _MPT_SCSI_HOST {
wait_queue_head_t scandv_waitq; wait_queue_head_t scandv_waitq;
int scandv_wait_done; int scandv_wait_done;
long last_queue_full; long last_queue_full;
u8 mpt_pq_filter; u16 tm_iocstatus;
} MPT_SCSI_HOST; } MPT_SCSI_HOST;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

View File

@ -2332,7 +2332,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* Prototype Routine for the HP HOST INFO command. /* Prototype Routine for the HOST INFO command.
* *
* Outputs: None. * Outputs: None.
* Return: 0 if successful * 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. * Outputs: None.
* Return: 0 if successful * Return: 0 if successful

View File

@ -354,9 +354,6 @@ struct mpt_ioctl_command32 {
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* HP Specific IOCTL Defines and Structures
*/
#define CPQFCTS_IOC_MAGIC 'Z' #define CPQFCTS_IOC_MAGIC 'Z'
#define HP_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_GETHOSTINFO1 _IOR(HP_IOC_MAGIC, 20, hp_host_info_rev0_t)
#define HP_GETTARGETINFO _IOR(HP_IOC_MAGIC, 21, hp_target_info_t) #define HP_GETTARGETINFO _IOR(HP_IOC_MAGIC, 21, hp_target_info_t)
/* All HP IOCTLs must include this header
*/
typedef struct _hp_header { typedef struct _hp_header {
unsigned int iocnum; unsigned int iocnum;
unsigned int host; unsigned int host;

View File

@ -77,10 +77,6 @@ MODULE_DESCRIPTION(my_NAME);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
/* Command line args */ /* 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) #define MPTFC_DEV_LOSS_TMO (60)
static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; /* reasonable default */ static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; /* reasonable default */
module_param(mptfc_dev_loss_tmo, int, 0); module_param(mptfc_dev_loss_tmo, int, 0);
@ -513,8 +509,7 @@ mptfc_slave_alloc(struct scsi_device *sdev)
if (vtarget->num_luns == 0) { if (vtarget->num_luns == 0) {
vtarget->ioc_id = hd->ioc->id; vtarget->ioc_id = hd->ioc->id;
vtarget->tflags = MPT_TARGET_FLAGS_Q_YES | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
MPT_TARGET_FLAGS_VALID_INQUIRY;
hd->Targets[sdev->id] = vtarget; 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.data = (unsigned long) hd;
hd->timer.function = mptscsih_timer_expired; 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); init_waitqueue_head(&hd->scandv_waitq);
hd->scandv_wait_done = 0; hd->scandv_wait_done = 0;
hd->last_queue_full = 0; hd->last_queue_full = 0;

View File

@ -67,20 +67,19 @@
#define my_VERSION MPT_LINUX_VERSION_COMMON #define my_VERSION MPT_LINUX_VERSION_COMMON
#define MYNAM "mptsas" #define MYNAM "mptsas"
/*
* Reserved channel for integrated raid
*/
#define MPTSAS_RAID_CHANNEL 1
MODULE_AUTHOR(MODULEAUTHOR); MODULE_AUTHOR(MODULEAUTHOR);
MODULE_DESCRIPTION(my_NAME); MODULE_DESCRIPTION(my_NAME);
MODULE_LICENSE("GPL"); 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; static int mpt_pt_clear;
module_param(mpt_pt_clear, int, 0); module_param(mpt_pt_clear, int, 0);
MODULE_PARM_DESC(mpt_pt_clear, MODULE_PARM_DESC(mpt_pt_clear,
"Clear persistency table: enable=1 " " Clear persistency table: enable=1 "
"(default=MPTSCSIH_PT_CLEAR=0)"); "(default=MPTSCSIH_PT_CLEAR=0)");
static int mptsasDoneCtx = -1; static int mptsasDoneCtx = -1;
@ -144,7 +143,6 @@ struct mptsas_devinfo {
* Specific details on ports, wide/narrow * Specific details on ports, wide/narrow
*/ */
struct mptsas_portinfo_details{ struct mptsas_portinfo_details{
u8 port_id; /* port number provided to transport */
u16 num_phys; /* number of phys belong to this port */ u16 num_phys; /* number of phys belong to this port */
u64 phy_bitmask; /* TODO, extend support for 255 phys */ u64 phy_bitmask; /* TODO, extend support for 255 phys */
struct sas_rphy *rphy; /* transport layer rphy object */ 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; port_info = port_details->port_info;
phy_info = port_info->phy_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", "bitmask=0x%016llX\n",
__FUNCTION__, port_details, port_details->port_id, __FUNCTION__, port_details, port_details->num_phys,
port_details->num_phys, port_details->phy_bitmask)); port_details->phy_bitmask));
for (i = 0; i < port_info->num_phys; i++, phy_info++) { for (i = 0; i < port_info->num_phys; i++, phy_info++) {
if(phy_info->port_details != port_details) 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. * phy be removed by firmware events.
*/ */
dsaswideprintk((KERN_DEBUG dsaswideprintk((KERN_DEBUG
"%s: [%p]: port=%d deleting phy = %d\n", "%s: [%p]: deleting phy = %d\n",
__FUNCTION__, port_details, __FUNCTION__, port_details, i));
port_details->port_id, i));
port_details->num_phys--; port_details->num_phys--;
port_details->phy_bitmask &= ~ (1 << phy_info->phy_id); port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); 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; goto out;
port_details->num_phys = 1; port_details->num_phys = 1;
port_details->port_info = port_info; port_details->port_info = port_info;
port_details->port_id = ioc->port_serial_number++;
if (phy_info->phy_id < 64 ) if (phy_info->phy_id < 64 )
port_details->phy_bitmask |= port_details->phy_bitmask |=
(1 << phy_info->phy_id); (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); mptsas_get_port(phy_info_cmp);
port_details->starget = port_details->starget =
mptsas_get_starget(phy_info_cmp); mptsas_get_starget(phy_info_cmp);
port_details->port_id =
phy_info_cmp->port_details->port_id;
port_details->num_phys = port_details->num_phys =
phy_info_cmp->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) if (!phy_info_cmp->port_details->num_phys)
kfree(phy_info_cmp->port_details); kfree(phy_info_cmp->port_details);
} else } else
@ -554,11 +546,11 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
if (!port_details) if (!port_details)
continue; continue;
dsaswideprintk((KERN_DEBUG 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", "bitmask=0x%016llX\n",
__FUNCTION__, __FUNCTION__,
port_details, i, port_details->port_id, port_details, i, port_details->num_phys,
port_details->num_phys, port_details->phy_bitmask)); port_details->phy_bitmask));
dsaswideprintk((KERN_DEBUG"\t\tport = %p rphy=%p\n", dsaswideprintk((KERN_DEBUG"\t\tport = %p rphy=%p\n",
port_details->port, port_details->rphy)); port_details->port, port_details->rphy));
} }
@ -651,16 +643,13 @@ mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
static int static int
mptsas_slave_configure(struct scsi_device *sdev) mptsas_slave_configure(struct scsi_device *sdev)
{ {
struct Scsi_Host *host = sdev->host;
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
/* if (sdev->channel == MPTSAS_RAID_CHANNEL)
* RAID volumes placed beyond the last expected port. goto out;
* Ignore sending sas mode pages in that case..
*/
if (sdev->channel < hd->ioc->num_ports)
sas_read_port_mode_page(sdev);
sas_read_port_mode_page(sdev);
out:
return mptscsih_slave_configure(sdev); return mptscsih_slave_configure(sdev);
} }
@ -689,10 +678,7 @@ mptsas_target_alloc(struct scsi_target *starget)
hd->Targets[target_id] = vtarget; hd->Targets[target_id] = vtarget;
/* if (starget->channel == MPTSAS_RAID_CHANNEL)
* RAID volumes placed beyond the last expected port.
*/
if (starget->channel == hd->ioc->num_ports)
goto out; goto out;
rphy = dev_to_rphy(starget->dev.parent); rphy = dev_to_rphy(starget->dev.parent);
@ -743,7 +729,7 @@ mptsas_target_destroy(struct scsi_target *starget)
if (!starget->hostdata) if (!starget->hostdata)
return; return;
if (starget->channel == hd->ioc->num_ports) if (starget->channel == MPTSAS_RAID_CHANNEL)
goto out; goto out;
rphy = dev_to_rphy(starget->dev.parent); rphy = dev_to_rphy(starget->dev.parent);
@ -783,10 +769,7 @@ mptsas_slave_alloc(struct scsi_device *sdev)
starget = scsi_target(sdev); starget = scsi_target(sdev);
vdev->vtarget = starget->hostdata; vdev->vtarget = starget->hostdata;
/* if (sdev->channel == MPTSAS_RAID_CHANNEL)
* RAID volumes placed beyond the last expected port.
*/
if (sdev->channel == hd->ioc->num_ports)
goto out; goto out;
rphy = dev_to_rphy(sdev->sdev_target->dev.parent); 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 (phy_info->sas_port_add_phy) {
if (!port) { if (!port) {
port = sas_port_alloc(dev, port = sas_port_alloc_num(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));
if (!port) { if (!port) {
error = -ENOMEM; error = -ENOMEM;
goto out; goto out;
@ -1625,6 +1604,9 @@ static int mptsas_probe_one_phy(struct device *dev,
goto out; goto out;
} }
mptsas_set_port(phy_info, port); 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", dsaswideprintk((KERN_DEBUG "sas_port_add_phy: phy_id=%d\n",
phy_info->phy_id)); phy_info->phy_id));
@ -1736,7 +1718,6 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
hba = NULL; hba = NULL;
} }
mutex_unlock(&ioc->sas_topology_mutex); mutex_unlock(&ioc->sas_topology_mutex);
ioc->num_ports = port_info->num_phys;
for (i = 0; i < port_info->num_phys; i++) { for (i = 0; i < port_info->num_phys; i++) {
mptsas_sas_phy_pg0(ioc, &port_info->phy_info[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) expander_sas_address)
continue; continue;
#ifdef MPT_DEBUG_SAS_WIDE #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 #endif
sas_port_delete(port); sas_port_delete(port);
mptsas_port_delete(phy_info->port_details); mptsas_port_delete(phy_info->port_details);
@ -1984,7 +1966,7 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
if (!ioc->raid_data.pIocPg2->NumActiveVolumes) if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
goto out; goto out;
for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) { 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); ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
} }
out: out:
@ -2185,7 +2167,8 @@ mptsas_hotplug_work(void *arg)
ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
#ifdef MPT_DEBUG_SAS_WIDE #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 #endif
sas_port_delete(port); sas_port_delete(port);
mptsas_port_delete(phy_info->port_details); mptsas_port_delete(phy_info->port_details);
@ -2289,35 +2272,26 @@ mptsas_hotplug_work(void *arg)
mptsas_set_rphy(phy_info, rphy); mptsas_set_rphy(phy_info, rphy);
break; break;
case MPTSAS_ADD_RAID: case MPTSAS_ADD_RAID:
sdev = scsi_device_lookup( sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
ioc->sh, ev->id, 0);
ioc->num_ports,
ev->id,
0);
if (sdev) { if (sdev) {
scsi_device_put(sdev); scsi_device_put(sdev);
break; break;
} }
printk(MYIOC_s_INFO_FMT printk(MYIOC_s_INFO_FMT
"attaching raid volume, channel %d, id %d\n", "attaching raid volume, channel %d, id %d\n",
ioc->name, ioc->num_ports, ev->id); ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
scsi_add_device(ioc->sh, scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ev->id, 0);
ioc->num_ports,
ev->id,
0);
mpt_findImVolumes(ioc); mpt_findImVolumes(ioc);
break; break;
case MPTSAS_DEL_RAID: case MPTSAS_DEL_RAID:
sdev = scsi_device_lookup( sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
ioc->sh, ev->id, 0);
ioc->num_ports,
ev->id,
0);
if (!sdev) if (!sdev)
break; break;
printk(MYIOC_s_INFO_FMT printk(MYIOC_s_INFO_FMT
"removing raid volume, channel %d, id %d\n", "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 = sdev->hostdata;
vdevice->vtarget->deleted = 1; vdevice->vtarget->deleted = 1;
mptsas_target_reset(ioc, vdevice->vtarget); 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.data = (unsigned long) hd;
hd->timer.function = mptscsih_timer_expired; hd->timer.function = mptscsih_timer_expired;
hd->mpt_pq_filter = mpt_pq_filter;
ioc->sas_data.ptClear = mpt_pt_clear; ioc->sas_data.ptClear = mpt_pt_clear;
if (ioc->sas_data.ptClear==1) { 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); 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); init_waitqueue_head(&hd->scandv_waitq);
hd->scandv_wait_done = 0; hd->scandv_wait_done = 0;
hd->last_queue_full = 0; hd->last_queue_full = 0;

View File

@ -66,6 +66,7 @@
#include "mptbase.h" #include "mptbase.h"
#include "mptscsih.h" #include "mptscsih.h"
#include "lsi/mpi_log_sas.h"
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#define my_NAME "Fusion MPT SCSI Host driver" #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 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_pending_wait(MPT_SCSI_HOST * hd);
static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); 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); static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
@ -497,6 +498,34 @@ mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
return SUCCESS; return SUCCESS;
} /* mptscsih_AddSGE() */ } /* 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 * 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; SCSIIORequest_t *pScsiReq;
SCSIIOReply_t *pScsiReply; SCSIIOReply_t *pScsiReply;
u16 req_idx, req_idx_MR; u16 req_idx, req_idx_MR;
VirtDevice *vdev;
VirtTarget *vtarget;
hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; 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]; sc = hd->ScsiLookup[req_idx];
hd->ScsiLookup[req_idx] = NULL;
if (sc == NULL) { if (sc == NULL) {
MPIHeader_t *hdr = (MPIHeader_t *)mf; 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; 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 */ sc->result = DID_OK << 16; /* Set default reply as OK */
pScsiReq = (SCSIIORequest_t *) mf; pScsiReq = (SCSIIORequest_t *) mf;
pScsiReply = (SCSIIOReply_t *) mr; 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) if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
hd->sel_timeout[pScsiReq->TargetID]++; 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; break;
case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */ 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 */ case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
/* Linux handles an unsolicited DID_RESET better /* Linux handles an unsolicited DID_RESET better
* than an unsolicited DID_ABORT. * 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; sc->result=DID_SOFT_ERROR << 16;
else /* Sufficient data transfer occurred */ else /* Sufficient data transfer occurred */
sc->result = (DID_OK << 16) | scsi_status; 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)); "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
break; 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); sc->request_bufflen, sc->sc_data_direction);
} }
hd->ScsiLookup[req_idx] = NULL;
sc->scsi_done(sc); /* Issue the command callback */ sc->scsi_done(sc); /* Issue the command callback */
/* Free Chain buffers */ /* Free Chain buffers */
@ -827,9 +889,17 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n", dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
mf, SCpnt)); 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) /* Set status, free OS resources (SG DMA buffers)
* Do OS callback * Do OS callback
* Free driver resources (chain, msg buffers)
*/ */
if (SCpnt->use_sg) { if (SCpnt->use_sg) {
pci_unmap_sg(ioc->pcidev, pci_unmap_sg(ioc->pcidev,
@ -845,12 +915,6 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
SCpnt->result = DID_RESET << 16; SCpnt->result = DID_RESET << 16;
SCpnt->host_scribble = NULL; 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 */ 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) { if ((sc = hd->ScsiLookup[ii]) != NULL) {
mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii); 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", dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1])); hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun))) if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
continue; continue;
@ -899,6 +963,8 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
hd->ScsiLookup[ii] = NULL; hd->ScsiLookup[ii] = NULL;
mptscsih_freeChainBuffers(hd->ioc, ii); mptscsih_freeChainBuffers(hd->ioc, ii);
mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf); mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
if ((unsigned char *)mf != sc->host_scribble)
continue;
if (sc->use_sg) { if (sc->use_sg) {
pci_unmap_sg(hd->ioc->pcidev, pci_unmap_sg(hd->ioc->pcidev,
(struct scatterlist *) sc->request_buffer, (struct scatterlist *) sc->request_buffer,
@ -1341,8 +1407,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
goto fail; goto fail;
} }
SCpnt->host_scribble = (unsigned char *)mf;
hd->ScsiLookup[my_idx] = SCpnt; hd->ScsiLookup[my_idx] = SCpnt;
SCpnt->host_scribble = NULL;
mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf); mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n", 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); 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)); dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
return rc; return rc;
@ -1654,6 +1726,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
int scpnt_idx; int scpnt_idx;
int retval; int retval;
VirtDevice *vdev; VirtDevice *vdev;
ulong sn = SCpnt->serial_number;
/* If we can't locate our host adapter structure, return FAILED status. /* 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, vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun,
ctx2abort, mptscsih_get_tm_timeout(hd->ioc)); 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", printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
hd->ioc->name, hd->ioc->name,
((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt); ((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); DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK; 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", dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo))); ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
/* Error? (anything non-zero?) */ /* 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->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
ioc->eventContext++; 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 { } 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) SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
{ {
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;

View File

@ -83,10 +83,6 @@ static int mpt_saf_te = MPTSCSIH_SAF_TE;
module_param(mpt_saf_te, int, 0); module_param(mpt_saf_te, int, 0);
MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1 (default=MPTSCSIH_SAF_TE=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_offset(struct scsi_target *, int);
static void mptspi_write_width(struct scsi_target *, int); static void mptspi_write_width(struct scsi_target *, int);
static int mptspi_write_spi_device_pg1(struct scsi_target *, 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; hd->timer.function = mptscsih_timer_expired;
ioc->spi_data.Saf_Te = mpt_saf_te; ioc->spi_data.Saf_Te = mpt_saf_te;
hd->mpt_pq_filter = mpt_pq_filter;
hd->negoNvram = MPT_SCSICFG_USE_NVRAM; hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
ddvprintk((MYIOC_s_INFO_FMT ddvprintk((MYIOC_s_INFO_FMT
"saf_te %x mpt_pq_filter %x\n", "saf_te %x\n",
ioc->name, ioc->name,
mpt_saf_te, mpt_saf_te));
mpt_pq_filter));
ioc->spi_data.noQas = 0; ioc->spi_data.noQas = 0;
init_waitqueue_head(&hd->scandv_waitq); init_waitqueue_head(&hd->scandv_waitq);

View File

@ -132,6 +132,7 @@ static int __init dummy_init_module(void)
for (i = 0; i < numdummies && !err; i++) for (i = 0; i < numdummies && !err; i++)
err = dummy_init_one(i); err = dummy_init_one(i);
if (err) { if (err) {
i--;
while (--i >= 0) while (--i >= 0)
dummy_free_one(i); dummy_free_one(i);
} }

View File

@ -110,6 +110,9 @@ struct e1000_adapter;
#define E1000_MIN_RXD 80 #define E1000_MIN_RXD 80
#define E1000_MAX_82544_RXD 4096 #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 */ /* Supported Rx Buffer Sizes */
#define E1000_RXBUFFER_128 128 /* Used for packet split */ #define E1000_RXBUFFER_128 128 /* Used for packet split */
#define E1000_RXBUFFER_256 256 /* Used for packet split */ #define E1000_RXBUFFER_256 256 /* Used for packet split */

View File

@ -36,7 +36,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
#else #else
#define DRIVERNAPI "-NAPI" #define DRIVERNAPI "-NAPI"
#endif #endif
#define DRV_VERSION "7.1.9-k2"DRIVERNAPI #define DRV_VERSION "7.1.9-k4"DRIVERNAPI
char e1000_driver_version[] = DRV_VERSION; char e1000_driver_version[] = DRV_VERSION;
static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; 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); 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; adapter->rx_ps_bsize0 = E1000_RXBUFFER_128;
hw->max_frame_size = netdev->mtu + hw->max_frame_size = netdev->mtu +
ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; 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; adapter->rx_buffer_len = E1000_RXBUFFER_16384;
/* adjust allocation if LPE protects us, and we aren't using SBP */ /* adjust allocation if LPE protects us, and we aren't using SBP */
#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
if (!adapter->hw.tbi_compatibility_on && if (!adapter->hw.tbi_compatibility_on &&
((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) || ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) ||
(max_frame == MAXIMUM_ETHERNET_VLAN_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_REG(hw, IMC, ~0);
E1000_WRITE_FLUSH(hw); E1000_WRITE_FLUSH(hw);
} }
if (likely(netif_rx_schedule_prep(&adapter->polling_netdev[0]))) if (likely(netif_rx_schedule_prep(netdev)))
__netif_rx_schedule(&adapter->polling_netdev[0]); __netif_rx_schedule(netdev);
else else
e1000_irq_enable(adapter); e1000_irq_enable(adapter);
#else #else
@ -3431,34 +3430,26 @@ e1000_clean(struct net_device *poll_dev, int *budget)
{ {
struct e1000_adapter *adapter; struct e1000_adapter *adapter;
int work_to_do = min(*budget, poll_dev->quota); 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. */ /* Must NOT use netdev_priv macro here. */
adapter = poll_dev->priv; adapter = poll_dev->priv;
/* Keep link state information with original netdev */ /* Keep link state information with original netdev */
if (!netif_carrier_ok(adapter->netdev)) if (!netif_carrier_ok(poll_dev))
goto quit_polling; goto quit_polling;
while (poll_dev != &adapter->polling_netdev[i]) { /* e1000_clean is called per-cpu. This lock protects
i++; * tx_ring[0] from being cleaned by multiple cpus
BUG_ON(i == adapter->num_rx_queues); * 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)) { adapter->clean_rx(adapter, &adapter->rx_ring[0],
/* 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],
&work_done, work_to_do); &work_done, work_to_do);
*budget -= work_done; *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 no Tx and not enough Rx work done, exit the polling mode */
if ((!tx_cleaned && (work_done == 0)) || if ((!tx_cleaned && (work_done == 0)) ||
!netif_running(adapter->netdev)) { !netif_running(poll_dev)) {
quit_polling: quit_polling:
netif_rx_complete(poll_dev); netif_rx_complete(poll_dev);
e1000_irq_enable(adapter); e1000_irq_enable(adapter);
@ -3681,6 +3672,9 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
length = le16_to_cpu(rx_desc->length); length = le16_to_cpu(rx_desc->length);
/* adjust length to remove Ethernet CRC */
length -= 4;
if (unlikely(!(status & E1000_RXD_STAT_EOP))) { if (unlikely(!(status & E1000_RXD_STAT_EOP))) {
/* All receives must fit into a single buffer */ /* All receives must fit into a single buffer */
E1000_DBG("%s: Receive packet consumed multiple" 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, pci_dma_sync_single_for_device(pdev,
ps_page_dma->ps_page_dma[0], ps_page_dma->ps_page_dma[0],
PAGE_SIZE, PCI_DMA_FROMDEVICE); PAGE_SIZE, PCI_DMA_FROMDEVICE);
/* remove the CRC */
l1 -= 4;
skb_put(skb, l1); skb_put(skb, l1);
length += l1;
goto copydone; goto copydone;
} /* if */ } /* if */
} }
@ -3905,6 +3900,10 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
skb->truesize += length; 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: copydone:
e1000_rx_checksum(adapter, staterr, e1000_rx_checksum(adapter, staterr,
le16_to_cpu(rx_desc->wb.lower.hi_dword.csum_ip.csum), skb); 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) e1000_netpoll(struct net_device *netdev)
{ {
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
disable_irq(adapter->pdev->irq); disable_irq(adapter->pdev->irq);
e1000_intr(adapter->pdev->irq, netdev, NULL); e1000_intr(adapter->pdev->irq, netdev, NULL);
e1000_clean_tx_irq(adapter, adapter->tx_ring); e1000_clean_tx_irq(adapter, adapter->tx_ring);

View File

@ -271,6 +271,7 @@ static int __init ifb_init_module(void)
for (i = 0; i < numifbs && !err; i++) for (i = 0; i < numifbs && !err; i++)
err = ifb_init_one(i); err = ifb_init_one(i);
if (err) { if (err) {
i--;
while (--i >= 0) while (--i >= 0)
ifb_free_one(i); ifb_free_one(i);
} }

View File

@ -620,7 +620,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
return -ENXIO; return -ENXIO;
} }
dev_info(&mgp->pdev->dev, "handoff confirmed\n"); dev_info(&mgp->pdev->dev, "handoff confirmed\n");
myri10ge_dummy_rdma(mgp, mgp->tx.boundary != 4096); myri10ge_dummy_rdma(mgp, 1);
return 0; return 0;
} }

View File

@ -516,10 +516,7 @@ static int skge_set_pauseparam(struct net_device *dev,
/* Chip internal frequency for clock calculations */ /* Chip internal frequency for clock calculations */
static inline u32 hwkhz(const struct skge_hw *hw) static inline u32 hwkhz(const struct skge_hw *hw)
{ {
if (hw->chip_id == CHIP_ID_GENESIS) return (hw->chip_id == CHIP_ID_GENESIS) ? 53125 : 78125;
return 53215; /* or: 53.125 MHz */
else
return 78215; /* or: 78.125 MHz */
} }
/* Chip HZ to microseconds */ /* Chip HZ to microseconds */

View File

@ -50,7 +50,7 @@
#include "sky2.h" #include "sky2.h"
#define DRV_NAME "sky2" #define DRV_NAME "sky2"
#define DRV_VERSION "1.4" #define DRV_VERSION "1.5"
#define PFX DRV_NAME " " #define PFX DRV_NAME " "
/* /*
@ -2204,9 +2204,6 @@ static int sky2_poll(struct net_device *dev0, int *budget)
int work_done = 0; int work_done = 0;
u32 status = sky2_read32(hw, B0_Y2_SP_EISR); u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
if (!~status)
goto out;
if (status & Y2_IS_HW_ERR) if (status & Y2_IS_HW_ERR)
sky2_hw_intr(hw); sky2_hw_intr(hw);
@ -2243,7 +2240,7 @@ static int sky2_poll(struct net_device *dev0, int *budget)
if (sky2_more_work(hw)) if (sky2_more_work(hw))
return 1; return 1;
out:
netif_rx_complete(dev0); netif_rx_complete(dev0);
sky2_read32(hw, B0_Y2_SP_LISR); sky2_read32(hw, B0_Y2_SP_LISR);

View File

@ -84,7 +84,7 @@ MODULE_DEVICE_TABLE(pci, spider_net_pci_tbl);
* *
* returns the content of the specified SMMIO register. * returns the content of the specified SMMIO register.
*/ */
static u32 static inline u32
spider_net_read_reg(struct spider_net_card *card, u32 reg) spider_net_read_reg(struct spider_net_card *card, u32 reg)
{ {
u32 value; u32 value;
@ -101,7 +101,7 @@ spider_net_read_reg(struct spider_net_card *card, u32 reg)
* @reg: register to write to * @reg: register to write to
* @value: value to write into the specified SMMIO register * @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) spider_net_write_reg(struct spider_net_card *card, u32 reg, u32 value)
{ {
value = cpu_to_le32(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 * 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) spider_net_get_descr_status(struct spider_net_descr *descr)
{ {
u32 cmd_status; return descr->dmac_cmd_status & SPIDER_NET_DESCR_IND_PROC_MASK;
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;
} }
/** /**
@ -328,24 +299,23 @@ spider_net_free_chain(struct spider_net_card *card,
static int static int
spider_net_init_chain(struct spider_net_card *card, spider_net_init_chain(struct spider_net_card *card,
struct spider_net_descr_chain *chain, 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; int i;
struct spider_net_descr *descr; struct spider_net_descr *descr;
dma_addr_t buf; dma_addr_t buf;
atomic_set(&card->rx_chain_refill,0);
descr = start_descr; descr = start_descr;
memset(descr, 0, sizeof(*descr) * no); memset(descr, 0, sizeof(*descr) * no);
/* set up the hardware pointers in each descriptor */ /* set up the hardware pointers in each descriptor */
for (i=0; i<no; i++, descr++) { 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, buf = pci_map_single(card->pdev, descr,
SPIDER_NET_DESCR_SIZE, SPIDER_NET_DESCR_SIZE,
PCI_DMA_BIDIRECTIONAL); direction);
if (buf == DMA_ERROR_CODE) if (buf == DMA_ERROR_CODE)
goto iommu_error; goto iommu_error;
@ -360,10 +330,11 @@ spider_net_init_chain(struct spider_net_card *card,
start_descr->prev = descr-1; start_descr->prev = descr-1;
descr = start_descr; descr = start_descr;
for (i=0; i < no; i++, descr++) { if (direction == PCI_DMA_FROMDEVICE)
descr->next_descr_addr = descr->next->bus_addr; 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->head = start_descr;
chain->tail = start_descr; chain->tail = start_descr;
@ -375,7 +346,7 @@ spider_net_init_chain(struct spider_net_card *card,
if (descr->bus_addr) if (descr->bus_addr)
pci_unmap_single(card->pdev, descr->bus_addr, pci_unmap_single(card->pdev, descr->bus_addr,
SPIDER_NET_DESCR_SIZE, SPIDER_NET_DESCR_SIZE,
PCI_DMA_BIDIRECTIONAL); direction);
return -ENOMEM; return -ENOMEM;
} }
@ -396,7 +367,7 @@ spider_net_free_rx_chain_contents(struct spider_net_card *card)
dev_kfree_skb(descr->skb); dev_kfree_skb(descr->skb);
pci_unmap_single(card->pdev, descr->buf_addr, pci_unmap_single(card->pdev, descr->buf_addr,
SPIDER_NET_MAX_FRAME, SPIDER_NET_MAX_FRAME,
PCI_DMA_BIDIRECTIONAL); PCI_DMA_FROMDEVICE);
} }
descr = descr->next; 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); skb_reserve(descr->skb, SPIDER_NET_RXBUF_ALIGN - offset);
/* io-mmu-map the skb */ /* io-mmu-map the skb */
buf = pci_map_single(card->pdev, descr->skb->data, 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; descr->buf_addr = buf;
if (buf == DMA_ERROR_CODE) { if (buf == DMA_ERROR_CODE) {
dev_kfree_skb_any(descr->skb); dev_kfree_skb_any(descr->skb);
if (netif_msg_rx_err(card) && net_ratelimit()) if (netif_msg_rx_err(card) && net_ratelimit())
pr_err("Could not iommu-map rx buffer\n"); 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 { } 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; 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 * chip by writing to the appropriate register. DMA is enabled in
* spider_net_enable_rxdmac. * spider_net_enable_rxdmac.
*/ */
static void static inline void
spider_net_enable_rxchtails(struct spider_net_card *card) spider_net_enable_rxchtails(struct spider_net_card *card)
{ {
/* assume chain is aligned correctly */ /* 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 * spider_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN
* in the GDADMACCNTR register * in the GDADMACCNTR register
*/ */
static void static inline void
spider_net_enable_rxdmac(struct spider_net_card *card) spider_net_enable_rxdmac(struct spider_net_card *card)
{ {
wmb(); wmb();
@ -500,23 +472,24 @@ spider_net_enable_rxdmac(struct spider_net_card *card)
static void static void
spider_net_refill_rx_chain(struct spider_net_card *card) spider_net_refill_rx_chain(struct spider_net_card *card)
{ {
struct spider_net_descr_chain *chain; struct spider_net_descr_chain *chain = &card->rx_chain;
unsigned long flags;
chain = &card->rx_chain;
/* one context doing the refill (and a second context seeing that /* 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 * 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 * as spider_net_decode_one_descr is called several times. If some
* interrupt calls us, the NAPI is about to clean up anyway. */ * interrupt calls us, the NAPI is about to clean up anyway. */
if (atomic_inc_return(&card->rx_chain_refill) == 1) if (!spin_trylock_irqsave(&chain->lock, flags))
while (spider_net_get_descr_status(chain->head) == return;
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); 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;
}
spin_unlock_irqrestore(&chain->lock, flags);
} }
/** /**
@ -553,111 +526,6 @@ spider_net_alloc_rx_skbs(struct spider_net_card *card)
return result; return result;
} }
/**
* 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 * spider_net_get_multicast_hash - generates hash for multicast filter table
* @addr: multicast address * @addr: multicast address
@ -760,97 +628,6 @@ spider_net_disable_rxdmac(struct spider_net_card *card)
SPIDER_NET_DMA_RX_FEND_VALUE); SPIDER_NET_DMA_RX_FEND_VALUE);
} }
/**
* 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 * spider_net_prepare_tx_descr - fill tx descriptor with skb data
* @card: card structure * @card: card structure
@ -864,13 +641,12 @@ spider_net_set_txdescr_cmdstat(struct spider_net_descr *descr,
*/ */
static int static int
spider_net_prepare_tx_descr(struct spider_net_card *card, spider_net_prepare_tx_descr(struct spider_net_card *card,
struct spider_net_descr *descr,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct spider_net_descr *descr = card->tx_chain.head;
dma_addr_t buf; dma_addr_t buf;
buf = pci_map_single(card->pdev, skb->data, buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
skb->len, PCI_DMA_BIDIRECTIONAL);
if (buf == DMA_ERROR_CODE) { if (buf == DMA_ERROR_CODE) {
if (netif_msg_tx_err(card) && net_ratelimit()) if (netif_msg_tx_err(card) && net_ratelimit())
pr_err("could not iommu-map packet (%p, %i). " 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_addr = buf;
descr->buf_size = skb->len; descr->buf_size = skb->len;
descr->next_descr_addr = 0;
descr->skb = skb; descr->skb = skb;
descr->data_status = 0; 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; 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 * 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 * of the tx descriptor chain and enables the transmission DMA engine
*/ */
static void static inline void
spider_net_kick_tx_dma(struct spider_net_card *card, spider_net_kick_tx_dma(struct spider_net_card *card)
struct spider_net_descr *descr)
{ {
/* this is the only descriptor in the output chain. struct spider_net_descr *descr;
* Enable TX DMA */
spider_net_write_reg(card, SPIDER_NET_GDTDCHA, if (spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR) &
descr->bus_addr); SPIDER_NET_TX_DMA_EN)
goto out;
spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, descr = card->tx_chain.tail;
SPIDER_NET_DMA_TX_VALUE); 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 * @skb: packet to send out
* @netdev: interface device structure * @netdev: interface device structure
* *
* returns 0 on success, <0 on failure * returns 0 on success, !0 on failure
*/ */
static int static int
spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) spider_net_xmit(struct sk_buff *skb, struct net_device *netdev)
{ {
struct spider_net_card *card = netdev_priv(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; int result;
spin_lock_irqsave(&chain->lock, flags);
spider_net_release_tx_chain(card, 0); 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++;
if (!descr) result = NETDEV_TX_LOCKED;
goto error; goto out;
result = spider_net_prepare_tx_descr(card, descr, skb);
if (result)
goto error;
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);
} }
mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER); if (spider_net_get_descr_status(descr) != SPIDER_NET_DESCR_NOT_IN_USE) {
result = NETDEV_TX_LOCKED;
goto out;
}
return NETDEV_TX_OK; if (spider_net_prepare_tx_descr(card, skb) != 0) {
card->netdev_stats.tx_dropped++;
result = NETDEV_TX_BUSY;
goto out;
}
error: result = NETDEV_TX_OK;
card->netdev_stats.tx_dropped++;
return NETDEV_TX_BUSY; spider_net_kick_tx_dma(card);
card->tx_chain.head = card->tx_chain.head->next;
out:
spin_unlock_irqrestore(&chain->lock, flags);
netif_wake_queue(netdev);
return result;
}
/**
* 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;
spin_lock_irqsave(&card->tx_chain.lock, flags);
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 */ /* unmap descriptor */
pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_FRAME, 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 */ /* the cases we'll throw away the packet immediately */
if (data_error & SPIDER_NET_DESTROY_RX_FLAGS) { if (data_error & SPIDER_NET_DESTROY_RX_FLAGS) {
@ -1067,14 +970,11 @@ spider_net_pass_skb_up(struct spider_net_descr *descr,
static int static int
spider_net_decode_one_descr(struct spider_net_card *card, int napi) spider_net_decode_one_descr(struct spider_net_card *card, int napi)
{ {
enum spider_net_descr_status status; struct spider_net_descr_chain *chain = &card->rx_chain;
struct spider_net_descr *descr; struct spider_net_descr *descr = chain->tail;
struct spider_net_descr_chain *chain; int status;
int result; int result;
chain = &card->rx_chain;
descr = chain->tail;
status = spider_net_get_descr_status(descr); status = spider_net_get_descr_status(descr);
if (status == SPIDER_NET_DESCR_CARDOWNED) { 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->name, status);
card->netdev_stats.rx_dropped++; card->netdev_stats.rx_dropped++;
pci_unmap_single(card->pdev, descr->buf_addr, 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); dev_kfree_skb_irq(descr->skb);
goto refill; 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 */ /* ok, we've got a packet in descr */
result = spider_net_pass_skb_up(descr, card, napi); result = spider_net_pass_skb_up(descr, card, napi);
refill: 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: */ /* change the descriptor state: */
if (!napi) if (!napi)
spider_net_refill_rx_chain(card); spider_net_refill_rx_chain(card);
@ -1290,21 +1190,6 @@ spider_net_set_mac(struct net_device *netdev, void *p)
return 0; return 0;
} }
/**
* 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 * spider_net_handle_rxram_full - cleans up RX ring upon RX RAM full interrupt
* @card: card structure * @card: card structure
@ -1653,7 +1538,6 @@ spider_net_enable_card(struct spider_net_card *card)
{ SPIDER_NET_GMRWOLCTRL, 0 }, { SPIDER_NET_GMRWOLCTRL, 0 },
{ SPIDER_NET_GTESTMD, 0x10000000 }, { SPIDER_NET_GTESTMD, 0x10000000 },
{ SPIDER_NET_GTTQMSK, 0x00400040 }, { SPIDER_NET_GTTQMSK, 0x00400040 },
{ SPIDER_NET_GTESTMD, 0 },
{ SPIDER_NET_GMACINTEN, 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); 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_write_reg(card, SPIDER_NET_GMACLENLMT,
SPIDER_NET_LENLMT_VALUE); SPIDER_NET_LENLMT_VALUE);
spider_net_write_reg(card, SPIDER_NET_GMACMODE, 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_INT1_MASK_VALUE);
spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK,
SPIDER_NET_INT2_MASK_VALUE); 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; result = -ENOMEM;
if (spider_net_init_chain(card, &card->tx_chain, if (spider_net_init_chain(card, &card->tx_chain,
card->descr, tx_descriptors)) card->descr,
PCI_DMA_TODEVICE, tx_descriptors))
goto alloc_tx_failed; goto alloc_tx_failed;
if (spider_net_init_chain(card, &card->rx_chain, 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; goto alloc_rx_failed;
/* allocate rx skbs */ /* allocate rx skbs */
@ -1938,7 +1824,7 @@ spider_net_workaround_rxramfull(struct spider_net_card *card)
/* empty sequencer data */ /* empty sequencer data */
for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS; for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS;
sequencer++) { sequencer++) {
spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + spider_net_write_reg(card, SPIDER_NET_GSnPRGADR +
sequencer * 8, 0x0); sequencer * 8, 0x0);
for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) { for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) {
spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT +
@ -1954,6 +1840,49 @@ spider_net_workaround_rxramfull(struct spider_net_card *card)
SPIDER_NET_CKRCTRL_STOP_VALUE); SPIDER_NET_CKRCTRL_STOP_VALUE);
} }
/**
* 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 * spider_net_tx_timeout_task - task scheduled by the watchdog timeout
* function (to be called not under interrupt status) * function (to be called not under interrupt status)
@ -1982,7 +1911,7 @@ spider_net_tx_timeout_task(void *data)
goto out; goto out;
spider_net_open(netdev); spider_net_open(netdev);
spider_net_kick_tx_dma(card, card->tx_chain.head); spider_net_kick_tx_dma(card);
netif_device_attach(netdev); netif_device_attach(netdev);
out: out:
@ -2065,7 +1994,6 @@ spider_net_setup_netdev(struct spider_net_card *card)
pci_set_drvdata(card->pdev, netdev); 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.data = (unsigned long) card;
card->rxram_full_tl.func = card->rxram_full_tl.func =
(void (*)(unsigned long)) spider_net_handle_rxram_full; (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); 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 | /* some time: NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
* NETIF_F_HW_VLAN_FILTER */ * NETIF_F_HW_VLAN_FILTER */

View File

@ -208,7 +208,10 @@ extern char spider_net_driver_name[];
#define SPIDER_NET_DMA_RX_VALUE 0x80000000 #define SPIDER_NET_DMA_RX_VALUE 0x80000000
#define SPIDER_NET_DMA_RX_FEND_VALUE 0x00030003 #define SPIDER_NET_DMA_RX_FEND_VALUE 0x00030003
/* to set TX_DMA_EN */ /* 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 #define SPIDER_NET_DMA_TX_FEND_VALUE 0x00030003
/* SPIDER_NET_UA_DESCR_VALUE is OR'ed with the unicast address */ /* 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_TXINT) & \
(~SPIDER_NET_RXINT) ) (~SPIDER_NET_RXINT) )
#define SPIDER_NET_GPREXEC 0x80000000 #define SPIDER_NET_GPREXEC 0x80000000
#define SPIDER_NET_GPRDAT_MASK 0x0000ffff #define SPIDER_NET_GPRDAT_MASK 0x0000ffff
/* descriptor bits #define SPIDER_NET_DMAC_NOINTR_COMPLETE 0x00800000
* #define SPIDER_NET_DMAC_NOCS 0x00040000
* 1010 descriptor ready #define SPIDER_NET_DMAC_TCP 0x00020000
* 0 descr in middle of chain #define SPIDER_NET_DMAC_UDP 0x00030000
* 000 fixed to 0 #define SPIDER_NET_TXDCEST 0x08000000
*
* 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_DESCR_IND_PROC_MASK 0xF0000000
#define SPIDER_NET_DMAC_RX_CARDOWNED 0xa0800000 #define SPIDER_NET_DESCR_COMPLETE 0x00000000 /* used in rx and tx */
#define SPIDER_NET_DESCR_RESPONSE_ERROR 0x10000000 /* used in rx and tx */
enum spider_net_descr_status { #define SPIDER_NET_DESCR_PROTECTION_ERROR 0x20000000 /* used in rx and tx */
SPIDER_NET_DESCR_COMPLETE = 0x00, /* used in rx and tx */ #define SPIDER_NET_DESCR_FRAME_END 0x40000000 /* used in rx */
SPIDER_NET_DESCR_RESPONSE_ERROR = 0x01, /* used in rx and tx */ #define SPIDER_NET_DESCR_FORCE_END 0x50000000 /* used in rx and tx */
SPIDER_NET_DESCR_PROTECTION_ERROR = 0x02, /* used in rx and tx */ #define SPIDER_NET_DESCR_CARDOWNED 0xA0000000 /* used in rx and tx */
SPIDER_NET_DESCR_FRAME_END = 0x04, /* used in rx */ #define SPIDER_NET_DESCR_NOT_IN_USE 0xF0000000
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 */
};
struct spider_net_descr { struct spider_net_descr {
/* as defined by the hardware */ /* as defined by the hardware */
@ -398,7 +369,7 @@ struct spider_net_descr {
} __attribute__((aligned(32))); } __attribute__((aligned(32)));
struct spider_net_descr_chain { struct spider_net_descr_chain {
/* we walk from tail to head */ spinlock_t lock;
struct spider_net_descr *head; struct spider_net_descr *head;
struct spider_net_descr *tail; 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 tx_chain;
struct spider_net_descr_chain rx_chain; struct spider_net_descr_chain rx_chain;
atomic_t rx_chain_refill;
atomic_t tx_chain_release;
struct net_device_stats netdev_stats; struct net_device_stats netdev_stats;

View File

@ -3255,12 +3255,7 @@ static void __devexit happy_meal_pci_remove(struct pci_dev *pdev)
} }
static struct pci_device_id happymeal_pci_ids[] = { static struct pci_device_id happymeal_pci_ids[] = {
{ { PCI_DEVICE(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_HAPPYMEAL) },
.vendor = PCI_VENDOR_ID_SUN,
.device = PCI_DEVICE_ID_SUN_HAPPYMEAL,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
@ -3275,7 +3270,7 @@ static struct pci_driver hme_pci_driver = {
static int __init happy_meal_pci_init(void) 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) static void happy_meal_pci_exit(void)

View File

@ -1537,7 +1537,7 @@ static int __init sparc_lance_init(void)
{ {
if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) ||
(idprom->id_machtype == (SM_SUN4|SM_4_470))) { (idprom->id_machtype == (SM_SUN4|SM_4_470))) {
memset(&sun4_sdev, 0, sizeof(sdev)); memset(&sun4_sdev, 0, sizeof(struct sbus_dev));
sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr;
sun4_sdev.irqs[0] = 6; sun4_sdev.irqs[0] = 6;
return sparc_lance_probe_one(&sun4_sdev, NULL, NULL); return sparc_lance_probe_one(&sun4_sdev, NULL, NULL);
@ -1547,16 +1547,16 @@ static int __init sparc_lance_init(void)
static int __exit sunlance_sun4_remove(void) static int __exit sunlance_sun4_remove(void)
{ {
struct lance_private *lp = dev_get_drvdata(&sun4_sdev->dev); struct lance_private *lp = dev_get_drvdata(&sun4_sdev.ofdev.dev);
struct net_device *net_dev = lp->dev; struct net_device *net_dev = lp->dev;
unregister_netdevice(net_dev); unregister_netdevice(net_dev);
lance_free_hwresources(root_lance_dev); lance_free_hwresources(lp);
free_netdev(net_dev); free_netdev(net_dev);
dev_set_drvdata(&sun4_sdev->dev, NULL); dev_set_drvdata(&sun4_sdev.ofdev.dev, NULL);
return 0; return 0;
} }

View File

@ -68,8 +68,8 @@
#define DRV_MODULE_NAME "tg3" #define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": " #define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "3.62" #define DRV_MODULE_VERSION "3.63"
#define DRV_MODULE_RELDATE "June 30, 2006" #define DRV_MODULE_RELDATE "July 25, 2006"
#define TG3_DEF_MAC_MODE 0 #define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0 #define TG3_DEF_RX_MODE 0
@ -3590,6 +3590,28 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id,
static int tg3_init_hw(struct tg3 *, int); static int tg3_init_hw(struct tg3 *, int);
static int tg3_halt(struct tg3 *, int, int); static int tg3_halt(struct tg3 *, int, int);
/* Restart hardware after configuration changes, self-test, etc.
* Invoked with tp->lock held.
*/
static int tg3_restart_hw(struct tg3 *tp, int reset_phy)
{
int err;
err = tg3_init_hw(tp, reset_phy);
if (err) {
printk(KERN_ERR PFX "%s: Failed to re-initialize device, "
"aborting.\n", tp->dev->name);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
tg3_full_unlock(tp);
del_timer_sync(&tp->timer);
tp->irq_sync = 0;
netif_poll_enable(tp->dev);
dev_close(tp->dev);
tg3_full_lock(tp, 0);
}
return err;
}
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
static void tg3_poll_controller(struct net_device *dev) static void tg3_poll_controller(struct net_device *dev)
{ {
@ -3630,13 +3652,15 @@ static void tg3_reset_task(void *_data)
} }
tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
tg3_init_hw(tp, 1); if (tg3_init_hw(tp, 1))
goto out;
tg3_netif_start(tp); tg3_netif_start(tp);
if (restart_timer) if (restart_timer)
mod_timer(&tp->timer, jiffies + 1); mod_timer(&tp->timer, jiffies + 1);
out:
tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK; tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK;
tg3_full_unlock(tp); tg3_full_unlock(tp);
@ -4124,6 +4148,7 @@ static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
static int tg3_change_mtu(struct net_device *dev, int new_mtu) static int tg3_change_mtu(struct net_device *dev, int new_mtu)
{ {
struct tg3 *tp = netdev_priv(dev); struct tg3 *tp = netdev_priv(dev);
int err;
if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU(tp)) if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU(tp))
return -EINVAL; return -EINVAL;
@ -4144,13 +4169,14 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
tg3_set_mtu(dev, tp, new_mtu); tg3_set_mtu(dev, tp, new_mtu);
tg3_init_hw(tp, 0); err = tg3_restart_hw(tp, 0);
tg3_netif_start(tp); if (!err)
tg3_netif_start(tp);
tg3_full_unlock(tp); tg3_full_unlock(tp);
return 0; return err;
} }
/* Free up pending packets in all rx/tx rings. /* Free up pending packets in all rx/tx rings.
@ -4232,7 +4258,7 @@ static void tg3_free_rings(struct tg3 *tp)
* end up in the driver. tp->{tx,}lock are held and thus * end up in the driver. tp->{tx,}lock are held and thus
* we may not sleep. * we may not sleep.
*/ */
static void tg3_init_rings(struct tg3 *tp) static int tg3_init_rings(struct tg3 *tp)
{ {
u32 i; u32 i;
@ -4281,18 +4307,38 @@ static void tg3_init_rings(struct tg3 *tp)
/* Now allocate fresh SKBs for each rx ring. */ /* Now allocate fresh SKBs for each rx ring. */
for (i = 0; i < tp->rx_pending; i++) { for (i = 0; i < tp->rx_pending; i++) {
if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD, if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD, -1, i) < 0) {
-1, i) < 0) printk(KERN_WARNING PFX
"%s: Using a smaller RX standard ring, "
"only %d out of %d buffers were allocated "
"successfully.\n",
tp->dev->name, i, tp->rx_pending);
if (i == 0)
return -ENOMEM;
tp->rx_pending = i;
break; break;
}
} }
if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) { if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
for (i = 0; i < tp->rx_jumbo_pending; i++) { for (i = 0; i < tp->rx_jumbo_pending; i++) {
if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_JUMBO, if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_JUMBO,
-1, i) < 0) -1, i) < 0) {
printk(KERN_WARNING PFX
"%s: Using a smaller RX jumbo ring, "
"only %d out of %d buffers were "
"allocated successfully.\n",
tp->dev->name, i, tp->rx_jumbo_pending);
if (i == 0) {
tg3_free_rings(tp);
return -ENOMEM;
}
tp->rx_jumbo_pending = i;
break; break;
}
} }
} }
return 0;
} }
/* /*
@ -5815,6 +5861,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
{ {
struct tg3 *tp = netdev_priv(dev); struct tg3 *tp = netdev_priv(dev);
struct sockaddr *addr = p; struct sockaddr *addr = p;
int err = 0;
if (!is_valid_ether_addr(addr->sa_data)) if (!is_valid_ether_addr(addr->sa_data))
return -EINVAL; return -EINVAL;
@ -5832,9 +5879,9 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
tg3_full_lock(tp, 1); tg3_full_lock(tp, 1);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
tg3_init_hw(tp, 0); err = tg3_restart_hw(tp, 0);
if (!err)
tg3_netif_start(tp); tg3_netif_start(tp);
tg3_full_unlock(tp); tg3_full_unlock(tp);
} else { } else {
spin_lock_bh(&tp->lock); spin_lock_bh(&tp->lock);
@ -5842,7 +5889,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
spin_unlock_bh(&tp->lock); spin_unlock_bh(&tp->lock);
} }
return 0; return err;
} }
/* tp->lock is held. */ /* tp->lock is held. */
@ -5942,7 +5989,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
* can only do this after the hardware has been * can only do this after the hardware has been
* successfully reset. * successfully reset.
*/ */
tg3_init_rings(tp); err = tg3_init_rings(tp);
if (err)
return err;
/* This value is determined during the probe time DMA /* This value is determined during the probe time DMA
* engine test, tg3_test_dma. * engine test, tg3_test_dma.
@ -7956,7 +8005,7 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam *
static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
{ {
struct tg3 *tp = netdev_priv(dev); struct tg3 *tp = netdev_priv(dev);
int irq_sync = 0; int irq_sync = 0, err = 0;
if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) ||
(ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) ||
@ -7980,13 +8029,14 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
if (netif_running(dev)) { if (netif_running(dev)) {
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
tg3_init_hw(tp, 1); err = tg3_restart_hw(tp, 1);
tg3_netif_start(tp); if (!err)
tg3_netif_start(tp);
} }
tg3_full_unlock(tp); tg3_full_unlock(tp);
return 0; return err;
} }
static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
@ -8001,7 +8051,7 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam
static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
{ {
struct tg3 *tp = netdev_priv(dev); struct tg3 *tp = netdev_priv(dev);
int irq_sync = 0; int irq_sync = 0, err = 0;
if (netif_running(dev)) { if (netif_running(dev)) {
tg3_netif_stop(tp); tg3_netif_stop(tp);
@ -8025,13 +8075,14 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
if (netif_running(dev)) { if (netif_running(dev)) {
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
tg3_init_hw(tp, 1); err = tg3_restart_hw(tp, 1);
tg3_netif_start(tp); if (!err)
tg3_netif_start(tp);
} }
tg3_full_unlock(tp); tg3_full_unlock(tp);
return 0; return err;
} }
static u32 tg3_get_rx_csum(struct net_device *dev) static u32 tg3_get_rx_csum(struct net_device *dev)
@ -8666,7 +8717,9 @@ static int tg3_test_loopback(struct tg3 *tp)
if (!netif_running(tp->dev)) if (!netif_running(tp->dev))
return TG3_LOOPBACK_FAILED; return TG3_LOOPBACK_FAILED;
tg3_reset_hw(tp, 1); err = tg3_reset_hw(tp, 1);
if (err)
return TG3_LOOPBACK_FAILED;
if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK)) if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK))
err |= TG3_MAC_LOOPBACK_FAILED; err |= TG3_MAC_LOOPBACK_FAILED;
@ -8740,8 +8793,8 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
if (netif_running(dev)) { if (netif_running(dev)) {
tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
tg3_init_hw(tp, 1); if (!tg3_restart_hw(tp, 1))
tg3_netif_start(tp); tg3_netif_start(tp);
} }
tg3_full_unlock(tp); tg3_full_unlock(tp);
@ -11699,7 +11752,8 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
tg3_full_lock(tp, 0); tg3_full_lock(tp, 0);
tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
tg3_init_hw(tp, 1); if (tg3_restart_hw(tp, 1))
goto out;
tp->timer.expires = jiffies + tp->timer_offset; tp->timer.expires = jiffies + tp->timer_offset;
add_timer(&tp->timer); add_timer(&tp->timer);
@ -11707,6 +11761,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
netif_device_attach(dev); netif_device_attach(dev);
tg3_netif_start(tp); tg3_netif_start(tp);
out:
tg3_full_unlock(tp); tg3_full_unlock(tp);
} }
@ -11733,16 +11788,19 @@ static int tg3_resume(struct pci_dev *pdev)
tg3_full_lock(tp, 0); tg3_full_lock(tp, 0);
tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
tg3_init_hw(tp, 1); err = tg3_restart_hw(tp, 1);
if (err)
goto out;
tp->timer.expires = jiffies + tp->timer_offset; tp->timer.expires = jiffies + tp->timer_offset;
add_timer(&tp->timer); add_timer(&tp->timer);
tg3_netif_start(tp); tg3_netif_start(tp);
out:
tg3_full_unlock(tp); tg3_full_unlock(tp);
return 0; return err;
} }
static struct pci_driver tg3_driver = { static struct pci_driver tg3_driver = {

View File

@ -2742,7 +2742,7 @@ static u32 check_connection_type(struct mac_regs __iomem * regs)
if (PHYSR0 & PHYSR0_SPDG) if (PHYSR0 & PHYSR0_SPDG)
status |= VELOCITY_SPEED_1000; status |= VELOCITY_SPEED_1000;
if (PHYSR0 & PHYSR0_SPD10) else if (PHYSR0 & PHYSR0_SPD10)
status |= VELOCITY_SPEED_10; status |= VELOCITY_SPEED_10;
else else
status |= VELOCITY_SPEED_100; status |= VELOCITY_SPEED_100;
@ -2851,8 +2851,17 @@ static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd
u32 status; u32 status;
status = check_connection_type(vptr->mac_regs); status = check_connection_type(vptr->mac_regs);
cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; cmd->supported = SUPPORTED_TP |
if (status & VELOCITY_SPEED_100) SUPPORTED_Autoneg |
SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Half |
SUPPORTED_1000baseT_Full;
if (status & VELOCITY_SPEED_1000)
cmd->speed = SPEED_1000;
else if (status & VELOCITY_SPEED_100)
cmd->speed = SPEED_100; cmd->speed = SPEED_100;
else else
cmd->speed = SPEED_10; cmd->speed = SPEED_10;
@ -2896,7 +2905,7 @@ static u32 velocity_get_link(struct net_device *dev)
{ {
struct velocity_info *vptr = netdev_priv(dev); struct velocity_info *vptr = netdev_priv(dev);
struct mac_regs __iomem * regs = vptr->mac_regs; struct mac_regs __iomem * regs = vptr->mac_regs;
return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, &regs->PHYSR0) ? 0 : 1; return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, &regs->PHYSR0) ? 1 : 0;
} }
static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)

View File

@ -197,7 +197,6 @@ static int c101_open(struct net_device *dev)
sca_out(IE0_TXINT, MSCI0_OFFSET + IE0, port); sca_out(IE0_TXINT, MSCI0_OFFSET + IE0, port);
set_carrier(port); set_carrier(port);
printk(KERN_DEBUG "0x%X\n", sca_in(MSCI1_OFFSET + ST3, port));
/* enable MSCI1 CDCD interrupt */ /* enable MSCI1 CDCD interrupt */
sca_out(IE1_CDCD, MSCI1_OFFSET + IE1, port); 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_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
MODULE_DESCRIPTION("Moxa C101 serial port driver"); MODULE_DESCRIPTION("Moxa C101 serial port driver");
MODULE_LICENSE("GPL v2"); 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,...");

View File

@ -107,6 +107,7 @@ int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
dev->hard_header = NULL; dev->hard_header = NULL;
dev->type = ARPHRD_PPP; dev->type = ARPHRD_PPP;
dev->addr_len = 0; dev->addr_len = 0;
netif_dormant_off(dev);
return 0; return 0;
} }

Some files were not shown because too many files have changed in this diff Show More