Commit fcd27415 authored by Richard Russon's avatar Richard Russon

Merge flatcap.org:/home/flatcap/backup/bk/ntfs-2.6

into flatcap.org:/home/flatcap/backup/bk/ntfs-2.6-devel
parents 63d3803f 8756f2ef
Generic networking statistics for netlink users
======================================================================
Statistic counters are grouped into structs:
Struct TLV type Description
----------------------------------------------------------------------
gnet_stats_basic TCA_STATS_BASIC Basic statistics
gnet_stats_rate_est TCA_STATS_RATE_EST Rate estimator
gnet_stats_queue TCA_STATS_QUEUE Queue statistics
none TCA_STATS_APP Application specific
Collecting:
-----------
Declare the statistic structs you need:
struct mystruct {
struct gnet_stats_basic bstats;
struct gnet_stats_queue qstats;
...
};
Update statistics:
mystruct->tstats.packet++;
mystruct->qstats.backlog += skb->pkt_len;
Export to userspace (Dump):
---------------------------
my_dumping_routine(struct sk_buff *skb, ...)
{
struct gnet_dump dump;
if (gnet_stats_start_copy(skb, TCA_STATS2, &mystruct->lock, &dump) < 0)
goto rtattr_failure;
if (gnet_stats_copy_basic(&dump, &mystruct->bstats) < 0 ||
gnet_stats_copy_queue(&dump, &mystruct->qstats) < 0 ||
gnet_stats_copy_app(&dump, &xstats, sizeof(xstats)) < 0)
goto rtattr_failure;
if (gnet_stats_finish_copy(&dump) < 0)
goto rtattr_failure;
...
}
TCA_STATS/TCA_XSTATS backward compatibility:
--------------------------------------------
Prior users of struct tc_stats and xstats can maintain backward
compatibility by calling the compat wrappers to keep providing the
existing TLV types.
my_dumping_routine(struct sk_buff *skb, ...)
{
if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS,
TCA_XSTATS, &mystruct->lock, &dump) < 0)
goto rtattr_failure;
...
}
A struct tc_stats will be filled out during gnet_stats_copy_* calls
and appended to the skb. TCA_XSTATS is provided if gnet_stats_copy_app
was called.
Locking:
--------
Locks are taken before writing and released once all statistics have
been written. Locks are always released in case of an error. You
are responsible for making sure that the lock is initialized.
Rate Estimator:
--------------
0) Prepare an estimator attribute. Most likely this would be in user
space. The value of this TLV should contain a tc_estimator structure.
As usual, such a TLV nees to be 32 bit aligned and therefore the
length needs to be appropriately set etc. The estimator interval
and ewma log need to be converted to the appropriate values.
tc_estimator.c::tc_setup_estimator() is advisable to be used as the
conversion routine. It does a few clever things. It takes a time
interval in microsecs, a time constant also in microsecs and a struct
tc_estimator to be populated. The returned tc_estimator can be
transported to the kernel. Transfer such a structure in a TLV of type
TCA_RATE to your code in the kernel.
In the kernel when setting up:
1) make sure you have basic stats and rate stats setup first.
2) make sure you have initialized stats lock that is used to setup such
stats.
3) Now initialize a new estimator:
int ret = gen_new_estimator(my_basicstats,my_rate_est_stats,
mystats_lock, attr_with_tcestimator_struct);
if ret == 0
success
else
failed
From now on, everytime you dump my_rate_est_stats it will contain
uptodate info.
Once you are done, call gen_kill_estimator(my_basicstats,
my_rate_est_stats) Make sure that my_basicstats and my_rate_est_stats
are still valid (i.e still exist) at the time of making this call.
Authors:
--------
Thomas Graf <tgraf@suug.ch>
Jamal Hadi Salim <hadi@cyberus.ca>
......@@ -632,9 +632,9 @@ M: g.liakhovetski@gmx.de
S: Maintained
DECnet NETWORK LAYER
P: Steven Whitehouse
M: SteveW@ACM.org
W: http://www.sucs.swan.ac.uk/~rohan/DECnet/index.html
P: Patrick Caulfield
M: patrick@tykepenguin.com
W: http://linux-decnet.sourceforge.net
L: linux-decnet-user@lists.sourceforge.net
S: Maintained
......
......@@ -326,7 +326,7 @@ DEPMOD = /sbin/depmod
KALLSYMS = scripts/kallsyms
PERL = perl
CHECK = sparse
CHECKFLAGS :=
CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__
MODFLAGS = -DMODULE
CFLAGS_MODULE = $(MODFLAGS)
AFLAGS_MODULE = $(MODFLAGS)
......
......@@ -11,7 +11,7 @@
NM := $(NM) -B
LDFLAGS_vmlinux := -static -N #-relax
CHECKFLAGS += -D__alpha__=1
CHECKFLAGS += -D__alpha__
cflags-y := -pipe -mno-fp-regs -ffixed-8
# Determine if we can use the BWX instructions with GAS.
......
......@@ -57,7 +57,7 @@ tune-$(CONFIG_CPU_V6) :=-mtune=strongarm
CFLAGS +=-mapcs-32 $(arch-y) $(tune-y) $(call cc-option,-malignment-traps,-mshort-load-bytes) -msoft-float -Uarm
AFLAGS +=-mapcs-32 $(arch-y) $(tune-y) -msoft-float
CHECKFLAGS += -D__arm__=1
CHECKFLAGS += -D__arm__
#Default value
DATAADDR := .
......
......@@ -304,6 +304,39 @@ int do_settimeofday(struct timespec *tv)
EXPORT_SYMBOL(do_settimeofday);
/**
* save_time_delta - Save the offset between system time and RTC time
* @delta: pointer to timespec to store delta
* @rtc: pointer to timespec for current RTC time
*
* Return a delta between the system time and the RTC time, such
* that system time can be restored later with restore_time_delta()
*/
void save_time_delta(struct timespec *delta, struct timespec *rtc)
{
set_normalized_timespec(delta,
xtime.tv_sec - rtc->tv_sec,
xtime.tv_nsec - rtc->tv_nsec);
}
EXPORT_SYMBOL(save_time_delta);
/**
* restore_time_delta - Restore the current system time
* @delta: delta returned by save_time_delta()
* @rtc: pointer to timespec for current RTC time
*/
void restore_time_delta(struct timespec *delta, struct timespec *rtc)
{
struct timespec ts;
set_normalized_timespec(&ts,
delta->tv_sec + rtc->tv_sec,
delta->tv_nsec + rtc->tv_nsec);
do_settimeofday(&ts);
}
EXPORT_SYMBOL(restore_time_delta);
void timer_tick(struct pt_regs *regs)
{
profile_tick(CPU_PROFILING, regs);
......
......@@ -21,6 +21,7 @@
#include <asm/system.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/lubbock.h>
#include <asm/mach/time.h>
/*
......@@ -69,14 +70,16 @@ static int pxa_pm_enter(u32 state)
{
unsigned long sleep_save[SLEEP_SAVE_SIZE];
unsigned long checksum = 0;
unsigned long delta;
struct timespec delta, rtc;
int i;
if (state != PM_SUSPEND_MEM)
return -EINVAL;
/* preserve current time */
delta = xtime.tv_sec - RCNR;
rtc.tv_sec = RCNR;
rtc.tv_nsec = 0;
save_time_delta(&delta, &rtc);
/* save vital registers */
SAVE(OSMR0);
......@@ -161,7 +164,8 @@ static int pxa_pm_enter(u32 state)
RESTORE(ICMR);
/* restore current time */
xtime.tv_sec = RCNR + delta;
rtc.tv_sec = RCNR;
restore_time_delta(&delta, &rtc);
#ifdef DEBUG
printk(KERN_DEBUG "*** made it back from resume\n");
......
......@@ -30,6 +30,7 @@
#include <asm/hardware.h>
#include <asm/memory.h>
#include <asm/system.h>
#include <asm/mach/time.h>
extern void sa1100_cpu_suspend(void);
extern void sa1100_cpu_resume(void);
......@@ -58,14 +59,16 @@ enum { SLEEP_SAVE_SP = 0,
static int sa11x0_pm_enter(u32 state)
{
unsigned long sleep_save[SLEEP_SAVE_SIZE];
unsigned long delta, gpio;
unsigned long gpio, sleep_save[SLEEP_SAVE_SIZE];
struct timespec delta, rtc;
if (state != PM_SUSPEND_MEM)
return -EINVAL;
/* preserve current time */
delta = xtime.tv_sec - RCNR;
rtc.tv_sec = RCNR;
rtc.tv_nsec = 0;
save_time_delta(&delta, &rtc);
gpio = GPLR;
/* save vital registers */
......@@ -136,7 +139,8 @@ static int sa11x0_pm_enter(u32 state)
OSCR = OSMR0 - LATCH;
/* restore current time */
xtime.tv_sec = RCNR + delta;
rtc.tv_sec = RCNR;
restore_time_delta(&delta, &rtc);
return 0;
}
......
......@@ -14,6 +14,7 @@
#include <linux/swap.h>
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/mman.h>
#include <linux/initrd.h>
#include <asm/mach-types.h>
......
......@@ -18,7 +18,7 @@
LDFLAGS := -m elf_i386
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
LDFLAGS_vmlinux :=
CHECKFLAGS += -D__i386__=1
CHECKFLAGS += -D__i386__
CFLAGS += -pipe -msoft-float
......
......@@ -45,7 +45,7 @@ unsigned int __VMALLOC_RESERVE = 128 << 20;
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
unsigned long highstart_pfn, highend_pfn;
static int do_test_wp_bit(void);
static int noinline do_test_wp_bit(void);
/*
* Creates a middle page table and puts a pointer to it in the
......@@ -673,7 +673,7 @@ void __init pgtable_cache_init(void)
* This function cannot be __init, since exceptions don't work in that
* section. Put this after the callers, so that it cannot be inlined.
*/
static int do_test_wp_bit(void)
static int noinline do_test_wp_bit(void)
{
char tmp_reg;
int flag;
......
......@@ -25,7 +25,7 @@ aflags-$(CONFIG_ISA_M32R) += -DNO_FPU -Wa,-no-bitinst
CFLAGS += $(cflags-y)
AFLAGS += $(aflags-y)
CHECKFLAGS := $(CHECK) -D__m32r__=1
CHECKFLAGS := $(CHECK) -D__m32r__
head-y := arch/m32r/kernel/head.o arch/m32r/kernel/init_task.o
......
......@@ -28,7 +28,7 @@ ifdef CONFIG_SUN3
LDFLAGS_vmlinux = -N
endif
CHECKFLAGS += -D__mc68000__=1 -I$(shell $(CC) -print-file-name=include)
CHECKFLAGS += -D__mc68000__ -I$(shell $(CC) -print-file-name=include)
# without -fno-strength-reduce the 53c7xx.c driver fails ;-(
CFLAGS += -pipe -fno-strength-reduce -ffixed-a2
......
......@@ -27,7 +27,7 @@ CFLAGS += -Iarch/$(ARCH) -msoft-float -pipe \
-ffixed-r2 -mmultiple
CPP = $(CC) -E $(CFLAGS)
CHECKFLAGS += -D__powerpc__=1
CHECKFLAGS += -D__powerpc__
ifndef CONFIG_E500
CFLAGS += -mstring
......
......@@ -28,7 +28,7 @@ ifeq ($(new_nm),y)
NM := $(NM) --synthetic
endif
CHECKFLAGS += -m64 -D__powerpc__=1
CHECKFLAGS += -m64 -D__powerpc__
LDFLAGS := -m elf64ppc
LDFLAGS_vmlinux := -Bstatic -e $(KERNELLOAD) -Ttext $(KERNELLOAD)
......
......@@ -13,7 +13,7 @@
AS := $(AS) -32
LDFLAGS := -m elf32_sparc
CHECKFLAGS += -D__sparc__=1
CHECKFLAGS += -D__sparc__
#CFLAGS := $(CFLAGS) -g -pipe -fcall-used-g5 -fcall-used-g7
CFLAGS := $(CFLAGS) -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
......
......@@ -8,7 +8,7 @@
# Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
#
CHECKFLAGS += -D__sparc__=1 -D__sparc_v9__=1
CHECKFLAGS += -D__sparc__ -D__sparc_v9__
CPPFLAGS_vmlinux.lds += -Usparc
......
......@@ -37,7 +37,7 @@ LDFLAGS := -m elf_x86_64
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
LDFLAGS_vmlinux := -e stext
CHECKFLAGS += -D__x86_64__=1 -m64
CHECKFLAGS += -D__x86_64__ -m64
cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8)
cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona)
......
......@@ -102,10 +102,10 @@ struct aes_ctx {
#define E_KEY ctx->E
#define D_KEY ctx->D
static u8 pow_tab[256];
static u8 log_tab[256];
static u8 sbx_tab[256];
static u8 isb_tab[256];
static u8 pow_tab[256] __initdata;
static u8 log_tab[256] __initdata;
static u8 sbx_tab[256] __initdata;
static u8 isb_tab[256] __initdata;
static u32 rco_tab[10];
static u32 ft_tab[4][256];
static u32 it_tab[4][256];
......@@ -113,7 +113,7 @@ static u32 it_tab[4][256];
static u32 fl_tab[4][256];
static u32 il_tab[4][256];
static inline u8
static inline u8 __init
f_mult (u8 a, u8 b)
{
u8 aa = log_tab[a], cc = aa + log_tab[b];
......@@ -153,7 +153,7 @@ f_mult (u8 a, u8 b)
il_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
static void
static void __init
gen_tabs (void)
{
u32 i, t;
......
......@@ -2187,7 +2187,7 @@ static __u32 twothirdsMD4Transform (__u32 const buf[4], __u32 const in[12])
#undef K3
/* This should not be decreased so low that ISNs wrap too fast. */
#define REKEY_INTERVAL 300
#define REKEY_INTERVAL (300*HZ)
/*
* Bit layout of the tcp sequence numbers (before adding current time):
* bit 24-31: increased after every key exchange
......@@ -2213,48 +2213,55 @@ static __u32 twothirdsMD4Transform (__u32 const buf[4], __u32 const in[12])
#define HASH_MASK ( (1<<HASH_BITS)-1 )
static struct keydata {
time_t rekey_time;
__u32 count; // already shifted to the final position
__u32 secret[12];
} ____cacheline_aligned ip_keydata[2];
static spinlock_t ip_lock = SPIN_LOCK_UNLOCKED;
static unsigned int ip_cnt;
static void rekey_seq_generator(void *private_)
{
struct keydata *keyptr;
struct timeval tv;
static void rekey_seq_generator(void *private_);
do_gettimeofday(&tv);
static DECLARE_WORK(rekey_work, rekey_seq_generator, NULL);
spin_lock_bh(&ip_lock);
keyptr = &ip_keydata[ip_cnt&1];
/*
* Lock avoidance:
* The ISN generation runs lockless - it's just a hash over random data.
* State changes happen every 5 minutes when the random key is replaced.
* Synchronization is performed by having two copies of the hash function
* state and rekey_seq_generator always updates the inactive copy.
* The copy is then activated by updating ip_cnt.
* The implementation breaks down if someone blocks the thread
* that processes SYN requests for more than 5 minutes. Should never
* happen, and even if that happens only a not perfectly compliant
* ISN is generated, nothing fatal.
*/
static void rekey_seq_generator(void *private_)
{
struct keydata *keyptr = &ip_keydata[1^(ip_cnt&1)];
keyptr = &ip_keydata[1^(ip_cnt&1)];
keyptr->rekey_time = tv.tv_sec;
get_random_bytes(keyptr->secret, sizeof(keyptr->secret));
keyptr->count = (ip_cnt&COUNT_MASK)<<HASH_BITS;
mb();
smp_wmb();
ip_cnt++;
spin_unlock_bh(&ip_lock);
schedule_delayed_work(&rekey_work, REKEY_INTERVAL);
}
static DECLARE_WORK(rekey_work, rekey_seq_generator, NULL);
static inline struct keydata *check_and_rekey(time_t time)
static inline struct keydata *get_keyptr(void)
{
struct keydata *keyptr = &ip_keydata[ip_cnt&1];
rmb();
if (!keyptr->rekey_time || (time - keyptr->rekey_time) > REKEY_INTERVAL) {
schedule_work(&rekey_work);
}
smp_rmb();
return keyptr;
}
static __init int seqgen_init(void)
{
rekey_seq_generator(NULL);
return 0;
}
late_initcall(seqgen_init);
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
__u32 secure_tcpv6_sequence_number(__u32 *saddr, __u32 *daddr,
__u16 sport, __u16 dport)
......@@ -2262,14 +2269,12 @@ __u32 secure_tcpv6_sequence_number(__u32 *saddr, __u32 *daddr,
struct timeval tv;
__u32 seq;
__u32 hash[12];
struct keydata *keyptr;
struct keydata *keyptr = get_keyptr();
/* The procedure is the same as for IPv4, but addresses are longer.
* Thus we must use twothirdsMD4Transform.
*/
do_gettimeofday(&tv); /* We need the usecs below... */
keyptr = check_and_rekey(tv.tv_sec);
memcpy(hash, saddr, 16);
hash[4]=(sport << 16) + dport;
......@@ -2277,6 +2282,8 @@ __u32 secure_tcpv6_sequence_number(__u32 *saddr, __u32 *daddr,
seq = twothirdsMD4Transform(daddr, hash) & HASH_MASK;
seq += keyptr->count;
do_gettimeofday(&tv);
seq += tv.tv_usec + tv.tv_sec*1000000;
return seq;
......@@ -2290,13 +2297,7 @@ __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
struct timeval tv;
__u32 seq;
__u32 hash[4];
struct keydata *keyptr;
/*
* Pick a random secret every REKEY_INTERVAL seconds.
*/
do_gettimeofday(&tv); /* We need the usecs below... */
keyptr = check_and_rekey(tv.tv_sec);
struct keydata *keyptr = get_keyptr();
/*
* Pick a unique starting offset for each TCP connection endpoints
......@@ -2319,6 +2320,7 @@ __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
* That's funny, Linux has one built in! Use it!
* (Networks are faster now - should this be increased?)
*/
do_gettimeofday(&tv);
seq += tv.tv_usec + tv.tv_sec*1000000;
#if 0
printk("init_seq(%lx, %lx, %d, %d) = %d\n",
......@@ -2337,7 +2339,7 @@ __u32 secure_ip_id(__u32 daddr)
struct keydata *keyptr;
__u32 hash[4];
keyptr = check_and_rekey(get_seconds());
keyptr = get_keyptr();
/*
* Pick a unique starting offset for each IP destination.
......
......@@ -1297,6 +1297,13 @@ static int __devinit vortex_probe1(struct device *gendev,
for (i = 0; i < 6; i++)
printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);
}
/* Unfortunately an all zero eeprom passes the checksum and this
gets found in the wild in failure cases. Crypto is hard 8) */
if (!is_valid_ether_addr(dev->dev_addr)) {
retval = -EINVAL;
printk(KERN_ERR "*** EEPROM MAC address is invalid.\n");
goto free_ring; /* With every pack */
}
EL3WINDOW(2);
for (i = 0; i < 6; i++)
outb(dev->dev_addr[i], ioaddr + i);
......
......@@ -1814,16 +1814,18 @@ static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev)
/* Fill the bp->stats structure with driver-maintained counters */
bp->stats.rx_packets = bp->rcv_total_frames;
bp->stats.tx_packets = bp->xmt_total_frames;
bp->stats.rx_bytes = bp->rcv_total_bytes;
bp->stats.tx_bytes = bp->xmt_total_bytes;
bp->stats.rx_errors = (u32)(bp->rcv_crc_errors + bp->rcv_frame_status_errors + bp->rcv_length_errors);
bp->stats.tx_errors = bp->xmt_length_errors;
bp->stats.rx_dropped = bp->rcv_discards;
bp->stats.tx_dropped = bp->xmt_discards;
bp->stats.multicast = bp->rcv_multicast_frames;
bp->stats.transmit_collision = 0; /* always zero (0) for FDDI */
bp->stats.gen.rx_packets = bp->rcv_total_frames;
bp->stats.gen.tx_packets = bp->xmt_total_frames;
bp->stats.gen.rx_bytes = bp->rcv_total_bytes;
bp->stats.gen.tx_bytes = bp->xmt_total_bytes;
bp->stats.gen.rx_errors = bp->rcv_crc_errors +
bp->rcv_frame_status_errors +
bp->rcv_length_errors;
bp->stats.gen.tx_errors = bp->xmt_length_errors;
bp->stats.gen.rx_dropped = bp->rcv_discards;
bp->stats.gen.tx_dropped = bp->xmt_discards;
bp->stats.gen.multicast = bp->rcv_multicast_frames;
bp->stats.gen.collisions = 0; /* always zero (0) for FDDI */
/* Get FDDI SMT MIB objects */
......
......@@ -1095,7 +1095,7 @@ static int skfp_send_pkt(struct sk_buff *skb, struct net_device *dev)
*/
if (!(skb->len >= FDDI_K_LLC_ZLEN && skb->len <= FDDI_K_LLC_LEN)) {
bp->MacStat.tx_errors++; /* bump error counter */
bp->MacStat.gen.tx_errors++; /* bump error counter */
// dequeue packets from xmt queue and send them
netif_start_queue(dev);
dev_kfree_skb(skb);
......@@ -1546,8 +1546,8 @@ void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd)
skb->len, PCI_DMA_TODEVICE);
txd->txd_os.dma_addr = 0;
smc->os.MacStat.tx_packets++; // Count transmitted packets.
smc->os.MacStat.tx_bytes+=skb->len; // Count bytes
smc->os.MacStat.gen.tx_packets++; // Count transmitted packets.
smc->os.MacStat.gen.tx_bytes+=skb->len; // Count bytes
// free the skb
dev_kfree_skb_irq(skb);
......@@ -1629,7 +1629,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
skb = rxd->rxd_os.skb;
if (!skb) {
PRINTK(KERN_INFO "No skb in rxd\n");
smc->os.MacStat.rx_errors++;
smc->os.MacStat.gen.rx_errors++;
goto RequeueRxd;
}
virt = skb->data;
......@@ -1682,13 +1682,14 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
}
// Count statistics.
smc->os.MacStat.rx_packets++; // Count indicated receive packets.
smc->os.MacStat.rx_bytes+=len; // Count bytes
smc->os.MacStat.gen.rx_packets++; // Count indicated receive
// packets.
smc->os.MacStat.gen.rx_bytes+=len; // Count bytes.
// virt points to header again
if (virt[1] & 0x01) { // Check group (multicast) bit.
smc->os.MacStat.multicast++;
smc->os.MacStat.gen.multicast++;
}
// deliver frame to system
......@@ -1706,7 +1707,8 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
RequeueRxd:
PRINTK(KERN_INFO "Rx: re-queue RXD.\n");
mac_drv_requeue_rxd(smc, rxd, frag_count);
smc->os.MacStat.rx_errors++; // Count receive packets not indicated.
smc->os.MacStat.gen.rx_errors++; // Count receive packets
// not indicated.
} // mac_drv_rx_complete
......@@ -2081,7 +2083,7 @@ void smt_stat_counter(struct s_smc *smc, int stat)
break;
case 1:
PRINTK(KERN_INFO "Receive fifo overflow.\n");
smc->os.MacStat.rx_errors++;
smc->os.MacStat.gen.rx_errors++;
break;
default:
PRINTK(KERN_INFO "Unknown status (%d).\n", stat);
......
......@@ -84,7 +84,8 @@ config 3C359
config TMS380TR
tristate "Generic TMS380 Token Ring ISA/PCI adapter support"
depends on TR && (PCI || ISA)
depends on TR && (PCI || ISA) && HOTPLUG
select FW_LOADER
---help---
This driver provides generic support for token ring adapters
based on the Texas Instruments TMS380 series chipsets. This
......
......@@ -221,6 +221,8 @@ static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device
olympic_priv = dev->priv ;
spin_lock_init(&olympic_priv->olympic_lock) ;
init_waitqueue_head(&olympic_priv->srb_wait);
init_waitqueue_head(&olympic_priv->trb_wait);
#if OLYMPIC_DEBUG
......@@ -311,7 +313,6 @@ static int __devinit olympic_init(struct net_device *dev)
}
}
spin_lock_init(&olympic_priv->olympic_lock) ;
/* Needed for cardbus */
if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR)) {
......@@ -442,6 +443,8 @@ static int olympic_open(struct net_device *dev)
DECLARE_WAITQUEUE(wait,current) ;
olympic_init(dev);
if(request_irq(dev->irq, &olympic_interrupt, SA_SHIRQ , "olympic", dev)) {
return -EAGAIN;
}
......@@ -898,7 +901,10 @@ static void olympic_freemem(struct net_device *dev)
int i;
for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
dev_kfree_skb_irq(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
if (olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received] != NULL) {
dev_kfree_skb_irq(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received] = NULL;
}
if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != 0xdeadbeef) {
pci_unmap_single(olympic_priv->pdev,
le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer),
......@@ -944,9 +950,6 @@ static irqreturn_t olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs
/* Hotswap gives us this on removal */
if (sisr == 0xffffffff) {
printk(KERN_WARNING "%s: Hotswap adapter removal.\n",dev->name) ;
olympic_freemem(dev) ;
free_irq(dev->irq, dev) ;
dev->stop = NULL ;
spin_unlock(&olympic_priv->olympic_lock) ;
return IRQ_NONE;
}
......@@ -961,9 +964,7 @@ static irqreturn_t olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs
printk(KERN_ERR "The adapter must be reset to clear this condition.\n") ;
printk(KERN_ERR "Please report this error to the driver maintainer and/\n") ;
printk(KERN_ERR "or the linux-tr mailing list.\n") ;
olympic_freemem(dev) ;
free_irq(dev->irq, dev) ;
dev->stop = NULL ;
wake_up_interruptible(&olympic_priv->srb_wait);
spin_unlock(&olympic_priv->olympic_lock) ;
return IRQ_HANDLED;
} /* SISR_ERR */
......@@ -1006,9 +1007,6 @@ static irqreturn_t olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs
writel(readl(olympic_mmio+LAPWWC),olympic_mmio+LAPA);
adapter_check_area = olympic_priv->olympic_lap + ((readl(olympic_mmio+LAPWWC)) & (~0xf800)) ;
printk(KERN_WARNING "%s: Bytes %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, readb(adapter_check_area+0), readb(adapter_check_area+1), readb(adapter_check_area+2), readb(adapter_check_area+3), readb(adapter_check_area+4), readb(adapter_check_area+5), readb(adapter_check_area+6), readb(adapter_check_area+7)) ;
olympic_freemem(dev) ;
free_irq(dev->irq, dev) ;
dev->stop = NULL ;
spin_unlock(&olympic_priv->olympic_lock) ;
return IRQ_HANDLED;
} /* SISR_ADAPTER_CHECK */
......@@ -1094,34 +1092,32 @@ static int olympic_close(struct net_device *dev)
writeb(0,srb+1);
writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
add_wait_queue(&olympic_priv->srb_wait,&wait) ;
set_current_state(TASK_INTERRUPTIBLE) ;
spin_lock_irqsave(&olympic_priv->olympic_lock,flags);
olympic_priv->srb_queued=1;
writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
t = jiffies ;
add_wait_queue(&olympic_priv->srb_wait,&wait) ;
set_current_state(TASK_INTERRUPTIBLE) ;
while(olympic_priv->srb_queued) {
schedule() ;
t = schedule_timeout(60*HZ);
if(signal_pending(current)) {
printk(KERN_WARNING "%s: SRB timed out.\n",dev->name);
printk(KERN_WARNING "SISR=%x MISR=%x\n",readl(olympic_mmio+SISR),readl(olympic_mmio+LISR));
olympic_priv->srb_queued=0;
break;
}
if ((jiffies-t) > 60*HZ) {
if (t == 0) {
printk(KERN_WARNING "%s: SRB timed out. May not be fatal. \n",dev->name) ;
olympic_priv->srb_queued=0;
break ;
}
set_current_state(TASK_INTERRUPTIBLE) ;
olympic_priv->srb_queued=0;
}
remove_wait_queue(&olympic_priv->srb_wait,&wait) ;
set_current_state(TASK_RUNNING) ;
olympic_priv->rx_status_last_received++;
olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
......@@ -1513,29 +1509,6 @@ static void olympic_arb_cmd(struct net_device *dev)
writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL);
netif_stop_queue(dev);
olympic_priv->srb = readw(olympic_priv->olympic_lap + LAPWWO) ;
for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
dev_kfree_skb_irq(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != 0xdeadbeef) {
pci_unmap_single(olympic_priv->pdev,
le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer),
olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE);
}
olympic_priv->rx_status_last_received++;
olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
}
/* unmap rings */
pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_status_ring_dma_addr,
sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE);
pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_ring_dma_addr,
sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE);
pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_status_ring_dma_addr,
sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE);
pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_ring_dma_addr,
sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE, PCI_DMA_TODEVICE);
free_irq(dev->irq,dev);
dev->stop=NULL;
printk(KERN_WARNING "%s: Adapter has been closed \n", dev->name) ;
} /* If serious error */
......
......@@ -359,6 +359,8 @@ static void __devexit velocity_remove1(struct pci_dev *pdev)
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
free_netdev(dev);
velocity_nics--;
}
/**
......@@ -462,7 +464,7 @@ static void velocity_init_cam_filter(struct velocity_info *vptr)
{
struct mac_regs * regs = vptr->mac_regs;
/* T urn on MCFG_PQEN, turn off MCFG_RTGOPT */
/* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */
WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, &regs->MCFG);
WORD_REG_BITS_ON(MCFG_VIDFR, &regs->MCFG);
......@@ -490,12 +492,6 @@ static void velocity_init_cam_filter(struct velocity_info *vptr)
}
}
static inline void velocity_give_rx_desc(struct rx_desc *rd)
{
*(u32 *)&rd->rdesc0 = 0;
rd->rdesc0.owner = cpu_to_le32(OWNED_BY_NIC);
}
/**
* velocity_rx_reset - handle a receive reset
* @vptr: velocity we are resetting
......@@ -516,7 +512,7 @@ static void velocity_rx_reset(struct velocity_info *vptr)
* Init state, all RD entries belong to the NIC
*/
for (i = 0; i < vptr->options.numrx; ++i)
velocity_give_rx_desc(vptr->rd_ring + i);
vptr->rd_ring[i].rdesc0.owner = OWNED_BY_NIC;
writew(vptr->options.numrx, &regs->RBRDU);
writel(vptr->rd_pool_dma, &regs->RDBaseLo);
......@@ -591,10 +587,15 @@ static void velocity_init_registers(struct velocity_info *vptr,
writeb(WOLCFG_SAM | WOLCFG_SAB, &regs->WOLCFGSet);
/*
* Bback off algorithm use original IEEE standard
* Back off algorithm use original IEEE standard
*/
BYTE_REG_BITS_SET(CFGB_OFSET, (CFGB_CRANDOM | CFGB_CAP | CFGB_MBA | CFGB_BAKOPT), &regs->CFGB);
/*
* Init CAM filter
*/
velocity_init_cam_filter(vptr);
/*
* Set packet filter: Receive directed and broadcast address
*/
......@@ -619,8 +620,6 @@ static void velocity_init_registers(struct velocity_info *vptr,
mac_tx_queue_run(regs, i);
}
velocity_init_cam_filter(vptr);
init_flow_control_register(vptr);
writel(CR0_STOP, &regs->CR0Clr);
......@@ -628,7 +627,6 @@ static void velocity_init_registers(struct velocity_info *vptr,
mii_status = velocity_get_opt_media_mode(vptr);
netif_stop_queue(vptr->dev);
mac_clear_isr(regs);
mii_init(vptr, mii_status);
......@@ -695,7 +693,7 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
struct mac_regs * regs;
int ret = -ENOMEM;
if (velocity_nics++ >= MAX_UNITS) {
if (velocity_nics >= MAX_UNITS) {
printk(KERN_NOTICE VELOCITY_NAME ": already found %d NICs.\n",
velocity_nics);
return -ENODEV;
......@@ -727,7 +725,6 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
vptr->dev = dev;
dev->priv = vptr;
dev->irq = pdev->irq;
ret = pci_enable_device(pdev);
......@@ -762,7 +759,7 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
dev->dev_addr[i] = readb(&regs->PAR[i]);
velocity_get_options(&vptr->options, velocity_nics - 1, dev->name);
velocity_get_options(&vptr->options, velocity_nics, dev->name);
/*
* Mask out the options cannot be set to the chip
......@@ -817,6 +814,7 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
spin_unlock_irqrestore(&velocity_dev_list_lock, flags);
}
#endif
velocity_nics++;
out:
return ret;
......@@ -869,10 +867,7 @@ static void __devinit velocity_init_info(struct pci_dev *pdev, struct velocity_i
vptr->io_size = info->io_size;
vptr->num_txq = info->txqueue;
vptr->multicast_limit = MCAM_SIZE;
spin_lock_init(&vptr->lock);
spin_lock_init(&vptr->xmit_lock);
INIT_LIST_HEAD(&vptr->list);
}
......@@ -1024,11 +1019,11 @@ static inline void velocity_give_many_rx_descs(struct velocity_info *vptr)
wmb();
unusable = vptr->rd_filled | 0x0003;
dirty = vptr->rd_dirty - unusable + 1;
unusable = vptr->rd_filled & 0x0003;
dirty = vptr->rd_dirty - unusable;
for (avail = vptr->rd_filled & 0xfffc; avail; avail--) {
dirty = (dirty > 0) ? dirty - 1 : vptr->options.numrx - 1;
velocity_give_rx_desc(vptr->rd_ring + dirty);
vptr->rd_ring[dirty].rdesc0.owner = OWNED_BY_NIC;
}
writew(vptr->rd_filled & 0xfffc, &regs->RBRDU);
......@@ -1043,7 +1038,7 @@ static int velocity_rx_refill(struct velocity_info *vptr)
struct rx_desc *rd = vptr->rd_ring + dirty;
/* Fine for an all zero Rx desc at init time as well */
if (rd->rdesc0.owner == cpu_to_le32(OWNED_BY_NIC))
if (rd->rdesc0.owner == OWNED_BY_NIC)
break;
if (!vptr->rd_info[dirty].skb) {
......@@ -1096,7 +1091,7 @@ static int velocity_init_rd_ring(struct velocity_info *vptr)
}
/**
* velocity_free_rd_ring - set up receive ring
* velocity_free_rd_ring - free receive ring
* @vptr: velocity to clean up
*
* Free the receive buffers for each ring slot and any
......@@ -1161,8 +1156,10 @@ static int velocity_init_td_ring(struct velocity_info *vptr)
for (i = 0; i < vptr->options.numtx; i++, curr += sizeof(struct tx_desc)) {
td = &(vptr->td_rings[j][i]);
td_info = &(vptr->td_infos[j][i]);
td_info->buf = vptr->tx_bufs + (i + j) * PKT_BUF_SZ;
td_info->buf_dma = vptr->tx_bufs_dma + (i + j) * PKT_BUF_SZ;
td_info->buf = vptr->tx_bufs +
(j * vptr->options.numtx + i) * PKT_BUF_SZ;
td_info->buf_dma = vptr->tx_bufs_dma +
(j * vptr->options.numtx + i) * PKT_BUF_SZ;
}
vptr->td_tail[j] = vptr->td_curr[j] = vptr->td_used[j] = 0;
}
......@@ -1238,15 +1235,17 @@ static int velocity_rx_srv(struct velocity_info *vptr, int status)
int rd_curr = vptr->rd_curr;
int works = 0;
while (1) {
do {
struct rx_desc *rd = vptr->rd_ring + rd_curr;
if (!vptr->rd_info[rd_curr].skb || (works++ > 15))
if (!vptr->rd_info[rd_curr].skb)
break;
if (rd->rdesc0.owner == OWNED_BY_NIC)
break;
rmb();
/*
* Don't drop CE or RL error frame although RXOK is off
*/
......@@ -1269,14 +1268,15 @@ static int velocity_rx_srv(struct velocity_info *vptr, int status)
rd_curr++;
if (rd_curr >= vptr->options.numrx)
rd_curr = 0;
}
} while (++works <= 15);
if (velocity_rx_refill(vptr) < 0) {
vptr->rd_curr = rd_curr;
if (works > 0 && velocity_rx_refill(vptr) < 0) {
VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR
"%s: rx buf allocation failure\n", vptr->dev->name);
}
vptr->rd_curr = rd_curr;
VAR_USED(stats);
return works;
}
......
......@@ -1319,7 +1319,7 @@ static inline void mac_set_cam_mask(struct mac_regs * regs, u8 * mask, enum velo
/* disable CAMEN */
writeb(0, &regs->CAMADDR);
/* Select CAM mask */
/* Select mar */
BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
}
......@@ -1360,7 +1360,7 @@ static inline void mac_set_cam(struct mac_regs * regs, int idx, u8 *addr, enum v
writeb(0, &regs->CAMADDR);
/* Select CAM mask */
/* Select mar */
BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
}
......@@ -1401,7 +1401,7 @@ static inline void mac_get_cam(struct mac_regs * regs, int idx, u8 *addr, enum v
writeb(0, &regs->CAMADDR);
/* Select CAM mask */
/* Select mar */
BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
}
......@@ -1792,7 +1792,6 @@ struct velocity_info {
u8 mCAMmask[(MCAM_SIZE / 8)];
spinlock_t lock;
spinlock_t xmit_lock;
int wol_opts;
u8 wol_passwd[6];
......
......@@ -44,7 +44,7 @@
* register located at offset %ISL38XX_INT_IDENT_REG.
*/
void
isl38xx_disable_interrupts(void *device)
isl38xx_disable_interrupts(void __iomem *device)
{
isl38xx_w32_flush(device, 0x00000000, ISL38XX_INT_EN_REG);
udelay(ISL38XX_WRITEIO_DELAY);
......@@ -52,7 +52,7 @@ isl38xx_disable_interrupts(void *device)
void
isl38xx_handle_sleep_request(isl38xx_control_block *control_block,
int *powerstate, void *device_base)
int *powerstate, void __iomem *device_base)
{
/* device requests to go into sleep mode
* check whether the transmit queues for data and management are empty */
......@@ -88,7 +88,7 @@ isl38xx_handle_sleep_request(isl38xx_control_block *control_block,
void
isl38xx_handle_wakeup(isl38xx_control_block *control_block,
int *powerstate, void *device_base)
int *powerstate, void __iomem *device_base)
{
/* device is in active state, update the powerstate flag */
*powerstate = ISL38XX_PSM_ACTIVE_STATE;
......@@ -110,7 +110,7 @@ isl38xx_handle_wakeup(isl38xx_control_block *control_block,
}
void
isl38xx_trigger_device(int asleep, void *device_base)
isl38xx_trigger_device(int asleep, void __iomem *device_base)
{
struct timeval current_time;
u32 reg, counter = 0;
......@@ -190,7 +190,7 @@ isl38xx_trigger_device(int asleep, void *device_base)
}
void
isl38xx_interface_reset(void *device_base, dma_addr_t host_address)
isl38xx_interface_reset(void __iomem *device_base, dma_addr_t host_address)
{
u32 reg;
......@@ -219,7 +219,7 @@ isl38xx_interface_reset(void *device_base, dma_addr_t host_address)
}
void
isl38xx_enable_common_interrupts(void *device_base) {
isl38xx_enable_common_interrupts(void __iomem *device_base) {
u32 reg;
reg = ( ISL38XX_INT_IDENT_UPDATE |
ISL38XX_INT_IDENT_SLEEP | ISL38XX_INT_IDENT_WAKEUP);
......
......@@ -75,7 +75,7 @@
* from the %ISL38XX_PCI_POSTING_FLUSH offset.
*/
static inline void
isl38xx_w32_flush(void *base, u32 val, unsigned long offset)
isl38xx_w32_flush(void __iomem *base, u32 val, unsigned long offset)
{
writel(val, base + offset);
(void) readl(base + ISL38XX_PCI_POSTING_FLUSH);
......@@ -157,13 +157,13 @@ typedef struct isl38xx_cb isl38xx_control_block;
/* determine number of entries currently in queue */
int isl38xx_in_queue(isl38xx_control_block *cb, int queue);
void isl38xx_disable_interrupts(void *);
void isl38xx_enable_common_interrupts(void *);
void isl38xx_disable_interrupts(void __iomem *);
void isl38xx_enable_common_interrupts(void __iomem *);
void isl38xx_handle_sleep_request(isl38xx_control_block *, int *,
void *);
void isl38xx_handle_wakeup(isl38xx_control_block *, int *, void *);
void isl38xx_trigger_device(int, void *);
void isl38xx_interface_reset(void *, dma_addr_t);
void __iomem *);
void isl38xx_handle_wakeup(isl38xx_control_block *, int *, void __iomem *);
void isl38xx_trigger_device(int, void __iomem *);
void isl38xx_interface_reset(void __iomem *, dma_addr_t);
#endif /* _ISL_38XX_H */
......@@ -58,7 +58,7 @@ static int
isl_upload_firmware(islpci_private *priv)
{
u32 reg, rc;
void *device_base = priv->device_base;
void __iomem *device_base = priv->device_base;
/* clear the RAMBoot and the Reset bit */
reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
......@@ -113,7 +113,7 @@ isl_upload_firmware(islpci_private *priv)
(fw_len >
ISL38XX_MEMORY_WINDOW_SIZE) ?
ISL38XX_MEMORY_WINDOW_SIZE : fw_len;
u32 *dev_fw_ptr = device_base + ISL38XX_DIRECT_MEM_WIN;
u32 __iomem *dev_fw_ptr = device_base + ISL38XX_DIRECT_MEM_WIN;
/* set the cards base address for writting the data */
isl38xx_w32_flush(device_base, reg,
......@@ -183,7 +183,7 @@ islpci_interrupt(int irq, void *config, struct pt_regs *regs)
u32 reg;
islpci_private *priv = config;
struct net_device *ndev = priv->ndev;
void *device = priv->device_base;
void __iomem *device = priv->device_base;
int powerstate = ISL38XX_PSM_POWERSAVE_STATE;
/* lock the interrupt handler */
......@@ -405,7 +405,7 @@ islpci_close(struct net_device *ndev)
static int
prism54_bring_down(islpci_private *priv)
{
void *device_base = priv->device_base;
void __iomem *device_base = priv->device_base;
u32 reg;
/* we are going to shutdown the device */
islpci_set_state(priv, PRV_STATE_PREBOOT);
......
......@@ -109,7 +109,7 @@ typedef struct {
u32 pci_state[16]; /* used for suspend/resume */
char firmware[33];
void *device_base; /* ioremapped device base address */
void __iomem *device_base; /* ioremapped device base address */
/* consistent DMA region */
void *driver_mem_address; /* base DMA address */
......
......@@ -85,7 +85,7 @@
=====================================================================*/
static u_int xlate_rom_addr(u_char * b, u_int addr)
static u_int xlate_rom_addr(void __iomem *b, u_int addr)
{
u_int img = 0, ofs = 0, sz;
u_short data;
......
......@@ -103,7 +103,7 @@ void release_cis_mem(struct pcmcia_socket *s)
* If flags & MAP_ATTRIB, map the attribute space, otherwise
* map the memory space.
*/
static unsigned char *
static void __iomem *
set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags)
{
pccard_mem_map *mem = &s->cis_mem;
......@@ -141,7 +141,8 @@ set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flag
int read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
u_int len, void *ptr)
{
u_char *sys, *end, *buf = ptr;
void __iomem *sys, *end;
unsigned char *buf = ptr;
cs_dbg(s, 3, "read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
......@@ -204,7 +205,8 @@ int read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
void write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
u_int len, void *ptr)
{
u_char *sys, *end, *buf = ptr;
void __iomem *sys, *end;
unsigned char *buf = ptr;
cs_dbg(s, 3, "write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
......
......@@ -321,7 +321,7 @@ static int checksum(struct pcmcia_socket *s, struct resource *res)
{
pccard_mem_map map;
int i, a = 0, b = -1, d;
void *virt;
void __iomem *virt;
virt = ioremap(res->start, s->map_size);
if (virt) {
......
......@@ -107,7 +107,7 @@ struct cardbus_type {
struct yenta_socket {
struct pci_dev *dev;
int cb_irq, io_irq;
void *base;
void __iomem *base;
struct timer_list poll_timer;
struct pcmcia_socket socket;
......
......@@ -696,7 +696,6 @@ static int __init pl011_console_setup(struct console *co, char *options)
int bits = 8;
int parity = 'n';
int flow = 'n';
int ret;
/*
* Check whether an invalid uart number has been specified, and
......
......@@ -26,8 +26,6 @@
#include <asm/hardware.h>
#include <asm/arch/regs-serial.h>
#include <asm/mach-types.h>
#if 0
#include <asm/debug-ll.h>
#define dbg(x...) llprintk(x)
......
......@@ -395,7 +395,7 @@ uart_get_divisor(struct uart_port *port, unsigned int baud)
if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
quot = port->custom_divisor;
else
quot = port->uartclk / (16 * baud);
quot = (port->uartclk + (8 * baud)) / (16 * baud);
return quot;
}
......
......@@ -13,8 +13,11 @@
extern void (*init_arch_time)(void);
extern int (*set_rtc)(void);
extern unsigned long(*gettimeoffset)(void);
extern unsigned long (*gettimeoffset)(void);
void timer_tick(struct pt_regs *);
extern void timer_tick(struct pt_regs *);
extern void save_time_delta(struct timespec *delta, struct timespec *rtc);
extern void restore_time_delta(struct timespec *delta, struct timespec *rtc);
#endif
#ifndef __LINUX_GEN_STATS_H
#define __LINUX_GEN_STATS_H
#include <linux/types.h>
enum {
TCA_STATS_UNSPEC,
TCA_STATS_BASIC,
TCA_STATS_RATE_EST,
TCA_STATS_QUEUE,
TCA_STATS_APP,
__TCA_STATS_MAX,
};
#define TCA_STATS_MAX (__TCA_STATS_MAX - 1)
/**
* @bytes: number of seen bytes
* @packets: number of seen packets
*/
struct gnet_stats_basic
{
__u64 bytes;
__u32 packets;
};
/**
* @bps: current byte rate
* @pps: current packet rate
*/
struct gnet_stats_rate_est
{
__u32 bps;
__u32 pps;
};
/**
* @qlen: queue length
* @backlog: backlog size of queue
* @drops: number of dropped packets
* @requeues: number of requeues
*/
struct gnet_stats_queue
{
__u32 qlen;
__u32 backlog;
__u32 drops;
__u32 requeues;
__u32 overlimits;
};
/**
* @interval: sampling period
* @ewma_log: the log of measurement window weight
*/
struct gnet_estimator
{
signed char interval;
unsigned char ewma_log;
};
#endif /* __LINUX_GEN_STATS_H */
......@@ -5,7 +5,7 @@
*
* Global definitions for the ANSI FDDI interface.
*
* Version: @(#)if_fddi.h 1.0.1 09/16/96
* Version: @(#)if_fddi.h 1.0.2 Sep 29 2004
*
* Author: Lawrence V. Stefani, <stefani@lkg.dec.com>
*
......@@ -103,38 +103,12 @@ struct fddihdr
} __attribute__ ((packed));
/* Define FDDI statistics structure */
struct fddi_statistics
{
__u32 rx_packets; /* total packets received */
__u32 tx_packets; /* total packets transmitted */
__u32 rx_bytes; /* total bytes received */
__u32 tx_bytes; /* total bytes transmitted */
__u32 rx_errors; /* bad packets received */
__u32 tx_errors; /* packet transmit problems */
__u32 rx_dropped; /* no space in linux buffers */
__u32 tx_dropped; /* no space available in linux */
__u32 multicast; /* multicast packets received */
__u32 transmit_collision; /* always 0 for FDDI */
struct fddi_statistics {
/* Generic statistics. */
/* detailed rx_errors */
__u32 rx_length_errors;
__u32 rx_over_errors; /* receiver ring buff overflow */
__u32 rx_crc_errors; /* recved pkt with crc error */
__u32 rx_frame_errors; /* recv'd frame alignment error */
__u32 rx_fifo_errors; /* recv'r fifo overrun */
__u32 rx_missed_errors; /* receiver missed packet */
struct net_device_stats gen;
/* detailed tx_errors */
__u32 tx_aborted_errors;
__u32 tx_carrier_errors;
__u32 tx_fifo_errors;
__u32 tx_heartbeat_errors;
__u32 tx_window_errors;
/* for cslip etc */
__u32 rx_compressed;
__u32 tx_compressed;
/* Detailed FDDI statistics. Adopted from RFC 1512 */
__u8 smt_station_id[8];
......
......@@ -449,7 +449,7 @@ struct task_struct {
unsigned long sleep_avg;
long interactive_credit;
unsigned long long timestamp;
unsigned long long timestamp, last_ran;
int activated;
unsigned long policy;
......
......@@ -15,11 +15,9 @@
#define _LINUX_SUNRPC_AUTH_GSS_H
#ifdef __KERNEL__
#ifdef __linux__
#include <linux/sunrpc/auth.h>
#include <linux/sunrpc/svc.h>
#include <linux/sunrpc/gss_api.h>
#endif
#define RPC_GSS_VERSION 1
......
#ifndef __NET_GEN_STATS_H
#define __NET_GEN_STATS_H
#include <linux/gen_stats.h>
#include <linux/socket.h>
#include <linux/rtnetlink.h>
#include <linux/pkt_sched.h>
struct gnet_dump
{
spinlock_t * lock;
struct sk_buff * skb;
struct rtattr * tail;
/* Backward compatability */
int compat_tc_stats;
int compat_xstats;
struct rtattr * xstats;
struct tc_stats tc_stats;
};
extern int gnet_stats_start_copy(struct sk_buff *skb, int type,
spinlock_t *lock, struct gnet_dump *d);
extern int gnet_stats_start_copy_compat(struct sk_buff *skb, int type,
int tc_stats_type,int xstats_type,
spinlock_t *lock, struct gnet_dump *d);
extern int gnet_stats_copy_basic(struct gnet_dump *d,
struct gnet_stats_basic *b);
extern int gnet_stats_copy_rate_est(struct gnet_dump *d,
struct gnet_stats_rate_est *r);
extern int gnet_stats_copy_queue(struct gnet_dump *d,
struct gnet_stats_queue *q);
extern int gnet_stats_copy_app(struct gnet_dump *d, void *st, int len);
extern int gnet_stats_finish_copy(struct gnet_dump *d);
extern int gen_new_estimator(struct gnet_stats_basic *bstats,
struct gnet_stats_rate_est *rate_est,
spinlock_t *stats_lock, struct rtattr *opt);
extern void gen_kill_estimator(struct gnet_stats_basic *bstats,
struct gnet_stats_rate_est *rate_est);
#endif
......@@ -176,7 +176,7 @@ struct pcmcia_socket {
u_short lock_count;
client_handle_t clients;
pccard_mem_map cis_mem;
u_char *cis_virt;
void __iomem *cis_virt;
struct config_t *config;
struct {
u_int AssignedIRQ;
......@@ -227,7 +227,7 @@ struct pcmcia_socket {
/* cardbus (32-bit) */
#ifdef CONFIG_CARDBUS
struct resource * cb_cis_res;
u_char *cb_cis_virt;
void __iomem *cb_cis_virt;
#endif
/* socket device */
......
......@@ -180,7 +180,8 @@ static unsigned int task_timeslice(task_t *p)
else
return SCALE_PRIO(DEF_TIMESLICE, p->static_prio);
}
#define task_hot(p, now, sd) ((now) - (p)->timestamp < (sd)->cache_hot_time)
#define task_hot(p, now, sd) ((long long) ((now) - (p)->last_ran) \
< (long long) (sd)->cache_hot_time)
enum idle_type
{
......@@ -2764,7 +2765,7 @@ asmlinkage void __sched schedule(void)
if (!(HIGH_CREDIT(prev) || LOW_CREDIT(prev)))
prev->interactive_credit--;
}
prev->timestamp = now;
prev->timestamp = prev->last_ran = now;
sched_info_switch(prev, next);
if (likely(prev != next)) {
......
......@@ -2,7 +2,7 @@
# Makefile for the Linux networking core.
#
obj-y := sock.o skbuff.o iovec.o datagram.o stream.o scm.o
obj-y := sock.o skbuff.o iovec.o datagram.o stream.o scm.o gen_stats.o gen_estimator.o
obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
......
/*
* net/sched/gen_estimator.c Simple rate estimator.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
*
* Changes:
* Jamal Hadi Salim - moved it to net/core and reshulfed
* names to make it usable in general net subsystem.
*/
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/in.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
#include <linux/init.h>
#include <net/sock.h>
#include <net/gen_stats.h>
/*
This code is NOT intended to be used for statistics collection,
its purpose is to provide a base for statistical multiplexing
for controlled load service.
If you need only statistics, run a user level daemon which
periodically reads byte counters.
Unfortunately, rate estimation is not a very easy task.
F.e. I did not find a simple way to estimate the current peak rate
and even failed to formulate the problem 8)8)
So I preferred not to built an estimator into the scheduler,
but run this task separately.
Ideally, it should be kernel thread(s), but for now it runs
from timers, which puts apparent top bounds on the number of rated
flows, has minimal overhead on small, but is enough
to handle controlled load service, sets of aggregates.
We measure rate over A=(1<<interval) seconds and evaluate EWMA:
avrate = avrate*(1-W) + rate*W
where W is chosen as negative power of 2: W = 2^(-ewma_log)
The resulting time constant is:
T = A/(-ln(1-W))
NOTES.
* The stored value for avbps is scaled by 2^5, so that maximal
rate is ~1Gbit, avpps is scaled by 2^10.
* Minimal interval is HZ/4=250msec (it is the greatest common divisor
for HZ=100 and HZ=1024 8)), maximal interval
is (HZ*2^EST_MAX_INTERVAL)/4 = 8sec. Shorter intervals
are too expensive, longer ones can be implemented
at user level painlessly.
*/
#define EST_MAX_INTERVAL 5
struct gen_estimator
{
struct gen_estimator *next;
struct gnet_stats_basic *bstats;
struct gnet_stats_rate_est *rate_est;
spinlock_t *stats_lock;
unsigned interval;
int ewma_log;
u64 last_bytes;
u32 last_packets;
u32 avpps;
u32 avbps;
};
struct gen_estimator_head
{
struct timer_list timer;
struct gen_estimator *list;
};
static struct gen_estimator_head elist[EST_MAX_INTERVAL+1];
/* Estimator array lock */
static rwlock_t est_lock = RW_LOCK_UNLOCKED;
static void est_timer(unsigned long arg)
{
int idx = (int)arg;
struct gen_estimator *e;
read_lock(&est_lock);
for (e = elist[idx].list; e; e = e->next) {
u64 nbytes;
u32 npackets;
u32 rate;
spin_lock(e->stats_lock);
nbytes = e->bstats->bytes;
npackets = e->bstats->packets;
rate = (nbytes - e->last_bytes)<<(7 - idx);
e->last_bytes = nbytes;
e->avbps += ((long)rate - (long)e->avbps) >> e->ewma_log;
e->rate_est->bps = (e->avbps+0xF)>>5;
rate = (npackets - e->last_packets)<<(12 - idx);
e->last_packets = npackets;
e->avpps += ((long)rate - (long)e->avpps) >> e->ewma_log;
e->rate_est->pps = (e->avpps+0x1FF)>>10;
spin_unlock(e->stats_lock);
}
mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
read_unlock(&est_lock);
}
int gen_new_estimator(struct gnet_stats_basic *bstats,
struct gnet_stats_rate_est *rate_est, spinlock_t *stats_lock, struct rtattr *opt)
{
struct gen_estimator *est;
struct gnet_estimator *parm = RTA_DATA(opt);
if (RTA_PAYLOAD(opt) < sizeof(*parm))
return -EINVAL;
if (parm->interval < -2 || parm->interval > 3)
return -EINVAL;
est = kmalloc(sizeof(*est), GFP_KERNEL);
if (est == NULL)
return -ENOBUFS;
memset(est, 0, sizeof(*est));
est->interval = parm->interval + 2;
est->bstats = bstats;
est->rate_est = rate_est;
est->stats_lock = stats_lock;
est->ewma_log = parm->ewma_log;
est->last_bytes = bstats->bytes;
est->avbps = rate_est->bps<<5;
est->last_packets = bstats->packets;
est->avpps = rate_est->pps<<10;
est->next = elist[est->interval].list;
if (est->next == NULL) {
init_timer(&elist[est->interval].timer);
elist[est->interval].timer.data = est->interval;
elist[est->interval].timer.expires = jiffies + ((HZ<<est->interval)/4);
elist[est->interval].timer.function = est_timer;
add_timer(&elist[est->interval].timer);
}
write_lock_bh(&est_lock);
elist[est->interval].list = est;
write_unlock_bh(&est_lock);
return 0;
}
void gen_kill_estimator(struct gnet_stats_basic *bstats,
struct gnet_stats_rate_est *rate_est)
{
int idx;
struct gen_estimator *est, **pest;
for (idx=0; idx <= EST_MAX_INTERVAL; idx++) {
int killed = 0;
pest = &elist[idx].list;
while ((est=*pest) != NULL) {
if (est->rate_est != rate_est || est->bstats != bstats) {
pest = &est->next;
continue;
}
write_lock_bh(&est_lock);
*pest = est->next;
write_unlock_bh(&est_lock);
kfree(est);
killed++;
}
if (killed && elist[idx].list == NULL)
del_timer(&elist[idx].timer);
}
}
EXPORT_SYMBOL(gen_kill_estimator);
EXPORT_SYMBOL(gen_new_estimator);
/*
* net/core/gen_stats.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Authors: Thomas Graf <tgraf@suug.ch>
* Jamal Hadi Salim
* Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
*
* See Documentation/networking/gen_stats.txt
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/socket.h>
#include <linux/rtnetlink.h>
#include <linux/gen_stats.h>
#include <net/gen_stats.h>
static inline int
gnet_stats_copy(struct gnet_dump *d, int type, void *buf, int size)
{
RTA_PUT(d->skb, type, size, buf);
return 0;
rtattr_failure:
spin_unlock_bh(d->lock);
return -1;
}
int
gnet_stats_start_copy_compat(struct sk_buff *skb, int type, int tc_stats_type,
int xstats_type, spinlock_t *lock, struct gnet_dump *d)
{
spin_lock_bh(lock);
d->lock = lock;
d->tail = (struct rtattr *) skb->tail;
d->skb = skb;
d->compat_tc_stats = tc_stats_type;
d->compat_xstats = xstats_type;
d->xstats = NULL;
if (d->compat_tc_stats)
memset(&d->tc_stats, 0, sizeof(d->tc_stats));
return gnet_stats_copy(d, type, NULL, 0);
}
int
gnet_stats_start_copy(struct sk_buff *skb, int type, spinlock_t *lock,
struct gnet_dump *d)
{
return gnet_stats_start_copy_compat(skb, type, 0, 0, lock, d);
}
int
gnet_stats_copy_basic(struct gnet_dump *d, struct gnet_stats_basic *b)
{
if (d->compat_tc_stats) {
d->tc_stats.bytes = b->bytes;
d->tc_stats.packets = b->packets;
}
return gnet_stats_copy(d, TCA_STATS_BASIC, b, sizeof(*b));
}
int
gnet_stats_copy_rate_est(struct gnet_dump *d, struct gnet_stats_rate_est *r)
{
if (d->compat_tc_stats) {
d->tc_stats.bps = r->bps;
d->tc_stats.pps = r->pps;
}
return gnet_stats_copy(d, TCA_STATS_RATE_EST, r, sizeof(*r));
}
int
gnet_stats_copy_queue(struct gnet_dump *d, struct gnet_stats_queue *q)
{
if (d->compat_tc_stats) {
d->tc_stats.drops = q->drops;
d->tc_stats.qlen = q->qlen;
d->tc_stats.backlog = q->backlog;
d->tc_stats.overlimits = q->overlimits;
}
return gnet_stats_copy(d, TCA_STATS_QUEUE, q, sizeof(*q));
}
int
gnet_stats_copy_app(struct gnet_dump *d, void *st, int len)
{
if (d->compat_xstats)
d->xstats = (struct rtattr *) d->skb->tail;
return gnet_stats_copy(d, TCA_STATS_APP, st, len);
}
int
gnet_stats_finish_copy(struct gnet_dump *d)
{
d->tail->rta_len = d->skb->tail - (u8 *) d->tail;
if (d->compat_tc_stats)
if (gnet_stats_copy(d, d->compat_tc_stats, &d->tc_stats,
sizeof(d->tc_stats)) < 0)
return -1;
if (d->compat_xstats && d->xstats) {
if (gnet_stats_copy(d, d->compat_xstats, RTA_DATA(d->xstats),
RTA_PAYLOAD(d->xstats)) < 0)
return -1;
}
spin_unlock_bh(d->lock);
return 0;
}
EXPORT_SYMBOL(gnet_stats_start_copy);
EXPORT_SYMBOL(gnet_stats_copy_basic);
EXPORT_SYMBOL(gnet_stats_copy_rate_est);
EXPORT_SYMBOL(gnet_stats_copy_queue);
EXPORT_SYMBOL(gnet_stats_copy_app);
EXPORT_SYMBOL(gnet_stats_finish_copy);
......@@ -810,9 +810,15 @@ static void neigh_timer_handler(unsigned long arg)
add_timer(&neigh->timer);
}
if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) {
struct sk_buff *skb = skb_peek(&neigh->arp_queue);
/* keep skb alive even if arp_queue overflows */
if (skb)
skb_get(skb);
write_unlock(&neigh->lock);
neigh->ops->solicit(neigh, skb_peek(&neigh->arp_queue));
neigh->ops->solicit(neigh, skb);
atomic_inc(&neigh->probes);
if (skb)
kfree_skb(skb);
} else {
out:
write_unlock(&neigh->lock);
......
......@@ -1005,8 +1005,26 @@ int arp_req_set(struct arpreq *r, struct net_device * dev)
if (!dev)
return -EINVAL;
}
if (r->arp_ha.sa_family != dev->type)
return -EINVAL;
switch (dev->type) {
#ifdef CONFIG_FDDI
case ARPHRD_FDDI:
/*
* According to RFC 1390, FDDI devices should accept ARP
* hardware types of 1 (Ethernet). However, to be more
* robust, we'll accept hardware types of either 1 (Ethernet)
* or 6 (IEEE 802.2).
*/
if (r->arp_ha.sa_family != ARPHRD_FDDI &&
r->arp_ha.sa_family != ARPHRD_ETHER &&
r->arp_ha.sa_family != ARPHRD_IEEE802)
return -EINVAL;
break;
#endif
default:
if (r->arp_ha.sa_family != dev->type)
return -EINVAL;
break;
}
neigh = __neigh_lookup_errno(&arp_tbl, &ip, dev);
err = PTR_ERR(neigh);
......
......@@ -720,6 +720,8 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d
b->htype = dev->type;
else if (dev->type == ARPHRD_IEEE802_TR) /* fix for token ring */
b->htype = ARPHRD_IEEE802;
else if (dev->type == ARPHRD_FDDI)
b->htype = ARPHRD_ETHER;
else {
printk("Unknown ARP type 0x%04x for device %s\n", dev->type, dev->name);
b->htype = dev->type; /* can cause undefined behavior */
......
......@@ -16,6 +16,7 @@
* Alexandre Cassen : Added master & backup support at a time.
* Alexandre Cassen : Added SyncID support for incoming sync
* messages filtering.
* Justin Ossevoort : Fix endian problem on sync message size.
*/
#include <linux/module.h>
......@@ -279,6 +280,9 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
char *p;
int i;
/* Convert size back to host byte order */
m->size = ntohs(m->size);
if (buflen != m->size) {
IP_VS_ERR("bogus message\n");
return;
......@@ -569,6 +573,19 @@ ip_vs_send_async(struct socket *sock, const char *buffer, const size_t length)
return len;
}
static void
ip_vs_send_sync_msg(struct socket *sock, struct ip_vs_sync_mesg *msg)
{
int msize;
msize = msg->size;
/* Put size in network byte order */
msg->size = htons(msg->size);
if (ip_vs_send_async(sock, (char *)msg, msize) != msize)
IP_VS_ERR("ip_vs_send_async error\n");
}
static int
ip_vs_receive(struct socket *sock, char *buffer, const size_t buflen)
......@@ -605,7 +622,6 @@ static void sync_master_loop(void)
{
struct socket *sock;
struct ip_vs_sync_buff *sb;
struct ip_vs_sync_mesg *m;
/* create the sending multicast socket */
sock = make_send_sock();
......@@ -618,19 +634,13 @@ static void sync_master_loop(void)
for (;;) {
while ((sb=sb_dequeue())) {
m = sb->mesg;
if (ip_vs_send_async(sock, (char *)m,
m->size) != m->size)
IP_VS_ERR("ip_vs_send_async error\n");
ip_vs_send_sync_msg(sock, sb->mesg);
ip_vs_sync_buff_release(sb);
}
/* check if entries stay in curr_sb for 2 seconds */
if ((sb = get_curr_sync_buff(2*HZ))) {
m = sb->mesg;
if (ip_vs_send_async(sock, (char *)m,
m->size) != m->size)
IP_VS_ERR("ip_vs_send_async error\n");
ip_vs_send_sync_msg(sock, sb->mesg);
ip_vs_sync_buff_release(sb);
}
......
......@@ -66,15 +66,11 @@
* Minimal interval is HZ/4=250msec (it is the greatest common divisor
for HZ=100 and HZ=1024 8)), maximal interval
is (HZ/4)*2^EST_MAX_INTERVAL = 8sec. Shorter intervals
is (HZ*2^EST_MAX_INTERVAL)/4 = 8sec. Shorter intervals
are too expensive, longer ones can be implemented
at user level painlessly.
*/
#if (HZ%4) != 0
#error Bad HZ value.
#endif
#define EST_MAX_INTERVAL 5
struct qdisc_estimator
......@@ -128,7 +124,7 @@ static void est_timer(unsigned long arg)
spin_unlock(e->stats_lock);
}
mod_timer(&elist[idx].timer, jiffies + ((HZ/4)<<idx));
mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
read_unlock(&est_lock);
}
......@@ -161,7 +157,7 @@ int qdisc_new_estimator(struct tc_stats *stats, spinlock_t *stats_lock, struct r
if (est->next == NULL) {
init_timer(&elist[est->interval].timer);
elist[est->interval].timer.data = est->interval;
elist[est->interval].timer.expires = jiffies + ((HZ/4)<<est->interval);
elist[est->interval].timer.expires = jiffies + ((HZ<<est->interval)/4);
elist[est->interval].timer.function = est_timer;
add_timer(&elist[est->interval].timer);
}
......
......@@ -1675,7 +1675,6 @@ cbq_dump_class(struct Qdisc *sch, unsigned long arg,
cl->xstats.undertime = 0;
if (!PSCHED_IS_PASTPERFECT(cl->undertime))
cl->xstats.undertime = PSCHED_TDIFF(cl->undertime, q->now);
q->link.xstats.avgidle = q->link.avgidle;
if (cbq_copy_xstats(skb, &cl->xstats)) {
spin_unlock_bh(&sch->dev->queue_lock);
goto rtattr_failure;
......
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