Auto merge with /home/aegl/GIT/linus

This commit is contained in:
Tony Luck
2005-07-06 15:35:18 -07:00
202 changed files with 4167 additions and 2794 deletions
+2
View File
@@ -1505,6 +1505,7 @@
#define PSSR_OTGPH (1 << 6) /* OTG Peripheral control Hold */
#define PSSR_RDH (1 << 5) /* Read Disable Hold */
#define PSSR_PH (1 << 4) /* Peripheral Control Hold */
#define PSSR_STS (1 << 3) /* Standby Mode Status */
#define PSSR_VFS (1 << 2) /* VDD Fault Status */
#define PSSR_BFS (1 << 1) /* Battery Fault Status */
#define PSSR_SSS (1 << 0) /* Software Sleep Status */
@@ -1965,6 +1966,7 @@
#define MECR_NOS (1 << 0) /* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */
#define MECR_CIT (1 << 1) /* Card Is There: 0 -> no card, 1 -> card inserted */
#define MDREFR_K0DB4 (1 << 29) /* SDCLK0 Divide by 4 Control/Status */
#define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */
#define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */
#define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */
+1 -33
View File
@@ -26,7 +26,7 @@ struct machine_desc {
* page tabe entry */
const char *name; /* architecture name */
unsigned int param_offset; /* parameter page */
unsigned long boot_params; /* tagged list */
unsigned int video_start; /* start of video RAM */
unsigned int video_end; /* end of video RAM */
@@ -54,38 +54,6 @@ const struct machine_desc __mach_desc_##_type \
.nr = MACH_TYPE_##_type, \
.name = _name,
#define MAINTAINER(n)
#define BOOT_MEM(_pram,_pio,_vio) \
.phys_ram = _pram, \
.phys_io = _pio, \
.io_pg_offst = ((_vio)>>18)&0xfffc,
#define BOOT_PARAMS(_params) \
.param_offset = _params,
#define VIDEO(_start,_end) \
.video_start = _start, \
.video_end = _end,
#define DISABLE_PARPORT(_n) \
.reserve_lp##_n = 1,
#define SOFT_REBOOT \
.soft_reboot = 1,
#define FIXUP(_func) \
.fixup = _func,
#define MAPIO(_func) \
.map_io = _func,
#define INITIRQ(_func) \
.init_irq = _func,
#define INIT_MACHINE(_func) \
.init_machine = _func,
#define MACHINE_END \
};
+1 -1
View File
@@ -89,6 +89,6 @@ struct stat64 {
unsigned long st_ctime_nsec;
unsigned long long st_ino;
};
} __attribute__((packed));
#endif
+3 -1
View File
@@ -85,7 +85,9 @@ struct pt_regs;
void die(const char *msg, struct pt_regs *regs, int err)
__attribute__((noreturn));
void die_if_kernel(const char *str, struct pt_regs *regs, int err);
struct siginfo;
void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
unsigned long err, unsigned long trap);
void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
struct pt_regs *),
+4
View File
@@ -68,6 +68,10 @@
#include <platforms/lantec.h>
#endif
#if defined(CONFIG_MPC885ADS)
#include <platforms/mpc885ads.h>
#endif
/* Currently, all 8xx boards that support a processor to PCI/ISA bridge
* use the same memory map.
*/
+19 -28
View File
@@ -16,6 +16,18 @@
#include <asm/pil.h>
#include <asm/ptrace.h>
struct ino_bucket;
#define MAX_IRQ_DESC_ACTION 4
struct irq_desc {
void (*pre_handler)(struct ino_bucket *, void *, void *);
void *pre_handler_arg1;
void *pre_handler_arg2;
u32 action_active_mask;
struct irqaction action[MAX_IRQ_DESC_ACTION];
};
/* You should not mess with this directly. That's the job of irq.c.
*
* If you make changes here, please update hand coded assembler of
@@ -42,24 +54,11 @@ struct ino_bucket {
/* Miscellaneous flags. */
/*0x06*/unsigned char flags;
/* This is used to deal with IBF_DMA_SYNC on
* Sabre systems.
*/
/*0x07*/unsigned char synctab_ent;
/* Currently unused. */
/*0x07*/unsigned char __pad;
/* Reference to handler for this IRQ. If this is
* non-NULL this means it is active and should be
* serviced. Else the pending member is set to one
* and later registry of the interrupt checks for
* this condition.
*
* Normally this is just an irq_action structure.
* But, on PCI, if multiple interrupt sources behind
* a bridge have multiple interrupt sources that share
* the same INO bucket, this points to an array of
* pointers to four IRQ action structures.
*/
/*0x08*/void *irq_info;
/* Reference to IRQ descriptor for this bucket. */
/*0x08*/struct irq_desc *irq_info;
/* Sun5 Interrupt Clear Register. */
/*0x10*/unsigned long iclr;
@@ -69,12 +68,6 @@ struct ino_bucket {
};
#ifdef CONFIG_PCI
extern unsigned long pci_dma_wsync;
extern unsigned long dma_sync_reg_table[256];
extern unsigned char dma_sync_reg_table_entry;
#endif
/* IMAP/ICLR register defines */
#define IMAP_VALID 0x80000000 /* IRQ Enabled */
#define IMAP_TID_UPA 0x7c000000 /* UPA TargetID */
@@ -90,11 +83,9 @@ extern unsigned char dma_sync_reg_table_entry;
#define ICLR_PENDING 0x00000003 /* Pending state */
/* Only 8-bits are available, be careful. -DaveM */
#define IBF_DMA_SYNC 0x01 /* DMA synchronization behind PCI bridge needed. */
#define IBF_PCI 0x02 /* Indicates PSYCHO/SABRE/SCHIZO PCI interrupt. */
#define IBF_ACTIVE 0x04 /* This interrupt is active and has a handler. */
#define IBF_MULTI 0x08 /* On PCI, indicates shared bucket. */
#define IBF_INPROGRESS 0x10 /* IRQ is being serviced. */
#define IBF_PCI 0x02 /* PSYCHO/SABRE/SCHIZO PCI interrupt. */
#define IBF_ACTIVE 0x04 /* Interrupt is active and has a handler.*/
#define IBF_INPROGRESS 0x10 /* IRQ is being serviced. */
#define NUM_IVECS (IMAP_INR + 1)
extern struct ino_bucket ivector_table[NUM_IVECS];
+3
View File
@@ -145,6 +145,9 @@ struct pci_pbm_info {
/* Physical address base of PBM registers. */
unsigned long pbm_regs;
/* Physical address of DMA sync register, if any. */
unsigned long sync_reg;
/* Opaque 32-bit system bus Port ID. */
u32 portid;
-15
View File
@@ -162,21 +162,6 @@ struct sigstack {
#define MINSIGSTKSZ 4096
#define SIGSTKSZ 16384
#ifdef __KERNEL__
/*
* DJHR
* SA_STATIC_ALLOC is used for the SPARC system to indicate that this
* interrupt handler's irq structure should be statically allocated
* by the request_irq routine.
* The alternative is that arch/sparc/kernel/irq.c has carnal knowledge
* of interrupt usage and that sucks. Also without a flag like this
* it may be possible for the free_irq routine to attempt to free
* statically allocated data.. which is NOT GOOD.
*
*/
#define SA_STATIC_ALLOC 0x80
#endif
#include <asm-generic/signal.h>
struct __new_sigaction {
+18 -1
View File
@@ -346,10 +346,27 @@ COMPATIBLE_IOCTL(PPPOEIOCDFWD)
/* LP */
COMPATIBLE_IOCTL(LPGETSTATUS)
/* ppdev */
COMPATIBLE_IOCTL(PPSETMODE)
COMPATIBLE_IOCTL(PPRSTATUS)
COMPATIBLE_IOCTL(PPRCONTROL)
COMPATIBLE_IOCTL(PPWCONTROL)
COMPATIBLE_IOCTL(PPFCONTROL)
COMPATIBLE_IOCTL(PPRDATA)
COMPATIBLE_IOCTL(PPWDATA)
COMPATIBLE_IOCTL(PPCLAIM)
COMPATIBLE_IOCTL(PPRELEASE)
COMPATIBLE_IOCTL(PPEXCL)
COMPATIBLE_IOCTL(PPYIELD)
COMPATIBLE_IOCTL(PPEXCL)
COMPATIBLE_IOCTL(PPDATADIR)
COMPATIBLE_IOCTL(PPNEGOT)
COMPATIBLE_IOCTL(PPWCTLONIRQ)
COMPATIBLE_IOCTL(PPCLRIRQ)
COMPATIBLE_IOCTL(PPSETPHASE)
COMPATIBLE_IOCTL(PPGETMODES)
COMPATIBLE_IOCTL(PPGETMODE)
COMPATIBLE_IOCTL(PPGETPHASE)
COMPATIBLE_IOCTL(PPGETFLAGS)
COMPATIBLE_IOCTL(PPSETFLAGS)
/* CDROM stuff */
COMPATIBLE_IOCTL(CDROMPAUSE)
COMPATIBLE_IOCTL(CDROMRESUME)
+1 -1
View File
@@ -23,7 +23,7 @@ struct shaper
__u32 shapeclock;
unsigned long recovery; /* Time we can next clock a packet out on
an empty queue */
struct semaphore sem;
spinlock_t lock;
struct net_device_stats stats;
struct net_device *dev;
int (*hard_start_xmit) (struct sk_buff *skb,
+1 -1
View File
@@ -155,7 +155,7 @@ extern void arch_copy_kprobe(struct kprobe *p);
extern void arch_arm_kprobe(struct kprobe *p);
extern void arch_disarm_kprobe(struct kprobe *p);
extern void arch_remove_kprobe(struct kprobe *p);
extern int arch_init(void);
extern int arch_init_kprobes(void);
extern void show_registers(struct pt_regs *regs);
extern kprobe_opcode_t *get_insn_slot(void);
extern void free_insn_slot(kprobe_opcode_t *slot);
-18
View File
@@ -1,18 +0,0 @@
/*
* PCI defines and function prototypes
* Copyright 2003 Dell Inc.
* by Matt Domsch <Matt_Domsch@dell.com>
*/
#ifndef LINUX_PCI_DYNIDS_H
#define LINUX_PCI_DYNIDS_H
#include <linux/list.h>
#include <linux/mod_devicetable.h>
struct dynid {
struct list_head node;
struct pci_device_id id;
};
#endif
+3 -2
View File
@@ -586,7 +586,7 @@ struct pci_dev {
#define PCI_NUM_RESOURCES 11
#ifndef PCI_BUS_NUM_RESOURCES
#define PCI_BUS_NUM_RESOURCES 4
#define PCI_BUS_NUM_RESOURCES 8
#endif
#define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us the PCI region flags */
@@ -860,7 +860,8 @@ int pci_register_driver(struct pci_driver *);
void pci_unregister_driver(struct pci_driver *);
void pci_remove_behind_bridge(struct pci_dev *);
struct pci_driver *pci_dev_driver(const struct pci_dev *);
const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev);
const struct pci_device_id *pci_match_device(struct pci_driver *drv, struct pci_dev *dev);
const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev);
int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass);
/* kmem_cache style wrapper around pci_alloc_consistent() */
+1
View File
@@ -1238,6 +1238,7 @@
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE 0x0265
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA 0x0266
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2 0x0267
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE 0x036E
#define PCI_DEVICE_ID_NVIDIA_NVENET_12 0x0268
#define PCI_DEVICE_ID_NVIDIA_NVENET_13 0x0269
#define PCI_DEVICE_ID_NVIDIA_MCP51_AUDIO 0x026B
+9 -10
View File
@@ -183,7 +183,6 @@ struct skb_shared_info {
* @priority: Packet queueing priority
* @users: User count - see {datagram,tcp}.c
* @protocol: Packet protocol from driver
* @security: Security level of packet
* @truesize: Buffer size
* @head: Head of buffer
* @data: Data head pointer
@@ -249,18 +248,18 @@ struct sk_buff {
data_len,
mac_len,
csum;
unsigned char local_df,
cloned:1,
nohdr:1,
pkt_type,
ip_summed;
__u32 priority;
unsigned short protocol,
security;
__u8 local_df:1,
cloned:1,
ip_summed:2,
nohdr:1;
/* 3 bits spare */
__u8 pkt_type;
__u16 protocol;
void (*destructor)(struct sk_buff *skb);
#ifdef CONFIG_NETFILTER
unsigned long nfmark;
unsigned long nfmark;
__u32 nfcache;
__u32 nfctinfo;
struct nf_conntrack *nfct;
@@ -1211,7 +1210,7 @@ static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
{
int hlen = skb_headlen(skb);
if (offset + len <= hlen)
if (hlen - offset >= len)
return skb->data + offset;
if (skb_copy_bits(skb, offset, buffer, len) < 0)
+1 -1
View File
@@ -45,7 +45,7 @@ enum
TCF_META_ID_REALDEV,
TCF_META_ID_PRIORITY,
TCF_META_ID_PROTOCOL,
TCF_META_ID_SECURITY,
TCF_META_ID_SECURITY, /* obsolete */
TCF_META_ID_PKTTYPE,
TCF_META_ID_PKTLEN,
TCF_META_ID_DATALEN,
+1 -1
View File
@@ -286,7 +286,7 @@ struct tcp_sock {
__u32 max_window; /* Maximal window ever seen from peer */
__u32 pmtu_cookie; /* Last pmtu seen by socket */
__u32 mss_cache; /* Cached effective mss, not including SACKS */
__u16 mss_cache_std; /* Like mss_cache, but without TSO */
__u16 xmit_size_goal; /* Goal for segmenting output packets */
__u16 ext_header_len; /* Network protocol overhead (IP/IPv6 options) */
__u8 ca_state; /* State of fast-retransmit machine */
__u8 retransmits; /* Number of unrecovered RTO timeouts. */
+3 -14
View File
@@ -13,13 +13,12 @@ struct qdisc_walker
extern rwlock_t qdisc_tree_lock;
#define QDISC_ALIGN 32
#define QDISC_ALIGN_CONST (QDISC_ALIGN - 1)
#define QDISC_ALIGNTO 32
#define QDISC_ALIGN(len) (((len) + QDISC_ALIGNTO-1) & ~(QDISC_ALIGNTO-1))
static inline void *qdisc_priv(struct Qdisc *q)
{
return (char *)q + ((sizeof(struct Qdisc) + QDISC_ALIGN_CONST)
& ~QDISC_ALIGN_CONST);
return (char *) q + QDISC_ALIGN(sizeof(struct Qdisc));
}
/*
@@ -207,8 +206,6 @@ psched_tod_diff(int delta_sec, int bound)
#endif /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */
extern struct Qdisc noop_qdisc;
extern struct Qdisc_ops noop_qdisc_ops;
extern struct Qdisc_ops pfifo_qdisc_ops;
extern struct Qdisc_ops bfifo_qdisc_ops;
@@ -216,14 +213,6 @@ extern int register_qdisc(struct Qdisc_ops *qops);
extern int unregister_qdisc(struct Qdisc_ops *qops);
extern struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle);
extern struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle);
extern void dev_init_scheduler(struct net_device *dev);
extern void dev_shutdown(struct net_device *dev);
extern void dev_activate(struct net_device *dev);
extern void dev_deactivate(struct net_device *dev);
extern void qdisc_reset(struct Qdisc *qdisc);
extern void qdisc_destroy(struct Qdisc *qdisc);
extern struct Qdisc * qdisc_create_dflt(struct net_device *dev,
struct Qdisc_ops *ops);
extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
struct rtattr *tab);
extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
+13
View File
@@ -164,6 +164,19 @@ extern void qdisc_unlock_tree(struct net_device *dev);
#define tcf_tree_lock(tp) qdisc_lock_tree((tp)->q->dev)
#define tcf_tree_unlock(tp) qdisc_unlock_tree((tp)->q->dev)
extern struct Qdisc noop_qdisc;
extern struct Qdisc_ops noop_qdisc_ops;
extern void dev_init_scheduler(struct net_device *dev);
extern void dev_shutdown(struct net_device *dev);
extern void dev_activate(struct net_device *dev);
extern void dev_deactivate(struct net_device *dev);
extern void qdisc_reset(struct Qdisc *qdisc);
extern void qdisc_destroy(struct Qdisc *qdisc);
extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops);
extern struct Qdisc *qdisc_create_dflt(struct net_device *dev,
struct Qdisc_ops *ops);
static inline void
tcf_destroy(struct tcf_proto *tp)
{
+7 -12
View File
@@ -170,19 +170,14 @@ struct slcompress {
};
#define NULLSLCOMPR (struct slcompress *)0
#define __ARGS(x) x
/* In slhc.c: */
struct slcompress *slhc_init __ARGS((int rslots, int tslots));
void slhc_free __ARGS((struct slcompress *comp));
struct slcompress *slhc_init(int rslots, int tslots);
void slhc_free(struct slcompress *comp);
int slhc_compress __ARGS((struct slcompress *comp, unsigned char *icp,
int isize, unsigned char *ocp, unsigned char **cpp,
int compress_cid));
int slhc_uncompress __ARGS((struct slcompress *comp, unsigned char *icp,
int isize));
int slhc_remember __ARGS((struct slcompress *comp, unsigned char *icp,
int isize));
int slhc_toss __ARGS((struct slcompress *comp));
int slhc_compress(struct slcompress *comp, unsigned char *icp, int isize,
unsigned char *ocp, unsigned char **cpp, int compress_cid);
int slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize);
int slhc_remember(struct slcompress *comp, unsigned char *icp, int isize);
int slhc_toss(struct slcompress *comp);
#endif /* _SLHC_H */
+5 -2
View File
@@ -1134,13 +1134,16 @@ static inline void sk_stream_moderate_sndbuf(struct sock *sk)
static inline struct sk_buff *sk_stream_alloc_pskb(struct sock *sk,
int size, int mem, int gfp)
{
struct sk_buff *skb = alloc_skb(size + sk->sk_prot->max_header, gfp);
struct sk_buff *skb;
int hdr_len;
hdr_len = SKB_DATA_ALIGN(sk->sk_prot->max_header);
skb = alloc_skb(size + hdr_len, gfp);
if (skb) {
skb->truesize += mem;
if (sk->sk_forward_alloc >= (int)skb->truesize ||
sk_stream_mem_schedule(sk, skb->truesize, 0)) {
skb_reserve(skb, sk->sk_prot->max_header);
skb_reserve(skb, hdr_len);
return skb;
}
__kfree_skb(skb);
+17 -139
View File
@@ -721,11 +721,16 @@ static inline int tcp_ack_scheduled(struct tcp_sock *tp)
return tp->ack.pending&TCP_ACK_SCHED;
}
static __inline__ void tcp_dec_quickack_mode(struct tcp_sock *tp)
static __inline__ void tcp_dec_quickack_mode(struct tcp_sock *tp, unsigned int pkts)
{
if (tp->ack.quick && --tp->ack.quick == 0) {
/* Leaving quickack mode we deflate ATO. */
tp->ack.ato = TCP_ATO_MIN;
if (tp->ack.quick) {
if (pkts >= tp->ack.quick) {
tp->ack.quick = 0;
/* Leaving quickack mode we deflate ATO. */
tp->ack.ato = TCP_ATO_MIN;
} else
tp->ack.quick -= pkts;
}
}
@@ -843,7 +848,9 @@ extern __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb,
/* tcp_output.c */
extern int tcp_write_xmit(struct sock *, int nonagle);
extern void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp,
unsigned int cur_mss, int nonagle);
extern int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp);
extern int tcp_retransmit_skb(struct sock *, struct sk_buff *);
extern void tcp_xmit_retransmit_queue(struct sock *);
extern void tcp_simple_retransmit(struct sock *);
@@ -855,10 +862,13 @@ extern int tcp_write_wakeup(struct sock *);
extern void tcp_send_fin(struct sock *sk);
extern void tcp_send_active_reset(struct sock *sk, int priority);
extern int tcp_send_synack(struct sock *);
extern void tcp_push_one(struct sock *, unsigned mss_now);
extern void tcp_push_one(struct sock *, unsigned int mss_now);
extern void tcp_send_ack(struct sock *sk);
extern void tcp_send_delayed_ack(struct sock *sk);
/* tcp_input.c */
extern void tcp_cwnd_application_limited(struct sock *sk);
/* tcp_timer.c */
extern void tcp_init_xmit_timers(struct sock *);
extern void tcp_clear_xmit_timers(struct sock *);
@@ -958,7 +968,7 @@ static inline void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long
static inline void tcp_initialize_rcv_mss(struct sock *sk)
{
struct tcp_sock *tp = tcp_sk(sk);
unsigned int hint = min(tp->advmss, tp->mss_cache_std);
unsigned int hint = min_t(unsigned int, tp->advmss, tp->mss_cache);
hint = min(hint, tp->rcv_wnd/2);
hint = min(hint, TCP_MIN_RCVMSS);
@@ -1225,28 +1235,6 @@ static inline void tcp_sync_left_out(struct tcp_sock *tp)
tp->left_out = tp->sacked_out + tp->lost_out;
}
extern void tcp_cwnd_application_limited(struct sock *sk);
/* Congestion window validation. (RFC2861) */
static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp)
{
__u32 packets_out = tp->packets_out;
if (packets_out >= tp->snd_cwnd) {
/* Network is feed fully. */
tp->snd_cwnd_used = 0;
tp->snd_cwnd_stamp = tcp_time_stamp;
} else {
/* Network starves. */
if (tp->packets_out > tp->snd_cwnd_used)
tp->snd_cwnd_used = tp->packets_out;
if ((s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= tp->rto)
tcp_cwnd_application_limited(sk);
}
}
/* Set slow start threshould and cwnd not falling to slow start */
static inline void __tcp_enter_cwr(struct tcp_sock *tp)
{
@@ -1279,12 +1267,6 @@ static __inline__ __u32 tcp_max_burst(const struct tcp_sock *tp)
return 3;
}
static __inline__ int tcp_minshall_check(const struct tcp_sock *tp)
{
return after(tp->snd_sml,tp->snd_una) &&
!after(tp->snd_sml, tp->snd_nxt);
}
static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss,
const struct sk_buff *skb)
{
@@ -1292,122 +1274,18 @@ static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss,
tp->snd_sml = TCP_SKB_CB(skb)->end_seq;
}
/* Return 0, if packet can be sent now without violation Nagle's rules:
1. It is full sized.
2. Or it contains FIN.
3. Or TCP_NODELAY was set.
4. Or TCP_CORK is not set, and all sent packets are ACKed.
With Minshall's modification: all sent small packets are ACKed.
*/
static __inline__ int
tcp_nagle_check(const struct tcp_sock *tp, const struct sk_buff *skb,
unsigned mss_now, int nonagle)
{
return (skb->len < mss_now &&
!(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) &&
((nonagle&TCP_NAGLE_CORK) ||
(!nonagle &&
tp->packets_out &&
tcp_minshall_check(tp))));
}
extern void tcp_set_skb_tso_segs(struct sock *, struct sk_buff *);
/* This checks if the data bearing packet SKB (usually sk->sk_send_head)
* should be put on the wire right now.
*/
static __inline__ int tcp_snd_test(struct sock *sk,
struct sk_buff *skb,
unsigned cur_mss, int nonagle)
{
struct tcp_sock *tp = tcp_sk(sk);
int pkts = tcp_skb_pcount(skb);
if (!pkts) {
tcp_set_skb_tso_segs(sk, skb);
pkts = tcp_skb_pcount(skb);
}
/* RFC 1122 - section 4.2.3.4
*
* We must queue if
*
* a) The right edge of this frame exceeds the window
* b) There are packets in flight and we have a small segment
* [SWS avoidance and Nagle algorithm]
* (part of SWS is done on packetization)
* Minshall version sounds: there are no _small_
* segments in flight. (tcp_nagle_check)
* c) We have too many packets 'in flight'
*
* Don't use the nagle rule for urgent data (or
* for the final FIN -DaveM).
*
* Also, Nagle rule does not apply to frames, which
* sit in the middle of queue (they have no chances
* to get new data) and if room at tail of skb is
* not enough to save something seriously (<32 for now).
*/
/* Don't be strict about the congestion window for the
* final FIN frame. -DaveM
*/
return (((nonagle&TCP_NAGLE_PUSH) || tp->urg_mode
|| !tcp_nagle_check(tp, skb, cur_mss, nonagle)) &&
(((tcp_packets_in_flight(tp) + (pkts-1)) < tp->snd_cwnd) ||
(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) &&
!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd));
}
static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp)
{
if (!tp->packets_out && !tp->pending)
tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, tp->rto);
}
static __inline__ int tcp_skb_is_last(const struct sock *sk,
const struct sk_buff *skb)
{
return skb->next == (struct sk_buff *)&sk->sk_write_queue;
}
/* Push out any pending frames which were held back due to
* TCP_CORK or attempt at coalescing tiny packets.
* The socket must be locked by the caller.
*/
static __inline__ void __tcp_push_pending_frames(struct sock *sk,
struct tcp_sock *tp,
unsigned cur_mss,
int nonagle)
{
struct sk_buff *skb = sk->sk_send_head;
if (skb) {
if (!tcp_skb_is_last(sk, skb))
nonagle = TCP_NAGLE_PUSH;
if (!tcp_snd_test(sk, skb, cur_mss, nonagle) ||
tcp_write_xmit(sk, nonagle))
tcp_check_probe_timer(sk, tp);
}
tcp_cwnd_validate(sk, tp);
}
static __inline__ void tcp_push_pending_frames(struct sock *sk,
struct tcp_sock *tp)
{
__tcp_push_pending_frames(sk, tp, tcp_current_mss(sk, 1), tp->nonagle);
}
static __inline__ int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp)
{
struct sk_buff *skb = sk->sk_send_head;
return (skb &&
tcp_snd_test(sk, skb, tcp_current_mss(sk, 1),
tcp_skb_is_last(sk, skb) ? TCP_NAGLE_PUSH : tp->nonagle));
}
static __inline__ void tcp_init_wl(struct tcp_sock *tp, u32 ack, u32 seq)
{
tp->snd_wl1 = seq;