Commit d708c140 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://ppc.bkbits.net/for-linus-ppc64

into home.osdl.org:/home/torvalds/v2.5/linux
parents 567aef7e 91410e1a
In order to use anything but the most primitive functions of ATM,
several user-mode programs are required to assist the kernel. These
programs and related material can be found via the ATM on Linux Web
page at http://icawww1.epfl.ch/linux-atm/
page at http://linux-atm.sourceforge.net/
If you encounter problems with ATM, please report them on the ATM
on Linux mailing list. Subscription information, archives, etc.,
can be found on http://icawww1.epfl.ch/linux-atm/
can be found on http://linux-atm.sourceforge.net/
......@@ -829,24 +829,19 @@ config SOFTWARE_SUSPEND
(patch for sysvinit needed).
It creates an image which is saved in your active swaps. By the next
booting the, pass 'resume=/path/to/your/swap/file' and kernel will
booting the, pass 'resume=/dev/swappartition' and kernel will
detect the saved image, restore the memory from
it and then it continues to run as before you've suspended.
If you don't want the previous state to continue use the 'noresume'
kernel option. However note that your partitions will be fsck'd and
you must re-mkswap your swap partitions/files.
you must re-mkswap your swap partitions. It does not work with swap
files.
Right now you may boot without resuming and then later resume but
in meantime you cannot use those swap partitions/files which were
involved in suspending. Also in this case there is a risk that buffers
on disk won't match with saved ones.
SMP is supported ``as-is''. There's a code for it but doesn't work.
There have been problems reported relating SCSI.
This option is about getting stable. However there is still some
absence of features.
For more information take a look at Documentation/swsusp.txt.
source "drivers/acpi/Kconfig"
......
......@@ -19,12 +19,12 @@ obj-$(CONFIG_X86_CPUID) += cpuid.o
obj-$(CONFIG_MICROCODE) += microcode.o
obj-$(CONFIG_PM) += suspend.o
obj-$(CONFIG_APM) += apm.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend_asm.o
obj-$(CONFIG_X86_SMP) += smp.o smpboot.o
obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
obj-$(CONFIG_X86_MPPARSE) += mpparse.o
obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o
obj-$(CONFIG_X86_IO_APIC) += io_apic.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o suspend_asm.o
obj-$(CONFIG_X86_NUMAQ) += numaq.o
obj-$(CONFIG_X86_SUMMIT) += summit.o
obj-$(CONFIG_EDD) += edd.o
......
......@@ -29,6 +29,12 @@
static struct saved_context saved_context;
static void fix_processor_context(void);
unsigned long saved_context_eax, saved_context_ebx;
unsigned long saved_context_ecx, saved_context_edx;
unsigned long saved_context_esp, saved_context_ebp;
unsigned long saved_context_esi, saved_context_edi;
unsigned long saved_context_eflags;
extern void enable_sep_cpu(void *);
void save_processor_state(void)
......
......@@ -6,32 +6,6 @@
#include <asm/segment.h>
#include <asm/page.h>
.data
.align 4
.globl saved_context_eax, saved_context_ebx
.globl saved_context_ecx, saved_context_edx
.globl saved_context_esp, saved_context_ebp
.globl saved_context_esi, saved_context_edi
.globl saved_context_eflags
saved_context_eax:
.long 0
saved_context_ebx:
.long 0
saved_context_ecx:
.long 0
saved_context_edx:
.long 0
saved_context_esp:
.long 0
saved_context_ebp:
.long 0
saved_context_esi:
.long 0
saved_context_edi:
.long 0
saved_context_eflags:
.long 0
.text
ENTRY(do_magic)
......
......@@ -31,8 +31,6 @@ void enable_sep_cpu(void *info)
wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0);
wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0);
printk("Enabling SEP on CPU %d\n", cpu);
put_cpu();
}
......
......@@ -404,6 +404,179 @@ struct cheetah_err_info {
};
#define CHAFSR_INVALID ((u64)-1L)
/* This table is ordered in priority of errors and matches the
* AFAR overwrite policy as well.
*/
struct afsr_error_table {
unsigned long mask;
const char *name;
};
static const char CHAFSR_PERR_msg[] =
"System interface protocol error";
static const char CHAFSR_IERR_msg[] =
"Internal processor error";
static const char CHAFSR_ISAP_msg[] =
"System request parity error on incoming addresss";
static const char CHAFSR_UCU_msg[] =
"Uncorrectable E-cache ECC error for ifetch/data";
static const char CHAFSR_UCC_msg[] =
"SW Correctable E-cache ECC error for ifetch/data";
static const char CHAFSR_UE_msg[] =
"Uncorrectable system bus data ECC error for read";
static const char CHAFSR_EDU_msg[] =
"Uncorrectable E-cache ECC error for stmerge/blkld";
static const char CHAFSR_EMU_msg[] =
"Uncorrectable system bus MTAG error";
static const char CHAFSR_WDU_msg[] =
"Uncorrectable E-cache ECC error for writeback";
static const char CHAFSR_CPU_msg[] =
"Uncorrectable ECC error for copyout";
static const char CHAFSR_CE_msg[] =
"HW corrected system bus data ECC error for read";
static const char CHAFSR_EDC_msg[] =
"HW corrected E-cache ECC error for stmerge/blkld";
static const char CHAFSR_EMC_msg[] =
"HW corrected system bus MTAG ECC error";
static const char CHAFSR_WDC_msg[] =
"HW corrected E-cache ECC error for writeback";
static const char CHAFSR_CPC_msg[] =
"HW corrected ECC error for copyout";
static const char CHAFSR_TO_msg[] =
"Unmapped error from system bus";
static const char CHAFSR_BERR_msg[] =
"Bus error response from system bus";
static const char CHAFSR_IVC_msg[] =
"HW corrected system bus data ECC error for ivec read";
static const char CHAFSR_IVU_msg[] =
"Uncorrectable system bus data ECC error for ivec read";
static struct afsr_error_table __cheetah_error_table[] = {
{ CHAFSR_PERR, CHAFSR_PERR_msg },
{ CHAFSR_IERR, CHAFSR_IERR_msg },
{ CHAFSR_ISAP, CHAFSR_ISAP_msg },
{ CHAFSR_UCU, CHAFSR_UCU_msg },
{ CHAFSR_UCC, CHAFSR_UCC_msg },
{ CHAFSR_UE, CHAFSR_UE_msg },
{ CHAFSR_EDU, CHAFSR_EDU_msg },
{ CHAFSR_EMU, CHAFSR_EMU_msg },
{ CHAFSR_WDU, CHAFSR_WDU_msg },
{ CHAFSR_CPU, CHAFSR_CPU_msg },
{ CHAFSR_CE, CHAFSR_CE_msg },
{ CHAFSR_EDC, CHAFSR_EDC_msg },
{ CHAFSR_EMC, CHAFSR_EMC_msg },
{ CHAFSR_WDC, CHAFSR_WDC_msg },
{ CHAFSR_CPC, CHAFSR_CPC_msg },
{ CHAFSR_TO, CHAFSR_TO_msg },
{ CHAFSR_BERR, CHAFSR_BERR_msg },
/* These two do not update the AFAR. */
{ CHAFSR_IVC, CHAFSR_IVC_msg },
{ CHAFSR_IVU, CHAFSR_IVU_msg },
{ 0, NULL },
};
static const char CHPAFSR_DTO_msg[] =
"System bus unmapped error for prefetch/storequeue-read";
static const char CHPAFSR_DBERR_msg[] =
"System bus error for prefetch/storequeue-read";
static const char CHPAFSR_THCE_msg[] =
"Hardware corrected E-cache Tag ECC error";
static const char CHPAFSR_TSCE_msg[] =
"SW handled correctable E-cache Tag ECC error";
static const char CHPAFSR_TUE_msg[] =
"Uncorrectable E-cache Tag ECC error";
static const char CHPAFSR_DUE_msg[] =
"System bus uncorrectable data ECC error due to prefetch/store-fill";
static struct afsr_error_table __cheetah_plus_error_table[] = {
{ CHAFSR_PERR, CHAFSR_PERR_msg },
{ CHAFSR_IERR, CHAFSR_IERR_msg },
{ CHAFSR_ISAP, CHAFSR_ISAP_msg },
{ CHAFSR_UCU, CHAFSR_UCU_msg },
{ CHAFSR_UCC, CHAFSR_UCC_msg },
{ CHAFSR_UE, CHAFSR_UE_msg },
{ CHAFSR_EDU, CHAFSR_EDU_msg },
{ CHAFSR_EMU, CHAFSR_EMU_msg },
{ CHAFSR_WDU, CHAFSR_WDU_msg },
{ CHAFSR_CPU, CHAFSR_CPU_msg },
{ CHAFSR_CE, CHAFSR_CE_msg },
{ CHAFSR_EDC, CHAFSR_EDC_msg },
{ CHAFSR_EMC, CHAFSR_EMC_msg },
{ CHAFSR_WDC, CHAFSR_WDC_msg },
{ CHAFSR_CPC, CHAFSR_CPC_msg },
{ CHAFSR_TO, CHAFSR_TO_msg },
{ CHAFSR_BERR, CHAFSR_BERR_msg },
{ CHPAFSR_DTO, CHPAFSR_DTO_msg },
{ CHPAFSR_DBERR, CHPAFSR_DBERR_msg },
{ CHPAFSR_THCE, CHPAFSR_THCE_msg },
{ CHPAFSR_TSCE, CHPAFSR_TSCE_msg },
{ CHPAFSR_TUE, CHPAFSR_TUE_msg },
{ CHPAFSR_DUE, CHPAFSR_DUE_msg },
/* These two do not update the AFAR. */
{ CHAFSR_IVC, CHAFSR_IVC_msg },
{ CHAFSR_IVU, CHAFSR_IVU_msg },
{ 0, NULL },
};
static const char JPAFSR_JETO_msg[] =
"System interface protocol error, hw timeout caused";
static const char JPAFSR_SCE_msg[] =
"Parity error on system snoop results";
static const char JPAFSR_JEIC_msg[] =
"System interface protocol error, illegal command detected";
static const char JPAFSR_JEIT_msg[] =
"System interface protocol error, illegal ADTYPE detected";
static const char JPAFSR_OM_msg[] =
"Out of range memory error has occurred";
static const char JPAFSR_ETP_msg[] =
"Parity error on L2 cache tag SRAM";
static const char JPAFSR_UMS_msg[] =
"Error due to unsupported store";
static const char JPAFSR_RUE_msg[] =
"Uncorrectable ECC error from remote cache/memory";
static const char JPAFSR_RCE_msg[] =
"Correctable ECC error from remote cache/memory";
static const char JPAFSR_BP_msg[] =
"JBUS parity error on returned read data";
static const char JPAFSR_WBP_msg[] =
"JBUS parity error on data for writeback or block store";
static const char JPAFSR_FRC_msg[] =
"Foreign read to DRAM incurring correctable ECC error";
static const char JPAFSR_FRU_msg[] =
"Foreign read to DRAM incurring uncorrectable ECC error";
static struct afsr_error_table __jalapeno_error_table[] = {
{ JPAFSR_JETO, JPAFSR_JETO_msg },
{ JPAFSR_SCE, JPAFSR_SCE_msg },
{ JPAFSR_JEIC, JPAFSR_JEIC_msg },
{ JPAFSR_JEIT, JPAFSR_JEIT_msg },
{ CHAFSR_PERR, CHAFSR_PERR_msg },
{ CHAFSR_IERR, CHAFSR_IERR_msg },
{ CHAFSR_ISAP, CHAFSR_ISAP_msg },
{ CHAFSR_UCU, CHAFSR_UCU_msg },
{ CHAFSR_UCC, CHAFSR_UCC_msg },
{ CHAFSR_UE, CHAFSR_UE_msg },
{ CHAFSR_EDU, CHAFSR_EDU_msg },
{ JPAFSR_OM, JPAFSR_OM_msg },
{ CHAFSR_WDU, CHAFSR_WDU_msg },
{ CHAFSR_CPU, CHAFSR_CPU_msg },
{ CHAFSR_CE, CHAFSR_CE_msg },
{ CHAFSR_EDC, CHAFSR_EDC_msg },
{ JPAFSR_ETP, JPAFSR_ETP_msg },
{ CHAFSR_WDC, CHAFSR_WDC_msg },
{ CHAFSR_CPC, CHAFSR_CPC_msg },
{ CHAFSR_TO, CHAFSR_TO_msg },
{ CHAFSR_BERR, CHAFSR_BERR_msg },
{ JPAFSR_UMS, JPAFSR_UMS_msg },
{ JPAFSR_RUE, JPAFSR_RUE_msg },
{ JPAFSR_RCE, JPAFSR_RCE_msg },
{ JPAFSR_BP, JPAFSR_BP_msg },
{ JPAFSR_WBP, JPAFSR_WBP_msg },
{ JPAFSR_FRC, JPAFSR_FRC_msg },
{ JPAFSR_FRU, JPAFSR_FRU_msg },
/* These two do not update the AFAR. */
{ CHAFSR_IVU, CHAFSR_IVU_msg },
{ 0, NULL },
};
static struct afsr_error_table *cheetah_error_table;
static unsigned long cheetah_afsr_errors;
/* This is allocated at boot time based upon the largest hardware
* cpu ID in the system. We allocate two entries per cpu, one for
* TL==0 logging and one for TL >= 1 logging.
......@@ -439,7 +612,7 @@ extern unsigned int cheetah_deferred_trap_vector[], cheetah_deferred_trap_vector
void __init cheetah_ecache_flush_init(void)
{
unsigned long largest_size, smallest_linesize, order;
unsigned long largest_size, smallest_linesize, order, ver;
char type[16];
int node, i;
......@@ -517,6 +690,18 @@ void __init cheetah_ecache_flush_init(void)
for (i = 0; i < 2 * NR_CPUS; i++)
cheetah_error_log[i].afsr = CHAFSR_INVALID;
__asm__ ("rdpr %%ver, %0" : "=r" (ver));
if ((ver >> 32) == 0x003e0016) {
cheetah_error_table = &__jalapeno_error_table[0];
cheetah_afsr_errors = JPAFSR_ERRORS;
} else if ((ver >> 32) == 0x003e0015) {
cheetah_error_table = &__cheetah_plus_error_table[0];
cheetah_afsr_errors = CHPAFSR_ERRORS;
} else {
cheetah_error_table = &__cheetah_error_table[0];
cheetah_afsr_errors = CHAFSR_ERRORS;
}
/* Now patch trap tables. */
memcpy(tl0_fecc, cheetah_fecc_trap_vector, (8 * 4));
memcpy(tl1_fecc, cheetah_fecc_trap_vector_tl1, (8 * 4));
......@@ -757,36 +942,6 @@ static unsigned char cheetah_mtag_syntab[] = {
NONE, NONE
};
/* This table is ordered in priority of errors and matches the
* AFAR overwrite policy as well.
*/
static struct {
unsigned long mask;
char *name;
} cheetah_error_table[] = {
{ CHAFSR_PERR, "System interface protocol error" },
{ CHAFSR_IERR, "Internal processor error" },
{ CHAFSR_ISAP, "System request parity error on incoming addresss" },
{ CHAFSR_UCU, "Uncorrectable E-cache ECC error for ifetch/data" },
{ CHAFSR_UCC, "SW Correctable E-cache ECC error for ifetch/data" },
{ CHAFSR_UE, "Uncorrectable system bus data ECC error for read" },
{ CHAFSR_EDU, "Uncorrectable E-cache ECC error for stmerge/blkld" },
{ CHAFSR_EMU, "Uncorrectable system bus MTAG error" },
{ CHAFSR_WDU, "Uncorrectable E-cache ECC error for writeback" },
{ CHAFSR_CPU, "Uncorrectable ECC error for copyout" },
{ CHAFSR_CE, "HW corrected system bus data ECC error for read" },
{ CHAFSR_EDC, "HW corrected E-cache ECC error for stmerge/blkld" },
{ CHAFSR_EMC, "HW corrected system bus MTAG ECC error" },
{ CHAFSR_WDC, "HW corrected E-cache ECC error for writeback" },
{ CHAFSR_CPC, "HW corrected ECC error for copyout" },
{ CHAFSR_TO, "Unmapped error from system bus" },
{ CHAFSR_BERR, "Bus error response from system bus" },
/* These two do not update the AFAR. */
{ CHAFSR_IVC, "HW corrected system bus data ECC error for ivec read" },
{ CHAFSR_IVU, "Uncorrectable system bus data ECC error for ivec read" },
{ 0, NULL }
};
/* Return the highest priority error conditon mentioned. */
static __inline__ unsigned long cheetah_get_hipri(unsigned long afsr)
{
......@@ -800,7 +955,7 @@ static __inline__ unsigned long cheetah_get_hipri(unsigned long afsr)
return tmp;
}
static char *cheetah_get_string(unsigned long bit)
static const char *cheetah_get_string(unsigned long bit)
{
int i;
......@@ -913,7 +1068,7 @@ static void cheetah_log_errors(struct pt_regs *regs, struct cheetah_err_info *in
info->ecache_data[2],
info->ecache_data[3]);
afsr = (afsr & ~hipri) & CHAFSR_ERRORS;
afsr = (afsr & ~hipri) & cheetah_afsr_errors;
while (afsr != 0UL) {
unsigned long bit = cheetah_get_hipri(afsr);
......@@ -936,7 +1091,7 @@ static int cheetah_recheck_errors(struct cheetah_err_info *logp)
__asm__ __volatile__("ldxa [%%g0] %1, %0\n\t"
: "=r" (afsr)
: "i" (ASI_AFSR));
if ((afsr & CHAFSR_ERRORS) != 0) {
if ((afsr & cheetah_afsr_errors) != 0) {
if (logp != NULL) {
__asm__ __volatile__("ldxa [%%g0] %1, %0\n\t"
: "=r" (afar)
......@@ -1162,12 +1317,12 @@ void cheetah_cee_handler(struct pt_regs *regs, unsigned long afsr, unsigned long
flush_all = flush_line = 0;
if ((afsr & CHAFSR_EDC) != 0UL) {
if ((afsr & CHAFSR_ERRORS) == CHAFSR_EDC)
if ((afsr & cheetah_afsr_errors) == CHAFSR_EDC)
flush_line = 1;
else
flush_all = 1;
} else if ((afsr & CHAFSR_CPC) != 0UL) {
if ((afsr & CHAFSR_ERRORS) == CHAFSR_CPC)
if ((afsr & cheetah_afsr_errors) == CHAFSR_CPC)
flush_line = 1;
else
flush_all = 1;
......@@ -1290,12 +1445,12 @@ void cheetah_deferred_handler(struct pt_regs *regs, unsigned long afsr, unsigned
flush_all = flush_line = 0;
if ((afsr & CHAFSR_EDU) != 0UL) {
if ((afsr & CHAFSR_ERRORS) == CHAFSR_EDU)
if ((afsr & cheetah_afsr_errors) == CHAFSR_EDU)
flush_line = 1;
else
flush_all = 1;
} else if ((afsr & CHAFSR_BERR) != 0UL) {
if ((afsr & CHAFSR_ERRORS) == CHAFSR_BERR)
if ((afsr & cheetah_afsr_errors) == CHAFSR_BERR)
flush_line = 1;
else
flush_all = 1;
......
......@@ -5,11 +5,12 @@
EXTRA_AFLAGS := -ansi
EXTRA_CFLAGS := -Werror
lib-y := PeeCeeI.o blockops.o debuglocks.o strlen.o strncmp.o \
lib-y := PeeCeeI.o blockops.o strlen.o strncmp.o \
memscan.o strncpy_from_user.o strlen_user.o memcmp.o checksum.o \
VIScopy.o VISbzero.o VISmemset.o VIScsum.o VIScsumcopy.o \
VIScsumcopyusr.o VISsave.o atomic.o rwlock.o bitops.o \
U3memcpy.o U3copy_from_user.o U3copy_to_user.o \
U3copy_in_user.o mcount.o ipcsum.o rwsem.o xor.o
lib-$(CONFIG_DEBUG_SPINLOCK) += debuglocks.o
lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
......@@ -10,7 +10,7 @@
#include <linux/spinlock.h>
#include <asm/system.h>
#if defined(CONFIG_SMP) && defined(CONFIG_DEBUG_SPINLOCK)
#ifdef CONFIG_SMP
#define GET_CALLER(PC) __asm__ __volatile__("mov %%i7, %0" : "=r" (PC))
......@@ -296,4 +296,4 @@ void _do_write_unlock(rwlock_t *rw)
}
}
#endif /* CONFIG_SMP && CONFIG_DEBUG_SPINLOCK */
#endif /* CONFIG_SMP */
......@@ -58,8 +58,8 @@ config ACPI_BOOT
default y
config ACPI_SLEEP
bool "Sleep States"
depends on X86 && ACPI && !ACPI_HT_ONLY && SOFTWARE_SUSPEND
bool "Sleep States (EXPERIMENTAL)"
depends on X86 && ACPI && !ACPI_HT_ONLY && EXPERIMENTAL
---help---
This option adds support for ACPI suspend states.
......
......@@ -197,7 +197,7 @@ acpi_system_suspend(
break;
}
local_irq_restore(flags);
printk(KERN_CRIT "Back to C!\n");
printk(KERN_DEBUG "Back to C!\n");
return status;
}
......@@ -226,13 +226,15 @@ acpi_suspend (
if (state == ACPI_STATE_S4 && !acpi_gbl_FACS->S4bios_f)
return AE_ERROR;
pm_prepare_console();
/*
* TBD: S1 can be done without device_suspend. Make a CONFIG_XX
* to handle however when S1 failed without device_suspend.
*/
if (freeze_processes()) {
thaw_processes();
return AE_ERROR; /* device_suspend needs processes to be stopped */
status = AE_ERROR;
goto Done;
}
/* do we have a wakeup address for S2 and S3? */
......@@ -269,8 +271,10 @@ acpi_suspend (
/* reset firmware waking vector */
acpi_set_firmware_waking_vector((acpi_physical_address) 0);
thaw_processes();
Done:
thaw_processes();
pm_restore_console();
return status;
}
......
......@@ -71,12 +71,6 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#ifndef PCI_VENDOR_ID_EF_ATM_LANAI2
/* These need to eventually go into <linux/pci.h> - they're here for now */
#define PCI_VENDOR_ID_EF_ATM_LANAI2 0x0003
#define PCI_VENDOR_ID_EF_ATM_LANAIHB 0x0005
#endif
/* -------------------- TUNABLE PARAMATERS: */
/*
......@@ -205,12 +199,6 @@
typedef int vci_t;
typedef unsigned long bus_addr_t;
/* A bitfield large enough for NUM_VCI */
#define VCI_BITFIELD_NELEM ((NUM_VCI + BITS_PER_LONG - 1) / BITS_PER_LONG)
typedef struct {
unsigned long ul[VCI_BITFIELD_NELEM];
} vci_bitfield;
/* DMA buffer in host memory for TX, RX, or service list. */
struct lanai_buffer {
u32 *start; /* From get_free_pages */
......@@ -302,8 +290,8 @@ struct lanai_dev {
u8 eeprom[LANAI_EEPROM_SIZE];
u32 serialno, magicno;
struct pci_dev *pci;
vci_bitfield backlog_vccs; /* VCCs that are backlogged */
vci_bitfield transmit_ready; /* VCCs that have transmit space */
DECLARE_BITMAP(backlog_vccs, NUM_VCI); /* VCCs with tx backlog */
DECLARE_BITMAP(transmit_ready, NUM_VCI); /* VCCs with transmit space */
struct timer_list timer;
int naal0;
struct lanai_buffer aal0buf; /* AAL0 RX buffers */
......@@ -320,54 +308,20 @@ struct lanai_dev {
/* TODO - organize above in some rational fashion (see <asm/cache.h>) */
};
/* -------------------- VCI_BITFIELD UTILITIES: */
/*
* These functions assume that BITS_PER_LONG is a power of two, which
* should be safe
*/
#if (BITS_PER_LONG & (BITS_PER_LONG - 1))
#error lanai driver requires type long to have a power of two number of bits
#endif
/*
* In vci_bitfield_{set,clear} we do the operation in three
* parts to ensure that gcc doesn't cast anything down to
* 32 bits (and then sign extend them later) on 64-bit
* platforms like the alpha
* Each device has two bitmaps for each VCC (baclog_vccs and transmit_ready)
* This function iterates one of these, calling a given function for each
* vci with their bit set
*/
static inline void vci_bitfield_set(vci_bitfield *bf, vci_t vci)
{
unsigned long bit = 1;
bit <<= (unsigned long) (vci & (BITS_PER_LONG - 1));
bf->ul[vci / BITS_PER_LONG] |= bit;
}
static inline void vci_bitfield_clear(vci_bitfield *bf, vci_t vci)
{
unsigned long bit = 1;
bit <<= (unsigned long) (vci & (BITS_PER_LONG - 1));
bf->ul[vci / BITS_PER_LONG] &= ~bit;
}
static inline void vci_bitfield_init(vci_bitfield *bf)
{
memset(bf, 0, sizeof(*bf));
}
static void vci_bitfield_iterate(struct lanai_dev *lanai,
const vci_bitfield *bf, void (*func)(struct lanai_dev *,vci_t vci))
/*const*/ unsigned long *lp,
void (*func)(struct lanai_dev *,vci_t vci))
{
vci_t vci;
unsigned long mask;
const unsigned long *lp = &(bf->ul[0]);
for (vci = 0; vci < NUM_VCI; lp++)
if (*lp == 0)
vci += BITS_PER_LONG;
else
for (mask = 1; mask != 0; mask <<= 1, vci++)
if (*lp & mask)
func(lanai, vci);
vci_t vci = find_first_bit(lp, NUM_VCI);
while (vci < NUM_VCI) {
func(lanai, vci);
vci = find_next_bit(lp, NUM_VCI, vci + 1);
}
}
/* -------------------- BUFFER UTILITIES: */
......@@ -446,33 +400,6 @@ static int lanai_buf_size_cardorder(const struct lanai_buffer *buf)
return order;
}
/* -------------------- HANDLE BACKLOG_VCCS BITFIELD: */
static inline void vcc_mark_backlogged(struct lanai_dev *lanai,
const struct lanai_vcc *lvcc)
{
APRINTK(lvcc->vbase != 0, "vcc_mark_backlogged: zero vbase!\n");
vci_bitfield_set(&lanai->backlog_vccs, lvcc->vci);
}
static inline void vcc_unmark_backlogged(struct lanai_dev *lanai,
const struct lanai_vcc *lvcc)
{
APRINTK(lvcc->vbase != 0, "vcc_unmark_backlogged: zero vbase!\n");
vci_bitfield_clear(&lanai->backlog_vccs, lvcc->vci);
}
static inline void vcc_backlog_init(struct lanai_dev *lanai)
{
vci_bitfield_init(&lanai->backlog_vccs);
}
static inline int vcc_is_backlogged(/*const*/ struct lanai_vcc *lvcc)
{
return lvcc->tx.inprogress != NULL ||
!skb_queue_empty(&lvcc->tx.backlog);
}
/* -------------------- PORT I/O UTILITIES: */
/* Registers (and their bit-fields) */
......@@ -558,7 +485,6 @@ static inline bus_addr_t reg_addr(const struct lanai_dev *lanai,
return lanai->base + (bus_addr_t) reg;
}
static inline u32 reg_read(const struct lanai_dev *lanai,
enum lanai_register reg)
{
......@@ -921,7 +847,7 @@ static void lanai_shutdown_tx_vci(struct lanai_dev *lanai,
}
while ((skb = skb_dequeue(&lvcc->tx.backlog)) != NULL)
lanai_free_skb(lvcc->tx.atmvcc, skb);
vcc_unmark_backlogged(lanai, lvcc);
__clear_bit(lvcc->vci, lanai->backlog_vccs);
spin_unlock_irqrestore(&lanai->txlock, flags);
timeout = jiffies + ((lanai_buf_size(&lvcc->tx.buf) * HZ) >> 17);
write = TXWRITEPTR_GET_PTR(cardvcc_read(lvcc, vcc_txwriteptr));
......@@ -1283,6 +1209,13 @@ static inline int vcc_tx_space(const struct lanai_vcc *lvcc, int endptr)
return r;
}
/* test if VCC is currently backlogged */
static inline int vcc_is_backlogged(/*const*/ struct lanai_vcc *lvcc)
{
return lvcc->tx.inprogress != NULL ||
!skb_queue_empty(&lvcc->tx.backlog);
}
/* Bit fields in the segmentation buffer descriptor */
#define DESCRIPTOR_MAGIC (0xD0000000)
#define DESCRIPTOR_AAL5 (0x00008000)
......@@ -1467,7 +1400,7 @@ static void vcc_tx_unqueue_aal5(struct lanai_dev *lanai,
atomic_inc(&lvcc->tx.atmvcc->stats->tx);
}
if (skb_queue_empty(&lvcc->tx.backlog))
vcc_unmark_backlogged(lanai, lvcc);
__clear_bit(lvcc->vci, lanai->backlog_vccs);
end:
lanai_endtx(lanai, lvcc);
}
......@@ -1481,8 +1414,8 @@ static void vcc_tx_aal5(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
goto queue_it;
space = vcc_tx_space(lvcc, TXREADPTR_GET_PTR(cardvcc_read(lvcc,
vcc_txreadptr)));
if (space < 64) {
vcc_mark_backlogged(lanai, lvcc); /* No space */
if (space < 64) { /* No space at all */
__set_bit(lvcc->vci, lanai->backlog_vccs);
goto queue_it;
}
if (space >= 16 + (n = aal5_size(skb->len))) {
......@@ -1506,7 +1439,7 @@ static void vcc_tx_aal5(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
lvcc->tx.inprogress = skb;
lvcc->tx.inprogleft = n - bytes;
lvcc->tx.pptr = skb->data + bytes;
vcc_mark_backlogged(lanai, lvcc);
__set_bit(lvcc->vci, lanai->backlog_vccs);
}
lanai_endtx(lanai, lvcc);
return;
......@@ -1535,7 +1468,7 @@ static void iter_dequeue(struct lanai_dev *lanai, vci_t vci)
struct lanai_vcc *lvcc = lanai->vccs[vci];
int endptr;
if (lvcc == NULL || !vcc_is_backlogged(lvcc)) {
vci_bitfield_clear(&lanai->backlog_vccs, vci);
__clear_bit(vci, lanai->backlog_vccs);
return;
}
endptr = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr));
......@@ -1547,7 +1480,7 @@ static inline void vcc_tx_dequeue_all(struct lanai_dev *lanai)
{
unsigned long flags;
spin_lock_irqsave(&lanai->txlock, flags);
vci_bitfield_iterate(lanai, &lanai->backlog_vccs, iter_dequeue);
vci_bitfield_iterate(lanai, lanai->backlog_vccs, iter_dequeue);
spin_unlock_irqrestore(&lanai->txlock, flags);
}
......@@ -1831,7 +1764,7 @@ static int handle_service(struct lanai_dev *lanai, u32 s)
lanai->stats.service_notx++;
return 0;
}
vci_bitfield_set(&lanai->transmit_ready, vci);
__set_bit(vci, lanai->transmit_ready);
lvcc->tx.endptr = SERVICE_GET_END(s);
vcclist_read_unlock();
return 1;
......@@ -1916,9 +1849,9 @@ static void run_service(struct lanai_dev *lanai)
if (ntx != 0) {
spin_lock(&lanai->txlock);
vcclist_read_lock();
vci_bitfield_iterate(lanai, &lanai->transmit_ready,
vci_bitfield_iterate(lanai, lanai->transmit_ready,
iter_transmit);
vci_bitfield_init(&lanai->transmit_ready);
CLEAR_BITMAP(&lanai->transmit_ready, NUM_VCI);
vcclist_read_unlock();
spin_unlock(&lanai->txlock);
}
......@@ -2300,8 +2233,8 @@ static int __init lanai_dev_open(struct atm_dev *atmdev)
/* Basic device fields */
lanai->number = atmdev->number;
lanai->num_vci = NUM_VCI;
vci_bitfield_init(&lanai->backlog_vccs);
vci_bitfield_init(&lanai->transmit_ready);
CLEAR_BITMAP(&lanai->backlog_vccs, NUM_VCI);
CLEAR_BITMAP(&lanai->transmit_ready, NUM_VCI);
lanai->naal0 = 0;
#ifdef USE_POWERDOWN
lanai->nbound = 0;
......@@ -2380,7 +2313,7 @@ static int __init lanai_dev_open(struct atm_dev *atmdev)
reg_write(lanai, TX_FIFO_DEPTH, TxDepth_Reg);
reg_write(lanai, 0, CBR_ICG_Reg); /* CBR defaults to no limit */
if ((result = request_irq(lanai->pci->irq, lanai_int, SA_SHIRQ,
"lanai", lanai)) != 0) {
DEV_LABEL, lanai)) != 0) {
printk(KERN_ERR DEV_LABEL ": can't allocate interrupt\n");
goto error_vcctable;
}
......@@ -2573,6 +2506,7 @@ static int lanai_open(struct atm_vcc *atmvcc, short vpi, int vci)
/* NOTE: these are all DEBUGGING ONLY currently */
static int lanai_ioctl(struct atm_dev *atmdev, unsigned int cmd, void *arg)
{
#if 0
int result = 0;
struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;
switch(cmd) {
......@@ -2649,9 +2583,13 @@ static int lanai_ioctl(struct atm_dev *atmdev, unsigned int cmd, void *arg)
return 0;
#endif
default:
result = -EINVAL;
result = -ENOIOCTLCMD;
}
return result;
#else /* !0 */
(void) atmdev; (void) cmd; (void) arg; /* no compiler warnings */
return -ENOIOCTLCMD;
#endif /* 0 */
}
static int lanai_send(struct atm_vcc *atmvcc, struct sk_buff *skb)
......@@ -2862,7 +2800,7 @@ static int __devinit lanai_init_one(struct pci_dev *pci,
return result;
}
static struct pci_device_id lanai_pci_tbl[] __devinitdata = {
static struct pci_device_id lanai_pci_tbl[] = {
{
PCI_VENDOR_ID_EF, PCI_VENDOR_ID_EF_ATM_LANAI2,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0
......
......@@ -52,8 +52,6 @@ int device_suspend(u32 state, u32 level)
struct device * dev;
int error = 0;
printk(KERN_EMERG "Suspending devices\n");
down_write(&devices_subsys.rwsem);
list_for_each_entry_reverse(dev,&devices_subsys.kset.list,kobj.entry) {
if (dev->driver && dev->driver->suspend) {
......@@ -114,8 +112,6 @@ void device_resume(u32 level)
}
}
up_write(&devices_subsys.rwsem);
printk(KERN_EMERG "Devices Resumed\n");
}
/**
......@@ -125,8 +121,6 @@ void device_shutdown(void)
{
struct device * dev;
printk(KERN_EMERG "Shutting down devices\n");
down_write(&devices_subsys.rwsem);
list_for_each_entry_reverse(dev,&devices_subsys.kset.list,kobj.entry) {
pr_debug("shutting down %s: ",dev->name);
......
......@@ -1420,15 +1420,15 @@ static int i596_close(struct net_device *dev)
DEB(DEB_INIT,printk(KERN_DEBUG "%s: Shutting down ethercard, status was %4.4x.\n",
dev->name, lp->scb.status));
save_flags(flags);
cli();
spin_lock_irqsave(&lp->lock, flags);
wait_cmd(dev,lp,100,"close1 timed out");
lp->scb.command = CUC_ABORT | RX_ABORT;
CA(dev);
wait_cmd(dev,lp,100,"close2 timed out");
restore_flags(flags);
spin_unlock_irqrestore(&lp->lock, flags);
DEB(DEB_STRUCT,i596_display_data(dev));
i596_cleanup_cmd(dev,lp);
......
......@@ -975,15 +975,7 @@ int __init lp486e_probe(struct net_device *dev) {
return -EBUSY;
}
/*
* Allocate working memory, 16-byte aligned
*/
dev->mem_start = (unsigned long) kmalloc(sizeof(struct i596_private) + 0x0f, GFP_KERNEL);
if (!dev->mem_start)
goto err_out;
dev->priv = (void *)((dev->mem_start + 0xf) & 0xfffffff0);
lp = (struct i596_private *) dev->priv;
memset((void *)lp, 0, sizeof(struct i596_private));
spin_lock_init(&lp->cmd_lock);
/*
......@@ -997,7 +989,6 @@ int __init lp486e_probe(struct net_device *dev) {
dev->base_addr = IOADDR;
dev->irq = IRQ;
ether_setup(dev);
/*
* How do we find the ethernet address? I don't know.
......@@ -1045,8 +1036,6 @@ int __init lp486e_probe(struct net_device *dev) {
return 0;
err_out_kfree:
kfree ((void *) dev->mem_start);
err_out:
release_region(IOADDR, LP486E_TOTAL_SIZE);
return ret;
}
......@@ -1318,29 +1307,36 @@ MODULE_PARM(debug, "i");
MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
static struct net_device dev_lp486e;
static struct net_device *dev_lp486e;
static int full_duplex;
static int options;
static int io = IOADDR;
static int irq = IRQ;
static int __init lp486e_init_module(void) {
struct net_device *dev = &dev_lp486e;
struct net_device *dev;
dev = alloc_etherdev(sizeof(struct i596_private));
if (!dev)
return -ENOMEM;
dev->irq = irq;
dev->base_addr = io;
dev->init = lp486e_probe;
if (register_netdev(dev) != 0)
if (register_netdev(dev) != 0) {
kfree(dev);
return -EIO;
}
dev_lp486e = dev;
full_duplex = 0;
options = 0;
return 0;
}
static void __exit lp486e_cleanup_module(void) {
unregister_netdev(&dev_lp486e);
kfree((void *)dev_lp486e.mem_start);
dev_lp486e.priv = NULL;
release_region(dev_lp486e.base_addr, LP486E_TOTAL_SIZE);
unregister_netdev(dev_lp486e);
release_region(dev_lp486e->base_addr, LP486E_TOTAL_SIZE);
kfree(dev_lp486e);
}
module_init(lp486e_init_module);
......
......@@ -57,8 +57,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "1.8"
#define DRV_MODULE_RELDATE "August 1, 2003"
#define DRV_MODULE_VERSION "1.9"
#define DRV_MODULE_RELDATE "August 3, 2003"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
......@@ -2199,7 +2199,6 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_RETVAL(handled);
}
static void tg3_init_rings(struct tg3 *);
static int tg3_init_hw(struct tg3 *);
static int tg3_halt(struct tg3 *);
......@@ -2217,7 +2216,6 @@ static void tg3_reset_task(void *_data)
tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER;
tg3_halt(tp);
tg3_init_rings(tp);
tg3_init_hw(tp);
spin_unlock(&tp->tx_lock);
......@@ -2719,7 +2717,6 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
tg3_set_mtu(dev, tp, new_mtu);
tg3_init_rings(tp);
tg3_init_hw(tp);
spin_unlock(&tp->tx_lock);
......@@ -2805,8 +2802,8 @@ static void tg3_free_rings(struct tg3 *tp)
*
* The chip has been shut down and the driver detached from
* the networking, so no interrupts or new tx packets will
* end up in the driver. tp->{tx,}lock is not held and we are not
* in an interrupt context and thus may sleep.
* end up in the driver. tp->{tx,}lock are held and thus
* we may not sleep.
*/
static void tg3_init_rings(struct tg3 *tp)
{
......@@ -3985,6 +3982,13 @@ static int tg3_reset_hw(struct tg3 *tp)
tw32(TG3PCI_PCISTATE, val);
}
/* Descriptor ring init may make accesses to the
* NIC SRAM area to setup the TX descriptors, so we
* can only do this after the hardware has been
* successfully reset.
*/
tg3_init_rings(tp);
/* Clear statistics/status block in chip, and status block in ram. */
for (i = NIC_SRAM_STATS_BLK;
i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE;
......@@ -4546,8 +4550,6 @@ static int tg3_open(struct net_device *dev)
spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
tg3_init_rings(tp);
err = tg3_init_hw(tp);
if (err) {
tg3_halt(tp);
......@@ -5359,7 +5361,6 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
tp->tx_pending = ering.tx_pending;
tg3_halt(tp);
tg3_init_rings(tp);
tg3_init_hw(tp);
netif_wake_queue(tp->dev);
spin_unlock(&tp->tx_lock);
......@@ -5403,7 +5404,6 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
else
tp->tg3_flags &= ~TG3_FLAG_PAUSE_TX;
tg3_halt(tp);
tg3_init_rings(tp);
tg3_init_hw(tp);
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock);
......@@ -7017,7 +7017,6 @@ static int tg3_suspend(struct pci_dev *pdev, u32 state)
spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
tg3_init_rings(tp);
tg3_init_hw(tp);
spin_unlock(&tp->tx_lock);
......@@ -7048,7 +7047,6 @@ static int tg3_resume(struct pci_dev *pdev)
spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
tg3_init_rings(tp);
tg3_init_hw(tp);
tg3_enable_ints(tp);
......
......@@ -36,10 +36,12 @@
#define ASI_PCACHE_DATA 0x31 /* (III) PCache data RAM diag */
#define ASI_PCACHE_TAG 0x32 /* (III) PCache tag RAM diag */
#define ASI_PCACHE_SNOOP_TAG 0x33 /* (III) PCache snoop tag RAM diag */
#define ASI_QUAD_LDD_PHYS 0x34 /* (III+) PADDR, qword load */
#define ASI_WCACHE_VALID_BITS 0x38 /* (III) WCache Valid Bits diag */
#define ASI_WCACHE_DATA 0x39 /* (III) WCache data RAM diag */
#define ASI_WCACHE_TAG 0x3a /* (III) WCache tag RAM diag */
#define ASI_WCACHE_SNOOP_TAG 0x3b /* (III) WCache snoop tag RAM diag */
#define ASI_QUAD_LDD_PHYS_L 0x3c /* (III+) PADDR, qword load, little endian */
#define ASI_SRAM_FAST_INIT 0x40 /* (III+) Fast SRAM init */
#define ASI_DCACHE_INVALIDATE 0x42 /* (III) DCache Invalidate diag */
#define ASI_DCACHE_UTAG 0x43 /* (III) DCache uTag diag */
......
......@@ -4,10 +4,54 @@
/* Cheetah Asynchronous Fault Status register, ASI=0x4C VA<63:0>=0x0 */
/* Comments indicate which processor variants on which the bit definition
* is valid. Codes are:
* ch --> cheetah
* ch+ --> cheetah plus
* jp --> jalapeno
*/
/* All bits of this register except M_SYNDROME and E_SYNDROME are
* read, write 1 to clear. M_SYNDROME and E_SYNDROME are read-only.
*/
/* Software bit set by linux trap handlers to indicate that the trap was
* signalled at %tl >= 1.
*/
#define CHAFSR_TL1 (1UL << 63UL) /* n/a */
/* Unmapped error from system bus for prefetch queue or
* store queue read operation
*/
#define CHPAFSR_DTO (1UL << 59UL) /* ch+ */
/* Bus error from system bus for prefetch queue or store queue
* read operation
*/
#define CHPAFSR_DBERR (1UL << 58UL) /* ch+ */
/* Hardware corrected E-cache Tag ECC error */
#define CHPAFSR_THCE (1UL << 57UL) /* ch+ */
/* System interface protocol error, hw timeout caused */
#define JPAFSR_JETO (1UL << 57UL) /* jp */
/* SW handled correctable E-cache Tag ECC error */
#define CHPAFSR_TSCE (1UL << 56UL) /* ch+ */
/* Parity error on system snoop results */
#define JPAFSR_SCE (1UL << 56UL) /* jp */
/* Uncorrectable E-cache Tag ECC error */
#define CHPAFSR_TUE (1UL << 55UL) /* ch+ */
/* System interface protocol error, illegal command detected */
#define JPAFSR_JEIC (1UL << 55UL) /* jp */
/* Uncorrectable system bus data ECC error due to prefetch
* or store fill request
*/
#define CHPAFSR_DUE (1UL << 54UL) /* ch+ */
/* System interface protocol error, illegal ADTYPE detected */
#define JPAFSR_JEIT (1UL << 54UL) /* jp */
/* Multiple errors of the same type have occurred. This bit is set when
* an uncorrectable error or a SW correctable error occurs and the status
* bit to report that error is already set. When multiple errors of
......@@ -22,12 +66,12 @@
* subunit will be logged. All errors in subsequent 16-byte subunits
* from the same 64-byte transaction are ignored.
*/
#define CHAFSR_ME 0x0020000000000000
#define CHAFSR_ME (1UL << 53UL) /* ch,ch+,jp */
/* Privileged state error has occurred. This is a capture of PSTATE.PRIV
* at the time the error is detected.
*/
#define CHAFSR_PRIV 0x0010000000000000
#define CHAFSR_PRIV (1UL << 52UL) /* ch,ch+,jp */
/* The following bits 51 (CHAFSR_PERR) to 33 (CHAFSR_CE) are sticky error
* bits and record the most recently detected errors. Bits accumulate
......@@ -38,74 +82,123 @@
* pin when this event occurs and it also logs a specific cause code
* into a JTAG scannable flop.
*/
#define CHAFSR_PERR 0x0008000000000000
#define CHAFSR_PERR (1UL << 51UL) /* ch,ch+,jp */
/* Internal processor error. The processor asserts its' ERROR
* pin when this event occurs and it also logs a specific cause code
* into a JTAG scannable flop.
*/
#define CHAFSR_IERR 0x0004000000000000
#define CHAFSR_IERR (1UL << 50UL) /* ch,ch+,jp */
/* System request parity error on incoming address */
#define CHAFSR_ISAP 0x0002000000000000
#define CHAFSR_ISAP (1UL << 49UL) /* ch,ch+,jp */
/* HW Corrected system bus MTAG ECC error */
#define CHAFSR_EMC 0x0001000000000000
#define CHAFSR_EMC (1UL << 48UL) /* ch,ch+ */
/* Parity error on L2 cache tag SRAM */
#define JPAFSR_ETP (1UL << 48UL) /* jp */
/* Uncorrectable system bus MTAG ECC error */
#define CHAFSR_EMU 0x0000800000000000
#define CHAFSR_EMU (1UL << 47UL) /* ch,ch+ */
/* Out of range memory error has occurred */
#define JPAFSR_OM (1UL << 47UL) /* jp */
/* HW Corrected system bus data ECC error for read of interrupt vector */
#define CHAFSR_IVC 0x0000400000000000
#define CHAFSR_IVC (1UL << 46UL) /* ch,ch+ */
/* Error due to unsupported store */
#define JPAFSR_UMS (1UL << 46UL) /* jp */
/* Uncorrectable system bus data ECC error for read of interrupt vector */
#define CHAFSR_IVU 0x0000200000000000
#define CHAFSR_IVU (1UL << 45UL) /* ch,ch+,jp */
/* Unmapped error from system bus */
#define CHAFSR_TO 0x0000100000000000
#define CHAFSR_TO (1UL << 44UL) /* ch,ch+,jp */
/* Bus error response from system bus */
#define CHAFSR_BERR 0x0000080000000000
#define CHAFSR_BERR (1UL << 43UL) /* ch,ch+,jp */
/* SW Correctable E-cache ECC error for instruction fetch or data access
* other than block load.
*/
#define CHAFSR_UCC 0x0000040000000000
#define CHAFSR_UCC (1UL << 42UL) /* ch,ch+,jp */
/* Uncorrectable E-cache ECC error for instruction fetch or data access
* other than block load.
*/
#define CHAFSR_UCU 0x0000020000000000
#define CHAFSR_UCU (1UL << 41UL) /* ch,ch+,jp */
/* Copyout HW Corrected ECC error */
#define CHAFSR_CPC 0x0000010000000000
#define CHAFSR_CPC (1UL << 40UL) /* ch,ch+,jp */
/* Copyout Uncorrectable ECC error */
#define CHAFSR_CPU 0x0000008000000000
#define CHAFSR_CPU (1UL << 39UL) /* ch,ch+,jp */
/* HW Corrected ECC error from E-cache for writeback */
#define CHAFSR_WDC 0x0000004000000000
#define CHAFSR_WDC (1UL << 38UL) /* ch,ch+,jp */
/* Uncorrectable ECC error from E-cache for writeback */
#define CHAFSR_WDU 0x0000002000000000
#define CHAFSR_WDU (1UL << 37UL) /* ch,ch+,jp */
/* HW Corrected ECC error from E-cache for store merge or block load */
#define CHAFSR_EDC 0x0000001000000000
#define CHAFSR_EDC (1UL << 36UL) /* ch,ch+,jp */
/* Uncorrectable ECC error from E-cache for store merge or block load */
#define CHAFSR_EDU 0x0000000800000000
#define CHAFSR_EDU (1UL << 35UL) /* ch,ch+,jp */
/* Uncorrectable system bus data ECC error for read of memory or I/O */
#define CHAFSR_UE 0x0000000400000000
#define CHAFSR_UE (1UL << 34UL) /* ch,ch+,jp */
/* HW Corrected system bus data ECC error for read of memory or I/O */
#define CHAFSR_CE 0x0000000200000000
#define CHAFSR_CE (1UL << 33UL) /* ch,ch+,jp */
/* Uncorrectable ECC error from remote cache/memory */
#define JPAFSR_RUE (1UL << 32UL) /* jp */
/* Correctable ECC error from remote cache/memory */
#define JPAFSR_RCE (1UL << 31UL) /* jp */
/* JBUS parity error on returned read data */
#define JPAFSR_BP (1UL << 30UL) /* jp */
/* JBUS parity error on data for writeback or block store */
#define JPAFSR_WBP (1UL << 29UL) /* jp */
/* Foreign read to DRAM incurring correctable ECC error */
#define JPAFSR_FRC (1UL << 28UL) /* jp */
/* Foreign read to DRAM incurring uncorrectable ECC error */
#define JPAFSR_FRU (1UL << 27UL) /* jp */
#define CHAFSR_ERRORS (CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP | CHAFSR_EMC | \
CHAFSR_EMU | CHAFSR_IVC | CHAFSR_IVU | CHAFSR_TO | \
CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | CHAFSR_CPC | \
CHAFSR_CPU | CHAFSR_WDC | CHAFSR_WDU | CHAFSR_EDC | \
CHAFSR_EDU | CHAFSR_UE | CHAFSR_CE)
#define CHPAFSR_ERRORS (CHPAFSR_DTO | CHPAFSR_DBERR | CHPAFSR_THCE | \
CHPAFSR_TSCE | CHPAFSR_TUE | CHPAFSR_DUE | \
CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP | CHAFSR_EMC | \
CHAFSR_EMU | CHAFSR_IVC | CHAFSR_IVU | CHAFSR_TO | \
CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | CHAFSR_CPC | \
CHAFSR_CPU | CHAFSR_WDC | CHAFSR_WDU | CHAFSR_EDC | \
CHAFSR_EDU | CHAFSR_UE | CHAFSR_CE)
#define JPAFSR_ERRORS (JPAFSR_JETO | JPAFSR_SCE | JPAFSR_JEIC | \
JPAFSR_JEIT | CHAFSR_PERR | CHAFSR_IERR | \
CHAFSR_ISAP | JPAFSR_ETP | JPAFSR_OM | \
JPAFSR_UMS | CHAFSR_IVU | CHAFSR_TO | \
CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | \
CHAFSR_CPC | CHAFSR_CPU | CHAFSR_WDC | \
CHAFSR_WDU | CHAFSR_EDC | CHAFSR_EDU | \
CHAFSR_UE | CHAFSR_CE | JPAFSR_RUE | \
JPAFSR_RCE | JPAFSR_BP | JPAFSR_WBP | \
JPAFSR_FRC | JPAFSR_FRU)
/* Active JBUS request signal when error occurred */
#define JPAFSR_JBREQ (0x7UL << 24UL) /* jp */
#define JPAFSR_JBREQ_SHIFT 24UL
/* L2 cache way information */
#define JPAFSR_ETW (0x3UL << 22UL) /* jp */
#define JPAFSR_ETW_SHIFT 22UL
/* System bus MTAG ECC syndrome. This field captures the status of the
* first occurrence of the highest-priority error according to the M_SYND
......@@ -113,8 +206,12 @@
* for which the M_SYND is reported, is cleared, the contents of the M_SYND
* field will be unchanged by will be unfrozen for further error capture.
*/
#define CHAFSR_M_SYNDROME 0x00000000000f0000
#define CHAFSR_M_SYNDROME_SHIFT 16
#define CHAFSR_M_SYNDROME (0xfUL << 16UL) /* ch,ch+,jp */
#define CHAFSR_M_SYNDROME_SHIFT 16UL
/* Agenid Id of the foreign device causing the UE/CE errors */
#define JPAFSR_AID (0x1fUL << 9UL) /* jp */
#define JPAFSR_AID_SHIFT 9UL
/* System bus or E-cache data ECC syndrome. This field captures the status
* of the first occurrence of the highest-priority error according to the
......@@ -122,8 +219,8 @@
* error for which the E_SYND is reported, is cleare, the contents of the E_SYND
* field will be unchanged but will be unfrozen for further error capture.
*/
#define CHAFSR_E_SYNDROME 0x00000000000001ff
#define CHAFSR_E_SYNDROME_SHIFT 0
#define CHAFSR_E_SYNDROME (0x1ffUL << 0UL) /* ch,ch+,jp */
#define CHAFSR_E_SYNDROME_SHIFT 0UL
/* The AFSR must be explicitly cleared by software, it is not cleared automatically
* by a read. Writes to bits <51:33> with bits set will clear the corresponding
......@@ -142,9 +239,4 @@
* also apply to the M_SYNDROME and E_SYNDROME fields of the AFSR.
*/
/* Software bit set by linux trap handlers to indicate that the trap was
* signalled at %tl >= 1.
*/
#define CHAFSR_TL1 0x8000000000000000
#endif /* _SPARC64_CHAFSR_H */
......@@ -55,10 +55,6 @@ extern void software_resume(void);
extern int register_suspend_notifier(struct notifier_block *);
extern int unregister_suspend_notifier(struct notifier_block *);
extern void refrigerator(unsigned long);
extern int freeze_processes(void);
extern void thaw_processes(void);
extern unsigned int nr_copy_pages __nosavedata;
extern suspend_pagedir_t *pagedir_nosave __nosavedata;
......@@ -75,16 +71,37 @@ extern void do_magic_suspend_2(void);
extern void do_suspend_lowlevel(int resume);
extern void do_suspend_lowlevel_s4bios(int resume);
#else
#else /* CONFIG_SOFTWARE_SUSPEND */
static inline void software_suspend(void)
{
}
#define software_resume() do { } while(0)
#define register_suspend_notifier(a) do { } while(0)
#define unregister_suspend_notifier(a) do { } while(0)
#define refrigerator(a) do { BUG(); } while(0)
#define freeze_processes() do { panic("You need CONFIG_SOFTWARE_SUSPEND to do sleeps."); } while(0)
#define thaw_processes() do { } while(0)
#endif
#endif /* CONFIG_SOFTWARE_SUSPEND */
#ifdef CONFIG_PM
extern void refrigerator(unsigned long);
extern int freeze_processes(void);
extern void thaw_processes(void);
extern int pm_prepare_console(void);
extern void pm_restore_console(void);
#else
static inline void refrigerator(unsigned long)
{
}
static inline int freeze_processes(void)
{
return 0;
}
static inline void thaw_processes(void)
{
}
#endif /* CONFIG_PM */
#endif /* _LINUX_SWSUSP_H */
......@@ -14,10 +14,9 @@ obj-$(CONFIG_SMP) += cpu.o
obj-$(CONFIG_UID16) += uid16.o
obj-$(CONFIG_MODULES) += ksyms.o module.o
obj-$(CONFIG_KALLSYMS) += kallsyms.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_PM) += pm.o power/
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o
obj-$(CONFIG_COMPAT) += compat.o
obj-$(CONFIG_IKCONFIG) += configs.o
......
obj-y := process.o console.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
#include <linux/vt_kern.h>
#include <linux/kbd_kern.h>
#include "power.h"
static int new_loglevel = 7;
static int orig_loglevel;
static int orig_fgconsole, orig_kmsg;
int pm_prepare_console(void)
{
orig_loglevel = console_loglevel;
console_loglevel = new_loglevel;
#ifdef SUSPEND_CONSOLE
orig_fgconsole = fg_console;
if(vc_allocate(SUSPEND_CONSOLE))
/* we can't have a free VC for now. Too bad,
* we don't want to mess the screen for now. */
return 1;
set_console (SUSPEND_CONSOLE);
if(vt_waitactive(SUSPEND_CONSOLE)) {
pr_debug("Suspend: Can't switch VCs.");
return 1;
}
orig_kmsg = kmsg_redirect;
kmsg_redirect = SUSPEND_CONSOLE;
#endif
return 0;
}
void pm_restore_console(void)
{
console_loglevel = orig_loglevel;
#ifdef SUSPEND_CONSOLE
set_console (orig_fgconsole);
#endif
return;
}
/* With SUSPEND_CONSOLE defined, it suspend looks *really* cool, but
we probably do not take enough locks for switching consoles, etc,
so bad things might happen.
*/
#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
#define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1)
#endif
/*
* drivers/power/process.c - Functions for starting/stopping processes on
* suspend transitions.
*
* Originally from swsusp.
*/
#undef DEBUG
#include <linux/interrupt.h>
#include <linux/suspend.h>
#include <linux/module.h>
#ifdef DEBUG_SLOW
#define MDELAY(a) mdelay(a)
#else
#define MDELAY(a)
#endif
/*
* Timeout for stopping processes
*/
#define TIMEOUT (6 * HZ)
static inline int freezeable(struct task_struct * p)
{
if ((p == current) ||
(p->flags & PF_IOTHREAD) ||
(p->state == TASK_ZOMBIE) ||
(p->state == TASK_DEAD))
return 0;
return 1;
}
/* Refrigerator is place where frozen processes are stored :-). */
void refrigerator(unsigned long flag)
{
/* You need correct to work with real-time processes.
OTOH, this way one process may see (via /proc/) some other
process in stopped state (and thereby discovered we were
suspended. We probably do not care.
*/
long save;
save = current->state;
current->state = TASK_STOPPED;
pr_debug("%s entered refrigerator\n", current->comm);
printk("=");
current->flags &= ~PF_FREEZE;
if (flag)
flush_signals(current); /* We have signaled a kernel thread, which isn't normal behaviour
and that may lead to 100%CPU sucking because those threads
just don't manage signals. */
current->flags |= PF_FROZEN;
while (current->flags & PF_FROZEN)
schedule();
pr_debug("%s left refrigerator\n", current->comm);
current->state = save;
}
/* 0 = success, else # of processes that we failed to stop */
int freeze_processes(void)
{
int todo;
unsigned long start_time;
struct task_struct *g, *p;
printk( "Stopping tasks: " );
start_time = jiffies;
do {
todo = 0;
read_lock(&tasklist_lock);
do_each_thread(g, p) {
unsigned long flags;
if (!freezeable(p))
continue;
if ((p->flags & PF_FROZEN) ||
(p->state == TASK_STOPPED))
continue;
/* FIXME: smp problem here: we may not access other process' flags
without locking */
p->flags |= PF_FREEZE;
spin_lock_irqsave(&p->sighand->siglock, flags);
signal_wake_up(p, 0);
spin_unlock_irqrestore(&p->sighand->siglock, flags);
todo++;
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
yield(); /* Yield is okay here */
if (time_after(jiffies, start_time + TIMEOUT)) {
printk( "\n" );
printk(KERN_ERR " stopping tasks failed (%d tasks remaining)\n", todo );
return todo;
}
} while(todo);
printk( "|\n" );
BUG_ON(in_atomic());
return 0;
}
void thaw_processes(void)
{
struct task_struct *g, *p;
printk( "Restarting tasks..." );
read_lock(&tasklist_lock);
do_each_thread(g, p) {
if (!freezeable(p))
continue;
if (p->flags & PF_FROZEN) {
p->flags &= ~PF_FROZEN;
wake_up_process(p);
} else
printk(KERN_INFO " Strange, %s not stopped\n", p->comm );
wake_up_process(p);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
schedule();
printk( " done\n" );
MDELAY(500);
}
EXPORT_SYMBOL(refrigerator);
......@@ -43,9 +43,8 @@
#include <linux/version.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/vt_kern.h>
#include <linux/bitops.h>
#include <linux/interrupt.h>
#include <linux/vt_kern.h>
#include <linux/kbd_kern.h>
#include <linux/keyboard.h>
#include <linux/spinlock.h>
......@@ -64,20 +63,12 @@
#include <asm/pgtable.h>
#include <asm/io.h>
#include "power.h"
extern long sys_sync(void);
unsigned char software_suspend_enabled = 0;
#define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1)
/* With SUSPEND_CONSOLE defined, it suspend looks *really* cool, but
we probably do not take enough locks for switching consoles, etc,
so bad things might happen.
*/
#if !defined(CONFIG_VT) || !defined(CONFIG_VT_CONSOLE)
#undef SUSPEND_CONSOLE
#endif
#define TIMEOUT (6 * HZ) /* Timeout for stopping processes */
#define __ADDRESS(x) ((unsigned long) phys_to_virt(x))
#define ADDRESS(x) __ADDRESS((x) << PAGE_SHIFT)
#define ADDRESS2(x) __ADDRESS(__pa(x)) /* Needed for x86-64 where some pages are in memory twice */
......@@ -91,9 +82,6 @@ extern int is_head_of_free_region(struct page *);
spinlock_t suspend_pagedir_lock __nosavedata = SPIN_LOCK_UNLOCKED;
/* Variables to be preserved over suspend */
static int new_loglevel = 7;
static int orig_loglevel;
static int orig_fgconsole, orig_kmsg;
static int pagedir_order_check;
static int nr_copy_pages_check;
......@@ -158,104 +146,6 @@ static const char name_resume[] = "Resume Machine: ";
#define MDELAY(a)
#endif
/*
* Refrigerator and related stuff
*/
#define INTERESTING(p) \
/* We don't want to touch kernel_threads..*/ \
if (p->flags & PF_IOTHREAD) \
continue; \
if (p == current) \
continue; \
if (p->state == TASK_ZOMBIE) \
continue;
/* Refrigerator is place where frozen processes are stored :-). */
void refrigerator(unsigned long flag)
{
/* You need correct to work with real-time processes.
OTOH, this way one process may see (via /proc/) some other
process in stopped state (and thereby discovered we were
suspended. We probably do not care.
*/
long save;
save = current->state;
current->state = TASK_STOPPED;
PRINTK("%s entered refrigerator\n", current->comm);
printk("=");
current->flags &= ~PF_FREEZE;
if (flag)
flush_signals(current); /* We have signaled a kernel thread, which isn't normal behaviour
and that may lead to 100%CPU sucking because those threads
just don't manage signals. */
current->flags |= PF_FROZEN;
while (current->flags & PF_FROZEN)
schedule();
PRINTK("%s left refrigerator\n", current->comm);
current->state = save;
}
/* 0 = success, else # of processes that we failed to stop */
int freeze_processes(void)
{
int todo;
unsigned long start_time;
struct task_struct *g, *p;
printk( "Stopping tasks: " );
start_time = jiffies;
do {
todo = 0;
read_lock(&tasklist_lock);
do_each_thread(g, p) {
unsigned long flags;
INTERESTING(p);
if (p->flags & PF_FROZEN)
continue;
/* FIXME: smp problem here: we may not access other process' flags
without locking */
p->flags |= PF_FREEZE;
spin_lock_irqsave(&p->sighand->siglock, flags);
signal_wake_up(p, 0);
spin_unlock_irqrestore(&p->sighand->siglock, flags);
todo++;
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
yield(); /* Yield is okay here */
if (time_after(jiffies, start_time + TIMEOUT)) {
printk( "\n" );
printk(KERN_ERR " stopping tasks failed (%d tasks remaining)\n", todo );
return todo;
}
} while(todo);
printk( "|\n" );
BUG_ON(in_atomic());
return 0;
}
void thaw_processes(void)
{
struct task_struct *g, *p;
printk( "Restarting tasks..." );
read_lock(&tasklist_lock);
do_each_thread(g, p) {
INTERESTING(p);
if (p->flags & PF_FROZEN) p->flags &= ~PF_FROZEN;
else
printk(KERN_INFO " Strange, %s not stopped\n", p->comm );
wake_up_process(p);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
printk( " done\n" );
MDELAY(500);
}
/*
* Saving part...
*/
......@@ -281,17 +171,6 @@ static __inline__ int fill_suspend_header(struct suspend_header *sh)
return 0;
}
/*
* This is our sync function. With this solution we probably won't sleep
* but that should not be a problem since tasks are stopped..
*/
static inline void do_suspend_sync(void)
{
blk_run_queues();
#warning This might be broken. We need to somehow wait for data to reach the disk
}
/* We memorize in swapfile_used what swap devices are used for suspension */
#define SWAPFILE_UNUSED 0
#define SWAPFILE_SUSPEND 1 /* This is the suspending device */
......@@ -559,7 +438,6 @@ static suspend_pagedir_t *create_suspend_pagedir(int nr_copy_pages)
free_suspend_pagedir((unsigned long) pagedir);
return NULL;
}
printk(".");
SetPageNosave(virt_to_page(p->address));
p->orig_address = 0;
p++;
......@@ -567,40 +445,6 @@ static suspend_pagedir_t *create_suspend_pagedir(int nr_copy_pages)
return pagedir;
}
static int prepare_suspend_console(void)
{
orig_loglevel = console_loglevel;
console_loglevel = new_loglevel;
#ifdef CONFIG_VT
orig_fgconsole = fg_console;
#ifdef SUSPEND_CONSOLE
if(vc_allocate(SUSPEND_CONSOLE))
/* we can't have a free VC for now. Too bad,
* we don't want to mess the screen for now. */
return 1;
set_console (SUSPEND_CONSOLE);
if(vt_waitactive(SUSPEND_CONSOLE)) {
PRINTK("Bummer. Can't switch VCs.");
return 1;
}
orig_kmsg = kmsg_redirect;
kmsg_redirect = SUSPEND_CONSOLE;
#endif
#endif
return 0;
}
static void restore_console(void)
{
console_loglevel = orig_loglevel;
#ifdef SUSPEND_CONSOLE
set_console (orig_fgconsole);
#endif
return;
}
static int prepare_suspend_processes(void)
{
sys_sync(); /* Syncing needs pdflushd, so do it before stopping processes */
......@@ -850,13 +694,12 @@ void do_magic_suspend_2(void)
free_pages((unsigned long) pagedir_nosave, pagedir_order);
spin_unlock_irq(&suspend_pagedir_lock);
mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME);
PRINTK(KERN_WARNING "%sLeaving do_magic_suspend_2...\n", name_suspend);
}
static void do_software_suspend(void)
{
arch_prepare_suspend();
if (prepare_suspend_console())
if (pm_prepare_console())
printk( "%sCan't allocate a console... proceeding\n", name_suspend);
if (!prepare_suspend_processes()) {
......@@ -866,13 +709,10 @@ static void do_software_suspend(void)
free_some_memory();
/* No need to invalidate any vfsmnt list -- they will be valid after resume, anyway.
*
* We sync here -- so you have consistent filesystem state when things go wrong.
* -- so that noone writes to disk after we do atomic copy of data.
/* No need to invalidate any vfsmnt list --
* they will be valid after resume, anyway.
*/
PRINTK("Syncing disks before copy\n");
do_suspend_sync();
blk_run_queues();
/* Save state of all device drivers, and stop them. */
if(drivers_suspend()==0)
......@@ -886,12 +726,11 @@ static void do_software_suspend(void)
* using normal kernel mechanism.
*/
do_magic(0);
PRINTK("Restarting processes...\n");
thaw_processes();
}
software_suspend_enabled = 1;
MDELAY(1000);
restore_console ();
pm_restore_console();
}
/*
......@@ -904,7 +743,7 @@ void software_suspend(void)
return;
software_suspend_enabled = 0;
BUG_ON(in_interrupt());
might_sleep();
do_software_suspend();
}
......@@ -1114,8 +953,6 @@ static int __read_suspend_image(struct block_device *bdev, union diskpage *cur,
bdev_write_page(bdev, 0, cur);
}
if (prepare_suspend_console())
printk("%sCan't allocate a console... proceeding\n", name_resume);
printk( "%sSignature found, resuming\n", name_resume );
MDELAY(1000);
......@@ -1236,8 +1073,8 @@ void software_resume(void)
}
MDELAY(1000);
orig_loglevel = console_loglevel;
console_loglevel = new_loglevel;
if (pm_prepare_console())
printk("swsusp: Can't allocate a console... proceeding\n");
if (!resume_file[0] && resume_status == RESUME_SPECIFIED) {
printk( "suspension device unspecified\n" );
......@@ -1251,7 +1088,7 @@ void software_resume(void)
panic("This never returns");
read_failure:
console_loglevel = orig_loglevel;
pm_restore_console();
return;
}
......@@ -1277,4 +1114,3 @@ __setup("resume=", resume_setup);
EXPORT_SYMBOL(software_suspend);
EXPORT_SYMBOL(software_suspend_enabled);
EXPORT_SYMBOL(refrigerator);
......@@ -175,7 +175,6 @@ source "net/decnet/Kconfig"
config BRIDGE
tristate "802.1d Ethernet Bridging"
depends on INET
---help---
If you say Y here, then your Linux box will be able to act as an
Ethernet bridge, which means that the different Ethernet segments it
......
......@@ -8,6 +8,9 @@ bridge-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o \
br_ioctl.o br_notify.o br_stp.o br_stp_bpdu.o \
br_stp_if.o br_stp_timer.o
# br_netfilter only deals with IPv4 and ARP filtering, both are INET protocols
ifeq ($(CONFIG_INET),y)
bridge-$(CONFIG_NETFILTER) += br_netfilter.o
endif
obj-$(CONFIG_BRIDGE_NF_EBTABLES) += netfilter/
......@@ -34,7 +34,7 @@ static int __init br_init(void)
{
printk(KERN_INFO "NET4: Ethernet Bridge 008 for NET4.0\n");
#ifdef CONFIG_NETFILTER
#if defined(CONFIG_INET) && defined(CONFIG_NETFILTER)
if (br_netfilter_init())
return 1;
#endif
......@@ -52,7 +52,7 @@ static int __init br_init(void)
static void __exit br_deinit(void)
{
#ifdef CONFIG_NETFILTER
#if defined(CONFIG_INET) && defined(CONFIG_NETFILTER)
br_netfilter_fini();
#endif
unregister_netdevice_notifier(&br_device_notifier);
......
......@@ -22,7 +22,6 @@
#include <net/ip.h>
#include <net/xfrm.h>
#include <net/icmp.h>
#include <net/esp.h>
#include <net/ipcomp.h>
static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment